























@@ -1,25 +1,90 @@
11const crypto = require("node:crypto");
22const fs = require("node:fs");
33const http = require("node:http");
4+const os = require("node:os");
45const path = require("node:path");
56const { createRequire } = require("node:module");
6778const profile = process.argv[2];
89const portFile = process.argv[3];
910const requireFromApp = createRequire(path.join(process.cwd(), "package.json"));
1011const JSZip = requireFromApp("jszip");
12+const tar = requireFromApp("tar");
1113const packageName = "@openclaw/kitchen-sink";
1214const pluginId = "openclaw-kitchen-sink-fixture";
131514-const buildClawPackSummary = ({ sha256hash, manifestSha256, size }) => ({
16+const buildArtifactSummary = ({
17+ clawpackSha256,
18+ clawpackSize,
19+ npmIntegrity,
20+ npmShasum,
21+ npmTarballName,
22+}) => ({
23+kind: "npm-pack",
24+format: "tgz",
25+sha256: clawpackSha256,
26+size: clawpackSize,
27+ npmIntegrity,
28+ npmShasum,
29+ npmTarballName,
30+});
31+32+const buildClawPackSummary = ({
33+ clawpackSha256,
34+ clawpackSize,
35+ npmIntegrity,
36+ npmShasum,
37+ npmTarballName,
38+}) => ({
1539available: true,
16-specVersion: 1,
17-format: "clawpack.zip",
18-sha256: sha256hash,
19- size,
20- manifestSha256,
40+format: "tgz",
41+sha256: clawpackSha256,
42+size: clawpackSize,
43+ npmIntegrity,
44+ npmShasum,
45+ npmTarballName,
2146});
224748+async function buildNpmPackArtifact(fixture) {
49+const packRoot = await fs.promises.mkdtemp(path.join(os.tmpdir(), "openclaw-clawhub-fixture-"));
50+try {
51+const packageDir = path.join(packRoot, "package");
52+await fs.promises.mkdir(packageDir, { recursive: true });
53+await fs.promises.writeFile(
54+path.join(packageDir, "package.json"),
55+`${JSON.stringify(fixture.packageJson, null, 2)}\n`,
56+);
57+await fs.promises.writeFile(path.join(packageDir, "index.js"), fixture.indexJs);
58+await fs.promises.writeFile(
59+path.join(packageDir, "openclaw.plugin.json"),
60+`${JSON.stringify(fixture.manifest, null, 2)}\n`,
61+);
62+const npmTarballName = `${packageName.replace(/^@/, "").replace("/", "-")}-${fixture.version}.tgz`;
63+const archivePath = path.join(packRoot, npmTarballName);
64+await tar.c(
65+{
66+cwd: packRoot,
67+file: archivePath,
68+gzip: true,
69+portable: true,
70+noMtime: true,
71+},
72+["package"],
73+);
74+const archive = await fs.promises.readFile(archivePath);
75+return {
76+ archive,
77+clawpackSha256: crypto.createHash("sha256").update(archive).digest("hex"),
78+clawpackSize: archive.length,
79+npmIntegrity: `sha512-${crypto.createHash("sha512").update(archive).digest("base64")}`,
80+npmShasum: crypto.createHash("sha1").update(archive).digest("hex"),
81+ npmTarballName,
82+};
83+} finally {
84+await fs.promises.rm(packRoot, { recursive: true, force: true }).catch(() => undefined);
85+}
86+}
87+2388const profiles = {
2489"kitchen-sink-plugin": {
2590version: "0.1.3",
@@ -98,6 +163,7 @@ export default definePluginEntry({
98163},
99164packageDetail(artifact) {
100165const clawpack = buildClawPackSummary(artifact);
166+const packageArtifact = buildArtifactSummary(artifact);
101167const packageDetail = {
102168package: {
103169name: packageName,
@@ -131,6 +197,7 @@ export default definePluginEntry({
131197hasProvenance: false,
132198scanStatus: "passed",
133199},
200+artifact: packageArtifact,
134201 clawpack,
135202},
136203};
@@ -151,6 +218,7 @@ export default definePluginEntry({
151218compatibility: packageDetail.package.compatibility,
152219capabilities: packageDetail.package.capabilities,
153220verification: packageDetail.package.verification,
221+artifact: packageArtifact,
154222 clawpack,
155223},
156224},
@@ -209,6 +277,7 @@ export default definePluginEntry({
209277minGatewayVersion: "2026.4.26",
210278};
211279const clawpack = buildClawPackSummary(artifact);
280+const packageArtifact = buildArtifactSummary(artifact);
212281return {
213282packageDetail: {
214283package: {
@@ -222,6 +291,7 @@ export default definePluginEntry({
222291createdAt: 0,
223292updatedAt: 0,
224293 compatibility,
294+artifact: packageArtifact,
225295 clawpack,
226296},
227297},
@@ -232,6 +302,7 @@ export default definePluginEntry({
232302changelog: "Kitchen-sink fixture package for Docker plugin E2E.",
233303sha256hash: artifact.sha256hash,
234304 compatibility,
305+artifact: packageArtifact,
235306 clawpack,
236307},
237308},
@@ -257,11 +328,10 @@ async function main() {
257328258329const archive = await zip.generateAsync({ type: "nodebuffer", compression: "DEFLATE" });
259330const sha256hash = crypto.createHash("sha256").update(archive).digest("hex");
260-const manifestSha256 = crypto.createHash("sha256").update(manifestJson).digest("hex");
331+const clawpack = await buildNpmPackArtifact(fixture);
261332const { packageDetail, versionDetail, betaStatus } = fixture.packageDetail({
262333 sha256hash,
263- manifestSha256,
264-size: archive.length,
334+ ...clawpack,
265335});
266336267337const json = (response, value, status = 200) => {
@@ -304,15 +374,17 @@ async function main() {
304374}
305375if (
306376url.pathname ===
307-`/api/v1/packages/${encodeURIComponent(packageName)}/versions/${fixture.version}/clawpack`
377+`/api/v1/packages/${encodeURIComponent(packageName)}/versions/${fixture.version}/artifact/download`
308378) {
309379response.writeHead(200, {
310-"content-type": "application/zip",
311-"content-length": String(archive.length),
312-"X-ClawHub-ClawPack-Sha256": sha256hash,
313-"X-ClawHub-ClawPack-Spec-Version": "1",
380+"content-type": "application/octet-stream",
381+"content-length": String(clawpack.archive.length),
382+"X-ClawHub-Artifact-Type": "npm-pack-tarball",
383+"X-ClawHub-Artifact-Sha256": clawpack.clawpackSha256,
384+"X-ClawHub-Npm-Integrity": clawpack.npmIntegrity,
385+"X-ClawHub-Npm-Shasum": clawpack.npmShasum,
314386});
315-response.end(archive);
387+response.end(clawpack.archive);
316388return;
317389}
318390response.writeHead(404, { "content-type": "text/plain" });
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。