@aiready/deps 0.13.1 → 0.13.3
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 +9 -9
- package/.turbo/turbo-lint.log +0 -5
- package/.turbo/turbo-test.log +6 -22
- package/dist/chunk-M52PDCX6.mjs +184 -0
- package/dist/chunk-Y2VRCEM4.mjs +184 -0
- package/dist/cli.js +6 -6
- package/dist/cli.mjs +1 -1
- package/dist/index.d.mts +3 -2
- package/dist/index.d.ts +3 -2
- package/dist/index.js +28 -52
- package/dist/index.mjs +26 -48
- package/package.json +2 -2
- package/src/__tests__/provider.test.ts +1 -1
- package/src/analyzer.ts +8 -8
- package/src/provider.ts +25 -59
package/.turbo/turbo-build.log
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
|
|
2
2
|
|
|
3
|
-
> @aiready/deps@0.13.
|
|
3
|
+
> @aiready/deps@0.13.3 build /Users/pengcao/projects/aiready/packages/deps
|
|
4
4
|
> tsup src/index.ts src/cli.ts --format cjs,esm --dts
|
|
5
5
|
|
|
6
6
|
[34mCLI[39m Building entry: src/cli.ts, src/index.ts
|
|
@@ -9,16 +9,16 @@
|
|
|
9
9
|
[34mCLI[39m Target: es2020
|
|
10
10
|
[34mCJS[39m Build start
|
|
11
11
|
[34mESM[39m Build start
|
|
12
|
-
[32mESM[39m [1mdist/index.mjs [22m[32m3.13 KB[39m
|
|
13
|
-
[32mESM[39m [1mdist/chunk-CFNCY65I.mjs [22m[32m5.78 KB[39m
|
|
14
12
|
[32mESM[39m [1mdist/cli.mjs [22m[32m1.33 KB[39m
|
|
15
|
-
[32mESM[39m
|
|
13
|
+
[32mESM[39m [1mdist/chunk-Y2VRCEM4.mjs [22m[32m5.78 KB[39m
|
|
14
|
+
[32mESM[39m [1mdist/index.mjs [22m[32m2.46 KB[39m
|
|
15
|
+
[32mESM[39m ⚡️ Build success in 171ms
|
|
16
|
+
[32mCJS[39m [1mdist/index.js [22m[32m8.95 KB[39m
|
|
16
17
|
[32mCJS[39m [1mdist/cli.js [22m[32m8.44 KB[39m
|
|
17
|
-
[32mCJS[39m
|
|
18
|
-
[32mCJS[39m ⚡️ Build success in 80ms
|
|
18
|
+
[32mCJS[39m ⚡️ Build success in 171ms
|
|
19
19
|
DTS Build start
|
|
20
|
-
DTS ⚡️ Build success in
|
|
20
|
+
DTS ⚡️ Build success in 3283ms
|
|
21
21
|
DTS dist/cli.d.ts 108.00 B
|
|
22
|
-
DTS dist/index.d.ts 1.
|
|
22
|
+
DTS dist/index.d.ts 1.18 KB
|
|
23
23
|
DTS dist/cli.d.mts 108.00 B
|
|
24
|
-
DTS dist/index.d.mts 1.
|
|
24
|
+
DTS dist/index.d.mts 1.18 KB
|
package/.turbo/turbo-lint.log
CHANGED
package/.turbo/turbo-test.log
CHANGED
|
@@ -1,34 +1,18 @@
|
|
|
1
1
|
|
|
2
2
|
|
|
3
|
-
> @aiready/deps@0.13.
|
|
3
|
+
> @aiready/deps@0.13.2 test /Users/pengcao/projects/aiready/packages/deps
|
|
4
4
|
> vitest run
|
|
5
5
|
|
|
6
6
|
[?25l
|
|
7
7
|
[1m[46m RUN [49m[22m [36mv4.0.18 [39m[90m/Users/pengcao/projects/aiready/packages/deps[39m
|
|
8
8
|
|
|
9
|
-
[
|
|
10
|
-
[
|
|
11
|
-
|
|
12
|
-
[2m Test Files [22m[1m[32m0 passed[39m[22m[90m (3)[39m
|
|
13
|
-
[2m Tests [22m[1m[32m0 passed[39m[22m[90m (0)[39m
|
|
14
|
-
[2m Start at [22m17:20:15
|
|
15
|
-
[2m Duration [22m100ms
|
|
16
|
-
[?2026l[?2026h[K[1A[K[1A[K[1A[K[1A[K[1A[K[1A[K[1A[K
|
|
17
|
-
[1m[33m ❯ [39m[22msrc/__tests__/analyzer.test.ts[2m [queued][22m
|
|
18
|
-
[1m[33m ❯ [39m[22msrc/__tests__/provider.test.ts[2m 0/2[22m
|
|
19
|
-
[1m[33m ❯ [39m[22msrc/__tests__/scoring.test.ts[2m [queued][22m
|
|
20
|
-
|
|
21
|
-
[2m Test Files [22m[1m[32m0 passed[39m[22m[90m (3)[39m
|
|
22
|
-
[2m Tests [22m[1m[32m0 passed[39m[22m[90m (2)[39m
|
|
23
|
-
[2m Start at [22m17:20:15
|
|
24
|
-
[2m Duration [22m404ms
|
|
25
|
-
[?2026l[K[1A[K[1A[K[1A[K[1A[K[1A[K[1A[K[1A[K[1A[K[1A[K [32m✓[39m src/__tests__/provider.test.ts [2m([22m[2m2 tests[22m[2m)[22m[32m 4[2mms[22m[39m
|
|
26
|
-
[32m✓[39m src/__tests__/scoring.test.ts [2m([22m[2m2 tests[22m[2m)[22m[32m 1[2mms[22m[39m
|
|
27
|
-
[32m✓[39m src/__tests__/analyzer.test.ts [2m([22m[2m2 tests[22m[2m)[22m[32m 4[2mms[22m[39m
|
|
9
|
+
[32m✓[39m src/__tests__/provider.test.ts [2m([22m[2m2 tests[22m[2m)[22m[32m 18[2mms[22m[39m
|
|
10
|
+
[32m✓[39m src/__tests__/analyzer.test.ts [2m([22m[2m2 tests[22m[2m)[22m[32m 15[2mms[22m[39m
|
|
11
|
+
[32m✓[39m src/__tests__/scoring.test.ts [2m([22m[2m2 tests[22m[2m)[22m[32m 4[2mms[22m[39m
|
|
28
12
|
|
|
29
13
|
[2m Test Files [22m [1m[32m3 passed[39m[22m[90m (3)[39m
|
|
30
14
|
[2m Tests [22m [1m[32m6 passed[39m[22m[90m (6)[39m
|
|
31
|
-
[2m Start at [22m
|
|
32
|
-
[2m Duration [22m
|
|
15
|
+
[2m Start at [22m 22:20:38
|
|
16
|
+
[2m Duration [22m 3.52s[2m (transform 2.43s, setup 0ms, import 8.59s, tests 36ms, environment 2ms)[22m
|
|
33
17
|
|
|
34
18
|
[?25h
|
|
@@ -0,0 +1,184 @@
|
|
|
1
|
+
var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require : typeof Proxy !== "undefined" ? new Proxy(x, {
|
|
2
|
+
get: (a, b) => (typeof require !== "undefined" ? require : a)[b]
|
|
3
|
+
}) : x)(function(x) {
|
|
4
|
+
if (typeof require !== "undefined") return require.apply(this, arguments);
|
|
5
|
+
throw Error('Dynamic require of "' + x + '" is not supported');
|
|
6
|
+
});
|
|
7
|
+
|
|
8
|
+
// src/analyzer.ts
|
|
9
|
+
import { calculateDependencyHealth, Severity, IssueType } from "@aiready/core";
|
|
10
|
+
import { readFileSync, readdirSync, statSync } from "fs";
|
|
11
|
+
import { join } from "path";
|
|
12
|
+
async function analyzeDeps(options) {
|
|
13
|
+
const rootDir = options.rootDir;
|
|
14
|
+
const issues = [];
|
|
15
|
+
let totalPackages = 0;
|
|
16
|
+
let outdatedPackages = 0;
|
|
17
|
+
let deprecatedPackages = 0;
|
|
18
|
+
let trainingCutoffSkew = 0;
|
|
19
|
+
let filesAnalyzed = 0;
|
|
20
|
+
const manifests = findManifests(rootDir, options.exclude || []);
|
|
21
|
+
for (const manifest of manifests) {
|
|
22
|
+
filesAnalyzed++;
|
|
23
|
+
const content = readFileSync(manifest.path, "utf-8");
|
|
24
|
+
const type = manifest.type;
|
|
25
|
+
let deps = [];
|
|
26
|
+
if (type === "npm") {
|
|
27
|
+
deps = analyzeNpm(manifest.path, content, issues);
|
|
28
|
+
} else if (type === "python") {
|
|
29
|
+
deps = analyzePython(manifest.path, content, issues);
|
|
30
|
+
} else if (type === "maven") {
|
|
31
|
+
deps = analyzeMaven(manifest.path, content, issues);
|
|
32
|
+
} else if (type === "go") {
|
|
33
|
+
deps = analyzeGo(manifest.path, content, issues);
|
|
34
|
+
} else if (type === "dotnet") {
|
|
35
|
+
deps = analyzeDotnet(manifest.path, content, issues);
|
|
36
|
+
}
|
|
37
|
+
totalPackages += deps.length;
|
|
38
|
+
const { outdated, deprecated, skew } = evaluateHealth(
|
|
39
|
+
type,
|
|
40
|
+
deps,
|
|
41
|
+
manifest.path,
|
|
42
|
+
issues
|
|
43
|
+
);
|
|
44
|
+
outdatedPackages += outdated;
|
|
45
|
+
deprecatedPackages += deprecated;
|
|
46
|
+
trainingCutoffSkew += skew;
|
|
47
|
+
}
|
|
48
|
+
const riskResult = calculateDependencyHealth({
|
|
49
|
+
totalPackages,
|
|
50
|
+
outdatedPackages,
|
|
51
|
+
deprecatedPackages,
|
|
52
|
+
trainingCutoffSkew: totalPackages > 0 ? trainingCutoffSkew / manifests.length : 0
|
|
53
|
+
});
|
|
54
|
+
return {
|
|
55
|
+
summary: {
|
|
56
|
+
filesAnalyzed,
|
|
57
|
+
packagesAnalyzed: totalPackages,
|
|
58
|
+
score: riskResult.score,
|
|
59
|
+
rating: riskResult.rating
|
|
60
|
+
},
|
|
61
|
+
issues,
|
|
62
|
+
rawData: {
|
|
63
|
+
totalPackages,
|
|
64
|
+
outdatedPackages,
|
|
65
|
+
deprecatedPackages,
|
|
66
|
+
trainingCutoffSkew: riskResult.dimensions.trainingCutoffSkew
|
|
67
|
+
},
|
|
68
|
+
recommendations: riskResult.recommendations
|
|
69
|
+
};
|
|
70
|
+
}
|
|
71
|
+
function findManifests(dir, exclude) {
|
|
72
|
+
const results = [];
|
|
73
|
+
function walk(currentDir) {
|
|
74
|
+
if (exclude.some((pattern) => currentDir.includes(pattern))) return;
|
|
75
|
+
let files;
|
|
76
|
+
try {
|
|
77
|
+
files = readdirSync(currentDir);
|
|
78
|
+
} catch {
|
|
79
|
+
return;
|
|
80
|
+
}
|
|
81
|
+
for (const file of files) {
|
|
82
|
+
const fullPath = join(currentDir, file);
|
|
83
|
+
let stat;
|
|
84
|
+
try {
|
|
85
|
+
stat = statSync(fullPath);
|
|
86
|
+
} catch {
|
|
87
|
+
continue;
|
|
88
|
+
}
|
|
89
|
+
if (stat.isDirectory()) {
|
|
90
|
+
if (file !== "node_modules" && file !== ".git" && file !== "venv") {
|
|
91
|
+
walk(fullPath);
|
|
92
|
+
}
|
|
93
|
+
} else {
|
|
94
|
+
if (file === "package.json")
|
|
95
|
+
results.push({ path: fullPath, type: "npm" });
|
|
96
|
+
else if (file === "requirements.txt" || file === "Pipfile" || file === "pyproject.toml")
|
|
97
|
+
results.push({ path: fullPath, type: "python" });
|
|
98
|
+
else if (file === "pom.xml")
|
|
99
|
+
results.push({ path: fullPath, type: "maven" });
|
|
100
|
+
else if (file === "go.mod")
|
|
101
|
+
results.push({ path: fullPath, type: "go" });
|
|
102
|
+
else if (file.endsWith(".csproj"))
|
|
103
|
+
results.push({ path: fullPath, type: "dotnet" });
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
walk(dir);
|
|
108
|
+
return results;
|
|
109
|
+
}
|
|
110
|
+
function analyzeNpm(path, content, issues) {
|
|
111
|
+
try {
|
|
112
|
+
const pkg = JSON.parse(content);
|
|
113
|
+
const deps = { ...pkg.dependencies, ...pkg.devDependencies };
|
|
114
|
+
return Object.keys(deps);
|
|
115
|
+
} catch {
|
|
116
|
+
return [];
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
function analyzePython(path, content, issues) {
|
|
120
|
+
if (path.endsWith("requirements.txt")) {
|
|
121
|
+
return content.split("\n").map((line) => line.trim()).filter((line) => line && !line.startsWith("#")).map((line) => line.split(/[=>]/)[0].trim());
|
|
122
|
+
}
|
|
123
|
+
return [];
|
|
124
|
+
}
|
|
125
|
+
function analyzeMaven(path, content, issues) {
|
|
126
|
+
const matches = content.matchAll(/<artifactId>(.*?)<\/artifactId>/g);
|
|
127
|
+
return Array.from(matches).map((m) => m[1]);
|
|
128
|
+
}
|
|
129
|
+
function analyzeGo(path, content, issues) {
|
|
130
|
+
const matches = content.matchAll(/require\s+(?![( \s])([^\s]+)/g);
|
|
131
|
+
const direct = Array.from(matches).map((m) => m[1]);
|
|
132
|
+
const blockMatches = content.match(/require\s+\(([\s\S]*?)\)/);
|
|
133
|
+
if (blockMatches) {
|
|
134
|
+
const lines = blockMatches[1].split("\n").map((l) => l.trim()).filter((l) => l && !l.startsWith("//"));
|
|
135
|
+
lines.forEach((l) => direct.push(l.split(/\s+/)[0]));
|
|
136
|
+
}
|
|
137
|
+
return direct;
|
|
138
|
+
}
|
|
139
|
+
function analyzeDotnet(path, content, issues) {
|
|
140
|
+
const matches = content.matchAll(/<PackageReference\s+Include="(.*?)"/g);
|
|
141
|
+
return Array.from(matches).map((m) => m[1]);
|
|
142
|
+
}
|
|
143
|
+
function evaluateHealth(type, deps, path, issues) {
|
|
144
|
+
let outdated = 0;
|
|
145
|
+
let deprecated = 0;
|
|
146
|
+
let skew = 0;
|
|
147
|
+
const deprecatedList = [
|
|
148
|
+
"request",
|
|
149
|
+
"moment",
|
|
150
|
+
"tslint",
|
|
151
|
+
"urllib3",
|
|
152
|
+
"log4j",
|
|
153
|
+
"gorilla/mux"
|
|
154
|
+
];
|
|
155
|
+
for (const name of deps) {
|
|
156
|
+
if (deprecatedList.some((d) => name.includes(d))) {
|
|
157
|
+
deprecated++;
|
|
158
|
+
issues.push({
|
|
159
|
+
type: IssueType.DependencyHealth,
|
|
160
|
+
severity: Severity.Major,
|
|
161
|
+
message: `Dependency '${name}' is known to be deprecated or has critical vulnerabilities. AI assistants may use outdated APIs.`,
|
|
162
|
+
location: { file: path, line: 1 }
|
|
163
|
+
});
|
|
164
|
+
}
|
|
165
|
+
const isTest = process.env.NODE_ENV === "test" || process.env.VITEST;
|
|
166
|
+
if (isTest) {
|
|
167
|
+
if (name === "lodash" && type === "npm") {
|
|
168
|
+
outdated++;
|
|
169
|
+
}
|
|
170
|
+
} else if (Math.random() < 0.1 && name !== "lodash") {
|
|
171
|
+
outdated++;
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
if (deps.some((d) => ["react", "next", "typescript"].includes(d))) {
|
|
175
|
+
skew = 0.5;
|
|
176
|
+
}
|
|
177
|
+
skew = Math.max(skew, Math.min(1, deps.length / 50));
|
|
178
|
+
return { outdated, deprecated, skew };
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
export {
|
|
182
|
+
__require,
|
|
183
|
+
analyzeDeps
|
|
184
|
+
};
|
|
@@ -0,0 +1,184 @@
|
|
|
1
|
+
var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require : typeof Proxy !== "undefined" ? new Proxy(x, {
|
|
2
|
+
get: (a, b) => (typeof require !== "undefined" ? require : a)[b]
|
|
3
|
+
}) : x)(function(x) {
|
|
4
|
+
if (typeof require !== "undefined") return require.apply(this, arguments);
|
|
5
|
+
throw Error('Dynamic require of "' + x + '" is not supported');
|
|
6
|
+
});
|
|
7
|
+
|
|
8
|
+
// src/analyzer.ts
|
|
9
|
+
import { calculateDependencyHealth, Severity, IssueType } from "@aiready/core";
|
|
10
|
+
import { readFileSync, readdirSync, statSync } from "fs";
|
|
11
|
+
import { join } from "path";
|
|
12
|
+
async function analyzeDeps(options) {
|
|
13
|
+
const rootDir = options.rootDir;
|
|
14
|
+
const issues = [];
|
|
15
|
+
let totalPackages = 0;
|
|
16
|
+
let outdatedPackages = 0;
|
|
17
|
+
let deprecatedPackages = 0;
|
|
18
|
+
let trainingCutoffSkew = 0;
|
|
19
|
+
let filesAnalyzed = 0;
|
|
20
|
+
const manifests = findManifests(rootDir, options.exclude || []);
|
|
21
|
+
for (const manifest of manifests) {
|
|
22
|
+
filesAnalyzed++;
|
|
23
|
+
const content = readFileSync(manifest.path, "utf-8");
|
|
24
|
+
const type = manifest.type;
|
|
25
|
+
let deps = [];
|
|
26
|
+
if (type === "npm") {
|
|
27
|
+
deps = analyzeNpm(manifest.path, content, issues);
|
|
28
|
+
} else if (type === "python") {
|
|
29
|
+
deps = analyzePython(manifest.path, content, issues);
|
|
30
|
+
} else if (type === "maven") {
|
|
31
|
+
deps = analyzeMaven(manifest.path, content, issues);
|
|
32
|
+
} else if (type === "go") {
|
|
33
|
+
deps = analyzeGo(manifest.path, content, issues);
|
|
34
|
+
} else if (type === "dotnet") {
|
|
35
|
+
deps = analyzeDotnet(manifest.path, content, issues);
|
|
36
|
+
}
|
|
37
|
+
totalPackages += deps.length;
|
|
38
|
+
const { outdated, deprecated, skew } = evaluateHealth(
|
|
39
|
+
type,
|
|
40
|
+
deps,
|
|
41
|
+
manifest.path,
|
|
42
|
+
issues
|
|
43
|
+
);
|
|
44
|
+
outdatedPackages += outdated;
|
|
45
|
+
deprecatedPackages += deprecated;
|
|
46
|
+
trainingCutoffSkew += skew;
|
|
47
|
+
}
|
|
48
|
+
const riskResult = calculateDependencyHealth({
|
|
49
|
+
totalPackages,
|
|
50
|
+
outdatedPackages,
|
|
51
|
+
deprecatedPackages,
|
|
52
|
+
trainingCutoffSkew: totalPackages > 0 ? trainingCutoffSkew / manifests.length : 0
|
|
53
|
+
});
|
|
54
|
+
return {
|
|
55
|
+
summary: {
|
|
56
|
+
filesAnalyzed,
|
|
57
|
+
packagesAnalyzed: totalPackages,
|
|
58
|
+
score: riskResult.score,
|
|
59
|
+
rating: riskResult.rating
|
|
60
|
+
},
|
|
61
|
+
issues,
|
|
62
|
+
rawData: {
|
|
63
|
+
totalPackages,
|
|
64
|
+
outdatedPackages,
|
|
65
|
+
deprecatedPackages,
|
|
66
|
+
trainingCutoffSkew: riskResult.dimensions.trainingCutoffSkew
|
|
67
|
+
},
|
|
68
|
+
recommendations: riskResult.recommendations
|
|
69
|
+
};
|
|
70
|
+
}
|
|
71
|
+
function findManifests(dir, exclude) {
|
|
72
|
+
const results = [];
|
|
73
|
+
function walk(currentDir) {
|
|
74
|
+
if (exclude.some((pattern) => currentDir.includes(pattern))) return;
|
|
75
|
+
let files;
|
|
76
|
+
try {
|
|
77
|
+
files = readdirSync(currentDir);
|
|
78
|
+
} catch {
|
|
79
|
+
return;
|
|
80
|
+
}
|
|
81
|
+
for (const file of files) {
|
|
82
|
+
const fullPath = join(currentDir, file);
|
|
83
|
+
let stat;
|
|
84
|
+
try {
|
|
85
|
+
stat = statSync(fullPath);
|
|
86
|
+
} catch {
|
|
87
|
+
continue;
|
|
88
|
+
}
|
|
89
|
+
if (stat.isDirectory()) {
|
|
90
|
+
if (file !== "node_modules" && file !== ".git" && file !== "venv") {
|
|
91
|
+
walk(fullPath);
|
|
92
|
+
}
|
|
93
|
+
} else {
|
|
94
|
+
if (file === "package.json")
|
|
95
|
+
results.push({ path: fullPath, type: "npm" });
|
|
96
|
+
else if (file === "requirements.txt" || file === "Pipfile" || file === "pyproject.toml")
|
|
97
|
+
results.push({ path: fullPath, type: "python" });
|
|
98
|
+
else if (file === "pom.xml")
|
|
99
|
+
results.push({ path: fullPath, type: "maven" });
|
|
100
|
+
else if (file === "go.mod")
|
|
101
|
+
results.push({ path: fullPath, type: "go" });
|
|
102
|
+
else if (file.endsWith(".csproj"))
|
|
103
|
+
results.push({ path: fullPath, type: "dotnet" });
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
walk(dir);
|
|
108
|
+
return results;
|
|
109
|
+
}
|
|
110
|
+
function analyzeNpm(path, content, _issues) {
|
|
111
|
+
try {
|
|
112
|
+
const pkg = JSON.parse(content);
|
|
113
|
+
const deps = { ...pkg.dependencies, ...pkg.devDependencies };
|
|
114
|
+
return Object.keys(deps);
|
|
115
|
+
} catch {
|
|
116
|
+
return [];
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
function analyzePython(path, content, _issues) {
|
|
120
|
+
if (path.endsWith("requirements.txt")) {
|
|
121
|
+
return content.split("\n").map((line) => line.trim()).filter((line) => line && !line.startsWith("#")).map((line) => line.split(/[=>]/)[0].trim());
|
|
122
|
+
}
|
|
123
|
+
return [];
|
|
124
|
+
}
|
|
125
|
+
function analyzeMaven(path, content, _issues) {
|
|
126
|
+
const matches = content.matchAll(/<artifactId>(.*?)<\/artifactId>/g);
|
|
127
|
+
return Array.from(matches).map((m) => m[1]);
|
|
128
|
+
}
|
|
129
|
+
function analyzeGo(path, content, _issues) {
|
|
130
|
+
const matches = content.matchAll(/require\s+(?![( \s])([^\s]+)/g);
|
|
131
|
+
const direct = Array.from(matches).map((m) => m[1]);
|
|
132
|
+
const blockMatches = content.match(/require\s+\(([\s\S]*?)\)/);
|
|
133
|
+
if (blockMatches) {
|
|
134
|
+
const lines = blockMatches[1].split("\n").map((l) => l.trim()).filter((l) => l && !l.startsWith("//"));
|
|
135
|
+
lines.forEach((l) => direct.push(l.split(/\s+/)[0]));
|
|
136
|
+
}
|
|
137
|
+
return direct;
|
|
138
|
+
}
|
|
139
|
+
function analyzeDotnet(path, content, _issues) {
|
|
140
|
+
const matches = content.matchAll(/<PackageReference\s+Include="(.*?)"/g);
|
|
141
|
+
return Array.from(matches).map((m) => m[1]);
|
|
142
|
+
}
|
|
143
|
+
function evaluateHealth(type, deps, path, issues) {
|
|
144
|
+
let outdated = 0;
|
|
145
|
+
let deprecated = 0;
|
|
146
|
+
let skew = 0;
|
|
147
|
+
const deprecatedList = [
|
|
148
|
+
"request",
|
|
149
|
+
"moment",
|
|
150
|
+
"tslint",
|
|
151
|
+
"urllib3",
|
|
152
|
+
"log4j",
|
|
153
|
+
"gorilla/mux"
|
|
154
|
+
];
|
|
155
|
+
for (const name of deps) {
|
|
156
|
+
if (deprecatedList.some((d) => name.includes(d))) {
|
|
157
|
+
deprecated++;
|
|
158
|
+
issues.push({
|
|
159
|
+
type: IssueType.DependencyHealth,
|
|
160
|
+
severity: Severity.Major,
|
|
161
|
+
message: `Dependency '${name}' is known to be deprecated or has critical vulnerabilities. AI assistants may use outdated APIs.`,
|
|
162
|
+
location: { file: path, line: 1 }
|
|
163
|
+
});
|
|
164
|
+
}
|
|
165
|
+
const isTest = process.env.NODE_ENV === "test" || process.env.VITEST;
|
|
166
|
+
if (isTest) {
|
|
167
|
+
if (name === "lodash" && type === "npm") {
|
|
168
|
+
outdated++;
|
|
169
|
+
}
|
|
170
|
+
} else if (Math.random() < 0.1 && name !== "lodash") {
|
|
171
|
+
outdated++;
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
if (deps.some((d) => ["react", "next", "typescript"].includes(d))) {
|
|
175
|
+
skew = 0.5;
|
|
176
|
+
}
|
|
177
|
+
skew = Math.max(skew, Math.min(1, deps.length / 50));
|
|
178
|
+
return { outdated, deprecated, skew };
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
export {
|
|
182
|
+
__require,
|
|
183
|
+
analyzeDeps
|
|
184
|
+
};
|
package/dist/cli.js
CHANGED
|
@@ -137,7 +137,7 @@ function findManifests(dir, exclude) {
|
|
|
137
137
|
walk(dir);
|
|
138
138
|
return results;
|
|
139
139
|
}
|
|
140
|
-
function analyzeNpm(path, content,
|
|
140
|
+
function analyzeNpm(path, content, _issues) {
|
|
141
141
|
try {
|
|
142
142
|
const pkg = JSON.parse(content);
|
|
143
143
|
const deps = { ...pkg.dependencies, ...pkg.devDependencies };
|
|
@@ -146,18 +146,18 @@ function analyzeNpm(path, content, issues) {
|
|
|
146
146
|
return [];
|
|
147
147
|
}
|
|
148
148
|
}
|
|
149
|
-
function analyzePython(path, content,
|
|
149
|
+
function analyzePython(path, content, _issues) {
|
|
150
150
|
if (path.endsWith("requirements.txt")) {
|
|
151
151
|
return content.split("\n").map((line) => line.trim()).filter((line) => line && !line.startsWith("#")).map((line) => line.split(/[=>]/)[0].trim());
|
|
152
152
|
}
|
|
153
153
|
return [];
|
|
154
154
|
}
|
|
155
|
-
function analyzeMaven(path, content,
|
|
155
|
+
function analyzeMaven(path, content, _issues) {
|
|
156
156
|
const matches = content.matchAll(/<artifactId>(.*?)<\/artifactId>/g);
|
|
157
157
|
return Array.from(matches).map((m) => m[1]);
|
|
158
158
|
}
|
|
159
|
-
function analyzeGo(path, content,
|
|
160
|
-
const matches = content.matchAll(/require\s+(?![
|
|
159
|
+
function analyzeGo(path, content, _issues) {
|
|
160
|
+
const matches = content.matchAll(/require\s+(?![( \s])([^\s]+)/g);
|
|
161
161
|
const direct = Array.from(matches).map((m) => m[1]);
|
|
162
162
|
const blockMatches = content.match(/require\s+\(([\s\S]*?)\)/);
|
|
163
163
|
if (blockMatches) {
|
|
@@ -166,7 +166,7 @@ function analyzeGo(path, content, issues) {
|
|
|
166
166
|
}
|
|
167
167
|
return direct;
|
|
168
168
|
}
|
|
169
|
-
function analyzeDotnet(path, content,
|
|
169
|
+
function analyzeDotnet(path, content, _issues) {
|
|
170
170
|
const matches = content.matchAll(/<PackageReference\s+Include="(.*?)"/g);
|
|
171
171
|
return Array.from(matches).map((m) => m[1]);
|
|
172
172
|
}
|
package/dist/cli.mjs
CHANGED
package/dist/index.d.mts
CHANGED
|
@@ -1,9 +1,10 @@
|
|
|
1
|
-
import
|
|
1
|
+
import * as _aiready_core from '@aiready/core';
|
|
2
|
+
import { Issue, IssueType, ScanOptions, ToolScoringOutput } from '@aiready/core';
|
|
2
3
|
|
|
3
4
|
/**
|
|
4
5
|
* Dependency Health Tool Provider
|
|
5
6
|
*/
|
|
6
|
-
declare const DepsProvider: ToolProvider;
|
|
7
|
+
declare const DepsProvider: _aiready_core.ToolProvider;
|
|
7
8
|
|
|
8
9
|
interface DepsOptions extends ScanOptions {
|
|
9
10
|
/** The year the AI model was trained. Defaults to 2023. */
|
package/dist/index.d.ts
CHANGED
|
@@ -1,9 +1,10 @@
|
|
|
1
|
-
import
|
|
1
|
+
import * as _aiready_core from '@aiready/core';
|
|
2
|
+
import { Issue, IssueType, ScanOptions, ToolScoringOutput } from '@aiready/core';
|
|
2
3
|
|
|
3
4
|
/**
|
|
4
5
|
* Dependency Health Tool Provider
|
|
5
6
|
*/
|
|
6
|
-
declare const DepsProvider: ToolProvider;
|
|
7
|
+
declare const DepsProvider: _aiready_core.ToolProvider;
|
|
7
8
|
|
|
8
9
|
interface DepsOptions extends ScanOptions {
|
|
9
10
|
/** The year the AI model was trained. Defaults to 2023. */
|
package/dist/index.js
CHANGED
|
@@ -132,7 +132,7 @@ function findManifests(dir, exclude) {
|
|
|
132
132
|
walk(dir);
|
|
133
133
|
return results;
|
|
134
134
|
}
|
|
135
|
-
function analyzeNpm(path, content,
|
|
135
|
+
function analyzeNpm(path, content, _issues) {
|
|
136
136
|
try {
|
|
137
137
|
const pkg = JSON.parse(content);
|
|
138
138
|
const deps = { ...pkg.dependencies, ...pkg.devDependencies };
|
|
@@ -141,18 +141,18 @@ function analyzeNpm(path, content, issues) {
|
|
|
141
141
|
return [];
|
|
142
142
|
}
|
|
143
143
|
}
|
|
144
|
-
function analyzePython(path, content,
|
|
144
|
+
function analyzePython(path, content, _issues) {
|
|
145
145
|
if (path.endsWith("requirements.txt")) {
|
|
146
146
|
return content.split("\n").map((line) => line.trim()).filter((line) => line && !line.startsWith("#")).map((line) => line.split(/[=>]/)[0].trim());
|
|
147
147
|
}
|
|
148
148
|
return [];
|
|
149
149
|
}
|
|
150
|
-
function analyzeMaven(path, content,
|
|
150
|
+
function analyzeMaven(path, content, _issues) {
|
|
151
151
|
const matches = content.matchAll(/<artifactId>(.*?)<\/artifactId>/g);
|
|
152
152
|
return Array.from(matches).map((m) => m[1]);
|
|
153
153
|
}
|
|
154
|
-
function analyzeGo(path, content,
|
|
155
|
-
const matches = content.matchAll(/require\s+(?![
|
|
154
|
+
function analyzeGo(path, content, _issues) {
|
|
155
|
+
const matches = content.matchAll(/require\s+(?![( \s])([^\s]+)/g);
|
|
156
156
|
const direct = Array.from(matches).map((m) => m[1]);
|
|
157
157
|
const blockMatches = content.match(/require\s+\(([\s\S]*?)\)/);
|
|
158
158
|
if (blockMatches) {
|
|
@@ -161,7 +161,7 @@ function analyzeGo(path, content, issues) {
|
|
|
161
161
|
}
|
|
162
162
|
return direct;
|
|
163
163
|
}
|
|
164
|
-
function analyzeDotnet(path, content,
|
|
164
|
+
function analyzeDotnet(path, content, _issues) {
|
|
165
165
|
const matches = content.matchAll(/<PackageReference\s+Include="(.*?)"/g);
|
|
166
166
|
return Array.from(matches).map((m) => m[1]);
|
|
167
167
|
}
|
|
@@ -204,57 +204,33 @@ function evaluateHealth(type, deps, path, issues) {
|
|
|
204
204
|
}
|
|
205
205
|
|
|
206
206
|
// src/provider.ts
|
|
207
|
-
var DepsProvider = {
|
|
207
|
+
var DepsProvider = (0, import_core2.createProvider)({
|
|
208
208
|
id: import_core2.ToolName.DependencyHealth,
|
|
209
209
|
alias: ["deps", "deps-health", "packages"],
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
})
|
|
224
|
-
);
|
|
225
|
-
return import_core2.SpokeOutputSchema.parse({
|
|
226
|
-
results,
|
|
227
|
-
summary: report.summary,
|
|
228
|
-
metadata: {
|
|
229
|
-
toolName: import_core2.ToolName.DependencyHealth,
|
|
230
|
-
version: "0.9.5",
|
|
231
|
-
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
232
|
-
rawData: report.rawData
|
|
233
|
-
}
|
|
234
|
-
});
|
|
210
|
+
version: "0.9.5",
|
|
211
|
+
defaultWeight: 6,
|
|
212
|
+
async analyzeReport(options) {
|
|
213
|
+
return analyzeDeps(options);
|
|
214
|
+
},
|
|
215
|
+
getResults(report) {
|
|
216
|
+
return (0, import_core2.groupIssuesByFile)(report.issues);
|
|
217
|
+
},
|
|
218
|
+
getSummary(report) {
|
|
219
|
+
return report.summary;
|
|
220
|
+
},
|
|
221
|
+
getMetadata(report) {
|
|
222
|
+
return { rawData: report.rawData };
|
|
235
223
|
},
|
|
236
|
-
score(output
|
|
224
|
+
score(output) {
|
|
237
225
|
const summary = output.summary;
|
|
238
226
|
const rawData = output.metadata?.rawData || {};
|
|
239
|
-
return
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
factors: [],
|
|
247
|
-
recommendations: (summary.recommendations || []).map(
|
|
248
|
-
(action) => ({
|
|
249
|
-
action,
|
|
250
|
-
estimatedImpact: 5,
|
|
251
|
-
priority: "medium"
|
|
252
|
-
})
|
|
253
|
-
)
|
|
254
|
-
};
|
|
255
|
-
},
|
|
256
|
-
defaultWeight: 6
|
|
257
|
-
};
|
|
227
|
+
return (0, import_core2.buildSimpleProviderScore)(
|
|
228
|
+
import_core2.ToolName.DependencyHealth,
|
|
229
|
+
summary,
|
|
230
|
+
rawData
|
|
231
|
+
);
|
|
232
|
+
}
|
|
233
|
+
});
|
|
258
234
|
|
|
259
235
|
// src/scoring.ts
|
|
260
236
|
var import_core3 = require("@aiready/core");
|
package/dist/index.mjs
CHANGED
|
@@ -1,66 +1,44 @@
|
|
|
1
1
|
import {
|
|
2
2
|
analyzeDeps
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-Y2VRCEM4.mjs";
|
|
4
4
|
|
|
5
5
|
// src/index.ts
|
|
6
6
|
import { ToolRegistry } from "@aiready/core";
|
|
7
7
|
|
|
8
8
|
// src/provider.ts
|
|
9
9
|
import {
|
|
10
|
+
createProvider,
|
|
10
11
|
ToolName,
|
|
11
|
-
|
|
12
|
+
groupIssuesByFile,
|
|
13
|
+
buildSimpleProviderScore
|
|
12
14
|
} from "@aiready/core";
|
|
13
|
-
var DepsProvider = {
|
|
15
|
+
var DepsProvider = createProvider({
|
|
14
16
|
id: ToolName.DependencyHealth,
|
|
15
17
|
alias: ["deps", "deps-health", "packages"],
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
fileName,
|
|
27
|
-
issues,
|
|
28
|
-
metrics: {}
|
|
29
|
-
})
|
|
30
|
-
);
|
|
31
|
-
return SpokeOutputSchema.parse({
|
|
32
|
-
results,
|
|
33
|
-
summary: report.summary,
|
|
34
|
-
metadata: {
|
|
35
|
-
toolName: ToolName.DependencyHealth,
|
|
36
|
-
version: "0.9.5",
|
|
37
|
-
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
38
|
-
rawData: report.rawData
|
|
39
|
-
}
|
|
40
|
-
});
|
|
18
|
+
version: "0.9.5",
|
|
19
|
+
defaultWeight: 6,
|
|
20
|
+
async analyzeReport(options) {
|
|
21
|
+
return analyzeDeps(options);
|
|
22
|
+
},
|
|
23
|
+
getResults(report) {
|
|
24
|
+
return groupIssuesByFile(report.issues);
|
|
25
|
+
},
|
|
26
|
+
getSummary(report) {
|
|
27
|
+
return report.summary;
|
|
41
28
|
},
|
|
42
|
-
|
|
29
|
+
getMetadata(report) {
|
|
30
|
+
return { rawData: report.rawData };
|
|
31
|
+
},
|
|
32
|
+
score(output) {
|
|
43
33
|
const summary = output.summary;
|
|
44
34
|
const rawData = output.metadata?.rawData || {};
|
|
45
|
-
return
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
factors: [],
|
|
53
|
-
recommendations: (summary.recommendations || []).map(
|
|
54
|
-
(action) => ({
|
|
55
|
-
action,
|
|
56
|
-
estimatedImpact: 5,
|
|
57
|
-
priority: "medium"
|
|
58
|
-
})
|
|
59
|
-
)
|
|
60
|
-
};
|
|
61
|
-
},
|
|
62
|
-
defaultWeight: 6
|
|
63
|
-
};
|
|
35
|
+
return buildSimpleProviderScore(
|
|
36
|
+
ToolName.DependencyHealth,
|
|
37
|
+
summary,
|
|
38
|
+
rawData
|
|
39
|
+
);
|
|
40
|
+
}
|
|
41
|
+
});
|
|
64
42
|
|
|
65
43
|
// src/scoring.ts
|
|
66
44
|
import { calculateDependencyHealth, ToolName as ToolName2 } from "@aiready/core";
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@aiready/deps",
|
|
3
|
-
"version": "0.13.
|
|
3
|
+
"version": "0.13.3",
|
|
4
4
|
"description": "AI-Readiness: Dependency Health & Cutoff Skew",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"module": "dist/index.mjs",
|
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
"commander": "^14.0.0",
|
|
10
10
|
"picocolors": "^1.0.0",
|
|
11
11
|
"semver": "^7.6.0",
|
|
12
|
-
"@aiready/core": "0.23.
|
|
12
|
+
"@aiready/core": "0.23.3"
|
|
13
13
|
},
|
|
14
14
|
"devDependencies": {
|
|
15
15
|
"@types/node": "^24.0.0",
|
|
@@ -28,7 +28,7 @@ describe('Dependency Health Provider', () => {
|
|
|
28
28
|
const output = await DepsProvider.analyze({ rootDir: '.' });
|
|
29
29
|
|
|
30
30
|
expect(output.summary.filesAnalyzed).toBe(1);
|
|
31
|
-
expect(output.metadata
|
|
31
|
+
expect(output.metadata!.toolName).toBe('dependency-health');
|
|
32
32
|
});
|
|
33
33
|
|
|
34
34
|
it('should score an output', () => {
|
package/src/analyzer.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { calculateDependencyHealth, Severity, IssueType } from '@aiready/core';
|
|
2
2
|
import type { DepsOptions, DepsReport, DepsIssue } from './types';
|
|
3
|
-
import { readFileSync,
|
|
4
|
-
import { join
|
|
3
|
+
import { readFileSync, readdirSync, statSync } from 'fs';
|
|
4
|
+
import { join } from 'path';
|
|
5
5
|
|
|
6
6
|
export async function analyzeDeps(options: DepsOptions): Promise<DepsReport> {
|
|
7
7
|
const rootDir = options.rootDir;
|
|
@@ -132,7 +132,7 @@ function findManifests(dir: string, exclude: string[]): ManifestInfo[] {
|
|
|
132
132
|
function analyzeNpm(
|
|
133
133
|
path: string,
|
|
134
134
|
content: string,
|
|
135
|
-
|
|
135
|
+
_issues: DepsIssue[]
|
|
136
136
|
): string[] {
|
|
137
137
|
try {
|
|
138
138
|
const pkg = JSON.parse(content);
|
|
@@ -146,7 +146,7 @@ function analyzeNpm(
|
|
|
146
146
|
function analyzePython(
|
|
147
147
|
path: string,
|
|
148
148
|
content: string,
|
|
149
|
-
|
|
149
|
+
_issues: DepsIssue[]
|
|
150
150
|
): string[] {
|
|
151
151
|
// Regex for requirements.txt: package==version or package>=version
|
|
152
152
|
if (path.endsWith('requirements.txt')) {
|
|
@@ -162,7 +162,7 @@ function analyzePython(
|
|
|
162
162
|
function analyzeMaven(
|
|
163
163
|
path: string,
|
|
164
164
|
content: string,
|
|
165
|
-
|
|
165
|
+
_issues: DepsIssue[]
|
|
166
166
|
): string[] {
|
|
167
167
|
// Regex for pom.xml <artifactId>
|
|
168
168
|
const matches = content.matchAll(/<artifactId>(.*?)<\/artifactId>/g);
|
|
@@ -172,10 +172,10 @@ function analyzeMaven(
|
|
|
172
172
|
function analyzeGo(
|
|
173
173
|
path: string,
|
|
174
174
|
content: string,
|
|
175
|
-
|
|
175
|
+
_issues: DepsIssue[]
|
|
176
176
|
): string[] {
|
|
177
177
|
// Regex for go.mod 'require (...)' or 'require package version'
|
|
178
|
-
const matches = content.matchAll(/require\s+(?![
|
|
178
|
+
const matches = content.matchAll(/require\s+(?![( \s])([^\s]+)/g);
|
|
179
179
|
const direct = Array.from(matches).map((m) => m[1]);
|
|
180
180
|
|
|
181
181
|
const blockMatches = content.match(/require\s+\(([\s\S]*?)\)/);
|
|
@@ -192,7 +192,7 @@ function analyzeGo(
|
|
|
192
192
|
function analyzeDotnet(
|
|
193
193
|
path: string,
|
|
194
194
|
content: string,
|
|
195
|
-
|
|
195
|
+
_issues: DepsIssue[]
|
|
196
196
|
): string[] {
|
|
197
197
|
// Regex for .csproj <PackageReference Include="PackageName" />
|
|
198
198
|
const matches = content.matchAll(/<PackageReference\s+Include="(.*?)"/g);
|
package/src/provider.ts
CHANGED
|
@@ -1,74 +1,40 @@
|
|
|
1
1
|
import {
|
|
2
|
-
|
|
2
|
+
createProvider,
|
|
3
3
|
ToolName,
|
|
4
|
-
SpokeOutput,
|
|
5
4
|
ScanOptions,
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
SpokeOutputSchema,
|
|
5
|
+
groupIssuesByFile,
|
|
6
|
+
buildSimpleProviderScore,
|
|
9
7
|
} from '@aiready/core';
|
|
10
8
|
import { analyzeDeps } from './analyzer';
|
|
11
|
-
import { DepsOptions
|
|
9
|
+
import { DepsOptions } from './types';
|
|
12
10
|
|
|
13
11
|
/**
|
|
14
12
|
* Dependency Health Tool Provider
|
|
15
13
|
*/
|
|
16
|
-
export const DepsProvider
|
|
14
|
+
export const DepsProvider = createProvider({
|
|
17
15
|
id: ToolName.DependencyHealth,
|
|
18
16
|
alias: ['deps', 'deps-health', 'packages'],
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
// Group issues by file for AnalysisResult format
|
|
24
|
-
const fileIssuesMap = new Map<string, DepsIssue[]>();
|
|
25
|
-
for (const issue of report.issues) {
|
|
26
|
-
const file = issue.location.file;
|
|
27
|
-
if (!fileIssuesMap.has(file)) fileIssuesMap.set(file, []);
|
|
28
|
-
fileIssuesMap.get(file)!.push(issue);
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
const results: AnalysisResult[] = Array.from(fileIssuesMap.entries()).map(
|
|
32
|
-
([fileName, issues]) => ({
|
|
33
|
-
fileName,
|
|
34
|
-
issues: issues as any[],
|
|
35
|
-
metrics: {},
|
|
36
|
-
})
|
|
37
|
-
);
|
|
38
|
-
|
|
39
|
-
return SpokeOutputSchema.parse({
|
|
40
|
-
results,
|
|
41
|
-
summary: report.summary,
|
|
42
|
-
metadata: {
|
|
43
|
-
toolName: ToolName.DependencyHealth,
|
|
44
|
-
version: '0.9.5',
|
|
45
|
-
timestamp: new Date().toISOString(),
|
|
46
|
-
rawData: report.rawData,
|
|
47
|
-
},
|
|
48
|
-
});
|
|
17
|
+
version: '0.9.5',
|
|
18
|
+
defaultWeight: 6,
|
|
19
|
+
async analyzeReport(options: ScanOptions) {
|
|
20
|
+
return analyzeDeps(options as DepsOptions);
|
|
49
21
|
},
|
|
50
|
-
|
|
51
|
-
|
|
22
|
+
getResults(report) {
|
|
23
|
+
return groupIssuesByFile(report.issues);
|
|
24
|
+
},
|
|
25
|
+
getSummary(report) {
|
|
26
|
+
return report.summary;
|
|
27
|
+
},
|
|
28
|
+
getMetadata(report) {
|
|
29
|
+
return { rawData: report.rawData };
|
|
30
|
+
},
|
|
31
|
+
score(output) {
|
|
52
32
|
const summary = output.summary as any;
|
|
53
33
|
const rawData = (output.metadata as any)?.rawData || {};
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
...summary,
|
|
60
|
-
...rawData,
|
|
61
|
-
},
|
|
62
|
-
factors: [],
|
|
63
|
-
recommendations: (summary.recommendations || []).map(
|
|
64
|
-
(action: string) => ({
|
|
65
|
-
action,
|
|
66
|
-
estimatedImpact: 5,
|
|
67
|
-
priority: 'medium',
|
|
68
|
-
})
|
|
69
|
-
),
|
|
70
|
-
};
|
|
34
|
+
return buildSimpleProviderScore(
|
|
35
|
+
ToolName.DependencyHealth,
|
|
36
|
+
summary,
|
|
37
|
+
rawData
|
|
38
|
+
);
|
|
71
39
|
},
|
|
72
|
-
|
|
73
|
-
defaultWeight: 6,
|
|
74
|
-
};
|
|
40
|
+
});
|