@aiready/cli 0.9.36 → 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 +11 -18
- package/.turbo/turbo-test.log +5 -5
- package/README.md +27 -287
- package/dist/chunk-JQG7ZATX.mjs +211 -0
- package/dist/chunk-M7O2MEM5.mjs +211 -0
- package/dist/chunk-PDOONNSK.mjs +228 -0
- package/dist/cli.js +291 -370
- package/dist/cli.mjs +42 -25
- package/dist/index.js +68 -0
- package/dist/index.mjs +1 -2
- 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 +24 -20
- package/src/index.ts +81 -1
package/dist/cli.js
CHANGED
|
@@ -6,13 +6,6 @@ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
|
6
6
|
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
7
7
|
var __getProtoOf = Object.getPrototypeOf;
|
|
8
8
|
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
9
|
-
var __esm = (fn, res) => function __init() {
|
|
10
|
-
return fn && (res = (0, fn[__getOwnPropNames(fn)[0]])(fn = 0)), res;
|
|
11
|
-
};
|
|
12
|
-
var __export = (target, all) => {
|
|
13
|
-
for (var name in all)
|
|
14
|
-
__defProp(target, name, { get: all[name], enumerable: true });
|
|
15
|
-
};
|
|
16
9
|
var __copyProps = (to, from, except, desc) => {
|
|
17
10
|
if (from && typeof from === "object" || typeof from === "function") {
|
|
18
11
|
for (let key of __getOwnPropNames(from))
|
|
@@ -30,147 +23,6 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
|
|
|
30
23
|
mod
|
|
31
24
|
));
|
|
32
25
|
|
|
33
|
-
// src/commands/hallucination-risk.ts
|
|
34
|
-
var hallucination_risk_exports = {};
|
|
35
|
-
__export(hallucination_risk_exports, {
|
|
36
|
-
hallucinationRiskAction: () => hallucinationRiskAction
|
|
37
|
-
});
|
|
38
|
-
async function hallucinationRiskAction(directory, options) {
|
|
39
|
-
const { analyzeHallucinationRisk, calculateHallucinationScore } = await import("@aiready/hallucination-risk");
|
|
40
|
-
const config = await (0, import_core.loadConfig)(directory);
|
|
41
|
-
const merged = (0, import_core.mergeConfigWithDefaults)(config, {
|
|
42
|
-
minSeverity: "info"
|
|
43
|
-
});
|
|
44
|
-
const report = await analyzeHallucinationRisk({
|
|
45
|
-
rootDir: directory,
|
|
46
|
-
minSeverity: options.minSeverity ?? merged.minSeverity ?? "info",
|
|
47
|
-
include: options.include,
|
|
48
|
-
exclude: options.exclude
|
|
49
|
-
});
|
|
50
|
-
const scoring = calculateHallucinationScore(report);
|
|
51
|
-
if (options.output === "json") {
|
|
52
|
-
return scoring;
|
|
53
|
-
}
|
|
54
|
-
const { summary } = report;
|
|
55
|
-
const ratingColors = {
|
|
56
|
-
minimal: import_chalk2.default.green,
|
|
57
|
-
low: import_chalk2.default.cyan,
|
|
58
|
-
moderate: import_chalk2.default.yellow,
|
|
59
|
-
high: import_chalk2.default.red,
|
|
60
|
-
severe: import_chalk2.default.bgRed.white
|
|
61
|
-
};
|
|
62
|
-
const color = ratingColors[summary.rating] ?? import_chalk2.default.white;
|
|
63
|
-
console.log(` \u{1F9E0} Hallucination Risk: ${import_chalk2.default.bold(scoring.score + "/100")} (${color(summary.rating)})`);
|
|
64
|
-
console.log(` Top Risk: ${import_chalk2.default.italic(summary.topRisk)}`);
|
|
65
|
-
if (summary.totalSignals > 0) {
|
|
66
|
-
console.log(import_chalk2.default.dim(` ${summary.criticalSignals} critical ${summary.majorSignals} major ${summary.minorSignals} minor signals`));
|
|
67
|
-
}
|
|
68
|
-
return scoring;
|
|
69
|
-
}
|
|
70
|
-
var import_chalk2, import_core;
|
|
71
|
-
var init_hallucination_risk = __esm({
|
|
72
|
-
"src/commands/hallucination-risk.ts"() {
|
|
73
|
-
"use strict";
|
|
74
|
-
import_chalk2 = __toESM(require("chalk"));
|
|
75
|
-
import_core = require("@aiready/core");
|
|
76
|
-
}
|
|
77
|
-
});
|
|
78
|
-
|
|
79
|
-
// src/commands/agent-grounding.ts
|
|
80
|
-
var agent_grounding_exports = {};
|
|
81
|
-
__export(agent_grounding_exports, {
|
|
82
|
-
agentGroundingAction: () => agentGroundingAction
|
|
83
|
-
});
|
|
84
|
-
async function agentGroundingAction(directory, options) {
|
|
85
|
-
const { analyzeAgentGrounding, calculateGroundingScore } = await import("@aiready/agent-grounding");
|
|
86
|
-
const config = await (0, import_core2.loadConfig)(directory);
|
|
87
|
-
const merged = (0, import_core2.mergeConfigWithDefaults)(config, {
|
|
88
|
-
maxRecommendedDepth: 4,
|
|
89
|
-
readmeStaleDays: 90
|
|
90
|
-
});
|
|
91
|
-
const report = await analyzeAgentGrounding({
|
|
92
|
-
rootDir: directory,
|
|
93
|
-
maxRecommendedDepth: options.maxDepth ?? merged.maxRecommendedDepth,
|
|
94
|
-
readmeStaleDays: options.readmeStaleDays ?? merged.readmeStaleDays,
|
|
95
|
-
include: options.include,
|
|
96
|
-
exclude: options.exclude
|
|
97
|
-
});
|
|
98
|
-
const scoring = calculateGroundingScore(report);
|
|
99
|
-
if (options.output === "json") {
|
|
100
|
-
return scoring;
|
|
101
|
-
}
|
|
102
|
-
const scoreColor = (s) => s >= 85 ? import_chalk3.default.green : s >= 70 ? import_chalk3.default.cyan : s >= 50 ? import_chalk3.default.yellow : import_chalk3.default.red;
|
|
103
|
-
console.log(` \u{1F9ED} Agent Grounding: ${import_chalk3.default.bold(scoring.score + "/100")} (${report.summary.rating})`);
|
|
104
|
-
const dims = report.summary.dimensions;
|
|
105
|
-
const worstDim = Object.entries(dims).sort(([, a], [, b]) => a - b)[0];
|
|
106
|
-
if (worstDim && worstDim[1] < 70) {
|
|
107
|
-
const name = worstDim[0].replace(/([A-Z])/g, " $1").replace("Score", "").trim();
|
|
108
|
-
console.log(import_chalk3.default.dim(` Weakest dimension: ${name} (${worstDim[1]}/100)`));
|
|
109
|
-
}
|
|
110
|
-
return scoring;
|
|
111
|
-
}
|
|
112
|
-
var import_chalk3, import_core2;
|
|
113
|
-
var init_agent_grounding = __esm({
|
|
114
|
-
"src/commands/agent-grounding.ts"() {
|
|
115
|
-
"use strict";
|
|
116
|
-
import_chalk3 = __toESM(require("chalk"));
|
|
117
|
-
import_core2 = require("@aiready/core");
|
|
118
|
-
}
|
|
119
|
-
});
|
|
120
|
-
|
|
121
|
-
// src/commands/testability.ts
|
|
122
|
-
var testability_exports = {};
|
|
123
|
-
__export(testability_exports, {
|
|
124
|
-
testabilityAction: () => testabilityAction
|
|
125
|
-
});
|
|
126
|
-
async function testabilityAction(directory, options) {
|
|
127
|
-
const { analyzeTestability, calculateTestabilityScore } = await import("@aiready/testability");
|
|
128
|
-
const config = await (0, import_core3.loadConfig)(directory);
|
|
129
|
-
const merged = (0, import_core3.mergeConfigWithDefaults)(config, {
|
|
130
|
-
minCoverageRatio: 0.3
|
|
131
|
-
});
|
|
132
|
-
const report = await analyzeTestability({
|
|
133
|
-
rootDir: directory,
|
|
134
|
-
minCoverageRatio: options.minCoverageRatio ?? merged.minCoverageRatio,
|
|
135
|
-
include: options.include,
|
|
136
|
-
exclude: options.exclude
|
|
137
|
-
});
|
|
138
|
-
const scoring = calculateTestabilityScore(report);
|
|
139
|
-
if (options.output === "json") {
|
|
140
|
-
return scoring;
|
|
141
|
-
}
|
|
142
|
-
const safetyIcons = {
|
|
143
|
-
"safe": "\u2705",
|
|
144
|
-
"moderate-risk": "\u26A0\uFE0F ",
|
|
145
|
-
"high-risk": "\u{1F534}",
|
|
146
|
-
"blind-risk": "\u{1F480}"
|
|
147
|
-
};
|
|
148
|
-
const safetyColors = {
|
|
149
|
-
"safe": import_chalk4.default.green,
|
|
150
|
-
"moderate-risk": import_chalk4.default.yellow,
|
|
151
|
-
"high-risk": import_chalk4.default.red,
|
|
152
|
-
"blind-risk": import_chalk4.default.bgRed.white
|
|
153
|
-
};
|
|
154
|
-
const safety = report.summary.aiChangeSafetyRating;
|
|
155
|
-
const icon = safetyIcons[safety] ?? "\u2753";
|
|
156
|
-
const color = safetyColors[safety] ?? import_chalk4.default.white;
|
|
157
|
-
console.log(` \u{1F9EA} Testability: ${import_chalk4.default.bold(scoring.score + "/100")} (${report.summary.rating})`);
|
|
158
|
-
console.log(` AI Change Safety: ${color(`${icon} ${safety.toUpperCase()}`)}`);
|
|
159
|
-
console.log(import_chalk4.default.dim(` Coverage: ${Math.round(report.summary.coverageRatio * 100)}% (${report.rawData.testFiles} test / ${report.rawData.sourceFiles} source files)`));
|
|
160
|
-
if (safety === "blind-risk") {
|
|
161
|
-
console.log(import_chalk4.default.red.bold("\n \u26A0\uFE0F NO TESTS \u2014 AI changes to this codebase are completely unverifiable!\n"));
|
|
162
|
-
}
|
|
163
|
-
return scoring;
|
|
164
|
-
}
|
|
165
|
-
var import_chalk4, import_core3;
|
|
166
|
-
var init_testability = __esm({
|
|
167
|
-
"src/commands/testability.ts"() {
|
|
168
|
-
"use strict";
|
|
169
|
-
import_chalk4 = __toESM(require("chalk"));
|
|
170
|
-
import_core3 = require("@aiready/core");
|
|
171
|
-
}
|
|
172
|
-
});
|
|
173
|
-
|
|
174
26
|
// src/cli.ts
|
|
175
27
|
var import_commander = require("commander");
|
|
176
28
|
var import_fs5 = require("fs");
|
|
@@ -178,10 +30,10 @@ var import_path7 = require("path");
|
|
|
178
30
|
var import_url = require("url");
|
|
179
31
|
|
|
180
32
|
// src/commands/scan.ts
|
|
181
|
-
var
|
|
33
|
+
var import_chalk2 = __toESM(require("chalk"));
|
|
182
34
|
var import_fs2 = require("fs");
|
|
183
35
|
var import_path2 = require("path");
|
|
184
|
-
var
|
|
36
|
+
var import_core = require("@aiready/core");
|
|
185
37
|
|
|
186
38
|
// src/index.ts
|
|
187
39
|
var import_pattern_detect = require("@aiready/pattern-detect");
|
|
@@ -291,6 +143,58 @@ async function analyzeUnified(options) {
|
|
|
291
143
|
result.deps = report;
|
|
292
144
|
result.summary.totalIssues += report.issues?.length || 0;
|
|
293
145
|
}
|
|
146
|
+
if (tools.includes("aiSignalClarity")) {
|
|
147
|
+
const { analyzeAiSignalClarity } = await import("@aiready/ai-signal-clarity");
|
|
148
|
+
const report = await analyzeAiSignalClarity({
|
|
149
|
+
rootDir: options.rootDir,
|
|
150
|
+
include: options.include,
|
|
151
|
+
exclude: options.exclude
|
|
152
|
+
});
|
|
153
|
+
if (options.progressCallback) {
|
|
154
|
+
options.progressCallback({ tool: "aiSignalClarity", data: report });
|
|
155
|
+
}
|
|
156
|
+
result.aiSignalClarity = report;
|
|
157
|
+
result.summary.totalIssues += report.results?.reduce((sum, r) => sum + (r.issues?.length || 0), 0) || 0;
|
|
158
|
+
}
|
|
159
|
+
if (tools.includes("grounding")) {
|
|
160
|
+
const { analyzeAgentGrounding } = await import("@aiready/agent-grounding");
|
|
161
|
+
const report = await analyzeAgentGrounding({
|
|
162
|
+
rootDir: options.rootDir,
|
|
163
|
+
include: options.include,
|
|
164
|
+
exclude: options.exclude
|
|
165
|
+
});
|
|
166
|
+
if (options.progressCallback) {
|
|
167
|
+
options.progressCallback({ tool: "grounding", data: report });
|
|
168
|
+
}
|
|
169
|
+
result.grounding = report;
|
|
170
|
+
result.summary.totalIssues += report.issues?.length || 0;
|
|
171
|
+
}
|
|
172
|
+
if (tools.includes("testability")) {
|
|
173
|
+
const { analyzeTestability } = await import("@aiready/testability");
|
|
174
|
+
const report = await analyzeTestability({
|
|
175
|
+
rootDir: options.rootDir,
|
|
176
|
+
include: options.include,
|
|
177
|
+
exclude: options.exclude
|
|
178
|
+
});
|
|
179
|
+
if (options.progressCallback) {
|
|
180
|
+
options.progressCallback({ tool: "testability", data: report });
|
|
181
|
+
}
|
|
182
|
+
result.testability = report;
|
|
183
|
+
result.summary.totalIssues += report.issues?.length || 0;
|
|
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
|
+
}
|
|
294
198
|
result.summary.executionTime = Date.now() - startTime;
|
|
295
199
|
return result;
|
|
296
200
|
}
|
|
@@ -402,12 +306,12 @@ function truncateArray(arr, cap = 8) {
|
|
|
402
306
|
|
|
403
307
|
// src/commands/scan.ts
|
|
404
308
|
async function scanAction(directory, options) {
|
|
405
|
-
console.log(
|
|
309
|
+
console.log(import_chalk2.default.blue("\u{1F680} Starting AIReady unified analysis...\n"));
|
|
406
310
|
const startTime = Date.now();
|
|
407
311
|
const resolvedDir = (0, import_path2.resolve)(process.cwd(), directory || ".");
|
|
408
312
|
try {
|
|
409
313
|
const defaults = {
|
|
410
|
-
tools: ["patterns", "context", "consistency", "
|
|
314
|
+
tools: ["patterns", "context", "consistency", "aiSignalClarity", "grounding", "testability", "doc-drift", "deps-health"],
|
|
411
315
|
include: void 0,
|
|
412
316
|
exclude: void 0,
|
|
413
317
|
output: {
|
|
@@ -415,11 +319,15 @@ async function scanAction(directory, options) {
|
|
|
415
319
|
file: void 0
|
|
416
320
|
}
|
|
417
321
|
};
|
|
418
|
-
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;
|
|
419
327
|
if (options.profile) {
|
|
420
328
|
switch (options.profile.toLowerCase()) {
|
|
421
329
|
case "agentic":
|
|
422
|
-
profileTools = ["
|
|
330
|
+
profileTools = ["aiSignalClarity", "grounding", "testability"];
|
|
423
331
|
break;
|
|
424
332
|
case "cost":
|
|
425
333
|
profileTools = ["patterns", "context"];
|
|
@@ -431,11 +339,11 @@ async function scanAction(directory, options) {
|
|
|
431
339
|
profileTools = ["context", "consistency", "grounding"];
|
|
432
340
|
break;
|
|
433
341
|
default:
|
|
434
|
-
console.log(
|
|
342
|
+
console.log(import_chalk2.default.yellow(`
|
|
435
343
|
\u26A0\uFE0F Unknown profile '${options.profile}'. Using specified tools or defaults.`));
|
|
436
344
|
}
|
|
437
345
|
}
|
|
438
|
-
const baseOptions = await (0,
|
|
346
|
+
const baseOptions = await (0, import_core.loadMergedConfig)(resolvedDir, defaults, {
|
|
439
347
|
tools: profileTools,
|
|
440
348
|
include: options.include?.split(","),
|
|
441
349
|
exclude: options.exclude?.split(",")
|
|
@@ -446,13 +354,13 @@ async function scanAction(directory, options) {
|
|
|
446
354
|
const patternSmartDefaults = await getSmartDefaults(resolvedDir, baseOptions);
|
|
447
355
|
finalOptions = { ...patternSmartDefaults, ...finalOptions, ...baseOptions };
|
|
448
356
|
}
|
|
449
|
-
console.log(
|
|
450
|
-
console.log(
|
|
451
|
-
console.log(
|
|
452
|
-
console.log(
|
|
453
|
-
if (finalOptions.rootDir) console.log(` rootDir: ${
|
|
454
|
-
if (finalOptions.include) console.log(` include: ${
|
|
455
|
-
if (finalOptions.exclude) console.log(` exclude: ${
|
|
357
|
+
console.log(import_chalk2.default.cyan("\n=== AIReady Run Preview ==="));
|
|
358
|
+
console.log(import_chalk2.default.white("Tools to run:"), (finalOptions.tools || ["patterns", "context", "consistency"]).join(", "));
|
|
359
|
+
console.log(import_chalk2.default.white("Will use settings from config and defaults."));
|
|
360
|
+
console.log(import_chalk2.default.white("\nGeneral settings:"));
|
|
361
|
+
if (finalOptions.rootDir) console.log(` rootDir: ${import_chalk2.default.bold(String(finalOptions.rootDir))}`);
|
|
362
|
+
if (finalOptions.include) console.log(` include: ${import_chalk2.default.bold(truncateArray(finalOptions.include, 6))}`);
|
|
363
|
+
if (finalOptions.exclude) console.log(` exclude: ${import_chalk2.default.bold(truncateArray(finalOptions.exclude, 6))}`);
|
|
456
364
|
if (finalOptions["pattern-detect"] || finalOptions.minSimilarity) {
|
|
457
365
|
const patternDetectConfig = finalOptions["pattern-detect"] || {
|
|
458
366
|
minSimilarity: finalOptions.minSimilarity,
|
|
@@ -465,16 +373,16 @@ async function scanAction(directory, options) {
|
|
|
465
373
|
severity: finalOptions.severity,
|
|
466
374
|
includeTests: finalOptions.includeTests
|
|
467
375
|
};
|
|
468
|
-
console.log(
|
|
469
|
-
console.log(` minSimilarity: ${
|
|
470
|
-
console.log(` minLines: ${
|
|
471
|
-
if (patternDetectConfig.approx !== void 0) console.log(` approx: ${
|
|
472
|
-
if (patternDetectConfig.minSharedTokens !== void 0) console.log(` minSharedTokens: ${
|
|
473
|
-
if (patternDetectConfig.maxCandidatesPerBlock !== void 0) console.log(` maxCandidatesPerBlock: ${
|
|
474
|
-
if (patternDetectConfig.batchSize !== void 0) console.log(` batchSize: ${
|
|
475
|
-
if (patternDetectConfig.streamResults !== void 0) console.log(` streamResults: ${
|
|
476
|
-
if (patternDetectConfig.severity !== void 0) console.log(` severity: ${
|
|
477
|
-
if (patternDetectConfig.includeTests !== void 0) console.log(` includeTests: ${
|
|
376
|
+
console.log(import_chalk2.default.white("\nPattern-detect settings:"));
|
|
377
|
+
console.log(` minSimilarity: ${import_chalk2.default.bold(patternDetectConfig.minSimilarity ?? "default")}`);
|
|
378
|
+
console.log(` minLines: ${import_chalk2.default.bold(patternDetectConfig.minLines ?? "default")}`);
|
|
379
|
+
if (patternDetectConfig.approx !== void 0) console.log(` approx: ${import_chalk2.default.bold(String(patternDetectConfig.approx))}`);
|
|
380
|
+
if (patternDetectConfig.minSharedTokens !== void 0) console.log(` minSharedTokens: ${import_chalk2.default.bold(String(patternDetectConfig.minSharedTokens))}`);
|
|
381
|
+
if (patternDetectConfig.maxCandidatesPerBlock !== void 0) console.log(` maxCandidatesPerBlock: ${import_chalk2.default.bold(String(patternDetectConfig.maxCandidatesPerBlock))}`);
|
|
382
|
+
if (patternDetectConfig.batchSize !== void 0) console.log(` batchSize: ${import_chalk2.default.bold(String(patternDetectConfig.batchSize))}`);
|
|
383
|
+
if (patternDetectConfig.streamResults !== void 0) console.log(` streamResults: ${import_chalk2.default.bold(String(patternDetectConfig.streamResults))}`);
|
|
384
|
+
if (patternDetectConfig.severity !== void 0) console.log(` severity: ${import_chalk2.default.bold(String(patternDetectConfig.severity))}`);
|
|
385
|
+
if (patternDetectConfig.includeTests !== void 0) console.log(` includeTests: ${import_chalk2.default.bold(String(patternDetectConfig.includeTests))}`);
|
|
478
386
|
}
|
|
479
387
|
if (finalOptions["context-analyzer"] || finalOptions.maxDepth) {
|
|
480
388
|
const ca = finalOptions["context-analyzer"] || {
|
|
@@ -484,32 +392,32 @@ async function scanAction(directory, options) {
|
|
|
484
392
|
maxFragmentation: finalOptions.maxFragmentation,
|
|
485
393
|
includeNodeModules: finalOptions.includeNodeModules
|
|
486
394
|
};
|
|
487
|
-
console.log(
|
|
488
|
-
console.log(` maxDepth: ${
|
|
489
|
-
console.log(` maxContextBudget: ${
|
|
490
|
-
if (ca.minCohesion !== void 0) console.log(` minCohesion: ${
|
|
491
|
-
if (ca.maxFragmentation !== void 0) console.log(` maxFragmentation: ${
|
|
492
|
-
if (ca.includeNodeModules !== void 0) console.log(` includeNodeModules: ${
|
|
395
|
+
console.log(import_chalk2.default.white("\nContext-analyzer settings:"));
|
|
396
|
+
console.log(` maxDepth: ${import_chalk2.default.bold(ca.maxDepth ?? "default")}`);
|
|
397
|
+
console.log(` maxContextBudget: ${import_chalk2.default.bold(ca.maxContextBudget ?? "default")}`);
|
|
398
|
+
if (ca.minCohesion !== void 0) console.log(` minCohesion: ${import_chalk2.default.bold(String(ca.minCohesion))}`);
|
|
399
|
+
if (ca.maxFragmentation !== void 0) console.log(` maxFragmentation: ${import_chalk2.default.bold(String(ca.maxFragmentation))}`);
|
|
400
|
+
if (ca.includeNodeModules !== void 0) console.log(` includeNodeModules: ${import_chalk2.default.bold(String(ca.includeNodeModules))}`);
|
|
493
401
|
}
|
|
494
402
|
if (finalOptions.consistency) {
|
|
495
403
|
const c = finalOptions.consistency;
|
|
496
|
-
console.log(
|
|
497
|
-
console.log(` checkNaming: ${
|
|
498
|
-
console.log(` checkPatterns: ${
|
|
499
|
-
console.log(` checkArchitecture: ${
|
|
500
|
-
if (c.minSeverity) console.log(` minSeverity: ${
|
|
501
|
-
if (c.acceptedAbbreviations) console.log(` acceptedAbbreviations: ${
|
|
502
|
-
if (c.shortWords) console.log(` shortWords: ${
|
|
404
|
+
console.log(import_chalk2.default.white("\nConsistency settings:"));
|
|
405
|
+
console.log(` checkNaming: ${import_chalk2.default.bold(String(c.checkNaming ?? true))}`);
|
|
406
|
+
console.log(` checkPatterns: ${import_chalk2.default.bold(String(c.checkPatterns ?? true))}`);
|
|
407
|
+
console.log(` checkArchitecture: ${import_chalk2.default.bold(String(c.checkArchitecture ?? false))}`);
|
|
408
|
+
if (c.minSeverity) console.log(` minSeverity: ${import_chalk2.default.bold(c.minSeverity)}`);
|
|
409
|
+
if (c.acceptedAbbreviations) console.log(` acceptedAbbreviations: ${import_chalk2.default.bold(truncateArray(c.acceptedAbbreviations, 8))}`);
|
|
410
|
+
if (c.shortWords) console.log(` shortWords: ${import_chalk2.default.bold(truncateArray(c.shortWords, 8))}`);
|
|
503
411
|
}
|
|
504
|
-
console.log(
|
|
412
|
+
console.log(import_chalk2.default.white("\nStarting analysis..."));
|
|
505
413
|
const progressCallback = (event) => {
|
|
506
|
-
console.log(
|
|
414
|
+
console.log(import_chalk2.default.cyan(`
|
|
507
415
|
--- ${event.tool.toUpperCase()} RESULTS ---`));
|
|
508
416
|
try {
|
|
509
417
|
if (event.tool === "patterns") {
|
|
510
418
|
const pr = event.data;
|
|
511
|
-
console.log(` Duplicate patterns: ${
|
|
512
|
-
console.log(` Files with pattern issues: ${
|
|
419
|
+
console.log(` Duplicate patterns: ${import_chalk2.default.bold(String(pr.duplicates?.length || 0))}`);
|
|
420
|
+
console.log(` Files with pattern issues: ${import_chalk2.default.bold(String(pr.results?.length || 0))}`);
|
|
513
421
|
if (pr.duplicates && pr.duplicates.length > 0) {
|
|
514
422
|
pr.duplicates.slice(0, 5).forEach((d, i) => {
|
|
515
423
|
console.log(` ${i + 1}. ${d.file1.split("/").pop()} \u2194 ${d.file2.split("/").pop()} (sim=${(d.similarity * 100).toFixed(1)}%)`);
|
|
@@ -523,10 +431,10 @@ async function scanAction(directory, options) {
|
|
|
523
431
|
});
|
|
524
432
|
}
|
|
525
433
|
if (pr.groups && pr.groups.length >= 0) {
|
|
526
|
-
console.log(` \u2705 Grouped ${
|
|
434
|
+
console.log(` \u2705 Grouped ${import_chalk2.default.bold(String(pr.duplicates?.length || 0))} duplicates into ${import_chalk2.default.bold(String(pr.groups.length))} file pairs`);
|
|
527
435
|
}
|
|
528
436
|
if (pr.clusters && pr.clusters.length >= 0) {
|
|
529
|
-
console.log(` \u2705 Created ${
|
|
437
|
+
console.log(` \u2705 Created ${import_chalk2.default.bold(String(pr.clusters.length))} refactor clusters`);
|
|
530
438
|
pr.clusters.slice(0, 3).forEach((cl, idx) => {
|
|
531
439
|
const files = (cl.files || []).map((f) => f.path.split("/").pop()).join(", ");
|
|
532
440
|
console.log(` ${idx + 1}. ${files} (${cl.tokenCost || "n/a"} tokens)`);
|
|
@@ -534,14 +442,14 @@ async function scanAction(directory, options) {
|
|
|
534
442
|
}
|
|
535
443
|
} else if (event.tool === "context") {
|
|
536
444
|
const cr = event.data;
|
|
537
|
-
console.log(` Context issues found: ${
|
|
445
|
+
console.log(` Context issues found: ${import_chalk2.default.bold(String(cr.length || 0))}`);
|
|
538
446
|
cr.slice(0, 5).forEach((c, i) => {
|
|
539
447
|
const msg = c.message ? ` - ${c.message}` : "";
|
|
540
448
|
console.log(` ${i + 1}. ${c.file} (${c.severity || "n/a"})${msg}`);
|
|
541
449
|
});
|
|
542
450
|
} else if (event.tool === "consistency") {
|
|
543
451
|
const rep = event.data;
|
|
544
|
-
console.log(` Consistency totalIssues: ${
|
|
452
|
+
console.log(` Consistency totalIssues: ${import_chalk2.default.bold(String(rep.summary?.totalIssues || 0))}`);
|
|
545
453
|
if (rep.results && rep.results.length > 0) {
|
|
546
454
|
const fileMap = /* @__PURE__ */ new Map();
|
|
547
455
|
rep.results.forEach((r) => {
|
|
@@ -565,38 +473,38 @@ async function scanAction(directory, options) {
|
|
|
565
473
|
});
|
|
566
474
|
const remaining = files.length - topFiles.length;
|
|
567
475
|
if (remaining > 0) {
|
|
568
|
-
console.log(
|
|
476
|
+
console.log(import_chalk2.default.dim(` ... and ${remaining} more files with issues (use --output json for full details)`));
|
|
569
477
|
}
|
|
570
478
|
}
|
|
571
479
|
} else if (event.tool === "doc-drift") {
|
|
572
480
|
const dr = event.data;
|
|
573
|
-
console.log(` Issues found: ${
|
|
481
|
+
console.log(` Issues found: ${import_chalk2.default.bold(String(dr.issues?.length || 0))}`);
|
|
574
482
|
if (dr.rawData) {
|
|
575
|
-
console.log(` Signature Mismatches: ${
|
|
576
|
-
console.log(` Undocumented Complexity: ${
|
|
483
|
+
console.log(` Signature Mismatches: ${import_chalk2.default.bold(dr.rawData.outdatedComments || 0)}`);
|
|
484
|
+
console.log(` Undocumented Complexity: ${import_chalk2.default.bold(dr.rawData.undocumentedComplexity || 0)}`);
|
|
577
485
|
}
|
|
578
486
|
} else if (event.tool === "deps-health") {
|
|
579
487
|
const dr = event.data;
|
|
580
|
-
console.log(` Packages Analyzed: ${
|
|
488
|
+
console.log(` Packages Analyzed: ${import_chalk2.default.bold(String(dr.summary?.packagesAnalyzed || 0))}`);
|
|
581
489
|
if (dr.rawData) {
|
|
582
|
-
console.log(` Deprecated Packages: ${
|
|
583
|
-
console.log(` AI Cutoff Skew Score: ${
|
|
490
|
+
console.log(` Deprecated Packages: ${import_chalk2.default.bold(dr.rawData.deprecatedPackages || 0)}`);
|
|
491
|
+
console.log(` AI Cutoff Skew Score: ${import_chalk2.default.bold(dr.rawData.trainingCutoffSkew?.toFixed(1) || 0)}`);
|
|
584
492
|
}
|
|
585
493
|
}
|
|
586
494
|
} catch (err) {
|
|
587
495
|
}
|
|
588
496
|
};
|
|
589
497
|
const results = await analyzeUnified({ ...finalOptions, progressCallback, suppressToolConfig: true });
|
|
590
|
-
console.log(
|
|
591
|
-
console.log(
|
|
592
|
-
console.log(
|
|
593
|
-
console.log(` Total issues (all tools): ${
|
|
594
|
-
if (results.duplicates) console.log(` Duplicate patterns found: ${
|
|
595
|
-
if (results.patterns) console.log(` Pattern files with issues: ${
|
|
596
|
-
if (results.context) console.log(` Context issues: ${
|
|
597
|
-
if (results.consistency) console.log(` Consistency issues: ${
|
|
598
|
-
console.log(
|
|
599
|
-
const elapsedTime = (0,
|
|
498
|
+
console.log(import_chalk2.default.cyan("\n=== AIReady Run Summary ==="));
|
|
499
|
+
console.log(import_chalk2.default.white("Tools run:"), (finalOptions.tools || ["patterns", "context", "consistency"]).join(", "));
|
|
500
|
+
console.log(import_chalk2.default.cyan("\nResults summary:"));
|
|
501
|
+
console.log(` Total issues (all tools): ${import_chalk2.default.bold(String(results.summary.totalIssues || 0))}`);
|
|
502
|
+
if (results.duplicates) console.log(` Duplicate patterns found: ${import_chalk2.default.bold(String(results.duplicates.length || 0))}`);
|
|
503
|
+
if (results.patterns) console.log(` Pattern files with issues: ${import_chalk2.default.bold(String(results.patterns.length || 0))}`);
|
|
504
|
+
if (results.context) console.log(` Context issues: ${import_chalk2.default.bold(String(results.context.length || 0))}`);
|
|
505
|
+
if (results.consistency) console.log(` Consistency issues: ${import_chalk2.default.bold(String(results.consistency.summary.totalIssues || 0))}`);
|
|
506
|
+
console.log(import_chalk2.default.cyan("===========================\n"));
|
|
507
|
+
const elapsedTime = (0, import_core.getElapsedTime)(startTime);
|
|
600
508
|
let scoringResult;
|
|
601
509
|
if (options.score || finalOptions.scoring?.showBreakdown) {
|
|
602
510
|
const toolScores = /* @__PURE__ */ new Map();
|
|
@@ -627,27 +535,27 @@ async function scanAction(directory, options) {
|
|
|
627
535
|
} catch (err) {
|
|
628
536
|
}
|
|
629
537
|
}
|
|
630
|
-
if (
|
|
538
|
+
if (results.aiSignalClarity) {
|
|
539
|
+
const { calculateHallucinationScore } = await import("@aiready/ai-signal-clarity");
|
|
631
540
|
try {
|
|
632
|
-
const
|
|
633
|
-
|
|
634
|
-
if (hrScore) toolScores.set("hallucination-risk", hrScore);
|
|
541
|
+
const hrScore = calculateHallucinationScore(results.aiSignalClarity);
|
|
542
|
+
toolScores.set("ai-signal-clarity", hrScore);
|
|
635
543
|
} catch (err) {
|
|
636
544
|
}
|
|
637
545
|
}
|
|
638
|
-
if (
|
|
546
|
+
if (results.grounding) {
|
|
547
|
+
const { calculateGroundingScore } = await import("@aiready/agent-grounding");
|
|
639
548
|
try {
|
|
640
|
-
const
|
|
641
|
-
|
|
642
|
-
if (agScore) toolScores.set("agent-grounding", agScore);
|
|
549
|
+
const agScore = calculateGroundingScore(results.grounding);
|
|
550
|
+
toolScores.set("agent-grounding", agScore);
|
|
643
551
|
} catch (err) {
|
|
644
552
|
}
|
|
645
553
|
}
|
|
646
|
-
if (
|
|
554
|
+
if (results.testability) {
|
|
555
|
+
const { calculateTestabilityScore } = await import("@aiready/testability");
|
|
647
556
|
try {
|
|
648
|
-
const
|
|
649
|
-
|
|
650
|
-
if (tbScore) toolScores.set("testability", tbScore);
|
|
557
|
+
const tbScore = calculateTestabilityScore(results.testability);
|
|
558
|
+
toolScores.set("testability", tbScore);
|
|
651
559
|
} catch (err) {
|
|
652
560
|
}
|
|
653
561
|
}
|
|
@@ -669,11 +577,11 @@ async function scanAction(directory, options) {
|
|
|
669
577
|
recommendations: results.deps.recommendations.map((action) => ({ action, estimatedImpact: 5, priority: "medium" }))
|
|
670
578
|
});
|
|
671
579
|
}
|
|
672
|
-
const cliWeights = (0,
|
|
580
|
+
const cliWeights = (0, import_core.parseWeightString)(options.weights);
|
|
673
581
|
if (toolScores.size > 0) {
|
|
674
|
-
scoringResult = (0,
|
|
675
|
-
console.log(
|
|
676
|
-
console.log(` ${(0,
|
|
582
|
+
scoringResult = (0, import_core.calculateOverallScore)(toolScores, finalOptions, cliWeights.size ? cliWeights : void 0);
|
|
583
|
+
console.log(import_chalk2.default.bold("\n\u{1F4CA} AI Readiness Overall Score"));
|
|
584
|
+
console.log(` ${(0, import_core.formatScore)(scoringResult)}`);
|
|
677
585
|
if (options.compareTo) {
|
|
678
586
|
try {
|
|
679
587
|
const prevReportStr = (0, import_fs2.readFileSync)((0, import_path2.resolve)(process.cwd(), options.compareTo), "utf8");
|
|
@@ -684,37 +592,37 @@ async function scanAction(directory, options) {
|
|
|
684
592
|
const diffStr = diff > 0 ? `+${diff}` : String(diff);
|
|
685
593
|
console.log();
|
|
686
594
|
if (diff > 0) {
|
|
687
|
-
console.log(
|
|
595
|
+
console.log(import_chalk2.default.green(` \u{1F4C8} Trend: ${diffStr} compared to ${options.compareTo} (${prevScore} \u2192 ${scoringResult.overall})`));
|
|
688
596
|
} else if (diff < 0) {
|
|
689
|
-
console.log(
|
|
597
|
+
console.log(import_chalk2.default.red(` \u{1F4C9} Trend: ${diffStr} compared to ${options.compareTo} (${prevScore} \u2192 ${scoringResult.overall})`));
|
|
690
598
|
} else {
|
|
691
|
-
console.log(
|
|
599
|
+
console.log(import_chalk2.default.blue(` \u2796 Trend: No change compared to ${options.compareTo} (${prevScore} \u2192 ${scoringResult.overall})`));
|
|
692
600
|
}
|
|
693
601
|
scoringResult.trend = {
|
|
694
602
|
previousScore: prevScore,
|
|
695
603
|
difference: diff
|
|
696
604
|
};
|
|
697
605
|
} else {
|
|
698
|
-
console.log(
|
|
606
|
+
console.log(import_chalk2.default.yellow(`
|
|
699
607
|
\u26A0\uFE0F Previous report at ${options.compareTo} does not contain an overall score.`));
|
|
700
608
|
}
|
|
701
609
|
} catch (e) {
|
|
702
|
-
console.log(
|
|
610
|
+
console.log(import_chalk2.default.yellow(`
|
|
703
611
|
\u26A0\uFE0F Could not read or parse previous report at ${options.compareTo}.`));
|
|
704
612
|
}
|
|
705
613
|
}
|
|
706
614
|
if (scoringResult.breakdown && scoringResult.breakdown.length > 0) {
|
|
707
|
-
console.log(
|
|
615
|
+
console.log(import_chalk2.default.bold("\nTool breakdown:"));
|
|
708
616
|
scoringResult.breakdown.forEach((tool) => {
|
|
709
|
-
const rating = (0,
|
|
710
|
-
const rd = (0,
|
|
617
|
+
const rating = (0, import_core.getRating)(tool.score);
|
|
618
|
+
const rd = (0, import_core.getRatingDisplay)(rating);
|
|
711
619
|
console.log(` - ${tool.toolName}: ${tool.score}/100 (${rating}) ${rd.emoji}`);
|
|
712
620
|
});
|
|
713
621
|
console.log();
|
|
714
622
|
if (finalOptions.scoring?.showBreakdown) {
|
|
715
|
-
console.log(
|
|
623
|
+
console.log(import_chalk2.default.bold("Detailed tool breakdown:"));
|
|
716
624
|
scoringResult.breakdown.forEach((tool) => {
|
|
717
|
-
console.log((0,
|
|
625
|
+
console.log((0, import_core.formatToolScore)(tool));
|
|
718
626
|
});
|
|
719
627
|
console.log();
|
|
720
628
|
}
|
|
@@ -726,9 +634,9 @@ async function scanAction(directory, options) {
|
|
|
726
634
|
if (outputFormat === "json") {
|
|
727
635
|
const timestamp = getReportTimestamp();
|
|
728
636
|
const defaultFilename = `aiready-report-${timestamp}.json`;
|
|
729
|
-
const outputPath = (0,
|
|
637
|
+
const outputPath = (0, import_core.resolveOutputPath)(userOutputFile, defaultFilename, resolvedDir);
|
|
730
638
|
const outputData = { ...results, scoring: scoringResult };
|
|
731
|
-
(0,
|
|
639
|
+
(0, import_core.handleJSONOutput)(outputData, outputPath, `\u2705 Report saved to ${outputPath}`);
|
|
732
640
|
warnIfGraphCapExceeded(outputData, resolvedDir);
|
|
733
641
|
}
|
|
734
642
|
const isCI = options.ci || process.env.CI === "true" || process.env.GITHUB_ACTIONS === "true";
|
|
@@ -801,23 +709,23 @@ async function scanAction(directory, options) {
|
|
|
801
709
|
}
|
|
802
710
|
}
|
|
803
711
|
if (shouldFail) {
|
|
804
|
-
console.log(
|
|
805
|
-
console.log(
|
|
806
|
-
console.log(
|
|
807
|
-
console.log(
|
|
808
|
-
console.log(
|
|
809
|
-
console.log(
|
|
712
|
+
console.log(import_chalk2.default.red("\n\u{1F6AB} PR BLOCKED: AI Readiness Check Failed"));
|
|
713
|
+
console.log(import_chalk2.default.red(` Reason: ${failReason}`));
|
|
714
|
+
console.log(import_chalk2.default.dim("\n Remediation steps:"));
|
|
715
|
+
console.log(import_chalk2.default.dim(" 1. Run `aiready scan` locally to see detailed issues"));
|
|
716
|
+
console.log(import_chalk2.default.dim(" 2. Fix the critical issues before merging"));
|
|
717
|
+
console.log(import_chalk2.default.dim(" 3. Consider upgrading to Team plan for historical tracking: https://getaiready.dev/pricing"));
|
|
810
718
|
process.exit(1);
|
|
811
719
|
} else {
|
|
812
|
-
console.log(
|
|
720
|
+
console.log(import_chalk2.default.green("\n\u2705 PR PASSED: AI Readiness Check"));
|
|
813
721
|
if (threshold) {
|
|
814
|
-
console.log(
|
|
722
|
+
console.log(import_chalk2.default.green(` Score: ${scoringResult.overall}/100 (threshold: ${threshold})`));
|
|
815
723
|
}
|
|
816
|
-
console.log(
|
|
724
|
+
console.log(import_chalk2.default.dim("\n \u{1F4A1} Track historical trends: https://getaiready.dev \u2014 Team plan $99/mo"));
|
|
817
725
|
}
|
|
818
726
|
}
|
|
819
727
|
} catch (error) {
|
|
820
|
-
(0,
|
|
728
|
+
(0, import_core.handleCLIError)(error, "Analysis");
|
|
821
729
|
}
|
|
822
730
|
}
|
|
823
731
|
var scanHelpText = `
|
|
@@ -833,7 +741,7 @@ EXAMPLES:
|
|
|
833
741
|
$ aiready scan --output json --output-file report.json
|
|
834
742
|
|
|
835
743
|
PROFILES:
|
|
836
|
-
agentic:
|
|
744
|
+
agentic: aiSignalClarity, grounding, testability
|
|
837
745
|
cost: patterns, context
|
|
838
746
|
security: consistency, testability
|
|
839
747
|
onboarding: context, consistency, grounding
|
|
@@ -850,11 +758,11 @@ CI/CD INTEGRATION (Gatekeeper Mode):
|
|
|
850
758
|
`;
|
|
851
759
|
|
|
852
760
|
// src/commands/patterns.ts
|
|
853
|
-
var
|
|
761
|
+
var import_chalk3 = __toESM(require("chalk"));
|
|
854
762
|
var import_path3 = require("path");
|
|
855
|
-
var
|
|
763
|
+
var import_core2 = require("@aiready/core");
|
|
856
764
|
async function patternsAction(directory, options) {
|
|
857
|
-
console.log(
|
|
765
|
+
console.log(import_chalk3.default.blue("\u{1F50D} Analyzing patterns...\n"));
|
|
858
766
|
const startTime = Date.now();
|
|
859
767
|
const resolvedDir = (0, import_path3.resolve)(process.cwd(), directory || ".");
|
|
860
768
|
try {
|
|
@@ -885,10 +793,10 @@ async function patternsAction(directory, options) {
|
|
|
885
793
|
if (options.minSharedTokens) {
|
|
886
794
|
cliOptions.minSharedTokens = parseInt(options.minSharedTokens);
|
|
887
795
|
}
|
|
888
|
-
const finalOptions = await (0,
|
|
796
|
+
const finalOptions = await (0, import_core2.loadMergedConfig)(resolvedDir, defaults, cliOptions);
|
|
889
797
|
const { analyzePatterns: analyzePatterns2, generateSummary, calculatePatternScore } = await import("@aiready/pattern-detect");
|
|
890
798
|
const { results, duplicates } = await analyzePatterns2(finalOptions);
|
|
891
|
-
const elapsedTime = (0,
|
|
799
|
+
const elapsedTime = (0, import_core2.getElapsedTime)(startTime);
|
|
892
800
|
const summary = generateSummary(results);
|
|
893
801
|
let patternScore;
|
|
894
802
|
if (options.score) {
|
|
@@ -902,60 +810,60 @@ async function patternsAction(directory, options) {
|
|
|
902
810
|
summary: { ...summary, executionTime: parseFloat(elapsedTime) },
|
|
903
811
|
...patternScore && { scoring: patternScore }
|
|
904
812
|
};
|
|
905
|
-
const outputPath = (0,
|
|
813
|
+
const outputPath = (0, import_core2.resolveOutputPath)(
|
|
906
814
|
userOutputFile,
|
|
907
815
|
`aiready-report-${getReportTimestamp()}.json`,
|
|
908
816
|
resolvedDir
|
|
909
817
|
);
|
|
910
|
-
(0,
|
|
818
|
+
(0, import_core2.handleJSONOutput)(outputData, outputPath, `\u2705 Results saved to ${outputPath}`);
|
|
911
819
|
} else {
|
|
912
820
|
const terminalWidth = process.stdout.columns || 80;
|
|
913
821
|
const dividerWidth = Math.min(60, terminalWidth - 2);
|
|
914
822
|
const divider = "\u2501".repeat(dividerWidth);
|
|
915
|
-
console.log(
|
|
916
|
-
console.log(
|
|
917
|
-
console.log(
|
|
918
|
-
console.log(
|
|
919
|
-
console.log(
|
|
920
|
-
console.log(
|
|
921
|
-
console.log(
|
|
823
|
+
console.log(import_chalk3.default.cyan(divider));
|
|
824
|
+
console.log(import_chalk3.default.bold.white(" PATTERN ANALYSIS SUMMARY"));
|
|
825
|
+
console.log(import_chalk3.default.cyan(divider) + "\n");
|
|
826
|
+
console.log(import_chalk3.default.white(`\u{1F4C1} Files analyzed: ${import_chalk3.default.bold(results.length)}`));
|
|
827
|
+
console.log(import_chalk3.default.yellow(`\u26A0 Duplicate patterns found: ${import_chalk3.default.bold(summary.totalPatterns)}`));
|
|
828
|
+
console.log(import_chalk3.default.red(`\u{1F4B0} Token cost (wasted): ${import_chalk3.default.bold(summary.totalTokenCost.toLocaleString())}`));
|
|
829
|
+
console.log(import_chalk3.default.gray(`\u23F1 Analysis time: ${import_chalk3.default.bold(elapsedTime + "s")}`));
|
|
922
830
|
const sortedTypes = Object.entries(summary.patternsByType || {}).filter(([, count]) => count > 0).sort(([, a], [, b]) => b - a);
|
|
923
831
|
if (sortedTypes.length > 0) {
|
|
924
|
-
console.log(
|
|
925
|
-
console.log(
|
|
926
|
-
console.log(
|
|
832
|
+
console.log(import_chalk3.default.cyan("\n" + divider));
|
|
833
|
+
console.log(import_chalk3.default.bold.white(" PATTERNS BY TYPE"));
|
|
834
|
+
console.log(import_chalk3.default.cyan(divider) + "\n");
|
|
927
835
|
sortedTypes.forEach(([type, count]) => {
|
|
928
|
-
console.log(` ${
|
|
836
|
+
console.log(` ${import_chalk3.default.white(type.padEnd(15))} ${import_chalk3.default.bold(count)}`);
|
|
929
837
|
});
|
|
930
838
|
}
|
|
931
839
|
if (summary.totalPatterns > 0 && duplicates.length > 0) {
|
|
932
|
-
console.log(
|
|
933
|
-
console.log(
|
|
934
|
-
console.log(
|
|
840
|
+
console.log(import_chalk3.default.cyan("\n" + divider));
|
|
841
|
+
console.log(import_chalk3.default.bold.white(" TOP DUPLICATE PATTERNS"));
|
|
842
|
+
console.log(import_chalk3.default.cyan(divider) + "\n");
|
|
935
843
|
const topDuplicates = [...duplicates].sort((a, b) => b.similarity - a.similarity).slice(0, 10);
|
|
936
844
|
topDuplicates.forEach((dup) => {
|
|
937
845
|
const severity = dup.similarity > 0.95 ? "CRITICAL" : dup.similarity > 0.9 ? "HIGH" : "MEDIUM";
|
|
938
846
|
const severityIcon = dup.similarity > 0.95 ? "\u{1F534}" : dup.similarity > 0.9 ? "\u{1F7E1}" : "\u{1F535}";
|
|
939
847
|
const file1Name = dup.file1.split("/").pop() || dup.file1;
|
|
940
848
|
const file2Name = dup.file2.split("/").pop() || dup.file2;
|
|
941
|
-
console.log(`${severityIcon} ${severity}: ${
|
|
942
|
-
console.log(` Similarity: ${
|
|
943
|
-
console.log(` Lines: ${
|
|
849
|
+
console.log(`${severityIcon} ${severity}: ${import_chalk3.default.bold(file1Name)} \u2194 ${import_chalk3.default.bold(file2Name)}`);
|
|
850
|
+
console.log(` Similarity: ${import_chalk3.default.bold(Math.round(dup.similarity * 100) + "%")} | Wasted: ${import_chalk3.default.bold(dup.tokenCost.toLocaleString())} tokens each`);
|
|
851
|
+
console.log(` Lines: ${import_chalk3.default.cyan(dup.line1 + "-" + dup.endLine1)} \u2194 ${import_chalk3.default.cyan(dup.line2 + "-" + dup.endLine2)}
|
|
944
852
|
`);
|
|
945
853
|
});
|
|
946
854
|
} else {
|
|
947
|
-
console.log(
|
|
855
|
+
console.log(import_chalk3.default.green("\n\u2728 Great! No duplicate patterns detected.\n"));
|
|
948
856
|
}
|
|
949
857
|
if (patternScore) {
|
|
950
|
-
console.log(
|
|
951
|
-
console.log(
|
|
952
|
-
console.log(
|
|
953
|
-
console.log((0,
|
|
858
|
+
console.log(import_chalk3.default.cyan(divider));
|
|
859
|
+
console.log(import_chalk3.default.bold.white(" AI READINESS SCORE (Patterns)"));
|
|
860
|
+
console.log(import_chalk3.default.cyan(divider) + "\n");
|
|
861
|
+
console.log((0, import_core2.formatToolScore)(patternScore));
|
|
954
862
|
console.log();
|
|
955
863
|
}
|
|
956
864
|
}
|
|
957
865
|
} catch (error) {
|
|
958
|
-
(0,
|
|
866
|
+
(0, import_core2.handleCLIError)(error, "Pattern analysis");
|
|
959
867
|
}
|
|
960
868
|
}
|
|
961
869
|
var patternsHelpText = `
|
|
@@ -966,11 +874,11 @@ EXAMPLES:
|
|
|
966
874
|
`;
|
|
967
875
|
|
|
968
876
|
// src/commands/context.ts
|
|
969
|
-
var
|
|
877
|
+
var import_chalk4 = __toESM(require("chalk"));
|
|
970
878
|
var import_path4 = require("path");
|
|
971
|
-
var
|
|
879
|
+
var import_core3 = require("@aiready/core");
|
|
972
880
|
async function contextAction(directory, options) {
|
|
973
|
-
console.log(
|
|
881
|
+
console.log(import_chalk4.default.blue("\u{1F9E0} Analyzing context costs...\n"));
|
|
974
882
|
const startTime = Date.now();
|
|
975
883
|
const resolvedDir = (0, import_path4.resolve)(process.cwd(), directory || ".");
|
|
976
884
|
try {
|
|
@@ -984,7 +892,7 @@ async function contextAction(directory, options) {
|
|
|
984
892
|
file: void 0
|
|
985
893
|
}
|
|
986
894
|
};
|
|
987
|
-
let baseOptions = await (0,
|
|
895
|
+
let baseOptions = await (0, import_core3.loadMergedConfig)(resolvedDir, defaults, {
|
|
988
896
|
maxDepth: options.maxDepth ? parseInt(options.maxDepth) : void 0,
|
|
989
897
|
maxContextBudget: options.maxContext ? parseInt(options.maxContext) : void 0,
|
|
990
898
|
include: options.include?.split(","),
|
|
@@ -1003,7 +911,7 @@ async function contextAction(directory, options) {
|
|
|
1003
911
|
console.log("");
|
|
1004
912
|
const { analyzeContext: analyzeContext2, generateSummary, calculateContextScore } = await import("@aiready/context-analyzer");
|
|
1005
913
|
const results = await analyzeContext2(finalOptions);
|
|
1006
|
-
const elapsedTime = (0,
|
|
914
|
+
const elapsedTime = (0, import_core3.getElapsedTime)(startTime);
|
|
1007
915
|
const summary = generateSummary(results);
|
|
1008
916
|
let contextScore;
|
|
1009
917
|
if (options.score) {
|
|
@@ -1017,104 +925,104 @@ async function contextAction(directory, options) {
|
|
|
1017
925
|
summary: { ...summary, executionTime: parseFloat(elapsedTime) },
|
|
1018
926
|
...contextScore && { scoring: contextScore }
|
|
1019
927
|
};
|
|
1020
|
-
const outputPath = (0,
|
|
928
|
+
const outputPath = (0, import_core3.resolveOutputPath)(
|
|
1021
929
|
userOutputFile,
|
|
1022
930
|
`aiready-report-${getReportTimestamp()}.json`,
|
|
1023
931
|
resolvedDir
|
|
1024
932
|
);
|
|
1025
|
-
(0,
|
|
933
|
+
(0, import_core3.handleJSONOutput)(outputData, outputPath, `\u2705 Results saved to ${outputPath}`);
|
|
1026
934
|
} else {
|
|
1027
935
|
const terminalWidth = process.stdout.columns || 80;
|
|
1028
936
|
const dividerWidth = Math.min(60, terminalWidth - 2);
|
|
1029
937
|
const divider = "\u2501".repeat(dividerWidth);
|
|
1030
|
-
console.log(
|
|
1031
|
-
console.log(
|
|
1032
|
-
console.log(
|
|
1033
|
-
console.log(
|
|
1034
|
-
console.log(
|
|
1035
|
-
console.log(
|
|
1036
|
-
console.log(
|
|
938
|
+
console.log(import_chalk4.default.cyan(divider));
|
|
939
|
+
console.log(import_chalk4.default.bold.white(" CONTEXT ANALYSIS SUMMARY"));
|
|
940
|
+
console.log(import_chalk4.default.cyan(divider) + "\n");
|
|
941
|
+
console.log(import_chalk4.default.white(`\u{1F4C1} Files analyzed: ${import_chalk4.default.bold(summary.totalFiles)}`));
|
|
942
|
+
console.log(import_chalk4.default.white(`\u{1F4CA} Total tokens: ${import_chalk4.default.bold(summary.totalTokens.toLocaleString())}`));
|
|
943
|
+
console.log(import_chalk4.default.yellow(`\u{1F4B0} Avg context budget: ${import_chalk4.default.bold(summary.avgContextBudget.toFixed(0))} tokens/file`));
|
|
944
|
+
console.log(import_chalk4.default.white(`\u23F1 Analysis time: ${import_chalk4.default.bold(elapsedTime + "s")}
|
|
1037
945
|
`));
|
|
1038
946
|
const totalIssues = summary.criticalIssues + summary.majorIssues + summary.minorIssues;
|
|
1039
947
|
if (totalIssues > 0) {
|
|
1040
|
-
console.log(
|
|
948
|
+
console.log(import_chalk4.default.bold("\u26A0\uFE0F Issues Found:\n"));
|
|
1041
949
|
if (summary.criticalIssues > 0) {
|
|
1042
|
-
console.log(
|
|
950
|
+
console.log(import_chalk4.default.red(` \u{1F534} Critical: ${import_chalk4.default.bold(summary.criticalIssues)}`));
|
|
1043
951
|
}
|
|
1044
952
|
if (summary.majorIssues > 0) {
|
|
1045
|
-
console.log(
|
|
953
|
+
console.log(import_chalk4.default.yellow(` \u{1F7E1} Major: ${import_chalk4.default.bold(summary.majorIssues)}`));
|
|
1046
954
|
}
|
|
1047
955
|
if (summary.minorIssues > 0) {
|
|
1048
|
-
console.log(
|
|
956
|
+
console.log(import_chalk4.default.blue(` \u{1F535} Minor: ${import_chalk4.default.bold(summary.minorIssues)}`));
|
|
1049
957
|
}
|
|
1050
|
-
console.log(
|
|
1051
|
-
\u{1F4A1} Potential savings: ${
|
|
958
|
+
console.log(import_chalk4.default.green(`
|
|
959
|
+
\u{1F4A1} Potential savings: ${import_chalk4.default.bold(summary.totalPotentialSavings.toLocaleString())} tokens
|
|
1052
960
|
`));
|
|
1053
961
|
} else {
|
|
1054
|
-
console.log(
|
|
962
|
+
console.log(import_chalk4.default.green("\u2705 No significant issues found!\n"));
|
|
1055
963
|
}
|
|
1056
964
|
if (summary.deepFiles.length > 0) {
|
|
1057
|
-
console.log(
|
|
1058
|
-
console.log(
|
|
1059
|
-
console.log(
|
|
965
|
+
console.log(import_chalk4.default.bold("\u{1F4CF} Deep Import Chains:\n"));
|
|
966
|
+
console.log(import_chalk4.default.gray(` Average depth: ${summary.avgImportDepth.toFixed(1)}`));
|
|
967
|
+
console.log(import_chalk4.default.gray(` Maximum depth: ${summary.maxImportDepth}
|
|
1060
968
|
`));
|
|
1061
969
|
summary.deepFiles.slice(0, 10).forEach((item) => {
|
|
1062
970
|
const fileName = item.file.split("/").slice(-2).join("/");
|
|
1063
|
-
console.log(` ${
|
|
971
|
+
console.log(` ${import_chalk4.default.cyan("\u2192")} ${import_chalk4.default.white(fileName)} ${import_chalk4.default.dim(`(depth: ${item.depth})`)}`);
|
|
1064
972
|
});
|
|
1065
973
|
console.log();
|
|
1066
974
|
}
|
|
1067
975
|
if (summary.fragmentedModules.length > 0) {
|
|
1068
|
-
console.log(
|
|
1069
|
-
console.log(
|
|
976
|
+
console.log(import_chalk4.default.bold("\u{1F9E9} Fragmented Modules:\n"));
|
|
977
|
+
console.log(import_chalk4.default.gray(` Average fragmentation: ${(summary.avgFragmentation * 100).toFixed(0)}%
|
|
1070
978
|
`));
|
|
1071
979
|
summary.fragmentedModules.slice(0, 10).forEach((module2) => {
|
|
1072
|
-
console.log(` ${
|
|
1073
|
-
console.log(
|
|
980
|
+
console.log(` ${import_chalk4.default.yellow("\u25CF")} ${import_chalk4.default.white(module2.domain)} - ${import_chalk4.default.dim(`${module2.files.length} files, ${(module2.fragmentationScore * 100).toFixed(0)}% scattered`)}`);
|
|
981
|
+
console.log(import_chalk4.default.dim(` Token cost: ${module2.totalTokens.toLocaleString()}, Cohesion: ${(module2.avgCohesion * 100).toFixed(0)}%`));
|
|
1074
982
|
});
|
|
1075
983
|
console.log();
|
|
1076
984
|
}
|
|
1077
985
|
if (summary.lowCohesionFiles.length > 0) {
|
|
1078
|
-
console.log(
|
|
1079
|
-
console.log(
|
|
986
|
+
console.log(import_chalk4.default.bold("\u{1F500} Low Cohesion Files:\n"));
|
|
987
|
+
console.log(import_chalk4.default.gray(` Average cohesion: ${(summary.avgCohesion * 100).toFixed(0)}%
|
|
1080
988
|
`));
|
|
1081
989
|
summary.lowCohesionFiles.slice(0, 10).forEach((item) => {
|
|
1082
990
|
const fileName = item.file.split("/").slice(-2).join("/");
|
|
1083
991
|
const scorePercent = (item.score * 100).toFixed(0);
|
|
1084
|
-
const color = item.score < 0.4 ?
|
|
1085
|
-
console.log(` ${color("\u25CB")} ${
|
|
992
|
+
const color = item.score < 0.4 ? import_chalk4.default.red : import_chalk4.default.yellow;
|
|
993
|
+
console.log(` ${color("\u25CB")} ${import_chalk4.default.white(fileName)} ${import_chalk4.default.dim(`(${scorePercent}% cohesion)`)}`);
|
|
1086
994
|
});
|
|
1087
995
|
console.log();
|
|
1088
996
|
}
|
|
1089
997
|
if (summary.topExpensiveFiles.length > 0) {
|
|
1090
|
-
console.log(
|
|
998
|
+
console.log(import_chalk4.default.bold("\u{1F4B8} Most Expensive Files (Context Budget):\n"));
|
|
1091
999
|
summary.topExpensiveFiles.slice(0, 10).forEach((item) => {
|
|
1092
1000
|
const fileName = item.file.split("/").slice(-2).join("/");
|
|
1093
|
-
const severityColor = item.severity === "critical" ?
|
|
1094
|
-
console.log(` ${severityColor("\u25CF")} ${
|
|
1001
|
+
const severityColor = item.severity === "critical" ? import_chalk4.default.red : item.severity === "major" ? import_chalk4.default.yellow : import_chalk4.default.blue;
|
|
1002
|
+
console.log(` ${severityColor("\u25CF")} ${import_chalk4.default.white(fileName)} ${import_chalk4.default.dim(`(${item.contextBudget.toLocaleString()} tokens)`)}`);
|
|
1095
1003
|
});
|
|
1096
1004
|
console.log();
|
|
1097
1005
|
}
|
|
1098
1006
|
if (contextScore) {
|
|
1099
|
-
console.log(
|
|
1100
|
-
console.log(
|
|
1101
|
-
console.log(
|
|
1102
|
-
console.log((0,
|
|
1007
|
+
console.log(import_chalk4.default.cyan(divider));
|
|
1008
|
+
console.log(import_chalk4.default.bold.white(" AI READINESS SCORE (Context)"));
|
|
1009
|
+
console.log(import_chalk4.default.cyan(divider) + "\n");
|
|
1010
|
+
console.log((0, import_core3.formatToolScore)(contextScore));
|
|
1103
1011
|
console.log();
|
|
1104
1012
|
}
|
|
1105
1013
|
}
|
|
1106
1014
|
} catch (error) {
|
|
1107
|
-
(0,
|
|
1015
|
+
(0, import_core3.handleCLIError)(error, "Context analysis");
|
|
1108
1016
|
}
|
|
1109
1017
|
}
|
|
1110
1018
|
|
|
1111
1019
|
// src/commands/consistency.ts
|
|
1112
|
-
var
|
|
1020
|
+
var import_chalk5 = __toESM(require("chalk"));
|
|
1113
1021
|
var import_fs3 = require("fs");
|
|
1114
1022
|
var import_path5 = require("path");
|
|
1115
|
-
var
|
|
1023
|
+
var import_core4 = require("@aiready/core");
|
|
1116
1024
|
async function consistencyAction(directory, options) {
|
|
1117
|
-
console.log(
|
|
1025
|
+
console.log(import_chalk5.default.blue("\u{1F50D} Analyzing consistency...\n"));
|
|
1118
1026
|
const startTime = Date.now();
|
|
1119
1027
|
const resolvedDir = (0, import_path5.resolve)(process.cwd(), directory || ".");
|
|
1120
1028
|
try {
|
|
@@ -1129,7 +1037,7 @@ async function consistencyAction(directory, options) {
|
|
|
1129
1037
|
file: void 0
|
|
1130
1038
|
}
|
|
1131
1039
|
};
|
|
1132
|
-
const finalOptions = await (0,
|
|
1040
|
+
const finalOptions = await (0, import_core4.loadMergedConfig)(resolvedDir, defaults, {
|
|
1133
1041
|
checkNaming: options.naming !== false,
|
|
1134
1042
|
checkPatterns: options.patterns !== false,
|
|
1135
1043
|
minSeverity: options.minSeverity,
|
|
@@ -1138,7 +1046,7 @@ async function consistencyAction(directory, options) {
|
|
|
1138
1046
|
});
|
|
1139
1047
|
const { analyzeConsistency: analyzeConsistency2, calculateConsistencyScore } = await import("@aiready/consistency");
|
|
1140
1048
|
const report = await analyzeConsistency2(finalOptions);
|
|
1141
|
-
const elapsedTime = (0,
|
|
1049
|
+
const elapsedTime = (0, import_core4.getElapsedTime)(startTime);
|
|
1142
1050
|
let consistencyScore;
|
|
1143
1051
|
if (options.score) {
|
|
1144
1052
|
const issues = report.results?.flatMap((r) => r.issues) || [];
|
|
@@ -1155,32 +1063,32 @@ async function consistencyAction(directory, options) {
|
|
|
1155
1063
|
},
|
|
1156
1064
|
...consistencyScore && { scoring: consistencyScore }
|
|
1157
1065
|
};
|
|
1158
|
-
const outputPath = (0,
|
|
1066
|
+
const outputPath = (0, import_core4.resolveOutputPath)(
|
|
1159
1067
|
userOutputFile,
|
|
1160
1068
|
`aiready-report-${getReportTimestamp()}.json`,
|
|
1161
1069
|
resolvedDir
|
|
1162
1070
|
);
|
|
1163
|
-
(0,
|
|
1071
|
+
(0, import_core4.handleJSONOutput)(outputData, outputPath, `\u2705 Results saved to ${outputPath}`);
|
|
1164
1072
|
} else if (outputFormat === "markdown") {
|
|
1165
1073
|
const markdown = generateMarkdownReport(report, elapsedTime);
|
|
1166
|
-
const outputPath = (0,
|
|
1074
|
+
const outputPath = (0, import_core4.resolveOutputPath)(
|
|
1167
1075
|
userOutputFile,
|
|
1168
1076
|
`aiready-report-${getReportTimestamp()}.md`,
|
|
1169
1077
|
resolvedDir
|
|
1170
1078
|
);
|
|
1171
1079
|
(0, import_fs3.writeFileSync)(outputPath, markdown);
|
|
1172
|
-
console.log(
|
|
1080
|
+
console.log(import_chalk5.default.green(`\u2705 Report saved to ${outputPath}`));
|
|
1173
1081
|
} else {
|
|
1174
|
-
console.log(
|
|
1175
|
-
console.log(`Files Analyzed: ${
|
|
1176
|
-
console.log(`Total Issues: ${
|
|
1177
|
-
console.log(` Naming: ${
|
|
1178
|
-
console.log(` Patterns: ${
|
|
1179
|
-
console.log(` Architecture: ${
|
|
1180
|
-
console.log(`Analysis Time: ${
|
|
1082
|
+
console.log(import_chalk5.default.bold("\n\u{1F4CA} Summary\n"));
|
|
1083
|
+
console.log(`Files Analyzed: ${import_chalk5.default.cyan(report.summary.filesAnalyzed)}`);
|
|
1084
|
+
console.log(`Total Issues: ${import_chalk5.default.yellow(report.summary.totalIssues)}`);
|
|
1085
|
+
console.log(` Naming: ${import_chalk5.default.yellow(report.summary.namingIssues)}`);
|
|
1086
|
+
console.log(` Patterns: ${import_chalk5.default.yellow(report.summary.patternIssues)}`);
|
|
1087
|
+
console.log(` Architecture: ${import_chalk5.default.yellow(report.summary.architectureIssues || 0)}`);
|
|
1088
|
+
console.log(`Analysis Time: ${import_chalk5.default.gray(elapsedTime + "s")}
|
|
1181
1089
|
`);
|
|
1182
1090
|
if (report.summary.totalIssues === 0) {
|
|
1183
|
-
console.log(
|
|
1091
|
+
console.log(import_chalk5.default.green("\u2728 No consistency issues found! Your codebase is well-maintained.\n"));
|
|
1184
1092
|
} else {
|
|
1185
1093
|
const namingResults = report.results.filter(
|
|
1186
1094
|
(r) => r.issues.some((i) => i.category === "naming")
|
|
@@ -1189,17 +1097,17 @@ async function consistencyAction(directory, options) {
|
|
|
1189
1097
|
(r) => r.issues.some((i) => i.category === "patterns")
|
|
1190
1098
|
);
|
|
1191
1099
|
if (namingResults.length > 0) {
|
|
1192
|
-
console.log(
|
|
1100
|
+
console.log(import_chalk5.default.bold("\u{1F3F7}\uFE0F Naming Issues\n"));
|
|
1193
1101
|
let shown = 0;
|
|
1194
1102
|
for (const result of namingResults) {
|
|
1195
1103
|
if (shown >= 5) break;
|
|
1196
1104
|
for (const issue of result.issues) {
|
|
1197
1105
|
if (shown >= 5) break;
|
|
1198
|
-
const severityColor = issue.severity === "critical" ?
|
|
1199
|
-
console.log(`${severityColor(issue.severity.toUpperCase())} ${
|
|
1106
|
+
const severityColor = issue.severity === "critical" ? import_chalk5.default.red : issue.severity === "major" ? import_chalk5.default.yellow : issue.severity === "minor" ? import_chalk5.default.blue : import_chalk5.default.gray;
|
|
1107
|
+
console.log(`${severityColor(issue.severity.toUpperCase())} ${import_chalk5.default.dim(`${issue.location.file}:${issue.location.line}`)}`);
|
|
1200
1108
|
console.log(` ${issue.message}`);
|
|
1201
1109
|
if (issue.suggestion) {
|
|
1202
|
-
console.log(` ${
|
|
1110
|
+
console.log(` ${import_chalk5.default.dim("\u2192")} ${import_chalk5.default.italic(issue.suggestion)}`);
|
|
1203
1111
|
}
|
|
1204
1112
|
console.log();
|
|
1205
1113
|
shown++;
|
|
@@ -1207,22 +1115,22 @@ async function consistencyAction(directory, options) {
|
|
|
1207
1115
|
}
|
|
1208
1116
|
const remaining = namingResults.reduce((sum, r) => sum + r.issues.length, 0) - shown;
|
|
1209
1117
|
if (remaining > 0) {
|
|
1210
|
-
console.log(
|
|
1118
|
+
console.log(import_chalk5.default.dim(` ... and ${remaining} more issues
|
|
1211
1119
|
`));
|
|
1212
1120
|
}
|
|
1213
1121
|
}
|
|
1214
1122
|
if (patternResults.length > 0) {
|
|
1215
|
-
console.log(
|
|
1123
|
+
console.log(import_chalk5.default.bold("\u{1F504} Pattern Issues\n"));
|
|
1216
1124
|
let shown = 0;
|
|
1217
1125
|
for (const result of patternResults) {
|
|
1218
1126
|
if (shown >= 5) break;
|
|
1219
1127
|
for (const issue of result.issues) {
|
|
1220
1128
|
if (shown >= 5) break;
|
|
1221
|
-
const severityColor = issue.severity === "critical" ?
|
|
1222
|
-
console.log(`${severityColor(issue.severity.toUpperCase())} ${
|
|
1129
|
+
const severityColor = issue.severity === "critical" ? import_chalk5.default.red : issue.severity === "major" ? import_chalk5.default.yellow : issue.severity === "minor" ? import_chalk5.default.blue : import_chalk5.default.gray;
|
|
1130
|
+
console.log(`${severityColor(issue.severity.toUpperCase())} ${import_chalk5.default.dim(`${issue.location.file}:${issue.location.line}`)}`);
|
|
1223
1131
|
console.log(` ${issue.message}`);
|
|
1224
1132
|
if (issue.suggestion) {
|
|
1225
|
-
console.log(` ${
|
|
1133
|
+
console.log(` ${import_chalk5.default.dim("\u2192")} ${import_chalk5.default.italic(issue.suggestion)}`);
|
|
1226
1134
|
}
|
|
1227
1135
|
console.log();
|
|
1228
1136
|
shown++;
|
|
@@ -1230,12 +1138,12 @@ async function consistencyAction(directory, options) {
|
|
|
1230
1138
|
}
|
|
1231
1139
|
const remaining = patternResults.reduce((sum, r) => sum + r.issues.length, 0) - shown;
|
|
1232
1140
|
if (remaining > 0) {
|
|
1233
|
-
console.log(
|
|
1141
|
+
console.log(import_chalk5.default.dim(` ... and ${remaining} more issues
|
|
1234
1142
|
`));
|
|
1235
1143
|
}
|
|
1236
1144
|
}
|
|
1237
1145
|
if (report.recommendations.length > 0) {
|
|
1238
|
-
console.log(
|
|
1146
|
+
console.log(import_chalk5.default.bold("\u{1F4A1} Recommendations\n"));
|
|
1239
1147
|
report.recommendations.forEach((rec, i) => {
|
|
1240
1148
|
console.log(`${i + 1}. ${rec}`);
|
|
1241
1149
|
});
|
|
@@ -1243,23 +1151,23 @@ async function consistencyAction(directory, options) {
|
|
|
1243
1151
|
}
|
|
1244
1152
|
}
|
|
1245
1153
|
if (consistencyScore) {
|
|
1246
|
-
console.log(
|
|
1247
|
-
console.log((0,
|
|
1154
|
+
console.log(import_chalk5.default.bold("\n\u{1F4CA} AI Readiness Score (Consistency)\n"));
|
|
1155
|
+
console.log((0, import_core4.formatToolScore)(consistencyScore));
|
|
1248
1156
|
console.log();
|
|
1249
1157
|
}
|
|
1250
1158
|
}
|
|
1251
1159
|
} catch (error) {
|
|
1252
|
-
(0,
|
|
1160
|
+
(0, import_core4.handleCLIError)(error, "Consistency analysis");
|
|
1253
1161
|
}
|
|
1254
1162
|
}
|
|
1255
1163
|
|
|
1256
1164
|
// src/commands/visualize.ts
|
|
1257
|
-
var
|
|
1165
|
+
var import_chalk6 = __toESM(require("chalk"));
|
|
1258
1166
|
var import_fs4 = require("fs");
|
|
1259
1167
|
var import_path6 = require("path");
|
|
1260
1168
|
var import_child_process = require("child_process");
|
|
1261
|
-
var
|
|
1262
|
-
var
|
|
1169
|
+
var import_core5 = require("@aiready/core");
|
|
1170
|
+
var import_core6 = require("@aiready/core");
|
|
1263
1171
|
async function visualizeAction(directory, options) {
|
|
1264
1172
|
try {
|
|
1265
1173
|
const dirPath = (0, import_path6.resolve)(process.cwd(), directory || ".");
|
|
@@ -1268,10 +1176,10 @@ async function visualizeAction(directory, options) {
|
|
|
1268
1176
|
const latestScan = findLatestScanReport(dirPath);
|
|
1269
1177
|
if (latestScan) {
|
|
1270
1178
|
reportPath = latestScan;
|
|
1271
|
-
console.log(
|
|
1179
|
+
console.log(import_chalk6.default.dim(`Found latest report: ${latestScan.split("/").pop()}`));
|
|
1272
1180
|
} else {
|
|
1273
|
-
console.error(
|
|
1274
|
-
console.log(
|
|
1181
|
+
console.error(import_chalk6.default.red("\u274C No AI readiness report found"));
|
|
1182
|
+
console.log(import_chalk6.default.dim(`
|
|
1275
1183
|
Generate a report with:
|
|
1276
1184
|
aiready scan --output json
|
|
1277
1185
|
|
|
@@ -1380,22 +1288,22 @@ Or specify a custom report:
|
|
|
1380
1288
|
devServerStarted = true;
|
|
1381
1289
|
return;
|
|
1382
1290
|
} else {
|
|
1383
|
-
console.log(
|
|
1384
|
-
console.log(
|
|
1291
|
+
console.log(import_chalk6.default.yellow("\u26A0\uFE0F Dev server not available (requires local @aiready/visualizer with web assets)."));
|
|
1292
|
+
console.log(import_chalk6.default.cyan(" Falling back to static HTML generation...\n"));
|
|
1385
1293
|
useDevMode = false;
|
|
1386
1294
|
}
|
|
1387
1295
|
} catch (err) {
|
|
1388
1296
|
console.error("Failed to start dev server:", err);
|
|
1389
|
-
console.log(
|
|
1297
|
+
console.log(import_chalk6.default.cyan(" Falling back to static HTML generation...\n"));
|
|
1390
1298
|
useDevMode = false;
|
|
1391
1299
|
}
|
|
1392
1300
|
}
|
|
1393
1301
|
console.log("Generating HTML...");
|
|
1394
|
-
const html = (0,
|
|
1302
|
+
const html = (0, import_core6.generateHTML)(graph);
|
|
1395
1303
|
const defaultOutput = "visualization.html";
|
|
1396
1304
|
const outPath = (0, import_path6.resolve)(dirPath, options.output || defaultOutput);
|
|
1397
1305
|
(0, import_fs4.writeFileSync)(outPath, html, "utf8");
|
|
1398
|
-
console.log(
|
|
1306
|
+
console.log(import_chalk6.default.green(`\u2705 Visualization written to: ${outPath}`));
|
|
1399
1307
|
if (options.open || options.serve) {
|
|
1400
1308
|
const opener = process.platform === "darwin" ? "open" : process.platform === "win32" ? "start" : "xdg-open";
|
|
1401
1309
|
if (options.serve) {
|
|
@@ -1421,7 +1329,7 @@ Or specify a custom report:
|
|
|
1421
1329
|
});
|
|
1422
1330
|
server.listen(port, () => {
|
|
1423
1331
|
const addr = `http://localhost:${port}/`;
|
|
1424
|
-
console.log(
|
|
1332
|
+
console.log(import_chalk6.default.cyan(`\u{1F310} Local visualization server running at ${addr}`));
|
|
1425
1333
|
(0, import_child_process.spawn)(opener, [`"${addr}"`], { shell: true });
|
|
1426
1334
|
});
|
|
1427
1335
|
process.on("SIGINT", () => {
|
|
@@ -1436,7 +1344,7 @@ Or specify a custom report:
|
|
|
1436
1344
|
}
|
|
1437
1345
|
}
|
|
1438
1346
|
} catch (err) {
|
|
1439
|
-
(0,
|
|
1347
|
+
(0, import_core5.handleCLIError)(err, "Visualization");
|
|
1440
1348
|
}
|
|
1441
1349
|
}
|
|
1442
1350
|
var visualizeHelpText = `
|
|
@@ -1466,10 +1374,20 @@ NOTES:
|
|
|
1466
1374
|
- Same options as 'visualize'. Use --serve to host the static HTML, or --dev for live reload.
|
|
1467
1375
|
`;
|
|
1468
1376
|
|
|
1469
|
-
// src/commands/
|
|
1470
|
-
|
|
1471
|
-
|
|
1472
|
-
|
|
1377
|
+
// src/commands/ai-signal-clarity.ts
|
|
1378
|
+
var import_chalk7 = __toESM(require("chalk"));
|
|
1379
|
+
var import_core7 = require("@aiready/core");
|
|
1380
|
+
|
|
1381
|
+
// src/commands/agent-grounding.ts
|
|
1382
|
+
var import_chalk8 = __toESM(require("chalk"));
|
|
1383
|
+
var import_core8 = require("@aiready/core");
|
|
1384
|
+
|
|
1385
|
+
// src/commands/testability.ts
|
|
1386
|
+
var import_chalk9 = __toESM(require("chalk"));
|
|
1387
|
+
var import_core9 = require("@aiready/core");
|
|
1388
|
+
|
|
1389
|
+
// src/commands/change-amplification.ts
|
|
1390
|
+
var import_cli = require("@aiready/change-amplification/dist/cli.js");
|
|
1473
1391
|
|
|
1474
1392
|
// src/cli.ts
|
|
1475
1393
|
var import_meta = {};
|
|
@@ -1515,7 +1433,7 @@ VERSION: ${packageJson.version}
|
|
|
1515
1433
|
DOCUMENTATION: https://aiready.dev/docs/cli
|
|
1516
1434
|
GITHUB: https://github.com/caopengau/aiready-cli
|
|
1517
1435
|
LANDING: https://github.com/caopengau/aiready-landing`);
|
|
1518
|
-
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) => {
|
|
1519
1437
|
await scanAction(directory, options);
|
|
1520
1438
|
});
|
|
1521
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) => {
|
|
@@ -1533,4 +1451,7 @@ program.command("visualise").description("Alias for visualize (British spelling)
|
|
|
1533
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) => {
|
|
1534
1452
|
await visualizeAction(directory, options);
|
|
1535
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
|
+
});
|
|
1536
1457
|
program.parse();
|