@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.
@@ -1,6 +1,6 @@
1
1
 
2
2
  
3
- > @aiready/deps@0.13.0 build /Users/pengcao/projects/aiready/packages/deps
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
  CLI Building entry: src/cli.ts, src/index.ts
@@ -9,16 +9,16 @@
9
9
  CLI Target: es2020
10
10
  CJS Build start
11
11
  ESM Build start
12
- ESM dist/index.mjs 3.13 KB
13
- ESM dist/chunk-CFNCY65I.mjs 5.78 KB
14
12
  ESM dist/cli.mjs 1.33 KB
15
- ESM ⚡️ Build success in 78ms
13
+ ESM dist/chunk-Y2VRCEM4.mjs 5.78 KB
14
+ ESM dist/index.mjs 2.46 KB
15
+ ESM ⚡️ Build success in 171ms
16
+ CJS dist/index.js 8.95 KB
16
17
  CJS dist/cli.js 8.44 KB
17
- CJS dist/index.js 9.63 KB
18
- CJS ⚡️ Build success in 80ms
18
+ CJS ⚡️ Build success in 171ms
19
19
  DTS Build start
20
- DTS ⚡️ Build success in 2988ms
20
+ DTS ⚡️ Build success in 3283ms
21
21
  DTS dist/cli.d.ts 108.00 B
22
- DTS dist/index.d.ts 1.13 KB
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.13 KB
24
+ DTS dist/index.d.mts 1.18 KB
@@ -1,5 +0,0 @@
1
-
2
- 
3
- > @aiready/deps@0.9.5 lint /Users/pengcao/projects/aiready/packages/deps
4
- > eslint src --ext .ts
5
-
@@ -1,34 +1,18 @@
1
1
 
2
2
  
3
- > @aiready/deps@0.13.0 test /Users/pengcao/projects/aiready/packages/deps
3
+ > @aiready/deps@0.13.2 test /Users/pengcao/projects/aiready/packages/deps
4
4
  > vitest run
5
5
 
