Skip to content

feat(doctor): add private API helper check; refactor checks into named functions#8

Merged
anmho merged 1 commit into
mainfrom
feat/doctor-private-api-helper
May 26, 2026
Merged

feat(doctor): add private API helper check; refactor checks into named functions#8
anmho merged 1 commit into
mainfrom
feat/doctor-private-api-helper

Conversation

@anmho
Copy link
Copy Markdown
Owner

@anmho anmho commented May 26, 2026

Summary

Adds a new doctor check that surfaces a common silent failure: the BlueBubbles server reports Private API as enabled, but the in-Messages helper dylib never actually connected — so every Private-API endpoint (unsend, edit, tapback, typing-indicator) 500s with a generic Unsend Message Error / iMessage Private API Helper is not connected!.

Hit this in production with bluebubbles messages unsend — wasted 20 min before catching the helper status in /api/v1/server/info. Doctor should flag it.

New check

PASS  private API helper   Server has Private API enabled and helper is connected
WARN  private API helper   Private API enabled in server settings but helper dylib is NOT connected — unsend/edit/tapback/typing-indicator endpoints will fail. Install/repair the Messages Helper via the BlueBubbles UI (Settings → Private API).
WARN  private API helper   Private API is disabled in server settings. Enable it (BlueBubbles UI → Settings → Private API) and install the Messages Helper to use unsend/edit/tapback/typing-indicator endpoints.
WARN  private API helper   Skipped because api ping did not succeed

Reads info.private_api + info.helper_connected from the existing getServerInfo() helper. No new dependencies.

Refactor

The original runDoctor() was a single 100-line function with inline check logic. Pulled each check out into its own named function returning a DoctorCheck. runDoctor() now just composes them. Easier to extend, easier to test individually, no behavior change for existing checks.

Diff: +140 / -67 lines in src/lib/doctor.ts.

Test plan

  • bun run build passes
  • bun run test (16 tests) passes
  • bluebubbles doctor on a server with helper disconnected → shows WARN line above
  • bluebubbles doctor on a server with helper connected → shows PASS

🤖 Generated with Claude Code

…d functions

Adds a 'private API helper' doctor check that queries
GET /api/v1/server/info and reports:
- PASS  when private_api && helper_connected
- WARN  when private_api but helper not connected (unsend/edit/tapback
        will fail; tells user where to install the Messages Helper)
- WARN  when private_api disabled in server settings
- WARN  when api ping didn't succeed (skip rationale)

This surfaces a common silent failure mode where the server reports
Private API enabled but the in-Messages helper dylib never connected,
so all private-API-dependent endpoints (unsend, edit, tapback,
typing-indicator) 500 with a generic error.

Refactor: each check is now its own named function returning a
DoctorCheck. runDoctor just composes them. Easier to add new checks,
easier to test individually.
Copy link
Copy Markdown
Owner Author

anmho commented May 26, 2026

Merge activity

  • May 26, 4:49 AM UTC: A user started a stack merge that includes this pull request via Graphite.
  • May 26, 4:50 AM UTC: @anmho merged this pull request with Graphite.

@anmho anmho merged commit 59e80a5 into main May 26, 2026
1 check passed
Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: fec92173d3

ℹ️ 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".

Comment thread src/lib/doctor.ts
Comment on lines +111 to +112
const privateApi = info.private_api === true;
const helperConnected = info.helper_connected === true;
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Treat unknown helper flags as indeterminate, not disabled

/api/v1/server/info fields are optional in practice, but this logic coerces missing private_api/helper_connected keys into false and then reports "Private API is disabled". In environments where the server returns partial metadata (e.g., older server builds or stripped responses), users will get a misleading diagnostic even when the actual Private API state is unknown; this should instead emit an "unable to determine" warning unless both flags are explicitly present.

Useful? React with 👍 / 👎.

anmho added a commit that referenced this pull request May 26, 2026
## 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)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant