@aiready/cli 0.9.38 → 0.9.39

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,7 +311,7 @@ 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"],
302
315
  include: void 0,
303
316
  exclude: void 0,
304
317
  output: {
@@ -306,11 +319,15 @@ async function scanAction(directory, options) {
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"];
@@ -518,11 +535,11 @@ async function scanAction(directory, options) {
518
535
  } catch (err) {
519
536
  }
520
537
  }
521
- if (results.hallucination) {
522
- const { calculateHallucinationScore } = await import("@aiready/hallucination-risk");
538
+ if (results.aiSignalClarity) {
539
+ const { calculateHallucinationScore } = await import("@aiready/ai-signal-clarity");
523
540
  try {
524
- const hrScore = calculateHallucinationScore(results.hallucination);
525
- toolScores.set("hallucination-risk", hrScore);
541
+ const hrScore = calculateHallucinationScore(results.aiSignalClarity);
542
+ toolScores.set("ai-signal-clarity", hrScore);
526
543
  } catch (err) {
527
544
  }
528
545
  }
@@ -724,7 +741,7 @@ EXAMPLES:
724
741
  $ aiready scan --output json --output-file report.json
725
742
 
726
743
  PROFILES:
727
- agentic: hallucination, grounding, testability
744
+ agentic: aiSignalClarity, grounding, testability
728
745
  cost: patterns, context
729
746
  security: consistency, testability
730
747
  onboarding: context, consistency, grounding
@@ -1357,7 +1374,7 @@ NOTES:
1357
1374
  - Same options as 'visualize'. Use --serve to host the static HTML, or --dev for live reload.
1358
1375
  `;
1359
1376
 
1360
- // src/commands/hallucination-risk.ts
1377
+ // src/commands/ai-signal-clarity.ts
1361
1378
  var import_chalk7 = __toESM(require("chalk"));
1362
1379
  var import_core7 = require("@aiready/core");
1363
1380
 
@@ -1369,6 +1386,9 @@ var import_core8 = require("@aiready/core");
1369
1386
  var import_chalk9 = __toESM(require("chalk"));
1370
1387
  var import_core9 = require("@aiready/core");
1371
1388
 
1389
+ // src/commands/change-amplification.ts
1390
+ var import_cli = require("@aiready/change-amplification/dist/cli.js");
1391
+
1372
1392
  // src/cli.ts
1373
1393
  var import_meta = {};
1374
1394
  var getDirname = () => {
@@ -1413,7 +1433,7 @@ VERSION: ${packageJson.version}
1413
1433
  DOCUMENTATION: https://aiready.dev/docs/cli
1414
1434
  GITHUB: https://github.com/caopengau/aiready-cli
1415
1435
  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) => {
1436
+ 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", "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) => {
1417
1437
  await scanAction(directory, options);
1418
1438
  });
1419
1439
  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 +1451,7 @@ program.command("visualise").description("Alias for visualize (British spelling)
1431
1451
  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
1452
  await visualizeAction(directory, options);
1433
1453
  });
1454
+ 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) => {
1455
+ await (0, import_cli.changeAmplificationAction)(directory, options);
1456
+ });
1434
1457
  program.parse();
package/dist/cli.mjs CHANGED
@@ -2,7 +2,7 @@
2
2
  import {
3
3
  __require,
4
4
  analyzeUnified
5
- } from "./chunk-JQG7ZATX.mjs";
5
+ } from "./chunk-PDOONNSK.mjs";
6
6
 
7
7
  // src/cli.ts
8
8
  import { Command } from "commander";
@@ -140,7 +140,7 @@ async function scanAction(directory, options) {
140
140
  const resolvedDir = resolvePath2(process.cwd(), directory || ".");
141
141
  try {
142
142
  const defaults = {
143
- tools: ["patterns", "context", "consistency", "hallucination", "grounding", "testability", "doc-drift", "deps-health"],
143
+ tools: ["patterns", "context", "consistency", "aiSignalClarity", "grounding", "testability", "doc-drift", "deps-health"],
144
144
  include: void 0,
145
145
  exclude: void 0,
146
146
  output: {
@@ -148,11 +148,15 @@ async function scanAction(directory, options) {
148
148
  file: void 0
149
149
  }
150
150
  };
151
- let profileTools = options.tools ? options.tools.split(",").map((t) => t.trim()) : void 0;
151
+ let profileTools = options.tools ? options.tools.split(",").map((t) => {
152
+ const tool = t.trim();
153
+ if (tool === "hallucination" || tool === "hallucination-risk") return "aiSignalClarity";
154
+ return tool;
155
+ }) : void 0;
152
156
  if (options.profile) {
153
157
  switch (options.profile.toLowerCase()) {
154
158
  case "agentic":
155
- profileTools = ["hallucination", "grounding", "testability"];
159
+ profileTools = ["aiSignalClarity", "grounding", "testability"];
156
160
  break;
157
161
  case "cost":
158
162
  profileTools = ["patterns", "context"];
@@ -360,11 +364,11 @@ async function scanAction(directory, options) {
360
364
  } catch (err) {
361
365
  }
362
366
  }
363
- if (results.hallucination) {
364
- const { calculateHallucinationScore } = await import("@aiready/hallucination-risk");
367
+ if (results.aiSignalClarity) {
368
+ const { calculateHallucinationScore } = await import("@aiready/ai-signal-clarity");
365
369
  try {
366
- const hrScore = calculateHallucinationScore(results.hallucination);
367
- toolScores.set("hallucination-risk", hrScore);
370
+ const hrScore = calculateHallucinationScore(results.aiSignalClarity);
371
+ toolScores.set("ai-signal-clarity", hrScore);
368
372
  } catch (err) {
369
373
  }
370
374
  }
@@ -566,7 +570,7 @@ EXAMPLES:
566
570
  $ aiready scan --output json --output-file report.json
567
571
 
568
572
  PROFILES:
569
- agentic: hallucination, grounding, testability
573
+ agentic: aiSignalClarity, grounding, testability
570
574
  cost: patterns, context
571
575
  security: consistency, testability
572
576
  onboarding: context, consistency, grounding
@@ -1220,7 +1224,7 @@ NOTES:
1220
1224
  - Same options as 'visualize'. Use --serve to host the static HTML, or --dev for live reload.
1221
1225
  `;
1222
1226
 
1223
- // src/commands/hallucination-risk.ts
1227
+ // src/commands/ai-signal-clarity.ts
1224
1228
  import chalk7 from "chalk";
1225
1229
  import { loadConfig, mergeConfigWithDefaults } from "@aiready/core";
1226
1230
 
@@ -1232,6 +1236,9 @@ import { loadConfig as loadConfig2, mergeConfigWithDefaults as mergeConfigWithDe
1232
1236
  import chalk9 from "chalk";
1233
1237
  import { loadConfig as loadConfig3, mergeConfigWithDefaults as mergeConfigWithDefaults3 } from "@aiready/core";
1234
1238
 
1239
+ // src/commands/change-amplification.ts
1240
+ import { changeAmplificationAction } from "@aiready/change-amplification/dist/cli.js";
1241
+
1235
1242
  // src/cli.ts
1236
1243
  var getDirname = () => {
1237
1244
  if (typeof __dirname !== "undefined") return __dirname;
@@ -1275,7 +1282,7 @@ VERSION: ${packageJson.version}
1275
1282
  DOCUMENTATION: https://aiready.dev/docs/cli
1276
1283
  GITHUB: https://github.com/caopengau/aiready-cli
1277
1284
  LANDING: https://github.com/caopengau/aiready-landing`);
1278
- 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) => {
1285
+ 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", "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) => {
1279
1286
  await scanAction(directory, options);
1280
1287
  });
1281
1288
  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) => {
@@ -1293,4 +1300,7 @@ program.command("visualise").description("Alias for visualize (British spelling)
1293
1300
  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) => {
1294
1301
  await visualizeAction(directory, options);
1295
1302
  });
1303
+ 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) => {
1304
+ await changeAmplificationAction(directory, options);
1305
+ });
1296
1306
  program.parse();
