@aiready/core 0.23.19 → 0.23.20
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/dist/chunk-2Y6WZCES.mjs +859 -0
- package/dist/chunk-FMNCV4CC.mjs +859 -0
- package/dist/chunk-REU6OUBT.mjs +859 -0
- package/dist/chunk-SQHS6PFL.mjs +859 -0
- package/dist/chunk-ST75O5C5.mjs +859 -0
- package/dist/client-CYz0qxGB.d.mts +1217 -0
- package/dist/client-CYz0qxGB.d.ts +1217 -0
- package/dist/client-jGuH6TAG.d.mts +1244 -0
- package/dist/client-jGuH6TAG.d.ts +1244 -0
- package/dist/client-pYldIAg2.d.mts +1209 -0
- package/dist/client-pYldIAg2.d.ts +1209 -0
- package/dist/client.d.mts +1 -1
- package/dist/client.d.ts +1 -1
- package/dist/client.js +16 -24
- package/dist/client.mjs +1 -3
- package/dist/index.d.mts +73 -4
- package/dist/index.d.ts +73 -4
- package/dist/index.js +194 -30
- package/dist/index.mjs +133 -9
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -91,6 +91,7 @@ __export(index_exports, {
|
|
|
91
91
|
calculateConceptCohesion: () => calculateConceptCohesion,
|
|
92
92
|
calculateDebtInterest: () => calculateDebtInterest,
|
|
93
93
|
calculateDependencyHealth: () => calculateDependencyHealth,
|
|
94
|
+
calculateDetailedTokenROI: () => calculateDetailedTokenROI,
|
|
94
95
|
calculateDocDrift: () => calculateDocDrift,
|
|
95
96
|
calculateExtendedFutureProofScore: () => calculateExtendedFutureProofScore,
|
|
96
97
|
calculateFutureProofScore: () => calculateFutureProofScore,
|
|
@@ -119,7 +120,12 @@ __export(index_exports, {
|
|
|
119
120
|
formatHours: () => formatHours,
|
|
120
121
|
formatScore: () => formatScore,
|
|
121
122
|
formatToolScore: () => formatToolScore,
|
|
123
|
+
generateCompleteReport: () => generateCompleteReport,
|
|
122
124
|
generateHTML: () => generateHTML,
|
|
125
|
+
generateReportFooter: () => generateReportFooter,
|
|
126
|
+
generateReportHead: () => generateReportHead,
|
|
127
|
+
generateStatCards: () => generateStatCards,
|
|
128
|
+
generateTable: () => generateTable,
|
|
123
129
|
generateValueChain: () => generateValueChain,
|
|
124
130
|
getElapsedTime: () => getElapsedTime,
|
|
125
131
|
getFileCommitTimestamps: () => getFileCommitTimestamps,
|
|
@@ -128,9 +134,12 @@ __export(index_exports, {
|
|
|
128
134
|
getLineRangeLastModifiedCached: () => getLineRangeLastModifiedCached,
|
|
129
135
|
getModelPreset: () => getModelPreset,
|
|
130
136
|
getParser: () => getParser,
|
|
137
|
+
getPriorityIcon: () => getPriorityIcon,
|
|
131
138
|
getProjectSizeTier: () => getProjectSizeTier,
|
|
132
139
|
getRating: () => getRating,
|
|
133
140
|
getRatingDisplay: () => getRatingDisplay,
|
|
141
|
+
getRatingEmoji: () => getRatingEmoji,
|
|
142
|
+
getRatingLabel: () => getRatingLabel,
|
|
134
143
|
getRatingSlug: () => getRatingSlug,
|
|
135
144
|
getRatingWithContext: () => getRatingWithContext,
|
|
136
145
|
getRecommendedThreshold: () => getRecommendedThreshold,
|
|
@@ -143,6 +152,7 @@ __export(index_exports, {
|
|
|
143
152
|
getSeverityLevel: () => getSeverityLevel,
|
|
144
153
|
getSeverityValue: () => getSeverityValue,
|
|
145
154
|
getSupportedLanguages: () => getSupportedLanguages,
|
|
155
|
+
getToolEmoji: () => getToolEmoji,
|
|
146
156
|
getToolWeight: () => getToolWeight,
|
|
147
157
|
getWasmPath: () => getWasmPath,
|
|
148
158
|
groupIssuesByFile: () => groupIssuesByFile,
|
|
@@ -172,7 +182,8 @@ __export(index_exports, {
|
|
|
172
182
|
setupParser: () => setupParser,
|
|
173
183
|
severityToAnnotationLevel: () => severityToAnnotationLevel,
|
|
174
184
|
validateSpokeOutput: () => validateSpokeOutput,
|
|
175
|
-
validateWithSchema: () => validateWithSchema
|
|
185
|
+
validateWithSchema: () => validateWithSchema,
|
|
186
|
+
wrapInCard: () => wrapInCard
|
|
176
187
|
});
|
|
177
188
|
module.exports = __toCommonJS(index_exports);
|
|
178
189
|
|
|
@@ -3568,13 +3579,84 @@ function generateHTML(graph) {
|
|
|
3568
3579
|
</html>`;
|
|
3569
3580
|
}
|
|
3570
3581
|
|
|
3571
|
-
// src/
|
|
3572
|
-
|
|
3573
|
-
|
|
3574
|
-
|
|
3575
|
-
|
|
3576
|
-
|
|
3577
|
-
|
|
3582
|
+
// src/utils/html-report-builder.ts
|
|
3583
|
+
function generateReportHead(title) {
|
|
3584
|
+
return `<!DOCTYPE html>
|
|
3585
|
+
<html lang="en">
|
|
3586
|
+
<head>
|
|
3587
|
+
<meta charset="UTF-8">
|
|
3588
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
3589
|
+
<title>${title}</title>
|
|
3590
|
+
<style>
|
|
3591
|
+
body { font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, 'Open Sans', 'Helvetica Neue', sans-serif; line-height: 1.6; color: #333; max-width: 1200px; margin: 0 auto; padding: 2rem; background-color: #f9f9f9; }
|
|
3592
|
+
h1, h2, h3 { color: #1a1a1a; border-bottom: 2px solid #eaeaea; padding-bottom: 0.5rem; }
|
|
3593
|
+
.card { background: white; padding: 1.5rem; border-radius: 8px; box-shadow: 0 2px 4px rgba(0,0,0,0.05); margin-bottom: 2rem; border: 1px solid #eaeaea; }
|
|
3594
|
+
.stats { display: grid; grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)); gap: 1rem; margin-bottom: 2rem; }
|
|
3595
|
+
.stat-card { background: #fff; padding: 1rem; border-radius: 6px; text-align: center; border: 1px solid #eaeaea; }
|
|
3596
|
+
.stat-value { font-size: 1.8rem; font-weight: bold; color: #2563eb; }
|
|
3597
|
+
.stat-label { font-size: 0.875rem; color: #666; text-transform: uppercase; }
|
|
3598
|
+
table { width: 100%; border-collapse: collapse; margin-top: 1rem; background: white; border-radius: 4px; overflow: hidden; }
|
|
3599
|
+
th, td { text-align: left; padding: 0.875rem 1rem; border-bottom: 1px solid #eaeaea; }
|
|
3600
|
+
th { background-color: #f8fafc; font-weight: 600; color: #475569; }
|
|
3601
|
+
tr:last-child td { border-bottom: none; }
|
|
3602
|
+
.critical { color: #dc2626; font-weight: bold; }
|
|
3603
|
+
.major { color: #ea580c; font-weight: bold; }
|
|
3604
|
+
.minor { color: #2563eb; }
|
|
3605
|
+
code { background: #f1f5f9; padding: 0.2rem 0.4rem; border-radius: 4px; font-size: 0.875rem; color: #334155; }
|
|
3606
|
+
.footer { margin-top: 4rem; text-align: center; color: #94a3b8; font-size: 0.875rem; }
|
|
3607
|
+
</style>
|
|
3608
|
+
</head>`;
|
|
3609
|
+
}
|
|
3610
|
+
function generateStatCards(cards) {
|
|
3611
|
+
const cardsHtml = cards.map(
|
|
3612
|
+
(card) => `
|
|
3613
|
+
<div class="stat-card">
|
|
3614
|
+
<div class="stat-value"${card.color ? ` style="color: ${card.color}"` : ""}>${card.value}</div>
|
|
3615
|
+
<div class="stat-label">${card.label}</div>
|
|
3616
|
+
</div>`
|
|
3617
|
+
).join("");
|
|
3618
|
+
return `<div class="stats">${cardsHtml}</div>`;
|
|
3619
|
+
}
|
|
3620
|
+
function generateTable(config) {
|
|
3621
|
+
const headersHtml = config.headers.map((h) => `<th>${h}</th>`).join("");
|
|
3622
|
+
const rowsHtml = config.rows.map((row) => `<tr>${row.map((cell) => `<td>${cell}</td>`).join("")}</tr>`).join("");
|
|
3623
|
+
return `<table>
|
|
3624
|
+
<thead><tr>${headersHtml}</tr></thead>
|
|
3625
|
+
<tbody>${rowsHtml}</tbody>
|
|
3626
|
+
</table>`;
|
|
3627
|
+
}
|
|
3628
|
+
function generateReportFooter(options) {
|
|
3629
|
+
const versionText = options.version ? ` v${options.version}` : "";
|
|
3630
|
+
const links = [];
|
|
3631
|
+
if (options.packageUrl) {
|
|
3632
|
+
links.push(`<a href="${options.packageUrl}">Star us on GitHub</a>`);
|
|
3633
|
+
}
|
|
3634
|
+
if (options.bugUrl) {
|
|
3635
|
+
links.push(`<a href="${options.bugUrl}">Report it here</a>`);
|
|
3636
|
+
}
|
|
3637
|
+
const linksHtml = links.length ? links.map((l) => `<p>Like AIReady? ${l}</p>`).join("\n ") : "";
|
|
3638
|
+
return `<div class="footer">
|
|
3639
|
+
<p>Generated by <strong>@aiready/${options.packageName}</strong>${versionText}</p>
|
|
3640
|
+
${linksHtml}
|
|
3641
|
+
</div>`;
|
|
3642
|
+
}
|
|
3643
|
+
function wrapInCard(content, title) {
|
|
3644
|
+
const titleHtml = title ? `<h2>${title}</h2>` : "";
|
|
3645
|
+
return `<div class="card">
|
|
3646
|
+
${titleHtml}
|
|
3647
|
+
${content}
|
|
3648
|
+
</div>`;
|
|
3649
|
+
}
|
|
3650
|
+
function generateCompleteReport(options, bodyContent) {
|
|
3651
|
+
return `${generateReportHead(options.title)}
|
|
3652
|
+
<body>
|
|
3653
|
+
${bodyContent}
|
|
3654
|
+
${generateReportFooter(options)}
|
|
3655
|
+
</body>
|
|
3656
|
+
</html>`;
|
|
3657
|
+
}
|
|
3658
|
+
|
|
3659
|
+
// src/utils/rating-helpers.ts
|
|
3578
3660
|
var ReadinessRating = /* @__PURE__ */ ((ReadinessRating2) => {
|
|
3579
3661
|
ReadinessRating2["Excellent"] = "Excellent";
|
|
3580
3662
|
ReadinessRating2["Good"] = "Good";
|
|
@@ -3583,6 +3665,59 @@ var ReadinessRating = /* @__PURE__ */ ((ReadinessRating2) => {
|
|
|
3583
3665
|
ReadinessRating2["Critical"] = "Critical";
|
|
3584
3666
|
return ReadinessRating2;
|
|
3585
3667
|
})(ReadinessRating || {});
|
|
3668
|
+
function getRatingLabel(score) {
|
|
3669
|
+
if (score >= 90) return "Excellent";
|
|
3670
|
+
if (score >= 75) return "Good";
|
|
3671
|
+
if (score >= 60) return "Fair";
|
|
3672
|
+
if (score >= 40) return "Needs Work";
|
|
3673
|
+
return "Critical";
|
|
3674
|
+
}
|
|
3675
|
+
function getRatingSlug(score) {
|
|
3676
|
+
if (score >= 90) return "excellent";
|
|
3677
|
+
if (score >= 75) return "good";
|
|
3678
|
+
if (score >= 60) return "fair";
|
|
3679
|
+
if (score >= 40) return "needs-work";
|
|
3680
|
+
return "critical";
|
|
3681
|
+
}
|
|
3682
|
+
function getRatingEmoji(score) {
|
|
3683
|
+
if (score >= 90) return "\u2705";
|
|
3684
|
+
if (score >= 75) return "\u{1F44D}";
|
|
3685
|
+
if (score >= 60) return "\u{1F44C}";
|
|
3686
|
+
if (score >= 40) return "\u{1F528}";
|
|
3687
|
+
return "\u{1F6A8}";
|
|
3688
|
+
}
|
|
3689
|
+
function getToolEmoji(score) {
|
|
3690
|
+
return getRatingEmoji(score);
|
|
3691
|
+
}
|
|
3692
|
+
function getPriorityIcon(priority) {
|
|
3693
|
+
switch (priority) {
|
|
3694
|
+
case "critical":
|
|
3695
|
+
return "\u{1F534}";
|
|
3696
|
+
case "high":
|
|
3697
|
+
return "\u{1F7E0}";
|
|
3698
|
+
case "medium":
|
|
3699
|
+
return "\u{1F7E1}";
|
|
3700
|
+
case "low":
|
|
3701
|
+
return "\u{1F535}";
|
|
3702
|
+
default:
|
|
3703
|
+
return "\u26AA";
|
|
3704
|
+
}
|
|
3705
|
+
}
|
|
3706
|
+
function getRating(score) {
|
|
3707
|
+
if (score >= 90) return "Excellent" /* Excellent */;
|
|
3708
|
+
if (score >= 75) return "Good" /* Good */;
|
|
3709
|
+
if (score >= 60) return "Fair" /* Fair */;
|
|
3710
|
+
if (score >= 40) return "Needs Work" /* NeedsWork */;
|
|
3711
|
+
return "Critical" /* Critical */;
|
|
3712
|
+
}
|
|
3713
|
+
|
|
3714
|
+
// src/scoring.ts
|
|
3715
|
+
var RecommendationPriority = /* @__PURE__ */ ((RecommendationPriority2) => {
|
|
3716
|
+
RecommendationPriority2["High"] = "high";
|
|
3717
|
+
RecommendationPriority2["Medium"] = "medium";
|
|
3718
|
+
RecommendationPriority2["Low"] = "low";
|
|
3719
|
+
return RecommendationPriority2;
|
|
3720
|
+
})(RecommendationPriority || {});
|
|
3586
3721
|
var DEFAULT_TOOL_WEIGHTS = {
|
|
3587
3722
|
["pattern-detect" /* PatternDetect */]: 22,
|
|
3588
3723
|
["context-analyzer" /* ContextAnalyzer */]: 19,
|
|
@@ -3761,20 +3896,6 @@ function calculateOverallScore(toolOutputs, config, cliWeights) {
|
|
|
3761
3896
|
}
|
|
3762
3897
|
};
|
|
3763
3898
|
}
|
|
3764
|
-
function getRating(score) {
|
|
3765
|
-
if (score >= 90) return "Excellent" /* Excellent */;
|
|
3766
|
-
if (score >= 75) return "Good" /* Good */;
|
|
3767
|
-
if (score >= 60) return "Fair" /* Fair */;
|
|
3768
|
-
if (score >= 40) return "Needs Work" /* NeedsWork */;
|
|
3769
|
-
return "Critical" /* Critical */;
|
|
3770
|
-
}
|
|
3771
|
-
function getRatingSlug(score) {
|
|
3772
|
-
if (score >= 90) return "excellent";
|
|
3773
|
-
if (score >= 75) return "good";
|
|
3774
|
-
if (score >= 60) return "fair";
|
|
3775
|
-
if (score >= 40) return "needs-work";
|
|
3776
|
-
return "critical";
|
|
3777
|
-
}
|
|
3778
3899
|
function getRatingWithContext(score, fileCount, modelTier = "standard") {
|
|
3779
3900
|
const threshold = getRecommendedThreshold(fileCount, modelTier);
|
|
3780
3901
|
const normalized = score - threshold + 70;
|
|
@@ -3897,20 +4018,52 @@ var DEFAULT_COST_CONFIG = {
|
|
|
3897
4018
|
developerCount: 5,
|
|
3898
4019
|
daysPerMonth: 30
|
|
3899
4020
|
};
|
|
3900
|
-
function calculateMonthlyCost(tokenWaste, config = {}) {
|
|
3901
|
-
const
|
|
4021
|
+
function calculateMonthlyCost(tokenWaste, config = {}, options) {
|
|
4022
|
+
const baseMultiplier = tokenWaste > 5e4 ? 5 : tokenWaste > 1e4 ? 3.5 : 2.5;
|
|
4023
|
+
const contextMultiplier = options?.avgContextBudget ? options.avgContextBudget / Math.max(1, tokenWaste) : baseMultiplier;
|
|
4024
|
+
const fragRatio = options?.fragmentationScore ?? 0.3;
|
|
4025
|
+
const dupRatio = 1 - fragRatio;
|
|
3902
4026
|
const budget = calculateTokenBudget({
|
|
3903
|
-
totalContextTokens: tokenWaste *
|
|
4027
|
+
totalContextTokens: tokenWaste * contextMultiplier,
|
|
3904
4028
|
wastedTokens: {
|
|
3905
|
-
duplication: tokenWaste *
|
|
3906
|
-
fragmentation: tokenWaste *
|
|
4029
|
+
duplication: tokenWaste * dupRatio * (options?.potentialSavings ? 1.2 : 1),
|
|
4030
|
+
fragmentation: tokenWaste * fragRatio,
|
|
3907
4031
|
chattiness: 0.1 * tokenWaste
|
|
3908
|
-
// Added baseline chattiness
|
|
3909
4032
|
}
|
|
3910
4033
|
});
|
|
3911
|
-
const preset = getModelPreset("
|
|
4034
|
+
const preset = getModelPreset("claude-3.5-sonnet");
|
|
3912
4035
|
return estimateCostFromBudget(budget, preset, config);
|
|
3913
4036
|
}
|
|
4037
|
+
function calculateDetailedTokenROI(params) {
|
|
4038
|
+
const {
|
|
4039
|
+
totalTokens,
|
|
4040
|
+
avgContextBudget,
|
|
4041
|
+
potentialSavings,
|
|
4042
|
+
fragmentationScore,
|
|
4043
|
+
developerCount,
|
|
4044
|
+
queriesPerDevPerDay = 60
|
|
4045
|
+
} = params;
|
|
4046
|
+
const budget = calculateTokenBudget({
|
|
4047
|
+
totalContextTokens: avgContextBudget,
|
|
4048
|
+
wastedTokens: {
|
|
4049
|
+
duplication: potentialSavings * 0.8,
|
|
4050
|
+
// 80% of potential savings are duplication-based
|
|
4051
|
+
fragmentation: totalTokens * fragmentationScore * 0.5,
|
|
4052
|
+
// fragmentation impact
|
|
4053
|
+
chattiness: totalTokens * 0.1
|
|
4054
|
+
}
|
|
4055
|
+
});
|
|
4056
|
+
const model = getModelPreset("claude-3.5-sonnet");
|
|
4057
|
+
const cost = estimateCostFromBudget(budget, model, {
|
|
4058
|
+
developerCount,
|
|
4059
|
+
queriesPerDevPerDay
|
|
4060
|
+
});
|
|
4061
|
+
return {
|
|
4062
|
+
monthlySavings: Math.round(cost.total),
|
|
4063
|
+
contextTaxPerDev: Math.round(cost.total / (developerCount || 1) * 100) / 100,
|
|
4064
|
+
efficiencyGain: Math.round(budget.efficiencyRatio * 100) / 100
|
|
4065
|
+
};
|
|
4066
|
+
}
|
|
3914
4067
|
function calculateTokenBudget(params) {
|
|
3915
4068
|
const { totalContextTokens, wastedTokens } = params;
|
|
3916
4069
|
const estimatedResponseTokens = params.estimatedResponseTokens ?? totalContextTokens * 0.2;
|
|
@@ -5438,6 +5591,7 @@ function emitIssuesAsAnnotations(issues) {
|
|
|
5438
5591
|
calculateConceptCohesion,
|
|
5439
5592
|
calculateDebtInterest,
|
|
5440
5593
|
calculateDependencyHealth,
|
|
5594
|
+
calculateDetailedTokenROI,
|
|
5441
5595
|
calculateDocDrift,
|
|
5442
5596
|
calculateExtendedFutureProofScore,
|
|
5443
5597
|
calculateFutureProofScore,
|
|
@@ -5466,7 +5620,12 @@ function emitIssuesAsAnnotations(issues) {
|
|
|
5466
5620
|
formatHours,
|
|
5467
5621
|
formatScore,
|
|
5468
5622
|
formatToolScore,
|
|
5623
|
+
generateCompleteReport,
|
|
5469
5624
|
generateHTML,
|
|
5625
|
+
generateReportFooter,
|
|
5626
|
+
generateReportHead,
|
|
5627
|
+
generateStatCards,
|
|
5628
|
+
generateTable,
|
|
5470
5629
|
generateValueChain,
|
|
5471
5630
|
getElapsedTime,
|
|
5472
5631
|
getFileCommitTimestamps,
|
|
@@ -5475,9 +5634,12 @@ function emitIssuesAsAnnotations(issues) {
|
|
|
5475
5634
|
getLineRangeLastModifiedCached,
|
|
5476
5635
|
getModelPreset,
|
|
5477
5636
|
getParser,
|
|
5637
|
+
getPriorityIcon,
|
|
5478
5638
|
getProjectSizeTier,
|
|
5479
5639
|
getRating,
|
|
5480
5640
|
getRatingDisplay,
|
|
5641
|
+
getRatingEmoji,
|
|
5642
|
+
getRatingLabel,
|
|
5481
5643
|
getRatingSlug,
|
|
5482
5644
|
getRatingWithContext,
|
|
5483
5645
|
getRecommendedThreshold,
|
|
@@ -5490,6 +5652,7 @@ function emitIssuesAsAnnotations(issues) {
|
|
|
5490
5652
|
getSeverityLevel,
|
|
5491
5653
|
getSeverityValue,
|
|
5492
5654
|
getSupportedLanguages,
|
|
5655
|
+
getToolEmoji,
|
|
5493
5656
|
getToolWeight,
|
|
5494
5657
|
getWasmPath,
|
|
5495
5658
|
groupIssuesByFile,
|
|
@@ -5519,5 +5682,6 @@ function emitIssuesAsAnnotations(issues) {
|
|
|
5519
5682
|
setupParser,
|
|
5520
5683
|
severityToAnnotationLevel,
|
|
5521
5684
|
validateSpokeOutput,
|
|
5522
|
-
validateWithSchema
|
|
5685
|
+
validateWithSchema,
|
|
5686
|
+
wrapInCard
|
|
5523
5687
|
});
|
package/dist/index.mjs
CHANGED
|
@@ -41,16 +41,20 @@ import {
|
|
|
41
41
|
formatScore,
|
|
42
42
|
formatToolScore,
|
|
43
43
|
generateHTML,
|
|
44
|
+
getPriorityIcon,
|
|
44
45
|
getProjectSizeTier,
|
|
45
46
|
getRating,
|
|
46
47
|
getRatingDisplay,
|
|
48
|
+
getRatingEmoji,
|
|
49
|
+
getRatingLabel,
|
|
47
50
|
getRatingSlug,
|
|
48
51
|
getRatingWithContext,
|
|
49
52
|
getRecommendedThreshold,
|
|
53
|
+
getToolEmoji,
|
|
50
54
|
getToolWeight,
|
|
51
55
|
normalizeToolName,
|
|
52
56
|
parseWeightString
|
|
53
|
-
} from "./chunk-
|
|
57
|
+
} from "./chunk-SQHS6PFL.mjs";
|
|
54
58
|
|
|
55
59
|
// src/utils/normalization.ts
|
|
56
60
|
function normalizeIssue(raw) {
|
|
@@ -2947,6 +2951,83 @@ function mergeConfigWithDefaults(userConfig, defaults) {
|
|
|
2947
2951
|
return mergedConfig;
|
|
2948
2952
|
}
|
|
2949
2953
|
|
|
2954
|
+
// src/utils/html-report-builder.ts
|
|
2955
|
+
function generateReportHead(title) {
|
|
2956
|
+
return `<!DOCTYPE html>
|
|
2957
|
+
<html lang="en">
|
|
2958
|
+
<head>
|
|
2959
|
+
<meta charset="UTF-8">
|
|
2960
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
2961
|
+
<title>${title}</title>
|
|
2962
|
+
<style>
|
|
2963
|
+
body { font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, 'Open Sans', 'Helvetica Neue', sans-serif; line-height: 1.6; color: #333; max-width: 1200px; margin: 0 auto; padding: 2rem; background-color: #f9f9f9; }
|
|
2964
|
+
h1, h2, h3 { color: #1a1a1a; border-bottom: 2px solid #eaeaea; padding-bottom: 0.5rem; }
|
|
2965
|
+
.card { background: white; padding: 1.5rem; border-radius: 8px; box-shadow: 0 2px 4px rgba(0,0,0,0.05); margin-bottom: 2rem; border: 1px solid #eaeaea; }
|
|
2966
|
+
.stats { display: grid; grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)); gap: 1rem; margin-bottom: 2rem; }
|
|
2967
|
+
.stat-card { background: #fff; padding: 1rem; border-radius: 6px; text-align: center; border: 1px solid #eaeaea; }
|
|
2968
|
+
.stat-value { font-size: 1.8rem; font-weight: bold; color: #2563eb; }
|
|
2969
|
+
.stat-label { font-size: 0.875rem; color: #666; text-transform: uppercase; }
|
|
2970
|
+
table { width: 100%; border-collapse: collapse; margin-top: 1rem; background: white; border-radius: 4px; overflow: hidden; }
|
|
2971
|
+
th, td { text-align: left; padding: 0.875rem 1rem; border-bottom: 1px solid #eaeaea; }
|
|
2972
|
+
th { background-color: #f8fafc; font-weight: 600; color: #475569; }
|
|
2973
|
+
tr:last-child td { border-bottom: none; }
|
|
2974
|
+
.critical { color: #dc2626; font-weight: bold; }
|
|
2975
|
+
.major { color: #ea580c; font-weight: bold; }
|
|
2976
|
+
.minor { color: #2563eb; }
|
|
2977
|
+
code { background: #f1f5f9; padding: 0.2rem 0.4rem; border-radius: 4px; font-size: 0.875rem; color: #334155; }
|
|
2978
|
+
.footer { margin-top: 4rem; text-align: center; color: #94a3b8; font-size: 0.875rem; }
|
|
2979
|
+
</style>
|
|
2980
|
+
</head>`;
|
|
2981
|
+
}
|
|
2982
|
+
function generateStatCards(cards) {
|
|
2983
|
+
const cardsHtml = cards.map(
|
|
2984
|
+
(card) => `
|
|
2985
|
+
<div class="stat-card">
|
|
2986
|
+
<div class="stat-value"${card.color ? ` style="color: ${card.color}"` : ""}>${card.value}</div>
|
|
2987
|
+
<div class="stat-label">${card.label}</div>
|
|
2988
|
+
</div>`
|
|
2989
|
+
).join("");
|
|
2990
|
+
return `<div class="stats">${cardsHtml}</div>`;
|
|
2991
|
+
}
|
|
2992
|
+
function generateTable(config) {
|
|
2993
|
+
const headersHtml = config.headers.map((h) => `<th>${h}</th>`).join("");
|
|
2994
|
+
const rowsHtml = config.rows.map((row) => `<tr>${row.map((cell) => `<td>${cell}</td>`).join("")}</tr>`).join("");
|
|
2995
|
+
return `<table>
|
|
2996
|
+
<thead><tr>${headersHtml}</tr></thead>
|
|
2997
|
+
<tbody>${rowsHtml}</tbody>
|
|
2998
|
+
</table>`;
|
|
2999
|
+
}
|
|
3000
|
+
function generateReportFooter(options) {
|
|
3001
|
+
const versionText = options.version ? ` v${options.version}` : "";
|
|
3002
|
+
const links = [];
|
|
3003
|
+
if (options.packageUrl) {
|
|
3004
|
+
links.push(`<a href="${options.packageUrl}">Star us on GitHub</a>`);
|
|
3005
|
+
}
|
|
3006
|
+
if (options.bugUrl) {
|
|
3007
|
+
links.push(`<a href="${options.bugUrl}">Report it here</a>`);
|
|
3008
|
+
}
|
|
3009
|
+
const linksHtml = links.length ? links.map((l) => `<p>Like AIReady? ${l}</p>`).join("\n ") : "";
|
|
3010
|
+
return `<div class="footer">
|
|
3011
|
+
<p>Generated by <strong>@aiready/${options.packageName}</strong>${versionText}</p>
|
|
3012
|
+
${linksHtml}
|
|
3013
|
+
</div>`;
|
|
3014
|
+
}
|
|
3015
|
+
function wrapInCard(content, title) {
|
|
3016
|
+
const titleHtml = title ? `<h2>${title}</h2>` : "";
|
|
3017
|
+
return `<div class="card">
|
|
3018
|
+
${titleHtml}
|
|
3019
|
+
${content}
|
|
3020
|
+
</div>`;
|
|
3021
|
+
}
|
|
3022
|
+
function generateCompleteReport(options, bodyContent) {
|
|
3023
|
+
return `${generateReportHead(options.title)}
|
|
3024
|
+
<body>
|
|
3025
|
+
${bodyContent}
|
|
3026
|
+
${generateReportFooter(options)}
|
|
3027
|
+
</body>
|
|
3028
|
+
</html>`;
|
|
3029
|
+
}
|
|
3030
|
+
|
|
2950
3031
|
// src/business/pricing-models.ts
|
|
2951
3032
|
var MODEL_PRICING_PRESETS = {
|
|
2952
3033
|
"gpt-5.4-mini": {
|
|
@@ -3010,20 +3091,52 @@ var DEFAULT_COST_CONFIG = {
|
|
|
3010
3091
|
developerCount: 5,
|
|
3011
3092
|
daysPerMonth: 30
|
|
3012
3093
|
};
|
|
3013
|
-
function calculateMonthlyCost(tokenWaste, config = {}) {
|
|
3014
|
-
const
|
|
3094
|
+
function calculateMonthlyCost(tokenWaste, config = {}, options) {
|
|
3095
|
+
const baseMultiplier = tokenWaste > 5e4 ? 5 : tokenWaste > 1e4 ? 3.5 : 2.5;
|
|
3096
|
+
const contextMultiplier = options?.avgContextBudget ? options.avgContextBudget / Math.max(1, tokenWaste) : baseMultiplier;
|
|
3097
|
+
const fragRatio = options?.fragmentationScore ?? 0.3;
|
|
3098
|
+
const dupRatio = 1 - fragRatio;
|
|
3015
3099
|
const budget = calculateTokenBudget({
|
|
3016
|
-
totalContextTokens: tokenWaste *
|
|
3100
|
+
totalContextTokens: tokenWaste * contextMultiplier,
|
|
3017
3101
|
wastedTokens: {
|
|
3018
|
-
duplication: tokenWaste *
|
|
3019
|
-
fragmentation: tokenWaste *
|
|
3102
|
+
duplication: tokenWaste * dupRatio * (options?.potentialSavings ? 1.2 : 1),
|
|
3103
|
+
fragmentation: tokenWaste * fragRatio,
|
|
3020
3104
|
chattiness: 0.1 * tokenWaste
|
|
3021
|
-
// Added baseline chattiness
|
|
3022
3105
|
}
|
|
3023
3106
|
});
|
|
3024
|
-
const preset = getModelPreset("
|
|
3107
|
+
const preset = getModelPreset("claude-3.5-sonnet");
|
|
3025
3108
|
return estimateCostFromBudget(budget, preset, config);
|
|
3026
3109
|
}
|
|
3110
|
+
function calculateDetailedTokenROI(params) {
|
|
3111
|
+
const {
|
|
3112
|
+
totalTokens,
|
|
3113
|
+
avgContextBudget,
|
|
3114
|
+
potentialSavings,
|
|
3115
|
+
fragmentationScore,
|
|
3116
|
+
developerCount,
|
|
3117
|
+
queriesPerDevPerDay = 60
|
|
3118
|
+
} = params;
|
|
3119
|
+
const budget = calculateTokenBudget({
|
|
3120
|
+
totalContextTokens: avgContextBudget,
|
|
3121
|
+
wastedTokens: {
|
|
3122
|
+
duplication: potentialSavings * 0.8,
|
|
3123
|
+
// 80% of potential savings are duplication-based
|
|
3124
|
+
fragmentation: totalTokens * fragmentationScore * 0.5,
|
|
3125
|
+
// fragmentation impact
|
|
3126
|
+
chattiness: totalTokens * 0.1
|
|
3127
|
+
}
|
|
3128
|
+
});
|
|
3129
|
+
const model = getModelPreset("claude-3.5-sonnet");
|
|
3130
|
+
const cost = estimateCostFromBudget(budget, model, {
|
|
3131
|
+
developerCount,
|
|
3132
|
+
queriesPerDevPerDay
|
|
3133
|
+
});
|
|
3134
|
+
return {
|
|
3135
|
+
monthlySavings: Math.round(cost.total),
|
|
3136
|
+
contextTaxPerDev: Math.round(cost.total / (developerCount || 1) * 100) / 100,
|
|
3137
|
+
efficiencyGain: Math.round(budget.efficiencyRatio * 100) / 100
|
|
3138
|
+
};
|
|
3139
|
+
}
|
|
3027
3140
|
function calculateTokenBudget(params) {
|
|
3028
3141
|
const { totalContextTokens, wastedTokens } = params;
|
|
3029
3142
|
const estimatedResponseTokens = params.estimatedResponseTokens ?? totalContextTokens * 0.2;
|
|
@@ -4550,6 +4663,7 @@ export {
|
|
|
4550
4663
|
calculateConceptCohesion,
|
|
4551
4664
|
calculateDebtInterest,
|
|
4552
4665
|
calculateDependencyHealth,
|
|
4666
|
+
calculateDetailedTokenROI,
|
|
4553
4667
|
calculateDocDrift,
|
|
4554
4668
|
calculateExtendedFutureProofScore,
|
|
4555
4669
|
calculateFutureProofScore,
|
|
@@ -4578,7 +4692,12 @@ export {
|
|
|
4578
4692
|
formatHours,
|
|
4579
4693
|
formatScore,
|
|
4580
4694
|
formatToolScore,
|
|
4695
|
+
generateCompleteReport,
|
|
4581
4696
|
generateHTML,
|
|
4697
|
+
generateReportFooter,
|
|
4698
|
+
generateReportHead,
|
|
4699
|
+
generateStatCards,
|
|
4700
|
+
generateTable,
|
|
4582
4701
|
generateValueChain,
|
|
4583
4702
|
getElapsedTime,
|
|
4584
4703
|
getFileCommitTimestamps,
|
|
@@ -4587,9 +4706,12 @@ export {
|
|
|
4587
4706
|
getLineRangeLastModifiedCached,
|
|
4588
4707
|
getModelPreset,
|
|
4589
4708
|
getParser,
|
|
4709
|
+
getPriorityIcon,
|
|
4590
4710
|
getProjectSizeTier,
|
|
4591
4711
|
getRating,
|
|
4592
4712
|
getRatingDisplay,
|
|
4713
|
+
getRatingEmoji,
|
|
4714
|
+
getRatingLabel,
|
|
4593
4715
|
getRatingSlug,
|
|
4594
4716
|
getRatingWithContext,
|
|
4595
4717
|
getRecommendedThreshold,
|
|
@@ -4602,6 +4724,7 @@ export {
|
|
|
4602
4724
|
getSeverityLevel,
|
|
4603
4725
|
getSeverityValue,
|
|
4604
4726
|
getSupportedLanguages,
|
|
4727
|
+
getToolEmoji,
|
|
4605
4728
|
getToolWeight,
|
|
4606
4729
|
getWasmPath,
|
|
4607
4730
|
groupIssuesByFile,
|
|
@@ -4631,5 +4754,6 @@ export {
|
|
|
4631
4754
|
setupParser,
|
|
4632
4755
|
severityToAnnotationLevel,
|
|
4633
4756
|
validateSpokeOutput,
|
|
4634
|
-
validateWithSchema
|
|
4757
|
+
validateWithSchema,
|
|
4758
|
+
wrapInCard
|
|
4635
4759
|
};
|