@aiready/cli 0.9.43 → 0.9.46
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.turbo/turbo-build.log +11 -11
- package/.turbo/turbo-test.log +5 -5
- package/README.md +45 -7
- package/dist/chunk-6FOVC2OE.mjs +392 -0
- package/dist/chunk-MEXEG3IJ.mjs +389 -0
- package/dist/cli.js +631 -415
- package/dist/cli.mjs +451 -377
- package/dist/index.js +149 -2
- package/dist/index.mjs +5 -3
- package/package.json +12 -12
- package/src/.aiready/aiready-report-20260301-141543.json +8261 -0
- package/src/.aiready/aiready-report-20260301-141556.json +8261 -0
- package/src/.aiready/aiready-report-20260301-141611.json +8261 -0
- package/src/.aiready/aiready-report-20260304-125348.json +8324 -0
- package/src/cli.ts +18 -0
- package/src/commands/index.ts +1 -0
- package/src/commands/scan.ts +176 -211
- package/src/commands/upload.ts +125 -0
- package/src/index.ts +190 -3
package/dist/cli.js
CHANGED
|
@@ -25,20 +25,21 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
|
|
|
25
25
|
|
|
26
26
|
// src/cli.ts
|
|
27
27
|
var import_commander = require("commander");
|
|
28
|
-
var
|
|
29
|
-
var
|
|
28
|
+
var import_fs6 = require("fs");
|
|
29
|
+
var import_path8 = require("path");
|
|
30
30
|
var import_url = require("url");
|
|
31
31
|
|
|
32
32
|
// src/commands/scan.ts
|
|
33
|
-
var
|
|
34
|
-
var
|
|
35
|
-
var
|
|
36
|
-
var
|
|
33
|
+
var import_chalk3 = __toESM(require("chalk"));
|
|
34
|
+
var import_fs3 = require("fs");
|
|
35
|
+
var import_path3 = require("path");
|
|
36
|
+
var import_core3 = require("@aiready/core");
|
|
37
37
|
|
|
38
38
|
// src/index.ts
|
|
39
39
|
var import_pattern_detect = require("@aiready/pattern-detect");
|
|
40
40
|
var import_context_analyzer = require("@aiready/context-analyzer");
|
|
41
41
|
var import_consistency = require("@aiready/consistency");
|
|
42
|
+
var import_core = require("@aiready/core");
|
|
42
43
|
var severityOrder = {
|
|
43
44
|
critical: 4,
|
|
44
45
|
major: 3,
|
|
@@ -213,6 +214,150 @@ async function analyzeUnified(options) {
|
|
|
213
214
|
result.summary.executionTime = Date.now() - startTime;
|
|
214
215
|
return result;
|
|
215
216
|
}
|
|
217
|
+
async function scoreUnified(results, options) {
|
|
218
|
+
const toolScores = /* @__PURE__ */ new Map();
|
|
219
|
+
if (results.duplicates) {
|
|
220
|
+
const { calculatePatternScore } = await import("@aiready/pattern-detect");
|
|
221
|
+
try {
|
|
222
|
+
const patternScore = calculatePatternScore(
|
|
223
|
+
results.duplicates,
|
|
224
|
+
results.patterns?.length || 0
|
|
225
|
+
);
|
|
226
|
+
const wastedTokens = results.duplicates.reduce(
|
|
227
|
+
(sum, d) => sum + (d.tokenCost || 0),
|
|
228
|
+
0
|
|
229
|
+
);
|
|
230
|
+
patternScore.tokenBudget = (0, import_core.calculateTokenBudget)({
|
|
231
|
+
totalContextTokens: wastedTokens * 2,
|
|
232
|
+
// Estimated context
|
|
233
|
+
wastedTokens: {
|
|
234
|
+
duplication: wastedTokens,
|
|
235
|
+
fragmentation: 0,
|
|
236
|
+
chattiness: 0
|
|
237
|
+
}
|
|
238
|
+
});
|
|
239
|
+
toolScores.set("pattern-detect", patternScore);
|
|
240
|
+
} catch (err) {
|
|
241
|
+
void err;
|
|
242
|
+
}
|
|
243
|
+
}
|
|
244
|
+
if (results.context) {
|
|
245
|
+
const { generateSummary: genContextSummary, calculateContextScore } = await import("@aiready/context-analyzer");
|
|
246
|
+
try {
|
|
247
|
+
const ctxSummary = genContextSummary(results.context);
|
|
248
|
+
const contextScore = calculateContextScore(ctxSummary);
|
|
249
|
+
contextScore.tokenBudget = (0, import_core.calculateTokenBudget)({
|
|
250
|
+
totalContextTokens: ctxSummary.totalTokens,
|
|
251
|
+
wastedTokens: {
|
|
252
|
+
duplication: 0,
|
|
253
|
+
fragmentation: ctxSummary.totalPotentialSavings || 0,
|
|
254
|
+
chattiness: 0
|
|
255
|
+
}
|
|
256
|
+
});
|
|
257
|
+
toolScores.set("context-analyzer", contextScore);
|
|
258
|
+
} catch (err) {
|
|
259
|
+
void err;
|
|
260
|
+
}
|
|
261
|
+
}
|
|
262
|
+
if (results.consistency) {
|
|
263
|
+
const { calculateConsistencyScore } = await import("@aiready/consistency");
|
|
264
|
+
try {
|
|
265
|
+
const issues = results.consistency.results?.flatMap((r) => r.issues) || [];
|
|
266
|
+
const totalFiles = results.consistency.summary?.filesAnalyzed || 0;
|
|
267
|
+
const consistencyScore = calculateConsistencyScore(issues, totalFiles);
|
|
268
|
+
toolScores.set("consistency", consistencyScore);
|
|
269
|
+
} catch (err) {
|
|
270
|
+
void err;
|
|
271
|
+
}
|
|
272
|
+
}
|
|
273
|
+
if (results.aiSignalClarity) {
|
|
274
|
+
const { calculateAiSignalClarityScore } = await import("@aiready/ai-signal-clarity");
|
|
275
|
+
try {
|
|
276
|
+
const hrScore = calculateAiSignalClarityScore(results.aiSignalClarity);
|
|
277
|
+
toolScores.set("ai-signal-clarity", hrScore);
|
|
278
|
+
} catch (err) {
|
|
279
|
+
void err;
|
|
280
|
+
}
|
|
281
|
+
}
|
|
282
|
+
if (results.grounding) {
|
|
283
|
+
const { calculateGroundingScore } = await import("@aiready/agent-grounding");
|
|
284
|
+
try {
|
|
285
|
+
const agScore = calculateGroundingScore(results.grounding);
|
|
286
|
+
toolScores.set("agent-grounding", agScore);
|
|
287
|
+
} catch (err) {
|
|
288
|
+
void err;
|
|
289
|
+
}
|
|
290
|
+
}
|
|
291
|
+
if (results.testability) {
|
|
292
|
+
const { calculateTestabilityScore } = await import("@aiready/testability");
|
|
293
|
+
try {
|
|
294
|
+
const tbScore = calculateTestabilityScore(results.testability);
|
|
295
|
+
toolScores.set("testability", tbScore);
|
|
296
|
+
} catch (err) {
|
|
297
|
+
void err;
|
|
298
|
+
}
|
|
299
|
+
}
|
|
300
|
+
if (results.docDrift) {
|
|
301
|
+
toolScores.set("doc-drift", {
|
|
302
|
+
toolName: "doc-drift",
|
|
303
|
+
score: results.docDrift.summary.score,
|
|
304
|
+
rawMetrics: results.docDrift.rawData,
|
|
305
|
+
factors: [],
|
|
306
|
+
recommendations: (results.docDrift.recommendations || []).map(
|
|
307
|
+
(action) => ({
|
|
308
|
+
action,
|
|
309
|
+
estimatedImpact: 5,
|
|
310
|
+
priority: "medium"
|
|
311
|
+
})
|
|
312
|
+
)
|
|
313
|
+
});
|
|
314
|
+
}
|
|
315
|
+
if (results.deps) {
|
|
316
|
+
toolScores.set("dependency-health", {
|
|
317
|
+
toolName: "dependency-health",
|
|
318
|
+
score: results.deps.summary.score,
|
|
319
|
+
rawMetrics: results.deps.rawData,
|
|
320
|
+
factors: [],
|
|
321
|
+
recommendations: (results.deps.recommendations || []).map(
|
|
322
|
+
(action) => ({
|
|
323
|
+
action,
|
|
324
|
+
estimatedImpact: 5,
|
|
325
|
+
priority: "medium"
|
|
326
|
+
})
|
|
327
|
+
)
|
|
328
|
+
});
|
|
329
|
+
}
|
|
330
|
+
if (results.changeAmplification) {
|
|
331
|
+
toolScores.set("change-amplification", {
|
|
332
|
+
toolName: "change-amplification",
|
|
333
|
+
score: results.changeAmplification.summary.score,
|
|
334
|
+
rawMetrics: results.changeAmplification.rawData,
|
|
335
|
+
factors: [],
|
|
336
|
+
recommendations: (results.changeAmplification.recommendations || []).map(
|
|
337
|
+
(action) => ({
|
|
338
|
+
action,
|
|
339
|
+
estimatedImpact: 5,
|
|
340
|
+
priority: "medium"
|
|
341
|
+
})
|
|
342
|
+
)
|
|
343
|
+
});
|
|
344
|
+
}
|
|
345
|
+
if (toolScores.size === 0) {
|
|
346
|
+
return {
|
|
347
|
+
overall: 0,
|
|
348
|
+
rating: "Critical",
|
|
349
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
350
|
+
toolsUsed: [],
|
|
351
|
+
breakdown: [],
|
|
352
|
+
calculation: {
|
|
353
|
+
formula: "0 / 0 = 0",
|
|
354
|
+
weights: {},
|
|
355
|
+
normalized: "0 / 0 = 0"
|
|
356
|
+
}
|
|
357
|
+
};
|
|
358
|
+
}
|
|
359
|
+
return (0, import_core.calculateOverallScore)(toolScores, options, void 0);
|
|
360
|
+
}
|
|
216
361
|
|
|
217
362
|
// src/utils/helpers.ts
|
|
218
363
|
var import_path = require("path");
|
|
@@ -338,11 +483,113 @@ function truncateArray(arr, cap = 8) {
|
|
|
338
483
|
return shown.join(", ") + (more > 0 ? `, ... (+${more} more)` : "");
|
|
339
484
|
}
|
|
340
485
|
|
|
486
|
+
// src/commands/upload.ts
|
|
487
|
+
var import_fs2 = __toESM(require("fs"));
|
|
488
|
+
var import_path2 = require("path");
|
|
489
|
+
var import_chalk2 = __toESM(require("chalk"));
|
|
490
|
+
var import_core2 = require("@aiready/core");
|
|
491
|
+
async function uploadAction(file, options) {
|
|
492
|
+
const startTime = Date.now();
|
|
493
|
+
const filePath = (0, import_path2.resolve)(process.cwd(), file);
|
|
494
|
+
const serverUrl = options.server || process.env.AIREADY_SERVER || "https://dev.platform.getaiready.dev";
|
|
495
|
+
const apiKey = options.apiKey || process.env.AIREADY_API_KEY;
|
|
496
|
+
if (!apiKey) {
|
|
497
|
+
console.error(import_chalk2.default.red("\u274C API Key is required for upload."));
|
|
498
|
+
console.log(
|
|
499
|
+
import_chalk2.default.dim(
|
|
500
|
+
" Set AIREADY_API_KEY environment variable or use --api-key flag."
|
|
501
|
+
)
|
|
502
|
+
);
|
|
503
|
+
console.log(
|
|
504
|
+
import_chalk2.default.dim(" Get an API key from https://getaiready.dev/dashboard")
|
|
505
|
+
);
|
|
506
|
+
process.exit(1);
|
|
507
|
+
}
|
|
508
|
+
if (!import_fs2.default.existsSync(filePath)) {
|
|
509
|
+
console.error(import_chalk2.default.red(`\u274C File not found: ${filePath}`));
|
|
510
|
+
process.exit(1);
|
|
511
|
+
}
|
|
512
|
+
try {
|
|
513
|
+
console.log(import_chalk2.default.blue(`\u{1F680} Uploading report to ${serverUrl}...`));
|
|
514
|
+
console.log(import_chalk2.default.dim(` Reading report from ${filePath}...`));
|
|
515
|
+
const reportContent = import_fs2.default.readFileSync(filePath, "utf-8");
|
|
516
|
+
const reportData = JSON.parse(reportContent);
|
|
517
|
+
console.log(import_chalk2.default.dim(` Successfully parsed report JSON.`));
|
|
518
|
+
const repoId = options.repoId || reportData.repository?.repoId;
|
|
519
|
+
const res = await fetch(`${serverUrl}/api/analysis/upload`, {
|
|
520
|
+
method: "POST",
|
|
521
|
+
headers: {
|
|
522
|
+
"Content-Type": "application/json",
|
|
523
|
+
Authorization: `Bearer ${apiKey}`
|
|
524
|
+
},
|
|
525
|
+
body: JSON.stringify({
|
|
526
|
+
data: reportData,
|
|
527
|
+
repoId
|
|
528
|
+
// Might be null, server will handle mapping
|
|
529
|
+
})
|
|
530
|
+
});
|
|
531
|
+
const contentType = res.headers.get("content-type");
|
|
532
|
+
let result = {};
|
|
533
|
+
if (contentType?.includes("application/json")) {
|
|
534
|
+
result = await res.json();
|
|
535
|
+
} else {
|
|
536
|
+
const text = await res.text();
|
|
537
|
+
result = { error: text || res.statusText };
|
|
538
|
+
}
|
|
539
|
+
if (!res.ok) {
|
|
540
|
+
console.error(
|
|
541
|
+
import_chalk2.default.red(`\u274C Upload failed: ${result.error || res.statusText}`)
|
|
542
|
+
);
|
|
543
|
+
if (contentType?.includes("text/html")) {
|
|
544
|
+
console.log(
|
|
545
|
+
import_chalk2.default.yellow(
|
|
546
|
+
" Note: Received an HTML response. This often indicates a redirect (e.g., to a login page) or a server error."
|
|
547
|
+
)
|
|
548
|
+
);
|
|
549
|
+
if (result.error?.includes("Redirecting")) {
|
|
550
|
+
console.log(
|
|
551
|
+
import_chalk2.default.dim(
|
|
552
|
+
" Detected redirect. Check if the API endpoint requires authentication or has changed."
|
|
553
|
+
)
|
|
554
|
+
);
|
|
555
|
+
}
|
|
556
|
+
}
|
|
557
|
+
if (res.status === 401) {
|
|
558
|
+
console.log(
|
|
559
|
+
import_chalk2.default.dim(" Hint: Your API key may be invalid or expired.")
|
|
560
|
+
);
|
|
561
|
+
}
|
|
562
|
+
process.exit(1);
|
|
563
|
+
}
|
|
564
|
+
const duration = ((Date.now() - startTime) / 1e3).toFixed(2);
|
|
565
|
+
console.log(import_chalk2.default.green(`
|
|
566
|
+
\u2705 Upload successful! (${duration}s)`));
|
|
567
|
+
console.log(import_chalk2.default.cyan(` View results: ${serverUrl}/dashboard`));
|
|
568
|
+
if (result.analysis) {
|
|
569
|
+
console.log(import_chalk2.default.dim(` Analysis ID: ${result.analysis.id}`));
|
|
570
|
+
console.log(import_chalk2.default.dim(` Score: ${result.analysis.aiScore}/100`));
|
|
571
|
+
}
|
|
572
|
+
} catch (error) {
|
|
573
|
+
(0, import_core2.handleCLIError)(error, "Upload");
|
|
574
|
+
}
|
|
575
|
+
}
|
|
576
|
+
var uploadHelpText = `
|
|
577
|
+
EXAMPLES:
|
|
578
|
+
$ aiready upload report.json --api-key ar_...
|
|
579
|
+
$ aiready upload .aiready/latest.json
|
|
580
|
+
$ AIREADY_API_KEY=ar_... aiready upload report.json
|
|
581
|
+
|
|
582
|
+
ENVIRONMENT VARIABLES:
|
|
583
|
+
AIREADY_API_KEY Your platform API key
|
|
584
|
+
AIREADY_SERVER Custom platform URL (default: https://dev.platform.getaiready.dev)
|
|
585
|
+
`;
|
|
586
|
+
|
|
341
587
|
// src/commands/scan.ts
|
|
342
588
|
async function scanAction(directory, options) {
|
|
343
|
-
console.log(
|
|
589
|
+
console.log(import_chalk3.default.blue("\u{1F680} Starting AIReady unified analysis...\n"));
|
|
344
590
|
const startTime = Date.now();
|
|
345
|
-
const resolvedDir = (0,
|
|
591
|
+
const resolvedDir = (0, import_path3.resolve)(process.cwd(), directory || ".");
|
|
592
|
+
const repoMetadata = (0, import_core3.getRepoMetadata)(resolvedDir);
|
|
346
593
|
try {
|
|
347
594
|
const defaults = {
|
|
348
595
|
tools: [
|
|
@@ -385,7 +632,7 @@ async function scanAction(directory, options) {
|
|
|
385
632
|
break;
|
|
386
633
|
default:
|
|
387
634
|
console.log(
|
|
388
|
-
|
|
635
|
+
import_chalk3.default.yellow(
|
|
389
636
|
`
|
|
390
637
|
\u26A0\uFE0F Unknown profile '${options.profile}'. Using specified tools or defaults.`
|
|
391
638
|
)
|
|
@@ -399,7 +646,7 @@ async function scanAction(directory, options) {
|
|
|
399
646
|
if (profileTools) {
|
|
400
647
|
cliOverrides.tools = profileTools;
|
|
401
648
|
}
|
|
402
|
-
const baseOptions = await (0,
|
|
649
|
+
const baseOptions = await (0, import_core3.loadMergedConfig)(
|
|
403
650
|
resolvedDir,
|
|
404
651
|
defaults,
|
|
405
652
|
cliOverrides
|
|
@@ -417,22 +664,22 @@ async function scanAction(directory, options) {
|
|
|
417
664
|
...baseOptions
|
|
418
665
|
};
|
|
419
666
|
}
|
|
420
|
-
console.log(
|
|
667
|
+
console.log(import_chalk3.default.cyan("\n=== AIReady Run Preview ==="));
|
|
421
668
|
console.log(
|
|
422
|
-
|
|
669
|
+
import_chalk3.default.white("Tools to run:"),
|
|
423
670
|
(finalOptions.tools || ["patterns", "context", "consistency"]).join(", ")
|
|
424
671
|
);
|
|
425
|
-
console.log(
|
|
426
|
-
console.log(
|
|
672
|
+
console.log(import_chalk3.default.white("Will use settings from config and defaults."));
|
|
673
|
+
console.log(import_chalk3.default.white("\nGeneral settings:"));
|
|
427
674
|
if (finalOptions.rootDir)
|
|
428
|
-
console.log(` rootDir: ${
|
|
675
|
+
console.log(` rootDir: ${import_chalk3.default.bold(String(finalOptions.rootDir))}`);
|
|
429
676
|
if (finalOptions.include)
|
|
430
677
|
console.log(
|
|
431
|
-
` include: ${
|
|
678
|
+
` include: ${import_chalk3.default.bold(truncateArray(finalOptions.include, 6))}`
|
|
432
679
|
);
|
|
433
680
|
if (finalOptions.exclude)
|
|
434
681
|
console.log(
|
|
435
|
-
` exclude: ${
|
|
682
|
+
` exclude: ${import_chalk3.default.bold(truncateArray(finalOptions.exclude, 6))}`
|
|
436
683
|
);
|
|
437
684
|
if (finalOptions["pattern-detect"] || finalOptions.minSimilarity) {
|
|
438
685
|
const patternDetectConfig = finalOptions["pattern-detect"] || {
|
|
@@ -446,40 +693,40 @@ async function scanAction(directory, options) {
|
|
|
446
693
|
severity: finalOptions.severity,
|
|
447
694
|
includeTests: finalOptions.includeTests
|
|
448
695
|
};
|
|
449
|
-
console.log(
|
|
696
|
+
console.log(import_chalk3.default.white("\nPattern-detect settings:"));
|
|
450
697
|
console.log(
|
|
451
|
-
` minSimilarity: ${
|
|
698
|
+
` minSimilarity: ${import_chalk3.default.bold(patternDetectConfig.minSimilarity ?? "default")}`
|
|
452
699
|
);
|
|
453
700
|
console.log(
|
|
454
|
-
` minLines: ${
|
|
701
|
+
` minLines: ${import_chalk3.default.bold(patternDetectConfig.minLines ?? "default")}`
|
|
455
702
|
);
|
|
456
703
|
if (patternDetectConfig.approx !== void 0)
|
|
457
704
|
console.log(
|
|
458
|
-
` approx: ${
|
|
705
|
+
` approx: ${import_chalk3.default.bold(String(patternDetectConfig.approx))}`
|
|
459
706
|
);
|
|
460
707
|
if (patternDetectConfig.minSharedTokens !== void 0)
|
|
461
708
|
console.log(
|
|
462
|
-
` minSharedTokens: ${
|
|
709
|
+
` minSharedTokens: ${import_chalk3.default.bold(String(patternDetectConfig.minSharedTokens))}`
|
|
463
710
|
);
|
|
464
711
|
if (patternDetectConfig.maxCandidatesPerBlock !== void 0)
|
|
465
712
|
console.log(
|
|
466
|
-
` maxCandidatesPerBlock: ${
|
|
713
|
+
` maxCandidatesPerBlock: ${import_chalk3.default.bold(String(patternDetectConfig.maxCandidatesPerBlock))}`
|
|
467
714
|
);
|
|
468
715
|
if (patternDetectConfig.batchSize !== void 0)
|
|
469
716
|
console.log(
|
|
470
|
-
` batchSize: ${
|
|
717
|
+
` batchSize: ${import_chalk3.default.bold(String(patternDetectConfig.batchSize))}`
|
|
471
718
|
);
|
|
472
719
|
if (patternDetectConfig.streamResults !== void 0)
|
|
473
720
|
console.log(
|
|
474
|
-
` streamResults: ${
|
|
721
|
+
` streamResults: ${import_chalk3.default.bold(String(patternDetectConfig.streamResults))}`
|
|
475
722
|
);
|
|
476
723
|
if (patternDetectConfig.severity !== void 0)
|
|
477
724
|
console.log(
|
|
478
|
-
` severity: ${
|
|
725
|
+
` severity: ${import_chalk3.default.bold(String(patternDetectConfig.severity))}`
|
|
479
726
|
);
|
|
480
727
|
if (patternDetectConfig.includeTests !== void 0)
|
|
481
728
|
console.log(
|
|
482
|
-
` includeTests: ${
|
|
729
|
+
` includeTests: ${import_chalk3.default.bold(String(patternDetectConfig.includeTests))}`
|
|
483
730
|
);
|
|
484
731
|
}
|
|
485
732
|
if (finalOptions["context-analyzer"] || finalOptions.maxDepth) {
|
|
@@ -490,57 +737,57 @@ async function scanAction(directory, options) {
|
|
|
490
737
|
maxFragmentation: finalOptions.maxFragmentation,
|
|
491
738
|
includeNodeModules: finalOptions.includeNodeModules
|
|
492
739
|
};
|
|
493
|
-
console.log(
|
|
494
|
-
console.log(` maxDepth: ${
|
|
740
|
+
console.log(import_chalk3.default.white("\nContext-analyzer settings:"));
|
|
741
|
+
console.log(` maxDepth: ${import_chalk3.default.bold(ca.maxDepth ?? "default")}`);
|
|
495
742
|
console.log(
|
|
496
|
-
` maxContextBudget: ${
|
|
743
|
+
` maxContextBudget: ${import_chalk3.default.bold(ca.maxContextBudget ?? "default")}`
|
|
497
744
|
);
|
|
498
745
|
if (ca.minCohesion !== void 0)
|
|
499
|
-
console.log(` minCohesion: ${
|
|
746
|
+
console.log(` minCohesion: ${import_chalk3.default.bold(String(ca.minCohesion))}`);
|
|
500
747
|
if (ca.maxFragmentation !== void 0)
|
|
501
748
|
console.log(
|
|
502
|
-
` maxFragmentation: ${
|
|
749
|
+
` maxFragmentation: ${import_chalk3.default.bold(String(ca.maxFragmentation))}`
|
|
503
750
|
);
|
|
504
751
|
if (ca.includeNodeModules !== void 0)
|
|
505
752
|
console.log(
|
|
506
|
-
` includeNodeModules: ${
|
|
753
|
+
` includeNodeModules: ${import_chalk3.default.bold(String(ca.includeNodeModules))}`
|
|
507
754
|
);
|
|
508
755
|
}
|
|
509
756
|
if (finalOptions.consistency) {
|
|
510
757
|
const c = finalOptions.consistency;
|
|
511
|
-
console.log(
|
|
758
|
+
console.log(import_chalk3.default.white("\nConsistency settings:"));
|
|
512
759
|
console.log(
|
|
513
|
-
` checkNaming: ${
|
|
760
|
+
` checkNaming: ${import_chalk3.default.bold(String(c.checkNaming ?? true))}`
|
|
514
761
|
);
|
|
515
762
|
console.log(
|
|
516
|
-
` checkPatterns: ${
|
|
763
|
+
` checkPatterns: ${import_chalk3.default.bold(String(c.checkPatterns ?? true))}`
|
|
517
764
|
);
|
|
518
765
|
console.log(
|
|
519
|
-
` checkArchitecture: ${
|
|
766
|
+
` checkArchitecture: ${import_chalk3.default.bold(String(c.checkArchitecture ?? false))}`
|
|
520
767
|
);
|
|
521
768
|
if (c.minSeverity)
|
|
522
|
-
console.log(` minSeverity: ${
|
|
769
|
+
console.log(` minSeverity: ${import_chalk3.default.bold(c.minSeverity)}`);
|
|
523
770
|
if (c.acceptedAbbreviations)
|
|
524
771
|
console.log(
|
|
525
|
-
` acceptedAbbreviations: ${
|
|
772
|
+
` acceptedAbbreviations: ${import_chalk3.default.bold(truncateArray(c.acceptedAbbreviations, 8))}`
|
|
526
773
|
);
|
|
527
774
|
if (c.shortWords)
|
|
528
775
|
console.log(
|
|
529
|
-
` shortWords: ${
|
|
776
|
+
` shortWords: ${import_chalk3.default.bold(truncateArray(c.shortWords, 8))}`
|
|
530
777
|
);
|
|
531
778
|
}
|
|
532
|
-
console.log(
|
|
779
|
+
console.log(import_chalk3.default.white("\nStarting analysis..."));
|
|
533
780
|
const progressCallback = (event) => {
|
|
534
|
-
console.log(
|
|
781
|
+
console.log(import_chalk3.default.cyan(`
|
|
535
782
|
--- ${event.tool.toUpperCase()} RESULTS ---`));
|
|
536
783
|
try {
|
|
537
784
|
if (event.tool === "patterns") {
|
|
538
785
|
const pr = event.data;
|
|
539
786
|
console.log(
|
|
540
|
-
` Duplicate patterns: ${
|
|
787
|
+
` Duplicate patterns: ${import_chalk3.default.bold(String(pr.duplicates?.length || 0))}`
|
|
541
788
|
);
|
|
542
789
|
console.log(
|
|
543
|
-
` Files with pattern issues: ${
|
|
790
|
+
` Files with pattern issues: ${import_chalk3.default.bold(String(pr.results?.length || 0))}`
|
|
544
791
|
);
|
|
545
792
|
if (pr.duplicates && pr.duplicates.length > 0) {
|
|
546
793
|
pr.duplicates.slice(0, 5).forEach((d, i) => {
|
|
@@ -562,12 +809,12 @@ async function scanAction(directory, options) {
|
|
|
562
809
|
}
|
|
563
810
|
if (pr.groups && pr.groups.length >= 0) {
|
|
564
811
|
console.log(
|
|
565
|
-
` \u2705 Grouped ${
|
|
812
|
+
` \u2705 Grouped ${import_chalk3.default.bold(String(pr.duplicates?.length || 0))} duplicates into ${import_chalk3.default.bold(String(pr.groups.length))} file pairs`
|
|
566
813
|
);
|
|
567
814
|
}
|
|
568
815
|
if (pr.clusters && pr.clusters.length >= 0) {
|
|
569
816
|
console.log(
|
|
570
|
-
` \u2705 Created ${
|
|
817
|
+
` \u2705 Created ${import_chalk3.default.bold(String(pr.clusters.length))} refactor clusters`
|
|
571
818
|
);
|
|
572
819
|
pr.clusters.slice(0, 3).forEach((cl, idx) => {
|
|
573
820
|
const files = (cl.files || []).map((f) => f.path.split("/").pop()).join(", ");
|
|
@@ -579,7 +826,7 @@ async function scanAction(directory, options) {
|
|
|
579
826
|
} else if (event.tool === "context") {
|
|
580
827
|
const cr = event.data;
|
|
581
828
|
console.log(
|
|
582
|
-
` Context issues found: ${
|
|
829
|
+
` Context issues found: ${import_chalk3.default.bold(String(cr.length || 0))}`
|
|
583
830
|
);
|
|
584
831
|
cr.slice(0, 5).forEach((c, i) => {
|
|
585
832
|
const msg = c.message ? ` - ${c.message}` : "";
|
|
@@ -590,7 +837,7 @@ async function scanAction(directory, options) {
|
|
|
590
837
|
} else if (event.tool === "consistency") {
|
|
591
838
|
const rep = event.data;
|
|
592
839
|
console.log(
|
|
593
|
-
` Consistency totalIssues: ${
|
|
840
|
+
` Consistency totalIssues: ${import_chalk3.default.bold(String(rep.summary?.totalIssues || 0))}`
|
|
594
841
|
);
|
|
595
842
|
if (rep.results && rep.results.length > 0) {
|
|
596
843
|
const fileMap = /* @__PURE__ */ new Map();
|
|
@@ -625,7 +872,7 @@ async function scanAction(directory, options) {
|
|
|
625
872
|
const remaining = files.length - topFiles.length;
|
|
626
873
|
if (remaining > 0) {
|
|
627
874
|
console.log(
|
|
628
|
-
|
|
875
|
+
import_chalk3.default.dim(
|
|
629
876
|
` ... and ${remaining} more files with issues (use --output json for full details)`
|
|
630
877
|
)
|
|
631
878
|
);
|
|
@@ -634,37 +881,37 @@ async function scanAction(directory, options) {
|
|
|
634
881
|
} else if (event.tool === "doc-drift") {
|
|
635
882
|
const dr = event.data;
|
|
636
883
|
console.log(
|
|
637
|
-
` Issues found: ${
|
|
884
|
+
` Issues found: ${import_chalk3.default.bold(String(dr.issues?.length || 0))}`
|
|
638
885
|
);
|
|
639
886
|
if (dr.rawData) {
|
|
640
887
|
console.log(
|
|
641
|
-
` Signature Mismatches: ${
|
|
888
|
+
` Signature Mismatches: ${import_chalk3.default.bold(dr.rawData.outdatedComments || 0)}`
|
|
642
889
|
);
|
|
643
890
|
console.log(
|
|
644
|
-
` Undocumented Complexity: ${
|
|
891
|
+
` Undocumented Complexity: ${import_chalk3.default.bold(dr.rawData.undocumentedComplexity || 0)}`
|
|
645
892
|
);
|
|
646
893
|
}
|
|
647
894
|
} else if (event.tool === "deps-health") {
|
|
648
895
|
const dr = event.data;
|
|
649
896
|
console.log(
|
|
650
|
-
` Packages Analyzed: ${
|
|
897
|
+
` Packages Analyzed: ${import_chalk3.default.bold(String(dr.summary?.packagesAnalyzed || 0))}`
|
|
651
898
|
);
|
|
652
899
|
if (dr.rawData) {
|
|
653
900
|
console.log(
|
|
654
|
-
` Deprecated Packages: ${
|
|
901
|
+
` Deprecated Packages: ${import_chalk3.default.bold(dr.rawData.deprecatedPackages || 0)}`
|
|
655
902
|
);
|
|
656
903
|
console.log(
|
|
657
|
-
` AI Cutoff Skew Score: ${
|
|
904
|
+
` AI Cutoff Skew Score: ${import_chalk3.default.bold(dr.rawData.trainingCutoffSkew?.toFixed(1) || 0)}`
|
|
658
905
|
);
|
|
659
906
|
}
|
|
660
907
|
} else if (event.tool === "change-amplification" || event.tool === "changeAmplification") {
|
|
661
908
|
const dr = event.data;
|
|
662
909
|
console.log(
|
|
663
|
-
` Coupling issues: ${
|
|
910
|
+
` Coupling issues: ${import_chalk3.default.bold(String(dr.issues?.length || 0))}`
|
|
664
911
|
);
|
|
665
912
|
if (dr.summary) {
|
|
666
913
|
console.log(
|
|
667
|
-
` Complexity Score: ${
|
|
914
|
+
` Complexity Score: ${import_chalk3.default.bold(dr.summary.score || 0)}/100`
|
|
668
915
|
);
|
|
669
916
|
}
|
|
670
917
|
}
|
|
@@ -685,227 +932,169 @@ async function scanAction(directory, options) {
|
|
|
685
932
|
},
|
|
686
933
|
suppressToolConfig: true
|
|
687
934
|
});
|
|
688
|
-
console.log(
|
|
935
|
+
console.log(import_chalk3.default.cyan("\n=== AIReady Run Summary ==="));
|
|
689
936
|
console.log(
|
|
690
|
-
|
|
937
|
+
import_chalk3.default.white("Tools run:"),
|
|
691
938
|
(finalOptions.tools || ["patterns", "context", "consistency"]).join(", ")
|
|
692
939
|
);
|
|
693
|
-
console.log(
|
|
940
|
+
console.log(import_chalk3.default.cyan("\nResults summary:"));
|
|
694
941
|
console.log(
|
|
695
|
-
` Total issues (all tools): ${
|
|
942
|
+
` Total issues (all tools): ${import_chalk3.default.bold(String(results.summary.totalIssues || 0))}`
|
|
696
943
|
);
|
|
697
944
|
if (results.duplicates)
|
|
698
945
|
console.log(
|
|
699
|
-
` Duplicate patterns found: ${
|
|
946
|
+
` Duplicate patterns found: ${import_chalk3.default.bold(String(results.duplicates.length || 0))}`
|
|
700
947
|
);
|
|
701
948
|
if (results.patterns)
|
|
702
949
|
console.log(
|
|
703
|
-
` Pattern files with issues: ${
|
|
950
|
+
` Pattern files with issues: ${import_chalk3.default.bold(String(results.patterns.length || 0))}`
|
|
704
951
|
);
|
|
705
952
|
if (results.context)
|
|
706
953
|
console.log(
|
|
707
|
-
` Context issues: ${
|
|
954
|
+
` Context issues: ${import_chalk3.default.bold(String(results.context.length || 0))}`
|
|
708
955
|
);
|
|
709
956
|
console.log(
|
|
710
|
-
` Consistency issues: ${
|
|
957
|
+
` Consistency issues: ${import_chalk3.default.bold(String(results.consistency?.summary?.totalIssues || 0))}`
|
|
711
958
|
);
|
|
712
959
|
if (results.changeAmplification)
|
|
713
960
|
console.log(
|
|
714
|
-
` Change amplification: ${
|
|
961
|
+
` Change amplification: ${import_chalk3.default.bold(String(results.changeAmplification.summary?.score || 0))}/100`
|
|
715
962
|
);
|
|
716
|
-
console.log(
|
|
717
|
-
const elapsedTime = (0,
|
|
963
|
+
console.log(import_chalk3.default.cyan("===========================\n"));
|
|
964
|
+
const elapsedTime = (0, import_core3.getElapsedTime)(startTime);
|
|
718
965
|
void elapsedTime;
|
|
719
966
|
let scoringResult;
|
|
720
967
|
if (options.score || finalOptions.scoring?.showBreakdown) {
|
|
721
|
-
|
|
722
|
-
|
|
723
|
-
|
|
968
|
+
scoringResult = await scoreUnified(results, finalOptions);
|
|
969
|
+
console.log(import_chalk3.default.bold("\n\u{1F4CA} AI Readiness Overall Score"));
|
|
970
|
+
console.log(` ${(0, import_core3.formatScore)(scoringResult)}`);
|
|
971
|
+
if (options.compareTo) {
|
|
724
972
|
try {
|
|
725
|
-
const
|
|
726
|
-
|
|
727
|
-
|
|
973
|
+
const prevReportStr = (0, import_fs3.readFileSync)(
|
|
974
|
+
(0, import_path3.resolve)(process.cwd(), options.compareTo),
|
|
975
|
+
"utf8"
|
|
728
976
|
);
|
|
729
|
-
|
|
730
|
-
|
|
731
|
-
|
|
732
|
-
|
|
733
|
-
|
|
734
|
-
|
|
735
|
-
|
|
736
|
-
|
|
737
|
-
|
|
738
|
-
|
|
739
|
-
|
|
740
|
-
|
|
741
|
-
|
|
742
|
-
|
|
743
|
-
|
|
744
|
-
|
|
745
|
-
|
|
746
|
-
|
|
747
|
-
const issues = results.consistency.results?.flatMap((r) => r.issues) || [];
|
|
748
|
-
const totalFiles = results.consistency.summary?.filesAnalyzed || 0;
|
|
749
|
-
const consistencyScore = calculateConsistencyScore(
|
|
750
|
-
issues,
|
|
751
|
-
totalFiles
|
|
752
|
-
);
|
|
753
|
-
toolScores.set("consistency", consistencyScore);
|
|
754
|
-
} catch (err) {
|
|
755
|
-
void err;
|
|
756
|
-
}
|
|
757
|
-
}
|
|
758
|
-
if (results.aiSignalClarity) {
|
|
759
|
-
const { calculateAiSignalClarityScore } = await import("@aiready/ai-signal-clarity");
|
|
760
|
-
try {
|
|
761
|
-
const hrScore = calculateAiSignalClarityScore(
|
|
762
|
-
results.aiSignalClarity
|
|
763
|
-
);
|
|
764
|
-
toolScores.set("ai-signal-clarity", hrScore);
|
|
765
|
-
} catch (err) {
|
|
766
|
-
void err;
|
|
767
|
-
}
|
|
768
|
-
}
|
|
769
|
-
if (results.grounding) {
|
|
770
|
-
const { calculateGroundingScore } = await import("@aiready/agent-grounding");
|
|
771
|
-
try {
|
|
772
|
-
const agScore = calculateGroundingScore(results.grounding);
|
|
773
|
-
toolScores.set("agent-grounding", agScore);
|
|
774
|
-
} catch (err) {
|
|
775
|
-
void err;
|
|
776
|
-
}
|
|
777
|
-
}
|
|
778
|
-
if (results.testability) {
|
|
779
|
-
const { calculateTestabilityScore } = await import("@aiready/testability");
|
|
780
|
-
try {
|
|
781
|
-
const tbScore = calculateTestabilityScore(results.testability);
|
|
782
|
-
toolScores.set("testability", tbScore);
|
|
783
|
-
} catch (err) {
|
|
784
|
-
void err;
|
|
785
|
-
}
|
|
786
|
-
}
|
|
787
|
-
if (results.docDrift) {
|
|
788
|
-
toolScores.set("doc-drift", {
|
|
789
|
-
toolName: "doc-drift",
|
|
790
|
-
score: results.docDrift.summary.score,
|
|
791
|
-
rawMetrics: results.docDrift.rawData,
|
|
792
|
-
factors: [],
|
|
793
|
-
recommendations: (results.docDrift.recommendations || []).map(
|
|
794
|
-
(action) => ({
|
|
795
|
-
action,
|
|
796
|
-
estimatedImpact: 5,
|
|
797
|
-
priority: "medium"
|
|
798
|
-
})
|
|
799
|
-
)
|
|
800
|
-
});
|
|
801
|
-
}
|
|
802
|
-
if (results.deps) {
|
|
803
|
-
toolScores.set("dependency-health", {
|
|
804
|
-
toolName: "dependency-health",
|
|
805
|
-
score: results.deps.summary.score,
|
|
806
|
-
rawMetrics: results.deps.rawData,
|
|
807
|
-
factors: [],
|
|
808
|
-
recommendations: (results.deps.recommendations || []).map(
|
|
809
|
-
(action) => ({
|
|
810
|
-
action,
|
|
811
|
-
estimatedImpact: 5,
|
|
812
|
-
priority: "medium"
|
|
813
|
-
})
|
|
814
|
-
)
|
|
815
|
-
});
|
|
816
|
-
}
|
|
817
|
-
if (results.changeAmplification) {
|
|
818
|
-
toolScores.set("change-amplification", {
|
|
819
|
-
toolName: "change-amplification",
|
|
820
|
-
score: results.changeAmplification.summary.score,
|
|
821
|
-
rawMetrics: results.changeAmplification.rawData,
|
|
822
|
-
factors: [],
|
|
823
|
-
recommendations: (results.changeAmplification.recommendations || []).map((action) => ({
|
|
824
|
-
action,
|
|
825
|
-
estimatedImpact: 5,
|
|
826
|
-
priority: "medium"
|
|
827
|
-
}))
|
|
828
|
-
});
|
|
829
|
-
}
|
|
830
|
-
const cliWeights = (0, import_core.parseWeightString)(options.weights);
|
|
831
|
-
if (toolScores.size > 0) {
|
|
832
|
-
scoringResult = (0, import_core.calculateOverallScore)(
|
|
833
|
-
toolScores,
|
|
834
|
-
finalOptions,
|
|
835
|
-
cliWeights.size ? cliWeights : void 0
|
|
836
|
-
);
|
|
837
|
-
console.log(import_chalk2.default.bold("\n\u{1F4CA} AI Readiness Overall Score"));
|
|
838
|
-
console.log(` ${(0, import_core.formatScore)(scoringResult)}`);
|
|
839
|
-
if (options.compareTo) {
|
|
840
|
-
try {
|
|
841
|
-
const prevReportStr = (0, import_fs2.readFileSync)(
|
|
842
|
-
(0, import_path2.resolve)(process.cwd(), options.compareTo),
|
|
843
|
-
"utf8"
|
|
844
|
-
);
|
|
845
|
-
const prevReport = JSON.parse(prevReportStr);
|
|
846
|
-
const prevScore = prevReport.scoring?.score || prevReport.scoring?.overallScore;
|
|
847
|
-
if (typeof prevScore === "number") {
|
|
848
|
-
const diff = scoringResult.overall - prevScore;
|
|
849
|
-
const diffStr = diff > 0 ? `+${diff}` : String(diff);
|
|
850
|
-
console.log();
|
|
851
|
-
if (diff > 0) {
|
|
852
|
-
console.log(
|
|
853
|
-
import_chalk2.default.green(
|
|
854
|
-
` \u{1F4C8} Trend: ${diffStr} compared to ${options.compareTo} (${prevScore} \u2192 ${scoringResult.overall})`
|
|
855
|
-
)
|
|
856
|
-
);
|
|
857
|
-
} else if (diff < 0) {
|
|
858
|
-
console.log(
|
|
859
|
-
import_chalk2.default.red(
|
|
860
|
-
` \u{1F4C9} Trend: ${diffStr} compared to ${options.compareTo} (${prevScore} \u2192 ${scoringResult.overall})`
|
|
861
|
-
)
|
|
862
|
-
);
|
|
863
|
-
} else {
|
|
864
|
-
console.log(
|
|
865
|
-
import_chalk2.default.blue(
|
|
866
|
-
` \u2796 Trend: No change compared to ${options.compareTo} (${prevScore} \u2192 ${scoringResult.overall})`
|
|
867
|
-
)
|
|
868
|
-
);
|
|
869
|
-
}
|
|
870
|
-
scoringResult.trend = {
|
|
871
|
-
previousScore: prevScore,
|
|
872
|
-
difference: diff
|
|
873
|
-
};
|
|
977
|
+
const prevReport = JSON.parse(prevReportStr);
|
|
978
|
+
const prevScore = prevReport.scoring?.score || prevReport.scoring?.overallScore;
|
|
979
|
+
if (typeof prevScore === "number") {
|
|
980
|
+
const diff = scoringResult.overall - prevScore;
|
|
981
|
+
const diffStr = diff > 0 ? `+${diff}` : String(diff);
|
|
982
|
+
console.log();
|
|
983
|
+
if (diff > 0) {
|
|
984
|
+
console.log(
|
|
985
|
+
import_chalk3.default.green(
|
|
986
|
+
` \u{1F4C8} Trend: ${diffStr} compared to ${options.compareTo} (${prevScore} \u2192 ${scoringResult.overall})`
|
|
987
|
+
)
|
|
988
|
+
);
|
|
989
|
+
} else if (diff < 0) {
|
|
990
|
+
console.log(
|
|
991
|
+
import_chalk3.default.red(
|
|
992
|
+
` \u{1F4C9} Trend: ${diffStr} compared to ${options.compareTo} (${prevScore} \u2192 ${scoringResult.overall})`
|
|
993
|
+
)
|
|
994
|
+
);
|
|
874
995
|
} else {
|
|
875
996
|
console.log(
|
|
876
|
-
|
|
877
|
-
`
|
|
878
|
-
\u26A0\uFE0F Previous report at ${options.compareTo} does not contain an overall score.`
|
|
997
|
+
import_chalk3.default.blue(
|
|
998
|
+
` \u2796 Trend: No change compared to ${options.compareTo} (${prevScore} \u2192 ${scoringResult.overall})`
|
|
879
999
|
)
|
|
880
1000
|
);
|
|
881
1001
|
}
|
|
882
|
-
|
|
883
|
-
|
|
1002
|
+
scoringResult.trend = {
|
|
1003
|
+
previousScore: prevScore,
|
|
1004
|
+
difference: diff
|
|
1005
|
+
};
|
|
1006
|
+
} else {
|
|
884
1007
|
console.log(
|
|
885
|
-
|
|
1008
|
+
import_chalk3.default.yellow(
|
|
886
1009
|
`
|
|
887
|
-
\u26A0\uFE0F
|
|
1010
|
+
\u26A0\uFE0F Previous report at ${options.compareTo} does not contain an overall score.`
|
|
888
1011
|
)
|
|
889
1012
|
);
|
|
890
1013
|
}
|
|
1014
|
+
} catch (e) {
|
|
1015
|
+
void e;
|
|
1016
|
+
console.log(
|
|
1017
|
+
import_chalk3.default.yellow(
|
|
1018
|
+
`
|
|
1019
|
+
\u26A0\uFE0F Could not read or parse previous report at ${options.compareTo}.`
|
|
1020
|
+
)
|
|
1021
|
+
);
|
|
891
1022
|
}
|
|
892
|
-
|
|
893
|
-
|
|
1023
|
+
}
|
|
1024
|
+
const totalWastedDuplication = (scoringResult.breakdown || []).reduce(
|
|
1025
|
+
(sum, s) => sum + (s.tokenBudget?.wastedTokens.bySource.duplication || 0),
|
|
1026
|
+
0
|
|
1027
|
+
);
|
|
1028
|
+
const totalWastedFragmentation = (scoringResult.breakdown || []).reduce(
|
|
1029
|
+
(sum, s) => sum + (s.tokenBudget?.wastedTokens.bySource.fragmentation || 0),
|
|
1030
|
+
0
|
|
1031
|
+
);
|
|
1032
|
+
const totalContext = Math.max(
|
|
1033
|
+
...(scoringResult.breakdown || []).map(
|
|
1034
|
+
(s) => s.tokenBudget?.totalContextTokens || 0
|
|
1035
|
+
)
|
|
1036
|
+
);
|
|
1037
|
+
if (totalContext > 0) {
|
|
1038
|
+
const unifiedBudget = (0, import_core3.calculateTokenBudget)({
|
|
1039
|
+
totalContextTokens: totalContext,
|
|
1040
|
+
wastedTokens: {
|
|
1041
|
+
duplication: totalWastedDuplication,
|
|
1042
|
+
fragmentation: totalWastedFragmentation,
|
|
1043
|
+
chattiness: 0
|
|
1044
|
+
}
|
|
1045
|
+
});
|
|
1046
|
+
const targetModel = options.model || "claude-4.6";
|
|
1047
|
+
const modelPreset = (0, import_core3.getModelPreset)(targetModel);
|
|
1048
|
+
const costEstimate = (0, import_core3.estimateCostFromBudget)(unifiedBudget, modelPreset);
|
|
1049
|
+
const barWidth = 20;
|
|
1050
|
+
const filled = Math.round(unifiedBudget.efficiencyRatio * barWidth);
|
|
1051
|
+
const bar = import_chalk3.default.green("\u2588".repeat(filled)) + import_chalk3.default.dim("\u2591".repeat(barWidth - filled));
|
|
1052
|
+
console.log(import_chalk3.default.bold("\n\u{1F4CA} AI Token Budget Analysis (v0.13)"));
|
|
1053
|
+
console.log(
|
|
1054
|
+
` Efficiency: [${bar}] ${(unifiedBudget.efficiencyRatio * 100).toFixed(0)}%`
|
|
1055
|
+
);
|
|
1056
|
+
console.log(
|
|
1057
|
+
` Total Context: ${import_chalk3.default.bold(unifiedBudget.totalContextTokens.toLocaleString())} tokens`
|
|
1058
|
+
);
|
|
1059
|
+
console.log(
|
|
1060
|
+
` Wasted Tokens: ${import_chalk3.default.red(unifiedBudget.wastedTokens.total.toLocaleString())} (${(unifiedBudget.wastedTokens.total / unifiedBudget.totalContextTokens * 100).toFixed(1)}%)`
|
|
1061
|
+
);
|
|
1062
|
+
console.log(` Waste Breakdown:`);
|
|
1063
|
+
console.log(
|
|
1064
|
+
` \u2022 Duplication: ${unifiedBudget.wastedTokens.bySource.duplication.toLocaleString()} tokens`
|
|
1065
|
+
);
|
|
1066
|
+
console.log(
|
|
1067
|
+
` \u2022 Fragmentation: ${unifiedBudget.wastedTokens.bySource.fragmentation.toLocaleString()} tokens`
|
|
1068
|
+
);
|
|
1069
|
+
console.log(
|
|
1070
|
+
` Potential Savings: ${import_chalk3.default.green(unifiedBudget.potentialRetrievableTokens.toLocaleString())} tokens retrievable`
|
|
1071
|
+
);
|
|
1072
|
+
console.log(
|
|
1073
|
+
`
|
|
1074
|
+
Est. Monthly Cost (${modelPreset.name}): ${import_chalk3.default.bold("$" + costEstimate.total)} [range: $${costEstimate.range[0]}-$${costEstimate.range[1]}]`
|
|
1075
|
+
);
|
|
1076
|
+
scoringResult.tokenBudget = unifiedBudget;
|
|
1077
|
+
scoringResult.costEstimate = {
|
|
1078
|
+
model: modelPreset.name,
|
|
1079
|
+
...costEstimate
|
|
1080
|
+
};
|
|
1081
|
+
}
|
|
1082
|
+
if (scoringResult.breakdown && scoringResult.breakdown.length > 0) {
|
|
1083
|
+
console.log(import_chalk3.default.bold("\nTool breakdown:"));
|
|
1084
|
+
scoringResult.breakdown.forEach((tool) => {
|
|
1085
|
+
const rating = (0, import_core3.getRating)(tool.score);
|
|
1086
|
+
const rd = (0, import_core3.getRatingDisplay)(rating);
|
|
1087
|
+
console.log(
|
|
1088
|
+
` - ${tool.toolName}: ${tool.score}/100 (${rating}) ${rd.emoji}`
|
|
1089
|
+
);
|
|
1090
|
+
});
|
|
1091
|
+
console.log();
|
|
1092
|
+
if (finalOptions.scoring?.showBreakdown) {
|
|
1093
|
+
console.log(import_chalk3.default.bold("Detailed tool breakdown:"));
|
|
894
1094
|
scoringResult.breakdown.forEach((tool) => {
|
|
895
|
-
|
|
896
|
-
const rd = (0, import_core.getRatingDisplay)(rating);
|
|
897
|
-
console.log(
|
|
898
|
-
` - ${tool.toolName}: ${tool.score}/100 (${rating}) ${rd.emoji}`
|
|
899
|
-
);
|
|
1095
|
+
console.log((0, import_core3.formatToolScore)(tool));
|
|
900
1096
|
});
|
|
901
1097
|
console.log();
|
|
902
|
-
if (finalOptions.scoring?.showBreakdown) {
|
|
903
|
-
console.log(import_chalk2.default.bold("Detailed tool breakdown:"));
|
|
904
|
-
scoringResult.breakdown.forEach((tool) => {
|
|
905
|
-
console.log((0, import_core.formatToolScore)(tool));
|
|
906
|
-
});
|
|
907
|
-
console.log();
|
|
908
|
-
}
|
|
909
1098
|
}
|
|
910
1099
|
}
|
|
911
1100
|
}
|
|
@@ -914,30 +1103,52 @@ async function scanAction(directory, options) {
|
|
|
914
1103
|
if (outputFormat === "json") {
|
|
915
1104
|
const timestamp = getReportTimestamp();
|
|
916
1105
|
const defaultFilename = `aiready-report-${timestamp}.json`;
|
|
917
|
-
const outputPath = (0,
|
|
1106
|
+
const outputPath = (0, import_core3.resolveOutputPath)(
|
|
918
1107
|
userOutputFile,
|
|
919
1108
|
defaultFilename,
|
|
920
1109
|
resolvedDir
|
|
921
1110
|
);
|
|
922
|
-
const outputData = {
|
|
923
|
-
|
|
1111
|
+
const outputData = {
|
|
1112
|
+
...results,
|
|
1113
|
+
scoring: scoringResult,
|
|
1114
|
+
repository: repoMetadata
|
|
1115
|
+
};
|
|
1116
|
+
(0, import_core3.handleJSONOutput)(
|
|
924
1117
|
outputData,
|
|
925
1118
|
outputPath,
|
|
926
1119
|
`\u2705 Report saved to ${outputPath}`
|
|
927
1120
|
);
|
|
1121
|
+
if (options.upload) {
|
|
1122
|
+
console.log(import_chalk3.default.blue("\n\u{1F4E4} Automatic upload triggered..."));
|
|
1123
|
+
await uploadAction(outputPath, {
|
|
1124
|
+
apiKey: options.apiKey,
|
|
1125
|
+
server: options.server
|
|
1126
|
+
});
|
|
1127
|
+
}
|
|
928
1128
|
await warnIfGraphCapExceeded(outputData, resolvedDir);
|
|
929
1129
|
} else {
|
|
930
1130
|
const timestamp = getReportTimestamp();
|
|
931
1131
|
const defaultFilename = `aiready-report-${timestamp}.json`;
|
|
932
|
-
const outputPath = (0,
|
|
1132
|
+
const outputPath = (0, import_core3.resolveOutputPath)(
|
|
933
1133
|
userOutputFile,
|
|
934
1134
|
defaultFilename,
|
|
935
1135
|
resolvedDir
|
|
936
1136
|
);
|
|
937
|
-
const outputData = {
|
|
1137
|
+
const outputData = {
|
|
1138
|
+
...results,
|
|
1139
|
+
scoring: scoringResult,
|
|
1140
|
+
repository: repoMetadata
|
|
1141
|
+
};
|
|
938
1142
|
try {
|
|
939
|
-
(0,
|
|
940
|
-
console.log(
|
|
1143
|
+
(0, import_fs3.writeFileSync)(outputPath, JSON.stringify(outputData, null, 2));
|
|
1144
|
+
console.log(import_chalk3.default.dim(`\u2705 Report auto-persisted to ${outputPath}`));
|
|
1145
|
+
if (options.upload) {
|
|
1146
|
+
console.log(import_chalk3.default.blue("\n\u{1F4E4} Automatic upload triggered..."));
|
|
1147
|
+
await uploadAction(outputPath, {
|
|
1148
|
+
apiKey: options.apiKey,
|
|
1149
|
+
server: options.server
|
|
1150
|
+
});
|
|
1151
|
+
}
|
|
941
1152
|
await warnIfGraphCapExceeded(outputData, resolvedDir);
|
|
942
1153
|
} catch (err) {
|
|
943
1154
|
void err;
|
|
@@ -1019,37 +1230,37 @@ async function scanAction(directory, options) {
|
|
|
1019
1230
|
}
|
|
1020
1231
|
}
|
|
1021
1232
|
if (shouldFail) {
|
|
1022
|
-
console.log(
|
|
1023
|
-
console.log(
|
|
1024
|
-
console.log(
|
|
1233
|
+
console.log(import_chalk3.default.red("\n\u{1F6AB} PR BLOCKED: AI Readiness Check Failed"));
|
|
1234
|
+
console.log(import_chalk3.default.red(` Reason: ${failReason}`));
|
|
1235
|
+
console.log(import_chalk3.default.dim("\n Remediation steps:"));
|
|
1025
1236
|
console.log(
|
|
1026
|
-
|
|
1237
|
+
import_chalk3.default.dim(" 1. Run `aiready scan` locally to see detailed issues")
|
|
1027
1238
|
);
|
|
1028
|
-
console.log(
|
|
1239
|
+
console.log(import_chalk3.default.dim(" 2. Fix the critical issues before merging"));
|
|
1029
1240
|
console.log(
|
|
1030
|
-
|
|
1241
|
+
import_chalk3.default.dim(
|
|
1031
1242
|
" 3. Consider upgrading to Team plan for historical tracking: https://getaiready.dev/pricing"
|
|
1032
1243
|
)
|
|
1033
1244
|
);
|
|
1034
1245
|
process.exit(1);
|
|
1035
1246
|
} else {
|
|
1036
|
-
console.log(
|
|
1247
|
+
console.log(import_chalk3.default.green("\n\u2705 PR PASSED: AI Readiness Check"));
|
|
1037
1248
|
if (threshold) {
|
|
1038
1249
|
console.log(
|
|
1039
|
-
|
|
1250
|
+
import_chalk3.default.green(
|
|
1040
1251
|
` Score: ${scoringResult.overall}/100 (threshold: ${threshold})`
|
|
1041
1252
|
)
|
|
1042
1253
|
);
|
|
1043
1254
|
}
|
|
1044
1255
|
console.log(
|
|
1045
|
-
|
|
1256
|
+
import_chalk3.default.dim(
|
|
1046
1257
|
"\n \u{1F4A1} Track historical trends: https://getaiready.dev \u2014 Team plan $99/mo"
|
|
1047
1258
|
)
|
|
1048
1259
|
);
|
|
1049
1260
|
}
|
|
1050
1261
|
}
|
|
1051
1262
|
} catch (error) {
|
|
1052
|
-
(0,
|
|
1263
|
+
(0, import_core3.handleCLIError)(error, "Analysis");
|
|
1053
1264
|
}
|
|
1054
1265
|
}
|
|
1055
1266
|
var scanHelpText = `
|
|
@@ -1063,6 +1274,8 @@ EXAMPLES:
|
|
|
1063
1274
|
$ aiready scan --ci --threshold 70 # GitHub Actions gatekeeper
|
|
1064
1275
|
$ aiready scan --ci --fail-on major # Fail on major+ issues
|
|
1065
1276
|
$ aiready scan --output json --output-file report.json
|
|
1277
|
+
$ aiready scan --upload --api-key ar_... # Automatic platform upload
|
|
1278
|
+
$ aiready scan --upload --server custom-url.com # Upload to custom platform
|
|
1066
1279
|
|
|
1067
1280
|
PROFILES:
|
|
1068
1281
|
agentic: aiSignalClarity, grounding, testability
|
|
@@ -1082,13 +1295,13 @@ CI/CD INTEGRATION (Gatekeeper Mode):
|
|
|
1082
1295
|
`;
|
|
1083
1296
|
|
|
1084
1297
|
// src/commands/patterns.ts
|
|
1085
|
-
var
|
|
1086
|
-
var
|
|
1087
|
-
var
|
|
1298
|
+
var import_chalk4 = __toESM(require("chalk"));
|
|
1299
|
+
var import_path4 = require("path");
|
|
1300
|
+
var import_core4 = require("@aiready/core");
|
|
1088
1301
|
async function patternsAction(directory, options) {
|
|
1089
|
-
console.log(
|
|
1302
|
+
console.log(import_chalk4.default.blue("\u{1F50D} Analyzing patterns...\n"));
|
|
1090
1303
|
const startTime = Date.now();
|
|
1091
|
-
const resolvedDir = (0,
|
|
1304
|
+
const resolvedDir = (0, import_path4.resolve)(process.cwd(), directory || ".");
|
|
1092
1305
|
try {
|
|
1093
1306
|
const useSmartDefaults = !options.fullScan;
|
|
1094
1307
|
const defaults = {
|
|
@@ -1117,14 +1330,14 @@ async function patternsAction(directory, options) {
|
|
|
1117
1330
|
if (options.minSharedTokens) {
|
|
1118
1331
|
cliOptions.minSharedTokens = parseInt(options.minSharedTokens);
|
|
1119
1332
|
}
|
|
1120
|
-
const finalOptions = await (0,
|
|
1333
|
+
const finalOptions = await (0, import_core4.loadMergedConfig)(
|
|
1121
1334
|
resolvedDir,
|
|
1122
1335
|
defaults,
|
|
1123
1336
|
cliOptions
|
|
1124
1337
|
);
|
|
1125
1338
|
const { analyzePatterns: analyzePatterns2, generateSummary, calculatePatternScore } = await import("@aiready/pattern-detect");
|
|
1126
1339
|
const { results, duplicates } = await analyzePatterns2(finalOptions);
|
|
1127
|
-
const elapsedTime = (0,
|
|
1340
|
+
const elapsedTime = (0, import_core4.getElapsedTime)(startTime);
|
|
1128
1341
|
const summary = generateSummary(results);
|
|
1129
1342
|
let patternScore;
|
|
1130
1343
|
if (options.score) {
|
|
@@ -1138,12 +1351,12 @@ async function patternsAction(directory, options) {
|
|
|
1138
1351
|
summary: { ...summary, executionTime: parseFloat(elapsedTime) },
|
|
1139
1352
|
...patternScore && { scoring: patternScore }
|
|
1140
1353
|
};
|
|
1141
|
-
const outputPath = (0,
|
|
1354
|
+
const outputPath = (0, import_core4.resolveOutputPath)(
|
|
1142
1355
|
userOutputFile,
|
|
1143
1356
|
`aiready-report-${getReportTimestamp()}.json`,
|
|
1144
1357
|
resolvedDir
|
|
1145
1358
|
);
|
|
1146
|
-
(0,
|
|
1359
|
+
(0, import_core4.handleJSONOutput)(
|
|
1147
1360
|
outputData,
|
|
1148
1361
|
outputPath,
|
|
1149
1362
|
`\u2705 Results saved to ${outputPath}`
|
|
@@ -1152,38 +1365,38 @@ async function patternsAction(directory, options) {
|
|
|
1152
1365
|
const terminalWidth = process.stdout.columns || 80;
|
|
1153
1366
|
const dividerWidth = Math.min(60, terminalWidth - 2);
|
|
1154
1367
|
const divider = "\u2501".repeat(dividerWidth);
|
|
1155
|
-
console.log(
|
|
1156
|
-
console.log(
|
|
1157
|
-
console.log(
|
|
1368
|
+
console.log(import_chalk4.default.cyan(divider));
|
|
1369
|
+
console.log(import_chalk4.default.bold.white(" PATTERN ANALYSIS SUMMARY"));
|
|
1370
|
+
console.log(import_chalk4.default.cyan(divider) + "\n");
|
|
1158
1371
|
console.log(
|
|
1159
|
-
|
|
1372
|
+
import_chalk4.default.white(`\u{1F4C1} Files analyzed: ${import_chalk4.default.bold(results.length)}`)
|
|
1160
1373
|
);
|
|
1161
1374
|
console.log(
|
|
1162
|
-
|
|
1163
|
-
`\u26A0 Duplicate patterns found: ${
|
|
1375
|
+
import_chalk4.default.yellow(
|
|
1376
|
+
`\u26A0 Duplicate patterns found: ${import_chalk4.default.bold(summary.totalPatterns)}`
|
|
1164
1377
|
)
|
|
1165
1378
|
);
|
|
1166
1379
|
console.log(
|
|
1167
|
-
|
|
1168
|
-
`\u{1F4B0} Token cost (wasted): ${
|
|
1380
|
+
import_chalk4.default.red(
|
|
1381
|
+
`\u{1F4B0} Token cost (wasted): ${import_chalk4.default.bold(summary.totalTokenCost.toLocaleString())}`
|
|
1169
1382
|
)
|
|
1170
1383
|
);
|
|
1171
1384
|
console.log(
|
|
1172
|
-
|
|
1385
|
+
import_chalk4.default.gray(`\u23F1 Analysis time: ${import_chalk4.default.bold(elapsedTime + "s")}`)
|
|
1173
1386
|
);
|
|
1174
1387
|
const sortedTypes = Object.entries(summary.patternsByType || {}).filter(([, count]) => count > 0).sort(([, a], [, b]) => b - a);
|
|
1175
1388
|
if (sortedTypes.length > 0) {
|
|
1176
|
-
console.log(
|
|
1177
|
-
console.log(
|
|
1178
|
-
console.log(
|
|
1389
|
+
console.log(import_chalk4.default.cyan("\n" + divider));
|
|
1390
|
+
console.log(import_chalk4.default.bold.white(" PATTERNS BY TYPE"));
|
|
1391
|
+
console.log(import_chalk4.default.cyan(divider) + "\n");
|
|
1179
1392
|
sortedTypes.forEach(([type, count]) => {
|
|
1180
|
-
console.log(` ${
|
|
1393
|
+
console.log(` ${import_chalk4.default.white(type.padEnd(15))} ${import_chalk4.default.bold(count)}`);
|
|
1181
1394
|
});
|
|
1182
1395
|
}
|
|
1183
1396
|
if (summary.totalPatterns > 0 && duplicates.length > 0) {
|
|
1184
|
-
console.log(
|
|
1185
|
-
console.log(
|
|
1186
|
-
console.log(
|
|
1397
|
+
console.log(import_chalk4.default.cyan("\n" + divider));
|
|
1398
|
+
console.log(import_chalk4.default.bold.white(" TOP DUPLICATE PATTERNS"));
|
|
1399
|
+
console.log(import_chalk4.default.cyan(divider) + "\n");
|
|
1187
1400
|
const topDuplicates = [...duplicates].sort((a, b) => b.similarity - a.similarity).slice(0, 10);
|
|
1188
1401
|
topDuplicates.forEach((dup) => {
|
|
1189
1402
|
const severity = dup.similarity > 0.95 ? "CRITICAL" : dup.similarity > 0.9 ? "HIGH" : "MEDIUM";
|
|
@@ -1191,31 +1404,31 @@ async function patternsAction(directory, options) {
|
|
|
1191
1404
|
const file1Name = dup.file1.split("/").pop() || dup.file1;
|
|
1192
1405
|
const file2Name = dup.file2.split("/").pop() || dup.file2;
|
|
1193
1406
|
console.log(
|
|
1194
|
-
`${severityIcon} ${severity}: ${
|
|
1407
|
+
`${severityIcon} ${severity}: ${import_chalk4.default.bold(file1Name)} \u2194 ${import_chalk4.default.bold(file2Name)}`
|
|
1195
1408
|
);
|
|
1196
1409
|
console.log(
|
|
1197
|
-
` Similarity: ${
|
|
1410
|
+
` Similarity: ${import_chalk4.default.bold(Math.round(dup.similarity * 100) + "%")} | Wasted: ${import_chalk4.default.bold(dup.tokenCost.toLocaleString())} tokens each`
|
|
1198
1411
|
);
|
|
1199
1412
|
console.log(
|
|
1200
|
-
` Lines: ${
|
|
1413
|
+
` Lines: ${import_chalk4.default.cyan(dup.line1 + "-" + dup.endLine1)} \u2194 ${import_chalk4.default.cyan(dup.line2 + "-" + dup.endLine2)}
|
|
1201
1414
|
`
|
|
1202
1415
|
);
|
|
1203
1416
|
});
|
|
1204
1417
|
} else {
|
|
1205
1418
|
console.log(
|
|
1206
|
-
|
|
1419
|
+
import_chalk4.default.green("\n\u2728 Great! No duplicate patterns detected.\n")
|
|
1207
1420
|
);
|
|
1208
1421
|
}
|
|
1209
1422
|
if (patternScore) {
|
|
1210
|
-
console.log(
|
|
1211
|
-
console.log(
|
|
1212
|
-
console.log(
|
|
1213
|
-
console.log((0,
|
|
1423
|
+
console.log(import_chalk4.default.cyan(divider));
|
|
1424
|
+
console.log(import_chalk4.default.bold.white(" AI READINESS SCORE (Patterns)"));
|
|
1425
|
+
console.log(import_chalk4.default.cyan(divider) + "\n");
|
|
1426
|
+
console.log((0, import_core4.formatToolScore)(patternScore));
|
|
1214
1427
|
console.log();
|
|
1215
1428
|
}
|
|
1216
1429
|
}
|
|
1217
1430
|
} catch (error) {
|
|
1218
|
-
(0,
|
|
1431
|
+
(0, import_core4.handleCLIError)(error, "Pattern analysis");
|
|
1219
1432
|
}
|
|
1220
1433
|
}
|
|
1221
1434
|
var patternsHelpText = `
|
|
@@ -1226,13 +1439,13 @@ EXAMPLES:
|
|
|
1226
1439
|
`;
|
|
1227
1440
|
|
|
1228
1441
|
// src/commands/context.ts
|
|
1229
|
-
var
|
|
1230
|
-
var
|
|
1231
|
-
var
|
|
1442
|
+
var import_chalk5 = __toESM(require("chalk"));
|
|
1443
|
+
var import_path5 = require("path");
|
|
1444
|
+
var import_core5 = require("@aiready/core");
|
|
1232
1445
|
async function contextAction(directory, options) {
|
|
1233
|
-
console.log(
|
|
1446
|
+
console.log(import_chalk5.default.blue("\u{1F9E0} Analyzing context costs...\n"));
|
|
1234
1447
|
const startTime = Date.now();
|
|
1235
|
-
const resolvedDir = (0,
|
|
1448
|
+
const resolvedDir = (0, import_path5.resolve)(process.cwd(), directory || ".");
|
|
1236
1449
|
try {
|
|
1237
1450
|
const defaults = {
|
|
1238
1451
|
maxDepth: 5,
|
|
@@ -1244,7 +1457,7 @@ async function contextAction(directory, options) {
|
|
|
1244
1457
|
file: void 0
|
|
1245
1458
|
}
|
|
1246
1459
|
};
|
|
1247
|
-
const baseOptions = await (0,
|
|
1460
|
+
const baseOptions = await (0, import_core5.loadMergedConfig)(resolvedDir, defaults, {
|
|
1248
1461
|
maxDepth: options.maxDepth ? parseInt(options.maxDepth) : void 0,
|
|
1249
1462
|
maxContextBudget: options.maxContext ? parseInt(options.maxContext) : void 0,
|
|
1250
1463
|
include: options.include?.split(","),
|
|
@@ -1270,7 +1483,7 @@ async function contextAction(directory, options) {
|
|
|
1270
1483
|
console.log("");
|
|
1271
1484
|
const { analyzeContext: analyzeContext2, generateSummary, calculateContextScore } = await import("@aiready/context-analyzer");
|
|
1272
1485
|
const results = await analyzeContext2(finalOptions);
|
|
1273
|
-
const elapsedTime = (0,
|
|
1486
|
+
const elapsedTime = (0, import_core5.getElapsedTime)(startTime);
|
|
1274
1487
|
const summary = generateSummary(results);
|
|
1275
1488
|
let contextScore;
|
|
1276
1489
|
if (options.score) {
|
|
@@ -1284,12 +1497,12 @@ async function contextAction(directory, options) {
|
|
|
1284
1497
|
summary: { ...summary, executionTime: parseFloat(elapsedTime) },
|
|
1285
1498
|
...contextScore && { scoring: contextScore }
|
|
1286
1499
|
};
|
|
1287
|
-
const outputPath = (0,
|
|
1500
|
+
const outputPath = (0, import_core5.resolveOutputPath)(
|
|
1288
1501
|
userOutputFile,
|
|
1289
1502
|
`aiready-report-${getReportTimestamp()}.json`,
|
|
1290
1503
|
resolvedDir
|
|
1291
1504
|
);
|
|
1292
|
-
(0,
|
|
1505
|
+
(0, import_core5.handleJSONOutput)(
|
|
1293
1506
|
outputData,
|
|
1294
1507
|
outputPath,
|
|
1295
1508
|
`\u2705 Results saved to ${outputPath}`
|
|
@@ -1298,85 +1511,85 @@ async function contextAction(directory, options) {
|
|
|
1298
1511
|
const terminalWidth = process.stdout.columns || 80;
|
|
1299
1512
|
const dividerWidth = Math.min(60, terminalWidth - 2);
|
|
1300
1513
|
const divider = "\u2501".repeat(dividerWidth);
|
|
1301
|
-
console.log(
|
|
1302
|
-
console.log(
|
|
1303
|
-
console.log(
|
|
1514
|
+
console.log(import_chalk5.default.cyan(divider));
|
|
1515
|
+
console.log(import_chalk5.default.bold.white(" CONTEXT ANALYSIS SUMMARY"));
|
|
1516
|
+
console.log(import_chalk5.default.cyan(divider) + "\n");
|
|
1304
1517
|
console.log(
|
|
1305
|
-
|
|
1518
|
+
import_chalk5.default.white(`\u{1F4C1} Files analyzed: ${import_chalk5.default.bold(summary.totalFiles)}`)
|
|
1306
1519
|
);
|
|
1307
1520
|
console.log(
|
|
1308
|
-
|
|
1309
|
-
`\u{1F4CA} Total tokens: ${
|
|
1521
|
+
import_chalk5.default.white(
|
|
1522
|
+
`\u{1F4CA} Total tokens: ${import_chalk5.default.bold(summary.totalTokens.toLocaleString())}`
|
|
1310
1523
|
)
|
|
1311
1524
|
);
|
|
1312
1525
|
console.log(
|
|
1313
|
-
|
|
1314
|
-
`\u{1F4B0} Avg context budget: ${
|
|
1526
|
+
import_chalk5.default.yellow(
|
|
1527
|
+
`\u{1F4B0} Avg context budget: ${import_chalk5.default.bold(summary.avgContextBudget.toFixed(0))} tokens/file`
|
|
1315
1528
|
)
|
|
1316
1529
|
);
|
|
1317
1530
|
console.log(
|
|
1318
|
-
|
|
1531
|
+
import_chalk5.default.white(`\u23F1 Analysis time: ${import_chalk5.default.bold(elapsedTime + "s")}
|
|
1319
1532
|
`)
|
|
1320
1533
|
);
|
|
1321
1534
|
const totalIssues = summary.criticalIssues + summary.majorIssues + summary.minorIssues;
|
|
1322
1535
|
if (totalIssues > 0) {
|
|
1323
|
-
console.log(
|
|
1536
|
+
console.log(import_chalk5.default.bold("\u26A0\uFE0F Issues Found:\n"));
|
|
1324
1537
|
if (summary.criticalIssues > 0) {
|
|
1325
1538
|
console.log(
|
|
1326
|
-
|
|
1539
|
+
import_chalk5.default.red(` \u{1F534} Critical: ${import_chalk5.default.bold(summary.criticalIssues)}`)
|
|
1327
1540
|
);
|
|
1328
1541
|
}
|
|
1329
1542
|
if (summary.majorIssues > 0) {
|
|
1330
1543
|
console.log(
|
|
1331
|
-
|
|
1544
|
+
import_chalk5.default.yellow(` \u{1F7E1} Major: ${import_chalk5.default.bold(summary.majorIssues)}`)
|
|
1332
1545
|
);
|
|
1333
1546
|
}
|
|
1334
1547
|
if (summary.minorIssues > 0) {
|
|
1335
1548
|
console.log(
|
|
1336
|
-
|
|
1549
|
+
import_chalk5.default.blue(` \u{1F535} Minor: ${import_chalk5.default.bold(summary.minorIssues)}`)
|
|
1337
1550
|
);
|
|
1338
1551
|
}
|
|
1339
1552
|
console.log(
|
|
1340
|
-
|
|
1553
|
+
import_chalk5.default.green(
|
|
1341
1554
|
`
|
|
1342
|
-
\u{1F4A1} Potential savings: ${
|
|
1555
|
+
\u{1F4A1} Potential savings: ${import_chalk5.default.bold(summary.totalPotentialSavings.toLocaleString())} tokens
|
|
1343
1556
|
`
|
|
1344
1557
|
)
|
|
1345
1558
|
);
|
|
1346
1559
|
} else {
|
|
1347
|
-
console.log(
|
|
1560
|
+
console.log(import_chalk5.default.green("\u2705 No significant issues found!\n"));
|
|
1348
1561
|
}
|
|
1349
1562
|
if (summary.deepFiles.length > 0) {
|
|
1350
|
-
console.log(
|
|
1563
|
+
console.log(import_chalk5.default.bold("\u{1F4CF} Deep Import Chains:\n"));
|
|
1351
1564
|
console.log(
|
|
1352
|
-
|
|
1565
|
+
import_chalk5.default.gray(` Average depth: ${summary.avgImportDepth.toFixed(1)}`)
|
|
1353
1566
|
);
|
|
1354
1567
|
console.log(
|
|
1355
|
-
|
|
1568
|
+
import_chalk5.default.gray(` Maximum depth: ${summary.maxImportDepth}
|
|
1356
1569
|
`)
|
|
1357
1570
|
);
|
|
1358
1571
|
summary.deepFiles.slice(0, 10).forEach((item) => {
|
|
1359
1572
|
const fileName = item.file.split("/").slice(-2).join("/");
|
|
1360
1573
|
console.log(
|
|
1361
|
-
` ${
|
|
1574
|
+
` ${import_chalk5.default.cyan("\u2192")} ${import_chalk5.default.white(fileName)} ${import_chalk5.default.dim(`(depth: ${item.depth})`)}`
|
|
1362
1575
|
);
|
|
1363
1576
|
});
|
|
1364
1577
|
console.log();
|
|
1365
1578
|
}
|
|
1366
1579
|
if (summary.fragmentedModules.length > 0) {
|
|
1367
|
-
console.log(
|
|
1580
|
+
console.log(import_chalk5.default.bold("\u{1F9E9} Fragmented Modules:\n"));
|
|
1368
1581
|
console.log(
|
|
1369
|
-
|
|
1582
|
+
import_chalk5.default.gray(
|
|
1370
1583
|
` Average fragmentation: ${(summary.avgFragmentation * 100).toFixed(0)}%
|
|
1371
1584
|
`
|
|
1372
1585
|
)
|
|
1373
1586
|
);
|
|
1374
1587
|
summary.fragmentedModules.slice(0, 10).forEach((module2) => {
|
|
1375
1588
|
console.log(
|
|
1376
|
-
` ${
|
|
1589
|
+
` ${import_chalk5.default.yellow("\u25CF")} ${import_chalk5.default.white(module2.domain)} - ${import_chalk5.default.dim(`${module2.files.length} files, ${(module2.fragmentationScore * 100).toFixed(0)}% scattered`)}`
|
|
1377
1590
|
);
|
|
1378
1591
|
console.log(
|
|
1379
|
-
|
|
1592
|
+
import_chalk5.default.dim(
|
|
1380
1593
|
` Token cost: ${module2.totalTokens.toLocaleString()}, Cohesion: ${(module2.avgCohesion * 100).toFixed(0)}%`
|
|
1381
1594
|
)
|
|
1382
1595
|
);
|
|
@@ -1384,9 +1597,9 @@ async function contextAction(directory, options) {
|
|
|
1384
1597
|
console.log();
|
|
1385
1598
|
}
|
|
1386
1599
|
if (summary.lowCohesionFiles.length > 0) {
|
|
1387
|
-
console.log(
|
|
1600
|
+
console.log(import_chalk5.default.bold("\u{1F500} Low Cohesion Files:\n"));
|
|
1388
1601
|
console.log(
|
|
1389
|
-
|
|
1602
|
+
import_chalk5.default.gray(
|
|
1390
1603
|
` Average cohesion: ${(summary.avgCohesion * 100).toFixed(0)}%
|
|
1391
1604
|
`
|
|
1392
1605
|
)
|
|
@@ -1394,46 +1607,46 @@ async function contextAction(directory, options) {
|
|
|
1394
1607
|
summary.lowCohesionFiles.slice(0, 10).forEach((item) => {
|
|
1395
1608
|
const fileName = item.file.split("/").slice(-2).join("/");
|
|
1396
1609
|
const scorePercent = (item.score * 100).toFixed(0);
|
|
1397
|
-
const color = item.score < 0.4 ?
|
|
1610
|
+
const color = item.score < 0.4 ? import_chalk5.default.red : import_chalk5.default.yellow;
|
|
1398
1611
|
console.log(
|
|
1399
|
-
` ${color("\u25CB")} ${
|
|
1612
|
+
` ${color("\u25CB")} ${import_chalk5.default.white(fileName)} ${import_chalk5.default.dim(`(${scorePercent}% cohesion)`)}`
|
|
1400
1613
|
);
|
|
1401
1614
|
});
|
|
1402
1615
|
console.log();
|
|
1403
1616
|
}
|
|
1404
1617
|
if (summary.topExpensiveFiles.length > 0) {
|
|
1405
|
-
console.log(
|
|
1618
|
+
console.log(import_chalk5.default.bold("\u{1F4B8} Most Expensive Files (Context Budget):\n"));
|
|
1406
1619
|
summary.topExpensiveFiles.slice(0, 10).forEach((item) => {
|
|
1407
1620
|
const fileName = item.file.split("/").slice(-2).join("/");
|
|
1408
|
-
const severityColor = item.severity === "critical" ?
|
|
1621
|
+
const severityColor = item.severity === "critical" ? import_chalk5.default.red : item.severity === "major" ? import_chalk5.default.yellow : import_chalk5.default.blue;
|
|
1409
1622
|
console.log(
|
|
1410
|
-
` ${severityColor("\u25CF")} ${
|
|
1623
|
+
` ${severityColor("\u25CF")} ${import_chalk5.default.white(fileName)} ${import_chalk5.default.dim(`(${item.contextBudget.toLocaleString()} tokens)`)}`
|
|
1411
1624
|
);
|
|
1412
1625
|
});
|
|
1413
1626
|
console.log();
|
|
1414
1627
|
}
|
|
1415
1628
|
if (contextScore) {
|
|
1416
|
-
console.log(
|
|
1417
|
-
console.log(
|
|
1418
|
-
console.log(
|
|
1419
|
-
console.log((0,
|
|
1629
|
+
console.log(import_chalk5.default.cyan(divider));
|
|
1630
|
+
console.log(import_chalk5.default.bold.white(" AI READINESS SCORE (Context)"));
|
|
1631
|
+
console.log(import_chalk5.default.cyan(divider) + "\n");
|
|
1632
|
+
console.log((0, import_core5.formatToolScore)(contextScore));
|
|
1420
1633
|
console.log();
|
|
1421
1634
|
}
|
|
1422
1635
|
}
|
|
1423
1636
|
} catch (error) {
|
|
1424
|
-
(0,
|
|
1637
|
+
(0, import_core5.handleCLIError)(error, "Context analysis");
|
|
1425
1638
|
}
|
|
1426
1639
|
}
|
|
1427
1640
|
|
|
1428
1641
|
// src/commands/consistency.ts
|
|
1429
|
-
var
|
|
1430
|
-
var
|
|
1431
|
-
var
|
|
1432
|
-
var
|
|
1642
|
+
var import_chalk6 = __toESM(require("chalk"));
|
|
1643
|
+
var import_fs4 = require("fs");
|
|
1644
|
+
var import_path6 = require("path");
|
|
1645
|
+
var import_core6 = require("@aiready/core");
|
|
1433
1646
|
async function consistencyAction(directory, options) {
|
|
1434
|
-
console.log(
|
|
1647
|
+
console.log(import_chalk6.default.blue("\u{1F50D} Analyzing consistency...\n"));
|
|
1435
1648
|
const startTime = Date.now();
|
|
1436
|
-
const resolvedDir = (0,
|
|
1649
|
+
const resolvedDir = (0, import_path6.resolve)(process.cwd(), directory || ".");
|
|
1437
1650
|
try {
|
|
1438
1651
|
const defaults = {
|
|
1439
1652
|
checkNaming: true,
|
|
@@ -1446,7 +1659,7 @@ async function consistencyAction(directory, options) {
|
|
|
1446
1659
|
file: void 0
|
|
1447
1660
|
}
|
|
1448
1661
|
};
|
|
1449
|
-
const finalOptions = await (0,
|
|
1662
|
+
const finalOptions = await (0, import_core6.loadMergedConfig)(resolvedDir, defaults, {
|
|
1450
1663
|
checkNaming: options.naming !== false,
|
|
1451
1664
|
checkPatterns: options.patterns !== false,
|
|
1452
1665
|
minSeverity: options.minSeverity,
|
|
@@ -1455,7 +1668,7 @@ async function consistencyAction(directory, options) {
|
|
|
1455
1668
|
});
|
|
1456
1669
|
const { analyzeConsistency: analyzeConsistency2, calculateConsistencyScore } = await import("@aiready/consistency");
|
|
1457
1670
|
const report = await analyzeConsistency2(finalOptions);
|
|
1458
|
-
const elapsedTime = (0,
|
|
1671
|
+
const elapsedTime = (0, import_core6.getElapsedTime)(startTime);
|
|
1459
1672
|
let consistencyScore;
|
|
1460
1673
|
if (options.score) {
|
|
1461
1674
|
const issues = report.results?.flatMap((r) => r.issues) || [];
|
|
@@ -1475,41 +1688,41 @@ async function consistencyAction(directory, options) {
|
|
|
1475
1688
|
},
|
|
1476
1689
|
...consistencyScore && { scoring: consistencyScore }
|
|
1477
1690
|
};
|
|
1478
|
-
const outputPath = (0,
|
|
1691
|
+
const outputPath = (0, import_core6.resolveOutputPath)(
|
|
1479
1692
|
userOutputFile,
|
|
1480
1693
|
`aiready-report-${getReportTimestamp()}.json`,
|
|
1481
1694
|
resolvedDir
|
|
1482
1695
|
);
|
|
1483
|
-
(0,
|
|
1696
|
+
(0, import_core6.handleJSONOutput)(
|
|
1484
1697
|
outputData,
|
|
1485
1698
|
outputPath,
|
|
1486
1699
|
`\u2705 Results saved to ${outputPath}`
|
|
1487
1700
|
);
|
|
1488
1701
|
} else if (outputFormat === "markdown") {
|
|
1489
1702
|
const markdown = generateMarkdownReport(report, elapsedTime);
|
|
1490
|
-
const outputPath = (0,
|
|
1703
|
+
const outputPath = (0, import_core6.resolveOutputPath)(
|
|
1491
1704
|
userOutputFile,
|
|
1492
1705
|
`aiready-report-${getReportTimestamp()}.md`,
|
|
1493
1706
|
resolvedDir
|
|
1494
1707
|
);
|
|
1495
|
-
(0,
|
|
1496
|
-
console.log(
|
|
1708
|
+
(0, import_fs4.writeFileSync)(outputPath, markdown);
|
|
1709
|
+
console.log(import_chalk6.default.green(`\u2705 Report saved to ${outputPath}`));
|
|
1497
1710
|
} else {
|
|
1498
|
-
console.log(
|
|
1711
|
+
console.log(import_chalk6.default.bold("\n\u{1F4CA} Summary\n"));
|
|
1499
1712
|
console.log(
|
|
1500
|
-
`Files Analyzed: ${
|
|
1713
|
+
`Files Analyzed: ${import_chalk6.default.cyan(report.summary.filesAnalyzed)}`
|
|
1501
1714
|
);
|
|
1502
|
-
console.log(`Total Issues: ${
|
|
1503
|
-
console.log(` Naming: ${
|
|
1504
|
-
console.log(` Patterns: ${
|
|
1715
|
+
console.log(`Total Issues: ${import_chalk6.default.yellow(report.summary.totalIssues)}`);
|
|
1716
|
+
console.log(` Naming: ${import_chalk6.default.yellow(report.summary.namingIssues)}`);
|
|
1717
|
+
console.log(` Patterns: ${import_chalk6.default.yellow(report.summary.patternIssues)}`);
|
|
1505
1718
|
console.log(
|
|
1506
|
-
` Architecture: ${
|
|
1719
|
+
` Architecture: ${import_chalk6.default.yellow(report.summary.architectureIssues || 0)}`
|
|
1507
1720
|
);
|
|
1508
|
-
console.log(`Analysis Time: ${
|
|
1721
|
+
console.log(`Analysis Time: ${import_chalk6.default.gray(elapsedTime + "s")}
|
|
1509
1722
|
`);
|
|
1510
1723
|
if (report.summary.totalIssues === 0) {
|
|
1511
1724
|
console.log(
|
|
1512
|
-
|
|
1725
|
+
import_chalk6.default.green(
|
|
1513
1726
|
"\u2728 No consistency issues found! Your codebase is well-maintained.\n"
|
|
1514
1727
|
)
|
|
1515
1728
|
);
|
|
@@ -1521,20 +1734,20 @@ async function consistencyAction(directory, options) {
|
|
|
1521
1734
|
(r) => r.issues.some((i) => i.category === "patterns")
|
|
1522
1735
|
);
|
|
1523
1736
|
if (namingResults.length > 0) {
|
|
1524
|
-
console.log(
|
|
1737
|
+
console.log(import_chalk6.default.bold("\u{1F3F7}\uFE0F Naming Issues\n"));
|
|
1525
1738
|
let shown = 0;
|
|
1526
1739
|
for (const result of namingResults) {
|
|
1527
1740
|
if (shown >= 5) break;
|
|
1528
1741
|
for (const issue of result.issues) {
|
|
1529
1742
|
if (shown >= 5) break;
|
|
1530
|
-
const severityColor = issue.severity === "critical" ?
|
|
1743
|
+
const severityColor = issue.severity === "critical" ? import_chalk6.default.red : issue.severity === "major" ? import_chalk6.default.yellow : issue.severity === "minor" ? import_chalk6.default.blue : import_chalk6.default.gray;
|
|
1531
1744
|
console.log(
|
|
1532
|
-
`${severityColor(issue.severity.toUpperCase())} ${
|
|
1745
|
+
`${severityColor(issue.severity.toUpperCase())} ${import_chalk6.default.dim(`${issue.location.file}:${issue.location.line}`)}`
|
|
1533
1746
|
);
|
|
1534
1747
|
console.log(` ${issue.message}`);
|
|
1535
1748
|
if (issue.suggestion) {
|
|
1536
1749
|
console.log(
|
|
1537
|
-
` ${
|
|
1750
|
+
` ${import_chalk6.default.dim("\u2192")} ${import_chalk6.default.italic(issue.suggestion)}`
|
|
1538
1751
|
);
|
|
1539
1752
|
}
|
|
1540
1753
|
console.log();
|
|
@@ -1543,25 +1756,25 @@ async function consistencyAction(directory, options) {
|
|
|
1543
1756
|
}
|
|
1544
1757
|
const remaining = namingResults.reduce((sum, r) => sum + r.issues.length, 0) - shown;
|
|
1545
1758
|
if (remaining > 0) {
|
|
1546
|
-
console.log(
|
|
1759
|
+
console.log(import_chalk6.default.dim(` ... and ${remaining} more issues
|
|
1547
1760
|
`));
|
|
1548
1761
|
}
|
|
1549
1762
|
}
|
|
1550
1763
|
if (patternResults.length > 0) {
|
|
1551
|
-
console.log(
|
|
1764
|
+
console.log(import_chalk6.default.bold("\u{1F504} Pattern Issues\n"));
|
|
1552
1765
|
let shown = 0;
|
|
1553
1766
|
for (const result of patternResults) {
|
|
1554
1767
|
if (shown >= 5) break;
|
|
1555
1768
|
for (const issue of result.issues) {
|
|
1556
1769
|
if (shown >= 5) break;
|
|
1557
|
-
const severityColor = issue.severity === "critical" ?
|
|
1770
|
+
const severityColor = issue.severity === "critical" ? import_chalk6.default.red : issue.severity === "major" ? import_chalk6.default.yellow : issue.severity === "minor" ? import_chalk6.default.blue : import_chalk6.default.gray;
|
|
1558
1771
|
console.log(
|
|
1559
|
-
`${severityColor(issue.severity.toUpperCase())} ${
|
|
1772
|
+
`${severityColor(issue.severity.toUpperCase())} ${import_chalk6.default.dim(`${issue.location.file}:${issue.location.line}`)}`
|
|
1560
1773
|
);
|
|
1561
1774
|
console.log(` ${issue.message}`);
|
|
1562
1775
|
if (issue.suggestion) {
|
|
1563
1776
|
console.log(
|
|
1564
|
-
` ${
|
|
1777
|
+
` ${import_chalk6.default.dim("\u2192")} ${import_chalk6.default.italic(issue.suggestion)}`
|
|
1565
1778
|
);
|
|
1566
1779
|
}
|
|
1567
1780
|
console.log();
|
|
@@ -1570,12 +1783,12 @@ async function consistencyAction(directory, options) {
|
|
|
1570
1783
|
}
|
|
1571
1784
|
const remaining = patternResults.reduce((sum, r) => sum + r.issues.length, 0) - shown;
|
|
1572
1785
|
if (remaining > 0) {
|
|
1573
|
-
console.log(
|
|
1786
|
+
console.log(import_chalk6.default.dim(` ... and ${remaining} more issues
|
|
1574
1787
|
`));
|
|
1575
1788
|
}
|
|
1576
1789
|
}
|
|
1577
1790
|
if (report.recommendations.length > 0) {
|
|
1578
|
-
console.log(
|
|
1791
|
+
console.log(import_chalk6.default.bold("\u{1F4A1} Recommendations\n"));
|
|
1579
1792
|
report.recommendations.forEach((rec, i) => {
|
|
1580
1793
|
console.log(`${i + 1}. ${rec}`);
|
|
1581
1794
|
});
|
|
@@ -1583,38 +1796,38 @@ async function consistencyAction(directory, options) {
|
|
|
1583
1796
|
}
|
|
1584
1797
|
}
|
|
1585
1798
|
if (consistencyScore) {
|
|
1586
|
-
console.log(
|
|
1587
|
-
console.log((0,
|
|
1799
|
+
console.log(import_chalk6.default.bold("\n\u{1F4CA} AI Readiness Score (Consistency)\n"));
|
|
1800
|
+
console.log((0, import_core6.formatToolScore)(consistencyScore));
|
|
1588
1801
|
console.log();
|
|
1589
1802
|
}
|
|
1590
1803
|
}
|
|
1591
1804
|
} catch (error) {
|
|
1592
|
-
(0,
|
|
1805
|
+
(0, import_core6.handleCLIError)(error, "Consistency analysis");
|
|
1593
1806
|
}
|
|
1594
1807
|
}
|
|
1595
1808
|
|
|
1596
1809
|
// src/commands/visualize.ts
|
|
1597
|
-
var
|
|
1598
|
-
var
|
|
1599
|
-
var
|
|
1810
|
+
var import_chalk7 = __toESM(require("chalk"));
|
|
1811
|
+
var import_fs5 = require("fs");
|
|
1812
|
+
var import_path7 = require("path");
|
|
1600
1813
|
var import_child_process = require("child_process");
|
|
1601
|
-
var
|
|
1602
|
-
var
|
|
1814
|
+
var import_core7 = require("@aiready/core");
|
|
1815
|
+
var import_core8 = require("@aiready/core");
|
|
1603
1816
|
async function visualizeAction(directory, options) {
|
|
1604
1817
|
try {
|
|
1605
|
-
const dirPath = (0,
|
|
1606
|
-
let reportPath = options.report ? (0,
|
|
1607
|
-
if (!reportPath || !(0,
|
|
1818
|
+
const dirPath = (0, import_path7.resolve)(process.cwd(), directory || ".");
|
|
1819
|
+
let reportPath = options.report ? (0, import_path7.resolve)(dirPath, options.report) : null;
|
|
1820
|
+
if (!reportPath || !(0, import_fs5.existsSync)(reportPath)) {
|
|
1608
1821
|
const latestScan = findLatestScanReport(dirPath);
|
|
1609
1822
|
if (latestScan) {
|
|
1610
1823
|
reportPath = latestScan;
|
|
1611
1824
|
console.log(
|
|
1612
|
-
|
|
1825
|
+
import_chalk7.default.dim(`Found latest report: ${latestScan.split("/").pop()}`)
|
|
1613
1826
|
);
|
|
1614
1827
|
} else {
|
|
1615
|
-
console.error(
|
|
1828
|
+
console.error(import_chalk7.default.red("\u274C No AI readiness report found"));
|
|
1616
1829
|
console.log(
|
|
1617
|
-
|
|
1830
|
+
import_chalk7.default.dim(
|
|
1618
1831
|
`
|
|
1619
1832
|
Generate a report with:
|
|
1620
1833
|
aiready scan --output json
|
|
@@ -1626,13 +1839,13 @@ Or specify a custom report:
|
|
|
1626
1839
|
return;
|
|
1627
1840
|
}
|
|
1628
1841
|
}
|
|
1629
|
-
const raw = (0,
|
|
1842
|
+
const raw = (0, import_fs5.readFileSync)(reportPath, "utf8");
|
|
1630
1843
|
const report = JSON.parse(raw);
|
|
1631
|
-
const configPath = (0,
|
|
1844
|
+
const configPath = (0, import_path7.resolve)(dirPath, "aiready.json");
|
|
1632
1845
|
let graphConfig = { maxNodes: 400, maxEdges: 600 };
|
|
1633
|
-
if ((0,
|
|
1846
|
+
if ((0, import_fs5.existsSync)(configPath)) {
|
|
1634
1847
|
try {
|
|
1635
|
-
const rawConfig = JSON.parse((0,
|
|
1848
|
+
const rawConfig = JSON.parse((0, import_fs5.readFileSync)(configPath, "utf8"));
|
|
1636
1849
|
if (rawConfig.visualizer?.graph) {
|
|
1637
1850
|
graphConfig = {
|
|
1638
1851
|
maxNodes: rawConfig.visualizer.graph.maxNodes ?? graphConfig.maxNodes,
|
|
@@ -1652,16 +1865,16 @@ Or specify a custom report:
|
|
|
1652
1865
|
let devServerStarted = false;
|
|
1653
1866
|
if (useDevMode) {
|
|
1654
1867
|
try {
|
|
1655
|
-
const monorepoWebDir = (0,
|
|
1868
|
+
const monorepoWebDir = (0, import_path7.resolve)(dirPath, "packages/visualizer");
|
|
1656
1869
|
let webDir = "";
|
|
1657
1870
|
let visualizerAvailable = false;
|
|
1658
|
-
if ((0,
|
|
1871
|
+
if ((0, import_fs5.existsSync)(monorepoWebDir)) {
|
|
1659
1872
|
webDir = monorepoWebDir;
|
|
1660
1873
|
visualizerAvailable = true;
|
|
1661
1874
|
} else {
|
|
1662
1875
|
const nodemodulesLocations = [
|
|
1663
|
-
(0,
|
|
1664
|
-
(0,
|
|
1876
|
+
(0, import_path7.resolve)(dirPath, "node_modules", "@aiready", "visualizer"),
|
|
1877
|
+
(0, import_path7.resolve)(
|
|
1665
1878
|
process.cwd(),
|
|
1666
1879
|
"node_modules",
|
|
1667
1880
|
"@aiready",
|
|
@@ -1671,14 +1884,14 @@ Or specify a custom report:
|
|
|
1671
1884
|
let currentDir = dirPath;
|
|
1672
1885
|
while (currentDir !== "/" && currentDir !== ".") {
|
|
1673
1886
|
nodemodulesLocations.push(
|
|
1674
|
-
(0,
|
|
1887
|
+
(0, import_path7.resolve)(currentDir, "node_modules", "@aiready", "visualizer")
|
|
1675
1888
|
);
|
|
1676
|
-
const parent = (0,
|
|
1889
|
+
const parent = (0, import_path7.resolve)(currentDir, "..");
|
|
1677
1890
|
if (parent === currentDir) break;
|
|
1678
1891
|
currentDir = parent;
|
|
1679
1892
|
}
|
|
1680
1893
|
for (const location of nodemodulesLocations) {
|
|
1681
|
-
if ((0,
|
|
1894
|
+
if ((0, import_fs5.existsSync)(location) && (0, import_fs5.existsSync)((0, import_path7.resolve)(location, "package.json"))) {
|
|
1682
1895
|
webDir = location;
|
|
1683
1896
|
visualizerAvailable = true;
|
|
1684
1897
|
break;
|
|
@@ -1687,21 +1900,21 @@ Or specify a custom report:
|
|
|
1687
1900
|
if (!visualizerAvailable) {
|
|
1688
1901
|
try {
|
|
1689
1902
|
const vizPkgPath = require.resolve("@aiready/visualizer/package.json");
|
|
1690
|
-
webDir = (0,
|
|
1903
|
+
webDir = (0, import_path7.resolve)(vizPkgPath, "..");
|
|
1691
1904
|
visualizerAvailable = true;
|
|
1692
1905
|
} catch (err) {
|
|
1693
1906
|
void err;
|
|
1694
1907
|
}
|
|
1695
1908
|
}
|
|
1696
1909
|
}
|
|
1697
|
-
const webViteConfigExists = webDir && (0,
|
|
1910
|
+
const webViteConfigExists = webDir && (0, import_fs5.existsSync)((0, import_path7.resolve)(webDir, "web", "vite.config.ts"));
|
|
1698
1911
|
if (visualizerAvailable && webViteConfigExists) {
|
|
1699
1912
|
const spawnCwd = webDir;
|
|
1700
1913
|
const { watch } = await import("fs");
|
|
1701
1914
|
const copyReportToViz = () => {
|
|
1702
1915
|
try {
|
|
1703
|
-
const destPath = (0,
|
|
1704
|
-
(0,
|
|
1916
|
+
const destPath = (0, import_path7.resolve)(spawnCwd, "web", "report-data.json");
|
|
1917
|
+
(0, import_fs5.copyFileSync)(reportPath, destPath);
|
|
1705
1918
|
console.log(`\u{1F4CB} Report synced to ${destPath}`);
|
|
1706
1919
|
} catch (e) {
|
|
1707
1920
|
console.error("Failed to sync report:", e);
|
|
@@ -1744,29 +1957,29 @@ Or specify a custom report:
|
|
|
1744
1957
|
return;
|
|
1745
1958
|
} else {
|
|
1746
1959
|
console.log(
|
|
1747
|
-
|
|
1960
|
+
import_chalk7.default.yellow(
|
|
1748
1961
|
"\u26A0\uFE0F Dev server not available (requires local @aiready/visualizer with web assets)."
|
|
1749
1962
|
)
|
|
1750
1963
|
);
|
|
1751
1964
|
console.log(
|
|
1752
|
-
|
|
1965
|
+
import_chalk7.default.cyan(" Falling back to static HTML generation...\n")
|
|
1753
1966
|
);
|
|
1754
1967
|
useDevMode = false;
|
|
1755
1968
|
}
|
|
1756
1969
|
} catch (err) {
|
|
1757
1970
|
console.error("Failed to start dev server:", err);
|
|
1758
1971
|
console.log(
|
|
1759
|
-
|
|
1972
|
+
import_chalk7.default.cyan(" Falling back to static HTML generation...\n")
|
|
1760
1973
|
);
|
|
1761
1974
|
useDevMode = false;
|
|
1762
1975
|
}
|
|
1763
1976
|
}
|
|
1764
1977
|
console.log("Generating HTML...");
|
|
1765
|
-
const html = (0,
|
|
1978
|
+
const html = (0, import_core8.generateHTML)(graph);
|
|
1766
1979
|
const defaultOutput = "visualization.html";
|
|
1767
|
-
const outPath = (0,
|
|
1768
|
-
(0,
|
|
1769
|
-
console.log(
|
|
1980
|
+
const outPath = (0, import_path7.resolve)(dirPath, options.output || defaultOutput);
|
|
1981
|
+
(0, import_fs5.writeFileSync)(outPath, html, "utf8");
|
|
1982
|
+
console.log(import_chalk7.default.green(`\u2705 Visualization written to: ${outPath}`));
|
|
1770
1983
|
if (options.open || options.serve) {
|
|
1771
1984
|
const opener = process.platform === "darwin" ? "open" : process.platform === "win32" ? "start" : "xdg-open";
|
|
1772
1985
|
if (options.serve) {
|
|
@@ -1796,7 +2009,7 @@ Or specify a custom report:
|
|
|
1796
2009
|
server.listen(port, () => {
|
|
1797
2010
|
const addr = `http://localhost:${port}/`;
|
|
1798
2011
|
console.log(
|
|
1799
|
-
|
|
2012
|
+
import_chalk7.default.cyan(`\u{1F310} Local visualization server running at ${addr}`)
|
|
1800
2013
|
);
|
|
1801
2014
|
(0, import_child_process.spawn)(opener, [`"${addr}"`], { shell: true });
|
|
1802
2015
|
});
|
|
@@ -1812,7 +2025,7 @@ Or specify a custom report:
|
|
|
1812
2025
|
}
|
|
1813
2026
|
}
|
|
1814
2027
|
} catch (err) {
|
|
1815
|
-
(0,
|
|
2028
|
+
(0, import_core7.handleCLIError)(err, "Visualization");
|
|
1816
2029
|
}
|
|
1817
2030
|
}
|
|
1818
2031
|
var visualizeHelpText = `
|
|
@@ -1843,16 +2056,16 @@ NOTES:
|
|
|
1843
2056
|
`;
|
|
1844
2057
|
|
|
1845
2058
|
// src/commands/ai-signal-clarity.ts
|
|
1846
|
-
var
|
|
1847
|
-
var
|
|
2059
|
+
var import_chalk8 = __toESM(require("chalk"));
|
|
2060
|
+
var import_core9 = require("@aiready/core");
|
|
1848
2061
|
|
|
1849
2062
|
// src/commands/agent-grounding.ts
|
|
1850
|
-
var
|
|
1851
|
-
var
|
|
2063
|
+
var import_chalk9 = __toESM(require("chalk"));
|
|
2064
|
+
var import_core10 = require("@aiready/core");
|
|
1852
2065
|
|
|
1853
2066
|
// src/commands/testability.ts
|
|
1854
|
-
var
|
|
1855
|
-
var
|
|
2067
|
+
var import_chalk10 = __toESM(require("chalk"));
|
|
2068
|
+
var import_core11 = require("@aiready/core");
|
|
1856
2069
|
|
|
1857
2070
|
// src/commands/change-amplification.ts
|
|
1858
2071
|
var import_cli = require("@aiready/change-amplification/dist/cli.js");
|
|
@@ -1861,10 +2074,10 @@ var import_cli = require("@aiready/change-amplification/dist/cli.js");
|
|
|
1861
2074
|
var import_meta = {};
|
|
1862
2075
|
var getDirname = () => {
|
|
1863
2076
|
if (typeof __dirname !== "undefined") return __dirname;
|
|
1864
|
-
return (0,
|
|
2077
|
+
return (0, import_path8.dirname)((0, import_url.fileURLToPath)(import_meta.url));
|
|
1865
2078
|
};
|
|
1866
2079
|
var packageJson = JSON.parse(
|
|
1867
|
-
(0,
|
|
2080
|
+
(0, import_fs6.readFileSync)((0, import_path8.join)(getDirname(), "../package.json"), "utf8")
|
|
1868
2081
|
);
|
|
1869
2082
|
var program = new import_commander.Command();
|
|
1870
2083
|
program.name("aiready").description("AIReady - Assess and improve AI-readiness of codebases").version(packageJson.version).addHelpText(
|
|
@@ -1927,7 +2140,7 @@ program.command("scan").description(
|
|
|
1927
2140
|
"--fail-on <level>",
|
|
1928
2141
|
"Fail on issues: critical, major, any",
|
|
1929
2142
|
"critical"
|
|
1930
|
-
).addHelpText("after", scanHelpText).action(async (directory, options) => {
|
|
2143
|
+
).option("--api-key <key>", "Platform API key for automatic upload").option("--upload", "Automatically upload results to the platform").option("--server <url>", "Custom platform URL").addHelpText("after", scanHelpText).action(async (directory, options) => {
|
|
1931
2144
|
await scanAction(directory, options);
|
|
1932
2145
|
});
|
|
1933
2146
|
program.command("patterns").description("Detect duplicate code patterns that confuse AI models").argument("[directory]", "Directory to analyze", ".").option("-s, --similarity <number>", "Minimum similarity score (0-1)", "0.40").option("-l, --min-lines <number>", "Minimum lines to consider", "5").option(
|
|
@@ -2008,4 +2221,7 @@ program.command("visualize").description("Generate interactive visualization fro
|
|
|
2008
2221
|
program.command("change-amplification").description("Analyze graph metrics for change amplification").argument("[directory]", "Directory to analyze", ".").option("--include <patterns>", "File patterns to include (comma-separated)").option("--exclude <patterns>", "File patterns to exclude (comma-separated)").option("-o, --output <format>", "Output format: console, json", "console").option("--output-file <path>", "Output file path (for json)").action(async (directory, options) => {
|
|
2009
2222
|
await (0, import_cli.changeAmplificationAction)(directory, options);
|
|
2010
2223
|
});
|
|
2224
|
+
program.command("upload").description("Upload an AIReady report JSON to the platform").argument("<file>", "Report JSON file to upload").option("--api-key <key>", "Platform API key").option("--repo-id <id>", "Platform repository ID (optional)").option("--server <url>", "Custom platform URL").addHelpText("after", uploadHelpText).action(async (file, options) => {
|
|
2225
|
+
await uploadAction(file, options);
|
|
2226
|
+
});
|
|
2011
2227
|
program.parse();
|