fix: repair fresh-install breakage and silent-success exit codes
P0: fresh installs of @wave-av/cli were broken; several safety commands lied about success
Reproduction (live probe, confirmed against 1.0.8 as published)
$ npm i @wave-av/cli # resolves @wave-av/sdk via ^2.0.11 -> 2.1.2 (2026-08-28)
$ wave --version
node_modules/@wave-av/sdk/dist/chunk-VYLVDBON.mjs:73
if (__require.main === module) {
^
ReferenceError: module is not defined in ES module scope
Root cause lives in @wave-av/sdk (separate PR: wave-av/sdk#111) — a CJS-only
require.main === module entry guard got bundled into a shared ESM chunk, so it
throws for any ESM importer of the package. This CLI is itself
"type": "module", so it always takes the SDK's "import" export condition —
exactly the path the bug hits. Every single wave invocation died before argv
parsing even started.
Related defects fixed in the same pass (all reproduced live before fixing):
@wave-av/sdkand@wave-av/cliboth declare a bin namedwave— which one
wins innode_modules/.binis install-order luck. (Resolved on the SDK side by
renaming its bin towave-sdk; see wave-av/sdk#111.)wave --versionprinted a hardcoded"1.0.0", not the real published version.wave doctor,wave status,wave auth statusall exited0unconditionally,
even with a failing check or while completely unauthenticated.wave statushealth-checkedhttps://wave.online(the marketing site) at
/api/health— verified live: 404. The correct target,
https://api.wave.online/health, verified live: 200
({"ok":true,"service":"wave-gateway","version":"dev"}).
Fixes in this PR
- Unbreak fresh installs today, independent of the SDK PR's publish timing.
Pinned@wave-av/sdkto2.0.14(exact, last known-good published version)
instead of the^2.0.11range that resolves the broken 2.1.x line.
@wave-av/sdk@2.1.3(the real fix) is not yet published to npm as of this
PR — verified vianpm view @wave-av/sdk versionsagainst the public registry.
Once it is published, bump this pin to^2.1.3in a follow-up so installs pick
up the fixed SDK build going forward instead of staying pinned indefinitely. wave --versionnow reads the version from package.json at runtime via
node:module'screateRequire(works identically fromsrc/cli.tsin dev and
the bundleddist/index.js, since both sit one directory below the package
root).wave doctor/wave status/wave auth statusnow set
process.exitCode = 1when a check fails or the caller is unauthenticated.
wave whoamialready exited1correctly ("keep the good copy" per the brief)
— unchanged in behavior, just hardened with an explicitreturnafter each
process.exit(1)so a future refactor (or a test harness that mocks
process.exit) can't accidentally fall through to the authenticated code path.wave statusnow health-checkshttps://api.wave.online/health(not
https://wave.online/api/health). Also fixed the identical wrong-default-host
bug inwave auth login's device-authorization flow andwave whoami's
/api/v1/mecall, both of which fell back to the marketing site when no
project-specificbaseUrlwas configured. No separate "apex"/marketing check
was added — there wasn't one before this fix either; the single check now just
targets the correct host.
Tests (this PR adds the CLI's first test suite — 0 tests existed before)
src/cli.test.ts—--versionresolves from package.json, not a hardcoded
string.src/commands/doctor/index.test.ts— exits non-zero on a failing check, exits
clean (noexitCodeset) when everything passes.src/commands/status/index.test.ts— hitshttps://api.wave.online/health
(not the marketing host); exits non-zero when unauthenticated; exits non-zero
when the API is unreachable even if authenticated; stays exit-0 on the healthy
path.src/commands/auth/index.test.ts—auth statusexits non-zero unauthenticated
(previously always 0);whoamicalls the API host, not the marketing site, and
exits 1 immediately without an API call when no key is stored.
Verified all 8 behavior-changing assertions fail against pre-fix origin/main
(ran the identical test files in a detached-HEAD worktree at the pre-fix commit,
with the fixed SDK tarball installed so only the CLI-side behavior is under
test) and pass against this branch. The 3 "stays healthy" assertions correctly
pass in both states — those aren't regressions, just confirming the happy path
was never broken.
Gates
npm run build(tsup) — succeeds.npx vitest run— 11 passed.npm run type-check— pre-existing breakage, unrelated to this change: 148
TS errors onorigin/mainbefore this PR, from a missingsrc/types/index.ts
(this repo's source was recovered from published sourcemaps — see PR #24/#18
history) plus drift between command code and the installed SDK's actual API
shape. Diffed the full error list before/after this PR: identical count,
identical error codes, zero errors in any file this PR touches. Not fixing
the pre-existing 148 here — that's a much larger, separate undertaking
(recreatingtypes/index.tsand reconciling ~15 command files against the
current SDK surface).npm run lint— pre-existing breakage, unrelated:eslintisn't even
listed indevDependencies(sh: eslint: command not found), confirmed on a
pristineorigin/maincheckout before this PR touched anything.
Fresh-install proof (paste of actual commands + exit codes)
$ npm install # picks up the @wave-av/sdk@2.0.14 pin from the public registry
$ npm run build
$ HOME=/tmp/fake-home node dist/index.js --version
1.0.9
exit: 0
$ HOME=/tmp/fake-home node dist/index.js doctor
...
✗ Auth: No API key found
1 issue(s) need attention.
exit: 1
$ HOME=/tmp/fake-home node dist/index.js status
...
API: Healthy (162ms) # <- really hit api.wave.online/health, not wave.online
exit: 1 # <- unauthenticated, correctly non-zero
$ HOME=/tmp/fake-home node dist/index.js whoami
Not authenticated. Run `wave auth login` first.
exit: 1
$ HOME=/tmp/fake-home node dist/index.js auth status
exit: 1
Release note
Publishing @wave-av/cli@1.0.9 to npm is a separate, manual operator step.
This PR does not run npm publish. Publish order is now less coupled to
wave-av/sdk#111's publish timing than originally planned, since this release pins
to the already-published, working 2.0.14 rather than depending on the
not-yet-published 2.1.3.
Co-Authored-By: Claude Fable 5.1 noreply@anthropic.com
Claude-Session: https://claude.ai/code/session_01K9mRh8G2ugbUt2kaXvFvF6
🤖 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]
Medium Risk
Touches install-time SDK resolution, default API hosts for auth/status, and exit-code semantics that automation may depend on—mostly fixes but behavior changes for failing/unauthenticated runs.
Overview
Release @wave-av/cli@1.0.9 addresses a P0 where fresh npm i pulled a broken @wave-av/sdk (2.1.x ESM crash) by pinning the SDK to 2.0.14 and adding a lockfile; version is bumped in package.json.
wave --version no longer hardcodes 1.0.0 — it loads the real version from package.json via createRequire, including the banner and Commander -v.
Diagnostics and auth commands now signal failure to scripts: wave doctor, wave status, and wave auth status set process.exitCode = 1 when checks fail or the user is unauthenticated; wave whoami keeps process.exit(1) but adds explicit return after exit so execution cannot fall through.
Default API base URL is corrected from the marketing site to https://api.wave.online for wave status (/health), wave auth login, and wave whoami when no project baseUrl is set.
Adds Vitest coverage (e.g. src/cli.test.ts and command tests per PR description) and a detailed CHANGELOG entry for 1.0.9.
Reviewed by Cursor Bugbot for commit dd897ec519fa60ed6e220bba5cdaa5a66ce58e2d. Bugbot is set up for automated code reviews on this repo. Configure here.
Summary by Sourcery
Repair fresh-install compatibility and make CLI health and authentication commands accurately report failures.
Bug Fixes:
- Restore fresh CLI installs by pinning the SDK to a known-good published version.
- Report the installed CLI version dynamically instead of using a hardcoded value.
- Return failing exit codes for unsuccessful doctor, status, and authentication checks.
- Route default authentication, identity, and health requests to the API host and correct health endpoint.
Build:
- Add the package lockfile and update the CLI package version to 1.0.9.
Documentation:
- Document the release fixes and manual npm publishing requirement in the changelog.
Tests:
- Add regression coverage for version reporting, command exit codes, authentication behavior, and API health-host selection.