@aiready/cli 0.14.3 → 0.14.4

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/cli.mjs CHANGED
@@ -12,7 +12,7 @@ import { join as join2, dirname } from "path";
12
12
  import { fileURLToPath } from "url";
13
13
 
14
14
  // src/commands/scan.ts
15
- import chalk3 from "chalk";
15
+ import chalk4 from "chalk";
16
16
  import { writeFileSync, readFileSync as readFileSync2 } from "fs";
17
17
  import { resolve as resolvePath3 } from "path";
18
18
  import {
@@ -20,12 +20,8 @@ import {
20
20
  handleJSONOutput,
21
21
  handleCLIError as handleCLIError2,
22
22
  resolveOutputPath,
23
- formatScore,
24
- calculateTokenBudget,
25
- getRating,
26
- getRatingDisplay,
27
23
  getRepoMetadata,
28
- Severity,
24
+ calculateTokenBudget,
29
25
  ToolName,
30
26
  emitIssuesAsAnnotations
31
27
  } from "@aiready/core";
@@ -127,10 +123,102 @@ function generateMarkdownReport(report, elapsedTime) {
127
123
  return markdown;
128
124
  }
129
125
 
126
+ // src/commands/report-formatter.ts
127
+ import chalk2 from "chalk";
128
+ import {
129
+ Severity,
130
+ formatScore,
131
+ getRating,
132
+ getRatingDisplay
133
+ } from "@aiready/core";
134
+ function printScanSummary(results, startTime) {
135
+ console.log(chalk2.cyan("\n=== AIReady Run Summary ==="));
136
+ console.log(
137
+ ` Total issues (all tools): ${chalk2.bold(String(results.summary.totalIssues || 0))}`
138
+ );
139
+ console.log(
140
+ ` Execution time: ${chalk2.bold(((Date.now() - startTime) / 1e3).toFixed(2) + "s")}`
141
+ );
142
+ }
143
+ function printBusinessImpact(roi, unifiedBudget) {
144
+ console.log(chalk2.bold("\n\u{1F4B0} Business Impact Analysis (Monthly)"));
145
+ console.log(
146
+ ` Potential Savings: ${chalk2.green(chalk2.bold("$" + roi.monthlySavings.toLocaleString()))}`
147
+ );
148
+ console.log(
149
+ ` Productivity Gain: ${chalk2.cyan(chalk2.bold(roi.productivityGainHours + "h"))} (est. dev time)`
150
+ );
151
+ console.log(
152
+ ` Context Efficiency: ${chalk2.yellow((unifiedBudget.efficiencyRatio * 100).toFixed(0) + "%")}`
153
+ );
154
+ console.log(
155
+ ` Annual Value: ${chalk2.bold("$" + roi.annualValue.toLocaleString())} (ROI Prediction)`
156
+ );
157
+ }
158
+ function printScoring(scoringResult, scoringProfile) {
159
+ console.log(chalk2.bold("\n\u{1F4CA} AI Readiness Overall Score"));
160
+ console.log(` ${formatScore(scoringResult)}`);
161
+ console.log(chalk2.dim(` (Scoring Profile: ${scoringProfile})`));
162
+ if (scoringResult.breakdown) {
163
+ console.log(chalk2.bold("\nTool breakdown:"));
164
+ scoringResult.breakdown.forEach((tool) => {
165
+ const rating = getRating(tool.score);
166
+ const emoji = getRatingDisplay(rating).emoji;
167
+ console.log(
168
+ ` - ${tool.toolName}: ${tool.score}/100 (${rating}) ${emoji}`
169
+ );
170
+ });
171
+ const allRecs = scoringResult.breakdown.flatMap(
172
+ (t) => (t.recommendations || []).map((r) => ({ ...r, tool: t.toolName }))
173
+ ).sort((a, b) => b.estimatedImpact - a.estimatedImpact).slice(0, 3);
174
+ if (allRecs.length > 0) {
175
+ console.log(chalk2.bold("\n\u{1F3AF} Top Actionable Recommendations:"));
176
+ allRecs.forEach((rec, i) => {
177
+ const priorityIcon = rec.priority === "high" ? "\u{1F534}" : rec.priority === "medium" ? "\u{1F7E1}" : "\u{1F535}";
178
+ console.log(` ${i + 1}. ${priorityIcon} ${chalk2.bold(rec.action)}`);
179
+ console.log(
180
+ ` Impact: ${chalk2.green(`+${rec.estimatedImpact} points`)} to ${rec.tool}`
181
+ );
182
+ });
183
+ }
184
+ }
185
+ }
186
+ function mapToUnifiedReport(res, scoring) {
187
+ const allResults = [];
188
+ const totalFilesSet = /* @__PURE__ */ new Set();
189
+ let criticalCount = 0;
190
+ let majorCount = 0;
191
+ res.summary.toolsRun.forEach((toolId) => {
192
+ const spokeRes = res[toolId];
193
+ if (!spokeRes || !spokeRes.results) return;
194
+ spokeRes.results.forEach((r) => {
195
+ totalFilesSet.add(r.fileName);
196
+ allResults.push(r);
197
+ r.issues?.forEach((i) => {
198
+ if (i.severity === Severity.Critical || i.severity === "critical")
199
+ criticalCount++;
200
+ if (i.severity === Severity.Major || i.severity === "major")
201
+ majorCount++;
202
+ });
203
+ });
204
+ });
205
+ return {
206
+ ...res,
207
+ results: allResults,
208
+ summary: {
209
+ ...res.summary,
210
+ totalFiles: totalFilesSet.size,
211
+ criticalIssues: criticalCount,
212
+ majorIssues: majorCount
213
+ },
214
+ scoring
215
+ };
216
+ }
217
+
130
218
  // src/commands/upload.ts
131
219
  import fs from "fs";
132
220
  import { resolve as resolvePath2 } from "path";
133
- import chalk2 from "chalk";
221
+ import chalk3 from "chalk";
134
222
  import { handleCLIError } from "@aiready/core";
135
223
  async function uploadAction(file, options) {
136
224
  const startTime = Date.now();
@@ -138,31 +226,31 @@ async function uploadAction(file, options) {
138
226
  const serverUrl = options.server || process.env.AIREADY_SERVER || "https://dev.platform.getaiready.dev";
139
227
  const apiKey = options.apiKey || process.env.AIREADY_API_KEY;
140
228
  if (!apiKey) {
141
- console.error(chalk2.red("\u274C API Key is required for upload."));
229
+ console.error(chalk3.red("\u274C API Key is required for upload."));
142
230
  console.log(
143
- chalk2.dim(
231
+ chalk3.dim(
144
232
  " Set AIREADY_API_KEY environment variable or use --api-key flag."
145
233
  )
146
234
  );
147
235
  console.log(
148
- chalk2.dim(
236
+ chalk3.dim(
149
237
  " Get an API key from https://platform.getaiready.dev/dashboard"
150
238
  )
151
239
  );
152
240
  process.exit(1);
153
241
  }
154
242
  if (!fs.existsSync(filePath)) {
155
- console.error(chalk2.red(`\u274C File not found: ${filePath}`));
243
+ console.error(chalk3.red(`\u274C File not found: ${filePath}`));
156
244
  process.exit(1);
157
245
  }
158
246
  try {
159
- console.log(chalk2.blue(`\u{1F680} Uploading report to ${serverUrl}...`));
160
- console.log(chalk2.dim(` Reading report from ${filePath}...`));
247
+ console.log(chalk3.blue(`\u{1F680} Uploading report to ${serverUrl}...`));
248
+ console.log(chalk3.dim(` Reading report from ${filePath}...`));
161
249
  const reportContent = fs.readFileSync(filePath, "utf-8");
162
250
  const reportData = JSON.parse(reportContent);
163
- console.log(chalk2.dim(` Successfully parsed report JSON.`));
251
+ console.log(chalk3.dim(` Successfully parsed report JSON.`));
164
252
  const repoId = options.repoId || reportData.repository?.repoId;
165
- const res = await fetch(`${serverUrl}/api/analysis/upload`, {
253
+ const response = await fetch(`${serverUrl}/api/analysis/upload`, {
166
254
  method: "POST",
167
255
  headers: {
168
256
  "Content-Type": "application/json",
@@ -174,46 +262,48 @@ async function uploadAction(file, options) {
174
262
  // Might be null, server will handle mapping
175
263
  })
176
264
  });
177
- const contentType = res.headers.get("content-type");
178
- let result = {};
265
+ const contentType = response.headers.get("content-type");
266
+ let uploadResult = {};
179
267
  if (contentType?.includes("application/json")) {
180
- result = await res.json();
268
+ uploadResult = await response.json();
181
269
  } else {
182
- const text = await res.text();
183
- result = { error: text || res.statusText };
270
+ const text = await response.text();
271
+ uploadResult = { error: text || response.statusText };
184
272
  }
185
- if (!res.ok) {
273
+ if (!response.ok) {
186
274
  console.error(
187
- chalk2.red(`\u274C Upload failed: ${result.error || res.statusText}`)
275
+ chalk3.red(
276
+ `\u274C Upload failed: ${uploadResult.error || response.statusText}`
277
+ )
188
278
  );
189
279
  if (contentType?.includes("text/html")) {
190
280
  console.log(
191
- chalk2.yellow(
281
+ chalk3.yellow(
192
282
  " Note: Received an HTML response. This often indicates a redirect (e.g., to a login page) or a server error."
193
283
  )
194
284
  );
195
- if (result.error?.includes("Redirecting")) {
285
+ if (uploadResult.error?.includes("Redirecting")) {
196
286
  console.log(
197
- chalk2.dim(
287
+ chalk3.dim(
198
288
  " Detected redirect. Check if the API endpoint requires authentication or has changed."
199
289
  )
200
290
  );
201
291
  }
202
292
  }
203
- if (res.status === 401) {
293
+ if (response.status === 401) {
204
294
  console.log(
205
- chalk2.dim(" Hint: Your API key may be invalid or expired.")
295
+ chalk3.dim(" Hint: Your API key may be invalid or expired.")
206
296
  );
207
297
  }
208
298
  process.exit(1);
209
299
  }
210
300
  const duration = ((Date.now() - startTime) / 1e3).toFixed(2);
211
- console.log(chalk2.green(`
301
+ console.log(chalk3.green(`
212
302
  \u2705 Upload successful! (${duration}s)`));
213
- console.log(chalk2.cyan(` View results: ${serverUrl}/dashboard`));
214
- if (result.analysis) {
215
- console.log(chalk2.dim(` Analysis ID: ${result.analysis.id}`));
216
- console.log(chalk2.dim(` Score: ${result.analysis.aiScore}/100`));
303
+ console.log(chalk3.cyan(` View results: ${serverUrl}/dashboard`));
304
+ if (uploadResult.analysis) {
305
+ console.log(chalk3.dim(` Analysis ID: ${uploadResult.analysis.id}`));
306
+ console.log(chalk3.dim(` Score: ${uploadResult.analysis.aiScore}/100`));
217
307
  }
218
308
  } catch (error) {
219
309
  handleCLIError(error, "Upload");
@@ -232,7 +322,7 @@ ENVIRONMENT VARIABLES:
232
322
 
233
323
  // src/commands/scan.ts
234
324
  async function scanAction(directory, options) {
235
- console.log(chalk3.blue("\u{1F680} Starting AIReady unified analysis...\n"));
325
+ console.log(chalk4.blue("\u{1F680} Starting AIReady unified analysis...\n"));
236
326
  const startTime = Date.now();
237
327
  const resolvedDir = resolvePath3(process.cwd(), directory || ".");
238
328
  const repoMetadata = getRepoMetadata(resolvedDir);
@@ -302,7 +392,7 @@ async function scanAction(directory, options) {
302
392
  break;
303
393
  default:
304
394
  console.log(
305
- chalk3.yellow(
395
+ chalk4.yellow(
306
396
  `
307
397
  \u26A0\uFE0F Unknown profile '${options.profile}'. Using defaults.`
308
398
  )
@@ -332,9 +422,9 @@ async function scanAction(directory, options) {
332
422
  ...finalOptions.toolConfigs[ToolName.PatternDetect]
333
423
  };
334
424
  }
335
- console.log(chalk3.cyan("\n=== AIReady Run Preview ==="));
425
+ console.log(chalk4.cyan("\n=== AIReady Run Preview ==="));
336
426
  console.log(
337
- chalk3.white("Tools to run:"),
427
+ chalk4.white("Tools to run:"),
338
428
  (finalOptions.tools || []).join(", ")
339
429
  );
340
430
  const progressCallback = (event) => {
@@ -343,16 +433,16 @@ async function scanAction(directory, options) {
343
433
  return;
344
434
  }
345
435
  process.stdout.write("\r\x1B[K");
346
- console.log(chalk3.cyan(`--- ${event.tool.toUpperCase()} RESULTS ---`));
436
+ console.log(chalk4.cyan(`--- ${event.tool.toUpperCase()} RESULTS ---`));
347
437
  const res = event.data;
348
438
  if (res && res.summary) {
349
439
  if (res.summary.totalIssues !== void 0)
350
- console.log(` Issues found: ${chalk3.bold(res.summary.totalIssues)}`);
440
+ console.log(` Issues found: ${chalk4.bold(res.summary.totalIssues)}`);
351
441
  if (res.summary.score !== void 0)
352
- console.log(` Tool Score: ${chalk3.bold(res.summary.score)}/100`);
442
+ console.log(` Tool Score: ${chalk4.bold(res.summary.score)}/100`);
353
443
  if (res.summary.totalFiles !== void 0)
354
444
  console.log(
355
- ` Files analyzed: ${chalk3.bold(res.summary.totalFiles)}`
445
+ ` Files analyzed: ${chalk4.bold(res.summary.totalFiles)}`
356
446
  );
357
447
  }
358
448
  };
@@ -364,13 +454,7 @@ async function scanAction(directory, options) {
364
454
  },
365
455
  suppressToolConfig: true
366
456
  });
367
- console.log(chalk3.cyan("\n=== AIReady Run Summary ==="));
368
- console.log(
369
- ` Total issues (all tools): ${chalk3.bold(String(results.summary.totalIssues || 0))}`
370
- );
371
- console.log(
372
- ` Execution time: ${chalk3.bold(((Date.now() - startTime) / 1e3).toFixed(2) + "s")}`
373
- );
457
+ printScanSummary(results, startTime);
374
458
  let scoringResult;
375
459
  if (options.score || finalOptions.scoring?.showBreakdown) {
376
460
  scoringResult = await scoreUnified(results, {
@@ -380,9 +464,7 @@ async function scanAction(directory, options) {
380
464
  profile: scoringProfile
381
465
  }
382
466
  });
383
- console.log(chalk3.bold("\n\u{1F4CA} AI Readiness Overall Score"));
384
- console.log(` ${formatScore(scoringResult)}`);
385
- console.log(chalk3.dim(` (Scoring Profile: ${scoringProfile})`));
467
+ printScoring(scoringResult, scoringProfile);
386
468
  if (options.compareTo) {
387
469
  try {
388
470
  const prevReport = JSON.parse(
@@ -394,19 +476,19 @@ async function scanAction(directory, options) {
394
476
  const diffStr = diff > 0 ? `+${diff}` : String(diff);
395
477
  if (diff > 0)
396
478
  console.log(
397
- chalk3.green(
479
+ chalk4.green(
398
480
  ` \u{1F4C8} Trend: ${diffStr} compared to ${options.compareTo} (${prevScore} \u2192 ${scoringResult.overall})`
399
481
  )
400
482
  );
401
483
  else if (diff < 0)
402
484
  console.log(
403
- chalk3.red(
485
+ chalk4.red(
404
486
  ` \u{1F4C9} Trend: ${diffStr} compared to ${options.compareTo} (${prevScore} \u2192 ${scoringResult.overall})`
405
487
  )
406
488
  );
407
489
  else
408
490
  console.log(
409
- chalk3.blue(
491
+ chalk4.blue(
410
492
  ` \u2796 Trend: No change (${prevScore} \u2192 ${scoringResult.overall})`
411
493
  )
412
494
  );
@@ -455,19 +537,7 @@ async function scanAction(directory, options) {
455
537
  issues: allIssues,
456
538
  modelId
457
539
  });
458
- console.log(chalk3.bold("\n\u{1F4B0} Business Impact Analysis (Monthly)"));
459
- console.log(
460
- ` Potential Savings: ${chalk3.green(chalk3.bold("$" + roi.monthlySavings.toLocaleString()))}`
461
- );
462
- console.log(
463
- ` Productivity Gain: ${chalk3.cyan(chalk3.bold(roi.productivityGainHours + "h"))} (est. dev time)`
464
- );
465
- console.log(
466
- ` Context Efficiency: ${chalk3.yellow((unifiedBudget.efficiencyRatio * 100).toFixed(0) + "%")}`
467
- );
468
- console.log(
469
- ` Annual Value: ${chalk3.bold("$" + roi.annualValue.toLocaleString())} (ROI Prediction)`
470
- );
540
+ printBusinessImpact(roi, unifiedBudget);
471
541
  results.summary.businessImpact = {
472
542
  estimatedMonthlyWaste: roi.monthlySavings,
473
543
  potentialSavings: roi.monthlySavings,
@@ -476,78 +546,24 @@ async function scanAction(directory, options) {
476
546
  scoringResult.tokenBudget = unifiedBudget;
477
547
  scoringResult.businessROI = roi;
478
548
  }
479
- if (scoringResult.breakdown) {
480
- console.log(chalk3.bold("\nTool breakdown:"));
481
- scoringResult.breakdown.forEach((tool) => {
482
- const rating = getRating(tool.score);
483
- const emoji = getRatingDisplay(rating).emoji;
484
- console.log(
485
- ` - ${tool.toolName}: ${tool.score}/100 (${rating}) ${emoji}`
486
- );
487
- });
488
- const allRecs = scoringResult.breakdown.flatMap(
489
- (t) => (t.recommendations || []).map((r) => ({ ...r, tool: t.toolName }))
490
- ).sort((a, b) => b.estimatedImpact - a.estimatedImpact).slice(0, 3);
491
- if (allRecs.length > 0) {
492
- console.log(chalk3.bold("\n\u{1F3AF} Top Actionable Recommendations:"));
493
- allRecs.forEach((rec, i) => {
494
- const priorityIcon = rec.priority === "high" ? "\u{1F534}" : rec.priority === "medium" ? "\u{1F7E1}" : "\u{1F535}";
495
- console.log(
496
- ` ${i + 1}. ${priorityIcon} ${chalk3.bold(rec.action)}`
497
- );
498
- console.log(
499
- ` Impact: ${chalk3.green(`+${rec.estimatedImpact} points`)} to ${rec.tool}`
500
- );
501
- });
502
- }
503
- }
504
549
  }
505
550
  console.log(
506
- chalk3.dim(
551
+ chalk4.dim(
507
552
  "\n\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500"
508
553
  )
509
554
  );
510
- console.log(chalk3.dim("\u{1F4AC} Found a bug or have a metric idea?"));
511
- console.log(chalk3.dim("\u{1F449} Copy/paste this to your AI agent:"));
555
+ console.log(chalk4.dim("\u{1F4AC} Found a bug or have a metric idea?"));
556
+ console.log(chalk4.dim("\u{1F449} Copy/paste this to your AI agent:"));
512
557
  console.log(
513
- chalk3.cyan(
558
+ chalk4.cyan(
514
559
  ` "Any feedback for the tools? Please use 'aiready bug' to report \u2764\uFE0F"`
515
560
  )
516
561
  );
517
562
  console.log(
518
- chalk3.dim(
563
+ chalk4.dim(
519
564
  "\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500"
520
565
  )
521
566
  );
522
- const mapToUnifiedReport = (res, scoring) => {
523
- const allResults = [];
524
- const totalFilesSet = /* @__PURE__ */ new Set();
525
- let criticalCount = 0;
526
- let majorCount = 0;
527
- res.summary.toolsRun.forEach((toolId) => {
528
- const spokeRes = res[toolId];
529
- if (!spokeRes || !spokeRes.results) return;
530
- spokeRes.results.forEach((r) => {
531
- totalFilesSet.add(r.fileName);
532
- allResults.push(r);
533
- r.issues?.forEach((i) => {
534
- if (i.severity === Severity.Critical) criticalCount++;
535
- if (i.severity === Severity.Major) majorCount++;
536
- });
537
- });
538
- });
539
- return {
540
- ...res,
541
- results: allResults,
542
- summary: {
543
- ...res.summary,
544
- totalFiles: totalFilesSet.size,
545
- criticalIssues: criticalCount,
546
- majorIssues: majorCount
547
- },
548
- scoring
549
- };
550
- };
551
567
  const outputData = {
552
568
  ...mapToUnifiedReport(results, scoringResult),
553
569
  repository: repoMetadata
@@ -567,7 +583,7 @@ async function scanAction(directory, options) {
567
583
  } else {
568
584
  try {
569
585
  writeFileSync(outputPath, JSON.stringify(outputData, null, 2));
570
- console.log(chalk3.dim(`\u2705 Report auto-persisted to ${outputPath}`));
586
+ console.log(chalk4.dim(`\u2705 Report auto-persisted to ${outputPath}`));
571
587
  } catch (err) {
572
588
  void err;
573
589
  }
@@ -588,7 +604,7 @@ async function scanAction(directory, options) {
588
604
  const report = mapToUnifiedReport(results, scoringResult);
589
605
  if (isCI && report.results && report.results.length > 0) {
590
606
  console.log(
591
- chalk3.cyan(
607
+ chalk4.cyan(
592
608
  `
593
609
  \u{1F4DD} Emitting GitHub Action annotations for ${report.results.length} issues...`
594
610
  )
@@ -609,11 +625,11 @@ async function scanAction(directory, options) {
609
625
  }
610
626
  }
611
627
  if (shouldFail) {
612
- console.log(chalk3.red(`
628
+ console.log(chalk4.red(`
613
629
  \u{1F6AB} SCAN FAILED: ${failReason}`));
614
630
  process.exit(1);
615
631
  } else {
616
- console.log(chalk3.green("\n\u2705 SCAN PASSED"));
632
+ console.log(chalk4.green("\n\u2705 SCAN PASSED"));
617
633
  }
618
634
  }
619
635
  } catch (error) {
@@ -625,7 +641,7 @@ var scanHelpText = `...`;
625
641
  // src/commands/init.ts
626
642
  import { writeFileSync as writeFileSync2, existsSync as existsSync2 } from "fs";
627
643
  import { join } from "path";
628
- import chalk4 from "chalk";
644
+ import chalk5 from "chalk";
629
645
  import { ToolName as ToolName2 } from "@aiready/core";
630
646
  async function initAction(options) {
631
647
  const fileExt = options.format === "js" ? "js" : "json";
@@ -633,7 +649,7 @@ async function initAction(options) {
633
649
  const filePath = join(process.cwd(), fileName);
634
650
  if (existsSync2(filePath) && !options.force) {
635
651
  console.error(
636
- chalk4.red(`Error: ${fileName} already exists. Use --force to overwrite.`)
652
+ chalk5.red(`Error: ${fileName} already exists. Use --force to overwrite.`)
637
653
  );
638
654
  process.exit(1);
639
655
  }
@@ -720,10 +736,6 @@ async function initAction(options) {
720
736
  ...options.full ? { profile: "default" } : {}
721
737
  },
722
738
  ...options.full ? {
723
- output: {
724
- format: fileExt,
725
- file: "aiready-report.json"
726
- },
727
739
  visualizer: {
728
740
  groupingDirs: ["packages", "src", "lib"],
729
741
  graph: {
@@ -749,33 +761,33 @@ module.exports = ${JSON.stringify(
749
761
  try {
750
762
  writeFileSync2(filePath, content, "utf8");
751
763
  console.log(
752
- chalk4.green(`
753
- \u2705 Created default configuration: ${chalk4.bold(fileName)}`)
764
+ chalk5.green(`
765
+ \u2705 Created default configuration: ${chalk5.bold(fileName)}`)
754
766
  );
755
767
  console.log(
756
- chalk4.cyan("You can now fine-tune your settings and run AIReady with:")
768
+ chalk5.cyan("You can now fine-tune your settings and run AIReady with:")
757
769
  );
758
- console.log(chalk4.white(` $ aiready scan
770
+ console.log(chalk5.white(` $ aiready scan
759
771
  `));
760
772
  } catch (error) {
761
- console.error(chalk4.red(`Failed to write configuration file: ${error}`));
773
+ console.error(chalk5.red(`Failed to write configuration file: ${error}`));
762
774
  process.exit(1);
763
775
  }
764
776
  }
765
777
 
766
778
  // src/commands/patterns.ts
767
- import chalk5 from "chalk";
779
+ import chalk6 from "chalk";
768
780
  import { resolve as resolvePath4 } from "path";
769
781
  import {
770
782
  loadMergedConfig as loadMergedConfig2,
771
783
  handleJSONOutput as handleJSONOutput2,
772
784
  handleCLIError as handleCLIError3,
773
- getElapsedTime as getElapsedTime2,
785
+ getElapsedTime,
774
786
  resolveOutputPath as resolveOutputPath2,
775
- formatToolScore as formatToolScore2
787
+ formatToolScore
776
788
  } from "@aiready/core";
777
789
  async function patternsAction(directory, options) {
778
- console.log(chalk5.blue("\u{1F50D} Analyzing patterns...\n"));
790
+ console.log(chalk6.blue("\u{1F50D} Analyzing patterns...\n"));
779
791
  const startTime = Date.now();
780
792
  const resolvedDir = resolvePath4(process.cwd(), directory || ".");
781
793
  try {
@@ -812,8 +824,10 @@ async function patternsAction(directory, options) {
812
824
  cliOptions
813
825
  );
814
826
  const { analyzePatterns, generateSummary, calculatePatternScore } = await import("@aiready/pattern-detect");
815
- const { results, duplicates } = await analyzePatterns(finalOptions);
816
- const elapsedTime = getElapsedTime2(startTime);
827
+ const { results, duplicates } = await analyzePatterns(
828
+ finalOptions
829
+ );
830
+ const elapsedTime = getElapsedTime(startTime);
817
831
  const summary = generateSummary(results);
818
832
  let patternScore;
819
833
  if (options.score) {
@@ -841,38 +855,38 @@ async function patternsAction(directory, options) {
841
855
  const terminalWidth = process.stdout.columns || 80;
842
856
  const dividerWidth = Math.min(60, terminalWidth - 2);
843
857
  const divider = "\u2501".repeat(dividerWidth);
844
- console.log(chalk5.cyan(divider));
845
- console.log(chalk5.bold.white(" PATTERN ANALYSIS SUMMARY"));
846
- console.log(chalk5.cyan(divider) + "\n");
858
+ console.log(chalk6.cyan(divider));
859
+ console.log(chalk6.bold.white(" PATTERN ANALYSIS SUMMARY"));
860
+ console.log(chalk6.cyan(divider) + "\n");
847
861
  console.log(
848
- chalk5.white(`\u{1F4C1} Files analyzed: ${chalk5.bold(results.length)}`)
862
+ chalk6.white(`\u{1F4C1} Files analyzed: ${chalk6.bold(results.length)}`)
849
863
  );
850
864
  console.log(
851
- chalk5.yellow(
852
- `\u26A0 Duplicate patterns found: ${chalk5.bold(summary.totalPatterns)}`
865
+ chalk6.yellow(
866
+ `\u26A0 Duplicate patterns found: ${chalk6.bold(summary.totalPatterns)}`
853
867
  )
854
868
  );
855
869
  console.log(
856
- chalk5.red(
857
- `\u{1F4B0} Token cost (wasted): ${chalk5.bold(summary.totalTokenCost.toLocaleString())}`
870
+ chalk6.red(
871
+ `\u{1F4B0} Token cost (wasted): ${chalk6.bold(summary.totalTokenCost.toLocaleString())}`
858
872
  )
859
873
  );
860
874
  console.log(
861
- chalk5.gray(`\u23F1 Analysis time: ${chalk5.bold(elapsedTime + "s")}`)
875
+ chalk6.gray(`\u23F1 Analysis time: ${chalk6.bold(elapsedTime + "s")}`)
862
876
  );
863
877
  const sortedTypes = Object.entries(summary.patternsByType || {}).filter(([, count]) => count > 0).sort(([, a], [, b]) => b - a);
864
878
  if (sortedTypes.length > 0) {
865
- console.log(chalk5.cyan("\n" + divider));
866
- console.log(chalk5.bold.white(" PATTERNS BY TYPE"));
867
- console.log(chalk5.cyan(divider) + "\n");
879
+ console.log(chalk6.cyan("\n" + divider));
880
+ console.log(chalk6.bold.white(" PATTERNS BY TYPE"));
881
+ console.log(chalk6.cyan(divider) + "\n");
868
882
  sortedTypes.forEach(([type, count]) => {
869
- console.log(` ${chalk5.white(type.padEnd(15))} ${chalk5.bold(count)}`);
883
+ console.log(` ${chalk6.white(type.padEnd(15))} ${chalk6.bold(count)}`);
870
884
  });
871
885
  }
872
886
  if (summary.totalPatterns > 0 && duplicates.length > 0) {
873
- console.log(chalk5.cyan("\n" + divider));
874
- console.log(chalk5.bold.white(" TOP DUPLICATE PATTERNS"));
875
- console.log(chalk5.cyan(divider) + "\n");
887
+ console.log(chalk6.cyan("\n" + divider));
888
+ console.log(chalk6.bold.white(" TOP DUPLICATE PATTERNS"));
889
+ console.log(chalk6.cyan(divider) + "\n");
876
890
  const topDuplicates = [...duplicates].sort((a, b) => b.similarity - a.similarity).slice(0, 10);
877
891
  topDuplicates.forEach((dup) => {
878
892
  const severity = dup.similarity > 0.95 ? "CRITICAL" : dup.similarity > 0.9 ? "HIGH" : "MEDIUM";
@@ -880,26 +894,26 @@ async function patternsAction(directory, options) {
880
894
  const file1Name = dup.file1.split("/").pop() || dup.file1;
881
895
  const file2Name = dup.file2.split("/").pop() || dup.file2;
882
896
  console.log(
883
- `${severityIcon} ${severity}: ${chalk5.bold(file1Name)} \u2194 ${chalk5.bold(file2Name)}`
897
+ `${severityIcon} ${severity}: ${chalk6.bold(file1Name)} \u2194 ${chalk6.bold(file2Name)}`
884
898
  );
885
899
  console.log(
886
- ` Similarity: ${chalk5.bold(Math.round(dup.similarity * 100) + "%")} | Wasted: ${chalk5.bold(dup.tokenCost.toLocaleString())} tokens each`
900
+ ` Similarity: ${chalk6.bold(Math.round(dup.similarity * 100) + "%")} | Wasted: ${chalk6.bold(dup.tokenCost.toLocaleString())} tokens each`
887
901
  );
888
902
  console.log(
889
- ` Lines: ${chalk5.cyan(dup.line1 + "-" + dup.endLine1)} \u2194 ${chalk5.cyan(dup.line2 + "-" + dup.endLine2)}
903
+ ` Lines: ${chalk6.cyan(dup.line1 + "-" + dup.endLine1)} \u2194 ${chalk6.cyan(dup.line2 + "-" + dup.endLine2)}
890
904
  `
891
905
  );
892
906
  });
893
907
  } else {
894
908
  console.log(
895
- chalk5.green("\n\u2728 Great! No duplicate patterns detected.\n")
909
+ chalk6.green("\n\u2728 Great! No duplicate patterns detected.\n")
896
910
  );
897
911
  }
898
912
  if (patternScore) {
899
- console.log(chalk5.cyan(divider));
900
- console.log(chalk5.bold.white(" AI READINESS SCORE (Patterns)"));
901
- console.log(chalk5.cyan(divider) + "\n");
902
- console.log(formatToolScore2(patternScore));
913
+ console.log(chalk6.cyan(divider));
914
+ console.log(chalk6.bold.white(" AI READINESS SCORE (Patterns)"));
915
+ console.log(chalk6.cyan(divider) + "\n");
916
+ console.log(formatToolScore(patternScore));
903
917
  console.log();
904
918
  }
905
919
  }
@@ -915,18 +929,18 @@ EXAMPLES:
915
929
  `;
916
930
 
917
931
  // src/commands/context.ts
918
- import chalk6 from "chalk";
932
+ import chalk7 from "chalk";
919
933
  import { resolve as resolvePath5 } from "path";
920
934
  import {
921
935
  loadMergedConfig as loadMergedConfig3,
922
936
  handleJSONOutput as handleJSONOutput3,
923
937
  handleCLIError as handleCLIError4,
924
- getElapsedTime as getElapsedTime3,
938
+ getElapsedTime as getElapsedTime2,
925
939
  resolveOutputPath as resolveOutputPath3,
926
- formatToolScore as formatToolScore3
940
+ formatToolScore as formatToolScore2
927
941
  } from "@aiready/core";
928
942
  async function contextAction(directory, options) {
929
- console.log(chalk6.blue("\u{1F9E0} Analyzing context costs...\n"));
943
+ console.log(chalk7.blue("\u{1F9E0} Analyzing context costs...\n"));
930
944
  const startTime = Date.now();
931
945
  const resolvedDir = resolvePath5(process.cwd(), directory || ".");
932
946
  try {
@@ -966,7 +980,7 @@ async function contextAction(directory, options) {
966
980
  console.log("");
967
981
  const { analyzeContext, generateSummary, calculateContextScore } = await import("@aiready/context-analyzer");
968
982
  const results = await analyzeContext(finalOptions);
969
- const elapsedTime = getElapsedTime3(startTime);
983
+ const elapsedTime = getElapsedTime2(startTime);
970
984
  const summary = generateSummary(results);
971
985
  let contextScore;
972
986
  if (options.score) {
@@ -994,85 +1008,85 @@ async function contextAction(directory, options) {
994
1008
  const terminalWidth = process.stdout.columns || 80;
995
1009
  const dividerWidth = Math.min(60, terminalWidth - 2);
996
1010
  const divider = "\u2501".repeat(dividerWidth);
997
- console.log(chalk6.cyan(divider));
998
- console.log(chalk6.bold.white(" CONTEXT ANALYSIS SUMMARY"));
999
- console.log(chalk6.cyan(divider) + "\n");
1011
+ console.log(chalk7.cyan(divider));
1012
+ console.log(chalk7.bold.white(" CONTEXT ANALYSIS SUMMARY"));
1013
+ console.log(chalk7.cyan(divider) + "\n");
1000
1014
  console.log(
1001
- chalk6.white(`\u{1F4C1} Files analyzed: ${chalk6.bold(summary.totalFiles)}`)
1015
+ chalk7.white(`\u{1F4C1} Files analyzed: ${chalk7.bold(summary.totalFiles)}`)
1002
1016
  );
1003
1017
  console.log(
1004
- chalk6.white(
1005
- `\u{1F4CA} Total tokens: ${chalk6.bold(summary.totalTokens.toLocaleString())}`
1018
+ chalk7.white(
1019
+ `\u{1F4CA} Total tokens: ${chalk7.bold(summary.totalTokens.toLocaleString())}`
1006
1020
  )
1007
1021
  );
1008
1022
  console.log(
1009
- chalk6.yellow(
1010
- `\u{1F4B0} Avg context budget: ${chalk6.bold(summary.avgContextBudget.toFixed(0))} tokens/file`
1023
+ chalk7.yellow(
1024
+ `\u{1F4B0} Avg context budget: ${chalk7.bold(summary.avgContextBudget.toFixed(0))} tokens/file`
1011
1025
  )
1012
1026
  );
1013
1027
  console.log(
1014
- chalk6.white(`\u23F1 Analysis time: ${chalk6.bold(elapsedTime + "s")}
1028
+ chalk7.white(`\u23F1 Analysis time: ${chalk7.bold(elapsedTime + "s")}
1015
1029
  `)
1016
1030
  );
1017
1031
  const totalIssues = summary.criticalIssues + summary.majorIssues + summary.minorIssues;
1018
1032
  if (totalIssues > 0) {
1019
- console.log(chalk6.bold("\u26A0\uFE0F Issues Found:\n"));
1033
+ console.log(chalk7.bold("\u26A0\uFE0F Issues Found:\n"));
1020
1034
  if (summary.criticalIssues > 0) {
1021
1035
  console.log(
1022
- chalk6.red(` \u{1F534} Critical: ${chalk6.bold(summary.criticalIssues)}`)
1036
+ chalk7.red(` \u{1F534} Critical: ${chalk7.bold(summary.criticalIssues)}`)
1023
1037
  );
1024
1038
  }
1025
1039
  if (summary.majorIssues > 0) {
1026
1040
  console.log(
1027
- chalk6.yellow(` \u{1F7E1} Major: ${chalk6.bold(summary.majorIssues)}`)
1041
+ chalk7.yellow(` \u{1F7E1} Major: ${chalk7.bold(summary.majorIssues)}`)
1028
1042
  );
1029
1043
  }
1030
1044
  if (summary.minorIssues > 0) {
1031
1045
  console.log(
1032
- chalk6.blue(` \u{1F535} Minor: ${chalk6.bold(summary.minorIssues)}`)
1046
+ chalk7.blue(` \u{1F535} Minor: ${chalk7.bold(summary.minorIssues)}`)
1033
1047
  );
1034
1048
  }
1035
1049
  console.log(
1036
- chalk6.green(
1050
+ chalk7.green(
1037
1051
  `
1038
- \u{1F4A1} Potential savings: ${chalk6.bold(summary.totalPotentialSavings.toLocaleString())} tokens
1052
+ \u{1F4A1} Potential savings: ${chalk7.bold(summary.totalPotentialSavings.toLocaleString())} tokens
1039
1053
  `
1040
1054
  )
1041
1055
  );
1042
1056
  } else {
1043
- console.log(chalk6.green("\u2705 No significant issues found!\n"));
1057
+ console.log(chalk7.green("\u2705 No significant issues found!\n"));
1044
1058
  }
1045
1059
  if (summary.deepFiles.length > 0) {
1046
- console.log(chalk6.bold("\u{1F4CF} Deep Import Chains:\n"));
1060
+ console.log(chalk7.bold("\u{1F4CF} Deep Import Chains:\n"));
1047
1061
  console.log(
1048
- chalk6.gray(` Average depth: ${summary.avgImportDepth.toFixed(1)}`)
1062
+ chalk7.gray(` Average depth: ${summary.avgImportDepth.toFixed(1)}`)
1049
1063
  );
1050
1064
  console.log(
1051
- chalk6.gray(` Maximum depth: ${summary.maxImportDepth}
1065
+ chalk7.gray(` Maximum depth: ${summary.maxImportDepth}
1052
1066
  `)
1053
1067
  );
1054
1068
  summary.deepFiles.slice(0, 10).forEach((item) => {
1055
1069
  const fileName = item.file.split("/").slice(-2).join("/");
1056
1070
  console.log(
1057
- ` ${chalk6.cyan("\u2192")} ${chalk6.white(fileName)} ${chalk6.dim(`(depth: ${item.depth})`)}`
1071
+ ` ${chalk7.cyan("\u2192")} ${chalk7.white(fileName)} ${chalk7.dim(`(depth: ${item.depth})`)}`
1058
1072
  );
1059
1073
  });
1060
1074
  console.log();
1061
1075
  }
1062
1076
  if (summary.fragmentedModules.length > 0) {
1063
- console.log(chalk6.bold("\u{1F9E9} Fragmented Modules:\n"));
1077
+ console.log(chalk7.bold("\u{1F9E9} Fragmented Modules:\n"));
1064
1078
  console.log(
1065
- chalk6.gray(
1079
+ chalk7.gray(
1066
1080
  ` Average fragmentation: ${(summary.avgFragmentation * 100).toFixed(0)}%
1067
1081
  `
1068
1082
  )
1069
1083
  );
1070
1084
  summary.fragmentedModules.slice(0, 10).forEach((module) => {
1071
1085
  console.log(
1072
- ` ${chalk6.yellow("\u25CF")} ${chalk6.white(module.domain)} - ${chalk6.dim(`${module.files.length} files, ${(module.fragmentationScore * 100).toFixed(0)}% scattered`)}`
1086
+ ` ${chalk7.yellow("\u25CF")} ${chalk7.white(module.domain)} - ${chalk7.dim(`${module.files.length} files, ${(module.fragmentationScore * 100).toFixed(0)}% scattered`)}`
1073
1087
  );
1074
1088
  console.log(
1075
- chalk6.dim(
1089
+ chalk7.dim(
1076
1090
  ` Token cost: ${module.totalTokens.toLocaleString()}, Cohesion: ${(module.avgCohesion * 100).toFixed(0)}%`
1077
1091
  )
1078
1092
  );
@@ -1080,9 +1094,9 @@ async function contextAction(directory, options) {
1080
1094
  console.log();
1081
1095
  }
1082
1096
  if (summary.lowCohesionFiles.length > 0) {
1083
- console.log(chalk6.bold("\u{1F500} Low Cohesion Files:\n"));
1097
+ console.log(chalk7.bold("\u{1F500} Low Cohesion Files:\n"));
1084
1098
  console.log(
1085
- chalk6.gray(
1099
+ chalk7.gray(
1086
1100
  ` Average cohesion: ${(summary.avgCohesion * 100).toFixed(0)}%
1087
1101
  `
1088
1102
  )
@@ -1090,29 +1104,29 @@ async function contextAction(directory, options) {
1090
1104
  summary.lowCohesionFiles.slice(0, 10).forEach((item) => {
1091
1105
  const fileName = item.file.split("/").slice(-2).join("/");
1092
1106
  const scorePercent = (item.score * 100).toFixed(0);
1093
- const color = item.score < 0.4 ? chalk6.red : chalk6.yellow;
1107
+ const color = item.score < 0.4 ? chalk7.red : chalk7.yellow;
1094
1108
  console.log(
1095
- ` ${color("\u25CB")} ${chalk6.white(fileName)} ${chalk6.dim(`(${scorePercent}% cohesion)`)}`
1109
+ ` ${color("\u25CB")} ${chalk7.white(fileName)} ${chalk7.dim(`(${scorePercent}% cohesion)`)}`
1096
1110
  );
1097
1111
  });
1098
1112
  console.log();
1099
1113
  }
1100
1114
  if (summary.topExpensiveFiles.length > 0) {
1101
- console.log(chalk6.bold("\u{1F4B8} Most Expensive Files (Context Budget):\n"));
1115
+ console.log(chalk7.bold("\u{1F4B8} Most Expensive Files (Context Budget):\n"));
1102
1116
  summary.topExpensiveFiles.slice(0, 10).forEach((item) => {
1103
1117
  const fileName = item.file.split("/").slice(-2).join("/");
1104
- const severityColor = item.severity === "critical" ? chalk6.red : item.severity === "major" ? chalk6.yellow : chalk6.blue;
1118
+ const severityColor = item.severity === "critical" ? chalk7.red : item.severity === "major" ? chalk7.yellow : chalk7.blue;
1105
1119
  console.log(
1106
- ` ${severityColor("\u25CF")} ${chalk6.white(fileName)} ${chalk6.dim(`(${item.contextBudget.toLocaleString()} tokens)`)}`
1120
+ ` ${severityColor("\u25CF")} ${chalk7.white(fileName)} ${chalk7.dim(`(${item.contextBudget.toLocaleString()} tokens)`)}`
1107
1121
  );
1108
1122
  });
1109
1123
  console.log();
1110
1124
  }
1111
1125
  if (contextScore) {
1112
- console.log(chalk6.cyan(divider));
1113
- console.log(chalk6.bold.white(" AI READINESS SCORE (Context)"));
1114
- console.log(chalk6.cyan(divider) + "\n");
1115
- console.log(formatToolScore3(contextScore));
1126
+ console.log(chalk7.cyan(divider));
1127
+ console.log(chalk7.bold.white(" AI READINESS SCORE (Context)"));
1128
+ console.log(chalk7.cyan(divider) + "\n");
1129
+ console.log(formatToolScore2(contextScore));
1116
1130
  console.log();
1117
1131
  }
1118
1132
  }
@@ -1122,19 +1136,19 @@ async function contextAction(directory, options) {
1122
1136
  }
1123
1137
 
1124
1138
  // src/commands/consistency.ts
1125
- import chalk7 from "chalk";
1139
+ import chalk8 from "chalk";
1126
1140
  import { writeFileSync as writeFileSync3 } from "fs";
1127
1141
  import { resolve as resolvePath6 } from "path";
1128
1142
  import {
1129
1143
  loadMergedConfig as loadMergedConfig4,
1130
1144
  handleJSONOutput as handleJSONOutput4,
1131
1145
  handleCLIError as handleCLIError5,
1132
- getElapsedTime as getElapsedTime4,
1146
+ getElapsedTime as getElapsedTime3,
1133
1147
  resolveOutputPath as resolveOutputPath4,
1134
- formatToolScore as formatToolScore4
1148
+ formatToolScore as formatToolScore3
1135
1149
  } from "@aiready/core";
1136
1150
  async function consistencyAction(directory, options) {
1137
- console.log(chalk7.blue("\u{1F50D} Analyzing consistency...\n"));
1151
+ console.log(chalk8.blue("\u{1F50D} Analyzing consistency...\n"));
1138
1152
  const startTime = Date.now();
1139
1153
  const resolvedDir = resolvePath6(process.cwd(), directory || ".");
1140
1154
  try {
@@ -1158,7 +1172,7 @@ async function consistencyAction(directory, options) {
1158
1172
  });
1159
1173
  const { analyzeConsistency, calculateConsistencyScore } = await import("@aiready/consistency");
1160
1174
  const report = await analyzeConsistency(finalOptions);
1161
- const elapsedTime = getElapsedTime4(startTime);
1175
+ const elapsedTime = getElapsedTime3(startTime);
1162
1176
  let consistencyScore;
1163
1177
  if (options.score) {
1164
1178
  const issues = report.results?.flatMap((r) => r.issues) || [];
@@ -1196,23 +1210,23 @@ async function consistencyAction(directory, options) {
1196
1210
  resolvedDir
1197
1211
  );
1198
1212
  writeFileSync3(outputPath, markdown);
1199
- console.log(chalk7.green(`\u2705 Report saved to ${outputPath}`));
1213
+ console.log(chalk8.green(`\u2705 Report saved to ${outputPath}`));
1200
1214
  } else {
1201
- console.log(chalk7.bold("\n\u{1F4CA} Summary\n"));
1215
+ console.log(chalk8.bold("\n\u{1F4CA} Summary\n"));
1202
1216
  console.log(
1203
- `Files Analyzed: ${chalk7.cyan(report.summary.filesAnalyzed)}`
1217
+ `Files Analyzed: ${chalk8.cyan(report.summary.filesAnalyzed)}`
1204
1218
  );
1205
- console.log(`Total Issues: ${chalk7.yellow(report.summary.totalIssues)}`);
1206
- console.log(` Naming: ${chalk7.yellow(report.summary.namingIssues)}`);
1207
- console.log(` Patterns: ${chalk7.yellow(report.summary.patternIssues)}`);
1219
+ console.log(`Total Issues: ${chalk8.yellow(report.summary.totalIssues)}`);
1220
+ console.log(` Naming: ${chalk8.yellow(report.summary.namingIssues)}`);
1221
+ console.log(` Patterns: ${chalk8.yellow(report.summary.patternIssues)}`);
1208
1222
  console.log(
1209
- ` Architecture: ${chalk7.yellow(report.summary.architectureIssues || 0)}`
1223
+ ` Architecture: ${chalk8.yellow(report.summary.architectureIssues || 0)}`
1210
1224
  );
1211
- console.log(`Analysis Time: ${chalk7.gray(elapsedTime + "s")}
1225
+ console.log(`Analysis Time: ${chalk8.gray(elapsedTime + "s")}
1212
1226
  `);
1213
1227
  if (report.summary.totalIssues === 0) {
1214
1228
  console.log(
1215
- chalk7.green(
1229
+ chalk8.green(
1216
1230
  "\u2728 No consistency issues found! Your codebase is well-maintained.\n"
1217
1231
  )
1218
1232
  );
@@ -1224,20 +1238,20 @@ async function consistencyAction(directory, options) {
1224
1238
  (r) => r.issues.some((i) => i.category === "patterns")
1225
1239
  );
1226
1240
  if (namingResults.length > 0) {
1227
- console.log(chalk7.bold("\u{1F3F7}\uFE0F Naming Issues\n"));
1241
+ console.log(chalk8.bold("\u{1F3F7}\uFE0F Naming Issues\n"));
1228
1242
  let shown = 0;
1229
1243
  for (const result of namingResults) {
1230
1244
  if (shown >= 5) break;
1231
1245
  for (const issue of result.issues) {
1232
1246
  if (shown >= 5) break;
1233
- const severityColor = issue.severity === "critical" ? chalk7.red : issue.severity === "major" ? chalk7.yellow : issue.severity === "minor" ? chalk7.blue : chalk7.gray;
1247
+ const severityColor = issue.severity === "critical" ? chalk8.red : issue.severity === "major" ? chalk8.yellow : issue.severity === "minor" ? chalk8.blue : chalk8.gray;
1234
1248
  console.log(
1235
- `${severityColor(issue.severity.toUpperCase())} ${chalk7.dim(`${issue.location.file}:${issue.location.line}`)}`
1249
+ `${severityColor(issue.severity.toUpperCase())} ${chalk8.dim(`${issue.location.file}:${issue.location.line}`)}`
1236
1250
  );
1237
1251
  console.log(` ${issue.message}`);
1238
1252
  if (issue.suggestion) {
1239
1253
  console.log(
1240
- ` ${chalk7.dim("\u2192")} ${chalk7.italic(issue.suggestion)}`
1254
+ ` ${chalk8.dim("\u2192")} ${chalk8.italic(issue.suggestion)}`
1241
1255
  );
1242
1256
  }
1243
1257
  console.log();
@@ -1246,25 +1260,25 @@ async function consistencyAction(directory, options) {
1246
1260
  }
1247
1261
  const remaining = namingResults.reduce((sum, r) => sum + r.issues.length, 0) - shown;
1248
1262
  if (remaining > 0) {
1249
- console.log(chalk7.dim(` ... and ${remaining} more issues
1263
+ console.log(chalk8.dim(` ... and ${remaining} more issues
1250
1264
  `));
1251
1265
  }
1252
1266
  }
1253
1267
  if (patternResults.length > 0) {
1254
- console.log(chalk7.bold("\u{1F504} Pattern Issues\n"));
1268
+ console.log(chalk8.bold("\u{1F504} Pattern Issues\n"));
1255
1269
  let shown = 0;
1256
1270
  for (const result of patternResults) {
1257
1271
  if (shown >= 5) break;
1258
1272
  for (const issue of result.issues) {
1259
1273
  if (shown >= 5) break;
1260
- const severityColor = issue.severity === "critical" ? chalk7.red : issue.severity === "major" ? chalk7.yellow : issue.severity === "minor" ? chalk7.blue : chalk7.gray;
1274
+ const severityColor = issue.severity === "critical" ? chalk8.red : issue.severity === "major" ? chalk8.yellow : issue.severity === "minor" ? chalk8.blue : chalk8.gray;
1261
1275
  console.log(
1262
- `${severityColor(issue.severity.toUpperCase())} ${chalk7.dim(`${issue.location.file}:${issue.location.line}`)}`
1276
+ `${severityColor(issue.severity.toUpperCase())} ${chalk8.dim(`${issue.location.file}:${issue.location.line}`)}`
1263
1277
  );
1264
1278
  console.log(` ${issue.message}`);
1265
1279
  if (issue.suggestion) {
1266
1280
  console.log(
1267
- ` ${chalk7.dim("\u2192")} ${chalk7.italic(issue.suggestion)}`
1281
+ ` ${chalk8.dim("\u2192")} ${chalk8.italic(issue.suggestion)}`
1268
1282
  );
1269
1283
  }
1270
1284
  console.log();
@@ -1273,12 +1287,12 @@ async function consistencyAction(directory, options) {
1273
1287
  }
1274
1288
  const remaining = patternResults.reduce((sum, r) => sum + r.issues.length, 0) - shown;
1275
1289
  if (remaining > 0) {
1276
- console.log(chalk7.dim(` ... and ${remaining} more issues
1290
+ console.log(chalk8.dim(` ... and ${remaining} more issues
1277
1291
  `));
1278
1292
  }
1279
1293
  }
1280
1294
  if (report.recommendations.length > 0) {
1281
- console.log(chalk7.bold("\u{1F4A1} Recommendations\n"));
1295
+ console.log(chalk8.bold("\u{1F4A1} Recommendations\n"));
1282
1296
  report.recommendations.forEach((rec, i) => {
1283
1297
  console.log(`${i + 1}. ${rec}`);
1284
1298
  });
@@ -1286,8 +1300,8 @@ async function consistencyAction(directory, options) {
1286
1300
  }
1287
1301
  }
1288
1302
  if (consistencyScore) {
1289
- console.log(chalk7.bold("\n\u{1F4CA} AI Readiness Score (Consistency)\n"));
1290
- console.log(formatToolScore4(consistencyScore));
1303
+ console.log(chalk8.bold("\n\u{1F4CA} AI Readiness Score (Consistency)\n"));
1304
+ console.log(formatToolScore3(consistencyScore));
1291
1305
  console.log();
1292
1306
  }
1293
1307
  }
@@ -1297,7 +1311,7 @@ async function consistencyAction(directory, options) {
1297
1311
  }
1298
1312
 
1299
1313
  // src/commands/visualize.ts
1300
- import chalk8 from "chalk";
1314
+ import chalk9 from "chalk";
1301
1315
  import { writeFileSync as writeFileSync4, readFileSync as readFileSync3, existsSync as existsSync3, copyFileSync } from "fs";
1302
1316
  import { resolve as resolvePath7 } from "path";
1303
1317
  import { spawn } from "child_process";
@@ -1312,12 +1326,12 @@ async function visualizeAction(directory, options) {
1312
1326
  if (latestScan) {
1313
1327
  reportPath = latestScan;
1314
1328
  console.log(
1315
- chalk8.dim(`Found latest report: ${latestScan.split("/").pop()}`)
1329
+ chalk9.dim(`Found latest report: ${latestScan.split("/").pop()}`)
1316
1330
  );
1317
1331
  } else {
1318
- console.error(chalk8.red("\u274C No AI readiness report found"));
1332
+ console.error(chalk9.red("\u274C No AI readiness report found"));
1319
1333
  console.log(
1320
- chalk8.dim(
1334
+ chalk9.dim(
1321
1335
  `
1322
1336
  Generate a report with:
1323
1337
  aiready scan --output json
@@ -1447,19 +1461,19 @@ Or specify a custom report:
1447
1461
  return;
1448
1462
  } else {
1449
1463
  console.log(
1450
- chalk8.yellow(
1464
+ chalk9.yellow(
1451
1465
  "\u26A0\uFE0F Dev server not available (requires local @aiready/visualizer with web assets)."
1452
1466
  )
1453
1467
  );
1454
1468
  console.log(
1455
- chalk8.cyan(" Falling back to static HTML generation...\n")
1469
+ chalk9.cyan(" Falling back to static HTML generation...\n")
1456
1470
  );
1457
1471
  useDevMode = false;
1458
1472
  }
1459
1473
  } catch (err) {
1460
1474
  console.error("Failed to start dev server:", err);
1461
1475
  console.log(
1462
- chalk8.cyan(" Falling back to static HTML generation...\n")
1476
+ chalk9.cyan(" Falling back to static HTML generation...\n")
1463
1477
  );
1464
1478
  useDevMode = false;
1465
1479
  }
@@ -1469,7 +1483,7 @@ Or specify a custom report:
1469
1483
  const defaultOutput = "visualization.html";
1470
1484
  const outPath = resolvePath7(dirPath, options.output || defaultOutput);
1471
1485
  writeFileSync4(outPath, html, "utf8");
1472
- console.log(chalk8.green(`\u2705 Visualization written to: ${outPath}`));
1486
+ console.log(chalk9.green(`\u2705 Visualization written to: ${outPath}`));
1473
1487
  if (options.open || options.serve) {
1474
1488
  const opener = process.platform === "darwin" ? "open" : process.platform === "win32" ? "start" : "xdg-open";
1475
1489
  if (options.serve) {
@@ -1499,7 +1513,7 @@ Or specify a custom report:
1499
1513
  server.listen(port, () => {
1500
1514
  const addr = `http://localhost:${port}/`;
1501
1515
  console.log(
1502
- chalk8.cyan(`\u{1F310} Local visualization server running at ${addr}`)
1516
+ chalk9.cyan(`\u{1F310} Local visualization server running at ${addr}`)
1503
1517
  );
1504
1518
  spawn(opener, [`"${addr}"`], { shell: true });
1505
1519
  });
@@ -1546,14 +1560,14 @@ NOTES:
1546
1560
  `;
1547
1561
 
1548
1562
  // src/commands/shared/standard-tool-actions.ts
1549
- import chalk9 from "chalk";
1563
+ import chalk10 from "chalk";
1550
1564
 
1551
1565
  // src/commands/agent-grounding.ts
1552
- import chalk10 from "chalk";
1566
+ import chalk11 from "chalk";
1553
1567
  import { loadConfig as loadConfig2, mergeConfigWithDefaults as mergeConfigWithDefaults2 } from "@aiready/core";
1554
1568
 
1555
1569
  // src/commands/testability.ts
1556
- import chalk11 from "chalk";
1570
+ import chalk12 from "chalk";
1557
1571
  import { loadConfig as loadConfig3, mergeConfigWithDefaults as mergeConfigWithDefaults3 } from "@aiready/core";
1558
1572
  async function testabilityAction(directory, options) {
1559
1573
  const { analyzeTestability, calculateTestabilityScore } = await import("@aiready/testability");
@@ -1578,28 +1592,28 @@ async function testabilityAction(directory, options) {
1578
1592
  "blind-risk": "\u{1F480}"
1579
1593
  };
1580
1594
  const safetyColors = {
1581
- safe: chalk11.green,
1582
- "moderate-risk": chalk11.yellow,
1583
- "high-risk": chalk11.red,
1584
- "blind-risk": chalk11.bgRed.white
1595
+ safe: chalk12.green,
1596
+ "moderate-risk": chalk12.yellow,
1597
+ "high-risk": chalk12.red,
1598
+ "blind-risk": chalk12.bgRed.white
1585
1599
  };
1586
1600
  const safety = report.summary.aiChangeSafetyRating;
1587
1601
  const icon = safetyIcons[safety] ?? "\u2753";
1588
- const color = safetyColors[safety] ?? chalk11.white;
1602
+ const color = safetyColors[safety] ?? chalk12.white;
1589
1603
  console.log(
1590
- ` \u{1F9EA} Testability: ${chalk11.bold(scoring.score + "/100")} (${report.summary.rating})`
1604
+ ` \u{1F9EA} Testability: ${chalk12.bold(scoring.score + "/100")} (${report.summary.rating})`
1591
1605
  );
1592
1606
  console.log(
1593
1607
  ` AI Change Safety: ${color(`${icon} ${safety.toUpperCase()}`)}`
1594
1608
  );
1595
1609
  console.log(
1596
- chalk11.dim(
1610
+ chalk12.dim(
1597
1611
  ` Coverage: ${Math.round(report.summary.coverageRatio * 100)}% (${report.rawData.testFiles} test / ${report.rawData.sourceFiles} source files)`
1598
1612
  )
1599
1613
  );
1600
1614
  if (safety === "blind-risk") {
1601
1615
  console.log(
1602
- chalk11.red.bold(
1616
+ chalk12.red.bold(
1603
1617
  "\n \u26A0\uFE0F NO TESTS \u2014 AI changes to this codebase are completely unverifiable!\n"
1604
1618
  )
1605
1619
  );
@@ -1611,7 +1625,7 @@ async function testabilityAction(directory, options) {
1611
1625
  import { changeAmplificationAction } from "@aiready/change-amplification/dist/cli.js";
1612
1626
 
1613
1627
  // src/commands/bug.ts
1614
- import chalk12 from "chalk";
1628
+ import chalk13 from "chalk";
1615
1629
  import { execSync } from "child_process";
1616
1630
  async function bugAction(message, options) {
1617
1631
  const repoUrl = "https://github.com/caopengau/aiready-cli";
@@ -1629,35 +1643,35 @@ Generated via AIReady CLI 'bug' command.
1629
1643
  Type: ${type}
1630
1644
  `.trim();
1631
1645
  if (options.submit) {
1632
- console.log(chalk12.blue("\u{1F680} Submitting issue via GitHub CLI...\n"));
1646
+ console.log(chalk13.blue("\u{1F680} Submitting issue via GitHub CLI...\n"));
1633
1647
  try {
1634
1648
  execSync("gh auth status", { stdio: "ignore" });
1635
1649
  const command = `gh issue create --repo ${repoSlug} --title ${JSON.stringify(title)} --body ${JSON.stringify(body)} --label ${label}`;
1636
1650
  const output = execSync(command, { encoding: "utf8" }).trim();
1637
- console.log(chalk12.green("\u2705 Issue Created Successfully!"));
1638
- console.log(chalk12.cyan(output));
1651
+ console.log(chalk13.green("\u2705 Issue Created Successfully!"));
1652
+ console.log(chalk13.cyan(output));
1639
1653
  return;
1640
- } catch (error) {
1641
- console.error(chalk12.red("\n\u274C Failed to submit via gh CLI."));
1654
+ } catch {
1655
+ console.error(chalk13.red("\n\u274C Failed to submit via gh CLI."));
1642
1656
  console.log(
1643
- chalk12.yellow(
1657
+ chalk13.yellow(
1644
1658
  ' Make sure gh is installed and run "gh auth login".\n'
1645
1659
  )
1646
1660
  );
1647
- console.log(chalk12.dim(" Falling back to URL generation..."));
1661
+ console.log(chalk13.dim(" Falling back to URL generation..."));
1648
1662
  }
1649
1663
  }
1650
1664
  const template = type === "bug" ? "bug_report.md" : type === "feature" ? "feature_request.md" : "new_metric_idea.md";
1651
1665
  const fullUrl = `${repoUrl}/issues/new?title=${encodeURIComponent(title)}&body=${encodeURIComponent(body)}&labels=${label}&template=${template}`;
1652
- console.log(chalk12.green("\u{1F680} Issue Draft Prepared!\n"));
1653
- console.log(chalk12.bold("Title: ") + title);
1654
- console.log(chalk12.bold("Type: ") + type);
1655
- console.log(chalk12.bold("\nClick the link below to submit this issue:"));
1656
- console.log(chalk12.cyan(fullUrl));
1657
- console.log(chalk12.bold("\n\u{1F916} [FOR AI AGENTS]:"));
1658
- console.log(chalk12.dim(" You have successfully prepared a report."));
1666
+ console.log(chalk13.green("\u{1F680} Issue Draft Prepared!\n"));
1667
+ console.log(chalk13.bold("Title: ") + title);
1668
+ console.log(chalk13.bold("Type: ") + type);
1669
+ console.log(chalk13.bold("\nClick the link below to submit this issue:"));
1670
+ console.log(chalk13.cyan(fullUrl));
1671
+ console.log(chalk13.bold("\n\u{1F916} [FOR AI AGENTS]:"));
1672
+ console.log(chalk13.dim(" You have successfully prepared a report."));
1659
1673
  console.log(
1660
- chalk12.dim(
1674
+ chalk13.dim(
1661
1675
  " Please present the URL above to the user so they can finalize the submission."
1662
1676
  )
1663
1677
  );
@@ -1666,14 +1680,14 @@ Type: ${type}
1666
1680
  const bugUrl = `${repoUrl}/issues/new?template=bug_report.md`;
1667
1681
  const featureUrl = `${repoUrl}/issues/new?template=feature_request.md`;
1668
1682
  const metricUrl = `${repoUrl}/issues/new?template=new_metric_idea.md`;
1669
- console.log(chalk12.blue("\u{1F4AC} Feedback & Bug Reports\n"));
1670
- console.log(` Report a Bug: ${chalk12.cyan(bugUrl)}`);
1671
- console.log(` Request a Feature: ${chalk12.cyan(featureUrl)}`);
1672
- console.log(` Suggest a Metric: ${chalk12.cyan(metricUrl)}`);
1673
- console.log(chalk12.bold("\n\u{1F916} [FOR AI AGENTS]:"));
1674
- console.log(chalk12.dim(" To prepare a specific report, run:"));
1683
+ console.log(chalk13.blue("\u{1F4AC} Feedback & Bug Reports\n"));
1684
+ console.log(` Report a Bug: ${chalk13.cyan(bugUrl)}`);
1685
+ console.log(` Request a Feature: ${chalk13.cyan(featureUrl)}`);
1686
+ console.log(` Suggest a Metric: ${chalk13.cyan(metricUrl)}`);
1687
+ console.log(chalk13.bold("\n\u{1F916} [FOR AI AGENTS]:"));
1688
+ console.log(chalk13.dim(" To prepare a specific report, run:"));
1675
1689
  console.log(
1676
- chalk12.cyan(
1690
+ chalk13.cyan(
1677
1691
  ' aiready bug "your description here" --type bug|feature|metric'
1678
1692
  )
1679
1693
  );