@aiready/change-amplification 0.1.8 → 0.1.10

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/change-amplification@0.1.8 build /Users/pengcao/projects/aiready/packages/change-amplification
3
+ > @aiready/change-amplification@0.1.10 build /Users/pengcao/projects/aiready/packages/change-amplification
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
@@ -10,7 +10,7 @@
10
10
  CJS Build start
11
11
  ESM Build start
12
12
 
13
- [12:55:24 AM]  WARN  ▲ [WARNING] The condition "types" here will never be used as it comes after both "import" and "require" [package.json]
13
+ [1:59:56 PM]  WARN  ▲ [WARNING] The condition "types" here will never be used as it comes after both "import" and "require" [package.json]
14
14
 
15
15
  package.json:33:6:
16
16
   33 │ "types": "./dist/index.d.ts"
@@ -31,7 +31,7 @@
31
31
 
32
32
 
33
33
 
34
- [12:55:24 AM]  WARN  ▲ [WARNING] The condition "types" here will never be used as it comes after both "import" and "require" [package.json]
34
+ [1:59:56 PM]  WARN  ▲ [WARNING] The condition "types" here will never be used as it comes after both "import" and "require" [package.json]
35
35
 
36
36
  package.json:38:6:
37
37
   38 │ "types": "./dist/cli.d.ts"
@@ -51,12 +51,8 @@
51
51
 
52
52
 
53
53
 
54
- ESM dist/index.mjs 110.00 B
55
- ESM dist/cli.mjs 2.78 KB
56
- ESM dist/chunk-MARO4FT6.mjs 3.52 KB
57
- ESM ⚡️ Build success in 440ms
58
54
 
59
- [12:55:25 AM]  WARN  ▲ [WARNING] The condition "types" here will never be used as it comes after both "import" and "require" [package.json]
55
+ [1:59:56 PM]  WARN  ▲ [WARNING] The condition "types" here will never be used as it comes after both "import" and "require" [package.json]
60
56
 
61
57
  package.json:33:6:
62
58
   33 │ "types": "./dist/index.d.ts"
@@ -77,7 +73,7 @@
77
73
 
78
74
 
79
75
 
80
- [12:55:25 AM]  WARN  ▲ [WARNING] The condition "types" here will never be used as it comes after both "import" and "require" [package.json]
76
+ [1:59:56 PM]  WARN  ▲ [WARNING] The condition "types" here will never be used as it comes after both "import" and "require" [package.json]
81
77
 
82
78
  package.json:38:6:
83
79
   38 │ "types": "./dist/cli.d.ts"
@@ -97,11 +93,15 @@
97
93
 
98
94
 
99
95
 
100
- CJS dist/index.js 4.79 KB
101
- CJS dist/cli.js 7.65 KB
102
- CJS ⚡️ Build success in 631ms
96
+ ESM dist/cli.mjs 2.78 KB
97
+ ESM dist/chunk-3CM4X7K3.mjs 3.47 KB
98
+ ESM dist/index.mjs 110.00 B
99
+ ESM ⚡️ Build success in 127ms
100
+ CJS dist/cli.js 7.60 KB
101
+ CJS dist/index.js 4.73 KB
102
+ CJS ⚡️ Build success in 160ms
103
103
  DTS Build start
104
- DTS ⚡️ Build success in 10596ms
104
+ DTS ⚡️ Build success in 3072ms
105
105
  DTS dist/cli.d.ts 152.00 B
106
106
  DTS dist/index.d.ts 999.00 B
107
107
  DTS dist/cli.d.mts 152.00 B
