@aiready/cli 0.14.2 → 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.
Files changed (44) hide show
  1. package/.aiready/aiready-report-20260314-164626.json +2 -5
  2. package/.aiready/aiready-report-20260314-164741.json +2 -5
  3. package/.turbo/turbo-build.log +29 -28
  4. package/.turbo/turbo-lint.log +0 -32
  5. package/.turbo/turbo-test.log +35 -125
  6. package/aiready-report.json +30703 -0
  7. package/dist/cli.js +415 -378
  8. package/dist/cli.mjs +358 -320
  9. package/package.json +12 -12
  10. package/packages/core/src/.aiready/aiready-report-20260314-161145.json +4 -10
  11. package/packages/core/src/.aiready/aiready-report-20260314-161152.json +10 -28
  12. package/packages/pattern-detect/src/.aiready/aiready-report-20260314-161139.json +4 -10
  13. package/src/.aiready/aiready-report-20260312-103623.json +3 -9
  14. package/src/.aiready/aiready-report-20260312-110843.json +3 -9
  15. package/src/.aiready/aiready-report-20260312-110955.json +3 -9
  16. package/src/.aiready/aiready-report-20260314-203209.json +3 -9
  17. package/src/.aiready/aiready-report-20260314-203736.json +3 -9
  18. package/src/.aiready/aiready-report-20260314-203857.json +3 -9
  19. package/src/.aiready/aiready-report-20260314-204047.json +3 -9
  20. package/src/__tests__/cli.test.ts +1 -1
  21. package/src/__tests__/config-shape.test.ts +0 -1
  22. package/src/__tests__/unified.test.ts +1 -1
  23. package/src/cli.ts +2 -1
  24. package/src/commands/__tests__/consistency.test.ts +3 -0
  25. package/src/commands/__tests__/extra-commands.test.ts +29 -38
  26. package/src/commands/__tests__/init.test.ts +56 -0
  27. package/src/commands/__tests__/scan.test.ts +4 -2
  28. package/src/commands/__tests__/upload.test.ts +0 -1
  29. package/src/commands/__tests__/visualize.test.ts +3 -7
  30. package/src/commands/ai-signal-clarity.ts +1 -56
  31. package/src/commands/bug.ts +1 -2
  32. package/src/commands/deps-health.ts +1 -65
  33. package/src/commands/doc-drift.ts +1 -62
  34. package/src/commands/init.ts +58 -2
  35. package/src/commands/patterns.ts +3 -1
  36. package/src/commands/report-formatter.ts +128 -0
  37. package/src/commands/scan.ts +29 -120
  38. package/src/commands/shared/configured-tool-action.ts +35 -0
  39. package/src/commands/shared/standard-tool-actions.ts +126 -0
  40. package/src/commands/upload.ts +15 -13
  41. package/src/commands/visualize.ts +11 -4
  42. package/src/index.ts +18 -3
  43. package/src/utils/helpers.ts +86 -37
  44. package/vitest.config.ts +5 -12
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,48 +20,23 @@ 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";
32
28
 
33
29
  // src/utils/helpers.ts
34
30
  import { resolve as resolvePath } from "path";
35
- import { existsSync, readdirSync, statSync, readFileSync } from "fs";
31
+ import { existsSync, readFileSync } from "fs";
36
32
  import chalk from "chalk";
33
+ import { loadConfig, mergeConfigWithDefaults } from "@aiready/core";
34
+ import { findLatestReport } from "@aiready/core";
37
35
  function getReportTimestamp() {
38
36
  const now = /* @__PURE__ */ new Date();
39
37
  const pad = (n) => String(n).padStart(2, "0");
40
38
  return `${now.getFullYear()}${pad(now.getMonth() + 1)}${pad(now.getDate())}-${pad(now.getHours())}${pad(now.getMinutes())}${pad(now.getSeconds())}`;
41
39
  }
