feat(cli): add 'bluebubbles update' to self-update from npm#9
Conversation
New top-level subcommand: bluebubbles update # install latest via npm (default) bluebubbles update --check # report 'up-to-date' or 'X -> Y' without installing bluebubbles update --package-manager bun|pnpm|yarn Reads installed version from package.json, queries https://registry.npmjs.org/bluebubbles-cli/latest, compares with semver, and either reports up-to-date or invokes the chosen package manager's global-install command for bluebubbles-cli@latest. Why: 'bluebubbles update' was a natural typing-blind reflex when a new release shipped, but the command didn't exist and the error ('unknown command "update"') was unhelpful. Doubles as a discoverable way to flag stale installs.
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 12807736c3
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| ? ["yarn", "global", "add", `${PACKAGE_NAME}@latest`] | ||
| : ["npm", "install", "-g", `${PACKAGE_NAME}@latest`]; | ||
| return new Promise((resolve) => { | ||
| const child = spawn(command[0]!, command.slice(1), { stdio: "inherit" }); |
There was a problem hiding this comment.
Use shell when spawning package managers on Windows
runInstall calls spawn() with default shell: false, but on Windows the npm/pnpm/yarn entrypoints are .cmd wrappers; Node's child_process docs for “Spawning .bat and .cmd files on Windows” state these cannot be launched directly without a shell. In that environment this path will emit an error and resolve to failure, so bluebubbles update will consistently fail for Windows users even when the package manager is installed.
Useful? React with 👍 / 👎.
| const parse = (s: string) => s.split(".").map((n) => Number.parseInt(n, 10) || 0); | ||
| const [aMaj, aMin, aPatch] = parse(a); | ||
| const [bMaj, bMin, bPatch] = parse(b); | ||
| if (aMaj !== bMaj) return (aMaj ?? 0) - (bMaj ?? 0); | ||
| if (aMin !== bMin) return (aMin ?? 0) - (bMin ?? 0); | ||
| return (aPatch ?? 0) - (bPatch ?? 0); |
There was a problem hiding this comment.
Use real semver precedence for prerelease versions
The version comparator strips each dot-separated token with parseInt, which drops prerelease semantics (for example, 1.2.3-beta.1 compares equal to 1.2.3). That causes --check and update decisions to misreport prerelease installs as up to date when a stable release with the same core version exists.
Useful? React with 👍 / 👎.
| latest = await fetchLatestVersion(); | ||
| } catch (error) { | ||
| printError(new CliError(error instanceof Error ? error.message : "Failed to query npm registry", "network")); | ||
| process.exitCode = 1; |
There was a problem hiding this comment.
Preserve typed exit codes for update command failures
This handler constructs typed CliErrors (network, validation) but then hard-codes process.exitCode = 1, which bypasses the exit-code mapping defined in lib/errors.ts. Scripts that distinguish retryable network failures from user validation errors will get the wrong status from bluebubbles update; propagate CliError.exitCode (or throw the error) instead of forcing 1.
Useful? React with 👍 / 👎.
## Summary Merges to `main` no longer sit unreleased. Each merge triggers an automated workflow that: 1. Scans commits since the last release for `feat:` / `fix:` / etc prefixes 2. Opens (or updates) a "release PR" that bumps `package.json`, regenerates `CHANGELOG.md`, and proposes the next semver version 3. When that release PR is merged, the matching `vX.Y.Z` tag is created 4. The existing `release.yml` (already wired to `v*` tag push) handles the npm publish This fixes the visible bug: PR #8 (private-API doctor check) and PR #9 (`bluebubbles update` command) merged into `main` but never reached npm, because `release.yml` only fires on tag push and nothing was automating the tag. ## Files added - `.github/workflows/release-please.yml` — runs on every push to `main` - `release-please-config.json` — release-type=node, v-in-tag=true - `.release-please-manifest.json` — current version (`0.1.7`) ## What happens after this merges 1. release-please run on `main` scans commits since `v0.1.7` 2. Sees two `feat:` commits → opens "chore(release): 0.2.0" PR with CHANGELOG diff 3. You merge that PR → `v0.2.0` tag + GitHub Release created 4. `release.yml` fires on tag push → `npm publish` ## Implementation note The bot is [`googleapis/release-please-action`](https://github.com/googleapis/release-please) — Google's standard tool for conventional-commit-driven releases. Internally named "release please" (the polite-ask meme stuck when they open-sourced it in 2020). All the logic lives in their action; this PR is just the config to point it at this repo. ## Requires - Commit messages already follow conventional commits (`feat:`, `fix:`, `chore:`, etc.) — verified against current log - No npm secrets/config changes — publish still goes through the existing trusted-publishing setup 🤖 Generated with [Claude Code](https://claude.com/claude-code)
Summary
Adds a top-level
updatesubcommand sobluebubbles updatebecomes a no-op when current, or upgrades via the user's chosen package manager when behind.Reads installed version from
package.json, fetcheshttps://registry.npmjs.org/bluebubbles-cli/latest, semver-compares, and either reports up-to-date or invokes the chosen package manager's global-install command forbluebubbles-cli@latest.Why
bluebubbles updatewas a natural typing-blind reflex when a new release shipped, but the command didn't exist and the error message (unknown command "update") was unhelpful. Doubles as a way to surface stale installs.Test plan
bun run buildpassesbun run test(16 tests) passesbun run dev update --check→ "bluebubbles-cli is up to date (installed 0.1.7, latest 0.1.7)."bluebubbles updateupgradesbluebubbles update --package-manager bunworks on bun installs🤖 Generated with Claude Code