@aiready/cli 0.10.6 → 0.12.1
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 +43 -4
- package/dist/chunk-LTUQDJPO.mjs +229 -0
- package/dist/chunk-N56YAZVN.mjs +194 -0
- package/dist/chunk-YBZKPKW3.mjs +161 -0
- package/dist/cli.js +237 -910
- package/dist/cli.mjs +92 -584
- package/dist/index.js +149 -369
- 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/.aiready/aiready-report-20260307-094831.json +50609 -0
- package/src/.aiready/aiready-report-20260307-100539.json +50609 -0
- package/src/.aiready/aiready-report-20260307-103508.json +51329 -0
- package/src/__tests__/cli.test.ts +55 -29
- package/src/commands/scan.ts +116 -700
- package/src/index.ts +191 -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,172 @@ var import_path3 = require("path");
|
|
|
36
36
|
var import_core3 = require("@aiready/core");
|
|
37
37
|
|
|
38
38
|
// src/index.ts
|
|
39
|
+
var import_core = require("@aiready/core");
|
|
39
40
|
var import_pattern_detect = require("@aiready/pattern-detect");
|
|
40
41
|
var import_context_analyzer = require("@aiready/context-analyzer");
|
|
41
42
|
var import_consistency = require("@aiready/consistency");
|
|
42
|
-
var
|
|
43
|
-
var
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
43
|
+
var import_ai_signal_clarity = require("@aiready/ai-signal-clarity");
|
|
44
|
+
var import_agent_grounding = require("@aiready/agent-grounding");
|
|
45
|
+
var import_testability = require("@aiready/testability");
|
|
46
|
+
var import_doc_drift = require("@aiready/doc-drift");
|
|
47
|
+
var import_deps = require("@aiready/deps");
|
|
48
|
+
var import_change_amplification = require("@aiready/change-amplification");
|
|
49
|
+
var TOOL_PACKAGE_MAP = {
|
|
50
|
+
[import_core.ToolName.PatternDetect]: "@aiready/pattern-detect",
|
|
51
|
+
[import_core.ToolName.ContextAnalyzer]: "@aiready/context-analyzer",
|
|
52
|
+
[import_core.ToolName.NamingConsistency]: "@aiready/consistency",
|
|
53
|
+
[import_core.ToolName.AiSignalClarity]: "@aiready/ai-signal-clarity",
|
|
54
|
+
[import_core.ToolName.AgentGrounding]: "@aiready/agent-grounding",
|
|
55
|
+
[import_core.ToolName.TestabilityIndex]: "@aiready/testability",
|
|
56
|
+
[import_core.ToolName.DocDrift]: "@aiready/doc-drift",
|
|
57
|
+
[import_core.ToolName.DependencyHealth]: "@aiready/deps",
|
|
58
|
+
[import_core.ToolName.ChangeAmplification]: "@aiready/change-amplification",
|
|
59
|
+
// Aliases handled by registry
|
|
60
|
+
patterns: "@aiready/pattern-detect",
|
|
61
|
+
duplicates: "@aiready/pattern-detect",
|
|
62
|
+
context: "@aiready/context-analyzer",
|
|
63
|
+
fragmentation: "@aiready/context-analyzer",
|
|
64
|
+
consistency: "@aiready/consistency",
|
|
65
|
+
"naming-consistency": "@aiready/consistency",
|
|
66
|
+
"ai-signal": "@aiready/ai-signal-clarity",
|
|
67
|
+
"ai-signal-clarity": "@aiready/ai-signal-clarity",
|
|
68
|
+
grounding: "@aiready/agent-grounding",
|
|
69
|
+
"agent-grounding": "@aiready/agent-grounding",
|
|
70
|
+
testability: "@aiready/testability",
|
|
71
|
+
"testability-index": "@aiready/testability",
|
|
72
|
+
"doc-drift": "@aiready/doc-drift",
|
|
73
|
+
"deps-health": "@aiready/deps",
|
|
74
|
+
"dependency-health": "@aiready/deps",
|
|
75
|
+
"change-amp": "@aiready/change-amplification",
|
|
76
|
+
"change-amplification": "@aiready/change-amplification"
|
|
48
77
|
};
|
|
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
78
|
async function analyzeUnified(options) {
|
|
76
79
|
const startTime = Date.now();
|
|
77
|
-
const
|
|
80
|
+
const requestedTools = options.tools || [
|
|
81
|
+
"patterns",
|
|
82
|
+
"context",
|
|
83
|
+
"consistency"
|
|
84
|
+
];
|
|
78
85
|
const result = {
|
|
79
86
|
summary: {
|
|
80
87
|
totalIssues: 0,
|
|
81
|
-
toolsRun:
|
|
88
|
+
toolsRun: [],
|
|
82
89
|
executionTime: 0
|
|
83
90
|
}
|
|
84
91
|
};
|
|
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 });
|
|
224
|
-
}
|
|
225
|
-
result[import_core.ToolName.TestabilityIndex] = {
|
|
226
|
-
...report,
|
|
227
|
-
results: report.results || report.issues || [],
|
|
228
|
-
summary: report.summary || {}
|
|
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
|
+
for (const toolName of requestedTools) {
|
|
93
|
+
let provider = import_core.ToolRegistry.find(toolName);
|
|
94
|
+
if (!provider) {
|
|
95
|
+
const packageName = TOOL_PACKAGE_MAP[toolName] || (toolName.startsWith("@aiready/") ? toolName : `@aiready/${toolName}`);
|
|
96
|
+
try {
|
|
97
|
+
await import(packageName);
|
|
98
|
+
provider = import_core.ToolRegistry.find(toolName);
|
|
99
|
+
if (provider) {
|
|
100
|
+
console.log(
|
|
101
|
+
`\u2705 Successfully loaded tool provider: ${toolName} from ${packageName}`
|
|
102
|
+
);
|
|
103
|
+
} else {
|
|
104
|
+
console.log(
|
|
105
|
+
`\u26A0\uFE0F Loaded ${packageName} but provider ${toolName} still not found in registry.`
|
|
106
|
+
);
|
|
107
|
+
}
|
|
108
|
+
} catch (err) {
|
|
109
|
+
console.log(
|
|
110
|
+
`\u274C Failed to dynamically load tool ${toolName} (${packageName}):`,
|
|
111
|
+
err.message
|
|
112
|
+
);
|
|
113
|
+
}
|
|
242
114
|
}
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
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
|
-
try {
|
|
258
|
-
const patternScore = calculatePatternScore(
|
|
259
|
-
data.duplicates,
|
|
260
|
-
data.results?.length || 0
|
|
261
|
-
);
|
|
262
|
-
const wastedTokens = data.duplicates.reduce(
|
|
263
|
-
(sum, d) => sum + (d.tokenCost || 0),
|
|
264
|
-
0
|
|
115
|
+
if (!provider) {
|
|
116
|
+
console.warn(
|
|
117
|
+
`\u26A0\uFE0F Warning: Tool provider for '${toolName}' not found. Skipping.`
|
|
265
118
|
);
|
|
266
|
-
|
|
267
|
-
totalContextTokens: wastedTokens * 2,
|
|
268
|
-
// Estimated context
|
|
269
|
-
wastedTokens: {
|
|
270
|
-
duplication: wastedTokens,
|
|
271
|
-
fragmentation: 0,
|
|
272
|
-
chattiness: 0
|
|
273
|
-
}
|
|
274
|
-
});
|
|
275
|
-
toolScores.set(import_core.ToolName.PatternDetect, patternScore);
|
|
276
|
-
} catch (err) {
|
|
277
|
-
void err;
|
|
119
|
+
continue;
|
|
278
120
|
}
|
|
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
121
|
try {
|
|
284
|
-
const
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
122
|
+
const output = await provider.analyze({
|
|
123
|
+
...options,
|
|
124
|
+
onProgress: (processed, total, message) => {
|
|
125
|
+
if (options.progressCallback) {
|
|
126
|
+
options.progressCallback({
|
|
127
|
+
tool: provider.id,
|
|
128
|
+
processed,
|
|
129
|
+
total,
|
|
130
|
+
message
|
|
131
|
+
});
|
|
132
|
+
}
|
|
292
133
|
}
|
|
293
134
|
});
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
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]
|
|
135
|
+
if (options.progressCallback) {
|
|
136
|
+
options.progressCallback({ tool: provider.id, data: output });
|
|
137
|
+
}
|
|
138
|
+
result[provider.id] = output;
|
|
139
|
+
result.summary.toolsRun.push(provider.id);
|
|
140
|
+
const issueCount = output.results.reduce(
|
|
141
|
+
(sum, file) => sum + (file.issues?.length || 0),
|
|
142
|
+
0
|
|
316
143
|
);
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
const
|
|
326
|
-
|
|
144
|
+
result.summary.totalIssues += issueCount;
|
|
145
|
+
if (provider.alias && Array.isArray(provider.alias)) {
|
|
146
|
+
for (const alias of provider.alias) {
|
|
147
|
+
if (!result[alias]) {
|
|
148
|
+
result[alias] = output;
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
const camelCaseId = provider.id.replace(
|
|
153
|
+
/-([a-z])/g,
|
|
154
|
+
(g) => g[1].toUpperCase()
|
|
155
|
+
);
|
|
156
|
+
if (camelCaseId !== provider.id && !result[camelCaseId]) {
|
|
157
|
+
result[camelCaseId] = output;
|
|
158
|
+
}
|
|
327
159
|
} catch (err) {
|
|
328
|
-
|
|
160
|
+
console.error(`\u274C Error running tool '${provider.id}':`, err);
|
|
329
161
|
}
|
|
330
162
|
}
|
|
331
|
-
|
|
332
|
-
|
|
163
|
+
result.summary.executionTime = Date.now() - startTime;
|
|
164
|
+
return result;
|
|
165
|
+
}
|
|
166
|
+
async function scoreUnified(results, options) {
|
|
167
|
+
const toolScores = /* @__PURE__ */ new Map();
|
|
168
|
+
for (const toolId of results.summary.toolsRun) {
|
|
169
|
+
const provider = import_core.ToolRegistry.get(toolId);
|
|
170
|
+
if (!provider) continue;
|
|
171
|
+
const output = results[toolId];
|
|
172
|
+
if (!output) continue;
|
|
333
173
|
try {
|
|
334
|
-
const
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
174
|
+
const toolScore = provider.score(output, options);
|
|
175
|
+
if (!toolScore.tokenBudget) {
|
|
176
|
+
if (toolId === import_core.ToolName.PatternDetect && output.duplicates) {
|
|
177
|
+
const wastedTokens = output.duplicates.reduce(
|
|
178
|
+
(sum, d) => sum + (d.tokenCost || 0),
|
|
179
|
+
0
|
|
180
|
+
);
|
|
181
|
+
toolScore.tokenBudget = (0, import_core.calculateTokenBudget)({
|
|
182
|
+
totalContextTokens: wastedTokens * 2,
|
|
183
|
+
wastedTokens: {
|
|
184
|
+
duplication: wastedTokens,
|
|
185
|
+
fragmentation: 0,
|
|
186
|
+
chattiness: 0
|
|
187
|
+
}
|
|
188
|
+
});
|
|
189
|
+
} else if (toolId === import_core.ToolName.ContextAnalyzer && output.summary) {
|
|
190
|
+
toolScore.tokenBudget = (0, import_core.calculateTokenBudget)({
|
|
191
|
+
totalContextTokens: output.summary.totalTokens,
|
|
192
|
+
wastedTokens: {
|
|
193
|
+
duplication: 0,
|
|
194
|
+
fragmentation: output.summary.totalPotentialSavings || 0,
|
|
195
|
+
chattiness: 0
|
|
196
|
+
}
|
|
197
|
+
});
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
toolScores.set(toolId, toolScore);
|
|
338
201
|
} catch (err) {
|
|
339
|
-
|
|
202
|
+
console.error(`\u274C Error scoring tool '${toolId}':`, err);
|
|
340
203
|
}
|
|
341
204
|
}
|
|
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
205
|
if (toolScores.size === 0) {
|
|
391
206
|
return {
|
|
392
207
|
overall: 0,
|
|
@@ -521,12 +336,6 @@ function generateMarkdownReport(report, elapsedTime) {
|
|
|
521
336
|
}
|
|
522
337
|
return markdown;
|
|
523
338
|
}
|
|
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
339
|
|
|
531
340
|
// src/commands/upload.ts
|
|
532
341
|
var import_fs2 = __toESM(require("fs"));
|
|
@@ -640,14 +449,14 @@ async function scanAction(directory, options) {
|
|
|
640
449
|
try {
|
|
641
450
|
const defaults = {
|
|
642
451
|
tools: [
|
|
643
|
-
"
|
|
644
|
-
"context",
|
|
645
|
-
"consistency",
|
|
452
|
+
"pattern-detect",
|
|
453
|
+
"context-analyzer",
|
|
454
|
+
"naming-consistency",
|
|
646
455
|
"ai-signal-clarity",
|
|
647
456
|
"agent-grounding",
|
|
648
|
-
"testability",
|
|
457
|
+
"testability-index",
|
|
649
458
|
"doc-drift",
|
|
650
|
-
"
|
|
459
|
+
"dependency-health",
|
|
651
460
|
"change-amplification"
|
|
652
461
|
],
|
|
653
462
|
include: void 0,
|
|
@@ -657,35 +466,37 @@ async function scanAction(directory, options) {
|
|
|
657
466
|
file: void 0
|
|
658
467
|
}
|
|
659
468
|
};
|
|
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;
|
|
469
|
+
let profileTools = options.tools ? options.tools.split(",").map((t) => t.trim()) : void 0;
|
|
666
470
|
if (options.profile) {
|
|
667
471
|
switch (options.profile.toLowerCase()) {
|
|
668
472
|
case "agentic":
|
|
669
473
|
profileTools = [
|
|
670
|
-
|
|
671
|
-
|
|
672
|
-
|
|
474
|
+
import_core3.ToolName.AiSignalClarity,
|
|
475
|
+
import_core3.ToolName.AgentGrounding,
|
|
476
|
+
import_core3.ToolName.TestabilityIndex
|
|
673
477
|
];
|
|
674
478
|
break;
|
|
675
479
|
case "cost":
|
|
676
|
-
profileTools = [
|
|
480
|
+
profileTools = [import_core3.ToolName.PatternDetect, import_core3.ToolName.ContextAnalyzer];
|
|
677
481
|
break;
|
|
678
482
|
case "security":
|
|
679
|
-
profileTools = [
|
|
483
|
+
profileTools = [
|
|
484
|
+
import_core3.ToolName.NamingConsistency,
|
|
485
|
+
import_core3.ToolName.TestabilityIndex
|
|
486
|
+
];
|
|
680
487
|
break;
|
|
681
488
|
case "onboarding":
|
|
682
|
-
profileTools = [
|
|
489
|
+
profileTools = [
|
|
490
|
+
import_core3.ToolName.ContextAnalyzer,
|
|
491
|
+
import_core3.ToolName.NamingConsistency,
|
|
492
|
+
import_core3.ToolName.AgentGrounding
|
|
493
|
+
];
|
|
683
494
|
break;
|
|
684
495
|
default:
|
|
685
496
|
console.log(
|
|
686
497
|
import_chalk3.default.yellow(
|
|
687
498
|
`
|
|
688
|
-
\u26A0\uFE0F Unknown profile '${options.profile}'. Using
|
|
499
|
+
\u26A0\uFE0F Unknown profile '${options.profile}'. Using defaults.`
|
|
689
500
|
)
|
|
690
501
|
);
|
|
691
502
|
}
|
|
@@ -694,16 +505,14 @@ async function scanAction(directory, options) {
|
|
|
694
505
|
include: options.include?.split(","),
|
|
695
506
|
exclude: options.exclude?.split(",")
|
|
696
507
|
};
|
|
697
|
-
if (profileTools)
|
|
698
|
-
cliOverrides.tools = profileTools;
|
|
699
|
-
}
|
|
508
|
+
if (profileTools) cliOverrides.tools = profileTools;
|
|
700
509
|
const baseOptions = await (0, import_core3.loadMergedConfig)(
|
|
701
510
|
resolvedDir,
|
|
702
511
|
defaults,
|
|
703
512
|
cliOverrides
|
|
704
513
|
);
|
|
705
514
|
let finalOptions = { ...baseOptions };
|
|
706
|
-
if (baseOptions.tools.includes("patterns")) {
|
|
515
|
+
if (baseOptions.tools.includes(import_core3.ToolName.PatternDetect) || baseOptions.tools.includes("patterns")) {
|
|
707
516
|
const { getSmartDefaults } = await import("@aiready/pattern-detect");
|
|
708
517
|
const patternSmartDefaults = await getSmartDefaults(
|
|
709
518
|
resolvedDir,
|
|
@@ -718,256 +527,25 @@ async function scanAction(directory, options) {
|
|
|
718
527
|
console.log(import_chalk3.default.cyan("\n=== AIReady Run Preview ==="));
|
|
719
528
|
console.log(
|
|
720
529
|
import_chalk3.default.white("Tools to run:"),
|
|
721
|
-
(finalOptions.tools || [
|
|
530
|
+
(finalOptions.tools || []).join(", ")
|
|
722
531
|
);
|
|
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
532
|
const progressCallback = (event) => {
|
|
832
|
-
|
|
833
|
-
|
|
834
|
-
|
|
835
|
-
|
|
836
|
-
|
|
837
|
-
|
|
838
|
-
|
|
839
|
-
|
|
840
|
-
|
|
841
|
-
|
|
842
|
-
|
|
843
|
-
|
|
844
|
-
|
|
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;
|
|
533
|
+
if (event.message) {
|
|
534
|
+
process.stdout.write(`\r\x1B[K [${event.tool}] ${event.message}`);
|
|
535
|
+
return;
|
|
536
|
+
}
|
|
537
|
+
process.stdout.write("\n");
|
|
538
|
+
console.log(import_chalk3.default.cyan(`--- ${event.tool.toUpperCase()} RESULTS ---`));
|
|
539
|
+
const res = event.data;
|
|
540
|
+
if (res && res.summary) {
|
|
541
|
+
if (res.summary.totalIssues !== void 0)
|
|
542
|
+
console.log(` Issues found: ${import_chalk3.default.bold(res.summary.totalIssues)}`);
|
|
543
|
+
if (res.summary.score !== void 0)
|
|
544
|
+
console.log(` Tool Score: ${import_chalk3.default.bold(res.summary.score)}/100`);
|
|
545
|
+
if (res.summary.totalFiles !== void 0)
|
|
960
546
|
console.log(
|
|
961
|
-
`
|
|
547
|
+
` Files analyzed: ${import_chalk3.default.bold(res.summary.totalFiles)}`
|
|
962
548
|
);
|
|
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
549
|
}
|
|
972
550
|
};
|
|
973
551
|
const results = await analyzeUnified({
|
|
@@ -977,44 +555,14 @@ async function scanAction(directory, options) {
|
|
|
977
555
|
process.stdout.write(
|
|
978
556
|
`\r\x1B[K [${processed}/${total}] ${message}...`
|
|
979
557
|
);
|
|
980
|
-
if (processed === total)
|
|
981
|
-
process.stdout.write("\n");
|
|
982
|
-
}
|
|
558
|
+
if (processed === total) process.stdout.write("\n");
|
|
983
559
|
},
|
|
984
560
|
suppressToolConfig: true
|
|
985
561
|
});
|
|
986
562
|
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
563
|
console.log(
|
|
993
564
|
` Total issues (all tools): ${import_chalk3.default.bold(String(results.summary.totalIssues || 0))}`
|
|
994
565
|
);
|
|
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
566
|
let scoringResult;
|
|
1019
567
|
if (options.score || finalOptions.scoring?.showBreakdown) {
|
|
1020
568
|
scoringResult = await scoreUnified(results, finalOptions);
|
|
@@ -1022,55 +570,34 @@ async function scanAction(directory, options) {
|
|
|
1022
570
|
console.log(` ${(0, import_core3.formatScore)(scoringResult)}`);
|
|
1023
571
|
if (options.compareTo) {
|
|
1024
572
|
try {
|
|
1025
|
-
const
|
|
1026
|
-
(0, import_path3.resolve)(process.cwd(), options.compareTo),
|
|
1027
|
-
"utf8"
|
|
573
|
+
const prevReport = JSON.parse(
|
|
574
|
+
(0, import_fs3.readFileSync)((0, import_path3.resolve)(process.cwd(), options.compareTo), "utf8")
|
|
1028
575
|
);
|
|
1029
|
-
const
|
|
1030
|
-
const prevScore = prevReport.scoring?.score || prevReport.scoring?.overallScore;
|
|
576
|
+
const prevScore = prevReport.scoring?.overall || prevReport.scoring?.score;
|
|
1031
577
|
if (typeof prevScore === "number") {
|
|
1032
578
|
const diff = scoringResult.overall - prevScore;
|
|
1033
579
|
const diffStr = diff > 0 ? `+${diff}` : String(diff);
|
|
1034
|
-
|
|
1035
|
-
if (diff > 0) {
|
|
580
|
+
if (diff > 0)
|
|
1036
581
|
console.log(
|
|
1037
582
|
import_chalk3.default.green(
|
|
1038
583
|
` \u{1F4C8} Trend: ${diffStr} compared to ${options.compareTo} (${prevScore} \u2192 ${scoringResult.overall})`
|
|
1039
584
|
)
|
|
1040
585
|
);
|
|
1041
|
-
|
|
586
|
+
else if (diff < 0)
|
|
1042
587
|
console.log(
|
|
1043
588
|
import_chalk3.default.red(
|
|
1044
589
|
` \u{1F4C9} Trend: ${diffStr} compared to ${options.compareTo} (${prevScore} \u2192 ${scoringResult.overall})`
|
|
1045
590
|
)
|
|
1046
591
|
);
|
|
1047
|
-
|
|
592
|
+
else
|
|
1048
593
|
console.log(
|
|
1049
594
|
import_chalk3.default.blue(
|
|
1050
|
-
` \u2796 Trend: No change
|
|
595
|
+
` \u2796 Trend: No change (${prevScore} \u2192 ${scoringResult.overall})`
|
|
1051
596
|
)
|
|
1052
597
|
);
|
|
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
598
|
}
|
|
1066
599
|
} catch (e) {
|
|
1067
600
|
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
601
|
}
|
|
1075
602
|
}
|
|
1076
603
|
const totalWastedDuplication = (scoringResult.breakdown || []).reduce(
|
|
@@ -1084,7 +611,8 @@ async function scanAction(directory, options) {
|
|
|
1084
611
|
const totalContext = Math.max(
|
|
1085
612
|
...(scoringResult.breakdown || []).map(
|
|
1086
613
|
(s) => s.tokenBudget?.totalContextTokens || 0
|
|
1087
|
-
)
|
|
614
|
+
),
|
|
615
|
+
0
|
|
1088
616
|
);
|
|
1089
617
|
if (totalContext > 0) {
|
|
1090
618
|
const unifiedBudget = (0, import_core3.calculateTokenBudget)({
|
|
@@ -1095,35 +623,17 @@ async function scanAction(directory, options) {
|
|
|
1095
623
|
chattiness: 0
|
|
1096
624
|
}
|
|
1097
625
|
});
|
|
1098
|
-
const
|
|
1099
|
-
const modelPreset = (0, import_core3.getModelPreset)(targetModel);
|
|
626
|
+
const modelPreset = (0, import_core3.getModelPreset)(options.model || "claude-4.6");
|
|
1100
627
|
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
|
-
);
|
|
628
|
+
console.log(import_chalk3.default.bold("\n\u{1F4CA} AI Token Budget Analysis"));
|
|
1118
629
|
console.log(
|
|
1119
|
-
`
|
|
630
|
+
` Efficiency: ${(unifiedBudget.efficiencyRatio * 100).toFixed(0)}%`
|
|
1120
631
|
);
|
|
1121
632
|
console.log(
|
|
1122
|
-
`
|
|
633
|
+
` Wasted Tokens: ${import_chalk3.default.red(unifiedBudget.wastedTokens.total.toLocaleString())}`
|
|
1123
634
|
);
|
|
1124
635
|
console.log(
|
|
1125
|
-
`
|
|
1126
|
-
Est. Monthly Cost (${modelPreset.name}): ${import_chalk3.default.bold("$" + costEstimate.total)} [range: $${costEstimate.range[0]}-$${costEstimate.range[1]}]`
|
|
636
|
+
` Est. Monthly Cost (${modelPreset.name}): ${import_chalk3.default.bold("$" + costEstimate.total)}`
|
|
1127
637
|
);
|
|
1128
638
|
scoringResult.tokenBudget = unifiedBudget;
|
|
1129
639
|
scoringResult.costEstimate = {
|
|
@@ -1131,85 +641,31 @@ async function scanAction(directory, options) {
|
|
|
1131
641
|
...costEstimate
|
|
1132
642
|
};
|
|
1133
643
|
}
|
|
1134
|
-
if (scoringResult.breakdown
|
|
644
|
+
if (scoringResult.breakdown) {
|
|
1135
645
|
console.log(import_chalk3.default.bold("\nTool breakdown:"));
|
|
1136
646
|
scoringResult.breakdown.forEach((tool) => {
|
|
1137
647
|
const rating = (0, import_core3.getRating)(tool.score);
|
|
1138
|
-
|
|
1139
|
-
console.log(
|
|
1140
|
-
` - ${tool.toolName}: ${tool.score}/100 (${rating}) ${rd.emoji}`
|
|
1141
|
-
);
|
|
648
|
+
console.log(` - ${tool.toolName}: ${tool.score}/100 (${rating})`);
|
|
1142
649
|
});
|
|
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
650
|
}
|
|
1152
651
|
}
|
|
1153
652
|
const mapToUnifiedReport = (res, scoring) => {
|
|
1154
653
|
const allResults = [];
|
|
1155
|
-
|
|
654
|
+
const totalFilesSet = /* @__PURE__ */ new Set();
|
|
1156
655
|
let criticalCount = 0;
|
|
1157
656
|
let majorCount = 0;
|
|
1158
|
-
|
|
657
|
+
res.summary.toolsRun.forEach((toolId) => {
|
|
658
|
+
const spokeRes = res[toolId];
|
|
1159
659
|
if (!spokeRes || !spokeRes.results) return;
|
|
1160
660
|
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);
|
|
661
|
+
totalFilesSet.add(r.fileName);
|
|
662
|
+
allResults.push(r);
|
|
663
|
+
r.issues?.forEach((i) => {
|
|
664
|
+
if (i.severity === import_core3.Severity.Critical) criticalCount++;
|
|
665
|
+
if (i.severity === import_core3.Severity.Major) majorCount++;
|
|
666
|
+
});
|
|
1202
667
|
});
|
|
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);
|
|
668
|
+
});
|
|
1213
669
|
return {
|
|
1214
670
|
...res,
|
|
1215
671
|
results: allResults,
|
|
@@ -1222,199 +678,70 @@ async function scanAction(directory, options) {
|
|
|
1222
678
|
scoring
|
|
1223
679
|
};
|
|
1224
680
|
};
|
|
681
|
+
const outputData = {
|
|
682
|
+
...mapToUnifiedReport(results, scoringResult),
|
|
683
|
+
repository: repoMetadata
|
|
684
|
+
};
|
|
1225
685
|
const outputFormat = options.output || finalOptions.output?.format || "console";
|
|
1226
|
-
const
|
|
686
|
+
const outputPath = (0, import_core3.resolveOutputPath)(
|
|
687
|
+
options.outputFile || finalOptions.output?.file,
|
|
688
|
+
`aiready-report-${getReportTimestamp()}.json`,
|
|
689
|
+
resolvedDir
|
|
690
|
+
);
|
|
1227
691
|
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
692
|
(0, import_core3.handleJSONOutput)(
|
|
1240
693
|
outputData,
|
|
1241
694
|
outputPath,
|
|
1242
695
|
`\u2705 Report saved to ${outputPath}`
|
|
1243
696
|
);
|
|
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
697
|
} 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
698
|
try {
|
|
1265
699
|
(0, import_fs3.writeFileSync)(outputPath, JSON.stringify(outputData, null, 2));
|
|
1266
700
|
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
701
|
} catch (err) {
|
|
1276
702
|
void err;
|
|
1277
703
|
}
|
|
1278
704
|
}
|
|
1279
|
-
|
|
705
|
+
if (options.upload) {
|
|
706
|
+
await uploadAction(outputPath, {
|
|
707
|
+
apiKey: options.apiKey,
|
|
708
|
+
server: options.server
|
|
709
|
+
});
|
|
710
|
+
}
|
|
711
|
+
await warnIfGraphCapExceeded(outputData, resolvedDir);
|
|
712
|
+
const isCI = options.ci || process.env.CI === "true";
|
|
1280
713
|
if (isCI && scoringResult) {
|
|
1281
714
|
const threshold = options.threshold ? parseInt(options.threshold) : void 0;
|
|
1282
715
|
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
716
|
let shouldFail = false;
|
|
1314
717
|
let failReason = "";
|
|
1315
718
|
if (threshold && scoringResult.overall < threshold) {
|
|
1316
719
|
shouldFail = true;
|
|
1317
|
-
failReason = `
|
|
720
|
+
failReason = `Score ${scoringResult.overall} < threshold ${threshold}`;
|
|
1318
721
|
}
|
|
722
|
+
const report = mapToUnifiedReport(results, scoringResult);
|
|
1319
723
|
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) {
|
|
724
|
+
if (failOnLevel === "critical" && report.summary.criticalIssues > 0) {
|
|
1347
725
|
shouldFail = true;
|
|
1348
|
-
failReason = `Found ${
|
|
1349
|
-
} else if (
|
|
726
|
+
failReason = `Found ${report.summary.criticalIssues} critical issues`;
|
|
727
|
+
} else if (failOnLevel === "major" && report.summary.criticalIssues + report.summary.majorIssues > 0) {
|
|
1350
728
|
shouldFail = true;
|
|
1351
|
-
failReason = `Found ${
|
|
729
|
+
failReason = `Found ${report.summary.criticalIssues} critical and ${report.summary.majorIssues} major issues`;
|
|
1352
730
|
}
|
|
1353
731
|
}
|
|
1354
732
|
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
|
-
);
|
|
733
|
+
console.log(import_chalk3.default.red(`
|
|
734
|
+
\u{1F6AB} PR BLOCKED: ${failReason}`));
|
|
1367
735
|
process.exit(1);
|
|
1368
736
|
} 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
|
-
);
|
|
737
|
+
console.log(import_chalk3.default.green("\n\u2705 PR PASSED"));
|
|
1382
738
|
}
|
|
1383
739
|
}
|
|
1384
740
|
} catch (error) {
|
|
1385
741
|
(0, import_core3.handleCLIError)(error, "Analysis");
|
|
1386
742
|
}
|
|
1387
743
|
}
|
|
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
|
-
`;
|
|
744
|
+
var scanHelpText = `...`;
|
|
1418
745
|
|
|
1419
746
|
// src/commands/patterns.ts
|
|
1420
747
|
var import_chalk4 = __toESM(require("chalk"));
|
|
@@ -1457,8 +784,8 @@ async function patternsAction(directory, options) {
|
|
|
1457
784
|
defaults,
|
|
1458
785
|
cliOptions
|
|
1459
786
|
);
|
|
1460
|
-
const { analyzePatterns
|
|
1461
|
-
const { results, duplicates } = await
|
|
787
|
+
const { analyzePatterns, generateSummary, calculatePatternScore } = await import("@aiready/pattern-detect");
|
|
788
|
+
const { results, duplicates } = await analyzePatterns(finalOptions);
|
|
1462
789
|
const elapsedTime = (0, import_core4.getElapsedTime)(startTime);
|
|
1463
790
|
const summary = generateSummary(results);
|
|
1464
791
|
let patternScore;
|
|
@@ -1603,8 +930,8 @@ async function contextAction(directory, options) {
|
|
|
1603
930
|
);
|
|
1604
931
|
console.log(` Analysis focus: ${finalOptions.focus}`);
|
|
1605
932
|
console.log("");
|
|
1606
|
-
const { analyzeContext
|
|
1607
|
-
const results = await
|
|
933
|
+
const { analyzeContext, generateSummary, calculateContextScore } = await import("@aiready/context-analyzer");
|
|
934
|
+
const results = await analyzeContext(finalOptions);
|
|
1608
935
|
const elapsedTime = (0, import_core5.getElapsedTime)(startTime);
|
|
1609
936
|
const summary = generateSummary(results);
|
|
1610
937
|
let contextScore;
|
|
@@ -1788,8 +1115,8 @@ async function consistencyAction(directory, options) {
|
|
|
1788
1115
|
include: options.include?.split(","),
|
|
1789
1116
|
exclude: options.exclude?.split(",")
|
|
1790
1117
|
});
|
|
1791
|
-
const { analyzeConsistency
|
|
1792
|
-
const report = await
|
|
1118
|
+
const { analyzeConsistency, calculateConsistencyScore } = await import("@aiready/consistency");
|
|
1119
|
+
const report = await analyzeConsistency(finalOptions);
|
|
1793
1120
|
const elapsedTime = (0, import_core6.getElapsedTime)(startTime);
|
|
1794
1121
|
let consistencyScore;
|
|
1795
1122
|
if (options.score) {
|