42
- function findLatestScanReport(dirPath) {
43
- const aireadyDir = resolvePath(dirPath, ".aiready");
44
- if (!existsSync(aireadyDir)) {
45
- return null;
46
- }
47
- let files = readdirSync(aireadyDir).filter(
48
- (f) => f.startsWith("aiready-report-") && f.endsWith(".json")
49
- );
50
- if (files.length === 0) {
51
- files = readdirSync(aireadyDir).filter(
52
- (f) => f.startsWith("aiready-scan-") && f.endsWith(".json")
53
- );
54
- }
55
- if (files.length === 0) {
56
- return null;
57
- }
58
- const sortedFiles = files.map((f) => ({
59
- name: f,
60
- path: resolvePath(aireadyDir, f),
61
- mtime: statSync(resolvePath(aireadyDir, f)).mtime
62
- })).sort((a, b) => b.mtime.getTime() - a.mtime.getTime());
63
- return sortedFiles[0].path;
64
- }
65
40
  async function warnIfGraphCapExceeded(report, dirPath) {
66
41
  try {
67
42
  const { loadConfig: loadConfig4 } = await import("@aiready/core");
@@ -148,10 +123,102 @@ function generateMarkdownReport(report, elapsedTime) {
148
123
  return markdown;
149
124
  }
150
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
+
151
218
  // src/commands/upload.ts
152
219
  import fs from "fs";
153
220
  import { resolve as resolvePath2 } from "path";
154
- import chalk2 from "chalk";
221
+ import chalk3 from "chalk";
155
222
  import { handleCLIError } from "@aiready/core";
156
223
  async function uploadAction(file, options) {
157
224
  const startTime = Date.now();
@@ -159,31 +226,31 @@ async function uploadAction(file, options) {
159
226
  const serverUrl = options.server || process.env.AIREADY_SERVER || "https://dev.platform.getaiready.dev";
160
227
  const apiKey = options.apiKey || process.env.AIREADY_API_KEY;
161
228
  if (!apiKey) {
162
- console.error(chalk2.red("\u274C API Key is required for upload."));
229
+ console.error(chalk3.red("\u274C API Key is required for upload."));
163
230
  console.log(
164
- chalk2.dim(
231
+ chalk3.dim(
165
232
  " Set AIREADY_API_KEY environment variable or use --api-key flag."
166
233
  )
167
234
  );
168
235
  console.log(
169
- chalk2.dim(
236
+ chalk3.dim(
170
237
  " Get an API key from https://platform.getaiready.dev/dashboard"
171
238
  )
172
239
  );
173
240
  process.exit(1);
174
241
  }
175
242
  if (!fs.existsSync(filePath)) {
176
- console.error(chalk2.red(`\u274C File not found: ${filePath}`));
243
+ console.error(chalk3.red(`\u274C File not found: ${filePath}`));
177
244
  process.exit(1);
178
245
  }
179
246
  try {
180
- console.log(chalk2.blue(`\u{1F680} Uploading report to ${serverUrl}...`));
181
- 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}...`));
182
249
  const reportContent = fs.readFileSync(filePath, "utf-8");
183
250
  const reportData = JSON.parse(reportContent);
184
- console.log(chalk2.dim(` Successfully parsed report JSON.`));
251
+ console.log(chalk3.dim(` Successfully parsed report JSON.`));
185
252
  const repoId = options.repoId || reportData.repository?.repoId;
186
- const res = await fetch(`${serverUrl}/api/analysis/upload`, {
253
+ const response = await fetch(`${serverUrl}/api/analysis/upload`, {
187
254
  method: "POST",
188
255
  headers: {
189
256
  "Content-Type": "application/json",
@@ -195,46 +262,48 @@ async function uploadAction(file, options) {
195
262
  // Might be null, server will handle mapping
196
263
  })
197
264
  });
198
- const contentType = res.headers.get("content-type");
199
- let result = {};
265
+ const contentType = response.headers.get("content-type");
266
+ let uploadResult = {};
200
267
  if (contentType?.includes("application/json")) {
201
- result = await res.json();
268
+ uploadResult = await response.json();
202
269
  } else {
203
- const text = await res.text();
204
- result = { error: text || res.statusText };
270
+ const text = await response.text();
271
+ uploadResult = { error: text || response.statusText };
205
272
  }
206
- if (!res.ok) {
273
+ if (!response.ok) {
207
274
  console.error(
208
- chalk2.red(`\u274C Upload failed: ${result.error || res.statusText}`)
275
+ chalk3.red(
276
+ `\u274C Upload failed: ${uploadResult.error || response.statusText}`
277
+ )
209
278
  );
210
279
  if (contentType?.includes("text/html")) {
211
280
  console.log(
212
- chalk2.yellow(
281
+ chalk3.yellow(
213
282
  " Note: Received an HTML response. This often indicates a redirect (e.g., to a login page) or a server error."
214
283
  )
215
284
  );
216
- if (result.error?.includes("Redirecting")) {
285
+ if (uploadResult.error?.includes("Redirecting")) {
217
286
  console.log(
218
- chalk2.dim(
287
+ chalk3.dim(
219
288
  " Detected redirect. Check if the API endpoint requires authentication or has changed."
220
289
  )
221
290
  );
222
291
  }
223
292
  }
224
- if (res.status === 401) {
293
+ if (response.status === 401) {
225
294
  console.log(
226
- chalk2.dim(" Hint: Your API key may be invalid or expired.")
295
+ chalk3.dim(" Hint: Your API key may be invalid or expired.")
227
296
  );
228
297
  }
229
298
  process.exit(1);
230
299
  }
231
300
  const duration = ((Date.now() - startTime) / 1e3).toFixed(2);
232
- console.log(chalk2.green(`
301
+ console.log(chalk3.green(`
233
302
  \u2705 Upload successful! (${duration}s)`));
234
- console.log(chalk2.cyan(` View results: ${serverUrl}/dashboard`));
235
- if (result.analysis) {
236
- console.log(chalk2.dim(` Analysis ID: ${result.analysis.id}`));
237
- 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`));
238
307
  }
239
308
  } catch (error) {
240
309
  handleCLIError(error, "Upload");
@@ -253,7 +322,7 @@ ENVIRONMENT VARIABLES:
253
322
 
254
323
  // src/commands/scan.ts
255
324
  async function scanAction(directory, options) {
256
- console.log(chalk3.blue("\u{1F680} Starting AIReady unified analysis...\n"));
325
+ console.log(chalk4.blue("\u{1F680} Starting AIReady unified analysis...\n"));
257
326
  const startTime = Date.now();
258
327
  const resolvedDir = resolvePath3(process.cwd(), directory || ".");
259
328
  const repoMetadata = getRepoMetadata(resolvedDir);
@@ -323,7 +392,7 @@ async function scanAction(directory, options) {
323
392
  break;
324
393
  default:
325
394
  console.log(
326
- chalk3.yellow(
395
+ chalk4.yellow(
327
396
  `
328
397
  \u26A0\uFE0F Unknown profile '${options.profile}'. Using defaults.`
329
398
  )
@@ -340,7 +409,7 @@ async function scanAction(directory, options) {
340
409
  defaults,
341
410
  cliOverrides
342
411
  );
343
- let finalOptions = { ...baseOptions };
412
+ const finalOptions = { ...baseOptions };
344
413
  if (baseOptions.tools.includes(ToolName.PatternDetect) || baseOptions.tools.includes("patterns")) {
345
414
  const { getSmartDefaults } = await import("@aiready/pattern-detect");
346
415
  const patternSmartDefaults = await getSmartDefaults(
@@ -353,9 +422,9 @@ async function scanAction(directory, options) {
353
422
  ...finalOptions.toolConfigs[ToolName.PatternDetect]
354
423
  };
355
424
  }
356
- console.log(chalk3.cyan("\n=== AIReady Run Preview ==="));
425
+ console.log(chalk4.cyan("\n=== AIReady Run Preview ==="));
357
426
  console.log(
358
- chalk3.white("Tools to run:"),
427
+ chalk4.white("Tools to run:"),
359
428
  (finalOptions.tools || []).join(", ")
360
429
  );
361
430
  const progressCallback = (event) => {
@@ -364,16 +433,16 @@ async function scanAction(directory, options) {
364
433
  return;
365
434
  }
366
435
  process.stdout.write("\r\x1B[K");
367
- console.log(chalk3.cyan(`--- ${event.tool.toUpperCase()} RESULTS ---`));
436
+ console.log(chalk4.cyan(`--- ${event.tool.toUpperCase()} RESULTS ---`));
368
437
  const res = event.data;
369
438
  if (res && res.summary) {
370
439
  if (res.summary.totalIssues !== void 0)
371
- console.log(` Issues found: ${chalk3.bold(res.summary.totalIssues)}`);
440
+ console.log(` Issues found: ${chalk4.bold(res.summary.totalIssues)}`);
372
441
  if (res.summary.score !== void 0)
373
- console.log(` Tool Score: ${chalk3.bold(res.summary.score)}/100`);
442
+ console.log(` Tool Score: ${chalk4.bold(res.summary.score)}/100`);
374
443
  if (res.summary.totalFiles !== void 0)
375
444
  console.log(
376
- ` Files analyzed: ${chalk3.bold(res.summary.totalFiles)}`
445
+ ` Files analyzed: ${chalk4.bold(res.summary.totalFiles)}`
377
446
  );
378
447
  }
379
448
  };
@@ -385,13 +454,7 @@ async function scanAction(directory, options) {
385
454
  },
386
455
  suppressToolConfig: true
387
456
  });
388
- console.log(chalk3.cyan("\n=== AIReady Run Summary ==="));
389
- console.log(
390
- ` Total issues (all tools): ${chalk3.bold(String(results.summary.totalIssues || 0))}`
391
- );
392
- console.log(
393
- ` Execution time: ${chalk3.bold(((Date.now() - startTime) / 1e3).toFixed(2) + "s")}`
394
- );
457
+ printScanSummary(results, startTime);
395
458
  let scoringResult;
396
459
  if (options.score || finalOptions.scoring?.showBreakdown) {
397
460
  scoringResult = await scoreUnified(results, {
@@ -401,9 +464,7 @@ async function scanAction(directory, options) {
401
464
  profile: scoringProfile
402
465
  }
403
466
  });
404
- console.log(chalk3.bold("\n\u{1F4CA} AI Readiness Overall Score"));
405
- console.log(` ${formatScore(scoringResult)}`);
406
- console.log(chalk3.dim(` (Scoring Profile: ${scoringProfile})`));
467
+ printScoring(scoringResult, scoringProfile);
407
468
  if (options.compareTo) {
408
469
  try {
409
470
  const prevReport = JSON.parse(
@@ -415,19 +476,19 @@ async function scanAction(directory, options) {
415
476
  const diffStr = diff > 0 ? `+${diff}` : String(diff);
416
477
  if (diff > 0)
417
478
  console.log(
418
- chalk3.green(
479
+ chalk4.green(
419
480
  ` \u{1F4C8} Trend: ${diffStr} compared to ${options.compareTo} (${prevScore} \u2192 ${scoringResult.overall})`
420
481
  )
421
482
  );
422
483
  else if (diff < 0)
423
484
  console.log(
424
- chalk3.red(
485
+ chalk4.red(
425
486
  ` \u{1F4C9} Trend: ${diffStr} compared to ${options.compareTo} (${prevScore} \u2192 ${scoringResult.overall})`
426
487
  )
427
488
  );
428
489
  else
429
490
  console.log(
430
- chalk3.blue(
491
+ chalk4.blue(
431
492
  ` \u2796 Trend: No change (${prevScore} \u2192 ${scoringResult.overall})`
432
493
  )
433
494
  );
@@ -476,19 +537,7 @@ async function scanAction(directory, options) {
476
537
  issues: allIssues,
477
538
  modelId
478
539
  });
479
- console.log(chalk3.bold("\n\u{1F4B0} Business Impact Analysis (Monthly)"));
480
- console.log(
481
- ` Potential Savings: ${chalk3.green(chalk3.bold("$" + roi.monthlySavings.toLocaleString()))}`
482
- );
483
- console.log(
484
- ` Productivity Gain: ${chalk3.cyan(chalk3.bold(roi.productivityGainHours + "h"))} (est. dev time)`
485
- );
486
- console.log(
487
- ` Context Efficiency: ${chalk3.yellow((unifiedBudget.efficiencyRatio * 100).toFixed(0) + "%")}`
488
- );
489
- console.log(
490
- ` Annual Value: ${chalk3.bold("$" + roi.annualValue.toLocaleString())} (ROI Prediction)`
491
- );
540
+ printBusinessImpact(roi, unifiedBudget);
492
541
  results.summary.businessImpact = {
493
542
  estimatedMonthlyWaste: roi.monthlySavings,
494
543
  potentialSavings: roi.monthlySavings,
@@ -497,78 +546,24 @@ async function scanAction(directory, options) {
497
546
  scoringResult.tokenBudget = unifiedBudget;
498
547
  scoringResult.businessROI = roi;
499
548
  }
500
- if (scoringResult.breakdown) {
501
- console.log(chalk3.bold("\nTool breakdown:"));
502
- scoringResult.breakdown.forEach((tool) => {
503
- const rating = getRating(tool.score);
504
- const emoji = getRatingDisplay(rating).emoji;
505
- console.log(
506
- ` - ${tool.toolName}: ${tool.score}/100 (${rating}) ${emoji}`
507
- );
508
- });
509
- const allRecs = scoringResult.breakdown.flatMap(
510
- (t) => (t.recommendations || []).map((r) => ({ ...r, tool: t.toolName }))
511
- ).sort((a, b) => b.estimatedImpact - a.estimatedImpact).slice(0, 3);
512
- if (allRecs.length > 0) {
513
- console.log(chalk3.bold("\n\u{1F3AF} Top Actionable Recommendations:"));
514
- allRecs.forEach((rec, i) => {
515
- const priorityIcon = rec.priority === "high" ? "\u{1F534}" : rec.priority === "medium" ? "\u{1F7E1}" : "\u{1F535}";
516
- console.log(
517
- ` ${i + 1}. ${priorityIcon} ${chalk3.bold(rec.action)}`
518
- );
519
- console.log(
520
- ` Impact: ${chalk3.green(`+${rec.estimatedImpact} points`)} to ${rec.tool}`
521
- );
522
- });
523
- }
524
- }
525
549
  }
526
550
  console.log(
527
- chalk3.dim(
551
+ chalk4.dim(
528
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"
529
553
  )
530
554
  );
531
- console.log(chalk3.dim("\u{1F4AC} Found a bug or have a metric idea?"));
532
- 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:"));
533
557
  console.log(
534
- chalk3.cyan(
558
+ chalk4.cyan(
535
559
  ` "Any feedback for the tools? Please use 'aiready bug' to report \u2764\uFE0F"`
536
560
  )
537
561
  );
538
562
  console.log(
539
- chalk3.dim(
563
+ chalk4.dim(
540
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"
541
565
  )
542
566
  );
543
- const mapToUnifiedReport = (res, scoring) => {
544
- const allResults = [];
545
- const totalFilesSet = /* @__PURE__ */ new Set();
546
- let criticalCount = 0;
547
- let majorCount = 0;
548
- res.summary.toolsRun.forEach((toolId) => {
549
- const spokeRes = res[toolId];
550
- if (!spokeRes || !spokeRes.results) return;
551
- spokeRes.results.forEach((r) => {
552
- totalFilesSet.add(r.fileName);
553
- allResults.push(r);
554
- r.issues?.forEach((i) => {
555
- if (i.severity === Severity.Critical) criticalCount++;
556
- if (i.severity === Severity.Major) majorCount++;
557
- });
558
- });
559
- });
560
- return {
561
- ...res,
562
- results: allResults,
563
- summary: {
564
- ...res.summary,
565
- totalFiles: totalFilesSet.size,
566
- criticalIssues: criticalCount,
567
- majorIssues: majorCount
568
- },
569
- scoring
570
- };
571
- };
572
567
  const outputData = {
573
568
  ...mapToUnifiedReport(results, scoringResult),
574
569
  repository: repoMetadata
@@ -588,7 +583,7 @@ async function scanAction(directory, options) {
588
583
  } else {
589
584
  try {
590
585
  writeFileSync(outputPath, JSON.stringify(outputData, null, 2));
591
- console.log(chalk3.dim(`\u2705 Report auto-persisted to ${outputPath}`));
586
+ console.log(chalk4.dim(`\u2705 Report auto-persisted to ${outputPath}`));
592
587
  } catch (err) {
593
588
  void err;
594
589
  }
@@ -600,16 +595,16 @@ async function scanAction(directory, options) {
600
595
  });
601
596
  }
602
597
  await warnIfGraphCapExceeded(outputData, resolvedDir);
603
- const isCI = options.ci || process.env.CI === "true";
604
- if (isCI && scoringResult) {
598
+ if (scoringResult) {
605
599
  const threshold = options.threshold ? parseInt(options.threshold) : void 0;
606
600
  const failOnLevel = options.failOn || "critical";
601
+ const isCI = options.ci || process.env.CI === "true";
607
602
  let shouldFail = false;
608
603
  let failReason = "";
609
604
  const report = mapToUnifiedReport(results, scoringResult);
610
- if (report.results && report.results.length > 0) {
605
+ if (isCI && report.results && report.results.length > 0) {
611
606
  console.log(
612
- chalk3.cyan(
607
+ chalk4.cyan(
613
608
  `
614
609
  \u{1F4DD} Emitting GitHub Action annotations for ${report.results.length} issues...`
615
610
  )
@@ -630,11 +625,11 @@ async function scanAction(directory, options) {
630
625
  }
631
626
  }
632
627
  if (shouldFail) {
633
- console.log(chalk3.red(`
634
- \u{1F6AB} PR BLOCKED: ${failReason}`));
628
+ console.log(chalk4.red(`
629
+ \u{1F6AB} SCAN FAILED: ${failReason}`));
635
630
  process.exit(1);
636
631
  } else {
637
- console.log(chalk3.green("\n\u2705 PR PASSED"));
632
+ console.log(chalk4.green("\n\u2705 SCAN PASSED"));
638
633
  }
639
634
  }
640
635
  } catch (error) {
@@ -646,7 +641,7 @@ var scanHelpText = `...`;
646
641
  // src/commands/init.ts
647
642
  import { writeFileSync as writeFileSync2, existsSync as existsSync2 } from "fs";
648
643
  import { join } from "path";
649
- import chalk4 from "chalk";
644
+ import chalk5 from "chalk";
650
645
  import { ToolName as ToolName2 } from "@aiready/core";
651
646
  async function initAction(options) {
652
647
  const fileExt = options.format === "js" ? "js" : "json";
@@ -654,11 +649,11 @@ async function initAction(options) {
654
649
  const filePath = join(process.cwd(), fileName);
655
650
  if (existsSync2(filePath) && !options.force) {
656
651
  console.error(
657
- chalk4.red(`Error: ${fileName} already exists. Use --force to overwrite.`)
652
+ chalk5.red(`Error: ${fileName} already exists. Use --force to overwrite.`)
658
653
  );
659
654
  process.exit(1);
660
655
  }
661
- const defaultConfig = {
656
+ const baseConfig = {
662
657
  scan: {
663
658
  include: [
664
659
  "src/**/*.ts",
@@ -688,28 +683,70 @@ async function initAction(options) {
688
683
  tools: {
689
684
  [ToolName2.PatternDetect]: {
690
685
  minSimilarity: 0.8,
691
- minLines: 5
686
+ minLines: 5,
687
+ ...options.full ? {
688
+ batchSize: 50,
689
+ approx: true,
690
+ minSharedTokens: 10,
691
+ maxCandidatesPerBlock: 100
692
+ } : {}
692
693
  },
693
694
  [ToolName2.ContextAnalyzer]: {
694
695
  maxContextBudget: 128e3,
695
- minCohesion: 0.6
696
+ minCohesion: 0.6,
697
+ ...options.full ? {
698
+ maxDepth: 7,
699
+ maxFragmentation: 0.4,
700
+ focus: "all",
701
+ includeNodeModules: false
702
+ } : {}
696
703
  },
697
704
  [ToolName2.NamingConsistency]: {
698
- shortWords: ["id", "db", "ui", "ai"]
705
+ shortWords: ["id", "db", "ui", "ai"],
706
+ ...options.full ? { acceptedAbbreviations: [], disableChecks: [] } : {}
699
707
  },
700
708
  [ToolName2.AiSignalClarity]: {
701
709
  checkMagicLiterals: true,
702
710
  checkBooleanTraps: true,
703
711
  checkAmbiguousNames: true,
704
- checkUndocumentedExports: true
705
- }
712
+ checkUndocumentedExports: true,
713
+ ...options.full ? { checkImplicitSideEffects: false, checkDeepCallbacks: false } : {}
714
+ },
715
+ ...options.full ? {
716
+ [ToolName2.AgentGrounding]: {
717
+ maxRecommendedDepth: 5,
718
+ readmeStaleDays: 30
719
+ },
720
+ [ToolName2.TestabilityIndex]: {
721
+ minCoverageRatio: 0.7,
722
+ testPatterns: ["**/*.test.ts", "**/__tests__/**"]
723
+ },
724
+ [ToolName2.DocDrift]: {
725
+ maxCommits: 50,
726
+ staleMonths: 3
727
+ },
728
+ [ToolName2.DependencyHealth]: {
729
+ trainingCutoffYear: 2023
730
+ }
731
+ } : {}
706
732
  },
707
733
  scoring: {
708
734
  threshold: 70,
709
- showBreakdown: true
710
- }
735
+ showBreakdown: true,
736
+ ...options.full ? { profile: "default" } : {}
737
+ },
738
+ ...options.full ? {
739
+ visualizer: {
740
+ groupingDirs: ["packages", "src", "lib"],
741
+ graph: {
742
+ maxNodes: 5e3,
743
+ maxEdges: 1e4
744
+ }
745
+ }
746
+ } : {}
711
747
  };
712
- let content = "";
748
+ const defaultConfig = baseConfig;
749
+ let content;
713
750
  if (fileExt === "js") {
714
751
  content = `/** @type {import('@aiready/core').AIReadyConfig} */
715
752
  module.exports = ${JSON.stringify(
@@ -724,33 +761,33 @@ module.exports = ${JSON.stringify(
724
761
  try {
725
762
  writeFileSync2(filePath, content, "utf8");
726
763
  console.log(
727
- chalk4.green(`
728
- \u2705 Created default configuration: ${chalk4.bold(fileName)}`)
764
+ chalk5.green(`
765
+ \u2705 Created default configuration: ${chalk5.bold(fileName)}`)
729
766
  );
730
767
  console.log(
731
- 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:")
732
769
  );
733
- console.log(chalk4.white(` $ aiready scan
770
+ console.log(chalk5.white(` $ aiready scan
734
771
  `));
735
772
  } catch (error) {
736
- console.error(chalk4.red(`Failed to write configuration file: ${error}`));
773
+ console.error(chalk5.red(`Failed to write configuration file: ${error}`));
737
774
  process.exit(1);
738
775
  }
739
776
  }
740
777
 
741
778
  // src/commands/patterns.ts
742
- import chalk5 from "chalk";
779
+ import chalk6 from "chalk";
743
780
  import { resolve as resolvePath4 } from "path";
744
781
  import {
745
782
  loadMergedConfig as loadMergedConfig2,
746
783
  handleJSONOutput as handleJSONOutput2,
747
784
  handleCLIError as handleCLIError3,
748
- getElapsedTime as getElapsedTime2,
785
+ getElapsedTime,
749
786
  resolveOutputPath as resolveOutputPath2,
750
- formatToolScore as formatToolScore2
787
+ formatToolScore
751
788
  } from "@aiready/core";
752
789
  async function patternsAction(directory, options) {
753
- console.log(chalk5.blue("\u{1F50D} Analyzing patterns...\n"));
790
+ console.log(chalk6.blue("\u{1F50D} Analyzing patterns...\n"));
754
791
  const startTime = Date.now();
755
792
  const resolvedDir = resolvePath4(process.cwd(), directory || ".");
756
793
  try {
@@ -787,8 +824,10 @@ async function patternsAction(directory, options) {
787
824
  cliOptions
788
825
  );
789
826
  const { analyzePatterns, generateSummary, calculatePatternScore } = await import("@aiready/pattern-detect");
790
- const { results, duplicates } = await analyzePatterns(finalOptions);
791
- const elapsedTime = getElapsedTime2(startTime);
827
+ const { results, duplicates } = await analyzePatterns(
828
+ finalOptions
829
+ );
830
+ const elapsedTime = getElapsedTime(startTime);
792
831
  const summary = generateSummary(results);
793
832
  let patternScore;
794
833
  if (options.score) {
@@ -816,38 +855,38 @@ async function patternsAction(directory, options) {
816
855
  const terminalWidth = process.stdout.columns || 80;
817
856
  const dividerWidth = Math.min(60, terminalWidth - 2);
818
857
  const divider = "\u2501".repeat(dividerWidth);
819
- console.log(chalk5.cyan(divider));
820
- console.log(chalk5.bold.white(" PATTERN ANALYSIS SUMMARY"));
821
- 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");
822
861
  console.log(
823
- chalk5.white(`\u{1F4C1} Files analyzed: ${chalk5.bold(results.length)}`)
862
+ chalk6.white(`\u{1F4C1} Files analyzed: ${chalk6.bold(results.length)}`)
824
863
  );
825
864
  console.log(
826
- chalk5.yellow(
827
- `\u26A0 Duplicate patterns found: ${chalk5.bold(summary.totalPatterns)}`
865
+ chalk6.yellow(
866
+ `\u26A0 Duplicate patterns found: ${chalk6.bold(summary.totalPatterns)}`
828
867
  )
829
868
  );
830
869
  console.log(
831
- chalk5.red(
832
- `\u{1F4B0} Token cost (wasted): ${chalk5.bold(summary.totalTokenCost.toLocaleString())}`
870
+ chalk6.red(
871
+ `\u{1F4B0} Token cost (wasted): ${chalk6.bold(summary.totalTokenCost.toLocaleString())}`
833
872
  )
834
873
  );
835
874
  console.log(
836
- chalk5.gray(`\u23F1 Analysis time: ${chalk5.bold(elapsedTime + "s")}`)
875
+ chalk6.gray(`\u23F1 Analysis time: ${chalk6.bold(elapsedTime + "s")}`)
837
876
  );
838
877
  const sortedTypes = Object.entries(summary.patternsByType || {}).filter(([, count]) => count > 0).sort(([, a], [, b]) => b - a);
839
878
  if (sortedTypes.length > 0) {
840
- console.log(chalk5.cyan("\n" + divider));
841
- console.log(chalk5.bold.white(" PATTERNS BY TYPE"));
842
- 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");
843
882
  sortedTypes.forEach(([type, count]) => {
844
- console.log(` ${chalk5.white(type.padEnd(15))} ${chalk5.bold(count)}`);
883
+ console.log(` ${chalk6.white(type.padEnd(15))} ${chalk6.bold(count)}`);
845
884
  });
846
885
  }
847
886
  if (summary.totalPatterns > 0 && duplicates.length > 0) {
848
- console.log(chalk5.cyan("\n" + divider));
849
- console.log(chalk5.bold.white(" TOP DUPLICATE PATTERNS"));
850
- 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");
851
890
  const topDuplicates = [...duplicates].sort((a, b) => b.similarity - a.similarity).slice(0, 10);
852
891
  topDuplicates.forEach((dup) => {
853
892
  const severity = dup.similarity > 0.95 ? "CRITICAL" : dup.similarity > 0.9 ? "HIGH" : "MEDIUM";
@@ -855,26 +894,26 @@ async function patternsAction(directory, options) {
855
894
  const file1Name = dup.file1.split("/").pop() || dup.file1;
856
895
  const file2Name = dup.file2.split("/").pop() || dup.file2;
857
896
  console.log(
858
- `${severityIcon} ${severity}: ${chalk5.bold(file1Name)} \u2194 ${chalk5.bold(file2Name)}`
897
+ `${severityIcon} ${severity}: ${chalk6.bold(file1Name)} \u2194 ${chalk6.bold(file2Name)}`
859
898
  );
860
899
  console.log(
861
- ` 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`
862
901
  );
863
902
  console.log(
864
- ` 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)}
865
904
  `
866
905
  );
867
906
  });
868
907
  } else {
869
908
  console.log(
870
- chalk5.green("\n\u2728 Great! No duplicate patterns detected.\n")
909
+ chalk6.green("\n\u2728 Great! No duplicate patterns detected.\n")
871
910
  );
872
911
  }
873
912
  if (patternScore) {
874
- console.log(chalk5.cyan(divider));
875
- console.log(chalk5.bold.white(" AI READINESS SCORE (Patterns)"));
876
- console.log(chalk5.cyan(divider) + "\n");
877
- 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));
878
917
  console.log();
879
918
  }
880
919
  }
@@ -890,18 +929,18 @@ EXAMPLES:
890
929
  `;
891
930
 
892
931
  // src/commands/context.ts
893
- import chalk6 from "chalk";
932
+ import chalk7 from "chalk";
894
933
  import { resolve as resolvePath5 } from "path";
895
934
  import {
896
935
  loadMergedConfig as loadMergedConfig3,
897
936
  handleJSONOutput as handleJSONOutput3,
898
937
  handleCLIError as handleCLIError4,
899
- getElapsedTime as getElapsedTime3,
938
+ getElapsedTime as getElapsedTime2,
900
939
  resolveOutputPath as resolveOutputPath3,
901
- formatToolScore as formatToolScore3
940
+ formatToolScore as formatToolScore2
902
941
  } from "@aiready/core";
903
942
  async function contextAction(directory, options) {
904
- console.log(chalk6.blue("\u{1F9E0} Analyzing context costs...\n"));
943
+ console.log(chalk7.blue("\u{1F9E0} Analyzing context costs...\n"));
905
944
  const startTime = Date.now();
906
945
  const resolvedDir = resolvePath5(process.cwd(), directory || ".");
907
946
  try {
@@ -941,7 +980,7 @@ async function contextAction(directory, options) {
941
980
  console.log("");
942
981
  const { analyzeContext, generateSummary, calculateContextScore } = await import("@aiready/context-analyzer");
943
982
  const results = await analyzeContext(finalOptions);
944
- const elapsedTime = getElapsedTime3(startTime);
983
+ const elapsedTime = getElapsedTime2(startTime);
945
984
  const summary = generateSummary(results);
946
985
  let contextScore;
947
986
  if (options.score) {
@@ -969,85 +1008,85 @@ async function contextAction(directory, options) {
969
1008
  const terminalWidth = process.stdout.columns || 80;
970
1009
  const dividerWidth = Math.min(60, terminalWidth - 2);
971
1010
  const divider = "\u2501".repeat(dividerWidth);
972
- console.log(chalk6.cyan(divider));
973
- console.log(chalk6.bold.white(" CONTEXT ANALYSIS SUMMARY"));
974
- 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");
975
1014
  console.log(
976
- chalk6.white(`\u{1F4C1} Files analyzed: ${chalk6.bold(summary.totalFiles)}`)
1015
+ chalk7.white(`\u{1F4C1} Files analyzed: ${chalk7.bold(summary.totalFiles)}`)
977
1016
  );
978
1017
  console.log(
979
- chalk6.white(
980
- `\u{1F4CA} Total tokens: ${chalk6.bold(summary.totalTokens.toLocaleString())}`
1018
+ chalk7.white(
1019
+ `\u{1F4CA} Total tokens: ${chalk7.bold(summary.totalTokens.toLocaleString())}`
981
1020
  )
982
1021
  );
983
1022
  console.log(
984
- chalk6.yellow(
985
- `\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`
986
1025
  )
987
1026
  );
988
1027
  console.log(
989
- chalk6.white(`\u23F1 Analysis time: ${chalk6.bold(elapsedTime + "s")}
1028
+ chalk7.white(`\u23F1 Analysis time: ${chalk7.bold(elapsedTime + "s")}
990
1029
  `)
991
1030
  );
992
1031
  const totalIssues = summary.criticalIssues + summary.majorIssues + summary.minorIssues;
993
1032
  if (totalIssues > 0) {
994
- console.log(chalk6.bold("\u26A0\uFE0F Issues Found:\n"));
1033
+ console.log(chalk7.bold("\u26A0\uFE0F Issues Found:\n"));
995
1034
  if (summary.criticalIssues > 0) {
996
1035
  console.log(
997
- chalk6.red(` \u{1F534} Critical: ${chalk6.bold(summary.criticalIssues)}`)
1036
+ chalk7.red(` \u{1F534} Critical: ${chalk7.bold(summary.criticalIssues)}`)
998
1037
  );
999
1038
  }
1000
1039
  if (summary.majorIssues > 0) {
1001
1040
  console.log(
1002
- chalk6.yellow(` \u{1F7E1} Major: ${chalk6.bold(summary.majorIssues)}`)
1041
+ chalk7.yellow(` \u{1F7E1} Major: ${chalk7.bold(summary.majorIssues)}`)
1003
1042
  );
1004
1043
  }
1005
1044
  if (summary.minorIssues > 0) {
1006
1045
  console.log(
1007
- chalk6.blue(` \u{1F535} Minor: ${chalk6.bold(summary.minorIssues)}`)
1046
+ chalk7.blue(` \u{1F535} Minor: ${chalk7.bold(summary.minorIssues)}`)
1008
1047
  );
1009
1048
  }
1010
1049
  console.log(
1011
- chalk6.green(
1050
+ chalk7.green(
1012
1051
  `
1013
- \u{1F4A1} Potential savings: ${chalk6.bold(summary.totalPotentialSavings.toLocaleString())} tokens
1052
+ \u{1F4A1} Potential savings: ${chalk7.bold(summary.totalPotentialSavings.toLocaleString())} tokens
1014
1053
  `
1015
1054
  )
1016
1055
  );
1017
1056
  } else {
1018
- console.log(chalk6.green("\u2705 No significant issues found!\n"));
1057
+ console.log(chalk7.green("\u2705 No significant issues found!\n"));
1019
1058
  }
1020
1059
  if (summary.deepFiles.length > 0) {
1021
- console.log(chalk6.bold("\u{1F4CF} Deep Import Chains:\n"));
1060
+ console.log(chalk7.bold("\u{1F4CF} Deep Import Chains:\n"));
1022
1061
  console.log(
1023
- chalk6.gray(` Average depth: ${summary.avgImportDepth.toFixed(1)}`)
1062
+ chalk7.gray(` Average depth: ${summary.avgImportDepth.toFixed(1)}`)
1024
1063
  );
1025
1064
  console.log(
1026
- chalk6.gray(` Maximum depth: ${summary.maxImportDepth}
1065
+ chalk7.gray(` Maximum depth: ${summary.maxImportDepth}
1027
1066
  `)
1028
1067
  );
1029
1068
  summary.deepFiles.slice(0, 10).forEach((item) => {
1030
1069
  const fileName = item.file.split("/").slice(-2).join("/");
1031
1070
  console.log(
1032
- ` ${chalk6.cyan("\u2192")} ${chalk6.white(fileName)} ${chalk6.dim(`(depth: ${item.depth})`)}`
1071
+ ` ${chalk7.cyan("\u2192")} ${chalk7.white(fileName)} ${chalk7.dim(`(depth: ${item.depth})`)}`
1033
1072
  );
1034
1073
  });
1035
1074
  console.log();
1036
1075
  }
1037
1076
  if (summary.fragmentedModules.length > 0) {
1038
- console.log(chalk6.bold("\u{1F9E9} Fragmented Modules:\n"));
1077
+ console.log(chalk7.bold("\u{1F9E9} Fragmented Modules:\n"));
1039
1078
  console.log(
1040
- chalk6.gray(
1079
+ chalk7.gray(
1041
1080
  ` Average fragmentation: ${(summary.avgFragmentation * 100).toFixed(0)}%
1042
1081
  `
1043
1082
  )
1044
1083
  );
1045
1084
  summary.fragmentedModules.slice(0, 10).forEach((module) => {
1046
1085
  console.log(
1047
- ` ${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`)}`
1048
1087
  );
1049
1088
  console.log(
1050
- chalk6.dim(
1089
+ chalk7.dim(
1051
1090
  ` Token cost: ${module.totalTokens.toLocaleString()}, Cohesion: ${(module.avgCohesion * 100).toFixed(0)}%`
1052
1091
  )
1053
1092
  );
@@ -1055,9 +1094,9 @@ async function contextAction(directory, options) {
1055
1094
  console.log();
1056
1095
  }
1057
1096
  if (summary.lowCohesionFiles.length > 0) {
1058
- console.log(chalk6.bold("\u{1F500} Low Cohesion Files:\n"));
1097
+ console.log(chalk7.bold("\u{1F500} Low Cohesion Files:\n"));
1059
1098
  console.log(
1060
- chalk6.gray(
1099
+ chalk7.gray(
1061
1100
  ` Average cohesion: ${(summary.avgCohesion * 100).toFixed(0)}%
1062
1101
  `
1063
1102
  )
@@ -1065,29 +1104,29 @@ async function contextAction(directory, options) {
1065
1104
  summary.lowCohesionFiles.slice(0, 10).forEach((item) => {
1066
1105
  const fileName = item.file.split("/").slice(-2).join("/");
1067
1106
  const scorePercent = (item.score * 100).toFixed(0);
1068
- const color = item.score < 0.4 ? chalk6.red : chalk6.yellow;
1107
+ const color = item.score < 0.4 ? chalk7.red : chalk7.yellow;
1069
1108
  console.log(
1070
- ` ${color("\u25CB")} ${chalk6.white(fileName)} ${chalk6.dim(`(${scorePercent}% cohesion)`)}`
1109
+ ` ${color("\u25CB")} ${chalk7.white(fileName)} ${chalk7.dim(`(${scorePercent}% cohesion)`)}`
1071
1110
  );
1072
1111
  });
1073
1112
  console.log();
1074
1113
  }
1075
1114
  if (summary.topExpensiveFiles.length > 0) {
1076
- 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"));
1077
1116
  summary.topExpensiveFiles.slice(0, 10).forEach((item) => {
1078
1117
  const fileName = item.file.split("/").slice(-2).join("/");
1079
- 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;
1080
1119
  console.log(
1081
- ` ${severityColor("\u25CF")} ${chalk6.white(fileName)} ${chalk6.dim(`(${item.contextBudget.toLocaleString()} tokens)`)}`
1120
+ ` ${severityColor("\u25CF")} ${chalk7.white(fileName)} ${chalk7.dim(`(${item.contextBudget.toLocaleString()} tokens)`)}`
1082
1121
  );
1083
1122
  });
1084
1123
  console.log();
1085
1124
  }
1086
1125
  if (contextScore) {
1087
- console.log(chalk6.cyan(divider));
1088
- console.log(chalk6.bold.white(" AI READINESS SCORE (Context)"));
1089
- console.log(chalk6.cyan(divider) + "\n");
1090
- 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));
1091
1130
  console.log();
1092
1131
  }
1093
1132
  }
@@ -1097,19 +1136,19 @@ async function contextAction(directory, options) {
1097
1136
  }
1098
1137
 
1099
1138
  // src/commands/consistency.ts
1100
- import chalk7 from "chalk";
1139
+ import chalk8 from "chalk";
1101
1140
  import { writeFileSync as writeFileSync3 } from "fs";
1102
1141
  import { resolve as resolvePath6 } from "path";
1103
1142
  import {
1104
1143
  loadMergedConfig as loadMergedConfig4,
1105
1144
  handleJSONOutput as handleJSONOutput4,
1106
1145
  handleCLIError as handleCLIError5,
1107
- getElapsedTime as getElapsedTime4,
1146
+ getElapsedTime as getElapsedTime3,
1108
1147
  resolveOutputPath as resolveOutputPath4,
1109
- formatToolScore as formatToolScore4
1148
+ formatToolScore as formatToolScore3
1110
1149
  } from "@aiready/core";
1111
1150
  async function consistencyAction(directory, options) {
1112
- console.log(chalk7.blue("\u{1F50D} Analyzing consistency...\n"));
1151
+ console.log(chalk8.blue("\u{1F50D} Analyzing consistency...\n"));
1113
1152
  const startTime = Date.now();
1114
1153
  const resolvedDir = resolvePath6(process.cwd(), directory || ".");
1115
1154
  try {
@@ -1133,7 +1172,7 @@ async function consistencyAction(directory, options) {
1133
1172
  });
1134
1173
  const { analyzeConsistency, calculateConsistencyScore } = await import("@aiready/consistency");
1135
1174
  const report = await analyzeConsistency(finalOptions);
1136
- const elapsedTime = getElapsedTime4(startTime);
1175
+ const elapsedTime = getElapsedTime3(startTime);
1137
1176
  let consistencyScore;
1138
1177
  if (options.score) {
1139
1178
  const issues = report.results?.flatMap((r) => r.issues) || [];
@@ -1171,23 +1210,23 @@ async function consistencyAction(directory, options) {
1171
1210
  resolvedDir
1172
1211
  );
1173
1212
  writeFileSync3(outputPath, markdown);
1174
- console.log(chalk7.green(`\u2705 Report saved to ${outputPath}`));
1213
+ console.log(chalk8.green(`\u2705 Report saved to ${outputPath}`));
1175
1214
  } else {
1176
- console.log(chalk7.bold("\n\u{1F4CA} Summary\n"));
1215
+ console.log(chalk8.bold("\n\u{1F4CA} Summary\n"));
1177
1216
  console.log(
1178
- `Files Analyzed: ${chalk7.cyan(report.summary.filesAnalyzed)}`
1217
+ `Files Analyzed: ${chalk8.cyan(report.summary.filesAnalyzed)}`
1179
1218
  );
1180
- console.log(`Total Issues: ${chalk7.yellow(report.summary.totalIssues)}`);
1181
- console.log(` Naming: ${chalk7.yellow(report.summary.namingIssues)}`);
1182
- 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)}`);
1183
1222
  console.log(
1184
- ` Architecture: ${chalk7.yellow(report.summary.architectureIssues || 0)}`
1223
+ ` Architecture: ${chalk8.yellow(report.summary.architectureIssues || 0)}`
1185
1224
  );
1186
- console.log(`Analysis Time: ${chalk7.gray(elapsedTime + "s")}
1225
+ console.log(`Analysis Time: ${chalk8.gray(elapsedTime + "s")}
1187
1226
  `);
1188
1227
  if (report.summary.totalIssues === 0) {
1189
1228
  console.log(
1190
- chalk7.green(
1229
+ chalk8.green(
1191
1230
  "\u2728 No consistency issues found! Your codebase is well-maintained.\n"
1192
1231
  )
1193
1232
  );
@@ -1199,20 +1238,20 @@ async function consistencyAction(directory, options) {
1199
1238
  (r) => r.issues.some((i) => i.category === "patterns")
1200
1239
  );
1201
1240
  if (namingResults.length > 0) {
1202
- console.log(chalk7.bold("\u{1F3F7}\uFE0F Naming Issues\n"));
1241
+ console.log(chalk8.bold("\u{1F3F7}\uFE0F Naming Issues\n"));
1203
1242
  let shown = 0;
1204
1243
  for (const result of namingResults) {
1205
1244
  if (shown >= 5) break;
1206
1245
  for (const issue of result.issues) {
1207
1246
  if (shown >= 5) break;
1208
- 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;
1209
1248
  console.log(
1210
- `${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}`)}`
1211
1250
  );
1212
1251
  console.log(` ${issue.message}`);
1213
1252
  if (issue.suggestion) {
1214
1253
  console.log(
1215
- ` ${chalk7.dim("\u2192")} ${chalk7.italic(issue.suggestion)}`
1254
+ ` ${chalk8.dim("\u2192")} ${chalk8.italic(issue.suggestion)}`
1216
1255
  );
1217
1256
  }
1218
1257
  console.log();
@@ -1221,25 +1260,25 @@ async function consistencyAction(directory, options) {
1221
1260
  }
1222
1261
  const remaining = namingResults.reduce((sum, r) => sum + r.issues.length, 0) - shown;
1223
1262
  if (remaining > 0) {
1224
- console.log(chalk7.dim(` ... and ${remaining} more issues
1263
+ console.log(chalk8.dim(` ... and ${remaining} more issues
1225
1264
  `));
1226
1265
  }
1227
1266
  }
1228
1267
  if (patternResults.length > 0) {
1229
- console.log(chalk7.bold("\u{1F504} Pattern Issues\n"));
1268
+ console.log(chalk8.bold("\u{1F504} Pattern Issues\n"));
1230
1269
  let shown = 0;
1231
1270
  for (const result of patternResults) {
1232
1271
  if (shown >= 5) break;
1233
1272
  for (const issue of result.issues) {
1234
1273
  if (shown >= 5) break;
1235
- 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;
1236
1275
  console.log(
1237
- `${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}`)}`
1238
1277
  );
1239
1278
  console.log(` ${issue.message}`);
1240
1279
  if (issue.suggestion) {
1241
1280
  console.log(
1242
- ` ${chalk7.dim("\u2192")} ${chalk7.italic(issue.suggestion)}`
1281
+ ` ${chalk8.dim("\u2192")} ${chalk8.italic(issue.suggestion)}`
1243
1282
  );
1244
1283
  }
1245
1284
  console.log();
@@ -1248,12 +1287,12 @@ async function consistencyAction(directory, options) {
1248
1287
  }
1249
1288
  const remaining = patternResults.reduce((sum, r) => sum + r.issues.length, 0) - shown;
1250
1289
  if (remaining > 0) {
1251
- console.log(chalk7.dim(` ... and ${remaining} more issues
1290
+ console.log(chalk8.dim(` ... and ${remaining} more issues
1252
1291
  `));
1253
1292
  }
1254
1293
  }
1255
1294
  if (report.recommendations.length > 0) {
1256
- console.log(chalk7.bold("\u{1F4A1} Recommendations\n"));
1295
+ console.log(chalk8.bold("\u{1F4A1} Recommendations\n"));
1257
1296
  report.recommendations.forEach((rec, i) => {
1258
1297
  console.log(`${i + 1}. ${rec}`);
1259
1298
  });
@@ -1261,8 +1300,8 @@ async function consistencyAction(directory, options) {
1261
1300
  }
1262
1301
  }
1263
1302
  if (consistencyScore) {
1264
- console.log(chalk7.bold("\n\u{1F4CA} AI Readiness Score (Consistency)\n"));
1265
- console.log(formatToolScore4(consistencyScore));
1303
+ console.log(chalk8.bold("\n\u{1F4CA} AI Readiness Score (Consistency)\n"));
1304
+ console.log(formatToolScore3(consistencyScore));
1266
1305
  console.log();
1267
1306
  }
1268
1307
  }
@@ -1272,27 +1311,27 @@ async function consistencyAction(directory, options) {
1272
1311
  }
1273
1312
 
1274
1313
  // src/commands/visualize.ts
1275
- import chalk8 from "chalk";
1314
+ import chalk9 from "chalk";
1276
1315
  import { writeFileSync as writeFileSync4, readFileSync as readFileSync3, existsSync as existsSync3, copyFileSync } from "fs";
1277
1316
  import { resolve as resolvePath7 } from "path";
1278
1317
  import { spawn } from "child_process";
1279
1318
  import { handleCLIError as handleCLIError6 } from "@aiready/core";
1280
- import { generateHTML } from "@aiready/core";
1319
+ import { generateHTML, findLatestReport as findLatestReport2 } from "@aiready/core";
1281
1320
  async function visualizeAction(directory, options) {
1282
1321
  try {
1283
1322
  const dirPath = resolvePath7(process.cwd(), directory || ".");
1284
1323
  let reportPath = options.report ? resolvePath7(dirPath, options.report) : null;
1285
1324
  if (!reportPath || !existsSync3(reportPath)) {
1286
- const latestScan = findLatestScanReport(dirPath);
1325
+ const latestScan = findLatestReport2(dirPath);
1287
1326
  if (latestScan) {
1288
1327
  reportPath = latestScan;
1289
1328
  console.log(
1290
- chalk8.dim(`Found latest report: ${latestScan.split("/").pop()}`)
1329
+ chalk9.dim(`Found latest report: ${latestScan.split("/").pop()}`)
1291
1330
  );
1292
1331
  } else {
1293
- console.error(chalk8.red("\u274C No AI readiness report found"));
1332
+ console.error(chalk9.red("\u274C No AI readiness report found"));
1294
1333
  console.log(
1295
- chalk8.dim(
1334
+ chalk9.dim(
1296
1335
  `
1297
1336
  Generate a report with:
1298
1337
  aiready scan --output json
@@ -1422,19 +1461,19 @@ Or specify a custom report:
1422
1461
  return;
1423
1462
  } else {
1424
1463
  console.log(
1425
- chalk8.yellow(
1464
+ chalk9.yellow(
1426
1465
  "\u26A0\uFE0F Dev server not available (requires local @aiready/visualizer with web assets)."
1427
1466
  )
1428
1467
  );
1429
1468
  console.log(
1430
- chalk8.cyan(" Falling back to static HTML generation...\n")
1469
+ chalk9.cyan(" Falling back to static HTML generation...\n")
1431
1470
  );
1432
1471
  useDevMode = false;
1433
1472
  }
1434
1473
  } catch (err) {
1435
1474
  console.error("Failed to start dev server:", err);
1436
1475
  console.log(
1437
- chalk8.cyan(" Falling back to static HTML generation...\n")
1476
+ chalk9.cyan(" Falling back to static HTML generation...\n")
1438
1477
  );
1439
1478
  useDevMode = false;
1440
1479
  }
@@ -1444,7 +1483,7 @@ Or specify a custom report:
1444
1483
  const defaultOutput = "visualization.html";
1445
1484
  const outPath = resolvePath7(dirPath, options.output || defaultOutput);
1446
1485
  writeFileSync4(outPath, html, "utf8");
1447
- console.log(chalk8.green(`\u2705 Visualization written to: ${outPath}`));
1486
+ console.log(chalk9.green(`\u2705 Visualization written to: ${outPath}`));
1448
1487
  if (options.open || options.serve) {
1449
1488
  const opener = process.platform === "darwin" ? "open" : process.platform === "win32" ? "start" : "xdg-open";
1450
1489
  if (options.serve) {
@@ -1474,7 +1513,7 @@ Or specify a custom report:
1474
1513
  server.listen(port, () => {
1475
1514
  const addr = `http://localhost:${port}/`;
1476
1515
  console.log(
1477
- chalk8.cyan(`\u{1F310} Local visualization server running at ${addr}`)
1516
+ chalk9.cyan(`\u{1F310} Local visualization server running at ${addr}`)
1478
1517
  );
1479
1518
  spawn(opener, [`"${addr}"`], { shell: true });
1480
1519
  });
@@ -1520,16 +1559,15 @@ NOTES:
1520
1559
  - Same options as 'visualize'. Use --serve to host the static HTML, or --dev for live reload.
1521
1560
  `;
1522
1561
 
1523
- // src/commands/ai-signal-clarity.ts
1524
- import chalk9 from "chalk";
1525
- import { loadConfig, mergeConfigWithDefaults } from "@aiready/core";
1562
+ // src/commands/shared/standard-tool-actions.ts
1563
+ import chalk10 from "chalk";
1526
1564
 
1527
1565
  // src/commands/agent-grounding.ts
1528
- import chalk10 from "chalk";
1566
+ import chalk11 from "chalk";
1529
1567
  import { loadConfig as loadConfig2, mergeConfigWithDefaults as mergeConfigWithDefaults2 } from "@aiready/core";
1530
1568
 
1531
1569
  // src/commands/testability.ts
1532
- import chalk11 from "chalk";
1570
+ import chalk12 from "chalk";
1533
1571
  import { loadConfig as loadConfig3, mergeConfigWithDefaults as mergeConfigWithDefaults3 } from "@aiready/core";
1534
1572
  async function testabilityAction(directory, options) {
1535
1573
  const { analyzeTestability, calculateTestabilityScore } = await import("@aiready/testability");
@@ -1554,28 +1592,28 @@ async function testabilityAction(directory, options) {
1554
1592
  "blind-risk": "\u{1F480}"
1555
1593
  };
1556
1594
  const safetyColors = {
1557
- safe: chalk11.green,
1558
- "moderate-risk": chalk11.yellow,
1559
- "high-risk": chalk11.red,
1560
- "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
1561
1599
  };
1562
1600
  const safety = report.summary.aiChangeSafetyRating;
1563
1601
  const icon = safetyIcons[safety] ?? "\u2753";
1564
- const color = safetyColors[safety] ?? chalk11.white;
1602
+ const color = safetyColors[safety] ?? chalk12.white;
1565
1603
  console.log(
1566
- ` \u{1F9EA} Testability: ${chalk11.bold(scoring.score + "/100")} (${report.summary.rating})`
1604
+ ` \u{1F9EA} Testability: ${chalk12.bold(scoring.score + "/100")} (${report.summary.rating})`
1567
1605
  );
1568
1606
  console.log(
1569
1607
  ` AI Change Safety: ${color(`${icon} ${safety.toUpperCase()}`)}`
1570
1608
  );
1571
1609
  console.log(
1572
- chalk11.dim(
1610
+ chalk12.dim(
1573
1611
  ` Coverage: ${Math.round(report.summary.coverageRatio * 100)}% (${report.rawData.testFiles} test / ${report.rawData.sourceFiles} source files)`
1574
1612
  )
1575
1613
  );
1576
1614
  if (safety === "blind-risk") {
1577
1615
  console.log(
1578
- chalk11.red.bold(
1616
+ chalk12.red.bold(
1579
1617
  "\n \u26A0\uFE0F NO TESTS \u2014 AI changes to this codebase are completely unverifiable!\n"
1580
1618
  )
1581
1619
  );
@@ -1587,7 +1625,7 @@ async function testabilityAction(directory, options) {
1587
1625
  import { changeAmplificationAction } from "@aiready/change-amplification/dist/cli.js";
1588
1626
 
1589
1627
  // src/commands/bug.ts
1590
- import chalk12 from "chalk";
1628
+ import chalk13 from "chalk";
1591
1629
  import { execSync } from "child_process";
1592
1630
  async function bugAction(message, options) {
1593
1631
  const repoUrl = "https://github.com/caopengau/aiready-cli";
@@ -1605,35 +1643,35 @@ Generated via AIReady CLI 'bug' command.
1605
1643
  Type: ${type}
1606
1644
  `.trim();
1607
1645
  if (options.submit) {
1608
- 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"));
1609
1647
  try {
1610
1648
  execSync("gh auth status", { stdio: "ignore" });
1611
1649
  const command = `gh issue create --repo ${repoSlug} --title ${JSON.stringify(title)} --body ${JSON.stringify(body)} --label ${label}`;
1612
1650
  const output = execSync(command, { encoding: "utf8" }).trim();
1613
- console.log(chalk12.green("\u2705 Issue Created Successfully!"));
1614
- console.log(chalk12.cyan(output));
1651
+ console.log(chalk13.green("\u2705 Issue Created Successfully!"));
1652
+ console.log(chalk13.cyan(output));
1615
1653
  return;
1616
- } catch (error) {
1617
- 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."));
1618
1656
  console.log(
1619
- chalk12.yellow(
1657
+ chalk13.yellow(
1620
1658
  ' Make sure gh is installed and run "gh auth login".\n'
1621
1659
  )
1622
1660
  );
1623
- console.log(chalk12.dim(" Falling back to URL generation..."));
1661
+ console.log(chalk13.dim(" Falling back to URL generation..."));
1624
1662
  }
1625
1663
  }
1626
1664
  const template = type === "bug" ? "bug_report.md" : type === "feature" ? "feature_request.md" : "new_metric_idea.md";
1627
1665
  const fullUrl = `${repoUrl}/issues/new?title=${encodeURIComponent(title)}&body=${encodeURIComponent(body)}&labels=${label}&template=${template}`;
1628
- console.log(chalk12.green("\u{1F680} Issue Draft Prepared!\n"));
1629
- console.log(chalk12.bold("Title: ") + title);
1630
- console.log(chalk12.bold("Type: ") + type);
1631
- console.log(chalk12.bold("\nClick the link below to submit this issue:"));
1632
- console.log(chalk12.cyan(fullUrl));
1633
- console.log(chalk12.bold("\n\u{1F916} [FOR AI AGENTS]:"));
1634
- 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."));
1635
1673
  console.log(
1636
- chalk12.dim(
1674
+ chalk13.dim(
1637
1675
  " Please present the URL above to the user so they can finalize the submission."
1638
1676
  )
1639
1677
  );
@@ -1642,14 +1680,14 @@ Type: ${type}
1642
1680
  const bugUrl = `${repoUrl}/issues/new?template=bug_report.md`;
1643
1681
  const featureUrl = `${repoUrl}/issues/new?template=feature_request.md`;
1644
1682
  const metricUrl = `${repoUrl}/issues/new?template=new_metric_idea.md`;
1645
- console.log(chalk12.blue("\u{1F4AC} Feedback & Bug Reports\n"));
1646
- console.log(` Report a Bug: ${chalk12.cyan(bugUrl)}`);
1647
- console.log(` Request a Feature: ${chalk12.cyan(featureUrl)}`);
1648
- console.log(` Suggest a Metric: ${chalk12.cyan(metricUrl)}`);
1649
- console.log(chalk12.bold("\n\u{1F916} [FOR AI AGENTS]:"));
1650
- 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:"));
1651
1689
  console.log(
1652
- chalk12.cyan(
1690
+ chalk13.cyan(
1653
1691
  ' aiready bug "your description here" --type bug|feature|metric'
1654
1692
  )
1655
1693
  );
@@ -1734,9 +1772,9 @@ program.command("scan").description(
1734
1772
  program.command("init").description("Generate a default configuration (aiready.json)").option("-f, --force", "Overwrite existing configuration file").option(
1735
1773
  "--js",
1736
1774
  "Generate configuration as a JavaScript file (aiready.config.js)"
1737
- ).action(async (options) => {
1775
+ ).option("--full", "Generate a full configuration with all available options").action(async (options) => {
1738
1776
  const format = options.js ? "js" : "json";
1739
- await initAction({ force: options.force, format });
1777
+ await initAction({ force: options.force, format, full: options.full });
1740
1778
  });
1741
1779
  program.command("patterns").description("Detect duplicate code patterns that confuse AI models").argument("[directory]", "Directory to analyze", ".").option("-s, --similarity <number>", "Minimum similarity score (0-1)", "0.40").option("-l, --min-lines <number>", "Minimum lines to consider", "5").option(
1742
1780
  "--max-candidates <number>",