@aiready/cli 0.9.38 → 0.9.40

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.
@@ -0,0 +1,228 @@
1
+ var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require : typeof Proxy !== "undefined" ? new Proxy(x, {
2
+ get: (a, b) => (typeof require !== "undefined" ? require : a)[b]
3
+ }) : x)(function(x) {
4
+ if (typeof require !== "undefined") return require.apply(this, arguments);
5
+ throw Error('Dynamic require of "' + x + '" is not supported');
6
+ });
7
+
8
+ // src/index.ts
9
+ import { analyzePatterns } from "@aiready/pattern-detect";
10
+ import { analyzeContext } from "@aiready/context-analyzer";
11
+ import { analyzeConsistency } from "@aiready/consistency";
12
+ var severityOrder = {
13
+ critical: 4,
14
+ major: 3,
15
+ minor: 2,
16
+ info: 1
17
+ };
18
+ function sortBySeverity(results) {
19
+ return results.map((file) => {
20
+ const sortedIssues = [...file.issues].sort((a, b) => {
21
+ const severityDiff = (severityOrder[b.severity] || 0) - (severityOrder[a.severity] || 0);
22
+ if (severityDiff !== 0) return severityDiff;
23
+ return (a.location?.line || 0) - (b.location?.line || 0);
24
+ });
25
+ return { ...file, issues: sortedIssues };
26
+ }).sort((a, b) => {
27
+ const aMaxSeverity = Math.max(...a.issues.map((i) => severityOrder[i.severity] || 0), 0);
28
+ const bMaxSeverity = Math.max(...b.issues.map((i) => severityOrder[i.severity] || 0), 0);
29
+ if (aMaxSeverity !== bMaxSeverity) {
30
+ return bMaxSeverity - aMaxSeverity;
31
+ }
32
+ if (a.issues.length !== b.issues.length) {
33
+ return b.issues.length - a.issues.length;
34
+ }
35
+ return a.fileName.localeCompare(b.fileName);
36
+ });
37
+ }
38
+ async function analyzeUnified(options) {
39
+ const startTime = Date.now();
40
+ const tools = options.tools || ["patterns", "context", "consistency"];
41
+ const result = {
42
+ summary: {
43
+ totalIssues: 0,
44
+ toolsRun: tools,
45
+ executionTime: 0
46
+ }
47
+ };
48
+ if (tools.includes("patterns")) {
49
+ const patternResult = await analyzePatterns(options);
50
+ if (options.progressCallback) {
51
+ options.progressCallback({ tool: "patterns", data: patternResult });
52
+ }
53
+ result.patterns = sortBySeverity(patternResult.results);
54
+ result.duplicates = patternResult.duplicates;
55
+ result.summary.totalIssues += patternResult.results.reduce(
56
+ (sum, file) => sum + file.issues.length,
57
+ 0
58
+ );
59
+ }
60
+ if (tools.includes("context")) {
61
+ const contextResults = await analyzeContext(options);
62
+ if (options.progressCallback) {
63
+ options.progressCallback({ tool: "context", data: contextResults });
64
+ }
65
+ result.context = contextResults.sort((a, b) => {
66
+ const severityDiff = (severityOrder[b.severity] || 0) - (severityOrder[a.severity] || 0);
67
+ if (severityDiff !== 0) return severityDiff;
68
+ if (a.tokenCost !== b.tokenCost) return b.tokenCost - a.tokenCost;
69
+ return b.fragmentationScore - a.fragmentationScore;
70
+ });
71
+ result.summary.totalIssues += result.context?.length || 0;
72
+ }
73
+ if (tools.includes("consistency")) {
74
+ const consistencyOptions = {
75
+ rootDir: options.rootDir,
76
+ include: options.include,
77
+ exclude: options.exclude,
78
+ ...options.consistency || {}
79
+ };
80
+ const report = await analyzeConsistency(consistencyOptions);
81
+ if (options.progressCallback) {
82
+ options.progressCallback({ tool: "consistency", data: report });
83
+ }
84
+ if (report.results) {
85
+ report.results = sortBySeverity(report.results);
86
+ }
87
+ result.consistency = report;
88
+ result.summary.totalIssues += report.summary.totalIssues;
89
+ }
90
+ if (tools.includes("doc-drift")) {
91
+ const { analyzeDocDrift } = await import("@aiready/doc-drift");
92
+ const report = await analyzeDocDrift({
93
+ rootDir: options.rootDir,
94
+ include: options.include,
95
+ exclude: options.exclude
96
+ });
97
+ if (options.progressCallback) {
98
+ options.progressCallback({ tool: "doc-drift", data: report });
99
+ }
100
+ result.docDrift = report;
101
+ result.summary.totalIssues += report.issues?.length || 0;
102
+ }
103
+ if (tools.includes("deps-health")) {
104
+ const { analyzeDeps } = await import("@aiready/deps");
105
+ const report = await analyzeDeps({
106
+ rootDir: options.rootDir,
107
+ include: options.include,
108
+ exclude: options.exclude
109
+ });
110
+ if (options.progressCallback) {
111
+ options.progressCallback({ tool: "deps-health", data: report });
112
+ }
113
+ result.deps = report;
114
+ result.summary.totalIssues += report.issues?.length || 0;
115
+ }
116
+ if (tools.includes("aiSignalClarity")) {
117
+ const { analyzeAiSignalClarity } = await import("@aiready/ai-signal-clarity");
118
+ const report = await analyzeAiSignalClarity({
119
+ rootDir: options.rootDir,
120
+ include: options.include,
121
+ exclude: options.exclude
122
+ });
123
+ if (options.progressCallback) {
124
+ options.progressCallback({ tool: "aiSignalClarity", data: report });
125
+ }
126
+ result.aiSignalClarity = report;
127
+ result.summary.totalIssues += report.results?.reduce((sum, r) => sum + (r.issues?.length || 0), 0) || 0;
128
+ }
129
+ if (tools.includes("grounding")) {
130
+ const { analyzeAgentGrounding } = await import("@aiready/agent-grounding");
131
+ const report = await analyzeAgentGrounding({
132
+ rootDir: options.rootDir,
133
+ include: options.include,
134
+ exclude: options.exclude
135
+ });
136
+ if (options.progressCallback) {
137
+ options.progressCallback({ tool: "grounding", data: report });
138
+ }
139
+ result.grounding = report;
140
+ result.summary.totalIssues += report.issues?.length || 0;
141
+ }
142
+ if (tools.includes("testability")) {
143
+ const { analyzeTestability } = await import("@aiready/testability");
144
+ const report = await analyzeTestability({
145
+ rootDir: options.rootDir,
146
+ include: options.include,
147
+ exclude: options.exclude
148
+ });
149
+ if (options.progressCallback) {
150
+ options.progressCallback({ tool: "testability", data: report });
151
+ }
152
+ result.testability = report;
153
+ result.summary.totalIssues += report.issues?.length || 0;
154
+ }
155
+ if (tools.includes("changeAmplification")) {
156
+ const { analyzeChangeAmplification } = await import("@aiready/change-amplification");
157
+ const report = await analyzeChangeAmplification({
158
+ rootDir: options.rootDir,
159
+ include: options.include,
160
+ exclude: options.exclude
161
+ });
162
+ if (options.progressCallback) {
163
+ options.progressCallback({ tool: "changeAmplification", data: report });
164
+ }
165
+ result.changeAmplification = report;
166
+ result.summary.totalIssues += report.summary?.totalIssues || 0;
167
+ }
168
+ result.summary.executionTime = Date.now() - startTime;
169
+ return result;
170
+ }
171
+ function generateUnifiedSummary(result) {
172
+ const { summary } = result;
173
+ let output = `\u{1F680} AIReady Analysis Complete
174
+
175
+ `;
176
+ output += `\u{1F4CA} Summary:
177
+ `;
178
+ output += ` Tools run: ${summary.toolsRun.join(", ")}
179
+ `;
180
+ output += ` Total issues found: ${summary.totalIssues}
181
+ `;
182
+ output += ` Execution time: ${(summary.executionTime / 1e3).toFixed(2)}s
183
+
184
+ `;
185
+ if (result.patterns) {
186
+ output += `\u{1F50D} Pattern Analysis: ${result.patterns.length} issues
187
+ `;
188
+ }
189
+ if (result.context) {
190
+ output += `\u{1F9E0} Context Analysis: ${result.context.length} issues
191
+ `;
192
+ }
193
+ if (result.consistency) {
194
+ output += `\u{1F3F7}\uFE0F Consistency Analysis: ${result.consistency.summary.totalIssues} issues
195
+ `;
196
+ }
197
+ if (result.docDrift) {
198
+ output += `\u{1F4DD} Doc Drift Analysis: ${result.docDrift.issues?.length || 0} issues
199
+ `;
200
+ }
201
+ if (result.deps) {
202
+ output += `\u{1F4E6} Dependency Health: ${result.deps.issues?.length || 0} issues
203
+ `;
204
+ }
205
+ if (result.aiSignalClarity) {
206
+ output += `\u{1F9E0} AI Signal Clarity: ${result.aiSignalClarity.summary?.totalSignals || 0} signals
207
+ `;
208
+ }
209
+ if (result.grounding) {
210
+ output += `\u{1F9ED} Agent Grounding: ${result.grounding.issues?.length || 0} issues
211
+ `;
212
+ }
213
+ if (result.testability) {
214
+ output += `\u{1F9EA} Testability Index: ${result.testability.issues?.length || 0} issues
215
+ `;
216
+ }
217
+ if (result.changeAmplification) {
218
+ output += `\u{1F4A5} Change Amplification: ${result.changeAmplification.summary?.totalIssues || 0} cascading risks
219
+ `;
220
+ }
221
+ return output;
222
+ }
223
+
224
+ export {
225
+ __require,
226
+ analyzeUnified,
227
+ generateUnifiedSummary
228
+ };
package/dist/cli.js CHANGED
@@ -143,17 +143,17 @@ async function analyzeUnified(options) {
143
143
  result.deps = report;
144
144
  result.summary.totalIssues += report.issues?.length || 0;
145
145
  }
