@zshuangmu/agenthub 0.1.3 → 0.1.4
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/cli.js +5 -2
- package/src/commands/install.js +19 -0
- package/src/lib/html.js +2 -2
- package/src/lib/install.js +51 -29
package/package.json
CHANGED
package/src/cli.js
CHANGED
|
@@ -26,7 +26,7 @@ import {
|
|
|
26
26
|
formatVersionsOutput,
|
|
27
27
|
} from "./index.js";
|
|
28
28
|
|
|
29
|
-
const VERSION = "0.1.
|
|
29
|
+
const VERSION = "0.1.3";
|
|
30
30
|
|
|
31
31
|
function printHelp() {
|
|
32
32
|
console.log(`
|
|
@@ -465,7 +465,10 @@ async function main() {
|
|
|
465
465
|
process.exitCode = 1;
|
|
466
466
|
}
|
|
467
467
|
} catch (error) {
|
|
468
|
-
|
|
468
|
+
// 提取更详细的错误信息
|
|
469
|
+
const causeMsg = error.cause?.errors?.[0]?.message || error.cause?.message || "";
|
|
470
|
+
const detailMsg = causeMsg ? `${error.message}\n 原因: ${causeMsg}` : error.message;
|
|
471
|
+
console.error(`\n❌ 错误: ${detailMsg}`);
|
|
469
472
|
process.exitCode = 1;
|
|
470
473
|
}
|
|
471
474
|
}
|
package/src/commands/install.js
CHANGED
|
@@ -11,6 +11,19 @@ export async function installCommand(agentSpec, options) {
|
|
|
11
11
|
options.server = "https://agenthub.cyou";
|
|
12
12
|
}
|
|
13
13
|
|
|
14
|
+
const debugEnabled = Boolean(process.env.AGENTHUB_DEBUG_INSTALL);
|
|
15
|
+
const debug = (message, details) => {
|
|
16
|
+
if (!debugEnabled) return;
|
|
17
|
+
console.error(`[agenthub:install] ${message} | ${JSON.stringify(details)}`);
|
|
18
|
+
};
|
|
19
|
+
|
|
20
|
+
debug("start install", {
|
|
21
|
+
agentSpec,
|
|
22
|
+
hasRegistry: Boolean(options.registry),
|
|
23
|
+
hasServer: Boolean(options.server),
|
|
24
|
+
targetWorkspace,
|
|
25
|
+
});
|
|
26
|
+
|
|
14
27
|
let result;
|
|
15
28
|
if (options.registry) {
|
|
16
29
|
result = await installBundle({
|
|
@@ -26,6 +39,12 @@ export async function installCommand(agentSpec, options) {
|
|
|
26
39
|
});
|
|
27
40
|
}
|
|
28
41
|
|
|
42
|
+
debug("install finished", {
|
|
43
|
+
slug: result.manifest.slug,
|
|
44
|
+
version: result.manifest.version,
|
|
45
|
+
installedAt: new Date().toISOString(),
|
|
46
|
+
});
|
|
47
|
+
|
|
29
48
|
const installRecordPath = path.join(targetWorkspace, ".agenthub", "install.json");
|
|
30
49
|
await writeJson(installRecordPath, {
|
|
31
50
|
slug: result.manifest.slug,
|
package/src/lib/html.js
CHANGED
|
@@ -1643,7 +1643,7 @@ export function renderAgentDetailPage(manifest) {
|
|
|
1643
1643
|
</div>
|
|
1644
1644
|
</div>
|
|
1645
1645
|
<div class="detail-install" title="Click to copy">
|
|
1646
|
-
<span class="code-text">npx @zshuangmu/agenthub install ${manifest.slug} --
|
|
1646
|
+
<span class="code-text">npx @zshuangmu/agenthub install ${manifest.slug} --target-workspace ./my-workspace</span>
|
|
1647
1647
|
<button class="copy-btn" title="Copy">📋</button>
|
|
1648
1648
|
</div>
|
|
1649
1649
|
</div>
|
|
@@ -1696,7 +1696,7 @@ export function renderAgentDetailPage(manifest) {
|
|
|
1696
1696
|
<span class="badge-new">推荐</span>
|
|
1697
1697
|
<div class="install-label">npx (无需预安装)</div>
|
|
1698
1698
|
<div class="detail-install" title="Click to copy">
|
|
1699
|
-
<span class="code-text">npx @zshuangmu/agenthub install ${manifest.slug} --
|
|
1699
|
+
<span class="code-text">npx @zshuangmu/agenthub install ${manifest.slug} --target-workspace ./my-workspace</span>
|
|
1700
1700
|
<button class="copy-btn" title="Copy">📋</button>
|
|
1701
1701
|
</div>
|
|
1702
1702
|
</div>
|
package/src/lib/install.js
CHANGED
|
@@ -5,53 +5,68 @@ 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
7
|
|
|
8
|
+
function debugLog(message, details) {
|
|
9
|
+
if (!process.env.AGENTHUB_DEBUG_INSTALL) return;
|
|
10
|
+
const suffix = details ? ` | ${JSON.stringify(details)}` : "";
|
|
11
|
+
console.error(`[agenthub:install] ${message}${suffix}`);
|
|
12
|
+
}
|
|
13
|
+
|
|
8
14
|
async function requestPayloadText(rawUrl) {
|
|
9
15
|
const parsed = new URL(rawUrl);
|
|
10
16
|
const transport = parsed.protocol === "http:" ? httpRequest : httpsRequest;
|
|
17
|
+
const requestOptions = {
|
|
18
|
+
method: "GET",
|
|
19
|
+
hostname: parsed.hostname,
|
|
20
|
+
port: parsed.port,
|
|
21
|
+
path: `${parsed.pathname}${parsed.search || ""}`,
|
|
22
|
+
protocol: parsed.protocol,
|
|
23
|
+
headers: {
|
|
24
|
+
"User-Agent": "agenthub-cli/0.1.3",
|
|
25
|
+
Accept: "application/json",
|
|
26
|
+
},
|
|
27
|
+
};
|
|
28
|
+
|
|
29
|
+
debugLog("fallback request begin", { url: rawUrl, protocol: parsed.protocol, hostname: parsed.hostname, path: requestOptions.path });
|
|
11
30
|
|
|
12
31
|
return await new Promise((resolve, reject) => {
|
|
13
|
-
const req = transport(
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
"
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
}
|
|
35
|
-
resolve(data);
|
|
36
|
-
});
|
|
37
|
-
},
|
|
38
|
-
);
|
|
39
|
-
|
|
40
|
-
req.on("error", (error) => reject(error));
|
|
32
|
+
const req = transport(requestOptions, (res) => {
|
|
33
|
+
let data = "";
|
|
34
|
+
res.on("data", (chunk) => {
|
|
35
|
+
data += chunk;
|
|
36
|
+
});
|
|
37
|
+
res.on("end", () => {
|
|
38
|
+
if (res.statusCode < 200 || res.statusCode >= 300) {
|
|
39
|
+
const reason = `${res.statusCode} ${res.statusMessage || ""}`;
|
|
40
|
+
debugLog("fallback request failed", { reason, rawUrl });
|
|
41
|
+
reject(new Error(`Remote install failed: ${reason}`));
|
|
42
|
+
return;
|
|
43
|
+
}
|
|
44
|
+
debugLog("fallback request success", { rawUrl, bytes: data.length });
|
|
45
|
+
resolve(data);
|
|
46
|
+
});
|
|
47
|
+
});
|
|
48
|
+
|
|
49
|
+
req.on("error", (error) => {
|
|
50
|
+
debugLog("fallback request error", { rawUrl, message: error.message });
|
|
51
|
+
reject(error);
|
|
52
|
+
});
|
|
41
53
|
req.end();
|
|
42
54
|
});
|
|
43
55
|
}
|
|
44
56
|
|
|
45
57
|
async function fetchPayload(url) {
|
|
46
58
|
const baseUrl = url.toString();
|
|
59
|
+
debugLog("requesting payload", { url: baseUrl });
|
|
47
60
|
|
|
48
61
|
try {
|
|
49
62
|
const response = await fetch(baseUrl);
|
|
63
|
+
debugLog("primary fetch done", { url: baseUrl, ok: response.ok, status: response.status, statusText: response.statusText });
|
|
50
64
|
if (!response.ok) {
|
|
51
65
|
throw new Error(`${response.status} ${response.statusText}`);
|
|
52
66
|
}
|
|
53
67
|
return response;
|
|
54
68
|
} catch (err) {
|
|
69
|
+
debugLog("primary fetch failed, fallback to http/https", { url: baseUrl, error: err.message });
|
|
55
70
|
const payloadText = await requestPayloadText(baseUrl);
|
|
56
71
|
return {
|
|
57
72
|
ok: true,
|
|
@@ -98,11 +113,17 @@ async function installFromRemote({ serverUrl, agentSpec, targetWorkspace }) {
|
|
|
98
113
|
url.searchParams.set("version", version);
|
|
99
114
|
}
|
|
100
115
|
|
|
116
|
+
debugLog("installing from remote", { serverUrl, slug, version: version || "latest", targetWorkspace, url: url.toString() });
|
|
117
|
+
|
|
101
118
|
let response;
|
|
102
119
|
try {
|
|
103
120
|
response = await fetchPayload(url);
|
|
104
121
|
} catch (error) {
|
|
105
|
-
|
|
122
|
+
debugLog("remote install failed", { slug, error: error.message, cause: error.cause });
|
|
123
|
+
// 提取更详细的错误信息
|
|
124
|
+
const causeMsg = error.cause?.errors?.[0]?.message || error.cause?.message || "";
|
|
125
|
+
const detailMsg = causeMsg ? `${error.message}: ${causeMsg}` : error.message;
|
|
126
|
+
throw new Error(`Remote install failed: ${detailMsg}`);
|
|
106
127
|
}
|
|
107
128
|
|
|
108
129
|
if (!response.ok) {
|
|
@@ -110,6 +131,7 @@ async function installFromRemote({ serverUrl, agentSpec, targetWorkspace }) {
|
|
|
110
131
|
}
|
|
111
132
|
|
|
112
133
|
const payload = await response.json();
|
|
134
|
+
debugLog("payload received", { slug, size: JSON.stringify(payload).length });
|
|
113
135
|
const bundleDir = await materializeBundlePayload(payload);
|
|
114
136
|
return applyBundleDir({ bundleDir, targetWorkspace });
|
|
115
137
|
}
|