package/dist/index.js CHANGED
@@ -141,17 +141,17 @@ async function analyzeUnified(options) {
141
141
  result.deps = report;
142
142
  result.summary.totalIssues += report.issues?.length || 0;
143
143
  }
144
- if (tools.includes("hallucination")) {
145
- const { analyzeHallucinationRisk } = await import("@aiready/hallucination-risk");
146
- const report = await analyzeHallucinationRisk({
144
+ if (tools.includes("aiSignalClarity")) {
145
+ const { analyzeAiSignalClarity } = await import("@aiready/ai-signal-clarity");
146
+ const report = await analyzeAiSignalClarity({
147
147
  rootDir: options.rootDir,
148
148
  include: options.include,
149
149
  exclude: options.exclude
150
150
  });
151
151
  if (options.progressCallback) {
152
- options.progressCallback({ tool: "hallucination", data: report });
152
+ options.progressCallback({ tool: "aiSignalClarity", data: report });
153
153
  }
154
- result.hallucination = report;
154
+ result.aiSignalClarity = report;
155
155
  result.summary.totalIssues += report.results?.reduce((sum, r) => sum + (r.issues?.length || 0), 0) || 0;
156
156
  }
157
157
  if (tools.includes("grounding")) {
@@ -180,6 +180,19 @@ async function analyzeUnified(options) {
180
180
  result.testability = report;
181
181
  result.summary.totalIssues += report.issues?.length || 0;
182
182
  }
183
+ if (tools.includes("changeAmplification")) {
184
+ const { analyzeChangeAmplification } = await import("@aiready/change-amplification");
185
+ const report = await analyzeChangeAmplification({
186
+ rootDir: options.rootDir,
187
+ include: options.include,
188
+ exclude: options.exclude
189
+ });
190
+ if (options.progressCallback) {
191
+ options.progressCallback({ tool: "changeAmplification", data: report });
192
+ }
193
+ result.changeAmplification = report;
194
+ result.summary.totalIssues += report.summary?.totalIssues || 0;
195
+ }
183
196
  result.summary.executionTime = Date.now() - startTime;
184
197
  return result;
185
198
  }
@@ -217,8 +230,8 @@ function generateUnifiedSummary(result) {
217
230
  output += `\u{1F4E6} Dependency Health: ${result.deps.issues?.length || 0} issues
218
231
  `;
219
232
  }
220
- if (result.hallucination) {
221
- output += `\u{1F9E0} Hallucination Risk: ${result.hallucination.summary?.totalSignals || 0} signals
233
+ if (result.aiSignalClarity) {
234
+ output += `\u{1F9E0} AI Signal Clarity: ${result.aiSignalClarity.summary?.totalSignals || 0} signals
222
235
  `;
223
236
  }
224
237
  if (result.grounding) {
@@ -227,6 +240,10 @@ function generateUnifiedSummary(result) {
227
240
  }
228
241
  if (result.testability) {
229
242
  output += `\u{1F9EA} Testability Index: ${result.testability.issues?.length || 0} issues
243
+ `;
244
+ }
245
+ if (result.changeAmplification) {
246
+ output += `\u{1F4A5} Change Amplification: ${result.changeAmplification.summary?.totalIssues || 0} cascading risks
230
247
  `;
231
248
  }
232
249
  return output;
package/dist/index.mjs CHANGED
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  analyzeUnified,
3
3
  generateUnifiedSummary
4
- } from "./chunk-JQG7ZATX.mjs";
4
+ } from "./chunk-PDOONNSK.mjs";
5
5
  export {
6
6
  analyzeUnified,
7
7
  generateUnifiedSummary
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@aiready/cli",
3
- "version": "0.9.38",
3
+ "version": "0.9.39",
4
4
  "description": "Unified CLI for AIReady analysis tools",
5
5
  "main": "./dist/index.js",
6
6
  "module": "./dist/index.mjs",
@@ -11,16 +11,17 @@
11
11
  "dependencies": {
12
12
  "chalk": "^5.3.0",
13
13
  "commander": "^14.0.0",
14
- "@aiready/core": "0.9.30",
15
- "@aiready/context-analyzer": "0.9.33",
16
- "@aiready/deps": "0.1.3",
17
- "@aiready/agent-grounding": "0.1.3",
18
- "@aiready/consistency": "0.8.29",
19
- "@aiready/visualizer": "0.1.35",
20
- "@aiready/testability": "0.1.3",
21
- "@aiready/pattern-detect": "0.11.29",
22
- "@aiready/hallucination-risk": "0.1.3",
23
- "@aiready/doc-drift": "0.1.3"
14
+ "@aiready/agent-grounding": "0.1.4",
15
+ "@aiready/core": "0.9.31",
16
+ "@aiready/context-analyzer": "0.9.34",
17
+ "@aiready/consistency": "0.8.30",
18
+ "@aiready/visualizer": "0.1.36",
19
+ "@aiready/doc-drift": "0.1.4",
20
+ "@aiready/pattern-detect": "0.11.30",
21
+ "@aiready/deps": "0.1.4",
22
+ "@aiready/ai-signal-clarity": "0.1.4",
23
+ "@aiready/change-amplification": "0.1.4",
24
+ "@aiready/testability": "0.1.4"
24
25
  },
25
26
  "devDependencies": {
26
27
  "@types/node": "^24.0.0",
package/src/cli.ts CHANGED
@@ -15,6 +15,7 @@ import {
15
15
  visualizeAction,
16
16
  visualizeHelpText,
17
17
  visualiseHelpText,
18
+ changeAmplificationAction,
18
19
  } from './commands';
19
20
 
20
21
  const getDirname = () => {
@@ -72,7 +73,7 @@ program
72
73
  .command('scan')
73
74
  .description('Run comprehensive AI-readiness analysis (patterns + context + consistency)')
74
75
  .argument('[directory]', 'Directory to analyze', '.')
75
- .option('-t, --tools <tools>', 'Tools to run (comma-separated: patterns,context,consistency,hallucination,grounding,testability)')
76
+ .option('-t, --tools <tools>', 'Tools to run (comma-separated: patterns,context,consistency,doc-drift,deps-health,aiSignalClarity,grounding,testability,changeAmplification)')
76
77
  .option('--profile <type>', 'Scan profile to use (agentic, cost, security, onboarding)')
77
78
  .option('--compare-to <path>', 'Compare results against a previous AIReady report JSON')
78
79
  .option('--include <patterns>', 'File patterns to include (comma-separated)')
@@ -174,4 +175,17 @@ program
174
175
  await visualizeAction(directory, options);
175
176
  });
176
177
 
178
+ // Change Amplification command
179
+ program
180
+ .command('change-amplification')
181
+ .description('Analyze graph metrics for change amplification')
182
+ .argument('[directory]', 'Directory to analyze', '.')
183
+ .option('--include <patterns>', 'File patterns to include (comma-separated)')
184
+ .option('--exclude <patterns>', 'File patterns to exclude (comma-separated)')
185
+ .option('-o, --output <format>', 'Output format: console, json', 'console')
186
+ .option('--output-file <path>', 'Output file path (for json)')
187
+ .action(async (directory, options) => {
188
+ await changeAmplificationAction(directory, options);
189
+ });
190
+
177
191
  program.parse();
@@ -1,5 +1,5 @@
1
1
  /**
2
- * Hallucination risk command for unified CLI
2
+ * AI signal clarity command for unified CLI
3
3
  */
4
4
 
5
5
  import chalk from 'chalk';
@@ -8,18 +8,18 @@ import { join } from 'path';
8
8
  import { resolveOutputPath, loadConfig, mergeConfigWithDefaults } from '@aiready/core';
9
9
  import type { ToolScoringOutput } from '@aiready/core';
10
10
 
11
- export async function hallucinationRiskAction(
11
+ export async function aiSignalClarityAction(
12
12
  directory: string,
13
13
  options: any,
14
14
  ): Promise<ToolScoringOutput | undefined> {
15
- const { analyzeHallucinationRisk, calculateHallucinationScore } = await import('@aiready/hallucination-risk');
15
+ const { analyzeAiSignalClarity, calculateHallucinationScore } = await import('@aiready/ai-signal-clarity');
16
16
 
17
17
  const config = await loadConfig(directory);
18
18
  const merged = mergeConfigWithDefaults(config, {
19
19
  minSeverity: 'info',
20
20
  });
21
21
 
22
- const report = await analyzeHallucinationRisk({
22
+ const report = await analyzeAiSignalClarity({
23
23
  rootDir: directory,
24
24
  minSeverity: options.minSeverity ?? merged.minSeverity ?? 'info',
25
25
  include: options.include,
@@ -41,7 +41,7 @@ export async function hallucinationRiskAction(
41
41
  severe: chalk.bgRed.white,
42
42
  };
43
43
  const color = ratingColors[summary.rating] ?? chalk.white;
44
- console.log(` 🧠 Hallucination Risk: ${chalk.bold(scoring.score + '/100')} (${color(summary.rating)})`);
44
+ console.log(` 🧠 AI Signal Clarity: ${chalk.bold(scoring.score + '/100')} (${color(summary.rating)})`);
45
45
  console.log(` Top Risk: ${chalk.italic(summary.topRisk)}`);
46
46
  if (summary.totalSignals > 0) {
47
47
  console.log(chalk.dim(` ${summary.criticalSignals} critical ${summary.majorSignals} major ${summary.minorSignals} minor signals`));
@@ -0,0 +1,3 @@
1
+ import { changeAmplificationAction } from '@aiready/change-amplification/dist/cli.js';
2
+
3
+ export { changeAmplificationAction };