From e2db64fc752f2d56f29e1969789ef8e4d13b474e Mon Sep 17 00:00:00 2001 From: Dotta Date: Tue, 23 Jun 2026 01:40:36 +0000 Subject: [PATCH] Enroll Hermes adapter in release publishing Co-Authored-By: Paperclip --- doc/PUBLISHING.md | 8 +++++-- scripts/bootstrap-npm-package.mjs | 28 ++++++++++++++++++------- scripts/bootstrap-npm-package.test.mjs | 29 +++++++++++++++++++++++++- scripts/release-package-manifest.json | 5 +++++ 4 files changed, 59 insertions(+), 11 deletions(-) diff --git a/doc/PUBLISHING.md b/doc/PUBLISHING.md index c430d3473a8..11582e9718e 100644 --- a/doc/PUBLISHING.md +++ b/doc/PUBLISHING.md @@ -209,8 +209,12 @@ The helper script: - checks that the package does not already exist on npm - builds the target package unless `--skip-build` is passed -- runs `npm pack --dry-run` in the package directory -- only runs the real `npm publish --access public` when `--publish --otp ` is provided +- runs `pnpm publish --dry-run --no-git-checks --access public` from the repo root +- only runs the real `pnpm publish --no-git-checks --access public` when `--publish --otp ` is provided + +The helper intentionally uses `pnpm publish` instead of `npm publish` so workspace +dependencies and `publishConfig` export fields are normalized before the package +is sent to the registry. For the real `--publish` step, the maintainer machine must already be authenticated to npm. If `npm whoami` returns `401`, first run `npm logout --registry=https://registry.npmjs.org/` to clear any stale local auth, then run `npm login` or `npm adduser` locally as an npm org member, and finally rerun the helper. diff --git a/scripts/bootstrap-npm-package.mjs b/scripts/bootstrap-npm-package.mjs index 9b1e01beb04..b255d59ab68 100644 --- a/scripts/bootstrap-npm-package.mjs +++ b/scripts/bootstrap-npm-package.mjs @@ -2,7 +2,7 @@ import { spawnSync } from "node:child_process"; import { fileURLToPath } from "node:url"; -import { dirname, join, resolve } from "node:path"; +import { dirname, resolve } from "node:path"; import { buildReleasePackagePlan } from "./release-package-map.mjs"; @@ -187,13 +187,24 @@ function printNextSteps(pkg) { ); } -function publishPackage(pkg, otp) { - const publishArgs = ["publish", "--access", "public"]; - if (otp) { - publishArgs.push("--otp", otp); +function buildPublishArgs(pkg, { dryRun = false, otp = null } = {}) { + const args = ["publish", pkg.dir, "--no-git-checks", "--access", "public"]; + + if (dryRun) { + args.push("--dry-run"); } - const result = runCommand("npm", publishArgs, { cwd: join(repoRoot, pkg.dir) }); + if (otp) { + args.push("--otp", otp); + } + + return args; +} + +function publishPackage(pkg, otp) { + const publishArgs = buildPublishArgs(pkg, { otp }); + + const result = runCommand("pnpm", publishArgs); const stdout = result.stdout ?? ""; const stderr = result.stderr ?? ""; const output = `${stdout}\n${stderr}`.trim(); @@ -214,7 +225,7 @@ function publishPackage(pkg, otp) { ); } - throw new Error(`${formatCommand("npm", publishArgs)} failed with status ${result.status ?? "unknown"}`); + throw new Error(`${formatCommand("pnpm", publishArgs)} failed with status ${result.status ?? "unknown"}`); } function main(argv) { @@ -255,7 +266,7 @@ function main(argv) { } process.stdout.write(`Previewing publish payload for ${pkg.name}...\n`); - runChecked("npm", ["pack", "--dry-run"], { cwd: join(repoRoot, pkg.dir) }); + runChecked("pnpm", buildPublishArgs(pkg, { dryRun: true })); if (!publish) { process.stdout.write( @@ -286,6 +297,7 @@ if (isDirectRun) { } export { + buildPublishArgs, ensureNpmAuth, inspectNpmPackage, parseArgs, diff --git a/scripts/bootstrap-npm-package.test.mjs b/scripts/bootstrap-npm-package.test.mjs index 32270f6be4e..3a2cb0fb1be 100644 --- a/scripts/bootstrap-npm-package.test.mjs +++ b/scripts/bootstrap-npm-package.test.mjs @@ -1,7 +1,7 @@ import assert from "node:assert/strict"; import test from "node:test"; -import { parseArgs, resolveTargetPackage } from "./bootstrap-npm-package.mjs"; +import { buildPublishArgs, parseArgs, resolveTargetPackage } from "./bootstrap-npm-package.mjs"; test("parseArgs recognizes publish and skip-build flags", () => { assert.deepEqual(parseArgs(["@paperclipai/adapter-acpx-local", "--publish", "--skip-build"]), { @@ -58,3 +58,30 @@ test("resolveTargetPackage includes the workspace diff plugin bootstrap package" assert.equal(pkg.dir, "packages/plugins/plugin-workspace-diff"); }); + +test("buildPublishArgs publishes from the repo root through pnpm", () => { + const pkg = { dir: "packages/adapters/hermes-local", name: "@paperclipai/hermes-paperclip-adapter" }; + + assert.deepEqual(buildPublishArgs(pkg), [ + "publish", + "packages/adapters/hermes-local", + "--no-git-checks", + "--access", + "public", + ]); +}); + +test("buildPublishArgs includes dry-run and otp flags when requested", () => { + const pkg = { dir: "packages/adapters/hermes-local", name: "@paperclipai/hermes-paperclip-adapter" }; + + assert.deepEqual(buildPublishArgs(pkg, { dryRun: true, otp: "123456" }), [ + "publish", + "packages/adapters/hermes-local", + "--no-git-checks", + "--access", + "public", + "--dry-run", + "--otp", + "123456", + ]); +}); diff --git a/scripts/release-package-manifest.json b/scripts/release-package-manifest.json index 9f851297820..edc68fb3d01 100644 --- a/scripts/release-package-manifest.json +++ b/scripts/release-package-manifest.json @@ -39,6 +39,11 @@ "name": "@paperclipai/adapter-grok-local", "publishFromCi": true }, + { + "dir": "packages/adapters/hermes-local", + "name": "@paperclipai/hermes-paperclip-adapter", + "publishFromCi": true + }, { "dir": "packages/adapters/opencode-local", "name": "@paperclipai/adapter-opencode-local",