@zshuangmu/agenthub 0.1.4 → 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/package.json +1 -1
- package/src/lib/install.js +63 -3
package/package.json
CHANGED
package/src/lib/install.js
CHANGED
|
@@ -4,6 +4,7 @@ import { readAgentInfo } from "./registry.js";
|
|
|
4
4
|
import { materializeBundlePayload } from "./bundle-transfer.js";
|
|
5
5
|
import { request as httpsRequest } from "node:https";
|
|
6
6
|
import { request as httpRequest } from "node:http";
|
|
7
|
+
import { spawn } from "node:child_process";
|
|
7
8
|
|
|
8
9
|
function debugLog(message, details) {
|
|
9
10
|
if (!process.env.AGENTHUB_DEBUG_INSTALL) return;
|
|
@@ -47,17 +48,55 @@ async function requestPayloadText(rawUrl) {
|
|
|
47
48
|
});
|
|
48
49
|
|
|
49
50
|
req.on("error", (error) => {
|
|
50
|
-
debugLog("fallback request error", { rawUrl, message: error.message });
|
|
51
|
-
|
|
51
|
+
debugLog("fallback request error", { rawUrl, code: error.code, message: error.message, errno: error.errno });
|
|
52
|
+
// 构造更完整的错误信息
|
|
53
|
+
const errorDetail = error.code || error.message || `errno ${error.errno}` || "unknown network error";
|
|
54
|
+
reject(new Error(`Network error: ${errorDetail} (${parsed.hostname})`));
|
|
52
55
|
});
|
|
53
56
|
req.end();
|
|
54
57
|
});
|
|
55
58
|
}
|
|
56
59
|
|
|
60
|
+
// 使用 curl 作为终极 fallback(绕过 Cloudflare 等网络限制)
|
|
61
|
+
async function fetchWithCurl(rawUrl) {
|
|
62
|
+
debugLog("curl fallback begin", { url: rawUrl });
|
|
63
|
+
|
|
64
|
+
return await new Promise((resolve, reject) => {
|
|
65
|
+
const curl = spawn("curl", [
|
|
66
|
+
"-s", "-f", // 静默模式,失败时返回非零
|
|
67
|
+
"--connect-timeout", "30",
|
|
68
|
+
"-H", "Accept: application/json",
|
|
69
|
+
rawUrl
|
|
70
|
+
]);
|
|
71
|
+
|
|
72
|
+
let stdout = "";
|
|
73
|
+
let stderr = "";
|
|
74
|
+
|
|
75
|
+
curl.stdout.on("data", (data) => { stdout += data; });
|
|
76
|
+
curl.stderr.on("data", (data) => { stderr += data; });
|
|
77
|
+
|
|
78
|
+
curl.on("close", (code) => {
|
|
79
|
+
if (code !== 0) {
|
|
80
|
+
debugLog("curl fallback failed", { code, stderr: stderr.slice(0, 200) });
|
|
81
|
+
reject(new Error(`curl failed with code ${code}: ${stderr.slice(0, 100)}`));
|
|
82
|
+
return;
|
|
83
|
+
}
|
|
84
|
+
debugLog("curl fallback success", { url: rawUrl, bytes: stdout.length });
|
|
85
|
+
resolve(stdout);
|
|
86
|
+
});
|
|
87
|
+
|
|
88
|
+
curl.on("error", (err) => {
|
|
89
|
+
debugLog("curl spawn error", { message: err.message });
|
|
90
|
+
reject(new Error(`Failed to spawn curl: ${err.message}`));
|
|
91
|
+
});
|
|
92
|
+
});
|
|
93
|
+
}
|
|
94
|
+
|
|
57
95
|
async function fetchPayload(url) {
|
|
58
96
|
const baseUrl = url.toString();
|
|
59
97
|
debugLog("requesting payload", { url: baseUrl });
|
|
60
98
|
|
|
99
|
+
// 1. 尝试原生 fetch
|
|
61
100
|
try {
|
|
62
101
|
const response = await fetch(baseUrl);
|
|
63
102
|
debugLog("primary fetch done", { url: baseUrl, ok: response.ok, status: response.status, statusText: response.statusText });
|
|
@@ -66,13 +105,34 @@ async function fetchPayload(url) {
|
|
|
66
105
|
}
|
|
67
106
|
return response;
|
|
68
107
|
} catch (err) {
|
|
69
|
-
debugLog("primary fetch failed
|
|
108
|
+
debugLog("primary fetch failed", { url: baseUrl, error: err.message });
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
// 2. 尝试 http/https 模块
|
|
112
|
+
try {
|
|
70
113
|
const payloadText = await requestPayloadText(baseUrl);
|
|
114
|
+
debugLog("http/https fallback success", { url: baseUrl });
|
|
71
115
|
return {
|
|
72
116
|
ok: true,
|
|
73
117
|
json: async () => JSON.parse(payloadText),
|
|
74
118
|
statusText: "OK",
|
|
75
119
|
};
|
|
120
|
+
} catch (err) {
|
|
121
|
+
debugLog("http/https fallback failed", { url: baseUrl, error: err.message });
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
// 3. 最终 fallback: 使用 curl
|
|
125
|
+
try {
|
|
126
|
+
const payloadText = await fetchWithCurl(baseUrl);
|
|
127
|
+
debugLog("curl fallback success", { url: baseUrl });
|
|
128
|
+
return {
|
|
129
|
+
ok: true,
|
|
130
|
+
json: async () => JSON.parse(payloadText),
|
|
131
|
+
statusText: "OK",
|
|
132
|
+
};
|
|
133
|
+
} catch (err) {
|
|
134
|
+
debugLog("all fetch methods failed", { url: baseUrl, finalError: err.message });
|
|
135
|
+
throw new Error(`All fetch methods failed. Last error: ${err.message}`);
|
|
76
136
|
}
|
|
77
137
|
}
|
|
78
138
|
|