ci: add release.yml for npm publish on v* tags; fix author field

Merged
YA
2mo ago
+103-1

LIVE RECEIPTS

Defect (2026-09-03, code yellow P1): npx @wave-av/cli --version on a fresh install crashes on node 20 and node 22 with ReferenceError: module is not defined in ES module scope inside the sdk's chunk-VYLVDBON.mjs:73. Root cause: package.json pinned @wave-av/sdk with a caret range (^2.0.11), which npm resolved to sdk 2.1.2 — a later sdk release that ships a broken (CJS-in-ESM-context) chunk. npm view @wave-av/sdk version --@wave-av:registry=https://registry.npmjs.org confirms latest is 2.1.2; npm view @wave-av/cli versions confirms the last published cli version is 1.0.8.

Fix already merged, never published: 1.0.9 (PR #39, origin/main at 3a3db2c) pins @wave-av/sdk to an exact 2.0.14 (no caret) in package.json. It sat unpublished because this repo has no release workflow — only _checks.yml, foundation-gate.yml, issue-ops-triage.yml, public-repo-guard.yml. The only path to npmjs was a manual npm publish from a laptop, with zero build/test/smoke gate in front of it. That gap is what let 1.0.8 ship broken in the first place.

Verified locally in an isolated worktree (/tmp/cli-release, git worktree add ... origin/main, npm ci --include=dev):

  • npm run build → tsup ESM build succeeds (158.82 KB).
  • npm test → vitest: 4 test files, 11 tests, all passed.
  • npm pack → wave-av-cli-1.0.9.tgz (96.8 kB, 30 files).
  • Smoke-tested the packed tarball in a throwaway project on node 20.20.2 and node 22.14.0 (npm i ./wave-av-cli-1.0.9.tgz --@wave-av:registry=https://registry.npmjs.org && npx wave --version) → both print 1.0.9, and the installed node_modules/@wave-av/sdk/package.json resolves to 2.0.14 (not the broken 2.1.2).

Note for the reviewer: npm run type-check on this same tree surfaces ~35 pre-existing tsc errors (signage/slides/stream/studio/transcribe/usb/vault/voice/zoom commands referencing SDK methods that don't exist on the current SDK types, plus 3 missing types/index.js module errors). These are pre-existing on origin/main — not introduced by this PR, and not blocking tsup's transpile-only build — but they mean npm run type-check is not wired into any gate today and should probably become one in a follow-up. npm run lint fails locally with eslint: command not found (eslint isn't resolving from --include=dev install); not investigated further since it's out of scope for this PR.

WHAT CHANGED

  • .github/workflows/release.yml (new). Triggered on v* tags. Steps: checkout (SHA-pinned) → actions/setup-node node 22 (SHA-pinned) → verify the tag version matches package.json version (fails closed on mismatch) → npm ci --include=dev → npm run build → npm test → npm pack → smoke-test the packed tarball in a throwaway project (npm i <tarball> && npx wave --version, compared against package.json version) — this is the exact check 1.0.8 shipped without — then npm publish --provenance --access public. Auth: npm trusted publishing (OIDC via id-token: write) once this repo+workflow is registered as a trusted publisher on npmjs; falls back to the NPM_TOKEN repository secret otherwise (only written to the npm config if the secret is non-empty). Modeled on wave-foundation's release-spoke-chassis.yml (tag-triggered, verify+publish shape, SHA-pinned actions), adapted for a public npm target instead of GitHub Packages.
  • package.json: author corrected from "WAVE Inc. <sdk@wave.online>" to the correct legal entity "WAVE Online, LLC".

OPERATOR STEPS (to activate publishing)

  1. One-time: register wave-av/cli + .github/workflows/release.yml as a trusted publisher for @wave-av/cli in the npmjs package settings (Publishing access → Trusted Publisher → GitHub Actions), OR set the NPM_TOKEN repository secret (Settings → Secrets and variables → Actions) as the fallback path. Either is sufficient; no workflow changes needed either way.
  2. To cut a release: git tag v1.0.9 3a3db2c && git push origin v1.0.9 (or the current main tip at release time).
  3. This PR does not merge itself and carries no autonomy:auto-merge label — review and merge manually.

GATES

  • npm run build — OK (tsup ESM build, 158.82 KB)
  • npm test — OK (vitest: 4 files / 11 tests passed)
  • npm run type-check — pre-existing FAIL (~35 errors, all pre-existing on origin/main, unrelated to this change)
  • npm run lint — FAIL locally (eslint: command not found), not investigated, out of scope

🤖 Generated with Claude Code
https://claude.ai/code/session_01K9mRh8G2ugbUt2kaXvFvF6


View with [code]smith Autofix with [code]smith
Need help on this PR? Tag @codesmith-bot with what you need. Autofix is disabled.


[!NOTE]
Cursor Bugbot is generating a summary for commit 364c726dbbf2980e6ec2fb7f7d766a58def882f8. Configure here.

Summary by Sourcery

Automate gated, version-validated npm publishing for tagged CLI releases and correct the package metadata.

New Features:

  • Add a tag-triggered CI workflow that validates, builds, tests, smoke-tests, and publishes the CLI package to public npm.

Bug Fixes:

  • Prevent releases from being published when the Git tag does not match the package version.

Enhancements:

  • Correct the package author to WAVE Online, LLC.

CI:

  • Support npm trusted publishing through OIDC with an NPM_TOKEN fallback.

Deployment:

  • Automate public npm releases with provenance enabled.

Tests:

  • Verify the packed release tarball by installing it and checking the CLI version before publication.