diff --git a/scripts/verify-plugin-npm-published-runtime.mjs b/scripts/verify-plugin-npm-published-runtime.mjs index 1370dc449cb..eb9cbd64eca 100644 --- a/scripts/verify-plugin-npm-published-runtime.mjs +++ b/scripts/verify-plugin-npm-published-runtime.mjs @@ -306,12 +306,26 @@ function readPackedPackage(tarballPath, extractDir) { tar.x({ file: tarballPath, cwd: extractDir, sync: true }); const packageDir = path.join(extractDir, "package"); const packageJson = JSON.parse(fs.readFileSync(path.join(packageDir, "package.json"), "utf8")); + const files = listFiles(packageDir); return { packageJson, - files: listFiles(packageDir), + files, + readme: readPackedPackageReadme(packageDir, files), }; } +export function findPackedPackageReadmePath(files) { + return files.find((file) => /^readme(?:\.(?:md|markdown|txt|rst))?$/iu.test(file)) ?? ""; +} + +function readPackedPackageReadme(packageDir, files) { + const readmePath = findPackedPackageReadmePath(files); + if (!readmePath) { + return ""; + } + return fs.readFileSync(path.join(packageDir, readmePath), "utf8").trim(); +} + export async function verifyPublishedPluginRuntime(spec) { const workingDir = fs.mkdtempSync(path.join(os.tmpdir(), "openclaw-plugin-npm-runtime.")); try { @@ -326,7 +340,18 @@ export async function verifyPublishedPluginRuntime(spec) { if (errors.length > 0) { throw new Error(errors.join("\n")); } - const readme = await verifyPublishedPackageReadme(spec); + let readme; + try { + readme = await verifyPublishedPackageReadme(spec); + } catch (error) { + if (!packedPackage.readme) { + throw error; + } + console.error( + `npm readme metadata for ${spec} was unavailable; verified README from published tarball instead.`, + ); + readme = packedPackage.readme; + } return { packageName: packedPackage.packageJson.name, version: packedPackage.packageJson.version, diff --git a/test/scripts/verify-plugin-npm-published-runtime.test.ts b/test/scripts/verify-plugin-npm-published-runtime.test.ts index 80266efafa4..2b54cde29af 100644 --- a/test/scripts/verify-plugin-npm-published-runtime.test.ts +++ b/test/scripts/verify-plugin-npm-published-runtime.test.ts @@ -1,6 +1,7 @@ import { describe, expect, it } from "vitest"; import { collectPluginNpmPublishedRuntimeErrors, + findPackedPackageReadmePath, parseNpmReadmeMetadata, readPositiveIntEnv, resolveNpmPackFilename, @@ -210,6 +211,15 @@ describe("resolveNpmPackFilename", () => { }); }); +describe("findPackedPackageReadmePath", () => { + it("finds a root package README without accepting nested documentation files", () => { + expect( + findPackedPackageReadmePath(["package.json", "docs/README.md", "README.md", "dist/index.js"]), + ).toBe("README.md"); + expect(findPackedPackageReadmePath(["package.json", "docs/README.md"])).toBe(""); + }); +}); + describe("parseNpmReadmeMetadata", () => { it("accepts non-empty npm readme metadata", () => { expect(parseNpmReadmeMetadata(JSON.stringify("# Plugin\n\nInstall it."))).toBe(