146
- if (tools.includes("hallucination")) {
147
- const { analyzeHallucinationRisk } = await import("@aiready/hallucination-risk");
148
- const report = await analyzeHallucinationRisk({
146
+ if (tools.includes("aiSignalClarity")) {
147
+ const { analyzeAiSignalClarity } = await import("@aiready/ai-signal-clarity");
148
+ const report = await analyzeAiSignalClarity({
149
149
  rootDir: options.rootDir,
150
150
  include: options.include,
151
151
  exclude: options.exclude
152
152
  });
153
153
  if (options.progressCallback) {
154
- options.progressCallback({ tool: "hallucination", data: report });
154
+ options.progressCallback({ tool: "aiSignalClarity", data: report });
155
155
  }
156
- result.hallucination = report;
156
+ result.aiSignalClarity = report;
157
157
  result.summary.totalIssues += report.results?.reduce((sum, r) => sum + (r.issues?.length || 0), 0) || 0;
158
158
  }
159
159
  if (tools.includes("grounding")) {
@@ -182,6 +182,19 @@ async function analyzeUnified(options) {
182
182
  result.testability = report;
183
183
  result.summary.totalIssues += report.issues?.length || 0;
184
184
  }
185
+ if (tools.includes("changeAmplification")) {
186
+ const { analyzeChangeAmplification } = await import("@aiready/change-amplification");
187
+ const report = await analyzeChangeAmplification({
188
+ rootDir: options.rootDir,
189
+ include: options.include,
190
+ exclude: options.exclude
191
+ });
192
+ if (options.progressCallback) {
193
+ options.progressCallback({ tool: "changeAmplification", data: report });
194
+ }
195
+ result.changeAmplification = report;
196
+ result.summary.totalIssues += report.summary?.totalIssues || 0;
197
+ }
185
198
  result.summary.executionTime = Date.now() - startTime;
186
199
  return result;
187
200
  }
@@ -298,19 +311,23 @@ async function scanAction(directory, options) {
298
311
  const resolvedDir = (0, import_path2.resolve)(process.cwd(), directory || ".");
299
312
  try {
300
313
  const defaults = {
301
- tools: ["patterns", "context", "consistency", "hallucination", "grounding", "testability", "doc-drift", "deps-health"],
314
+ tools: ["patterns", "context", "consistency", "aiSignalClarity", "grounding", "testability", "doc-drift", "deps-health", "changeAmplification"],
302
315
  include: void 0,
303
316
  exclude: void 0,
304
317
  output: {
305
- format: "json",
318
+ format: "console",
306
319
  file: void 0
307
320
  }
308
321
  };
309
- let profileTools = options.tools ? options.tools.split(",").map((t) => t.trim()) : void 0;
322
+ let profileTools = options.tools ? options.tools.split(",").map((t) => {
323
+ const tool = t.trim();
324
+ if (tool === "hallucination" || tool === "hallucination-risk") return "aiSignalClarity";
325
+ return tool;
326
+ }) : void 0;
310
327
  if (options.profile) {
311
328
  switch (options.profile.toLowerCase()) {
312
329
  case "agentic":
313
- profileTools = ["hallucination", "grounding", "testability"];
330
+ profileTools = ["aiSignalClarity", "grounding", "testability"];
314
331
  break;
315
332
  case "cost":
316
333
  profileTools = ["patterns", "context"];
@@ -326,11 +343,14 @@ async function scanAction(directory, options) {
326
343
  \u26A0\uFE0F Unknown profile '${options.profile}'. Using specified tools or defaults.`));
327
344
  }
328
345
  }
329
- const baseOptions = await (0, import_core.loadMergedConfig)(resolvedDir, defaults, {
330
- tools: profileTools,
346
+ const cliOverrides = {
331
347
  include: options.include?.split(","),
332
348
  exclude: options.exclude?.split(",")
333
- });
349
+ };
350
+ if (profileTools) {
351
+ cliOverrides.tools = profileTools;
352
+ }
353
+ const baseOptions = await (0, import_core.loadMergedConfig)(resolvedDir, defaults, cliOverrides);
334
354
  let finalOptions = { ...baseOptions };
335
355
  if (baseOptions.tools.includes("patterns")) {
336
356
  const { getSmartDefaults } = await import("@aiready/pattern-detect");
@@ -473,6 +493,12 @@ async function scanAction(directory, options) {
473
493
  console.log(` Deprecated Packages: ${import_chalk2.default.bold(dr.rawData.deprecatedPackages || 0)}`);
474
494
  console.log(` AI Cutoff Skew Score: ${import_chalk2.default.bold(dr.rawData.trainingCutoffSkew?.toFixed(1) || 0)}`);
475
495
  }
496
+ } else if (event.tool === "change-amplification" || event.tool === "changeAmplification") {
497
+ const dr = event.data;
498
+ console.log(` Coupling issues: ${import_chalk2.default.bold(String(dr.issues?.length || 0))}`);
499
+ if (dr.summary) {
500
+ console.log(` Complexity Score: ${import_chalk2.default.bold(dr.summary.score || 0)}/100`);
501
+ }
476
502
  }
477
503
  } catch (err) {
478
504
  }
@@ -485,7 +511,8 @@ async function scanAction(directory, options) {
485
511
  if (results.duplicates) console.log(` Duplicate patterns found: ${import_chalk2.default.bold(String(results.duplicates.length || 0))}`);
486
512
  if (results.patterns) console.log(` Pattern files with issues: ${import_chalk2.default.bold(String(results.patterns.length || 0))}`);
487
513
  if (results.context) console.log(` Context issues: ${import_chalk2.default.bold(String(results.context.length || 0))}`);
488
- if (results.consistency) console.log(` Consistency issues: ${import_chalk2.default.bold(String(results.consistency.summary.totalIssues || 0))}`);
514
+ console.log(` Consistency issues: ${import_chalk2.default.bold(String(results.consistency?.summary?.totalIssues || 0))}`);
515
+ if (results.changeAmplification) console.log(` Change amplification: ${import_chalk2.default.bold(String(results.changeAmplification.summary?.score || 0))}/100`);
489
516
  console.log(import_chalk2.default.cyan("===========================\n"));
490
517
  const elapsedTime = (0, import_core.getElapsedTime)(startTime);
491
518
  let scoringResult;
@@ -518,11 +545,11 @@ async function scanAction(directory, options) {
518
545
  } catch (err) {
519
546
  }
520
547
  }
521
- if (results.hallucination) {
522
- const { calculateHallucinationScore } = await import("@aiready/hallucination-risk");
548
+ if (results.aiSignalClarity) {
549
+ const { calculateAiSignalClarityScore } = await import("@aiready/ai-signal-clarity");
523
550
  try {
524
- const hrScore = calculateHallucinationScore(results.hallucination);
525
- toolScores.set("hallucination-risk", hrScore);
551
+ const hrScore = calculateAiSignalClarityScore(results.aiSignalClarity);
552
+ toolScores.set("ai-signal-clarity", hrScore);
526
553
  } catch (err) {
527
554
  }
528
555
  }
@@ -548,7 +575,7 @@ async function scanAction(directory, options) {
548
575
  score: results.docDrift.summary.score,
549
576
  rawMetrics: results.docDrift.rawData,
550
577
  factors: [],
551
- recommendations: results.docDrift.recommendations.map((action) => ({ action, estimatedImpact: 5, priority: "medium" }))
578
+ recommendations: (results.docDrift.recommendations || []).map((action) => ({ action, estimatedImpact: 5, priority: "medium" }))
552
579
  });
553
580
  }
554
581
  if (results.deps) {
@@ -557,7 +584,16 @@ async function scanAction(directory, options) {
557
584
  score: results.deps.summary.score,
558
585
  rawMetrics: results.deps.rawData,
559
586
  factors: [],
560
- recommendations: results.deps.recommendations.map((action) => ({ action, estimatedImpact: 5, priority: "medium" }))
587
+ recommendations: (results.deps.recommendations || []).map((action) => ({ action, estimatedImpact: 5, priority: "medium" }))
588
+ });
589
+ }
590
+ if (results.changeAmplification) {
591
+ toolScores.set("change-amplification", {
592
+ toolName: "change-amplification",
593
+ score: results.changeAmplification.summary.score,
594
+ rawMetrics: results.changeAmplification.rawData,
595
+ factors: [],
596
+ recommendations: (results.changeAmplification.recommendations || []).map((action) => ({ action, estimatedImpact: 5, priority: "medium" }))
561
597
  });
562
598
  }
563
599
  const cliWeights = (0, import_core.parseWeightString)(options.weights);
@@ -621,6 +657,17 @@ async function scanAction(directory, options) {
621
657
  const outputData = { ...results, scoring: scoringResult };
622
658
  (0, import_core.handleJSONOutput)(outputData, outputPath, `\u2705 Report saved to ${outputPath}`);
623
659
  warnIfGraphCapExceeded(outputData, resolvedDir);
660
+ } else {
661
+ const timestamp = getReportTimestamp();
662
+ const defaultFilename = `aiready-report-${timestamp}.json`;
663
+ const outputPath = (0, import_core.resolveOutputPath)(userOutputFile, defaultFilename, resolvedDir);
664
+ const outputData = { ...results, scoring: scoringResult };
665
+ try {
666
+ (0, import_fs2.writeFileSync)(outputPath, JSON.stringify(outputData, null, 2));
667
+ console.log(import_chalk2.default.dim(`\u2705 Report auto-persisted to ${outputPath}`));
668
+ warnIfGraphCapExceeded(outputData, resolvedDir);
669
+ } catch (err) {
670
+ }
624
671
  }
625
672
  const isCI = options.ci || process.env.CI === "true" || process.env.GITHUB_ACTIONS === "true";
626
673
  if (isCI && scoringResult) {
@@ -724,7 +771,7 @@ EXAMPLES:
724
771
  $ aiready scan --output json --output-file report.json
725
772
 
726
773
  PROFILES:
727
- agentic: hallucination, grounding, testability
774
+ agentic: aiSignalClarity, grounding, testability
728
775
  cost: patterns, context
729
776
  security: consistency, testability
730
777
  onboarding: context, consistency, grounding
@@ -1357,7 +1404,7 @@ NOTES:
1357
1404
  - Same options as 'visualize'. Use --serve to host the static HTML, or --dev for live reload.
1358
1405
  `;
1359
1406
 
1360
- // src/commands/hallucination-risk.ts
1407
+ // src/commands/ai-signal-clarity.ts
1361
1408
  var import_chalk7 = __toESM(require("chalk"));
1362
1409
  var import_core7 = require("@aiready/core");
1363
1410
 
@@ -1369,6 +1416,9 @@ var import_core8 = require("@aiready/core");
1369
1416
  var import_chalk9 = __toESM(require("chalk"));
1370
1417
  var import_core9 = require("@aiready/core");
1371
1418
 
1419
+ // src/commands/change-amplification.ts
1420
+ var import_cli = require("@aiready/change-amplification/dist/cli.js");
1421
+
1372
1422
  // src/cli.ts
1373
1423
  var import_meta = {};
1374
1424
  var getDirname = () => {
@@ -1383,11 +1433,11 @@ AI READINESS SCORING:
1383
1433
  Use --score flag with any analysis command for detailed breakdown.
1384
1434
 
1385
1435
  EXAMPLES:
1386
- $ aiready scan # Quick analysis of current directory
1436
+ $ aiready scan # Comprehensive analysis of current directory
1387
1437
  $ aiready scan --score # Get AI Readiness Score (0-100)
1388
1438
  $ aiready scan --tools patterns # Run only pattern detection
1389
- $ aiready patterns --similarity 0.6 # Custom similarity threshold
1390
- $ aiready scan --output json --output-file results.json
1439
+ $ npx @aiready/cli scan # Industry standard way to run standard scan
1440
+ $ aiready scan --output json # Output raw JSON for piping
1391
1441
 
1392
1442
  GETTING STARTED:
1393
1443
  1. Run 'aiready scan' to analyze your codebase
@@ -1413,7 +1463,7 @@ VERSION: ${packageJson.version}
1413
1463
  DOCUMENTATION: https://aiready.dev/docs/cli
1414
1464
  GITHUB: https://github.com/caopengau/aiready-cli
1415
1465
  LANDING: https://github.com/caopengau/aiready-landing`);
1416
- program.command("scan").description("Run comprehensive AI-readiness analysis (patterns + context + consistency)").argument("[directory]", "Directory to analyze", ".").option("-t, --tools <tools>", "Tools to run (comma-separated: patterns,context,consistency,hallucination,grounding,testability)").option("--profile <type>", "Scan profile to use (agentic, cost, security, onboarding)").option("--compare-to <path>", "Compare results against a previous AIReady report JSON").option("--include <patterns>", "File patterns to include (comma-separated)").option("--exclude <patterns>", "File patterns to exclude (comma-separated)").option("-o, --output <format>", "Output format: console, json", "json").option("--output-file <path>", "Output file path (for json)").option("--no-score", "Disable calculating AI Readiness Score (enabled by default)").option("--weights <weights>", "Custom scoring weights").option("--threshold <score>", "Fail CI/CD if score below threshold (0-100)").option("--ci", "CI mode: GitHub Actions annotations, no colors, fail on threshold").option("--fail-on <level>", "Fail on issues: critical, major, any", "critical").addHelpText("after", scanHelpText).action(async (directory, options) => {
1466
+ program.command("scan").description("Run comprehensive AI-readiness analysis (patterns + context + consistency)").argument("[directory]", "Directory to analyze", ".").option("-t, --tools <tools>", "Tools to run (comma-separated: patterns,context,consistency,doc-drift,deps-health,aiSignalClarity,grounding,testability,changeAmplification)").option("--profile <type>", "Scan profile to use (agentic, cost, security, onboarding)").option("--compare-to <path>", "Compare results against a previous AIReady report JSON").option("--include <patterns>", "File patterns to include (comma-separated)").option("--exclude <patterns>", "File patterns to exclude (comma-separated)").option("-o, --output <format>", "Output format: console, json", "console").option("--output-file <path>", "Output file path (for json)").option("--no-score", "Disable calculating AI Readiness Score (enabled by default)").option("--weights <weights>", "Custom scoring weights").option("--threshold <score>", "Fail CI/CD if score below threshold (0-100)").option("--ci", "CI mode: GitHub Actions annotations, no colors, fail on threshold").option("--fail-on <level>", "Fail on issues: critical, major, any", "critical").addHelpText("after", scanHelpText).action(async (directory, options) => {
1417
1467
  await scanAction(directory, options);
1418
1468
  });
1419
1469
  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("--max-candidates <number>", "Maximum candidates per block (performance tuning)").option("--min-shared-tokens <number>", "Minimum shared tokens for candidates (performance tuning)").option("--full-scan", "Disable smart defaults for comprehensive analysis (slower)").option("--include <patterns>", "File patterns to include (comma-separated)").option("--exclude <patterns>", "File patterns to exclude (comma-separated)").option("-o, --output <format>", "Output format: console, json", "console").option("--output-file <path>", "Output file path (for json)").option("--score", "Calculate and display AI Readiness Score for patterns (0-100)").addHelpText("after", patternsHelpText).action(async (directory, options) => {
@@ -1431,4 +1481,7 @@ program.command("visualise").description("Alias for visualize (British spelling)
1431
1481
  program.command("visualize").description("Generate interactive visualization from an AIReady report").argument("[directory]", "Directory to analyze", ".").option("--report <path>", "Report path (auto-detects latest .aiready/aiready-report-*.json if not provided)").option("-o, --output <path>", "Output HTML path (relative to directory)", "packages/visualizer/visualization.html").option("--open", "Open generated HTML in default browser").option("--serve [port]", "Start a local static server to serve the visualization (optional port number)", false).option("--dev", "Start Vite dev server (live reload) for interactive development", false).addHelpText("after", visualizeHelpText).action(async (directory, options) => {
1432
1482
  await visualizeAction(directory, options);
1433
1483
  });
1484
+ program.command("change-amplification").description("Analyze graph metrics for change amplification").argument("[directory]", "Directory to analyze", ".").option("--include <patterns>", "File patterns to include (comma-separated)").option("--exclude <patterns>", "File patterns to exclude (comma-separated)").option("-o, --output <format>", "Output format: console, json", "console").option("--output-file <path>", "Output file path (for json)").action(async (directory, options) => {
1485
+ await (0, import_cli.changeAmplificationAction)(directory, options);
1486
+ });
1434
1487
  program.parse();