@aiready/cli 0.9.35 → 0.9.38

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/cli.mjs CHANGED
@@ -2,15 +2,17 @@
2
2
  import {
3
3
  __require,
4
4
  analyzeUnified
5
- } from "./chunk-5GZDRZ3T.mjs";
5
+ } from "./chunk-JQG7ZATX.mjs";
6
6
 
7
7
  // src/cli.ts
8
8
  import { Command } from "commander";
9
- import { readFileSync as readFileSync3 } from "fs";
10
- import { join } from "path";
9
+ import { readFileSync as readFileSync4 } from "fs";
10
+ import { join, dirname } from "path";
11
+ import { fileURLToPath } from "url";
11
12
 
12
13
  // src/commands/scan.ts
13
14
  import chalk2 from "chalk";
15
+ import { readFileSync as readFileSync2 } from "fs";
14
16
  import { resolve as resolvePath2 } from "path";
15
17
  import {
16
18
  loadMergedConfig,
@@ -52,7 +54,7 @@ function findLatestScanReport(dirPath) {
52
54
  }
53
55
  function warnIfGraphCapExceeded(report, dirPath) {
54
56
  try {
55
- const { loadConfig } = __require("@aiready/core");
57
+ const { loadConfig: loadConfig4 } = __require("@aiready/core");
56
58
  let graphConfig = { maxNodes: 400, maxEdges: 600 };
57
59
  const configPath = resolvePath(dirPath, "aiready.json");
58
60
  if (existsSync(configPath)) {
@@ -138,7 +140,7 @@ async function scanAction(directory, options) {
138
140
  const resolvedDir = resolvePath2(process.cwd(), directory || ".");
139
141
  try {
140
142
  const defaults = {
141
- tools: ["patterns", "context", "consistency"],
143
+ tools: ["patterns", "context", "consistency", "hallucination", "grounding", "testability", "doc-drift", "deps-health"],
142
144
  include: void 0,
143
145
  exclude: void 0,
144
146
  output: {
@@ -146,8 +148,28 @@ async function scanAction(directory, options) {
146
148
  file: void 0
147
149
  }
148
150
  };
151
+ let profileTools = options.tools ? options.tools.split(",").map((t) => t.trim()) : void 0;
152
+ if (options.profile) {
153
+ switch (options.profile.toLowerCase()) {
154
+ case "agentic":
155
+ profileTools = ["hallucination", "grounding", "testability"];
156
+ break;
157
+ case "cost":
158
+ profileTools = ["patterns", "context"];
159
+ break;
160
+ case "security":
161
+ profileTools = ["consistency", "testability"];
162
+ break;
163
+ case "onboarding":
164
+ profileTools = ["context", "consistency", "grounding"];
165
+ break;
166
+ default:
167
+ console.log(chalk2.yellow(`
168
+ \u26A0\uFE0F Unknown profile '${options.profile}'. Using specified tools or defaults.`));
169
+ }
170
+ }
149
171
  const baseOptions = await loadMergedConfig(resolvedDir, defaults, {
150
- tools: options.tools ? options.tools.split(",").map((t) => t.trim()) : void 0,
172
+ tools: profileTools,
151
173
  include: options.include?.split(","),
152
174
  exclude: options.exclude?.split(",")
153
175
  });
@@ -279,6 +301,20 @@ async function scanAction(directory, options) {
279
301
  console.log(chalk2.dim(` ... and ${remaining} more files with issues (use --output json for full details)`));
280
302
  }
281
303
  }
304
+ } else if (event.tool === "doc-drift") {
305
+ const dr = event.data;
306
+ console.log(` Issues found: ${chalk2.bold(String(dr.issues?.length || 0))}`);
307
+ if (dr.rawData) {
308
+ console.log(` Signature Mismatches: ${chalk2.bold(dr.rawData.outdatedComments || 0)}`);
309
+ console.log(` Undocumented Complexity: ${chalk2.bold(dr.rawData.undocumentedComplexity || 0)}`);
310
+ }
311
+ } else if (event.tool === "deps-health") {
312
+ const dr = event.data;
313
+ console.log(` Packages Analyzed: ${chalk2.bold(String(dr.summary?.packagesAnalyzed || 0))}`);
314
+ if (dr.rawData) {
315
+ console.log(` Deprecated Packages: ${chalk2.bold(dr.rawData.deprecatedPackages || 0)}`);
316
+ console.log(` AI Cutoff Skew Score: ${chalk2.bold(dr.rawData.trainingCutoffSkew?.toFixed(1) || 0)}`);
317
+ }
282
318
  }
283
319
  } catch (err) {
284
320
  }
@@ -324,11 +360,82 @@ async function scanAction(directory, options) {
324
360
  } catch (err) {
325
361
  }
326
362
  }
363
+ if (results.hallucination) {
364
+ const { calculateHallucinationScore } = await import("@aiready/hallucination-risk");
365
+ try {
366
+ const hrScore = calculateHallucinationScore(results.hallucination);
367
+ toolScores.set("hallucination-risk", hrScore);
368
+ } catch (err) {
369
+ }
370
+ }
371
+ if (results.grounding) {
372
+ const { calculateGroundingScore } = await import("@aiready/agent-grounding");
373
+ try {
374
+ const agScore = calculateGroundingScore(results.grounding);
375
+ toolScores.set("agent-grounding", agScore);
376
+ } catch (err) {
377
+ }
378
+ }
379
+ if (results.testability) {
380
+ const { calculateTestabilityScore } = await import("@aiready/testability");
381
+ try {
382
+ const tbScore = calculateTestabilityScore(results.testability);
383
+ toolScores.set("testability", tbScore);
384
+ } catch (err) {
385
+ }
386
+ }
387
+ if (results.docDrift) {
388
+ toolScores.set("doc-drift", {
389
+ toolName: "doc-drift",
390
+ score: results.docDrift.summary.score,
391
+ rawMetrics: results.docDrift.rawData,
392
+ factors: [],
393
+ recommendations: results.docDrift.recommendations.map((action) => ({ action, estimatedImpact: 5, priority: "medium" }))
394
+ });
395
+ }
396
+ if (results.deps) {
397
+ toolScores.set("dependency-health", {
398
+ toolName: "dependency-health",
399
+ score: results.deps.summary.score,
400
+ rawMetrics: results.deps.rawData,
401
+ factors: [],
402
+ recommendations: results.deps.recommendations.map((action) => ({ action, estimatedImpact: 5, priority: "medium" }))
403
+ });
404
+ }
327
405
  const cliWeights = parseWeightString(options.weights);
328
406
  if (toolScores.size > 0) {
329
407
  scoringResult = calculateOverallScore(toolScores, finalOptions, cliWeights.size ? cliWeights : void 0);
330
408
  console.log(chalk2.bold("\n\u{1F4CA} AI Readiness Overall Score"));
331
409
  console.log(` ${formatScore(scoringResult)}`);
410
+ if (options.compareTo) {
411
+ try {
412
+ const prevReportStr = readFileSync2(resolvePath2(process.cwd(), options.compareTo), "utf8");
413
+ const prevReport = JSON.parse(prevReportStr);
414
+ const prevScore = prevReport.scoring?.score || prevReport.scoring?.overallScore;
415
+ if (typeof prevScore === "number") {
416
+ const diff = scoringResult.overall - prevScore;
417
+ const diffStr = diff > 0 ? `+${diff}` : String(diff);
418
+ console.log();
419
+ if (diff > 0) {
420
+ console.log(chalk2.green(` \u{1F4C8} Trend: ${diffStr} compared to ${options.compareTo} (${prevScore} \u2192 ${scoringResult.overall})`));
421
+ } else if (diff < 0) {
422
+ console.log(chalk2.red(` \u{1F4C9} Trend: ${diffStr} compared to ${options.compareTo} (${prevScore} \u2192 ${scoringResult.overall})`));
423
+ } else {
424
+ console.log(chalk2.blue(` \u2796 Trend: No change compared to ${options.compareTo} (${prevScore} \u2192 ${scoringResult.overall})`));
425
+ }
426
+ scoringResult.trend = {
427
+ previousScore: prevScore,
428
+ difference: diff
429
+ };
430
+ } else {
431
+ console.log(chalk2.yellow(`
432
+ \u26A0\uFE0F Previous report at ${options.compareTo} does not contain an overall score.`));
433
+ }
434
+ } catch (e) {
435
+ console.log(chalk2.yellow(`
436
+ \u26A0\uFE0F Could not read or parse previous report at ${options.compareTo}.`));
437
+ }
438
+ }
332
439
  if (scoringResult.breakdown && scoringResult.breakdown.length > 0) {
333
440
  console.log(chalk2.bold("\nTool breakdown:"));
334
441
  scoringResult.breakdown.forEach((tool) => {
@@ -364,17 +471,17 @@ async function scanAction(directory, options) {
364
471
  if (process.env.GITHUB_ACTIONS === "true") {
365
472
  console.log(`
366
473
  ::group::AI Readiness Score`);
367
- console.log(`score=${scoringResult.overallScore}`);
474
+ console.log(`score=${scoringResult.overall}`);
368
475
  if (scoringResult.breakdown) {
369
476
  scoringResult.breakdown.forEach((tool) => {
370
477
  console.log(`${tool.toolName}=${tool.score}`);
371
478
  });
372
479
  }
373
480
  console.log("::endgroup::");
374
- if (threshold && scoringResult.overallScore < threshold) {
375
- console.log(`::error::AI Readiness Score ${scoringResult.overallScore} is below threshold ${threshold}`);
481
+ if (threshold && scoringResult.overall < threshold) {
482
+ console.log(`::error::AI Readiness Score ${scoringResult.overall} is below threshold ${threshold}`);
376
483
  } else if (threshold) {
377
- console.log(`::notice::AI Readiness Score: ${scoringResult.overallScore}/100 (threshold: ${threshold})`);
484
+ console.log(`::notice::AI Readiness Score: ${scoringResult.overall}/100 (threshold: ${threshold})`);
378
485
  }
379
486
  if (results.patterns) {
380
487
  const criticalPatterns = results.patterns.flatMap(
@@ -387,9 +494,9 @@ async function scanAction(directory, options) {
387
494
  }
388
495
  let shouldFail = false;
389
496
  let failReason = "";
390
- if (threshold && scoringResult.overallScore < threshold) {
497
+ if (threshold && scoringResult.overall < threshold) {
391
498
  shouldFail = true;
392
- failReason = `AI Readiness Score ${scoringResult.overallScore} is below threshold ${threshold}`;
499
+ failReason = `AI Readiness Score ${scoringResult.overall} is below threshold ${threshold}`;
393
500
  }
394
501
  if (failOnLevel !== "none") {
395
502
  const severityLevels = { critical: 4, major: 3, minor: 2, any: 1 };
@@ -437,7 +544,7 @@ async function scanAction(directory, options) {
437
544
  } else {
438
545
  console.log(chalk2.green("\n\u2705 PR PASSED: AI Readiness Check"));
439
546
  if (threshold) {
440
- console.log(chalk2.green(` Score: ${scoringResult.overallScore}/100 (threshold: ${threshold})`));
547
+ console.log(chalk2.green(` Score: ${scoringResult.overall}/100 (threshold: ${threshold})`));
441
548
  }
442
549
  console.log(chalk2.dim("\n \u{1F4A1} Track historical trends: https://getaiready.dev \u2014 Team plan $99/mo"));
443
550
  }
@@ -450,11 +557,20 @@ var scanHelpText = `
450
557
  EXAMPLES:
451
558
  $ aiready scan # Analyze all tools
452
559
  $ aiready scan --tools patterns,context # Skip consistency
560
+ $ aiready scan --profile agentic # Optimize for AI agent execution
561
+ $ aiready scan --profile security # Optimize for secure coding (testability)
562
+ $ aiready scan --compare-to prev-report.json # Compare trends against previous run
453
563
  $ aiready scan --score --threshold 75 # CI/CD with threshold
454
564
  $ aiready scan --ci --threshold 70 # GitHub Actions gatekeeper
455
565
  $ aiready scan --ci --fail-on major # Fail on major+ issues
456
566
  $ aiready scan --output json --output-file report.json
457
567
 
568
+ PROFILES:
569
+ agentic: hallucination, grounding, testability
570
+ cost: patterns, context
571
+ security: consistency, testability
572
+ onboarding: context, consistency, grounding
573
+
458
574
  CI/CD INTEGRATION (Gatekeeper Mode):
459
575
  Use --ci for GitHub Actions integration:
460
576
  - Outputs GitHub Actions annotations for PR checks
@@ -741,7 +857,7 @@ async function contextAction(directory, options) {
741
857
 
742
858
  // src/commands/consistency.ts
743
859
  import chalk5 from "chalk";
744
- import { writeFileSync } from "fs";
860
+ import { writeFileSync as writeFileSync2 } from "fs";
745
861
  import { resolve as resolvePath5 } from "path";
746
862
  import {
747
863
  loadMergedConfig as loadMergedConfig4,
@@ -806,7 +922,7 @@ async function consistencyAction(directory, options) {
806
922
  `aiready-report-${getReportTimestamp()}.md`,
807
923
  resolvedDir
808
924
  );
809
- writeFileSync(outputPath, markdown);
925
+ writeFileSync2(outputPath, markdown);
810
926
  console.log(chalk5.green(`\u2705 Report saved to ${outputPath}`));
811
927
  } else {
812
928
  console.log(chalk5.bold("\n\u{1F4CA} Summary\n"));
@@ -893,7 +1009,7 @@ async function consistencyAction(directory, options) {
893
1009
 
894
1010
  // src/commands/visualize.ts
895
1011
  import chalk6 from "chalk";
896
- import { writeFileSync as writeFileSync2, readFileSync as readFileSync2, existsSync as existsSync2, copyFileSync as copyFileSync2 } from "fs";
1012
+ import { writeFileSync as writeFileSync3, readFileSync as readFileSync3, existsSync as existsSync2, copyFileSync as copyFileSync2 } from "fs";
897
1013
  import { resolve as resolvePath6 } from "path";
898
1014
  import { spawn } from "child_process";
899
1015
  import { handleCLIError as handleCLIError5 } from "@aiready/core";
@@ -918,13 +1034,13 @@ Or specify a custom report:
918
1034
  return;
919
1035
  }
920
1036
  }
921
- const raw = readFileSync2(reportPath, "utf8");
1037
+ const raw = readFileSync3(reportPath, "utf8");
922
1038
  const report = JSON.parse(raw);
923
1039
  const configPath = resolvePath6(dirPath, "aiready.json");
924
1040
  let graphConfig = { maxNodes: 400, maxEdges: 600 };
925
1041
  if (existsSync2(configPath)) {
926
1042
  try {
927
- const rawConfig = JSON.parse(readFileSync2(configPath, "utf8"));
1043
+ const rawConfig = JSON.parse(readFileSync3(configPath, "utf8"));
928
1044
  if (rawConfig.visualizer?.graph) {
929
1045
  graphConfig = {
930
1046
  maxNodes: rawConfig.visualizer.graph.maxNodes ?? graphConfig.maxNodes,
@@ -1032,7 +1148,7 @@ Or specify a custom report:
1032
1148
  const html = generateHTML(graph);
1033
1149
  const defaultOutput = "visualization.html";
1034
1150
  const outPath = resolvePath6(dirPath, options.output || defaultOutput);
1035
- writeFileSync2(outPath, html, "utf8");
1151
+ writeFileSync3(outPath, html, "utf8");
1036
1152
  console.log(chalk6.green(`\u2705 Visualization written to: ${outPath}`));
1037
1153
  if (options.open || options.serve) {
1038
1154
  const opener = process.platform === "darwin" ? "open" : process.platform === "win32" ? "start" : "xdg-open";
@@ -1104,8 +1220,24 @@ NOTES:
1104
1220
  - Same options as 'visualize'. Use --serve to host the static HTML, or --dev for live reload.
1105
1221
  `;
1106
1222
 
1223
+ // src/commands/hallucination-risk.ts
1224
+ import chalk7 from "chalk";
1225
+ import { loadConfig, mergeConfigWithDefaults } from "@aiready/core";
1226
+
1227
+ // src/commands/agent-grounding.ts
1228
+ import chalk8 from "chalk";
1229
+ import { loadConfig as loadConfig2, mergeConfigWithDefaults as mergeConfigWithDefaults2 } from "@aiready/core";
1230
+
1231
+ // src/commands/testability.ts
1232
+ import chalk9 from "chalk";
1233
+ import { loadConfig as loadConfig3, mergeConfigWithDefaults as mergeConfigWithDefaults3 } from "@aiready/core";
1234
+
1107
1235
  // src/cli.ts
1108
- var packageJson = JSON.parse(readFileSync3(join(__dirname, "../package.json"), "utf8"));
1236
+ var getDirname = () => {
1237
+ if (typeof __dirname !== "undefined") return __dirname;
1238
+ return dirname(fileURLToPath(import.meta.url));
1239
+ };
1240
+ var packageJson = JSON.parse(readFileSync4(join(getDirname(), "../package.json"), "utf8"));
1109
1241
  var program = new Command();
1110
1242
  program.name("aiready").description("AIReady - Assess and improve AI-readiness of codebases").version(packageJson.version).addHelpText("after", `
1111
1243
  AI READINESS SCORING:
@@ -1143,7 +1275,7 @@ VERSION: ${packageJson.version}
1143
1275
  DOCUMENTATION: https://aiready.dev/docs/cli
1144
1276
  GITHUB: https://github.com/caopengau/aiready-cli
1145
1277
  LANDING: https://github.com/caopengau/aiready-landing`);
1146
- 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)", "patterns,context,consistency").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 (patterns:40,context:35,consistency:25)").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) => {
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) => {
1147
1279
  await scanAction(directory, options);
1148
1280
  });
1149
1281
  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) => {
@@ -0,0 +1,47 @@
1
+ import "./chunk-Y6FXYEAI.mjs";
2
+
3
+ // src/commands/deps-health.ts
4
+ import chalk from "chalk";
5
+ import { loadConfig, mergeConfigWithDefaults } from "@aiready/core";
6
+ async function depsHealthAction(directory, options) {
7
+ const { analyzeDeps } = await import("@aiready/deps");
8
+ const config = await loadConfig(directory);
9
+ const merged = mergeConfigWithDefaults(config, {
10
+ trainingCutoffYear: 2023
11
+ });
12
+ const report = await analyzeDeps({
13
+ rootDir: directory,
14
+ include: options.include,
15
+ exclude: options.exclude,
16
+ trainingCutoffYear: options.trainingCutoffYear ?? merged.trainingCutoffYear ?? 2023
17
+ });
18
+ const scoring = {
19
+ toolName: "dependency-health",
20
+ score: report.summary.score,
21
+ rawMetrics: report.rawData,
22
+ factors: [],
23
+ recommendations: report.recommendations.map((action) => ({ action, estimatedImpact: 5, priority: "medium" }))
24
+ };
25
+ if (options.output === "json") {
26
+ return scoring;
27
+ }
28
+ const { summary } = report;
29
+ const ratingColors = {
30
+ excellent: chalk.green,
31
+ good: chalk.blueBright,
32
+ moderate: chalk.yellow,
33
+ poor: chalk.red,
34
+ hazardous: chalk.bgRed.white
35
+ };
36
+ const color = ratingColors[summary.rating] ?? chalk.white;
37
+ console.log(` \u{1F4E6} Dependency Health: ${chalk.bold(scoring.score + "/100 health")} (${color(summary.rating)})`);
38
+ if (report.issues.length > 0) {
39
+ console.log(chalk.dim(` Found ${report.issues.length} dependency issues.`));
40
+ } else {
41
+ console.log(chalk.dim(` Dependencies look healthy for AI assistance.`));
42
+ }
43
+ return scoring;
44
+ }
45
+ export {
46
+ depsHealthAction
47
+ };
@@ -0,0 +1,47 @@
1
+ import "./chunk-Y6FXYEAI.mjs";
2
+
3
+ // src/commands/doc-drift.ts
4
+ import chalk from "chalk";
5
+ import { loadConfig, mergeConfigWithDefaults } from "@aiready/core";
6
+ async function docDriftAction(directory, options) {
7
+ const { analyzeDocDrift } = await import("@aiready/doc-drift");
8
+ const config = await loadConfig(directory);
9
+ const merged = mergeConfigWithDefaults(config, {
10
+ staleMonths: 6
11
+ });
12
+ const report = await analyzeDocDrift({
13
+ rootDir: directory,
14
+ include: options.include,
15
+ exclude: options.exclude,
16
+ staleMonths: options.staleMonths ?? merged.staleMonths ?? 6
17
+ });
18
+ const scoring = {
19
+ toolName: "doc-drift",
20
+ score: report.summary.score,
21
+ rawMetrics: report.rawData,
22
+ factors: [],
23
+ recommendations: report.recommendations.map((action) => ({ action, estimatedImpact: 5, priority: "medium" }))
24
+ };
25
+ if (options.output === "json") {
26
+ return scoring;
27
+ }
28
+ const { summary } = report;
29
+ const ratingColors = {
30
+ minimal: chalk.green,
31
+ low: chalk.cyan,
32
+ moderate: chalk.yellow,
33
+ high: chalk.red,
34
+ severe: chalk.bgRed.white
35
+ };
36
+ const color = ratingColors[summary.rating] ?? chalk.white;
37
+ console.log(` \u{1F4DD} Documentation Drift: ${chalk.bold(100 - scoring.score + "/100 health")} (${color(summary.rating)} risk)`);
38
+ if (report.issues.length > 0) {
39
+ console.log(chalk.dim(` Found ${report.issues.length} drift issues.`));
40
+ } else {
41
+ console.log(chalk.dim(` No documentation drift detected.`));
42
+ }
43
+ return scoring;
44
+ }
45
+ export {
46
+ docDriftAction
47
+ };
@@ -0,0 +1,7 @@
1
+ import {
2
+ hallucinationRiskAction
3
+ } from "./chunk-RBWLQRKR.mjs";
4
+ import "./chunk-Y6FXYEAI.mjs";
5
+ export {
6
+ hallucinationRiskAction
7
+ };
package/dist/index.js CHANGED
@@ -1,7 +1,9 @@
1
1
  "use strict";
2
+ var __create = Object.create;
2
3
  var __defProp = Object.defineProperty;
3
4
  var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
5
  var __getOwnPropNames = Object.getOwnPropertyNames;
6
+ var __getProtoOf = Object.getPrototypeOf;
5
7
  var __hasOwnProp = Object.prototype.hasOwnProperty;
6
8
  var __export = (target, all) => {
7
9
  for (var name in all)
@@ -15,6 +17,14 @@ var __copyProps = (to, from, except, desc) => {
15
17
  }
16
18
  return to;
17
19
  };
20
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
21
+ // If the importer is in node compatibility mode or this is not an ESM
22
+ // file that has been converted to a CommonJS file using a Babel-
23
+ // compatible transform (i.e. "__esModule" has not been set), then set
24
+ // "default" to the CommonJS "module.exports" for node compatibility.
25
+ isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
26
+ mod
27
+ ));
18
28
  var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
29
 
20
30
  // src/index.ts
@@ -105,6 +115,71 @@ async function analyzeUnified(options) {
105
115
  result.consistency = report;
106
116
  result.summary.totalIssues += report.summary.totalIssues;
107
117
  }
118
+ if (tools.includes("doc-drift")) {
119
+ const { analyzeDocDrift } = await import("@aiready/doc-drift");
120
+ const report = await analyzeDocDrift({
121
+ rootDir: options.rootDir,
122
+ include: options.include,
123
+ exclude: options.exclude
124
+ });
125
+ if (options.progressCallback) {
126
+ options.progressCallback({ tool: "doc-drift", data: report });
127
+ }
128
+ result.docDrift = report;
129
+ result.summary.totalIssues += report.issues?.length || 0;
130
+ }
131
+ if (tools.includes("deps-health")) {
132
+ const { analyzeDeps } = await import("@aiready/deps");
133
+ const report = await analyzeDeps({
134
+ rootDir: options.rootDir,
135
+ include: options.include,
136
+ exclude: options.exclude
137
+ });
138
+ if (options.progressCallback) {
139
+ options.progressCallback({ tool: "deps-health", data: report });
140
+ }
141
+ result.deps = report;
142
+ result.summary.totalIssues += report.issues?.length || 0;
143
+ }
144
+ if (tools.includes("hallucination")) {
145
+ const { analyzeHallucinationRisk } = await import("@aiready/hallucination-risk");
146
+ const report = await analyzeHallucinationRisk({
147
+ rootDir: options.rootDir,
148
+ include: options.include,
149
+ exclude: options.exclude
150
+ });
151
+ if (options.progressCallback) {
152
+ options.progressCallback({ tool: "hallucination", data: report });
153
+ }
154
+ result.hallucination = report;
155
+ result.summary.totalIssues += report.results?.reduce((sum, r) => sum + (r.issues?.length || 0), 0) || 0;
156
+ }
157
+ if (tools.includes("grounding")) {
158
+ const { analyzeAgentGrounding } = await import("@aiready/agent-grounding");
159
+ const report = await analyzeAgentGrounding({
160
+ rootDir: options.rootDir,
161
+ include: options.include,
162
+ exclude: options.exclude
163
+ });
164
+ if (options.progressCallback) {
165
+ options.progressCallback({ tool: "grounding", data: report });
166
+ }
167
+ result.grounding = report;
168
+ result.summary.totalIssues += report.issues?.length || 0;
169
+ }
170
+ if (tools.includes("testability")) {
171
+ const { analyzeTestability } = await import("@aiready/testability");
172
+ const report = await analyzeTestability({
173
+ rootDir: options.rootDir,
174
+ include: options.include,
175
+ exclude: options.exclude
176
+ });
177
+ if (options.progressCallback) {
178
+ options.progressCallback({ tool: "testability", data: report });
179
+ }
180
+ result.testability = report;
181
+ result.summary.totalIssues += report.issues?.length || 0;
182
+ }
108
183
  result.summary.executionTime = Date.now() - startTime;
109
184
  return result;
110
185
  }
@@ -132,6 +207,26 @@ function generateUnifiedSummary(result) {
132
207
  }
133
208
  if (result.consistency) {
134
209
  output += `\u{1F3F7}\uFE0F Consistency Analysis: ${result.consistency.summary.totalIssues} issues
210
+ `;
211
+ }
212
+ if (result.docDrift) {
213
+ output += `\u{1F4DD} Doc Drift Analysis: ${result.docDrift.issues?.length || 0} issues
214
+ `;
215
+ }
216
+ if (result.deps) {
217
+ output += `\u{1F4E6} Dependency Health: ${result.deps.issues?.length || 0} issues
218
+ `;
219
+ }
220
+ if (result.hallucination) {
221
+ output += `\u{1F9E0} Hallucination Risk: ${result.hallucination.summary?.totalSignals || 0} signals
222
+ `;
223
+ }
224
+ if (result.grounding) {
225
+ output += `\u{1F9ED} Agent Grounding: ${result.grounding.issues?.length || 0} issues
226
+ `;
227
+ }
228
+ if (result.testability) {
229
+ output += `\u{1F9EA} Testability Index: ${result.testability.issues?.length || 0} issues
135
230
  `;
136
231
  }
137
232
  return output;
package/dist/index.mjs CHANGED
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  analyzeUnified,
3
3
  generateUnifiedSummary
4
- } from "./chunk-5GZDRZ3T.mjs";
4
+ } from "./chunk-JQG7ZATX.mjs";
5
5
  export {
6
6
  analyzeUnified,
7
7
  generateUnifiedSummary
@@ -0,0 +1,7 @@
1
+ import {
2
+ testabilityAction
3
+ } from "./chunk-XAF2EW5H.mjs";
4
+ import "./chunk-Y6FXYEAI.mjs";
5
+ export {
6
+ testabilityAction
7
+ };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@aiready/cli",
3
- "version": "0.9.35",
3
+ "version": "0.9.38",
4
4
  "description": "Unified CLI for AIReady analysis tools",
5
5
  "main": "./dist/index.js",
6
6
  "module": "./dist/index.mjs",
@@ -9,17 +9,22 @@
9
9
  "aiready": "./dist/cli.js"
10
10
  },
11
11
  "dependencies": {
12
- "commander": "^14.0.0",
13
12
  "chalk": "^5.3.0",
14
- "@aiready/core": "0.9.27",
15
- "@aiready/visualizer": "0.1.32",
16
- "@aiready/pattern-detect": "0.11.26",
17
- "@aiready/consistency": "0.8.26",
18
- "@aiready/context-analyzer": "0.9.30"
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"
19
24
  },
20
25
  "devDependencies": {
21
- "tsup": "^8.3.5",
22
- "@types/node": "^24.0.0"
26
+ "@types/node": "^24.0.0",
27
+ "tsup": "^8.3.5"
23
28
  },
24
29
  "keywords": [
25
30
  "aiready",
package/src/cli.ts CHANGED
@@ -2,7 +2,8 @@
2
2
 
3
3
  import { Command } from 'commander';
4
4
  import { readFileSync } from 'fs';
5
- import { join } from 'path';
5
+ import { join, dirname } from 'path';
6
+ import { fileURLToPath } from 'url';
6
7
 
7
8
  import {
8
9
  scanAction,
@@ -16,7 +17,12 @@ import {
16
17
  visualiseHelpText,
17
18
  } from './commands';
18
19
 
19
- const packageJson = JSON.parse(readFileSync(join(__dirname, '../package.json'), 'utf8'));
20
+ const getDirname = () => {
21
+ if (typeof __dirname !== 'undefined') return __dirname;
22
+ return dirname(fileURLToPath(import.meta.url));
23
+ };
24
+
25
+ const packageJson = JSON.parse(readFileSync(join(getDirname(), '../package.json'), 'utf8'));
20
26
 
21
27
  const program = new Command();
22
28
 
@@ -66,13 +72,15 @@ program
66
72
  .command('scan')
67
73
  .description('Run comprehensive AI-readiness analysis (patterns + context + consistency)')
68
74
  .argument('[directory]', 'Directory to analyze', '.')
69
- .option('-t, --tools <tools>', 'Tools to run (comma-separated: patterns,context,consistency)', 'patterns,context,consistency')
75
+ .option('-t, --tools <tools>', 'Tools to run (comma-separated: patterns,context,consistency,hallucination,grounding,testability)')
76
+ .option('--profile <type>', 'Scan profile to use (agentic, cost, security, onboarding)')
77
+ .option('--compare-to <path>', 'Compare results against a previous AIReady report JSON')
70
78
  .option('--include <patterns>', 'File patterns to include (comma-separated)')
71
79
  .option('--exclude <patterns>', 'File patterns to exclude (comma-separated)')
72
80
  .option('-o, --output <format>', 'Output format: console, json', 'json')
73
81
  .option('--output-file <path>', 'Output file path (for json)')
74
82
  .option('--no-score', 'Disable calculating AI Readiness Score (enabled by default)')
75
- .option('--weights <weights>', 'Custom scoring weights (patterns:40,context:35,consistency:25)')
83
+ .option('--weights <weights>', 'Custom scoring weights')
76
84
  .option('--threshold <score>', 'Fail CI/CD if score below threshold (0-100)')
77
85
  .option('--ci', 'CI mode: GitHub Actions annotations, no colors, fail on threshold')
78
86
  .option('--fail-on <level>', 'Fail on issues: critical, major, any', 'critical')