@hasankemaldemirci/aro 1.0.0
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/.agent_context_pro.json +57 -0
- package/.env.example +3 -0
- package/.github/workflows/aro.yml +41 -0
- package/.husky/pre-commit +19 -0
- package/CONTRIBUTING.md +34 -0
- package/LICENSE +21 -0
- package/README.md +55 -0
- package/bin/aro.ts +86 -0
- package/dist/bin/aro.d.ts +7 -0
- package/dist/bin/aro.js +118 -0
- package/dist/src/badge.d.ts +6 -0
- package/dist/src/badge.js +64 -0
- package/dist/src/constants.d.ts +20 -0
- package/dist/src/constants.js +68 -0
- package/dist/src/core.d.ts +12 -0
- package/dist/src/core.js +107 -0
- package/dist/src/enterprise.d.ts +8 -0
- package/dist/src/enterprise.js +125 -0
- package/dist/src/init.d.ts +1 -0
- package/dist/src/init.js +64 -0
- package/dist/src/mcp.d.ts +5 -0
- package/dist/src/mcp.js +138 -0
- package/dist/src/refactor.d.ts +6 -0
- package/dist/src/refactor.js +91 -0
- package/dist/src/rules.d.ts +6 -0
- package/dist/src/rules.js +67 -0
- package/dist/src/types.d.ts +39 -0
- package/dist/src/types.js +6 -0
- package/dist/src/utils.d.ts +14 -0
- package/dist/src/utils.js +194 -0
- package/dist/tests/cli.test.d.ts +1 -0
- package/dist/tests/cli.test.js +56 -0
- package/dist/tests/core.test.d.ts +5 -0
- package/dist/tests/core.test.js +129 -0
- package/dist/tests/enterprise.test.d.ts +1 -0
- package/dist/tests/enterprise.test.js +74 -0
- package/dist/tests/mcp.test.d.ts +1 -0
- package/dist/tests/mcp.test.js +81 -0
- package/eslint.config.mjs +9 -0
- package/package.json +66 -0
- package/src/badge.ts +77 -0
- package/src/constants.ts +68 -0
- package/src/core.ts +141 -0
- package/src/enterprise.ts +159 -0
- package/src/init.ts +75 -0
- package/src/mcp.ts +158 -0
- package/src/refactor.ts +122 -0
- package/src/rules.ts +78 -0
- package/src/types.ts +43 -0
- package/src/utils.ts +199 -0
- package/tests/cli.test.ts +71 -0
- package/tests/core.test.ts +146 -0
- package/tests/enterprise.test.ts +78 -0
- package/tests/mcp.test.ts +89 -0
- package/tsconfig.json +23 -0
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
import { calculateDebt } from "../src/enterprise";
|
|
2
|
+
import { AROMetrics } from "../src/utils";
|
|
3
|
+
|
|
4
|
+
describe("ARO Enterprise Analytics", () => {
|
|
5
|
+
test("should calculate $0 debt for a perfect project", () => {
|
|
6
|
+
const metrics: AROMetrics = {
|
|
7
|
+
hasReadme: true,
|
|
8
|
+
readmeSize: 1000,
|
|
9
|
+
hasSrc: true,
|
|
10
|
+
hasConfig: 4,
|
|
11
|
+
largeFiles: 0,
|
|
12
|
+
securityIssues: 0,
|
|
13
|
+
blindSpots: [],
|
|
14
|
+
};
|
|
15
|
+
const debt = calculateDebt(metrics);
|
|
16
|
+
expect(debt.totalDebt).toBe(0);
|
|
17
|
+
expect(debt.docDebt).toBe(0);
|
|
18
|
+
expect(debt.truncationDebt).toBe(0);
|
|
19
|
+
expect(debt.structuralDebt).toBe(0);
|
|
20
|
+
});
|
|
21
|
+
|
|
22
|
+
test("should calculate maximum debt for a missing documentation", () => {
|
|
23
|
+
const metrics: AROMetrics = {
|
|
24
|
+
hasReadme: false,
|
|
25
|
+
readmeSize: 0,
|
|
26
|
+
hasSrc: true,
|
|
27
|
+
hasConfig: 4,
|
|
28
|
+
largeFiles: 0,
|
|
29
|
+
securityIssues: 0,
|
|
30
|
+
blindSpots: [],
|
|
31
|
+
};
|
|
32
|
+
const debt = calculateDebt(metrics);
|
|
33
|
+
expect(debt.docDebt).toBe(15000);
|
|
34
|
+
expect(debt.totalDebt).toBe(15000);
|
|
35
|
+
});
|
|
36
|
+
|
|
37
|
+
test("should scale truncation debt with large files", () => {
|
|
38
|
+
const metrics: AROMetrics = {
|
|
39
|
+
hasReadme: true,
|
|
40
|
+
readmeSize: 1000,
|
|
41
|
+
hasSrc: true,
|
|
42
|
+
hasConfig: 4,
|
|
43
|
+
largeFiles: 3,
|
|
44
|
+
securityIssues: 0,
|
|
45
|
+
blindSpots: [],
|
|
46
|
+
};
|
|
47
|
+
const debt = calculateDebt(metrics);
|
|
48
|
+
expect(debt.truncationDebt).toBe(15000); // 3 * 5000
|
|
49
|
+
});
|
|
50
|
+
|
|
51
|
+
test("should calculate structural debt for flat projects", () => {
|
|
52
|
+
const metrics: AROMetrics = {
|
|
53
|
+
hasReadme: true,
|
|
54
|
+
readmeSize: 1000,
|
|
55
|
+
hasSrc: false,
|
|
56
|
+
hasConfig: 0,
|
|
57
|
+
largeFiles: 0,
|
|
58
|
+
securityIssues: 0,
|
|
59
|
+
blindSpots: [],
|
|
60
|
+
};
|
|
61
|
+
const debt = calculateDebt(metrics);
|
|
62
|
+
expect(debt.structuralDebt).toBe(20000); // 10000 (no src) + (2 * 5000) (missing 2 configs)
|
|
63
|
+
});
|
|
64
|
+
|
|
65
|
+
test("should handle partial configurations", () => {
|
|
66
|
+
const metrics: AROMetrics = {
|
|
67
|
+
hasReadme: true,
|
|
68
|
+
readmeSize: 1000,
|
|
69
|
+
hasSrc: true,
|
|
70
|
+
hasConfig: 2,
|
|
71
|
+
largeFiles: 0,
|
|
72
|
+
securityIssues: 0,
|
|
73
|
+
blindSpots: [],
|
|
74
|
+
};
|
|
75
|
+
const debt = calculateDebt(metrics);
|
|
76
|
+
expect(debt.structuralDebt).toBe(0); // Target met with 2 configs
|
|
77
|
+
});
|
|
78
|
+
});
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
import { spawn } from "child_process";
|
|
2
|
+
import path from "path";
|
|
3
|
+
|
|
4
|
+
describe("ARO MCP Server Integration", () => {
|
|
5
|
+
const mcpPath = path.join(__dirname, "../dist/src/mcp.js");
|
|
6
|
+
|
|
7
|
+
test("should start and respond to ListTools request over stdio", (done) => {
|
|
8
|
+
// We run the compiled version
|
|
9
|
+
const mcp = spawn("node", [mcpPath]);
|
|
10
|
+
|
|
11
|
+
let output = "";
|
|
12
|
+
mcp.stdout.on("data", (data) => {
|
|
13
|
+
output += data.toString();
|
|
14
|
+
try {
|
|
15
|
+
// MCP is JSON-RPC. We are looking for the tools definition.
|
|
16
|
+
if (
|
|
17
|
+
output.includes("analyze_readability") &&
|
|
18
|
+
output.includes("optimize_readability")
|
|
19
|
+
) {
|
|
20
|
+
mcp.kill();
|
|
21
|
+
done();
|
|
22
|
+
}
|
|
23
|
+
} catch (e) {
|
|
24
|
+
// Wait for more data
|
|
25
|
+
}
|
|
26
|
+
});
|
|
27
|
+
|
|
28
|
+
mcp.stderr.on("data", (data) => {
|
|
29
|
+
const msg = data.toString();
|
|
30
|
+
// The server logs "ARO MCP Server running on stdio" to stderr
|
|
31
|
+
if (msg.includes("ARO MCP Server running on stdio")) {
|
|
32
|
+
// Send dummy ListTools request
|
|
33
|
+
const listToolsRequest = {
|
|
34
|
+
jsonrpc: "2.0",
|
|
35
|
+
id: 1,
|
|
36
|
+
method: "tools/list",
|
|
37
|
+
params: {},
|
|
38
|
+
};
|
|
39
|
+
mcp.stdin.write(JSON.stringify(listToolsRequest) + "\n");
|
|
40
|
+
}
|
|
41
|
+
});
|
|
42
|
+
|
|
43
|
+
mcp.on("error", (err) => {
|
|
44
|
+
done(err);
|
|
45
|
+
});
|
|
46
|
+
|
|
47
|
+
// Timeout safety
|
|
48
|
+
setTimeout(() => {
|
|
49
|
+
if (mcp.killed) return;
|
|
50
|
+
mcp.kill();
|
|
51
|
+
done(
|
|
52
|
+
new Error(
|
|
53
|
+
"MCP Server response timeout or tools not found in output: " + output,
|
|
54
|
+
),
|
|
55
|
+
);
|
|
56
|
+
}, 5000);
|
|
57
|
+
});
|
|
58
|
+
|
|
59
|
+
test("should expose current-metrics resource", (done) => {
|
|
60
|
+
const mcp = spawn("node", [mcpPath]);
|
|
61
|
+
let output = "";
|
|
62
|
+
|
|
63
|
+
mcp.stdout.on("data", (data) => {
|
|
64
|
+
output += data.toString();
|
|
65
|
+
if (output.includes("aro://current-metrics")) {
|
|
66
|
+
mcp.kill();
|
|
67
|
+
done();
|
|
68
|
+
}
|
|
69
|
+
});
|
|
70
|
+
|
|
71
|
+
mcp.stderr.on("data", (data) => {
|
|
72
|
+
if (data.toString().includes("ARO MCP Server running on stdio")) {
|
|
73
|
+
const listResourcesRequest = {
|
|
74
|
+
jsonrpc: "2.0",
|
|
75
|
+
id: 2,
|
|
76
|
+
method: "resources/list",
|
|
77
|
+
params: {},
|
|
78
|
+
};
|
|
79
|
+
mcp.stdin.write(JSON.stringify(listResourcesRequest) + "\n");
|
|
80
|
+
}
|
|
81
|
+
});
|
|
82
|
+
|
|
83
|
+
setTimeout(() => {
|
|
84
|
+
if (mcp.killed) return;
|
|
85
|
+
mcp.kill();
|
|
86
|
+
done(new Error("MCP Server resource discovery failed"));
|
|
87
|
+
}, 5000);
|
|
88
|
+
});
|
|
89
|
+
});
|
package/tsconfig.json
ADDED
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
{
|
|
2
|
+
"compilerOptions": {
|
|
3
|
+
"target": "ESNext",
|
|
4
|
+
"module": "CommonJS",
|
|
5
|
+
"lib": ["ESNext"],
|
|
6
|
+
"declaration": true,
|
|
7
|
+
"outDir": "dist",
|
|
8
|
+
"rootDir": "./",
|
|
9
|
+
"strict": true,
|
|
10
|
+
"esModuleInterop": true,
|
|
11
|
+
"skipLibCheck": true,
|
|
12
|
+
"forceConsistentCasingInFileNames": true,
|
|
13
|
+
"resolveJsonModule": true,
|
|
14
|
+
"baseUrl": ".",
|
|
15
|
+
"paths": {
|
|
16
|
+
"@src/*": ["src/*"],
|
|
17
|
+
"@bin/*": ["bin/*"]
|
|
18
|
+
},
|
|
19
|
+
"types": ["node", "jest"]
|
|
20
|
+
},
|
|
21
|
+
"include": ["src/**/*.ts", "bin/**/*.ts", "tests/**/*.ts"],
|
|
22
|
+
"exclude": ["node_modules", "dist", "temp_repos"]
|
|
23
|
+
}
|