@aiready/core 0.9.22 → 0.9.25
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-HKSARRCD.mjs +357 -0
- package/dist/client.d.mts +547 -0
- package/dist/client.d.ts +547 -0
- package/dist/client.js +396 -0
- package/dist/client.mjs +32 -0
- package/dist/index.d.mts +35 -361
- package/dist/index.d.ts +35 -361
- package/dist/index.js +372 -0
- package/dist/index.mjs +187 -158
- package/package.json +9 -3
package/dist/index.js
CHANGED
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
+
var __create = Object.create;
|
|
2
3
|
var __defProp = Object.defineProperty;
|
|
3
4
|
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
5
|
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
6
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
5
7
|
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
8
|
var __export = (target, all) => {
|
|
7
9
|
for (var name in all)
|
|
@@ -15,11 +17,20 @@ var __copyProps = (to, from, except, desc) => {
|
|
|
15
17
|
}
|
|
16
18
|
return to;
|
|
17
19
|
};
|
|
20
|
+
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
|
21
|
+
// If the importer is in node compatibility mode or this is not an ESM
|
|
22
|
+
// file that has been converted to a CommonJS file using a Babel-
|
|
23
|
+
// compatible transform (i.e. "__esModule" has not been set), then set
|
|
24
|
+
// "default" to the CommonJS "module.exports" for node compatibility.
|
|
25
|
+
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
|
26
|
+
mod
|
|
27
|
+
));
|
|
18
28
|
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
29
|
|
|
20
30
|
// src/index.ts
|
|
21
31
|
var index_exports = {};
|
|
22
32
|
__export(index_exports, {
|
|
33
|
+
DEFAULT_COST_CONFIG: () => DEFAULT_COST_CONFIG,
|
|
23
34
|
DEFAULT_EXCLUDE: () => DEFAULT_EXCLUDE,
|
|
24
35
|
DEFAULT_TOOL_WEIGHTS: () => DEFAULT_TOOL_WEIGHTS,
|
|
25
36
|
LANGUAGE_EXTENSIONS: () => LANGUAGE_EXTENSIONS,
|
|
@@ -29,13 +40,20 @@ __export(index_exports, {
|
|
|
29
40
|
PythonParser: () => PythonParser,
|
|
30
41
|
TOOL_NAME_MAP: () => TOOL_NAME_MAP,
|
|
31
42
|
TypeScriptParser: () => TypeScriptParser,
|
|
43
|
+
calculateComprehensionDifficulty: () => calculateComprehensionDifficulty,
|
|
32
44
|
calculateImportSimilarity: () => calculateImportSimilarity,
|
|
45
|
+
calculateMonthlyCost: () => calculateMonthlyCost,
|
|
33
46
|
calculateOverallScore: () => calculateOverallScore,
|
|
47
|
+
calculateProductivityImpact: () => calculateProductivityImpact,
|
|
34
48
|
estimateTokens: () => estimateTokens,
|
|
35
49
|
extractFunctions: () => extractFunctions,
|
|
36
50
|
extractImports: () => extractImports,
|
|
51
|
+
formatAcceptanceRate: () => formatAcceptanceRate,
|
|
52
|
+
formatCost: () => formatCost,
|
|
53
|
+
formatHours: () => formatHours,
|
|
37
54
|
formatScore: () => formatScore,
|
|
38
55
|
formatToolScore: () => formatToolScore,
|
|
56
|
+
generateHTML: () => generateHTML,
|
|
39
57
|
getElapsedTime: () => getElapsedTime,
|
|
40
58
|
getFileExtension: () => getFileExtension,
|
|
41
59
|
getParser: () => getParser,
|
|
@@ -54,6 +72,7 @@ __export(index_exports, {
|
|
|
54
72
|
parseCode: () => parseCode,
|
|
55
73
|
parseFileExports: () => parseFileExports,
|
|
56
74
|
parseWeightString: () => parseWeightString,
|
|
75
|
+
predictAcceptanceRate: () => predictAcceptanceRate,
|
|
57
76
|
readFileContent: () => readFileContent,
|
|
58
77
|
resolveOutputPath: () => resolveOutputPath,
|
|
59
78
|
scanFiles: () => scanFiles
|
|
@@ -96,6 +115,7 @@ var import_glob = require("glob");
|
|
|
96
115
|
var import_promises = require("fs/promises");
|
|
97
116
|
var import_fs = require("fs");
|
|
98
117
|
var import_path = require("path");
|
|
118
|
+
var import_ignore = __toESM(require("ignore"));
|
|
99
119
|
var DEFAULT_EXCLUDE = [
|
|
100
120
|
// Dependencies
|
|
101
121
|
"**/node_modules/**",
|
|
@@ -164,6 +184,22 @@ async function scanFiles(options) {
|
|
|
164
184
|
ignore: finalExclude,
|
|
165
185
|
absolute: true
|
|
166
186
|
});
|
|
187
|
+
const gitignorePath = (0, import_path.join)(rootDir || ".", ".gitignore");
|
|
188
|
+
if ((0, import_fs.existsSync)(gitignorePath)) {
|
|
189
|
+
try {
|
|
190
|
+
const gitTxt = await (0, import_promises.readFile)(gitignorePath, "utf-8");
|
|
191
|
+
const ig = (0, import_ignore.default)();
|
|
192
|
+
ig.add(gitTxt);
|
|
193
|
+
const filtered = files.filter((f) => {
|
|
194
|
+
let rel = (0, import_path.relative)(rootDir || ".", f).replace(/\\/g, "/");
|
|
195
|
+
if (rel === "") rel = f;
|
|
196
|
+
return !ig.ignores(rel);
|
|
197
|
+
});
|
|
198
|
+
return filtered;
|
|
199
|
+
} catch (e) {
|
|
200
|
+
return files;
|
|
201
|
+
}
|
|
202
|
+
}
|
|
167
203
|
return files;
|
|
168
204
|
}
|
|
169
205
|
async function readFileContent(filePath) {
|
|
@@ -472,6 +508,172 @@ function getElapsedTime(startTime) {
|
|
|
472
508
|
return ((Date.now() - startTime) / 1e3).toFixed(2);
|
|
473
509
|
}
|
|
474
510
|
|
|
511
|
+
// src/utils/visualization.ts
|
|
512
|
+
function generateHTML(graph) {
|
|
513
|
+
const payload = JSON.stringify(graph, null, 2);
|
|
514
|
+
return `<!doctype html>
|
|
515
|
+
<html>
|
|
516
|
+
<head>
|
|
517
|
+
<meta charset="utf-8" />
|
|
518
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
519
|
+
<title>AIReady Visualization</title>
|
|
520
|
+
<style>
|
|
521
|
+
html,body { height: 100%; margin: 0; padding: 0; font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif; background: #0f172a; color: #e2e8f0 }
|
|
522
|
+
#container { display:flex; height:100vh }
|
|
523
|
+
#panel { width: 320px; padding: 16px; background: #071130; box-shadow: -2px 0 8px rgba(0,0,0,0.3); overflow:auto }
|
|
524
|
+
#canvasWrap { flex:1; display:flex; align-items:center; justify-content:center }
|
|
525
|
+
canvas { background: #0b1220; border-radius:8px }
|
|
526
|
+
.stat { margin-bottom:12px }
|
|
527
|
+
</style>
|
|
528
|
+
</head>
|
|
529
|
+
<body>
|
|
530
|
+
<div id="container">
|
|
531
|
+
<div id="canvasWrap"><canvas id="canvas" width="1200" height="800"></canvas></div>
|
|
532
|
+
<div id="panel">
|
|
533
|
+
<h2>AIReady Visualization</h2>
|
|
534
|
+
<div class="stat"><strong>Files:</strong> <span id="stat-files"></span></div>
|
|
535
|
+
<div class="stat"><strong>Dependencies:</strong> <span id="stat-deps"></span></div>
|
|
536
|
+
<div class="stat"><strong>Legend</strong></div>
|
|
537
|
+
<div style="font-size:13px;line-height:1.3;color:#cbd5e1;margin-top:8px">
|
|
538
|
+
<div style="margin-bottom:8px"><span style="display:inline-block;width:12px;height:12px;background:#ff4d4f;margin-right:8px;border:1px solid rgba(255,255,255,0.06)"></span><strong>Critical</strong>: highest severity issues.</div>
|
|
539
|
+
<div style="margin-bottom:8px"><span style="display:inline-block;width:12px;height:12px;background:#ff9900;margin-right:8px;border:1px solid rgba(255,255,255,0.06)"></span><strong>Major</strong>: important issues.</div>
|
|
540
|
+
<div style="margin-bottom:8px"><span style="display:inline-block;width:12px;height:12px;background:#ffd666;margin-right:8px;border:1px solid rgba(255,255,255,0.06)"></span><strong>Minor</strong>: low priority issues.</div>
|
|
541
|
+
<div style="margin-bottom:8px"><span style="display:inline-block;width:12px;height:12px;background:#91d5ff;margin-right:8px;border:1px solid rgba(255,255,255,0.06)"></span><strong>Info</strong>: informational notes.</div>
|
|
542
|
+
<div style="margin-top:10px;color:#94a3b8"><strong>Node size</strong>: larger = higher token cost, more issues or dependency weight.</div>
|
|
543
|
+
<div style="margin-top:6px;color:#94a3b8"><strong>Proximity</strong>: nodes that are spatially close are more contextually related; relatedness is represented by distance and size rather than explicit edges.</div>
|
|
544
|
+
<div style="margin-top:6px;color:#94a3b8"><strong>Edge colors</strong>: <span style="color:#fb7e81">Similarity</span>, <span style="color:#84c1ff">Dependency</span>, <span style="color:#ffa500">Reference</span>, default <span style="color:#334155">Other</span>.</div>
|
|
545
|
+
</div>
|
|
546
|
+
</div>
|
|
547
|
+
</div>
|
|
548
|
+
|
|
549
|
+
<script>
|
|
550
|
+
const graphData = ${payload};
|
|
551
|
+
document.getElementById('stat-files').textContent = graphData.metadata.totalFiles;
|
|
552
|
+
document.getElementById('stat-deps').textContent = graphData.metadata.totalDependencies;
|
|
553
|
+
|
|
554
|
+
const canvas = document.getElementById('canvas');
|
|
555
|
+
const ctx = canvas.getContext('2d');
|
|
556
|
+
|
|
557
|
+
const nodes = graphData.nodes.map((n, i) => ({
|
|
558
|
+
...n,
|
|
559
|
+
x: canvas.width / 2 + Math.cos(i / graphData.nodes.length * Math.PI * 2) * (Math.min(canvas.width, canvas.height) / 3),
|
|
560
|
+
y: canvas.height / 2 + Math.sin(i / graphData.nodes.length * Math.PI * 2) * (Math.min(canvas.width, canvas.height) / 3),
|
|
561
|
+
}));
|
|
562
|
+
|
|
563
|
+
function draw() {
|
|
564
|
+
ctx.clearRect(0, 0, canvas.width, canvas.height);
|
|
565
|
+
|
|
566
|
+
graphData.edges.forEach(edge => {
|
|
567
|
+
const s = nodes.find(n => n.id === edge.source);
|
|
568
|
+
const t = nodes.find(n => n.id === edge.target);
|
|
569
|
+
if (!s || !t) return;
|
|
570
|
+
if (edge.type === 'related') return;
|
|
571
|
+
if (edge.type === 'similarity') {
|
|
572
|
+
ctx.strokeStyle = '#fb7e81';
|
|
573
|
+
ctx.lineWidth = 1.2;
|
|
574
|
+
} else if (edge.type === 'dependency') {
|
|
575
|
+
ctx.strokeStyle = '#84c1ff';
|
|
576
|
+
ctx.lineWidth = 1.0;
|
|
577
|
+
} else if (edge.type === 'reference') {
|
|
578
|
+
ctx.strokeStyle = '#ffa500';
|
|
579
|
+
ctx.lineWidth = 0.9;
|
|
580
|
+
} else {
|
|
581
|
+
ctx.strokeStyle = '#334155';
|
|
582
|
+
ctx.lineWidth = 0.8;
|
|
583
|
+
}
|
|
584
|
+
ctx.beginPath();
|
|
585
|
+
ctx.moveTo(s.x, s.y);
|
|
586
|
+
ctx.lineTo(t.x, t.y);
|
|
587
|
+
ctx.stroke();
|
|
588
|
+
});
|
|
589
|
+
|
|
590
|
+
const groups = {};
|
|
591
|
+
nodes.forEach(n => {
|
|
592
|
+
const g = n.group || '__default';
|
|
593
|
+
if (!groups[g]) groups[g] = { minX: n.x, minY: n.y, maxX: n.x, maxY: n.y };
|
|
594
|
+
groups[g].minX = Math.min(groups[g].minX, n.x);
|
|
595
|
+
groups[g].minY = Math.min(groups[g].minY, n.y);
|
|
596
|
+
groups[g].maxX = Math.max(groups[g].maxX, n.x);
|
|
597
|
+
groups[g].maxY = Math.max(groups[g].maxY, n.y);
|
|
598
|
+
});
|
|
599
|
+
|
|
600
|
+
const groupRelations = {};
|
|
601
|
+
graphData.edges.forEach(edge => {
|
|
602
|
+
const sNode = nodes.find(n => n.id === edge.source);
|
|
603
|
+
const tNode = nodes.find(n => n.id === edge.target);
|
|
604
|
+
if (!sNode || !tNode) return;
|
|
605
|
+
const g1 = sNode.group || '__default';
|
|
606
|
+
const g2 = tNode.group || '__default';
|
|
607
|
+
if (g1 === g2) return;
|
|
608
|
+
const key = g1 < g2 ? g1 + '::' + g2 : g2 + '::' + g1;
|
|
609
|
+
groupRelations[key] = (groupRelations[key] || 0) + 1;
|
|
610
|
+
});
|
|
611
|
+
|
|
612
|
+
Object.keys(groupRelations).forEach(k => {
|
|
613
|
+
const count = groupRelations[k];
|
|
614
|
+
const [ga, gb] = k.split('::');
|
|
615
|
+
if (!groups[ga] || !groups[gb]) return;
|
|
616
|
+
const ax = (groups[ga].minX + groups[ga].maxX) / 2;
|
|
617
|
+
const ay = (groups[ga].minY + groups[ga].maxY) / 2;
|
|
618
|
+
const bx = (groups[gb].minX + groups[gb].maxX) / 2;
|
|
619
|
+
const by = (groups[gb].minY + groups[gb].maxY) / 2;
|
|
620
|
+
ctx.beginPath();
|
|
621
|
+
ctx.strokeStyle = 'rgba(148,163,184,0.25)';
|
|
622
|
+
ctx.lineWidth = Math.min(6, 0.6 + Math.sqrt(count));
|
|
623
|
+
ctx.moveTo(ax, ay);
|
|
624
|
+
ctx.lineTo(bx, by);
|
|
625
|
+
ctx.stroke();
|
|
626
|
+
});
|
|
627
|
+
|
|
628
|
+
Object.keys(groups).forEach(g => {
|
|
629
|
+
if (g === '__default') return;
|
|
630
|
+
const box = groups[g];
|
|
631
|
+
const pad = 16;
|
|
632
|
+
const x = box.minX - pad;
|
|
633
|
+
const y = box.minY - pad;
|
|
634
|
+
const w = (box.maxX - box.minX) + pad * 2;
|
|
635
|
+
const h = (box.maxY - box.minY) + pad * 2;
|
|
636
|
+
ctx.save();
|
|
637
|
+
ctx.fillStyle = 'rgba(30,64,175,0.04)';
|
|
638
|
+
ctx.strokeStyle = 'rgba(30,64,175,0.12)';
|
|
639
|
+
ctx.lineWidth = 1.2;
|
|
640
|
+
const r = 8;
|
|
641
|
+
ctx.beginPath();
|
|
642
|
+
ctx.moveTo(x + r, y);
|
|
643
|
+
ctx.arcTo(x + w, y, x + w, y + h, r);
|
|
644
|
+
ctx.arcTo(x + w, y + h, x, y + h, r);
|
|
645
|
+
ctx.arcTo(x, y + h, x, y, r);
|
|
646
|
+
ctx.arcTo(x, y, x + w, y, r);
|
|
647
|
+
ctx.closePath();
|
|
648
|
+
ctx.fill();
|
|
649
|
+
ctx.stroke();
|
|
650
|
+
ctx.restore();
|
|
651
|
+
ctx.fillStyle = '#94a3b8';
|
|
652
|
+
ctx.font = '11px sans-serif';
|
|
653
|
+
ctx.fillText(g, x + 8, y + 14);
|
|
654
|
+
});
|
|
655
|
+
|
|
656
|
+
nodes.forEach(n => {
|
|
657
|
+
const sizeVal = (n.size || n.value || 1);
|
|
658
|
+
const r = 6 + (sizeVal / 2);
|
|
659
|
+
ctx.beginPath();
|
|
660
|
+
ctx.fillStyle = n.color || '#60a5fa';
|
|
661
|
+
ctx.arc(n.x, n.y, r, 0, Math.PI * 2);
|
|
662
|
+
ctx.fill();
|
|
663
|
+
|
|
664
|
+
ctx.fillStyle = '#e2e8f0';
|
|
665
|
+
ctx.font = '11px sans-serif';
|
|
666
|
+
ctx.textAlign = 'center';
|
|
667
|
+
ctx.fillText(n.label || n.id.split('/').slice(-1)[0], n.x, n.y + r + 12);
|
|
668
|
+
});
|
|
669
|
+
}
|
|
670
|
+
|
|
671
|
+
draw();
|
|
672
|
+
</script>
|
|
673
|
+
</body>
|
|
674
|
+
</html>`;
|
|
675
|
+
}
|
|
676
|
+
|
|
475
677
|
// src/scoring.ts
|
|
476
678
|
var DEFAULT_TOOL_WEIGHTS = {
|
|
477
679
|
"pattern-detect": 40,
|
|
@@ -616,6 +818,167 @@ function formatToolScore(output) {
|
|
|
616
818
|
return result;
|
|
617
819
|
}
|
|
618
820
|
|
|
821
|
+
// src/business-metrics.ts
|
|
822
|
+
var DEFAULT_COST_CONFIG = {
|
|
823
|
+
pricePer1KTokens: 0.01,
|
|
824
|
+
// $0.01 per 1K tokens (GPT-4)
|
|
825
|
+
queriesPerDevPerDay: 50,
|
|
826
|
+
// Average AI queries per developer
|
|
827
|
+
developerCount: 5,
|
|
828
|
+
// Default team size
|
|
829
|
+
daysPerMonth: 30
|
|
830
|
+
};
|
|
831
|
+
var SEVERITY_TIME_ESTIMATES = {
|
|
832
|
+
critical: 4,
|
|
833
|
+
// Complex architectural issues
|
|
834
|
+
major: 2,
|
|
835
|
+
// Significant refactoring needed
|
|
836
|
+
minor: 0.5,
|
|
837
|
+
// Simple naming/style fixes
|
|
838
|
+
info: 0.25
|
|
839
|
+
// Documentation improvements
|
|
840
|
+
};
|
|
841
|
+
var DEFAULT_HOURLY_RATE = 75;
|
|
842
|
+
function calculateMonthlyCost(tokenWaste, config = {}) {
|
|
843
|
+
const cfg = { ...DEFAULT_COST_CONFIG, ...config };
|
|
844
|
+
const tokensPerDay = tokenWaste * cfg.queriesPerDevPerDay;
|
|
845
|
+
const tokensPerMonth = tokensPerDay * cfg.daysPerMonth;
|
|
846
|
+
const cost = tokensPerMonth / 1e3 * cfg.pricePer1KTokens;
|
|
847
|
+
return Math.round(cost * 100) / 100;
|
|
848
|
+
}
|
|
849
|
+
function calculateProductivityImpact(issues, hourlyRate = DEFAULT_HOURLY_RATE) {
|
|
850
|
+
const counts = {
|
|
851
|
+
critical: issues.filter((i) => i.severity === "critical").length,
|
|
852
|
+
major: issues.filter((i) => i.severity === "major").length,
|
|
853
|
+
minor: issues.filter((i) => i.severity === "minor").length,
|
|
854
|
+
info: issues.filter((i) => i.severity === "info").length
|
|
855
|
+
};
|
|
856
|
+
const hours = {
|
|
857
|
+
critical: counts.critical * SEVERITY_TIME_ESTIMATES.critical,
|
|
858
|
+
major: counts.major * SEVERITY_TIME_ESTIMATES.major,
|
|
859
|
+
minor: counts.minor * SEVERITY_TIME_ESTIMATES.minor,
|
|
860
|
+
info: counts.info * SEVERITY_TIME_ESTIMATES.info
|
|
861
|
+
};
|
|
862
|
+
const totalHours = hours.critical + hours.major + hours.minor + hours.info;
|
|
863
|
+
const totalCost = totalHours * hourlyRate;
|
|
864
|
+
return {
|
|
865
|
+
totalHours: Math.round(totalHours * 10) / 10,
|
|
866
|
+
hourlyRate,
|
|
867
|
+
totalCost: Math.round(totalCost),
|
|
868
|
+
bySeverity: {
|
|
869
|
+
critical: { hours: Math.round(hours.critical * 10) / 10, cost: Math.round(hours.critical * hourlyRate) },
|
|
870
|
+
major: { hours: Math.round(hours.major * 10) / 10, cost: Math.round(hours.major * hourlyRate) },
|
|
871
|
+
minor: { hours: Math.round(hours.minor * 10) / 10, cost: Math.round(hours.minor * hourlyRate) }
|
|
872
|
+
}
|
|
873
|
+
};
|
|
874
|
+
}
|
|
875
|
+
function predictAcceptanceRate(toolOutputs) {
|
|
876
|
+
const factors = [];
|
|
877
|
+
const patterns = toolOutputs.get("pattern-detect");
|
|
878
|
+
if (patterns) {
|
|
879
|
+
const patternImpact = (patterns.score - 50) * 0.3;
|
|
880
|
+
factors.push({
|
|
881
|
+
name: "Semantic Duplication",
|
|
882
|
+
impact: Math.round(patternImpact)
|
|
883
|
+
});
|
|
884
|
+
}
|
|
885
|
+
const context = toolOutputs.get("context-analyzer");
|
|
886
|
+
if (context) {
|
|
887
|
+
const contextImpact = (context.score - 50) * 0.4;
|
|
888
|
+
factors.push({
|
|
889
|
+
name: "Context Efficiency",
|
|
890
|
+
impact: Math.round(contextImpact)
|
|
891
|
+
});
|
|
892
|
+
}
|
|
893
|
+
const consistency = toolOutputs.get("consistency");
|
|
894
|
+
if (consistency) {
|
|
895
|
+
const consistencyImpact = (consistency.score - 50) * 0.3;
|
|
896
|
+
factors.push({
|
|
897
|
+
name: "Code Consistency",
|
|
898
|
+
impact: Math.round(consistencyImpact)
|
|
899
|
+
});
|
|
900
|
+
}
|
|
901
|
+
const baseRate = 0.65;
|
|
902
|
+
const totalImpact = factors.reduce((sum, f) => sum + f.impact / 100, 0);
|
|
903
|
+
const rate = Math.max(0.1, Math.min(0.95, baseRate + totalImpact));
|
|
904
|
+
const confidence = toolOutputs.size >= 3 ? 0.8 : toolOutputs.size >= 2 ? 0.6 : 0.4;
|
|
905
|
+
return {
|
|
906
|
+
rate: Math.round(rate * 100) / 100,
|
|
907
|
+
confidence,
|
|
908
|
+
factors
|
|
909
|
+
};
|
|
910
|
+
}
|
|
911
|
+
function calculateComprehensionDifficulty(contextBudget, importDepth, fragmentation, consistencyScore, totalFiles) {
|
|
912
|
+
const budgetFactor = Math.min(100, Math.max(0, (contextBudget - 5e3) / 250));
|
|
913
|
+
const depthFactor = Math.min(100, Math.max(0, (importDepth - 5) * 10));
|
|
914
|
+
const fragmentationFactor = Math.min(100, Math.max(0, (fragmentation - 0.3) * 250));
|
|
915
|
+
const consistencyFactor = Math.min(100, Math.max(0, 100 - consistencyScore));
|
|
916
|
+
const fileFactor = Math.min(100, Math.max(0, (totalFiles - 50) / 5));
|
|
917
|
+
const score = Math.round(
|
|
918
|
+
budgetFactor * 0.35 + depthFactor * 0.2 + fragmentationFactor * 0.2 + consistencyFactor * 0.15 + fileFactor * 0.1
|
|
919
|
+
);
|
|
920
|
+
let rating;
|
|
921
|
+
if (score < 20) rating = "trivial";
|
|
922
|
+
else if (score < 40) rating = "easy";
|
|
923
|
+
else if (score < 60) rating = "moderate";
|
|
924
|
+
else if (score < 80) rating = "difficult";
|
|
925
|
+
else rating = "expert";
|
|
926
|
+
return {
|
|
927
|
+
score,
|
|
928
|
+
rating,
|
|
929
|
+
factors: [
|
|
930
|
+
{
|
|
931
|
+
name: "Context Budget",
|
|
932
|
+
contribution: Math.round(budgetFactor * 0.35),
|
|
933
|
+
description: `${Math.round(contextBudget)} tokens required`
|
|
934
|
+
},
|
|
935
|
+
{
|
|
936
|
+
name: "Import Depth",
|
|
937
|
+
contribution: Math.round(depthFactor * 0.2),
|
|
938
|
+
description: `${importDepth.toFixed(1)} average levels`
|
|
939
|
+
},
|
|
940
|
+
{
|
|
941
|
+
name: "Code Fragmentation",
|
|
942
|
+
contribution: Math.round(fragmentationFactor * 0.2),
|
|
943
|
+
description: `${(fragmentation * 100).toFixed(0)}% fragmentation`
|
|
944
|
+
},
|
|
945
|
+
{
|
|
946
|
+
name: "Consistency",
|
|
947
|
+
contribution: Math.round(consistencyFactor * 0.15),
|
|
948
|
+
description: `${consistencyScore}/100 consistency score`
|
|
949
|
+
},
|
|
950
|
+
{
|
|
951
|
+
name: "Project Scale",
|
|
952
|
+
contribution: Math.round(fileFactor * 0.1),
|
|
953
|
+
description: `${totalFiles} files analyzed`
|
|
954
|
+
}
|
|
955
|
+
]
|
|
956
|
+
};
|
|
957
|
+
}
|
|
958
|
+
function formatCost(cost) {
|
|
959
|
+
if (cost < 1) {
|
|
960
|
+
return `$${cost.toFixed(2)}`;
|
|
961
|
+
} else if (cost < 1e3) {
|
|
962
|
+
return `$${cost.toFixed(0)}`;
|
|
963
|
+
} else {
|
|
964
|
+
return `$${(cost / 1e3).toFixed(1)}k`;
|
|
965
|
+
}
|
|
966
|
+
}
|
|
967
|
+
function formatHours(hours) {
|
|
968
|
+
if (hours < 1) {
|
|
969
|
+
return `${Math.round(hours * 60)}min`;
|
|
970
|
+
} else if (hours < 8) {
|
|
971
|
+
return `${hours.toFixed(1)}h`;
|
|
972
|
+
} else if (hours < 40) {
|
|
973
|
+
return `${Math.round(hours)}h`;
|
|
974
|
+
} else {
|
|
975
|
+
return `${(hours / 40).toFixed(1)} weeks`;
|
|
976
|
+
}
|
|
977
|
+
}
|
|
978
|
+
function formatAcceptanceRate(rate) {
|
|
979
|
+
return `${Math.round(rate * 100)}%`;
|
|
980
|
+
}
|
|
981
|
+
|
|
619
982
|
// src/parsers/typescript-parser.ts
|
|
620
983
|
var import_typescript_estree2 = require("@typescript-eslint/typescript-estree");
|
|
621
984
|
var TypeScriptParser = class {
|
|
@@ -1097,6 +1460,7 @@ function getSupportedLanguages() {
|
|
|
1097
1460
|
}
|
|
1098
1461
|
// Annotate the CommonJS export names for ESM import in node:
|
|
1099
1462
|
0 && (module.exports = {
|
|
1463
|
+
DEFAULT_COST_CONFIG,
|
|
1100
1464
|
DEFAULT_EXCLUDE,
|
|
1101
1465
|
DEFAULT_TOOL_WEIGHTS,
|
|
1102
1466
|
LANGUAGE_EXTENSIONS,
|
|
@@ -1106,13 +1470,20 @@ function getSupportedLanguages() {
|
|
|
1106
1470
|
PythonParser,
|
|
1107
1471
|
TOOL_NAME_MAP,
|
|
1108
1472
|
TypeScriptParser,
|
|
1473
|
+
calculateComprehensionDifficulty,
|
|
1109
1474
|
calculateImportSimilarity,
|
|
1475
|
+
calculateMonthlyCost,
|
|
1110
1476
|
calculateOverallScore,
|
|
1477
|
+
calculateProductivityImpact,
|
|
1111
1478
|
estimateTokens,
|
|
1112
1479
|
extractFunctions,
|
|
1113
1480
|
extractImports,
|
|
1481
|
+
formatAcceptanceRate,
|
|
1482
|
+
formatCost,
|
|
1483
|
+
formatHours,
|
|
1114
1484
|
formatScore,
|
|
1115
1485
|
formatToolScore,
|
|
1486
|
+
generateHTML,
|
|
1116
1487
|
getElapsedTime,
|
|
1117
1488
|
getFileExtension,
|
|
1118
1489
|
getParser,
|
|
@@ -1131,6 +1502,7 @@ function getSupportedLanguages() {
|
|
|
1131
1502
|
parseCode,
|
|
1132
1503
|
parseFileExports,
|
|
1133
1504
|
parseWeightString,
|
|
1505
|
+
predictAcceptanceRate,
|
|
1134
1506
|
readFileContent,
|
|
1135
1507
|
resolveOutputPath,
|
|
1136
1508
|
scanFiles
|