@aiready/deps 0.1.5 → 0.1.6
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 +10 -10
- package/.turbo/turbo-test.log +6 -6
- package/README.md +1 -1
- package/dist/chunk-MN25J52Z.mjs +97 -0
- package/dist/cli.js +25 -7
- package/dist/cli.mjs +16 -6
- package/dist/index.js +10 -2
- package/dist/index.mjs +1 -1
- package/package.json +5 -5
- package/src/__tests__/analyzer.test.ts +15 -12
- package/src/analyzer.ts +20 -11
- package/src/cli.ts +20 -8
package/.turbo/turbo-build.log
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
|
|
2
2
|
|
|
3
|
-
> @aiready/deps@0.1.
|
|
3
|
+
> @aiready/deps@0.1.6 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
|
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
[34mCJS[39m Build start
|
|
11
11
|
[34mESM[39m Build start
|
|
12
12
|
|
|
13
|
-
[90m[[
|
|
13
|
+
[90m[[90m10:18:49 PM[90m][39m [43m[30m WARN [39m[49m [33m▲ [43;33m[[43;30mWARNING[43;33m][0m [1mThe condition "types" here will never be used as it comes after both "import" and "require"[0m [package.json]
|
|
14
14
|
|
|
15
15
|
package.json:32:6:
|
|
16
16
|
[37m 32 │ [32m"types"[37m: "./dist/index.d.ts"
|
|
@@ -31,7 +31,7 @@
|
|
|
31
31
|
|
|
32
32
|
|
|
33
33
|
|
|
34
|
-
[90m[[
|
|
34
|
+
[90m[[90m10:18:49 PM[90m][39m [43m[30m WARN [39m[49m [33m▲ [43;33m[[43;30mWARNING[43;33m][0m [1mThe condition "types" here will never be used as it comes after both "import" and "require"[0m [package.json]
|
|
35
35
|
|
|
36
36
|
package.json:32:6:
|
|
37
37
|
[37m 32 │ [32m"types"[37m: "./dist/index.d.ts"
|
|
@@ -51,15 +51,15 @@
|
|
|
51
51
|
|
|
52
52
|
|
|
53
53
|
|
|
54
|
-
[32mESM[39m [1mdist/cli.mjs [22m[32m1.28 KB[39m
|
|
55
|
-
[32mESM[39m [1mdist/chunk-ZLQULJAV.mjs [22m[32m3.05 KB[39m
|
|
56
54
|
[32mESM[39m [1mdist/index.mjs [22m[32m80.00 B[39m
|
|
57
|
-
[32mESM[39m
|
|
58
|
-
[
|
|
59
|
-
[
|
|
60
|
-
[32mCJS[39m
|
|
55
|
+
[32mESM[39m [1mdist/chunk-MN25J52Z.mjs [22m[32m3.13 KB[39m
|
|
56
|
+
[32mESM[39m [1mdist/cli.mjs [22m[32m1.33 KB[39m
|
|
57
|
+
[32mESM[39m ⚡️ Build success in 37ms
|
|
58
|
+
[32mCJS[39m [1mdist/index.js [22m[32m3.82 KB[39m
|
|
59
|
+
[32mCJS[39m [1mdist/cli.js [22m[32m5.80 KB[39m
|
|
60
|
+
[32mCJS[39m ⚡️ Build success in 37ms
|
|
61
61
|
DTS Build start
|
|
62
|
-
DTS ⚡️ Build success in
|
|
62
|
+
DTS ⚡️ Build success in 3559ms
|
|
63
63
|
DTS dist/cli.d.ts 108.00 B
|
|
64
64
|
DTS dist/index.d.ts 839.00 B
|
|
65
65
|
DTS dist/cli.d.mts 108.00 B
|
package/.turbo/turbo-test.log
CHANGED
|
@@ -1,16 +1,16 @@
|
|
|
1
1
|
|
|
2
2
|
|
|
3
|
-
> @aiready/deps@0.1.
|
|
3
|
+
> @aiready/deps@0.1.6 test /Users/pengcao/projects/aiready/packages/deps
|
|
4
4
|
> vitest run
|
|
5
5
|
|
|
6
|
+
[?25l
|
|
7
|
+
[1m[46m RUN [49m[22m [36mv4.0.18 [39m[90m/Users/pengcao/projects/aiready/packages/deps[39m
|
|
6
8
|
|
|
7
|
-
[
|
|
8
|
-
|
|
9
|
-
[32m✓[39m src/__tests__/analyzer.test.ts [2m ([22m[2m1 test[22m[2m)[22m[90m 64[2mms[22m[39m
|
|
9
|
+
[32m✓[39m src/__tests__/analyzer.test.ts [2m([22m[2m1 test[22m[2m)[22m[32m 2[2mms[22m[39m
|
|
10
10
|
|
|
11
11
|
[2m Test Files [22m [1m[32m1 passed[39m[22m[90m (1)[39m
|
|
12
12
|
[2m Tests [22m [1m[32m1 passed[39m[22m[90m (1)[39m
|
|
13
|
-
[2m Start at [22m
|
|
14
|
-
[2m Duration [22m
|
|
13
|
+
[2m Start at [22m 22:19:16
|
|
14
|
+
[2m Duration [22m 1.15s[2m (transform 202ms, setup 0ms, import 940ms, tests 2ms, environment 0ms)[22m
|
|
15
15
|
|
|
16
16
|
[?25h
|
package/README.md
CHANGED
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
|
|
8
8
|
## Overview
|
|
9
9
|
|
|
10
|
-
The **Dependency Health** analyzer evaluates your `package.json` to compute timeline skews against AI knowledge cutoff dates.
|
|
10
|
+
The **Dependency Health** analyzer evaluates your `package.json` to compute timeline skews against AI knowledge cutoff dates.
|
|
11
11
|
|
|
12
12
|
## 🏛️ Architecture
|
|
13
13
|
|
|
@@ -0,0 +1,97 @@
|
|
|
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 } from "@aiready/core";
|
|
10
|
+
import { readFileSync, existsSync } from "fs";
|
|
11
|
+
import { join } from "path";
|
|
12
|
+
async function analyzeDeps(options) {
|
|
13
|
+
const rootDir = options.rootDir;
|
|
14
|
+
const packageJsonPath = join(rootDir, "package.json");
|
|
15
|
+
let totalPackages = 0;
|
|
16
|
+
let outdatedPackages = 0;
|
|
17
|
+
let deprecatedPackages = 0;
|
|
18
|
+
let trainingCutoffSkew = 0;
|
|
19
|
+
const issues = [];
|
|
20
|
+
if (existsSync(packageJsonPath)) {
|
|
21
|
+
try {
|
|
22
|
+
const content = readFileSync(packageJsonPath, "utf-8");
|
|
23
|
+
const pkg = JSON.parse(content);
|
|
24
|
+
const allDeps = {
|
|
25
|
+
...pkg.dependencies || {},
|
|
26
|
+
...pkg.devDependencies || {},
|
|
27
|
+
...pkg.peerDependencies || {}
|
|
28
|
+
};
|
|
29
|
+
const depNames = Object.keys(allDeps);
|
|
30
|
+
totalPackages = depNames.length;
|
|
31
|
+
for (const [name, version] of Object.entries(allDeps)) {
|
|
32
|
+
const vStr = String(version).replace(/[^0-9.]/g, "");
|
|
33
|
+
const major = parseInt(vStr.split(".")[0] || "0", 10);
|
|
34
|
+
if ([
|
|
35
|
+
"request",
|
|
36
|
+
"moment",
|
|
37
|
+
"tslint",
|
|
38
|
+
"mkdirp",
|
|
39
|
+
"uuid",
|
|
40
|
+
"node-uuid"
|
|
41
|
+
].includes(name) && major < 4) {
|
|
42
|
+
deprecatedPackages++;
|
|
43
|
+
issues.push({
|
|
44
|
+
type: "dependency-health",
|
|
45
|
+
severity: "major",
|
|
46
|
+
message: `Dependency '${name}' is known to be deprecated. AI assistants may use outdated APIs.`,
|
|
47
|
+
location: { file: packageJsonPath, line: 1 }
|
|
48
|
+
});
|
|
49
|
+
}
|
|
50
|
+
if (major === 0) {
|
|
51
|
+
outdatedPackages++;
|
|
52
|
+
issues.push({
|
|
53
|
+
type: "dependency-health",
|
|
54
|
+
severity: "minor",
|
|
55
|
+
message: `Dependency '${name}' (${version}) is pre-v1. APIs often unstable and hard for AI to predict.`,
|
|
56
|
+
location: { file: packageJsonPath, line: 1 }
|
|
57
|
+
});
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
let skewSignals = 0;
|
|
61
|
+
if (allDeps["next"] && allDeps["next"].includes("15")) skewSignals++;
|
|
62
|
+
if (allDeps["react"] && allDeps["react"].includes("19")) skewSignals++;
|
|
63
|
+
if (allDeps["typescript"] && allDeps["typescript"].includes("5.6"))
|
|
64
|
+
skewSignals++;
|
|
65
|
+
trainingCutoffSkew = totalPackages > 0 ? skewSignals / totalPackages * 5 : 0;
|
|
66
|
+
trainingCutoffSkew = Math.min(1, trainingCutoffSkew);
|
|
67
|
+
} catch {
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
const riskResult = calculateDependencyHealth({
|
|
71
|
+
totalPackages,
|
|
72
|
+
outdatedPackages,
|
|
73
|
+
deprecatedPackages,
|
|
74
|
+
trainingCutoffSkew
|
|
75
|
+
});
|
|
76
|
+
return {
|
|
77
|
+
summary: {
|
|
78
|
+
filesAnalyzed: existsSync(packageJsonPath) ? 1 : 0,
|
|
79
|
+
packagesAnalyzed: totalPackages,
|
|
80
|
+
score: riskResult.score,
|
|
81
|
+
rating: riskResult.rating
|
|
82
|
+
},
|
|
83
|
+
issues,
|
|
84
|
+
rawData: {
|
|
85
|
+
totalPackages,
|
|
86
|
+
outdatedPackages,
|
|
87
|
+
deprecatedPackages,
|
|
88
|
+
trainingCutoffSkew
|
|
89
|
+
},
|
|
90
|
+
recommendations: riskResult.recommendations
|
|
91
|
+
};
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
export {
|
|
95
|
+
__require,
|
|
96
|
+
analyzeDeps
|
|
97
|
+
};
|
package/dist/cli.js
CHANGED
|
@@ -61,7 +61,14 @@ async function analyzeDeps(options) {
|
|
|
61
61
|
for (const [name, version] of Object.entries(allDeps)) {
|
|
62
62
|
const vStr = String(version).replace(/[^0-9.]/g, "");
|
|
63
63
|
const major = parseInt(vStr.split(".")[0] || "0", 10);
|
|
64
|
-
if ([
|
|
64
|
+
if ([
|
|
65
|
+
"request",
|
|
66
|
+
"moment",
|
|
67
|
+
"tslint",
|
|
68
|
+
"mkdirp",
|
|
69
|
+
"uuid",
|
|
70
|
+
"node-uuid"
|
|
71
|
+
].includes(name) && major < 4) {
|
|
65
72
|
deprecatedPackages++;
|
|
66
73
|
issues.push({
|
|
67
74
|
type: "dependency-health",
|
|
@@ -83,7 +90,8 @@ async function analyzeDeps(options) {
|
|
|
83
90
|
let skewSignals = 0;
|
|
84
91
|
if (allDeps["next"] && allDeps["next"].includes("15")) skewSignals++;
|
|
85
92
|
if (allDeps["react"] && allDeps["react"].includes("19")) skewSignals++;
|
|
86
|
-
if (allDeps["typescript"] && allDeps["typescript"].includes("5.6"))
|
|
93
|
+
if (allDeps["typescript"] && allDeps["typescript"].includes("5.6"))
|
|
94
|
+
skewSignals++;
|
|
87
95
|
trainingCutoffSkew = totalPackages > 0 ? skewSignals / totalPackages * 5 : 0;
|
|
88
96
|
trainingCutoffSkew = Math.min(1, trainingCutoffSkew);
|
|
89
97
|
} catch {
|
|
@@ -116,18 +124,28 @@ async function analyzeDeps(options) {
|
|
|
116
124
|
// src/cli.ts
|
|
117
125
|
var import_picocolors = __toESM(require("picocolors"));
|
|
118
126
|
function createCommand() {
|
|
119
|
-
const program = new import_commander.Command("deps-health").description("Analyze dependency health and AI training cutoff skew").option(
|
|
127
|
+
const program = new import_commander.Command("deps-health").description("Analyze dependency health and AI training cutoff skew").option(
|
|
128
|
+
"--training-cutoff-year <year>",
|
|
129
|
+
"The year the target AI model was trained (e.g. 2023)",
|
|
130
|
+
"2023"
|
|
131
|
+
).action(async (options) => {
|
|
120
132
|
console.log(import_picocolors.default.cyan("Analyzing dependency health..."));
|
|
121
133
|
const report = await analyzeDeps({
|
|
122
134
|
rootDir: process.cwd(),
|
|
123
135
|
trainingCutoffYear: parseInt(options.trainingCutoffYear, 10)
|
|
124
136
|
});
|
|
125
137
|
console.log(import_picocolors.default.bold("\nDependency Health Analysis Results:"));
|
|
126
|
-
console.log(
|
|
127
|
-
|
|
138
|
+
console.log(
|
|
139
|
+
`Rating: ${report.summary.rating.toUpperCase()} (Score: ${report.summary.score})`
|
|
140
|
+
);
|
|
141
|
+
console.log(
|
|
142
|
+
`Total packages analyzed: ${report.summary.packagesAnalyzed}`
|
|
143
|
+
);
|
|
128
144
|
if (report.issues.length > 0) {
|
|
129
|
-
console.log(
|
|
130
|
-
|
|
145
|
+
console.log(
|
|
146
|
+
import_picocolors.default.red(`
|
|
147
|
+
Found ${report.issues.length} dependency health issues.`)
|
|
148
|
+
);
|
|
131
149
|
} else {
|
|
132
150
|
console.log(import_picocolors.default.green("\nDependencies are healthy for AI assistance."));
|
|
133
151
|
}
|
package/dist/cli.mjs
CHANGED
|
@@ -1,24 +1,34 @@
|
|
|
1
1
|
import {
|
|
2
2
|
__require,
|
|
3
3
|
analyzeDeps
|
|
4
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-MN25J52Z.mjs";
|
|
5
5
|
|
|
6
6
|
// src/cli.ts
|
|
7
7
|
import { Command } from "commander";
|
|
8
8
|
import pc from "picocolors";
|
|
9
9
|
function createCommand() {
|
|
10
|
-
const program = new Command("deps-health").description("Analyze dependency health and AI training cutoff skew").option(
|
|
10
|
+
const program = new Command("deps-health").description("Analyze dependency health and AI training cutoff skew").option(
|
|
11
|
+
"--training-cutoff-year <year>",
|
|
12
|
+
"The year the target AI model was trained (e.g. 2023)",
|
|
13
|
+
"2023"
|
|
14
|
+
).action(async (options) => {
|
|
11
15
|
console.log(pc.cyan("Analyzing dependency health..."));
|
|
12
16
|
const report = await analyzeDeps({
|
|
13
17
|
rootDir: process.cwd(),
|
|
14
18
|
trainingCutoffYear: parseInt(options.trainingCutoffYear, 10)
|
|
15
19
|
});
|
|
16
20
|
console.log(pc.bold("\nDependency Health Analysis Results:"));
|
|
17
|
-
console.log(
|
|
18
|
-
|
|
21
|
+
console.log(
|
|
22
|
+
`Rating: ${report.summary.rating.toUpperCase()} (Score: ${report.summary.score})`
|
|
23
|
+
);
|
|
24
|
+
console.log(
|
|
25
|
+
`Total packages analyzed: ${report.summary.packagesAnalyzed}`
|
|
26
|
+
);
|
|
19
27
|
if (report.issues.length > 0) {
|
|
20
|
-
console.log(
|
|
21
|
-
|
|
28
|
+
console.log(
|
|
29
|
+
pc.red(`
|
|
30
|
+
Found ${report.issues.length} dependency health issues.`)
|
|
31
|
+
);
|
|
22
32
|
} else {
|
|
23
33
|
console.log(pc.green("\nDependencies are healthy for AI assistance."));
|
|
24
34
|
}
|
package/dist/index.js
CHANGED
|
@@ -50,7 +50,14 @@ async function analyzeDeps(options) {
|
|
|
50
50
|
for (const [name, version] of Object.entries(allDeps)) {
|
|
51
51
|
const vStr = String(version).replace(/[^0-9.]/g, "");
|
|
52
52
|
const major = parseInt(vStr.split(".")[0] || "0", 10);
|
|
53
|
-
if ([
|
|
53
|
+
if ([
|
|
54
|
+
"request",
|
|
55
|
+
"moment",
|
|
56
|
+
"tslint",
|
|
57
|
+
"mkdirp",
|
|
58
|
+
"uuid",
|
|
59
|
+
"node-uuid"
|
|
60
|
+
].includes(name) && major < 4) {
|
|
54
61
|
deprecatedPackages++;
|
|
55
62
|
issues.push({
|
|
56
63
|
type: "dependency-health",
|
|
@@ -72,7 +79,8 @@ async function analyzeDeps(options) {
|
|
|
72
79
|
let skewSignals = 0;
|
|
73
80
|
if (allDeps["next"] && allDeps["next"].includes("15")) skewSignals++;
|
|
74
81
|
if (allDeps["react"] && allDeps["react"].includes("19")) skewSignals++;
|
|
75
|
-
if (allDeps["typescript"] && allDeps["typescript"].includes("5.6"))
|
|
82
|
+
if (allDeps["typescript"] && allDeps["typescript"].includes("5.6"))
|
|
83
|
+
skewSignals++;
|
|
76
84
|
trainingCutoffSkew = totalPackages > 0 ? skewSignals / totalPackages * 5 : 0;
|
|
77
85
|
trainingCutoffSkew = Math.min(1, trainingCutoffSkew);
|
|
78
86
|
} catch {
|
package/dist/index.mjs
CHANGED
package/package.json
CHANGED
|
@@ -1,22 +1,22 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@aiready/deps",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.6",
|
|
4
4
|
"description": "AI-Readiness: Dependency Health & Cutoff Skew",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"module": "dist/index.mjs",
|
|
7
7
|
"types": "dist/index.d.ts",
|
|
8
8
|
"dependencies": {
|
|
9
|
-
"commander": "^
|
|
9
|
+
"commander": "^14.0.0",
|
|
10
10
|
"picocolors": "^1.0.0",
|
|
11
11
|
"semver": "^7.6.0",
|
|
12
|
-
"@aiready/core": "0.9.
|
|
12
|
+
"@aiready/core": "0.9.33"
|
|
13
13
|
},
|
|
14
14
|
"devDependencies": {
|
|
15
|
-
"@types/node": "^
|
|
15
|
+
"@types/node": "^24.0.0",
|
|
16
16
|
"@types/semver": "^7.5.8",
|
|
17
17
|
"tsup": "^8.0.2",
|
|
18
18
|
"typescript": "^5.4.5",
|
|
19
|
-
"vitest": "^
|
|
19
|
+
"vitest": "^4.0.0"
|
|
20
20
|
},
|
|
21
21
|
"exports": {
|
|
22
22
|
".": {
|
|
@@ -12,18 +12,21 @@ describe('Deps Health Analyzer', () => {
|
|
|
12
12
|
mkdirSync(tmpDir, { recursive: true });
|
|
13
13
|
|
|
14
14
|
const packageJsonPath = join(tmpDir, 'package.json');
|
|
15
|
-
writeFileSync(
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
15
|
+
writeFileSync(
|
|
16
|
+
packageJsonPath,
|
|
17
|
+
JSON.stringify({
|
|
18
|
+
dependencies: {
|
|
19
|
+
request: '^2.88.2',
|
|
20
|
+
moment: '~2.29.4',
|
|
21
|
+
lodash: '^0.4.0',
|
|
22
|
+
react: '^19.0.0',
|
|
23
|
+
next: '15.0.0-rc',
|
|
24
|
+
},
|
|
25
|
+
devDependencies: {
|
|
26
|
+
typescript: '5.6.3',
|
|
27
|
+
},
|
|
28
|
+
})
|
|
29
|
+
);
|
|
27
30
|
});
|
|
28
31
|
|
|
29
32
|
afterAll(() => {
|
package/src/analyzer.ts
CHANGED
|
@@ -3,9 +3,7 @@ import type { DepsOptions, DepsReport, DepsIssue } from './types';
|
|
|
3
3
|
import { readFileSync, existsSync } from 'fs';
|
|
4
4
|
import { join } from 'path';
|
|
5
5
|
|
|
6
|
-
export async function analyzeDeps(
|
|
7
|
-
options: DepsOptions,
|
|
8
|
-
): Promise<DepsReport> {
|
|
6
|
+
export async function analyzeDeps(options: DepsOptions): Promise<DepsReport> {
|
|
9
7
|
const rootDir = options.rootDir;
|
|
10
8
|
const packageJsonPath = join(rootDir, 'package.json');
|
|
11
9
|
|
|
@@ -23,7 +21,7 @@ export async function analyzeDeps(
|
|
|
23
21
|
const allDeps = {
|
|
24
22
|
...(pkg.dependencies || {}),
|
|
25
23
|
...(pkg.devDependencies || {}),
|
|
26
|
-
...(pkg.peerDependencies || {})
|
|
24
|
+
...(pkg.peerDependencies || {}),
|
|
27
25
|
};
|
|
28
26
|
|
|
29
27
|
const depNames = Object.keys(allDeps);
|
|
@@ -36,13 +34,23 @@ export async function analyzeDeps(
|
|
|
36
34
|
const major = parseInt(vStr.split('.')[0] || '0', 10);
|
|
37
35
|
|
|
38
36
|
// Mock deprecated check based on known deprecated packages
|
|
39
|
-
if (
|
|
37
|
+
if (
|
|
38
|
+
[
|
|
39
|
+
'request',
|
|
40
|
+
'moment',
|
|
41
|
+
'tslint',
|
|
42
|
+
'mkdirp',
|
|
43
|
+
'uuid',
|
|
44
|
+
'node-uuid',
|
|
45
|
+
].includes(name) &&
|
|
46
|
+
major < 4
|
|
47
|
+
) {
|
|
40
48
|
deprecatedPackages++;
|
|
41
49
|
issues.push({
|
|
42
50
|
type: 'dependency-health',
|
|
43
51
|
severity: 'major',
|
|
44
52
|
message: `Dependency '${name}' is known to be deprecated. AI assistants may use outdated APIs.`,
|
|
45
|
-
location: { file: packageJsonPath, line: 1 }
|
|
53
|
+
location: { file: packageJsonPath, line: 1 },
|
|
46
54
|
});
|
|
47
55
|
}
|
|
48
56
|
|
|
@@ -53,7 +61,7 @@ export async function analyzeDeps(
|
|
|
53
61
|
type: 'dependency-health',
|
|
54
62
|
severity: 'minor',
|
|
55
63
|
message: `Dependency '${name}' (${version}) is pre-v1. APIs often unstable and hard for AI to predict.`,
|
|
56
|
-
location: { file: packageJsonPath, line: 1 }
|
|
64
|
+
location: { file: packageJsonPath, line: 1 },
|
|
57
65
|
});
|
|
58
66
|
}
|
|
59
67
|
}
|
|
@@ -63,11 +71,12 @@ export async function analyzeDeps(
|
|
|
63
71
|
let skewSignals = 0;
|
|
64
72
|
if (allDeps['next'] && allDeps['next'].includes('15')) skewSignals++;
|
|
65
73
|
if (allDeps['react'] && allDeps['react'].includes('19')) skewSignals++;
|
|
66
|
-
if (allDeps['typescript'] && allDeps['typescript'].includes('5.6'))
|
|
74
|
+
if (allDeps['typescript'] && allDeps['typescript'].includes('5.6'))
|
|
75
|
+
skewSignals++;
|
|
67
76
|
|
|
68
|
-
trainingCutoffSkew =
|
|
77
|
+
trainingCutoffSkew =
|
|
78
|
+
totalPackages > 0 ? (skewSignals / totalPackages) * 5 : 0;
|
|
69
79
|
trainingCutoffSkew = Math.min(1, trainingCutoffSkew); // cap at 1.0
|
|
70
|
-
|
|
71
80
|
} catch {
|
|
72
81
|
// ignore JSON parse errors
|
|
73
82
|
}
|
|
@@ -77,7 +86,7 @@ export async function analyzeDeps(
|
|
|
77
86
|
totalPackages,
|
|
78
87
|
outdatedPackages,
|
|
79
88
|
deprecatedPackages,
|
|
80
|
-
trainingCutoffSkew
|
|
89
|
+
trainingCutoffSkew,
|
|
81
90
|
});
|
|
82
91
|
|
|
83
92
|
return {
|
package/src/cli.ts
CHANGED
|
@@ -5,7 +5,11 @@ import pc from 'picocolors';
|
|
|
5
5
|
export function createCommand() {
|
|
6
6
|
const program = new Command('deps-health')
|
|
7
7
|
.description('Analyze dependency health and AI training cutoff skew')
|
|
8
|
-
.option(
|
|
8
|
+
.option(
|
|
9
|
+
'--training-cutoff-year <year>',
|
|
10
|
+
'The year the target AI model was trained (e.g. 2023)',
|
|
11
|
+
'2023'
|
|
12
|
+
)
|
|
9
13
|
.action(async (options) => {
|
|
10
14
|
console.log(pc.cyan('Analyzing dependency health...'));
|
|
11
15
|
const report = await analyzeDeps({
|
|
@@ -14,11 +18,17 @@ export function createCommand() {
|
|
|
14
18
|
});
|
|
15
19
|
|
|
16
20
|
console.log(pc.bold('\nDependency Health Analysis Results:'));
|
|
17
|
-
console.log(
|
|
18
|
-
|
|
21
|
+
console.log(
|
|
22
|
+
`Rating: ${report.summary.rating.toUpperCase()} (Score: ${report.summary.score})`
|
|
23
|
+
);
|
|
24
|
+
console.log(
|
|
25
|
+
`Total packages analyzed: ${report.summary.packagesAnalyzed}`
|
|
26
|
+
);
|
|
19
27
|
|
|
20
28
|
if (report.issues.length > 0) {
|
|
21
|
-
console.log(
|
|
29
|
+
console.log(
|
|
30
|
+
pc.red(`\nFound ${report.issues.length} dependency health issues.`)
|
|
31
|
+
);
|
|
22
32
|
} else {
|
|
23
33
|
console.log(pc.green('\nDependencies are healthy for AI assistance.'));
|
|
24
34
|
}
|
|
@@ -28,8 +38,10 @@ export function createCommand() {
|
|
|
28
38
|
}
|
|
29
39
|
|
|
30
40
|
if (require.main === module) {
|
|
31
|
-
createCommand()
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
41
|
+
createCommand()
|
|
42
|
+
.parseAsync(process.argv)
|
|
43
|
+
.catch((err) => {
|
|
44
|
+
console.error(pc.red(err.message));
|
|
45
|
+
process.exit(1);
|
|
46
|
+
});
|
|
35
47
|
}
|