@aiready/cli 0.10.6 → 0.12.0
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 +8 -8
- package/.turbo/turbo-lint.log +9 -1
- package/.turbo/turbo-test.log +16 -4
- package/dist/chunk-N56YAZVN.mjs +194 -0
- package/dist/chunk-YBZKPKW3.mjs +161 -0
- package/dist/cli.js +198 -910
- package/dist/cli.mjs +86 -582
- package/dist/index.js +116 -371
- package/dist/index.mjs +1 -1
- package/package.json +12 -12
- package/src/.aiready/aiready-report-20260307-092852.json +50609 -0
- package/src/.aiready/aiready-report-20260307-094301.json +50609 -0
- package/src/__tests__/cli.test.ts +55 -29
- package/src/commands/scan.ts +107 -699
- package/src/index.ts +154 -455
- package/dist/chunk-EQ2HQSTJ.mjs +0 -414
- package/dist/chunk-R3O7QPKD.mjs +0 -419
- package/dist/chunk-VQCWYJYJ.mjs +0 -438
- package/dist/chunk-VUCNUYI7.mjs +0 -417
package/dist/cli.js
CHANGED
|
@@ -36,357 +36,137 @@ var import_path3 = require("path");
|
|
|
36
36
|
var import_core3 = require("@aiready/core");
|
|
37
37
|
|
|
38
38
|
// src/index.ts
|
|
39
|
-
var import_pattern_detect = require("@aiready/pattern-detect");
|
|
40
|
-
var import_context_analyzer = require("@aiready/context-analyzer");
|
|
41
|
-
var import_consistency = require("@aiready/consistency");
|
|
42
39
|
var import_core = require("@aiready/core");
|
|
43
|
-
var
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
40
|
+
var TOOL_PACKAGE_MAP = {
|
|
41
|
+
[import_core.ToolName.PatternDetect]: "@aiready/pattern-detect",
|
|
42
|
+
[import_core.ToolName.ContextAnalyzer]: "@aiready/context-analyzer",
|
|
43
|
+
[import_core.ToolName.NamingConsistency]: "@aiready/consistency",
|
|
44
|
+
[import_core.ToolName.AiSignalClarity]: "@aiready/ai-signal-clarity",
|
|
45
|
+
[import_core.ToolName.AgentGrounding]: "@aiready/agent-grounding",
|
|
46
|
+
[import_core.ToolName.TestabilityIndex]: "@aiready/testability",
|
|
47
|
+
[import_core.ToolName.DocDrift]: "@aiready/doc-drift",
|
|
48
|
+
[import_core.ToolName.DependencyHealth]: "@aiready/deps",
|
|
49
|
+
[import_core.ToolName.ChangeAmplification]: "@aiready/change-amplification",
|
|
50
|
+
// Aliases handled by registry
|
|
51
|
+
patterns: "@aiready/pattern-detect",
|
|
52
|
+
context: "@aiready/context-analyzer",
|
|
53
|
+
consistency: "@aiready/consistency"
|
|
48
54
|
};
|
|
49
|
-
function sortBySeverity(results) {
|
|
50
|
-
return results.map((file) => {
|
|
51
|
-
const sortedIssues = [...file.issues].sort((a, b) => {
|
|
52
|
-
const severityDiff = (severityOrder[b.severity] || 0) - (severityOrder[a.severity] || 0);
|
|
53
|
-
if (severityDiff !== 0) return severityDiff;
|
|
54
|
-
return (a.location?.line || 0) - (b.location?.line || 0);
|
|
55
|
-
});
|
|
56
|
-
return { ...file, issues: sortedIssues };
|
|
57
|
-
}).sort((a, b) => {
|
|
58
|
-
const aMaxSeverity = Math.max(
|
|
59
|
-
...a.issues.map((i) => severityOrder[i.severity] || 0),
|
|
60
|
-
0
|
|
61
|
-
);
|
|
62
|
-
const bMaxSeverity = Math.max(
|
|
63
|
-
...b.issues.map((i) => severityOrder[i.severity] || 0),
|
|
64
|
-
0
|
|
65
|
-
);
|
|
66
|
-
if (aMaxSeverity !== bMaxSeverity) {
|
|
67
|
-
return bMaxSeverity - aMaxSeverity;
|
|
68
|
-
}
|
|
69
|
-
if (a.issues.length !== b.issues.length) {
|
|
70
|
-
return b.issues.length - a.issues.length;
|
|
71
|
-
}
|
|
72
|
-
return a.fileName.localeCompare(b.fileName);
|
|
73
|
-
});
|
|
74
|
-
}
|
|
75
55
|
async function analyzeUnified(options) {
|
|
76
56
|
const startTime = Date.now();
|
|
77
|
-
const
|
|
57
|
+
const requestedTools = options.tools || [
|
|
58
|
+
"patterns",
|
|
59
|
+
"context",
|
|
60
|
+
"consistency"
|
|
61
|
+
];
|
|
78
62
|
const result = {
|
|
79
63
|
summary: {
|
|
80
64
|
totalIssues: 0,
|
|
81
|
-
toolsRun:
|
|
65
|
+
toolsRun: [],
|
|
82
66
|
executionTime: 0
|
|
83
67
|
}
|
|
84
68
|
};
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
if (
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
const sorted = contextResults.sort((a, b) => {
|
|
108
|
-
const severityDiff = (severityOrder[b.severity] || 0) - (severityOrder[a.severity] || 0);
|
|
109
|
-
if (severityDiff !== 0) return severityDiff;
|
|
110
|
-
if (a.tokenCost !== b.tokenCost) return b.tokenCost - a.tokenCost;
|
|
111
|
-
return b.fragmentationScore - a.fragmentationScore;
|
|
112
|
-
});
|
|
113
|
-
const { generateSummary: genContextSummary } = await import("@aiready/context-analyzer");
|
|
114
|
-
const output = {
|
|
115
|
-
results: sorted,
|
|
116
|
-
summary: genContextSummary(sorted)
|
|
117
|
-
};
|
|
118
|
-
result[import_core.ToolName.ContextAnalyzer] = output;
|
|
119
|
-
result.contextAnalyzer = output;
|
|
120
|
-
result.summary.totalIssues += sorted.length;
|
|
121
|
-
}
|
|
122
|
-
if (tools.includes("consistency")) {
|
|
123
|
-
const consistencyOptions = {
|
|
124
|
-
rootDir: options.rootDir,
|
|
125
|
-
include: options.include,
|
|
126
|
-
exclude: options.exclude,
|
|
127
|
-
...options.consistency || {}
|
|
128
|
-
};
|
|
129
|
-
const report = await (0, import_consistency.analyzeConsistency)(consistencyOptions);
|
|
130
|
-
if (options.progressCallback) {
|
|
131
|
-
options.progressCallback({ tool: "consistency", data: report });
|
|
132
|
-
}
|
|
133
|
-
result[import_core.ToolName.NamingConsistency] = {
|
|
134
|
-
results: report.results ? sortBySeverity(report.results) : [],
|
|
135
|
-
summary: report.summary
|
|
136
|
-
};
|
|
137
|
-
result.summary.totalIssues += report.summary.totalIssues;
|
|
138
|
-
}
|
|
139
|
-
if (tools.includes("doc-drift")) {
|
|
140
|
-
const { analyzeDocDrift } = await import("@aiready/doc-drift");
|
|
141
|
-
const report = await analyzeDocDrift({
|
|
142
|
-
rootDir: options.rootDir,
|
|
143
|
-
include: options.include,
|
|
144
|
-
exclude: options.exclude,
|
|
145
|
-
onProgress: options.onProgress
|
|
146
|
-
});
|
|
147
|
-
if (options.progressCallback) {
|
|
148
|
-
options.progressCallback({ tool: "doc-drift", data: report });
|
|
149
|
-
}
|
|
150
|
-
result[import_core.ToolName.DocDrift] = {
|
|
151
|
-
results: report.results || report.issues || [],
|
|
152
|
-
summary: report.summary || {}
|
|
153
|
-
};
|
|
154
|
-
const issueCount = report.issues?.length || (report.results ? report.results.length : 0);
|
|
155
|
-
result.summary.totalIssues += issueCount;
|
|
156
|
-
}
|
|
157
|
-
if (tools.includes("deps-health")) {
|
|
158
|
-
const { analyzeDeps } = await import("@aiready/deps");
|
|
159
|
-
const report = await analyzeDeps({
|
|
160
|
-
rootDir: options.rootDir,
|
|
161
|
-
include: options.include,
|
|
162
|
-
exclude: options.exclude,
|
|
163
|
-
onProgress: options.onProgress
|
|
164
|
-
});
|
|
165
|
-
if (options.progressCallback) {
|
|
166
|
-
options.progressCallback({ tool: "deps-health", data: report });
|
|
167
|
-
}
|
|
168
|
-
result[import_core.ToolName.DependencyHealth] = {
|
|
169
|
-
results: report.results || report.issues || [],
|
|
170
|
-
summary: report.summary || {}
|
|
171
|
-
};
|
|
172
|
-
const issueCount = report.issues?.length || (report.results ? report.results.length : 0);
|
|
173
|
-
result.summary.totalIssues += issueCount;
|
|
174
|
-
}
|
|
175
|
-
if (tools.includes("ai-signal-clarity")) {
|
|
176
|
-
const { analyzeAiSignalClarity } = await import("@aiready/ai-signal-clarity");
|
|
177
|
-
const report = await analyzeAiSignalClarity({
|
|
178
|
-
rootDir: options.rootDir,
|
|
179
|
-
include: options.include,
|
|
180
|
-
exclude: options.exclude,
|
|
181
|
-
onProgress: options.onProgress
|
|
182
|
-
});
|
|
183
|
-
if (options.progressCallback) {
|
|
184
|
-
options.progressCallback({ tool: "ai-signal-clarity", data: report });
|
|
185
|
-
}
|
|
186
|
-
result[import_core.ToolName.AiSignalClarity] = {
|
|
187
|
-
...report,
|
|
188
|
-
results: report.results || report.issues || [],
|
|
189
|
-
summary: report.summary || {}
|
|
190
|
-
};
|
|
191
|
-
result.summary.totalIssues += (report.results || report.issues)?.reduce(
|
|
192
|
-
(sum, r) => sum + (r.issues?.length || 1),
|
|
193
|
-
0
|
|
194
|
-
) || 0;
|
|
195
|
-
}
|
|
196
|
-
if (tools.includes("agent-grounding")) {
|
|
197
|
-
const { analyzeAgentGrounding } = await import("@aiready/agent-grounding");
|
|
198
|
-
const report = await analyzeAgentGrounding({
|
|
199
|
-
rootDir: options.rootDir,
|
|
200
|
-
include: options.include,
|
|
201
|
-
exclude: options.exclude,
|
|
202
|
-
onProgress: options.onProgress
|
|
203
|
-
});
|
|
204
|
-
if (options.progressCallback) {
|
|
205
|
-
options.progressCallback({ tool: "agent-grounding", data: report });
|
|
206
|
-
}
|
|
207
|
-
result[import_core.ToolName.AgentGrounding] = {
|
|
208
|
-
...report,
|
|
209
|
-
results: report.results || report.issues || [],
|
|
210
|
-
summary: report.summary || {}
|
|
211
|
-
};
|
|
212
|
-
result.summary.totalIssues += (report.issues || report.results || []).length;
|
|
213
|
-
}
|
|
214
|
-
if (tools.includes("testability")) {
|
|
215
|
-
const { analyzeTestability } = await import("@aiready/testability");
|
|
216
|
-
const report = await analyzeTestability({
|
|
217
|
-
rootDir: options.rootDir,
|
|
218
|
-
include: options.include,
|
|
219
|
-
exclude: options.exclude,
|
|
220
|
-
onProgress: options.onProgress
|
|
221
|
-
});
|
|
222
|
-
if (options.progressCallback) {
|
|
223
|
-
options.progressCallback({ tool: "testability", data: report });
|
|
69
|
+
for (const toolName of requestedTools) {
|
|
70
|
+
let provider = import_core.ToolRegistry.find(toolName);
|
|
71
|
+
if (!provider) {
|
|
72
|
+
const packageName = TOOL_PACKAGE_MAP[toolName] || (toolName.startsWith("@aiready/") ? toolName : `@aiready/${toolName}`);
|
|
73
|
+
try {
|
|
74
|
+
await import(packageName);
|
|
75
|
+
provider = import_core.ToolRegistry.find(toolName);
|
|
76
|
+
if (provider) {
|
|
77
|
+
console.log(
|
|
78
|
+
`\u2705 Successfully loaded tool provider: ${toolName} from ${packageName}`
|
|
79
|
+
);
|
|
80
|
+
} else {
|
|
81
|
+
console.log(
|
|
82
|
+
`\u26A0\uFE0F Loaded ${packageName} but provider ${toolName} still not found in registry.`
|
|
83
|
+
);
|
|
84
|
+
}
|
|
85
|
+
} catch (err) {
|
|
86
|
+
console.log(
|
|
87
|
+
`\u274C Failed to dynamically load tool ${toolName} (${packageName}):`,
|
|
88
|
+
err.message
|
|
89
|
+
);
|
|
90
|
+
}
|
|
224
91
|
}
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
result.summary.totalIssues += (report.issues || report.results || []).length;
|
|
231
|
-
}
|
|
232
|
-
if (tools.includes("change-amplification")) {
|
|
233
|
-
const { analyzeChangeAmplification } = await import("@aiready/change-amplification");
|
|
234
|
-
const report = await analyzeChangeAmplification({
|
|
235
|
-
rootDir: options.rootDir,
|
|
236
|
-
include: options.include,
|
|
237
|
-
exclude: options.exclude,
|
|
238
|
-
onProgress: options.onProgress
|
|
239
|
-
});
|
|
240
|
-
if (options.progressCallback) {
|
|
241
|
-
options.progressCallback({ tool: "change-amplification", data: report });
|
|
92
|
+
if (!provider) {
|
|
93
|
+
console.warn(
|
|
94
|
+
`\u26A0\uFE0F Warning: Tool provider for '${toolName}' not found. Skipping.`
|
|
95
|
+
);
|
|
96
|
+
continue;
|
|
242
97
|
}
|
|
243
|
-
result[import_core.ToolName.ChangeAmplification] = {
|
|
244
|
-
results: report.results || [],
|
|
245
|
-
summary: report.summary || {}
|
|
246
|
-
};
|
|
247
|
-
result.summary.totalIssues += report.summary?.totalIssues || 0;
|
|
248
|
-
}
|
|
249
|
-
result.summary.executionTime = Date.now() - startTime;
|
|
250
|
-
return result;
|
|
251
|
-
}
|
|
252
|
-
async function scoreUnified(results, options) {
|
|
253
|
-
const toolScores = /* @__PURE__ */ new Map();
|
|
254
|
-
if (results[import_core.ToolName.PatternDetect]) {
|
|
255
|
-
const data = results[import_core.ToolName.PatternDetect];
|
|
256
|
-
const { calculatePatternScore } = await import("@aiready/pattern-detect");
|
|
257
98
|
try {
|
|
258
|
-
const
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
99
|
+
const output = await provider.analyze(options);
|
|
100
|
+
if (options.progressCallback) {
|
|
101
|
+
options.progressCallback({ tool: provider.id, data: output });
|
|
102
|
+
}
|
|
103
|
+
result[provider.id] = output;
|
|
104
|
+
result.summary.toolsRun.push(provider.id);
|
|
105
|
+
const issueCount = output.results.reduce(
|
|
106
|
+
(sum, file) => sum + (file.issues?.length || 0),
|
|
264
107
|
0
|
|
265
108
|
);
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
chattiness: 0
|
|
273
|
-
}
|
|
274
|
-
});
|
|
275
|
-
toolScores.set(import_core.ToolName.PatternDetect, patternScore);
|
|
276
|
-
} catch (err) {
|
|
277
|
-
void err;
|
|
278
|
-
}
|
|
279
|
-
}
|
|
280
|
-
if (results[import_core.ToolName.ContextAnalyzer]) {
|
|
281
|
-
const data = results[import_core.ToolName.ContextAnalyzer];
|
|
282
|
-
const { calculateContextScore } = await import("@aiready/context-analyzer");
|
|
283
|
-
try {
|
|
284
|
-
const ctxSummary = data.summary;
|
|
285
|
-
const contextScore = calculateContextScore(ctxSummary);
|
|
286
|
-
contextScore.tokenBudget = (0, import_core.calculateTokenBudget)({
|
|
287
|
-
totalContextTokens: ctxSummary.totalTokens,
|
|
288
|
-
wastedTokens: {
|
|
289
|
-
duplication: 0,
|
|
290
|
-
fragmentation: ctxSummary.totalPotentialSavings || 0,
|
|
291
|
-
chattiness: 0
|
|
109
|
+
result.summary.totalIssues += issueCount;
|
|
110
|
+
if (provider.alias && Array.isArray(provider.alias)) {
|
|
111
|
+
for (const alias of provider.alias) {
|
|
112
|
+
if (!result[alias]) {
|
|
113
|
+
result[alias] = output;
|
|
114
|
+
}
|
|
292
115
|
}
|
|
293
|
-
}
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
}
|
|
298
|
-
}
|
|
299
|
-
if (results[import_core.ToolName.NamingConsistency]) {
|
|
300
|
-
const data = results[import_core.ToolName.NamingConsistency];
|
|
301
|
-
const { calculateConsistencyScore } = await import("@aiready/consistency");
|
|
302
|
-
try {
|
|
303
|
-
const issues = data.results?.flatMap((r) => r.issues) || [];
|
|
304
|
-
const totalFiles = data.summary?.filesAnalyzed || 0;
|
|
305
|
-
const consistencyScore = calculateConsistencyScore(issues, totalFiles);
|
|
306
|
-
toolScores.set(import_core.ToolName.NamingConsistency, consistencyScore);
|
|
307
|
-
} catch (err) {
|
|
308
|
-
void err;
|
|
309
|
-
}
|
|
310
|
-
}
|
|
311
|
-
if (results[import_core.ToolName.AiSignalClarity]) {
|
|
312
|
-
const { calculateAiSignalClarityScore } = await import("@aiready/ai-signal-clarity");
|
|
313
|
-
try {
|
|
314
|
-
const hrScore = calculateAiSignalClarityScore(
|
|
315
|
-
results[import_core.ToolName.AiSignalClarity]
|
|
116
|
+
}
|
|
117
|
+
const camelCaseId = provider.id.replace(
|
|
118
|
+
/-([a-z])/g,
|
|
119
|
+
(g) => g[1].toUpperCase()
|
|
316
120
|
);
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
}
|
|
321
|
-
}
|
|
322
|
-
if (results[import_core.ToolName.AgentGrounding]) {
|
|
323
|
-
const { calculateGroundingScore } = await import("@aiready/agent-grounding");
|
|
324
|
-
try {
|
|
325
|
-
const agScore = calculateGroundingScore(results[import_core.ToolName.AgentGrounding]);
|
|
326
|
-
toolScores.set(import_core.ToolName.AgentGrounding, agScore);
|
|
121
|
+
if (camelCaseId !== provider.id && !result[camelCaseId]) {
|
|
122
|
+
result[camelCaseId] = output;
|
|
123
|
+
}
|
|
327
124
|
} catch (err) {
|
|
328
|
-
|
|
125
|
+
console.error(`\u274C Error running tool '${provider.id}':`, err);
|
|
329
126
|
}
|
|
330
127
|
}
|
|
331
|
-
|
|
332
|
-
|
|
128
|
+
result.summary.executionTime = Date.now() - startTime;
|
|
129
|
+
return result;
|
|
130
|
+
}
|
|
131
|
+
async function scoreUnified(results, options) {
|
|
132
|
+
const toolScores = /* @__PURE__ */ new Map();
|
|
133
|
+
for (const toolId of results.summary.toolsRun) {
|
|
134
|
+
const provider = import_core.ToolRegistry.get(toolId);
|
|
135
|
+
if (!provider) continue;
|
|
136
|
+
const output = results[toolId];
|
|
137
|
+
if (!output) continue;
|
|
333
138
|
try {
|
|
334
|
-
const
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
139
|
+
const toolScore = provider.score(output, options);
|
|
140
|
+
if (!toolScore.tokenBudget) {
|
|
141
|
+
if (toolId === import_core.ToolName.PatternDetect && output.duplicates) {
|
|
142
|
+
const wastedTokens = output.duplicates.reduce(
|
|
143
|
+
(sum, d) => sum + (d.tokenCost || 0),
|
|
144
|
+
0
|
|
145
|
+
);
|
|
146
|
+
toolScore.tokenBudget = (0, import_core.calculateTokenBudget)({
|
|
147
|
+
totalContextTokens: wastedTokens * 2,
|
|
148
|
+
wastedTokens: {
|
|
149
|
+
duplication: wastedTokens,
|
|
150
|
+
fragmentation: 0,
|
|
151
|
+
chattiness: 0
|
|
152
|
+
}
|
|
153
|
+
});
|
|
154
|
+
} else if (toolId === import_core.ToolName.ContextAnalyzer && output.summary) {
|
|
155
|
+
toolScore.tokenBudget = (0, import_core.calculateTokenBudget)({
|
|
156
|
+
totalContextTokens: output.summary.totalTokens,
|
|
157
|
+
wastedTokens: {
|
|
158
|
+
duplication: 0,
|
|
159
|
+
fragmentation: output.summary.totalPotentialSavings || 0,
|
|
160
|
+
chattiness: 0
|
|
161
|
+
}
|
|
162
|
+
});
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
toolScores.set(toolId, toolScore);
|
|
338
166
|
} catch (err) {
|
|
339
|
-
|
|
167
|
+
console.error(`\u274C Error scoring tool '${toolId}':`, err);
|
|
340
168
|
}
|
|
341
169
|
}
|
|
342
|
-
if (results[import_core.ToolName.DocDrift]) {
|
|
343
|
-
const data = results[import_core.ToolName.DocDrift];
|
|
344
|
-
toolScores.set(import_core.ToolName.DocDrift, {
|
|
345
|
-
toolName: import_core.ToolName.DocDrift,
|
|
346
|
-
score: data.summary.score || data.summary.totalScore || 0,
|
|
347
|
-
rawMetrics: data.summary,
|
|
348
|
-
factors: [],
|
|
349
|
-
recommendations: (data.summary.recommendations || []).map(
|
|
350
|
-
(action) => ({
|
|
351
|
-
action,
|
|
352
|
-
estimatedImpact: 5,
|
|
353
|
-
priority: "medium"
|
|
354
|
-
})
|
|
355
|
-
)
|
|
356
|
-
});
|
|
357
|
-
}
|
|
358
|
-
if (results[import_core.ToolName.DependencyHealth]) {
|
|
359
|
-
const data = results[import_core.ToolName.DependencyHealth];
|
|
360
|
-
toolScores.set(import_core.ToolName.DependencyHealth, {
|
|
361
|
-
toolName: import_core.ToolName.DependencyHealth,
|
|
362
|
-
score: data.summary.score || 0,
|
|
363
|
-
rawMetrics: data.summary,
|
|
364
|
-
factors: [],
|
|
365
|
-
recommendations: (data.summary.recommendations || []).map(
|
|
366
|
-
(action) => ({
|
|
367
|
-
action,
|
|
368
|
-
estimatedImpact: 5,
|
|
369
|
-
priority: "medium"
|
|
370
|
-
})
|
|
371
|
-
)
|
|
372
|
-
});
|
|
373
|
-
}
|
|
374
|
-
if (results[import_core.ToolName.ChangeAmplification]) {
|
|
375
|
-
const data = results[import_core.ToolName.ChangeAmplification];
|
|
376
|
-
toolScores.set(import_core.ToolName.ChangeAmplification, {
|
|
377
|
-
toolName: import_core.ToolName.ChangeAmplification,
|
|
378
|
-
score: data.summary.score || 0,
|
|
379
|
-
rawMetrics: data.summary,
|
|
380
|
-
factors: [],
|
|
381
|
-
recommendations: (data.summary.recommendations || []).map(
|
|
382
|
-
(action) => ({
|
|
383
|
-
action,
|
|
384
|
-
estimatedImpact: 5,
|
|
385
|
-
priority: "medium"
|
|
386
|
-
})
|
|
387
|
-
)
|
|
388
|
-
});
|
|
389
|
-
}
|
|
390
170
|
if (toolScores.size === 0) {
|
|
391
171
|
return {
|
|
392
172
|
overall: 0,
|
|
@@ -521,12 +301,6 @@ function generateMarkdownReport(report, elapsedTime) {
|
|
|
521
301
|
}
|
|
522
302
|
return markdown;
|
|
523
303
|
}
|
|
524
|
-
function truncateArray(arr, cap = 8) {
|
|
525
|
-
if (!Array.isArray(arr)) return "";
|
|
526
|
-
const shown = arr.slice(0, cap).map((v) => String(v));
|
|
527
|
-
const more = arr.length - shown.length;
|
|
528
|
-
return shown.join(", ") + (more > 0 ? `, ... (+${more} more)` : "");
|
|
529
|
-
}
|
|
530
304
|
|
|
531
305
|
// src/commands/upload.ts
|
|
532
306
|
var import_fs2 = __toESM(require("fs"));
|
|
@@ -640,14 +414,14 @@ async function scanAction(directory, options) {
|
|
|
640
414
|
try {
|
|
641
415
|
const defaults = {
|
|
642
416
|
tools: [
|
|
643
|
-
"
|
|
644
|
-
"context",
|
|
645
|
-
"consistency",
|
|
417
|
+
"pattern-detect",
|
|
418
|
+
"context-analyzer",
|
|
419
|
+
"naming-consistency",
|
|
646
420
|
"ai-signal-clarity",
|
|
647
421
|
"agent-grounding",
|
|
648
|
-
"testability",
|
|
422
|
+
"testability-index",
|
|
649
423
|
"doc-drift",
|
|
650
|
-
"
|
|
424
|
+
"dependency-health",
|
|
651
425
|
"change-amplification"
|
|
652
426
|
],
|
|
653
427
|
include: void 0,
|
|
@@ -657,35 +431,37 @@ async function scanAction(directory, options) {
|
|
|
657
431
|
file: void 0
|
|
658
432
|
}
|
|
659
433
|
};
|
|
660
|
-
let profileTools = options.tools ? options.tools.split(",").map((t) =>
|
|
661
|
-
const tool = t.trim();
|
|
662
|
-
if (tool === "hallucination" || tool === "hallucination-risk")
|
|
663
|
-
return "aiSignalClarity";
|
|
664
|
-
return tool;
|
|
665
|
-
}) : void 0;
|
|
434
|
+
let profileTools = options.tools ? options.tools.split(",").map((t) => t.trim()) : void 0;
|
|
666
435
|
if (options.profile) {
|
|
667
436
|
switch (options.profile.toLowerCase()) {
|
|
668
437
|
case "agentic":
|
|
669
438
|
profileTools = [
|
|
670
|
-
|
|
671
|
-
|
|
672
|
-
|
|
439
|
+
import_core3.ToolName.AiSignalClarity,
|
|
440
|
+
import_core3.ToolName.AgentGrounding,
|
|
441
|
+
import_core3.ToolName.TestabilityIndex
|
|
673
442
|
];
|
|
674
443
|
break;
|
|
675
444
|
case "cost":
|
|
676
|
-
profileTools = [
|
|
445
|
+
profileTools = [import_core3.ToolName.PatternDetect, import_core3.ToolName.ContextAnalyzer];
|
|
677
446
|
break;
|
|
678
447
|
case "security":
|
|
679
|
-
profileTools = [
|
|
448
|
+
profileTools = [
|
|
449
|
+
import_core3.ToolName.NamingConsistency,
|
|
450
|
+
import_core3.ToolName.TestabilityIndex
|
|
451
|
+
];
|
|
680
452
|
break;
|
|
681
453
|
case "onboarding":
|
|
682
|
-
profileTools = [
|
|
454
|
+
profileTools = [
|
|
455
|
+
import_core3.ToolName.ContextAnalyzer,
|
|
456
|
+
import_core3.ToolName.NamingConsistency,
|
|
457
|
+
import_core3.ToolName.AgentGrounding
|
|
458
|
+
];
|
|
683
459
|
break;
|
|
684
460
|
default:
|
|
685
461
|
console.log(
|
|
686
462
|
import_chalk3.default.yellow(
|
|
687
463
|
`
|
|
688
|
-
\u26A0\uFE0F Unknown profile '${options.profile}'. Using
|
|
464
|
+
\u26A0\uFE0F Unknown profile '${options.profile}'. Using defaults.`
|
|
689
465
|
)
|
|
690
466
|
);
|
|
691
467
|
}
|
|
@@ -694,16 +470,14 @@ async function scanAction(directory, options) {
|
|
|
694
470
|
include: options.include?.split(","),
|
|
695
471
|
exclude: options.exclude?.split(",")
|
|
696
472
|
};
|
|
697
|
-
if (profileTools)
|
|
698
|
-
cliOverrides.tools = profileTools;
|
|
699
|
-
}
|
|
473
|
+
if (profileTools) cliOverrides.tools = profileTools;
|
|
700
474
|
const baseOptions = await (0, import_core3.loadMergedConfig)(
|
|
701
475
|
resolvedDir,
|
|
702
476
|
defaults,
|
|
703
477
|
cliOverrides
|
|
704
478
|
);
|
|
705
479
|
let finalOptions = { ...baseOptions };
|
|
706
|
-
if (baseOptions.tools.includes("patterns")) {
|
|
480
|
+
if (baseOptions.tools.includes(import_core3.ToolName.PatternDetect) || baseOptions.tools.includes("patterns")) {
|
|
707
481
|
const { getSmartDefaults } = await import("@aiready/pattern-detect");
|
|
708
482
|
const patternSmartDefaults = await getSmartDefaults(
|
|
709
483
|
resolvedDir,
|
|
@@ -718,256 +492,21 @@ async function scanAction(directory, options) {
|
|
|
718
492
|
console.log(import_chalk3.default.cyan("\n=== AIReady Run Preview ==="));
|
|
719
493
|
console.log(
|
|
720
494
|
import_chalk3.default.white("Tools to run:"),
|
|
721
|
-
(finalOptions.tools || [
|
|
495
|
+
(finalOptions.tools || []).join(", ")
|
|
722
496
|
);
|
|
723
|
-
console.log(import_chalk3.default.white("Will use settings from config and defaults."));
|
|
724
|
-
console.log(import_chalk3.default.white("\nGeneral settings:"));
|
|
725
|
-
if (finalOptions.rootDir)
|
|
726
|
-
console.log(` rootDir: ${import_chalk3.default.bold(String(finalOptions.rootDir))}`);
|
|
727
|
-
if (finalOptions.include)
|
|
728
|
-
console.log(
|
|
729
|
-
` include: ${import_chalk3.default.bold(truncateArray(finalOptions.include, 6))}`
|
|
730
|
-
);
|
|
731
|
-
if (finalOptions.exclude)
|
|
732
|
-
console.log(
|
|
733
|
-
` exclude: ${import_chalk3.default.bold(truncateArray(finalOptions.exclude, 6))}`
|
|
734
|
-
);
|
|
735
|
-
if (finalOptions["pattern-detect"] || finalOptions.minSimilarity) {
|
|
736
|
-
const patternDetectConfig = finalOptions["pattern-detect"] || {
|
|
737
|
-
minSimilarity: finalOptions.minSimilarity,
|
|
738
|
-
minLines: finalOptions.minLines,
|
|
739
|
-
approx: finalOptions.approx,
|
|
740
|
-
minSharedTokens: finalOptions.minSharedTokens,
|
|
741
|
-
maxCandidatesPerBlock: finalOptions.maxCandidatesPerBlock,
|
|
742
|
-
batchSize: finalOptions.batchSize,
|
|
743
|
-
streamResults: finalOptions.streamResults,
|
|
744
|
-
severity: finalOptions.severity,
|
|
745
|
-
includeTests: finalOptions.includeTests
|
|
746
|
-
};
|
|
747
|
-
console.log(import_chalk3.default.white("\nPattern-detect settings:"));
|
|
748
|
-
console.log(
|
|
749
|
-
` minSimilarity: ${import_chalk3.default.bold(patternDetectConfig.minSimilarity ?? "default")}`
|
|
750
|
-
);
|
|
751
|
-
console.log(
|
|
752
|
-
` minLines: ${import_chalk3.default.bold(patternDetectConfig.minLines ?? "default")}`
|
|
753
|
-
);
|
|
754
|
-
if (patternDetectConfig.approx !== void 0)
|
|
755
|
-
console.log(
|
|
756
|
-
` approx: ${import_chalk3.default.bold(String(patternDetectConfig.approx))}`
|
|
757
|
-
);
|
|
758
|
-
if (patternDetectConfig.minSharedTokens !== void 0)
|
|
759
|
-
console.log(
|
|
760
|
-
` minSharedTokens: ${import_chalk3.default.bold(String(patternDetectConfig.minSharedTokens))}`
|
|
761
|
-
);
|
|
762
|
-
if (patternDetectConfig.maxCandidatesPerBlock !== void 0)
|
|
763
|
-
console.log(
|
|
764
|
-
` maxCandidatesPerBlock: ${import_chalk3.default.bold(String(patternDetectConfig.maxCandidatesPerBlock))}`
|
|
765
|
-
);
|
|
766
|
-
if (patternDetectConfig.batchSize !== void 0)
|
|
767
|
-
console.log(
|
|
768
|
-
` batchSize: ${import_chalk3.default.bold(String(patternDetectConfig.batchSize))}`
|
|
769
|
-
);
|
|
770
|
-
if (patternDetectConfig.streamResults !== void 0)
|
|
771
|
-
console.log(
|
|
772
|
-
` streamResults: ${import_chalk3.default.bold(String(patternDetectConfig.streamResults))}`
|
|
773
|
-
);
|
|
774
|
-
if (patternDetectConfig.severity !== void 0)
|
|
775
|
-
console.log(
|
|
776
|
-
` severity: ${import_chalk3.default.bold(String(patternDetectConfig.severity))}`
|
|
777
|
-
);
|
|
778
|
-
if (patternDetectConfig.includeTests !== void 0)
|
|
779
|
-
console.log(
|
|
780
|
-
` includeTests: ${import_chalk3.default.bold(String(patternDetectConfig.includeTests))}`
|
|
781
|
-
);
|
|
782
|
-
}
|
|
783
|
-
if (finalOptions["context-analyzer"] || finalOptions.maxDepth) {
|
|
784
|
-
const ca = finalOptions["context-analyzer"] || {
|
|
785
|
-
maxDepth: finalOptions.maxDepth,
|
|
786
|
-
maxContextBudget: finalOptions.maxContextBudget,
|
|
787
|
-
minCohesion: finalOptions.minCohesion,
|
|
788
|
-
maxFragmentation: finalOptions.maxFragmentation,
|
|
789
|
-
includeNodeModules: finalOptions.includeNodeModules
|
|
790
|
-
};
|
|
791
|
-
console.log(import_chalk3.default.white("\nContext-analyzer settings:"));
|
|
792
|
-
console.log(` maxDepth: ${import_chalk3.default.bold(ca.maxDepth ?? "default")}`);
|
|
793
|
-
console.log(
|
|
794
|
-
` maxContextBudget: ${import_chalk3.default.bold(ca.maxContextBudget ?? "default")}`
|
|
795
|
-
);
|
|
796
|
-
if (ca.minCohesion !== void 0)
|
|
797
|
-
console.log(` minCohesion: ${import_chalk3.default.bold(String(ca.minCohesion))}`);
|
|
798
|
-
if (ca.maxFragmentation !== void 0)
|
|
799
|
-
console.log(
|
|
800
|
-
` maxFragmentation: ${import_chalk3.default.bold(String(ca.maxFragmentation))}`
|
|
801
|
-
);
|
|
802
|
-
if (ca.includeNodeModules !== void 0)
|
|
803
|
-
console.log(
|
|
804
|
-
` includeNodeModules: ${import_chalk3.default.bold(String(ca.includeNodeModules))}`
|
|
805
|
-
);
|
|
806
|
-
}
|
|
807
|
-
if (finalOptions.consistency) {
|
|
808
|
-
const c = finalOptions.consistency;
|
|
809
|
-
console.log(import_chalk3.default.white("\nConsistency settings:"));
|
|
810
|
-
console.log(
|
|
811
|
-
` checkNaming: ${import_chalk3.default.bold(String(c.checkNaming ?? true))}`
|
|
812
|
-
);
|
|
813
|
-
console.log(
|
|
814
|
-
` checkPatterns: ${import_chalk3.default.bold(String(c.checkPatterns ?? true))}`
|
|
815
|
-
);
|
|
816
|
-
console.log(
|
|
817
|
-
` checkArchitecture: ${import_chalk3.default.bold(String(c.checkArchitecture ?? false))}`
|
|
818
|
-
);
|
|
819
|
-
if (c.minSeverity)
|
|
820
|
-
console.log(` minSeverity: ${import_chalk3.default.bold(c.minSeverity)}`);
|
|
821
|
-
if (c.acceptedAbbreviations)
|
|
822
|
-
console.log(
|
|
823
|
-
` acceptedAbbreviations: ${import_chalk3.default.bold(truncateArray(c.acceptedAbbreviations, 8))}`
|
|
824
|
-
);
|
|
825
|
-
if (c.shortWords)
|
|
826
|
-
console.log(
|
|
827
|
-
` shortWords: ${import_chalk3.default.bold(truncateArray(c.shortWords, 8))}`
|
|
828
|
-
);
|
|
829
|
-
}
|
|
830
|
-
console.log(import_chalk3.default.white("\nStarting analysis..."));
|
|
831
497
|
const progressCallback = (event) => {
|
|
832
498
|
console.log(import_chalk3.default.cyan(`
|
|
833
499
|
--- ${event.tool.toUpperCase()} RESULTS ---`));
|
|
834
|
-
|
|
835
|
-
|
|
836
|
-
|
|
500
|
+
const res = event.data;
|
|
501
|
+
if (res.summary) {
|
|
502
|
+
if (res.summary.totalIssues !== void 0)
|
|
503
|
+
console.log(` Issues found: ${import_chalk3.default.bold(res.summary.totalIssues)}`);
|
|
504
|
+
if (res.summary.score !== void 0)
|
|
505
|
+
console.log(` Tool Score: ${import_chalk3.default.bold(res.summary.score)}/100`);
|
|
506
|
+
if (res.summary.totalFiles !== void 0)
|
|
837
507
|
console.log(
|
|
838
|
-
`
|
|
508
|
+
` Files analyzed: ${import_chalk3.default.bold(res.summary.totalFiles)}`
|
|
839
509
|
);
|
|
840
|
-
console.log(
|
|
841
|
-
` Files with pattern issues: ${import_chalk3.default.bold(String(pr.results?.length || 0))}`
|
|
842
|
-
);
|
|
843
|
-
if (pr.duplicates && pr.duplicates.length > 0) {
|
|
844
|
-
pr.duplicates.slice(0, 5).forEach((d, i) => {
|
|
845
|
-
console.log(
|
|
846
|
-
` ${i + 1}. ${d.file1.split("/").pop()} \u2194 ${d.file2.split("/").pop()} (sim=${(d.similarity * 100).toFixed(1)}%)`
|
|
847
|
-
);
|
|
848
|
-
});
|
|
849
|
-
}
|
|
850
|
-
if (pr.results && pr.results.length > 0) {
|
|
851
|
-
console.log(` Top files with pattern issues:`);
|
|
852
|
-
const sortedByIssues = [...pr.results].sort(
|
|
853
|
-
(a, b) => (b.issues?.length || 0) - (a.issues?.length || 0)
|
|
854
|
-
);
|
|
855
|
-
sortedByIssues.slice(0, 5).forEach((r, i) => {
|
|
856
|
-
console.log(
|
|
857
|
-
` ${i + 1}. ${r.fileName.split("/").pop()} - ${r.issues.length} issue(s)`
|
|
858
|
-
);
|
|
859
|
-
});
|
|
860
|
-
}
|
|
861
|
-
if (pr.groups && pr.groups.length >= 0) {
|
|
862
|
-
console.log(
|
|
863
|
-
` \u2705 Grouped ${import_chalk3.default.bold(String(pr.duplicates?.length || 0))} duplicates into ${import_chalk3.default.bold(String(pr.groups.length))} file pairs`
|
|
864
|
-
);
|
|
865
|
-
}
|
|
866
|
-
if (pr.clusters && pr.clusters.length >= 0) {
|
|
867
|
-
console.log(
|
|
868
|
-
` \u2705 Created ${import_chalk3.default.bold(String(pr.clusters.length))} refactor clusters`
|
|
869
|
-
);
|
|
870
|
-
pr.clusters.slice(0, 3).forEach((cl, idx) => {
|
|
871
|
-
const files = (cl.files || []).map((f) => f.path.split("/").pop()).join(", ");
|
|
872
|
-
console.log(
|
|
873
|
-
` ${idx + 1}. ${files} (${cl.tokenCost || "n/a"} tokens)`
|
|
874
|
-
);
|
|
875
|
-
});
|
|
876
|
-
}
|
|
877
|
-
} else if (event.tool === "context") {
|
|
878
|
-
const cr = event.data;
|
|
879
|
-
console.log(
|
|
880
|
-
` Context issues found: ${import_chalk3.default.bold(String(cr.length || 0))}`
|
|
881
|
-
);
|
|
882
|
-
cr.slice(0, 5).forEach((c, i) => {
|
|
883
|
-
const msg = c.message ? ` - ${c.message}` : "";
|
|
884
|
-
console.log(
|
|
885
|
-
` ${i + 1}. ${c.file} (${c.severity || "n/a"})${msg}`
|
|
886
|
-
);
|
|
887
|
-
});
|
|
888
|
-
} else if (event.tool === "consistency") {
|
|
889
|
-
const rep = event.data;
|
|
890
|
-
console.log(
|
|
891
|
-
` Consistency totalIssues: ${import_chalk3.default.bold(String(rep.summary?.totalIssues || 0))}`
|
|
892
|
-
);
|
|
893
|
-
if (rep.results && rep.results.length > 0) {
|
|
894
|
-
const fileMap = /* @__PURE__ */ new Map();
|
|
895
|
-
rep.results.forEach((r) => {
|
|
896
|
-
(r.issues || []).forEach((issue) => {
|
|
897
|
-
const file = issue.location?.file || r.file || "unknown";
|
|
898
|
-
if (!fileMap.has(file)) fileMap.set(file, []);
|
|
899
|
-
fileMap.get(file).push(issue);
|
|
900
|
-
});
|
|
901
|
-
});
|
|
902
|
-
const files = Array.from(fileMap.entries()).sort(
|
|
903
|
-
(a, b) => b[1].length - a[1].length
|
|
904
|
-
);
|
|
905
|
-
const topFiles = files.slice(0, 10);
|
|
906
|
-
topFiles.forEach(([file, issues], idx) => {
|
|
907
|
-
const counts = issues.reduce(
|
|
908
|
-
(acc, it) => {
|
|
909
|
-
const s = (it.severity || import_core3.Severity.Info).toLowerCase();
|
|
910
|
-
acc[s] = (acc[s] || 0) + 1;
|
|
911
|
-
return acc;
|
|
912
|
-
},
|
|
913
|
-
{}
|
|
914
|
-
);
|
|
915
|
-
const sample = issues.find(
|
|
916
|
-
(it) => it.severity === import_core3.Severity.Critical || it.severity === import_core3.Severity.Major
|
|
917
|
-
) || issues[0];
|
|
918
|
-
const sampleMsg = sample ? ` \u2014 ${sample.message}` : "";
|
|
919
|
-
console.log(
|
|
920
|
-
` ${idx + 1}. ${file} \u2014 ${issues.length} issue(s) (critical:${counts[import_core3.Severity.Critical] || 0} major:${counts[import_core3.Severity.Major] || 0} minor:${counts[import_core3.Severity.Minor] || 0} info:${counts[import_core3.Severity.Info] || 0})${sampleMsg}`
|
|
921
|
-
);
|
|
922
|
-
});
|
|
923
|
-
const remaining = files.length - topFiles.length;
|
|
924
|
-
if (remaining > 0) {
|
|
925
|
-
console.log(
|
|
926
|
-
import_chalk3.default.dim(
|
|
927
|
-
` ... and ${remaining} more files with issues (use --output json for full details)`
|
|
928
|
-
)
|
|
929
|
-
);
|
|
930
|
-
}
|
|
931
|
-
}
|
|
932
|
-
} else if (event.tool === "doc-drift") {
|
|
933
|
-
const dr = event.data;
|
|
934
|
-
console.log(
|
|
935
|
-
` Issues found: ${import_chalk3.default.bold(String(dr.issues?.length || 0))}`
|
|
936
|
-
);
|
|
937
|
-
if (dr.rawData) {
|
|
938
|
-
console.log(
|
|
939
|
-
` Signature Mismatches: ${import_chalk3.default.bold(dr.rawData.outdatedComments || 0)}`
|
|
940
|
-
);
|
|
941
|
-
console.log(
|
|
942
|
-
` Undocumented Complexity: ${import_chalk3.default.bold(dr.rawData.undocumentedComplexity || 0)}`
|
|
943
|
-
);
|
|
944
|
-
}
|
|
945
|
-
} else if (event.tool === "deps-health") {
|
|
946
|
-
const dr = event.data;
|
|
947
|
-
console.log(
|
|
948
|
-
` Packages Analyzed: ${import_chalk3.default.bold(String(dr.summary?.packagesAnalyzed || 0))}`
|
|
949
|
-
);
|
|
950
|
-
if (dr.rawData) {
|
|
951
|
-
console.log(
|
|
952
|
-
` Deprecated Packages: ${import_chalk3.default.bold(dr.rawData.deprecatedPackages || 0)}`
|
|
953
|
-
);
|
|
954
|
-
console.log(
|
|
955
|
-
` AI Cutoff Skew Score: ${import_chalk3.default.bold(dr.rawData.trainingCutoffSkew?.toFixed(1) || 0)}`
|
|
956
|
-
);
|
|
957
|
-
}
|
|
958
|
-
} else if (event.tool === "change-amplification" || event.tool === "changeAmplification") {
|
|
959
|
-
const dr = event.data;
|
|
960
|
-
console.log(
|
|
961
|
-
` Coupling issues: ${import_chalk3.default.bold(String(dr.issues?.length || 0))}`
|
|
962
|
-
);
|
|
963
|
-
if (dr.summary) {
|
|
964
|
-
console.log(
|
|
965
|
-
` Complexity Score: ${import_chalk3.default.bold(dr.summary.score || 0)}/100`
|
|
966
|
-
);
|
|
967
|
-
}
|
|
968
|
-
}
|
|
969
|
-
} catch (err) {
|
|
970
|
-
void err;
|
|
971
510
|
}
|
|
972
511
|
};
|
|
973
512
|
const results = await analyzeUnified({
|
|
@@ -977,44 +516,14 @@ async function scanAction(directory, options) {
|
|
|
977
516
|
process.stdout.write(
|
|
978
517
|
`\r\x1B[K [${processed}/${total}] ${message}...`
|
|
979
518
|
);
|
|
980
|
-
if (processed === total)
|
|
981
|
-
process.stdout.write("\n");
|
|
982
|
-
}
|
|
519
|
+
if (processed === total) process.stdout.write("\n");
|
|
983
520
|
},
|
|
984
521
|
suppressToolConfig: true
|
|
985
522
|
});
|
|
986
523
|
console.log(import_chalk3.default.cyan("\n=== AIReady Run Summary ==="));
|
|
987
|
-
console.log(
|
|
988
|
-
import_chalk3.default.white("Tools run:"),
|
|
989
|
-
(finalOptions.tools || ["patterns", "context", "consistency"]).join(", ")
|
|
990
|
-
);
|
|
991
|
-
console.log(import_chalk3.default.cyan("\nResults summary:"));
|
|
992
524
|
console.log(
|
|
993
525
|
` Total issues (all tools): ${import_chalk3.default.bold(String(results.summary.totalIssues || 0))}`
|
|
994
526
|
);
|
|
995
|
-
if (results[import_core3.ToolName.PatternDetect]) {
|
|
996
|
-
console.log(
|
|
997
|
-
` Duplicate patterns found: ${import_chalk3.default.bold(String(results[import_core3.ToolName.PatternDetect].duplicates?.length || 0))}`
|
|
998
|
-
);
|
|
999
|
-
console.log(
|
|
1000
|
-
` Pattern files with issues: ${import_chalk3.default.bold(String(results[import_core3.ToolName.PatternDetect].results.length || 0))}`
|
|
1001
|
-
);
|
|
1002
|
-
}
|
|
1003
|
-
if (results[import_core3.ToolName.ContextAnalyzer])
|
|
1004
|
-
console.log(
|
|
1005
|
-
` Context issues: ${import_chalk3.default.bold(String(results[import_core3.ToolName.ContextAnalyzer].results.length || 0))}`
|
|
1006
|
-
);
|
|
1007
|
-
if (results[import_core3.ToolName.NamingConsistency])
|
|
1008
|
-
console.log(
|
|
1009
|
-
` Consistency issues: ${import_chalk3.default.bold(String(results[import_core3.ToolName.NamingConsistency].summary?.totalIssues || 0))}`
|
|
1010
|
-
);
|
|
1011
|
-
if (results[import_core3.ToolName.ChangeAmplification])
|
|
1012
|
-
console.log(
|
|
1013
|
-
` Change amplification: ${import_chalk3.default.bold(String(results[import_core3.ToolName.ChangeAmplification].summary?.score || 0))}/100`
|
|
1014
|
-
);
|
|
1015
|
-
console.log(import_chalk3.default.cyan("===========================\n"));
|
|
1016
|
-
const elapsedTime = (0, import_core3.getElapsedTime)(startTime);
|
|
1017
|
-
void elapsedTime;
|
|
1018
527
|
let scoringResult;
|
|
1019
528
|
if (options.score || finalOptions.scoring?.showBreakdown) {
|
|
1020
529
|
scoringResult = await scoreUnified(results, finalOptions);
|
|
@@ -1022,55 +531,34 @@ async function scanAction(directory, options) {
|
|
|
1022
531
|
console.log(` ${(0, import_core3.formatScore)(scoringResult)}`);
|
|
1023
532
|
if (options.compareTo) {
|
|
1024
533
|
try {
|
|
1025
|
-
const
|
|
1026
|
-
(0, import_path3.resolve)(process.cwd(), options.compareTo),
|
|
1027
|
-
"utf8"
|
|
534
|
+
const prevReport = JSON.parse(
|
|
535
|
+
(0, import_fs3.readFileSync)((0, import_path3.resolve)(process.cwd(), options.compareTo), "utf8")
|
|
1028
536
|
);
|
|
1029
|
-
const
|
|
1030
|
-
const prevScore = prevReport.scoring?.score || prevReport.scoring?.overallScore;
|
|
537
|
+
const prevScore = prevReport.scoring?.overall || prevReport.scoring?.score;
|
|
1031
538
|
if (typeof prevScore === "number") {
|
|
1032
539
|
const diff = scoringResult.overall - prevScore;
|
|
1033
540
|
const diffStr = diff > 0 ? `+${diff}` : String(diff);
|
|
1034
|
-
|
|
1035
|
-
if (diff > 0) {
|
|
541
|
+
if (diff > 0)
|
|
1036
542
|
console.log(
|
|
1037
543
|
import_chalk3.default.green(
|
|
1038
544
|
` \u{1F4C8} Trend: ${diffStr} compared to ${options.compareTo} (${prevScore} \u2192 ${scoringResult.overall})`
|
|
1039
545
|
)
|
|
1040
546
|
);
|
|
1041
|
-
|
|
547
|
+
else if (diff < 0)
|
|
1042
548
|
console.log(
|
|
1043
549
|
import_chalk3.default.red(
|
|
1044
550
|
` \u{1F4C9} Trend: ${diffStr} compared to ${options.compareTo} (${prevScore} \u2192 ${scoringResult.overall})`
|
|
1045
551
|
)
|
|
1046
552
|
);
|
|
1047
|
-
|
|
553
|
+
else
|
|
1048
554
|
console.log(
|
|
1049
555
|
import_chalk3.default.blue(
|
|
1050
|
-
` \u2796 Trend: No change
|
|
556
|
+
` \u2796 Trend: No change (${prevScore} \u2192 ${scoringResult.overall})`
|
|
1051
557
|
)
|
|
1052
558
|
);
|
|
1053
|
-
}
|
|
1054
|
-
scoringResult.trend = {
|
|
1055
|
-
previousScore: prevScore,
|
|
1056
|
-
difference: diff
|
|
1057
|
-
};
|
|
1058
|
-
} else {
|
|
1059
|
-
console.log(
|
|
1060
|
-
import_chalk3.default.yellow(
|
|
1061
|
-
`
|
|
1062
|
-
\u26A0\uFE0F Previous report at ${options.compareTo} does not contain an overall score.`
|
|
1063
|
-
)
|
|
1064
|
-
);
|
|
1065
559
|
}
|
|
1066
560
|
} catch (e) {
|
|
1067
561
|
void e;
|
|
1068
|
-
console.log(
|
|
1069
|
-
import_chalk3.default.yellow(
|
|
1070
|
-
`
|
|
1071
|
-
\u26A0\uFE0F Could not read or parse previous report at ${options.compareTo}.`
|
|
1072
|
-
)
|
|
1073
|
-
);
|
|
1074
562
|
}
|
|
1075
563
|
}
|
|
1076
564
|
const totalWastedDuplication = (scoringResult.breakdown || []).reduce(
|
|
@@ -1084,7 +572,8 @@ async function scanAction(directory, options) {
|
|
|
1084
572
|
const totalContext = Math.max(
|
|
1085
573
|
...(scoringResult.breakdown || []).map(
|
|
1086
574
|
(s) => s.tokenBudget?.totalContextTokens || 0
|
|
1087
|
-
)
|
|
575
|
+
),
|
|
576
|
+
0
|
|
1088
577
|
);
|
|
1089
578
|
if (totalContext > 0) {
|
|
1090
579
|
const unifiedBudget = (0, import_core3.calculateTokenBudget)({
|
|
@@ -1095,35 +584,17 @@ async function scanAction(directory, options) {
|
|
|
1095
584
|
chattiness: 0
|
|
1096
585
|
}
|
|
1097
586
|
});
|
|
1098
|
-
const
|
|
1099
|
-
const modelPreset = (0, import_core3.getModelPreset)(targetModel);
|
|
587
|
+
const modelPreset = (0, import_core3.getModelPreset)(options.model || "claude-4.6");
|
|
1100
588
|
const costEstimate = (0, import_core3.estimateCostFromBudget)(unifiedBudget, modelPreset);
|
|
1101
|
-
|
|
1102
|
-
const filled = Math.round(unifiedBudget.efficiencyRatio * barWidth);
|
|
1103
|
-
const bar = import_chalk3.default.green("\u2588".repeat(filled)) + import_chalk3.default.dim("\u2591".repeat(barWidth - filled));
|
|
1104
|
-
console.log(import_chalk3.default.bold("\n\u{1F4CA} AI Token Budget Analysis (v0.13)"));
|
|
1105
|
-
console.log(
|
|
1106
|
-
` Efficiency: [${bar}] ${(unifiedBudget.efficiencyRatio * 100).toFixed(0)}%`
|
|
1107
|
-
);
|
|
1108
|
-
console.log(
|
|
1109
|
-
` Total Context: ${import_chalk3.default.bold(unifiedBudget.totalContextTokens.toLocaleString())} tokens`
|
|
1110
|
-
);
|
|
1111
|
-
console.log(
|
|
1112
|
-
` Wasted Tokens: ${import_chalk3.default.red(unifiedBudget.wastedTokens.total.toLocaleString())} (${(unifiedBudget.wastedTokens.total / unifiedBudget.totalContextTokens * 100).toFixed(1)}%)`
|
|
1113
|
-
);
|
|
1114
|
-
console.log(` Waste Breakdown:`);
|
|
1115
|
-
console.log(
|
|
1116
|
-
` \u2022 Duplication: ${unifiedBudget.wastedTokens.bySource.duplication.toLocaleString()} tokens`
|
|
1117
|
-
);
|
|
589
|
+
console.log(import_chalk3.default.bold("\n\u{1F4CA} AI Token Budget Analysis"));
|
|
1118
590
|
console.log(
|
|
1119
|
-
`
|
|
591
|
+
` Efficiency: ${(unifiedBudget.efficiencyRatio * 100).toFixed(0)}%`
|
|
1120
592
|
);
|
|
1121
593
|
console.log(
|
|
1122
|
-
`
|
|
594
|
+
` Wasted Tokens: ${import_chalk3.default.red(unifiedBudget.wastedTokens.total.toLocaleString())}`
|
|
1123
595
|
);
|
|
1124
596
|
console.log(
|
|
1125
|
-
`
|
|
1126
|
-
Est. Monthly Cost (${modelPreset.name}): ${import_chalk3.default.bold("$" + costEstimate.total)} [range: $${costEstimate.range[0]}-$${costEstimate.range[1]}]`
|
|
597
|
+
` Est. Monthly Cost (${modelPreset.name}): ${import_chalk3.default.bold("$" + costEstimate.total)}`
|
|
1127
598
|
);
|
|
1128
599
|
scoringResult.tokenBudget = unifiedBudget;
|
|
1129
600
|
scoringResult.costEstimate = {
|
|
@@ -1131,85 +602,31 @@ async function scanAction(directory, options) {
|
|
|
1131
602
|
...costEstimate
|
|
1132
603
|
};
|
|
1133
604
|
}
|
|
1134
|
-
if (scoringResult.breakdown
|
|
605
|
+
if (scoringResult.breakdown) {
|
|
1135
606
|
console.log(import_chalk3.default.bold("\nTool breakdown:"));
|
|
1136
607
|
scoringResult.breakdown.forEach((tool) => {
|
|
1137
608
|
const rating = (0, import_core3.getRating)(tool.score);
|
|
1138
|
-
|
|
1139
|
-
console.log(
|
|
1140
|
-
` - ${tool.toolName}: ${tool.score}/100 (${rating}) ${rd.emoji}`
|
|
1141
|
-
);
|
|
609
|
+
console.log(` - ${tool.toolName}: ${tool.score}/100 (${rating})`);
|
|
1142
610
|
});
|
|
1143
|
-
console.log();
|
|
1144
|
-
if (finalOptions.scoring?.showBreakdown) {
|
|
1145
|
-
console.log(import_chalk3.default.bold("Detailed tool breakdown:"));
|
|
1146
|
-
scoringResult.breakdown.forEach((tool) => {
|
|
1147
|
-
console.log((0, import_core3.formatToolScore)(tool));
|
|
1148
|
-
});
|
|
1149
|
-
console.log();
|
|
1150
|
-
}
|
|
1151
611
|
}
|
|
1152
612
|
}
|
|
1153
613
|
const mapToUnifiedReport = (res, scoring) => {
|
|
1154
614
|
const allResults = [];
|
|
1155
|
-
|
|
615
|
+
const totalFilesSet = /* @__PURE__ */ new Set();
|
|
1156
616
|
let criticalCount = 0;
|
|
1157
617
|
let majorCount = 0;
|
|
1158
|
-
|
|
618
|
+
res.summary.toolsRun.forEach((toolId) => {
|
|
619
|
+
const spokeRes = res[toolId];
|
|
1159
620
|
if (!spokeRes || !spokeRes.results) return;
|
|
1160
621
|
spokeRes.results.forEach((r) => {
|
|
1161
|
-
|
|
1162
|
-
|
|
1163
|
-
|
|
1164
|
-
|
|
1165
|
-
|
|
1166
|
-
|
|
1167
|
-
};
|
|
1168
|
-
if (r.issues && Array.isArray(r.issues)) {
|
|
1169
|
-
r.issues.forEach((i) => {
|
|
1170
|
-
const normalizedIssue = typeof i === "string" ? {
|
|
1171
|
-
type: defaultType,
|
|
1172
|
-
severity: r.severity || import_core3.Severity.Info,
|
|
1173
|
-
message: i,
|
|
1174
|
-
location: { file: fileName, line: 1 }
|
|
1175
|
-
} : {
|
|
1176
|
-
type: i.type || defaultType,
|
|
1177
|
-
severity: i.severity || r.severity || import_core3.Severity.Info,
|
|
1178
|
-
message: i.message || String(i),
|
|
1179
|
-
location: i.location || { file: fileName, line: 1 },
|
|
1180
|
-
suggestion: i.suggestion
|
|
1181
|
-
};
|
|
1182
|
-
if (normalizedIssue.severity === import_core3.Severity.Critical || normalizedIssue.severity === "critical")
|
|
1183
|
-
criticalCount++;
|
|
1184
|
-
if (normalizedIssue.severity === import_core3.Severity.Major || normalizedIssue.severity === "major")
|
|
1185
|
-
majorCount++;
|
|
1186
|
-
normalizedResult.issues.push(normalizedIssue);
|
|
1187
|
-
});
|
|
1188
|
-
} else if (r.severity) {
|
|
1189
|
-
const normalizedIssue = {
|
|
1190
|
-
type: defaultType,
|
|
1191
|
-
severity: r.severity,
|
|
1192
|
-
message: r.message || "General issue",
|
|
1193
|
-
location: { file: fileName, line: 1 }
|
|
1194
|
-
};
|
|
1195
|
-
if (normalizedIssue.severity === import_core3.Severity.Critical || normalizedIssue.severity === "critical")
|
|
1196
|
-
criticalCount++;
|
|
1197
|
-
if (normalizedIssue.severity === import_core3.Severity.Major || normalizedIssue.severity === "major")
|
|
1198
|
-
majorCount++;
|
|
1199
|
-
normalizedResult.issues.push(normalizedIssue);
|
|
1200
|
-
}
|
|
1201
|
-
allResults.push(normalizedResult);
|
|
622
|
+
totalFilesSet.add(r.fileName);
|
|
623
|
+
allResults.push(r);
|
|
624
|
+
r.issues?.forEach((i) => {
|
|
625
|
+
if (i.severity === import_core3.Severity.Critical) criticalCount++;
|
|
626
|
+
if (i.severity === import_core3.Severity.Major) majorCount++;
|
|
627
|
+
});
|
|
1202
628
|
});
|
|
1203
|
-
};
|
|
1204
|
-
collect(res[import_core3.ToolName.PatternDetect], import_core3.IssueType.DuplicatePattern);
|
|
1205
|
-
collect(res[import_core3.ToolName.ContextAnalyzer], import_core3.IssueType.ContextFragmentation);
|
|
1206
|
-
collect(res[import_core3.ToolName.NamingConsistency], import_core3.IssueType.NamingInconsistency);
|
|
1207
|
-
collect(res[import_core3.ToolName.DocDrift], import_core3.IssueType.DocDrift);
|
|
1208
|
-
collect(res[import_core3.ToolName.DependencyHealth], import_core3.IssueType.DependencyHealth);
|
|
1209
|
-
collect(res[import_core3.ToolName.AiSignalClarity], import_core3.IssueType.AiSignalClarity);
|
|
1210
|
-
collect(res[import_core3.ToolName.AgentGrounding], import_core3.IssueType.AgentNavigationFailure);
|
|
1211
|
-
collect(res[import_core3.ToolName.TestabilityIndex], import_core3.IssueType.LowTestability);
|
|
1212
|
-
collect(res[import_core3.ToolName.ChangeAmplification], import_core3.IssueType.ChangeAmplification);
|
|
629
|
+
});
|
|
1213
630
|
return {
|
|
1214
631
|
...res,
|
|
1215
632
|
results: allResults,
|
|
@@ -1222,199 +639,70 @@ async function scanAction(directory, options) {
|
|
|
1222
639
|
scoring
|
|
1223
640
|
};
|
|
1224
641
|
};
|
|
642
|
+
const outputData = {
|
|
643
|
+
...mapToUnifiedReport(results, scoringResult),
|
|
644
|
+
repository: repoMetadata
|
|
645
|
+
};
|
|
1225
646
|
const outputFormat = options.output || finalOptions.output?.format || "console";
|
|
1226
|
-
const
|
|
647
|
+
const outputPath = (0, import_core3.resolveOutputPath)(
|
|
648
|
+
options.outputFile || finalOptions.output?.file,
|
|
649
|
+
`aiready-report-${getReportTimestamp()}.json`,
|
|
650
|
+
resolvedDir
|
|
651
|
+
);
|
|
1227
652
|
if (outputFormat === "json") {
|
|
1228
|
-
const timestamp = getReportTimestamp();
|
|
1229
|
-
const defaultFilename = `aiready-report-${timestamp}.json`;
|
|
1230
|
-
const outputPath = (0, import_core3.resolveOutputPath)(
|
|
1231
|
-
userOutputFile,
|
|
1232
|
-
defaultFilename,
|
|
1233
|
-
resolvedDir
|
|
1234
|
-
);
|
|
1235
|
-
const outputData = {
|
|
1236
|
-
...mapToUnifiedReport(results, scoringResult),
|
|
1237
|
-
repository: repoMetadata
|
|
1238
|
-
};
|
|
1239
653
|
(0, import_core3.handleJSONOutput)(
|
|
1240
654
|
outputData,
|
|
1241
655
|
outputPath,
|
|
1242
656
|
`\u2705 Report saved to ${outputPath}`
|
|
1243
657
|
);
|
|
1244
|
-
if (options.upload) {
|
|
1245
|
-
console.log(import_chalk3.default.blue("\n\u{1F4E4} Automatic upload triggered..."));
|
|
1246
|
-
await uploadAction(outputPath, {
|
|
1247
|
-
apiKey: options.apiKey,
|
|
1248
|
-
server: options.server
|
|
1249
|
-
});
|
|
1250
|
-
}
|
|
1251
|
-
await warnIfGraphCapExceeded(outputData, resolvedDir);
|
|
1252
658
|
} else {
|
|
1253
|
-
const timestamp = getReportTimestamp();
|
|
1254
|
-
const defaultFilename = `aiready-report-${timestamp}.json`;
|
|
1255
|
-
const outputPath = (0, import_core3.resolveOutputPath)(
|
|
1256
|
-
userOutputFile,
|
|
1257
|
-
defaultFilename,
|
|
1258
|
-
resolvedDir
|
|
1259
|
-
);
|
|
1260
|
-
const outputData = {
|
|
1261
|
-
...mapToUnifiedReport(results, scoringResult),
|
|
1262
|
-
repository: repoMetadata
|
|
1263
|
-
};
|
|
1264
659
|
try {
|
|
1265
660
|
(0, import_fs3.writeFileSync)(outputPath, JSON.stringify(outputData, null, 2));
|
|
1266
661
|
console.log(import_chalk3.default.dim(`\u2705 Report auto-persisted to ${outputPath}`));
|
|
1267
|
-
if (options.upload) {
|
|
1268
|
-
console.log(import_chalk3.default.blue("\n\u{1F4E4} Automatic upload triggered..."));
|
|
1269
|
-
await uploadAction(outputPath, {
|
|
1270
|
-
apiKey: options.apiKey,
|
|
1271
|
-
server: options.server
|
|
1272
|
-
});
|
|
1273
|
-
}
|
|
1274
|
-
await warnIfGraphCapExceeded(outputData, resolvedDir);
|
|
1275
662
|
} catch (err) {
|
|
1276
663
|
void err;
|
|
1277
664
|
}
|
|
1278
665
|
}
|
|
1279
|
-
|
|
666
|
+
if (options.upload) {
|
|
667
|
+
await uploadAction(outputPath, {
|
|
668
|
+
apiKey: options.apiKey,
|
|
669
|
+
server: options.server
|
|
670
|
+
});
|
|
671
|
+
}
|
|
672
|
+
await warnIfGraphCapExceeded(outputData, resolvedDir);
|
|
673
|
+
const isCI = options.ci || process.env.CI === "true";
|
|
1280
674
|
if (isCI && scoringResult) {
|
|
1281
675
|
const threshold = options.threshold ? parseInt(options.threshold) : void 0;
|
|
1282
676
|
const failOnLevel = options.failOn || "critical";
|
|
1283
|
-
if (process.env.GITHUB_ACTIONS === "true") {
|
|
1284
|
-
console.log(`
|
|
1285
|
-
::group::AI Readiness Score`);
|
|
1286
|
-
console.log(`score=${scoringResult.overall}`);
|
|
1287
|
-
if (scoringResult.breakdown) {
|
|
1288
|
-
scoringResult.breakdown.forEach((tool) => {
|
|
1289
|
-
console.log(`${tool.toolName}=${tool.score}`);
|
|
1290
|
-
});
|
|
1291
|
-
}
|
|
1292
|
-
console.log("::endgroup::");
|
|
1293
|
-
if (threshold && scoringResult.overall < threshold) {
|
|
1294
|
-
console.log(
|
|
1295
|
-
`::error::AI Readiness Score ${scoringResult.overall} is below threshold ${threshold}`
|
|
1296
|
-
);
|
|
1297
|
-
} else if (threshold) {
|
|
1298
|
-
console.log(
|
|
1299
|
-
`::notice::AI Readiness Score: ${scoringResult.overall}/100 (threshold: ${threshold})`
|
|
1300
|
-
);
|
|
1301
|
-
}
|
|
1302
|
-
if (results[import_core3.ToolName.PatternDetect]) {
|
|
1303
|
-
const criticalPatterns = results[import_core3.ToolName.PatternDetect].results.flatMap(
|
|
1304
|
-
(p) => p.issues.filter((i) => i.severity === import_core3.Severity.Critical)
|
|
1305
|
-
);
|
|
1306
|
-
criticalPatterns.slice(0, 10).forEach((issue) => {
|
|
1307
|
-
console.log(
|
|
1308
|
-
`::warning file=${issue.location?.file || "unknown"},line=${issue.location?.line || 1}::${issue.message}`
|
|
1309
|
-
);
|
|
1310
|
-
});
|
|
1311
|
-
}
|
|
1312
|
-
}
|
|
1313
677
|
let shouldFail = false;
|
|
1314
678
|
let failReason = "";
|
|
1315
679
|
if (threshold && scoringResult.overall < threshold) {
|
|
1316
680
|
shouldFail = true;
|
|
1317
|
-
failReason = `
|
|
681
|
+
failReason = `Score ${scoringResult.overall} < threshold ${threshold}`;
|
|
1318
682
|
}
|
|
683
|
+
const report = mapToUnifiedReport(results, scoringResult);
|
|
1319
684
|
if (failOnLevel !== "none") {
|
|
1320
|
-
|
|
1321
|
-
const minSeverity = severityLevels[failOnLevel] || 4;
|
|
1322
|
-
let criticalCount = 0;
|
|
1323
|
-
let majorCount = 0;
|
|
1324
|
-
if (results[import_core3.ToolName.PatternDetect]) {
|
|
1325
|
-
results[import_core3.ToolName.PatternDetect].results.forEach((p) => {
|
|
1326
|
-
p.issues.forEach((i) => {
|
|
1327
|
-
if (i.severity === import_core3.Severity.Critical) criticalCount++;
|
|
1328
|
-
if (i.severity === import_core3.Severity.Major) majorCount++;
|
|
1329
|
-
});
|
|
1330
|
-
});
|
|
1331
|
-
}
|
|
1332
|
-
if (results[import_core3.ToolName.ContextAnalyzer]) {
|
|
1333
|
-
results[import_core3.ToolName.ContextAnalyzer].results.forEach((c) => {
|
|
1334
|
-
if (c.severity === import_core3.Severity.Critical) criticalCount++;
|
|
1335
|
-
if (c.severity === import_core3.Severity.Major) majorCount++;
|
|
1336
|
-
});
|
|
1337
|
-
}
|
|
1338
|
-
if (results[import_core3.ToolName.NamingConsistency]) {
|
|
1339
|
-
results[import_core3.ToolName.NamingConsistency].results.forEach((r) => {
|
|
1340
|
-
r.issues?.forEach((i) => {
|
|
1341
|
-
if (i.severity === import_core3.Severity.Critical) criticalCount++;
|
|
1342
|
-
if (i.severity === import_core3.Severity.Major) majorCount++;
|
|
1343
|
-
});
|
|
1344
|
-
});
|
|
1345
|
-
}
|
|
1346
|
-
if (minSeverity >= 4 && criticalCount > 0) {
|
|
685
|
+
if (failOnLevel === "critical" && report.summary.criticalIssues > 0) {
|
|
1347
686
|
shouldFail = true;
|
|
1348
|
-
failReason = `Found ${
|
|
1349
|
-
} else if (
|
|
687
|
+
failReason = `Found ${report.summary.criticalIssues} critical issues`;
|
|
688
|
+
} else if (failOnLevel === "major" && report.summary.criticalIssues + report.summary.majorIssues > 0) {
|
|
1350
689
|
shouldFail = true;
|
|
1351
|
-
failReason = `Found ${
|
|
690
|
+
failReason = `Found ${report.summary.criticalIssues} critical and ${report.summary.majorIssues} major issues`;
|
|
1352
691
|
}
|
|
1353
692
|
}
|
|
1354
693
|
if (shouldFail) {
|
|
1355
|
-
console.log(import_chalk3.default.red(
|
|
1356
|
-
|
|
1357
|
-
console.log(import_chalk3.default.dim("\n Remediation steps:"));
|
|
1358
|
-
console.log(
|
|
1359
|
-
import_chalk3.default.dim(" 1. Run `aiready scan` locally to see detailed issues")
|
|
1360
|
-
);
|
|
1361
|
-
console.log(import_chalk3.default.dim(" 2. Fix the critical issues before merging"));
|
|
1362
|
-
console.log(
|
|
1363
|
-
import_chalk3.default.dim(
|
|
1364
|
-
" 3. Consider upgrading to Team plan for historical tracking: https://getaiready.dev/pricing"
|
|
1365
|
-
)
|
|
1366
|
-
);
|
|
694
|
+
console.log(import_chalk3.default.red(`
|
|
695
|
+
\u{1F6AB} PR BLOCKED: ${failReason}`));
|
|
1367
696
|
process.exit(1);
|
|
1368
697
|
} else {
|
|
1369
|
-
console.log(import_chalk3.default.green("\n\u2705 PR PASSED
|
|
1370
|
-
if (threshold) {
|
|
1371
|
-
console.log(
|
|
1372
|
-
import_chalk3.default.green(
|
|
1373
|
-
` Score: ${scoringResult.overall}/100 (threshold: ${threshold})`
|
|
1374
|
-
)
|
|
1375
|
-
);
|
|
1376
|
-
}
|
|
1377
|
-
console.log(
|
|
1378
|
-
import_chalk3.default.dim(
|
|
1379
|
-
"\n \u{1F4A1} Track historical trends: https://getaiready.dev \u2014 Team plan $99/mo"
|
|
1380
|
-
)
|
|
1381
|
-
);
|
|
698
|
+
console.log(import_chalk3.default.green("\n\u2705 PR PASSED"));
|
|
1382
699
|
}
|
|
1383
700
|
}
|
|
1384
701
|
} catch (error) {
|
|
1385
702
|
(0, import_core3.handleCLIError)(error, "Analysis");
|
|
1386
703
|
}
|
|
1387
704
|
}
|
|
1388
|
-
var scanHelpText =
|
|
1389
|
-
EXAMPLES:
|
|
1390
|
-
$ aiready scan # Analyze all tools
|
|
1391
|
-
$ aiready scan --tools patterns,context # Skip consistency
|
|
1392
|
-
$ aiready scan --profile agentic # Optimize for AI agent execution
|
|
1393
|
-
$ aiready scan --profile security # Optimize for secure coding (testability)
|
|
1394
|
-
$ aiready scan --compare-to prev-report.json # Compare trends against previous run
|
|
1395
|
-
$ aiready scan --score --threshold 75 # CI/CD with threshold
|
|
1396
|
-
$ aiready scan --ci --threshold 70 # GitHub Actions gatekeeper
|
|
1397
|
-
$ aiready scan --ci --fail-on major # Fail on major+ issues
|
|
1398
|
-
$ aiready scan --output json --output-file report.json
|
|
1399
|
-
$ aiready scan --upload --api-key ar_... # Automatic platform upload
|
|
1400
|
-
$ aiready scan --upload --server custom-url.com # Upload to custom platform
|
|
1401
|
-
|
|
1402
|
-
PROFILES:
|
|
1403
|
-
agentic: aiSignalClarity, grounding, testability
|
|
1404
|
-
cost: patterns, context
|
|
1405
|
-
security: consistency, testability
|
|
1406
|
-
onboarding: context, consistency, grounding
|
|
1407
|
-
|
|
1408
|
-
CI/CD INTEGRATION (Gatekeeper Mode):
|
|
1409
|
-
Use --ci for GitHub Actions integration:
|
|
1410
|
-
- Outputs GitHub Actions annotations for PR checks
|
|
1411
|
-
- Fails with exit code 1 if threshold not met
|
|
1412
|
-
- Shows clear "blocked" message with remediation steps
|
|
1413
|
-
|
|
1414
|
-
Example GitHub Actions workflow:
|
|
1415
|
-
- name: AI Readiness Check
|
|
1416
|
-
run: aiready scan --ci --threshold 70
|
|
1417
|
-
`;
|
|
705
|
+
var scanHelpText = `...`;
|
|
1418
706
|
|
|
1419
707
|
// src/commands/patterns.ts
|
|
1420
708
|
var import_chalk4 = __toESM(require("chalk"));
|
|
@@ -1457,8 +745,8 @@ async function patternsAction(directory, options) {
|
|
|
1457
745
|
defaults,
|
|
1458
746
|
cliOptions
|
|
1459
747
|
);
|
|
1460
|
-
const { analyzePatterns
|
|
1461
|
-
const { results, duplicates } = await
|
|
748
|
+
const { analyzePatterns, generateSummary, calculatePatternScore } = await import("@aiready/pattern-detect");
|
|
749
|
+
const { results, duplicates } = await analyzePatterns(finalOptions);
|
|
1462
750
|
const elapsedTime = (0, import_core4.getElapsedTime)(startTime);
|
|
1463
751
|
const summary = generateSummary(results);
|
|
1464
752
|
let patternScore;
|
|
@@ -1603,8 +891,8 @@ async function contextAction(directory, options) {
|
|
|
1603
891
|
);
|
|
1604
892
|
console.log(` Analysis focus: ${finalOptions.focus}`);
|
|
1605
893
|
console.log("");
|
|
1606
|
-
const { analyzeContext
|
|
1607
|
-
const results = await
|
|
894
|
+
const { analyzeContext, generateSummary, calculateContextScore } = await import("@aiready/context-analyzer");
|
|
895
|
+
const results = await analyzeContext(finalOptions);
|
|
1608
896
|
const elapsedTime = (0, import_core5.getElapsedTime)(startTime);
|
|
1609
897
|
const summary = generateSummary(results);
|
|
1610
898
|
let contextScore;
|
|
@@ -1788,8 +1076,8 @@ async function consistencyAction(directory, options) {
|
|
|
1788
1076
|
include: options.include?.split(","),
|
|
1789
1077
|
exclude: options.exclude?.split(",")
|
|
1790
1078
|
});
|
|
1791
|
-
const { analyzeConsistency
|
|
1792
|
-
const report = await
|
|
1079
|
+
const { analyzeConsistency, calculateConsistencyScore } = await import("@aiready/consistency");
|
|
1080
|
+
const report = await analyzeConsistency(finalOptions);
|
|
1793
1081
|
const elapsedTime = (0, import_core6.getElapsedTime)(startTime);
|
|
1794
1082
|
let consistencyScore;
|
|
1795
1083
|
if (options.score) {
|