#!/usr/bin/env node import { createHash } from "node:crypto"; import { readFileSync, writeFileSync } from "node:fs"; import { basename, resolve } from "node:path"; import { execFileSync } from "node:child_process"; import { parseArgs } from "node:util"; const { values } = parseArgs({ options: { "release-dir": { type: "string", default: "release-test" }, bundle: { type: "string", default: "output/dingmcp-test-bundle.tar.gz" }, "bundle-url": { type: "string" }, prompt: { type: "string", default: "output/agent-test-install.md" }, } }); const releaseDir = resolve(String(values["release-dir"])); const bundle = resolve(String(values.bundle)); const bundleUrl = exactHttps(values["bundle-url"]); const promptPath = resolve(String(values.prompt)); const manifest = JSON.parse(readFileSync(`${releaseDir}/manifest.json`, "utf8")); if (typeof manifest.gatewayUrl !== "string" || !manifest.gatewayUrl.trim()) { throw new Error("完整黑盒测试包必须配置薪福通 gatewayUrl;请先部署网关,并用 release:build --gateway-url https://<域名>/mcp 重新生成发行目录"); } const gateway = new URL(manifest.gatewayUrl); if (gateway.protocol !== "https:" || gateway.pathname !== "/mcp" || gateway.search || gateway.hash) { throw new Error("manifest.gatewayUrl 必须是无 query/hash 的 HTTPS /mcp 地址"); } const artifactNames = [...new Set(Object.values(manifest.artifacts ?? {}).map((item) => basename(String(item.url))))]; const members = ["SHA256SUMS", "install.md", "compat-install.md", "manifest.json", "manifest.sig", ...artifactNames]; execFileSync("tar", [ "--sort=name", "--mtime=@0", "--owner=0", "--group=0", "--numeric-owner", "--format=ustar", "-czf", bundle, "-C", releaseDir, ...members, ]); const digest = createHash("sha256").update(readFileSync(bundle)).digest("hex"); let prompt = readFileSync(resolve("distribution/agent-test.template.md"), "utf8"); prompt = prompt.replaceAll("{{BUNDLE_URL}}", bundleUrl).replaceAll("{{BUNDLE_SHA256}}", digest); writeFileSync(promptPath, prompt, "utf8"); console.log(`测试包:${bundle}`); console.log(`SHA-256:${digest}`); console.log(`测试提示词:${promptPath}`); function exactHttps(value) { if (!value) throw new Error("缺少 --bundle-url"); const url = new URL(String(value)); if (url.protocol !== "https:" || url.username || url.password || url.hash) throw new Error("--bundle-url 必须是无内嵌凭证的 HTTPS URL"); return url.toString(); }