@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.
- package/.turbo/turbo-build.log +10 -10
- package/.turbo/turbo-test.log +4 -4
- package/README.md +27 -287
- package/dist/chunk-M7O2MEM5.mjs +211 -0
- package/dist/chunk-PDOONNSK.mjs +228 -0
- package/dist/cli.js +38 -15
- package/dist/cli.mjs +21 -11
- package/dist/index.js +24 -7
- package/dist/index.mjs +1 -1
- package/package.json +12 -11
- package/src/cli.ts +15 -1
- package/src/commands/{hallucination-risk.ts → ai-signal-clarity.ts} +5 -5
- package/src/commands/change-amplification.ts +3 -0
- package/src/commands/index.ts +3 -2
- package/src/commands/scan.ts +13 -9
- package/src/index.ts +30 -10
|
@@ -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("
|
|
147
|
-
const {
|
|
148
|
-
const report = await
|
|
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: "
|
|
154
|
+
options.progressCallback({ tool: "aiSignalClarity", data: report });
|
|
155
155
|
}
|
|
156
|
-
result.
|
|
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", "
|
|
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) =>
|
|
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 = ["
|
|
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.
|
|
522
|
-
const { calculateHallucinationScore } = await import("@aiready/
|
|
538
|
+
if (results.aiSignalClarity) {
|
|
539
|
+
const { calculateHallucinationScore } = await import("@aiready/ai-signal-clarity");
|
|
523
540
|
try {
|
|
524
|
-
const hrScore = calculateHallucinationScore(results.
|
|
525
|
-
toolScores.set("
|
|
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:
|
|
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/
|
|
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,
|
|
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-
|
|
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", "
|
|
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) =>
|
|
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 = ["
|
|
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.
|
|
364
|
-
const { calculateHallucinationScore } = await import("@aiready/
|
|
367
|
+
if (results.aiSignalClarity) {
|
|
368
|
+
const { calculateHallucinationScore } = await import("@aiready/ai-signal-clarity");
|
|
365
369
|
try {
|
|
366
|
-
const hrScore = calculateHallucinationScore(results.
|
|
367
|
-
toolScores.set("
|
|
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:
|
|
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/
|
|
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,
|
|
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("
|
|
145
|
-
const {
|
|
146
|
-
const report = await
|
|
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: "
|
|
152
|
+
options.progressCallback({ tool: "aiSignalClarity", data: report });
|
|
153
153
|
}
|
|
154
|
-
result.
|
|
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.
|
|
221
|
-
output += `\u{1F9E0}
|
|
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
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@aiready/cli",
|
|
3
|
-
"version": "0.9.
|
|
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/
|
|
15
|
-
"@aiready/
|
|
16
|
-
"@aiready/
|
|
17
|
-
"@aiready/
|
|
18
|
-
"@aiready/
|
|
19
|
-
"@aiready/
|
|
20
|
-
"@aiready/
|
|
21
|
-
"@aiready/
|
|
22
|
-
"@aiready/
|
|
23
|
-
"@aiready/
|
|
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,
|
|
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
|
-
*
|
|
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
|
|
11
|
+
export async function aiSignalClarityAction(
|
|
12
12
|
directory: string,
|
|
13
13
|
options: any,
|
|
14
14
|
): Promise<ToolScoringOutput | undefined> {
|
|
15
|
-
const {
|
|
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
|
|
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(` 🧠
|
|
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`));
|