6
6
  [?25l
7
7
   RUN  v4.0.18 /Users/pengcao/projects/aiready/packages/deps
8
8
 
9
- [?2026h
10
-  ❯ src/__tests__/provider.test.ts [queued]
11
-
12
-  Test Files 0 passed (3)
13
-  Tests 0 passed (0)
14
-  Start at 17:20:15
15
-  Duration 100ms
16
- [?2026l[?2026h
17
-  ❯ src/__tests__/analyzer.test.ts [queued]
18
-  ❯ src/__tests__/provider.test.ts 0/2
19
-  ❯ src/__tests__/scoring.test.ts [queued]
20
-
21
-  Test Files 0 passed (3)
22
-  Tests 0 passed (2)
23
-  Start at 17:20:15
24
-  Duration 404ms
25
- [?2026l ✓ src/__tests__/provider.test.ts (2 tests) 4ms
26
- ✓ src/__tests__/scoring.test.ts (2 tests) 1ms
27
- ✓ src/__tests__/analyzer.test.ts (2 tests) 4ms
9
+ ✓ src/__tests__/provider.test.ts (2 tests) 18ms
10
+ ✓ src/__tests__/analyzer.test.ts (2 tests) 15ms
11
+ ✓ src/__tests__/scoring.test.ts (2 tests) 4ms
28
12
 
29
13
   Test Files  3 passed (3)
30
14
   Tests  6 passed (6)
31
-  Start at  17:20:15
32
-  Duration  461ms (transform 251ms, setup 0ms, import 998ms, tests 10ms, environment 0ms)
15
+  Start at  22:20:38
16
+  Duration  3.52s (transform 2.43s, setup 0ms, import 8.59s, tests 36ms, environment 2ms)
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, issues) {
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, issues) {
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, issues) {
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, issues) {
160
- const matches = content.matchAll(/require\s+(?![\(\s])([^\s]+)/g);
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, issues) {
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
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  __require,
3
3
  analyzeDeps
4
- } from "./chunk-CFNCY65I.mjs";
4
+ } from "./chunk-Y2VRCEM4.mjs";
5
5
 
6
6
  // src/cli.ts
7
7
  import { Command } from "commander";
package/dist/index.d.mts CHANGED
@@ -1,9 +1,10 @@
1
- import { ToolProvider, Issue, IssueType, ScanOptions, ToolScoringOutput } from '@aiready/core';
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 { ToolProvider, Issue, IssueType, ScanOptions, ToolScoringOutput } from '@aiready/core';
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, issues) {
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, issues) {
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, issues) {
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, issues) {
155
- const matches = content.matchAll(/require\s+(?![\(\s])([^\s]+)/g);
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, issues) {
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
- async analyze(options) {
211
- const report = await analyzeDeps(options);
212
- const fileIssuesMap = /* @__PURE__ */ new Map();
213
- for (const issue of report.issues) {
214
- const file = issue.location.file;
215
- if (!fileIssuesMap.has(file)) fileIssuesMap.set(file, []);
216
- fileIssuesMap.get(file).push(issue);
217
- }
218
- const results = Array.from(fileIssuesMap.entries()).map(
219
- ([fileName, issues]) => ({
220
- fileName,
221
- issues,
222
- metrics: {}
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, options) {
224
+ score(output) {
237
225
  const summary = output.summary;
238
226
  const rawData = output.metadata?.rawData || {};
239
- return {
240
- toolName: import_core2.ToolName.DependencyHealth,
241
- score: summary.score || 0,
242
- rawMetrics: {
243
- ...summary,
244
- ...rawData
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-CFNCY65I.mjs";
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
- SpokeOutputSchema
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
- async analyze(options) {
17
- const report = await analyzeDeps(options);
18
- const fileIssuesMap = /* @__PURE__ */ new Map();
19
- for (const issue of report.issues) {
20
- const file = issue.location.file;
21
- if (!fileIssuesMap.has(file)) fileIssuesMap.set(file, []);
22
- fileIssuesMap.get(file).push(issue);
23
- }
24
- const results = Array.from(fileIssuesMap.entries()).map(
25
- ([fileName, issues]) => ({
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
- score(output, options) {
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
- toolName: ToolName.DependencyHealth,
47
- score: summary.score || 0,
48
- rawMetrics: {
49
- ...summary,
50
- ...rawData
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.1",
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.1"
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.toolName).toBe('dependency-health');
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, existsSync, readdirSync, statSync } from 'fs';
4
- import { join, basename, extname } from 'path';
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
- issues: DepsIssue[]
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
- issues: DepsIssue[]
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
- issues: DepsIssue[]
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
- issues: DepsIssue[]
175
+ _issues: DepsIssue[]
176
176
  ): string[] {
177
177
  // Regex for go.mod 'require (...)' or 'require package version'
178
- const matches = content.matchAll(/require\s+(?![\(\s])([^\s]+)/g);
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
- issues: DepsIssue[]
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
- ToolProvider,
2
+ createProvider,
3
3
  ToolName,
4
- SpokeOutput,
5
4
  ScanOptions,
6
- ToolScoringOutput,
7
- AnalysisResult,
8
- SpokeOutputSchema,
5
+ groupIssuesByFile,
6
+ buildSimpleProviderScore,
9
7
  } from '@aiready/core';
10
8
  import { analyzeDeps } from './analyzer';
11
- import { DepsOptions, DepsIssue } from './types';
9
+ import { DepsOptions } from './types';
12
10
 
13
11
  /**
14
12
  * Dependency Health Tool Provider
15
13
  */
16
- export const DepsProvider: ToolProvider = {
14
+ export const DepsProvider = createProvider({
17
15
  id: ToolName.DependencyHealth,
18
16
  alias: ['deps', 'deps-health', 'packages'],
19
-
20
- async analyze(options: ScanOptions): Promise<SpokeOutput> {
21
- const report = await analyzeDeps(options as DepsOptions);
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
- score(output: SpokeOutput, options: ScanOptions): ToolScoringOutput {
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
- return {
56
- toolName: ToolName.DependencyHealth,
57
- score: summary.score || 0,
58
- rawMetrics: {
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
+ });