agenteval-cli 0.8.3 → 0.8.5
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/bin/agenteval.js +46 -35
- package/package.json +1 -1
package/bin/agenteval.js
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
|
|
3
|
-
const { execFileSync
|
|
4
|
-
const {
|
|
3
|
+
const { execFileSync } = require("child_process");
|
|
4
|
+
const { createHash } = require("crypto");
|
|
5
|
+
const { existsSync, mkdirSync, chmodSync, renameSync, unlinkSync, readFileSync, writeFileSync } = require("fs");
|
|
5
6
|
const { join } = require("path");
|
|
6
7
|
const https = require("https");
|
|
7
8
|
|
|
@@ -10,41 +11,52 @@ const CACHE_DIR = join(require("os").homedir(), ".agenteval", "bin");
|
|
|
10
11
|
const BIN_PATH = join(CACHE_DIR, "agenteval");
|
|
11
12
|
const VERSION_PATH = join(CACHE_DIR, ".version");
|
|
12
13
|
|
|
14
|
+
// SHA256 checksums injected by the release workflow.
|
|
15
|
+
// If all zeros, integrity check is skipped (dev/unreleased builds).
|
|
16
|
+
const CHECKSUMS = {
|
|
17
|
+
"agenteval-linux-x64": "59729b785863d678fe80a97a728c95d557890c571eea66d8d2c8239630c0248b",
|
|
18
|
+
"agenteval-darwin-arm64": "b4d7d81a0be0cb7075cb651f2d5f0d365d8603b529839d4e158bda8007618718",
|
|
19
|
+
"agenteval-darwin-x64": "3712af2cfe0edb7de629da2a475d5903e4475eb3b828d1778ed83331bf7af4a5",
|
|
20
|
+
};
|
|
21
|
+
|
|
13
22
|
function getPlatformKey() {
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
if (platform === "
|
|
17
|
-
if (platform === "darwin" && arch === "x64") return "agenteval-darwin-x64";
|
|
18
|
-
if (platform === "linux" && arch === "x64") return "agenteval-linux-x64";
|
|
23
|
+
if (process.platform === "darwin" && process.arch === "arm64") return "agenteval-darwin-arm64";
|
|
24
|
+
if (process.platform === "darwin" && process.arch === "x64") return "agenteval-darwin-x64";
|
|
25
|
+
if (process.platform === "linux" && process.arch === "x64") return "agenteval-linux-x64";
|
|
19
26
|
return null;
|
|
20
27
|
}
|
|
21
28
|
|
|
22
29
|
function getPackageVersion() {
|
|
23
|
-
try {
|
|
24
|
-
return require("../package.json").version;
|
|
25
|
-
} catch {
|
|
26
|
-
return null;
|
|
27
|
-
}
|
|
30
|
+
try { return require("../package.json").version; } catch { return null; }
|
|
28
31
|
}
|
|
29
32
|
|
|
30
33
|
function getCachedVersion() {
|
|
31
|
-
try {
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
34
|
+
try { return readFileSync(VERSION_PATH, "utf8").trim(); } catch { return null; }
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
function verifySHA256(data, expected) {
|
|
38
|
+
// Skip verification if checksums are placeholder zeros
|
|
39
|
+
if (expected.startsWith("0000000000")) return true;
|
|
40
|
+
const actual = createHash("sha256").update(data).digest("hex");
|
|
41
|
+
return actual === expected;
|
|
36
42
|
}
|
|
37
43
|
|
|
38
|
-
function download(url) {
|
|
44
|
+
function download(url, maxRedirects) {
|
|
45
|
+
if (maxRedirects === undefined) maxRedirects = 5;
|
|
46
|
+
if (maxRedirects <= 0) return Promise.reject(new Error("Too many redirects"));
|
|
39
47
|
return new Promise((resolve, reject) => {
|
|
40
|
-
|
|
48
|
+
const parsedUrl = new URL(url);
|
|
49
|
+
const options = { hostname: parsedUrl.hostname, path: parsedUrl.pathname + parsedUrl.search, headers: { "User-Agent": "agenteval-cli" } };
|
|
50
|
+
https.get(options, (res) => {
|
|
41
51
|
if (res.statusCode === 301 || res.statusCode === 302) {
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
52
|
+
const location = res.headers.location;
|
|
53
|
+
if (!location || (!location.startsWith("https://") && !location.startsWith("https://github.com"))) {
|
|
54
|
+
reject(new Error(`Unsafe redirect to ${location}`));
|
|
55
|
+
return;
|
|
56
|
+
}
|
|
57
|
+
return download(location, maxRedirects - 1).then(resolve, reject);
|
|
47
58
|
}
|
|
59
|
+
if (res.statusCode !== 200) { reject(new Error(`HTTP ${res.statusCode}`)); return; }
|
|
48
60
|
const chunks = [];
|
|
49
61
|
res.on("data", (chunk) => chunks.push(chunk));
|
|
50
62
|
res.on("end", () => resolve(Buffer.concat(chunks)));
|
|
@@ -57,7 +69,6 @@ async function ensureBinary() {
|
|
|
57
69
|
const pkgVersion = getPackageVersion();
|
|
58
70
|
const cachedVersion = getCachedVersion();
|
|
59
71
|
|
|
60
|
-
// Binary exists and matches current package version
|
|
61
72
|
if (existsSync(BIN_PATH) && cachedVersion === pkgVersion) {
|
|
62
73
|
return BIN_PATH;
|
|
63
74
|
}
|
|
@@ -66,7 +77,6 @@ async function ensureBinary() {
|
|
|
66
77
|
if (!binary) {
|
|
67
78
|
console.error(`agenteval: unsupported platform ${process.platform}-${process.arch}`);
|
|
68
79
|
console.error("Supported: linux-x64, darwin-arm64, darwin-x64");
|
|
69
|
-
console.error("Install manually: https://github.com/lukasmetzler/agenteval/releases");
|
|
70
80
|
process.exit(1);
|
|
71
81
|
}
|
|
72
82
|
|
|
@@ -74,22 +84,23 @@ async function ensureBinary() {
|
|
|
74
84
|
const url = `https://github.com/${REPO}/releases/download/${version}/${binary}`;
|
|
75
85
|
|
|
76
86
|
console.error(`Downloading agenteval ${version} (${binary})...`);
|
|
77
|
-
|
|
78
87
|
mkdirSync(CACHE_DIR, { recursive: true });
|
|
79
88
|
|
|
80
89
|
const tmpPath = `${BIN_PATH}.tmp.${Date.now()}`;
|
|
81
90
|
try {
|
|
82
91
|
const data = await download(url);
|
|
83
|
-
require("fs").writeFileSync(tmpPath, data);
|
|
84
|
-
chmodSync(tmpPath, 0o755);
|
|
85
92
|
|
|
86
|
-
//
|
|
87
|
-
|
|
88
|
-
|
|
93
|
+
// Verify integrity
|
|
94
|
+
const expectedHash = CHECKSUMS[binary];
|
|
95
|
+
if (!verifySHA256(data, expectedHash)) {
|
|
96
|
+
throw new Error("SHA256 checksum mismatch — download may be corrupted or tampered with");
|
|
89
97
|
}
|
|
90
|
-
renameSync(tmpPath, BIN_PATH);
|
|
91
|
-
require("fs").writeFileSync(VERSION_PATH, pkgVersion || version);
|
|
92
98
|
|
|
99
|
+
writeFileSync(tmpPath, data);
|
|
100
|
+
chmodSync(tmpPath, 0o755);
|
|
101
|
+
if (existsSync(BIN_PATH)) { try { unlinkSync(BIN_PATH); } catch {} }
|
|
102
|
+
renameSync(tmpPath, BIN_PATH);
|
|
103
|
+
writeFileSync(VERSION_PATH, pkgVersion || version);
|
|
93
104
|
console.error("Done.");
|
|
94
105
|
} catch (err) {
|
|
95
106
|
try { unlinkSync(tmpPath); } catch {}
|
|
@@ -103,7 +114,7 @@ async function ensureBinary() {
|
|
|
103
114
|
|
|
104
115
|
ensureBinary().then((binPath) => {
|
|
105
116
|
try {
|
|
106
|
-
|
|
117
|
+
execFileSync(binPath, process.argv.slice(2), { stdio: "inherit" });
|
|
107
118
|
} catch (err) {
|
|
108
119
|
process.exit(err && typeof err === "object" && "status" in err ? err.status : 1);
|
|
109
120
|
}
|