ci: add release.yml for npm publish on v* tags; fix author field
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 print1.0.9, and the installednode_modules/@wave-av/sdk/package.jsonresolves to2.0.14(not the broken2.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 onv*tags. Steps: checkout (SHA-pinned) →actions/setup-nodenode 22 (SHA-pinned) → verify the tag version matchespackage.jsonversion (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 againstpackage.jsonversion) — this is the exact check1.0.8shipped without — thennpm publish --provenance --access public. Auth: npm trusted publishing (OIDC viaid-token: write) once this repo+workflow is registered as a trusted publisher on npmjs; falls back to theNPM_TOKENrepository secret otherwise (only written to the npm config if the secret is non-empty). Modeled onwave-foundation'srelease-spoke-chassis.yml(tag-triggered, verify+publish shape, SHA-pinned actions), adapted for a public npm target instead of GitHub Packages.package.json:authorcorrected from"WAVE Inc. <sdk@wave.online>"to the correct legal entity"WAVE Online, LLC".
OPERATOR STEPS (to activate publishing)
- One-time: register
wave-av/cli+.github/workflows/release.ymlas a trusted publisher for@wave-av/cliin the npmjs package settings (Publishing access → Trusted Publisher → GitHub Actions), OR set theNPM_TOKENrepository secret (Settings → Secrets and variables → Actions) as the fallback path. Either is sufficient; no workflow changes needed either way. - To cut a release:
git tag v1.0.9 3a3db2c && git push origin v1.0.9(or the currentmaintip at release time). - This PR does not merge itself and carries no
autonomy:auto-mergelabel — 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 onorigin/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
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.