@@ -0,0 +1,111 @@
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 * as fs from "fs";
10
+ import * as path from "path";
11
+ import {
12
+ scanFiles,
13
+ calculateChangeAmplification,
14
+ getParser
15
+ } from "@aiready/core";
16
+ async function analyzeChangeAmplification(options) {
17
+ const files = await scanFiles({
18
+ ...options,
19
+ include: options.include || ["**/*.{ts,tsx,js,jsx,py,go}"]
20
+ });
21
+ const dependencyGraph = /* @__PURE__ */ new Map();
22
+ const reverseGraph = /* @__PURE__ */ new Map();
23
+ for (const file of files) {
24
+ dependencyGraph.set(file, []);
25
+ reverseGraph.set(file, []);
26
+ }
27
+ let processed = 0;
28
+ for (const file of files) {
29
+ processed++;
30
+ options.onProgress?.(
31
+ processed,
32
+ files.length,
33
+ `change-amplification: analyzing files`
34
+ );
35
+ try {
36
+ const parser = getParser(file);
37
+ if (!parser) continue;
38
+ const content = fs.readFileSync(file, "utf8");
39
+ const parseResult = parser.parse(content, file);
40
+ const dependencies = parseResult.imports.map((i) => i.source);
41
+ for (const dep of dependencies) {
42
+ const depDir = path.dirname(file);
43
+ const resolvedPath = files.find((f) => {
44
+ if (dep.startsWith(".")) {
45
+ return f.startsWith(path.resolve(depDir, dep));
46
+ } else {
47
+ return f.includes(dep);
48
+ }
49
+ });
50
+ if (resolvedPath) {
51
+ dependencyGraph.get(file)?.push(resolvedPath);
52
+ reverseGraph.get(resolvedPath)?.push(file);
53
+ }
54
+ }
55
+ } catch (err) {
56
+ void err;
57
+ }
58
+ }
59
+ const fileMetrics = files.map((file) => {
60
+ const fanOut = dependencyGraph.get(file)?.length || 0;
61
+ const fanIn = reverseGraph.get(file)?.length || 0;
62
+ return { file, fanOut, fanIn };
63
+ });
64
+ const riskResult = calculateChangeAmplification({ files: fileMetrics });
65
+ const results = [];
66
+ for (const hotspot of riskResult.hotspots) {
67
+ const issues = [];
68
+ if (hotspot.amplificationFactor > 20) {
69
+ issues.push({
70
+ type: "change-amplification",
71
+ severity: hotspot.amplificationFactor > 40 ? "critical" : "major",
72
+ message: `High change amplification detected (Factor: ${hotspot.amplificationFactor}). Changes here cascade heavily.`,
73
+ location: { file: hotspot.file, line: 1 },
74
+ suggestion: `Reduce coupling. Fan-out is ${hotspot.fanOut}, Fan-in is ${hotspot.fanIn}.`
75
+ });
76
+ }
77
+ if (hotspot.amplificationFactor > 5) {
78
+ results.push({
79
+ fileName: hotspot.file,
80
+ issues,
81
+ metrics: {
82
+ aiSignalClarityScore: 100 - hotspot.amplificationFactor
83
+ // Just a rough score
84
+ }
85
+ });
86
+ }
87
+ }
88
+ return {
89
+ summary: {
90
+ totalFiles: files.length,
91
+ totalIssues: results.reduce((sum, r) => sum + r.issues.length, 0),
92
+ criticalIssues: results.reduce(
93
+ (sum, r) => sum + r.issues.filter((i) => i.severity === "critical").length,
94
+ 0
95
+ ),
96
+ majorIssues: results.reduce(
97
+ (sum, r) => sum + r.issues.filter((i) => i.severity === "major").length,
98
+ 0
99
+ ),
100
+ score: riskResult.score,
101
+ rating: riskResult.rating,
102
+ recommendations: riskResult.recommendations
103
+ },
104
+ results
105
+ };
106
+ }
107
+
108
+ export {
109
+ __require,
110
+ analyzeChangeAmplification
111
+ };
package/dist/cli.js CHANGED
@@ -44,7 +44,6 @@ var fs = __toESM(require("fs"));
44
44
  var path = __toESM(require("path"));
45
45
  var import_core = require("@aiready/core");
46
46
  async function analyzeChangeAmplification(options) {
47
- const rootDir = path.resolve(options.rootDir || ".");
48
47
  const files = await (0, import_core.scanFiles)({
49
48
  ...options,
50
49
  include: options.include || ["**/*.{ts,tsx,js,jsx,py,go}"]
package/dist/cli.mjs CHANGED
@@ -2,7 +2,7 @@
2
2
  import {
3
3
  __require,
4
4
  analyzeChangeAmplification
5
- } from "./chunk-MARO4FT6.mjs";
5
+ } from "./chunk-3CM4X7K3.mjs";
6
6
 
7
7
  // src/cli.ts
8
8
  import { Command } from "commander";
package/dist/index.js CHANGED
@@ -39,7 +39,6 @@ var fs = __toESM(require("fs"));
39
39
  var path = __toESM(require("path"));
40
40
  var import_core = require("@aiready/core");
41
41
  async function analyzeChangeAmplification(options) {
42
- const rootDir = path.resolve(options.rootDir || ".");
43
42
  const files = await (0, import_core.scanFiles)({
44
43
  ...options,
45
44
  include: options.include || ["**/*.{ts,tsx,js,jsx,py,go}"]
package/dist/index.mjs CHANGED
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  analyzeChangeAmplification
3
- } from "./chunk-MARO4FT6.mjs";
3
+ } from "./chunk-3CM4X7K3.mjs";
4
4
  export {
5
5
  analyzeChangeAmplification
6
6
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@aiready/change-amplification",
3
- "version": "0.1.8",
3
+ "version": "0.1.10",
4
4
  "description": "AI-Readiness: Change Amplification Detection",
5
5
  "main": "dist/index.js",
6
6
  "module": "dist/index.mjs",
@@ -10,7 +10,7 @@
10
10
  "commander": "^14.0.0",
11
11
  "glob": "^13.0.0",
12
12
  "chalk": "^5.3.0",
13
- "@aiready/core": "0.9.35"
13
+ "@aiready/core": "0.9.37"
14
14
  },
15
15
  "devDependencies": {
16
16
  "@types/node": "^24.0.0",
package/src/analyzer.ts CHANGED
@@ -15,7 +15,6 @@ import type {
15
15
  export async function analyzeChangeAmplification(
16
16
  options: ChangeAmplificationOptions
17
17
  ): Promise<ChangeAmplificationReport> {
18
- const rootDir = path.resolve(options.rootDir || '.');
19
18
  // Use core scanFiles which respects .gitignore recursively
20
19
  const files = await scanFiles({
21
20
  ...options,