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