Skip to content

Releases: beebeeb-io/cli

bb 0.14.4

Choose a tag to compare

@guuslangelaar0 guuslangelaar0 released this 25 Oct 14:20
dd48984

bb 0.14.4: downloads straight from storage

bb pull and bb sync can now fetch a file's encrypted chunks directly from Beebeeb's object storage instead of streaming every byte through the API. The server hands out short-lived links for one file at a time. The CLI authenticates and decrypts every chunk on your machine exactly as before: the links carry ciphertext only, and your keys never leave the device. When the server does not offer direct downloads, or refuses a link, the file comes through the API as it did in 0.14.3.

What's New

  • Direct downloads. The CLI uses time-limited storage links when the server advertises direct downloads (GET /api/v1/transfer/capabilities). Chunks are decrypted in order, and the file only appears once it is complete and authenticated.
  • Automatic fallback. A file that storage cannot serve before the download starts goes through the API instead. A file that fails partway continues on the API's pinned per-chunk route and keeps what was already written.
  • bb pull --json reports transport (direct, mixed or api). This is an additive key; existing keys are unchanged.
  • BB_TRANSPORT=api (or --transport api) forces the API for every file. BB_TRANSPORT_TRACE=1 prints each transport decision to stderr, never a URL. bb sync --daemon passes the chosen transport on to its child process.
  • Uploads still go through the API in this release.

Bug Fixes / Hardening

  • A sync pass no longer aborts on a file it cannot read, or on a file that changes during its download. It defers that file and carries on. Under launchd or systemd an aborted pass meant a restart every 30 seconds.
  • bb pull <file> starts over once from fresh metadata when the file changes mid-download, then says "changed again" if it changes a second time.
  • The pinned per-chunk route retries rate limits (429), server errors (5xx), a file that is still being written (409) and a broken read: 4 attempts, at most 60 seconds of waiting, honouring Retry-After. A body of the wrong length, an authorization answer and a vanished version are final.
  • bb sync no longer mistakes a file ID containing 409 inside a decrypt error for "still uploading". This could make a failed pass exit 0.
  • Storage requests use an HTTP client of their own, with no cookies, no Authorization header, no redirects and https only. Their error messages never contain a storage URL.
  • bb refuses to install or remove a LaunchAgent or systemd unit when HOME is not your account's home directory (on Linux, also when XDG_CONFIG_HOME points elsewhere), because the service would run against a different configuration than the one you see. If your home directory is intentionally relocated (for example sudo -E), run the command again with BB_SERVICE_INSTALL_ALLOW_CUSTOM_HOME=1. Removing a service that is not installed is never refused.
  • A folder pull reads a file that changed during the pull again once instead of aborting, and the retry does not ask the overwrite question twice.

Compatibility

  • This CLI with an older server: the server advertises no direct downloads, so every file uses the API, exactly as in 0.14.3.
  • An older CLI with a newer server: unchanged. 0.14.3 and earlier never ask for storage links.
  • Dependency change: beebeeb-core / beebeeb-types pinned to 3235dc15 (the shared direct-transfer rules). No other dependency versions changed.

Verification

  • Full test suite on Linux, at the commit this release is built from, in a sandbox with no network access and an egress recorder: 730 passed, 0 failed, 4 ignored across 24 test binaries; 0 outbound connection attempts; no service manager touched. Clippy with warnings denied and rustfmt are clean.
  • tests/direct_download.rs runs the real bb binary against a mock API and a hand-written storage socket. It covers faults, redirects, tampered chunks, expired links, the mixed fallback, and that no link signature appears in any output.
  • tests/service_guard.rs puts recording launchctl / systemctl stubs ahead of the real tools on PATH and scans src/ for any unguarded call.
  • Release gates: full required CLI CI, five platform builds, and draft asset readback with checksum assertions before publishing.

Install / Update

bb update
bb --version   # bb 0.14.4

Homebrew: brew upgrade beebeeb-io/tap/bb. Scoop: scoop update bb. New installs: curl -fsSL https://get.beebeeb.io | sh. Restart a running bb sync daemon after updating.

Full changelog: v0.14.3...v0.14.4

bb 0.14.3

Choose a tag to compare

@guuslangelaar0 guuslangelaar0 released this 24 Oct 15:25

bb 0.14.3 — updates without the GitHub API rate limit

Bug Fixes / Hardening

  • bb update and background update checks use the public release manifest instead of GitHub REST API discovery. Shared-IP API rate limits no longer prevent CLI update checks; no GitHub token is required.
  • Download archives from the exact release tag in the manifest, retaining SHA-256 verification and staged binary version checks.
  • Retains CLI0.14.2's effective curl updates, Homebrew/Scoop ownership, explicit JSON/quiet updates and Beebeeb web billing navigation.

Install / Update

If0.14.2 reports403, bootstrap the patch through the public installer:

curl -fsSL https://get.beebeeb.io | sh
bb update
bb --version

Restart a running bb sync daemon after updating. Unmanaged Windows binaries still use release-archive reinstall or Scoop.

Verification

Regression tests cover a rate-limited REST route with an available public manifest and exact request counts. Release gates include the updater suite, full required CLI CI, formatting, Clippy with warnings denied, five platform builds, draft asset readback and native package checks. No dependency versions changed.

Full changelog: v0.14.2...v0.14.3

bb 0.14.2

Choose a tag to compare

@guuslangelaar0 guuslangelaar0 released this 24 Oct 14:23
0dfd167

bb 0.14.2 — reliable updates and web billing

This patch makes updating bb explicit and fixes billing navigation. Both billing commands now take you to Beebeeb's web app to manage your account.

What's New

  • bb update checks for a newer CLI immediately and reports the result. It bypasses the background-check cooldown; BB_NO_UPDATE=1 still disables automatic updates.

Bug Fixes / Hardening

  • Re-running curl -fsSL https://get.beebeeb.io | sh updates the existing Beebeeb installation your shell selects. Homebrew installations remain managed by Homebrew, including repair of a stale binary shadowing the formula.
  • bb account billing and bb billing portal open the Beebeeb web billing page. They no longer initiate a payment-method update or send you directly to Mollie.
  • Updates retain SHA-256 verification before replacing the executable. This release adds no new dependency or signing-key scheme.

Verification

  • Billing navigation: 6 passed; 0 failed. Deliberately restoring Mollie navigation/removing authentication made all six fail; restored tests pass with zero payment API requests.
  • Installer: 16 passed; 0 failed, against both the published cargo-dist template and a freshly generated template. Deliberate preflight/version-check mutations were rejected.
  • Focused updater run: 21 passed; 0 failed, plus 2 public command tests and 1 package-manager output test. New behavior was checked against deliberate mutations before restoring the passing implementation.
  • The release is gated by the full CLI test suite, Clippy with warnings denied, formatting, five platform builds, generated-installer fixtures, and native archive version checks. Final publication evidence is recorded with the release task.
  • Of 443 locked packages, only the first-party CLI version changed; 0 dependency versions changed.

Install / Update

curl -fsSL https://get.beebeeb.io | sh
# After installing 0.14.2:
bb update
bb --version

Homebrew users can also run brew upgrade beebeeb-io/tap/bb; Windows users can run scoop update bb; bb update delegates to Scoop for Scoop-managed installations. Unmanaged Windows binaries require reinstalling the release archive or using Scoop. Restart a running bb sync daemon after updating.

Full changelog: v0.14.1...v0.14.2

bb 0.14.1

Choose a tag to compare

@guuslangelaar0 guuslangelaar0 released this 24 Oct 13:03
0e6d273

Beebeeb CLI 0.14.1 — compatibility and packaging refresh

This patch prepares the CLI for the coordinated server 0.1.1 release. It retains the command
behavior of 0.14.0. Since that release, the only change on main updated the Windows Scoop
manifest to 0.14.0; this release adds version metadata and these authored notes.

What's New

  • A fresh release package. Existing upload, download, region and sync commands keep their
    current behavior. No new command or transfer protocol is introduced.

Bug Fixes / Hardening

  • The existing core pin (337436ae753ba99ac6c4dabd18593543367f1324) and all dependency versions
    remain unchanged. The server uses a different reviewed core revision; compatibility must be
    checked before publishing this CLI release.
  • This metadata update does not claim a new runtime or security fix.

Verification

  • The existing release-notes guard rejected the stale 0.14.0 notes for a 0.14.1 release before
    this update (exit 1); the updated notes passed (exit 0). Locked offline metadata and formatting
    checks also passed (exit 0).
  • Of 443 locked package entries, the first-party CLI package is the only changed version.
    No dependency, core pin, source module or release script changes are included.
  • Not yet verified for 0.14.1: server 0.1.1 compatibility, platform binaries, installer/updater
    behavior, the five-target release build, or the sixteen packaged assets and checksums. The
    existing release-local procedure must pass those applicable gates before publication.
  • Previous 0.14.0 test results remain evidence for that earlier source; no new full test-suite
    or performance result is claimed here.

Install / Update

0.14.1 is a release candidate until its release gates pass and the release is published.
Once published, use the existing installer or package manager:

curl -fsSL https://get.beebeeb.io | sh
brew upgrade beebeeb-io/tap/bb
scoop update bb

The Scoop manifest is updated through its normal follow-up pull request after the Windows
artifact checksum is available. Until then, Scoop can continue to offer the previous version.
Restart a running bb sync daemon after updating. Windows users update through Scoop.

Full changelog: v0.14.0...v0.14.1

0.14.0 - 2026-10-19

Choose a tag to compare

@github-actions github-actions released this 19 Oct 17:20
98b1ad3

Beebeeb CLI 0.14.0 — storage is chosen by country, and a push you interrupted can be resumed

bb region now works by country, not by city. You choose Europe (the default) or a country, and
bb no longer prints a city name anywhere, including in --json output. This release also lets you
re-run an interrupted bb push to finish it. Since v0.13.6 two pull requests landed on main:
#91 (re-running an interrupted push, task 1950) and #92 (bb region by country, task
2050). #90, the Scoop manifest bump for 0.13.6, does not touch the binary.

What's New

  • bb region list | get | set work by country. bb region list shows Europe (the default: no
    specific country, Beebeeb places your files in any of its European datacenters), Germany and
    Finland, with your current choice marked. Netherlands is listed as coming soon and cannot be chosen
    yet. bb region set takes a country code or a name, in any case: bb region set de and
    bb region set germany do the same thing, and europe returns to the default. The list comes from
    the server, so a country that goes live appears without a new bb. Your choice applies to new
    uploads only: files you already uploaded stay where they are.
  • A city is no longer a choice. If you type one, bb
    refuses it without changing your setting and tells you to choose by country, with the codes from the
    list.
  • bb billing usage groups by country. Usage that has no country is shown under Europe.
  • --json gains country and country_code. bb --json region get and set add both keys and
    keep the existing ones (preferred_region, current, label / name). bb --json billing usage
    keeps region and used_bytes, and adds country. Its city key is kept for scripts that read
    it, is deprecated, and now carries the country name.
  • Re-running an interrupted bb push resumes it. (task 1950) Before, a push stopped mid-upload
    left a half-uploaded file, and running the same command again refused with "already exists - pass
    --replace or --keep-both". Now, when that file is your own unfinished first upload (the local resume
    record and the server agree), the same command continues it. The chunks the server already holds are
    skipped, or the upload restarts from the first chunk if the chunk formats differ. A completed file is
    still a conflict, and so is an interrupted --replace: a plain push never finishes someone's replace.

Bug Fixes / Hardening

  • No city name in any output, including --json. bb account show and bb region list strip
    the server's deprecated city keys, so a server that still sends them does not leak them through bb.
    bb whoami, bb account show and bb speedtest name your choice by country (bb speedtest used
    to print a raw datacenter id), and bb billing show always reads "Europe" for the billing region. A
    test scans the production source and the README for place names, and fails if one comes back.
  • Older servers keep working. A server that still lists one row per datacenter is folded into one
    row per country, and a stored datacenter id reads as its country. Old datacenter ids typed by hand
    or kept in scripts (the short datacenter ids) are still accepted and sent as they are; the server maps them
    and bb shows the resulting country.
  • Known limit, not changed here: bb region set sends only the country, which the server reads
    as a non-strict choice. Setting a country from the CLI therefore clears a strict choice made in the
    web or mobile app. The CLI has no strict flag yet.

Verification

Code under test: 400b212 (cli main, after #92). The release commit on top of it only changes the
version to 0.14.0, Cargo.lock (that one line), this file, and the changelog.

  • cargo test --no-fail-fast on Linux (Legion), from the gate on #92: 19 test binaries, every one
    test result: ok, 0 failed. Main unit tests (bb): 511 passed, 3 ignored. region_choice: 18
    passed. no_city_copy: 3 passed. The other 16 integration binaries were unchanged and green.
  • cargo clippy --all-targets -- -D warnings and cargo fmt -- --check were clean. The GitHub CI
    Tests and Clippy & Format jobs passed on #92.
  • New tests were seen to fail first. Against the previous main, no_city_copy failed 2 of 3 (the
    README and two place names in billing.rs) and region_choice failed 11 of 18. Eleven mutations on
    the final code each turned the intended tests red, among them: no folding of per-datacenter rows,
    dropping the country-code match, switching the legacy-id passthrough off, billing reading city,
    and a city name added to the help text.
  • The #91 resume path was tested with the real bb binary killed mid-upload and re-run: 3 new
    integration tests, plus a mutation check on the download_version guard.
  • Real server, local: the lead ran this build (bb 0.14.0, built from 63345d1, scratch HOME) against a
    local server at the production server commit b6bf7fb4. bb region list showed Europe (default),
    Finland, Germany, and Netherlands "coming soon · not selectable". bb --json region list carried
    country / country_code and no city key.
  • Production, read-only: the lead ran the same build, not signed in, against production's public list.
    It gave the same four rows, and the JSON had no city or provider string.
  • Not verified: bb region set against production. It needs a signed-in account, and the lead does not
    use real accounts for checks. Also, bb.exe is cross-compiled and is not run on a Windows machine by
    this release process.

Install / Update

curl -fsSL https://get.beebeeb.io | sh           # macOS / Linux
brew upgrade beebeeb-io/tap/bb                   # macOS, Homebrew
scoop update bb                                  # Windows, Scoop

macOS and Linux installs (shell installer or Homebrew) self-update on next run via the built-in OTA
updater. The updater checks when bb starts, so a running bb sync daemon keeps the old version
until it restarts: restart it after updating. Windows installs do not self-update yet: run
scoop update bb to get 0.14.0. The Scoop manifest (scoop/bb.json) is bumped by a follow-up pull
request; until that pull request is merged, scoop update bb still installs 0.13.6.

Full changelog: v0.13.6...v0.14.0

bb 0.13.6

Choose a tag to compare

@guuslangelaar0 guuslangelaar0 released this 17 Oct 22:07
c7a9bc5

Beebeeb CLI 0.13.6 — choose where your files are stored, and a stricter download path

This release adds bb region, so you can choose where new uploads are stored: Europe (the default,
any of our European datacenters) or one specific datacenter. It also moves every download onto
beebeeb-core's chunk-format-aware reader, which checks each file's format against its encrypted
metadata before it decrypts anything, and fixes bb push --replace, which failed the second time
you replaced the same file. Since v0.13.5 three pull requests landed on main: #84
(bb region, task 1919), #87 (the new read path, task 1943) and #88 (the --replace fix, task
1951). #86, the Scoop manifest bump for 0.13.5, does not touch the binary.

What's New

  • bb region list | get | set. bb region (or bb region list) lists where new uploads can
    be stored, with your current choice marked. Today that is Europe (the default: no specific
    country, Beebeeb places the file in any of its European datacenters) or one datacenter:
    Falkenstein (Germany), Helsinki (Finland) or Nuremberg (Germany). Ede (Netherlands) is listed as
    coming soon and cannot be chosen yet. bb region set helsinki (a datacenter id or city, or
    europe) changes the choice; bb region get shows it. The list comes from the server, so a
    datacenter that goes live appears without a new bb. Your choice applies to new uploads only:
    files you already uploaded stay where they are.
  • bb whoami and bb account show name your storage choice (for example "Helsinki, Finland",
    or "Europe · default, any datacenter"). bb whoami --json has a new region_id key (null for
    the default), and region is now the name of your choice. bb account show no longer prints a
    provider name, and bb billing show no longer names one city for the billing region.

Bug Fixes / Hardening

  • A second bb push --replace of the same file no longer fails. (task 1951) In every release
    since 0.10.0 (the upload change of 2026-06-08), replacing a file that had already been replaced once failed with "stale base version
    for replacement upload": bb read the file's version from a field the server does not send, so
    it always claimed version 1. Every replace now sends the file's current version and creates the
    next one. The same fix applies to bb webdav saving over an existing file (a PUT with
    --read-write).
  • Every download now goes through core's format-aware reader. (task 1943, beebeeb-core
    337436a, task 1908) bb pull (single file, folder, --zip), bb sync, bb webdav,
    bb mount and bb repair first read the file's chunk-format pin from its encrypted, authenticated
    metadata (never from a field the server could change) and open every chunk under that pin. A file
    in the newer chunk format opens only as that format, and a truncated one is rejected. This is the
    read side of a format change that no client writes yet: uploads from 0.13.6 still use the current
    format and are readable by 0.13.5 and earlier.
  • Interrupted uploads resume only when the format allows it. A resumed upload continues only
    when both the interrupted session and this bb use the current format. Otherwise the partial
    upload is abandoned on the server and the file is uploaded again from the first chunk. A resume
    record written by 0.13.5 or earlier has no recorded format, so the first resume after updating
    starts that file again from the beginning, with the notice "the interrupted upload cannot be
    continued in this chunk format; starting it again". As before, you resume an interrupted bb push with
    bb push --replace.
  • Behaviour change: a file whose stored name is not encrypted is refused. Without encrypted
    metadata there is no format pin to check, so bb no longer guesses. bb pull of such a file fails
    with the reason; a folder pull or --zip skips it with a warning and exits 3; bb sync reports it,
    leaves the remote copy alone and exits 3, and tries again on the next pass. We know of no such
    files in real accounts (Beebeeb clients encrypt file names); if you see this error, please report
    it. Folders with plain names are not affected.

Verification

Code under test: f7cfd95 (cli main, after #88). The release commit on top of it only changes the
version to 0.13.6, Cargo.lock (that one line), this file, and the changelog.

This release is built and published from a maintainer's machine, the same way as 0.13.5, not by the
GitHub Actions release workflow. Artifacts and checksums use the same names and layout dist
produces, built with dist 0.31.0.

  • cargo test on macOS (Apple Silicon, rustc 1.96.0) on the release commit, scratch HOME:
    619 passed, 0 failed, 3 ignored across 17 test binaries: main suite (bb) 501 (3 ignored),
    account_email_change 2, auth_errors 8, ecdh_compat 4, mount_availability 3, move_parent 7,
    non_interactive 6, onboarding_state 9, pull_overwrite 5, pull_path_traversal 22,
    push_replace_versions 1, region_choice 14, share_resolves_like_pull 1, step_up_opaque 4,
    sync_never_deletes 14, webdav_auth 14, zero_byte_files 4.
  • cargo test on Linux, rustc 1.96.0, from the gated pull requests: 617 passed, 0 failed, 3 ignored
    over 16 test binaries for #87, and 619 passed, 0 failed, 3 ignored over 17 binaries for #88 (the new
    push_replace_versions binary). 0.13.5 had 573. cargo clippy --all-targets -- -D warnings and
    cargo fmt -- --check were clean on both, and the GitHub CI Tests job passed on #84, #87 and #88.
  • New tests were seen to fail first. The #87 format tests were red against the previous core, and
    each guard was mutation-checked: ignoring the metadata pin, not enforcing the newer format, skipping
    the truncation check (buffered and streaming), names not going through core, the wrong writer pin,
    resuming unconditionally, not recording the format, not skipping a pin-less file in a folder pull,
    and syncing without the pin check each turned the intended tests red. The #88 test was red on the
    previous main ("replace #2 ... stale base version") and under a mutation that reads the old field.
  • Compatibility against a real server (not mocks). The server's main ran locally with a scratch
    database and blob pool. Files uploaded with the released bb 0.13.5 (a 1 KiB file, a 20 MiB
    five-chunk file, a folder with a subfolder, a replaced file) were read back with the #87 build by
    bb pull, bb pull --zip and bb sync --once, and two 400 MiB uploads (one interrupted under
    0.13.5, one under the #87 build, both resumed by the #87 build) were read back by both builds:
    15 of 15 sha256 matches, 0 mismatches. A resume with a 0.13.5 resume record
    restarted from chunk 0 and completed; a resume with a new record continued the same session. For
    #88, a 6 MiB file pushed and then replaced three times ended at version 4 and pulled back
    byte-identical, while the previous build failed every replace against that file. bb region
    (#84) was run against a local server with the region API: Helsinki, Nuremberg and Europe uploads
    landed in the matching storage pools.
  • Not verified: none of this was run against production or a real account. Those end-to-end runs
    were made on Linux (#87, #88) and macOS (#84), not on every platform. bb webdav content reads,
    bb mount content reads, the interactive (TUI) sync watch loop and bb repair's refusal of a
    newer-format file have no dedicated tests yet. bb push does not print which datacenter a file
    landed in. Windows: the bb.exe is cross-compiled and is not executed on a Windows machine by
    this release process. The Linux binaries are cross-compiled and not executed here either. Please
    report a problem if you see one.

Install / Update

curl -fsSL https://get.beebeeb.io | sh           # macOS / Linux
brew upgrade beebeeb-io/tap/bb                   # macOS, Homebrew
scoop update bb                                  # Windows, Scoop

macOS and Linux installs (shell installer or Homebrew) self-update on next run via the built-in OTA
updater. The updater checks when bb starts, so a running bb sync daemon keeps the old version
until it restarts: restart it after updating. Windows installs do not self-update yet: run
scoop update bb to get 0.13.6. The Scoop manifest (scoop/bb.json) is bumped by a follow-up pull
request; until that pull request is merged, scoop update bb still installs 0.13.5.

Full changelog: v0.13.5...v0.13.6

bb 0.13.5

Choose a tag to compare

@guuslangelaar0 guuslangelaar0 released this 17 Oct 15:32

Beebeeb CLI 0.13.5 — bb sync no longer deletes a local file because it is missing remotely

This is a safety release for bb sync, with two fixes. In 0.13.4 and earlier, bb sync and the
background sync daemon deleted any synced local file that was missing from the remote listing, and a
download that failed to decrypt moved the remote copy to the vault Trash. A listing that came back
empty or incomplete, or a sync folder that now pointed at a different remote folder, could therefore
remove local files that nobody had deleted. 0.13.5 removes a local file only when the server reports
that exact file as trashed, and even then moves it into a recovery folder instead of deleting it. A
decrypt failure never touches the remote copy. Since v0.13.4 two pull requests landed on main:
#83 (both fixes, tasks 1915 and 1916) and #82 (the Scoop manifest bump for 0.13.4,
which does not touch the binary).

What's New

  • .bb-trash/ inside your sync folder. When bb sync removes a local file because it was deleted
    remotely, the file is moved to .bb-trash/<UTC time>/<path> inside the sync folder, not deleted.
    The folder starts with a dot, so bb sync never scans, uploads or watches it. bb does not empty it:
    look there if a file disappeared, and delete the folder yourself when you no longer need it.
  • bb sync --allow-mass-delete. If one pass would remove more than 50 files, or more than 10% of
    the files the folder tracks (whichever is larger: 51 of 501 trips it), it removes nothing and says
    so. Check the Trash in the web app first; if the deletions are intended, run
    bb sync --once --allow-mass-delete once to let them through (into .bb-trash/). The background
    daemon never gets this flag, and the continuous watch loop never removes over the limit.
  • bb sync --rebind. If the remote folder a sync folder points at changed (the old one was trashed
    and re-created, or you now sync against a different remote path), every pass keeps local removals
    paused, and a file that exists on both sides is reported as a conflict instead of replacing or
    overwriting either copy. bb sync --rebind accepts the new remote folder: it drops the old folder's
    sync record, so nothing is removed on its account, and your local files then sync in as new files.
    It cannot be combined with --daemon.
  • Exit code 3 from bb sync --once in more cases. A one-shot pass (--once, --json, --quiet)
    now exits 3 when the mass-delete limit held removals back, when a download could not be decrypted,
    and when --delete is used while the remote folder is unreconciled. Exit 3 already meant "the run
    finished but left items failed or unresolved"; scripts that treat any non-zero exit as a failure will
    now see these cases.

Bug Fixes / Hardening

  • A file missing from the remote listing is no longer deleted locally. (task 1915) A local file is
    removed only when all of these hold:
    • the server's own record for that file (GET /files/{id}) says it is trashed. A file that is gone
      without such a record (renamed or moved in the web app, permanently purged, or another account) is
      kept, and bb sync reports it on each pass;
    • the local file is still byte-identical to what was last synced, checked again right before the
      move, not only at the start of the pass;
    • the listing can be trusted: it is not empty while the folder tracks files, every remote name
      decrypted and was safe to use, it was not cut short by the 50,000-entry limit (a folder of exactly
      50,000 entries is no longer treated as cut short), and the remote folder is the one this folder last
      synced against;
    • the pass stays under the mass-delete limit above.
  • A download that fails to decrypt no longer moves the remote copy to the Trash. (task 1916) In
    0.13.4 and earlier, bb sync treated a file it could not decrypt as a corrupt remote copy and trashed
    it. Now the remote file is left untouched, no local file or sync record is written, the error names
    the file, a one-shot pass exits 3, and the next full pass tries again.
  • bb sync --delete on a changed remote folder trashes nothing. Its "synced before, missing
    locally" entries belong to the old folder, so it prints a notice naming bb sync --rebind and exits 3.
    After --rebind it behaves as before.
  • What is not changed. --delete on a folder whose remote root is unchanged still trashes remote
    files that you deleted locally, as before. --force keeps its meaning for a conflict: the local copy
    replaces the same-named remote file, and the remote copy goes to the web Trash first; on a changed
    remote folder that applies to every same-named file, so run bb sync --rebind first if that is not
    what you want. Moves and renames made in the web app are not reconciled: the old local copy stays next
    to the new download. A permanently purged file (no record on the server) is kept locally, because it
    cannot be told apart from a file in another account.

Verification

Code under test: cab3c86 (cli main, after #83). The release commit on top of it only changes the
version to 0.13.5, Cargo.lock (that one line), this file, and the changelog.

This release is built and published from a maintainer's machine, the same way as 0.13.4, not by the
GitHub Actions release workflow. Artifacts and checksums use the same names and layout dist
produces, built with dist 0.31.0.

  • cargo test on Linux, rustc 1.96.0: 573 passed, 0 failed, 2 ignored across 15 test binaries: main
    suite (bb) 472, sync_never_deletes 13, account_email_change 2, auth_errors 8, ecdh_compat 4,
    mount_availability 3, move_parent 7, non_interactive 6, onboarding_state 9, pull_overwrite
    5, pull_path_traversal 21, share_resolves_like_pull 1, step_up_opaque 4, webdav_auth 14,
    zero_byte_files 4. 0.13.4 had 532.
  • cargo clippy --all-targets -- -D warnings clean. cargo fmt -- --check clean. The GitHub CI
    Tests job passed on the merged pull request (6m02s).
  • sync_never_deletes runs the real bb binary against an in-process mock API with a scratch HOME.
    Every new behaviour test was seen to fail on the code before its fix, and each guard was
    mutation-checked: deliberately breaking it (ignoring the trashed flag, allowing an empty listing,
    turning the limit off, unlinking instead of moving, restoring the decrypt-failure trash, ignoring a
    changed remote folder, skipping the re-check before the move, and others) turned the intended tests
    red.
  • Not verified: none of this was run against production or a real account. The 50,000-entry limit is
    tested by feeding 50,001 entries through the listing code, not against a live vault. The plain watch
    loop has one end-to-end test (a changed remote folder removes nothing); the interactive (TUI) watch
    loop has none and shares the same checks. Windows: the bb.exe is cross-compiled and is not executed on a Windows
    machine by this release process. The Linux binaries are cross-compiled and not executed here either.
    Please report a problem if you see one.

Install / Update

curl -fsSL https://get.beebeeb.io | sh           # macOS / Linux
brew upgrade beebeeb-io/tap/bb                   # macOS, Homebrew
scoop update bb                                  # Windows, Scoop

macOS and Linux installs (shell installer or Homebrew) self-update on next run via the built-in OTA
updater. The updater checks when bb starts, so a background sync daemon that is already running keeps
running the old version (and the old deletion behaviour) until it is restarted: restart it after
updating. Windows installs do
not self-update yet: run scoop update bb to get 0.13.5. The Scoop manifest (scoop/bb.json) is
bumped by a follow-up pull request; until that pull request is merged, scoop update bb still installs
0.13.4.

Full changelog: v0.13.4...v0.13.5

bb 0.13.4

Choose a tag to compare

@guuslangelaar0 guuslangelaar0 released this 15 Oct 00:29

Beebeeb CLI 0.13.4 — bb account update --email no longer sends your password

This is a one-fix release. In 0.13.3 and earlier, running bb account update --email on a normal
(OPAQUE) account sent your account password to the server, in the body of a request, even though the
email change then failed. 0.13.4 never does. Changing your email from the CLI still does not work for
these accounts; you do it in the web app. Since v0.13.3 two pull requests landed on main:
#80 (the fix) and #79 (the Scoop manifest bump for 0.13.3, which does not touch the
binary).

What's New

Nothing. There are no new commands, flags or changed defaults in this release.

Bug Fixes / Hardening

  • bb account update --email no longer sends your password to the server on an OPAQUE account.
    Most accounts are OPAQUE accounts: the server is built so that it never receives the password.
    bb account update --email asked for your password and proved it over OPAQUE (that part has been
    correct since 0.13.3 and sends no password). It then always went on to call the old email-change
    endpoint, PUT /api/v1/auth/account/email, with your plaintext password in the request body. For an
    OPAQUE account that endpoint refuses the change, so you saw an error and nothing happened, but the
    server had already been sent the password. This is what 0.13.3 and earlier did: the 0.13.3 release
    notes said bb account update "still sends your password to the email-change endpoint itself", and
    that was true for every account, including OPAQUE ones. 0.13.4 stops after the OPAQUE check, which
    happens on your computer, makes no request to the old endpoint, and prints this instead:
    "Changing the email on an OPAQUE account is not yet supported from the CLI (the server does not
    expose the key material the re-registration needs). Use the web app for now. Your email was not
    changed." The command exits 1. (#80, task 1907)
    • The email change itself still has to be done in the web app. The CLI cannot do it for an OPAQUE
      account yet, as before.
    • Accounts without an OPAQUE credential behave as before. The server tells bb which kind of
      account you have while it checks your password; only an account with no OPAQUE credential still uses
      the old plaintext endpoint, because that is the only way it can change its email.
    • If you ran bb account update --email with 0.13.3 or earlier, the password you typed was sent
      to the Beebeeb server over TLS in a request body that the server rejected. This release fixes the
      client; it cannot undo a request already made. If you want to be certain, change your password in
      the web app.
    • This release is the client half. The server-side change that makes the old endpoint refuse an
      OPAQUE account before it reads a password is a separate change and is not part of this release; the
      fix here does not depend on it.

Verification

Code under test: a3bf683 (cli main, after #80) plus 92f7f05 (the Scoop manifest, no code). The
release commit on top of them only changes the version to 0.13.4, Cargo.lock (that one line), this
file, and the changelog.

This release is built and published from a maintainer's machine, the same way as 0.13.3, not by the
GitHub Actions release workflow. Artifacts and checksums use the same names and layout dist
produces, built with dist 0.31.0.

  • cargo test --locked: 532 passed, 0 failed, 2 ignored across 14 test binaries: main suite (bb)
    444, account_email_change 2, auth_errors 8, ecdh_compat 4, mount_availability 3,
    move_parent 7, non_interactive 6, onboarding_state 9, pull_overwrite 5,
    pull_path_traversal 21, share_resolves_like_pull 1, step_up_opaque 4, webdav_auth 14,
    zero_byte_files 4. 0.13.3 had 530.
  • cargo clippy --locked --all-targets -- -D warnings clean. cargo fmt -- --check clean.
  • The new account_email_change tests run the real bb binary under a pseudo-terminal against a mock
    API that records every request, with a scratch HOME. The OPAQUE test was run red against the old
    behaviour first (it saw PUT /api/v1/auth/account/email after the OPAQUE check) and the legacy test
    was mutation-checked afterwards.
  • Run end to end on macOS (arm64, 2026-10-15) against a local API built from server main
    (e9df0587) on a scratch database, with a scratch HOME, for an OPAQUE account signed in with
    bb login --headless: bb account update --email <new address> with the correct password prints the
    "Use the web app" message above and exits 1. The requests the API saw were confirm-opaque-start
    and confirm-opaque-finish, and nothing else: no PUT /api/v1/auth/account/email. The same run with
    bb 0.13.3 built from its tag showed the extra PUT /api/v1/auth/account/email (answered 400),
    so the check can tell the two apart. This was done with both a debug build of this commit and the
    release aarch64-apple-darwin archive this release ships, with the same result.
  • Not verified: the legacy path (an account with no OPAQUE credential still sends its password to
    the old endpoint, by necessity) is covered by a test and was not run against a live API. Windows:
    the bb.exe is cross-compiled and is not executed on a Windows machine by this release process. The
    Linux binaries are cross-compiled and not executed here either. This release has not been run against
    production. Please report a problem if you see one.

Install / Update

curl -fsSL https://get.beebeeb.io | sh           # macOS / Linux
brew upgrade beebeeb-io/tap/bb                   # macOS, Homebrew
scoop update bb                                  # Windows, Scoop

macOS and Linux installs (shell installer or Homebrew) self-update on next run via the built-in OTA
updater. Windows installs do not self-update yet: run scoop update bb to get 0.13.4. The Scoop
manifest (scoop/bb.json) is bumped by a follow-up pull request; until that pull request is merged,
scoop update bb still installs 0.13.3.

Full changelog: v0.13.3...v0.13.4

bb 0.13.3

Choose a tag to compare

@guuslangelaar0 guuslangelaar0 released this 14 Oct 22:48

Beebeeb CLI 0.13.3 — bb webdav now needs a password and is read-only by default

This release closes a hole in bb webdav and changes how bb proves your password for destructive
actions. Until now bb webdav served your decrypted vault on 127.0.0.1 to anything that could reach
the port: a web page in your browser (through DNS rebinding), any other account on the same machine,
with no password and with writes allowed. It now asks for a password, refuses requests that did not
come from a local program you started, and does not allow writes unless you ask for them. Separately,
bb trash empty, bb rm --permanent and bb account update no longer send your password to the
server when they ask you to confirm it. Three pull requests landed on main since v0.13.2:
#76 (bb webdav), #77 (password confirmation) and #75 (release tooling, nothing at run
time), plus the Scoop manifest bump for 0.13.2 (#74), which does not touch the binary.

This release changes what bb webdav does by default. Read "What's New" before you update if you
mount your vault through it.

What's New

  • bb webdav is read-only by default. Uploads, deletes, renames, copies and property changes
    (PUT, DELETE, MKCOL, MOVE, COPY, PROPPATCH) are refused with 403 and a message that names the
    flag. To save files through a mount, start it with bb webdav --read-write. --read-only is still
    accepted and now does nothing (it is the default); passing it together with --read-write is an
    error. (#76)
  • bb webdav prints a random password at startup. Every client must send it (HTTP Basic, any
    user name). bb webdav prints the password and a ready-to-use mount URL,
    http://bb:<password>@localhost:<port>/, once, when it starts. A new password is generated on every
    run. In Finder (Go, Connect to Server) enter http://localhost:<port> and type the password when it
    asks; in rclone or Cyberduck use the printed URL, user and password.
    • If you mount your vault unattended (a login item, a script, a service), it will stop
      connecting after you update: the password changes on every start and is only printed on the
      terminal. There is no way to set a fixed password in this release.
  • Windows Explorer is not supported by bb webdav. Explorer ("Map network drive") refuses a
    password over plain HTTP by default, and bb webdav serves plain HTTP on loopback only. On Windows,
    use the Beebeeb desktop app, or connect with rclone, Cyberduck or WinSCP. bb webdav --help, the
    README, and a one-line hint that bb webdav prints when it starts on Windows now say the same.
    Windows Explorer is not something we tested; this is what we know from how it handles Basic
    authentication, not from a run on a Windows machine.

Bug Fixes / Hardening

  • bb webdav refuses requests that are not from a local program. A request whose Host is not
    127.0.0.1:<port> or localhost:<port> (DNS rebinding) and any request carrying an Origin header
    (what a browser sends from a web page) get 403, and a missing or wrong password gets 401. The
    gateway listens on 127.0.0.1 only, and refuses to start with a clear message when the port is
    already taken. Before this release, anything that could reach the port could list, read, overwrite
    and delete the decrypted vault. Another account on the same machine is stopped by the password, not
    by the Host check. (#76)
  • Step-up confirmation no longer sends your password. bb trash empty, bb rm --permanent and
    bb account update ask for your password again before a destructive action. bb now proves it
    over OPAQUE (POST /auth/confirm-opaque-start, then /auth/confirm-opaque-finish), the same way
    the web app does, so the server never receives the password for this step. Only an account that has
    no OPAQUE credential still uses the old plaintext confirm; the server tells bb which one applies.
    The password you type, and the OPAQUE state derived from it, are wiped from memory after use.
    (#77)
    • bb account update still sends your password to the email-change endpoint itself. That is
      unchanged by this release.
  • The step-up error says what actually happened. A wrong password prints incorrect password.
    If the server answers 401 to the confirm request, your session has ended, and bb now prints
    "Your session expired or was revoked. Run bb login to sign in again." instead of blaming your
    password. (#77)
  • Release tooling (#75, nothing at run time). The local release procedure is a script with
    checksum and self-update assertions (scripts/release-local.sh, scripts/ota-rung.sh), and the
    release workflow now skips a tag whose release already exists.

Verification

Code under test: 3853ee3 (cli main, after #77). The release commit on top of it only changes the
version to 0.13.3, Cargo.lock (that one line), this file, and the changelog.

This release is built and published from a maintainer's machine, the same way as 0.13.2, not by the
GitHub Actions release workflow. Artifacts and checksums use the same names and layout dist
produces, built with dist 0.31.0.

  • cargo test --locked: 530 passed, 0 failed, 2 ignored across 13 test binaries: main suite (bb)
    444, auth_errors 8, ecdh_compat 4, mount_availability 3, move_parent 7, non_interactive
    6, onboarding_state 9, pull_overwrite 5, pull_path_traversal 21, share_resolves_like_pull
    1, step_up_opaque 4, webdav_auth 14, zero_byte_files 4. 0.13.2 had 492.
  • cargo clippy --locked --all-targets -- -D warnings clean. cargo fmt -- --check clean.
  • The new webdav_auth and step_up_opaque tests run the real bb binary. Each was run red against
    the old behaviour first (the webdav tests against the unguarded gateway, the step-up tests against
    the plaintext confirm), and the code was mutated afterwards to make sure the tests fail for the
    right reason.
  • Run end to end on macOS (arm64, 2026-10-15) against a local API built from server main
    (e9df0587) on a scratch database, with a scratch HOME: bb login --headless approved through the
    device-approval flow, two files uploaded into a folder, then bb webdav mounted with rclone and
    checked with curl.
    • Read-only (default): rclone lsf lists the folder, rclone cat returns the decrypted text; a
      copyto is refused with 403 Forbidden and the message that names --read-write; a PUT and a
      DELETE with the right password are 403; no password and a wrong password are 401; a foreign
      Host and an Origin header are 403; a PROPFIND with the password is 207. The vault was
      unchanged afterwards.
    • With --read-write: the same copyto succeeds, a PUT is 201, a DELETE is 204, and the file
      written through the gateway decrypts with bb pull and with rclone cat.
    • Step-up (bb trash empty on a real terminal): a wrong password prints incorrect password and
      empties nothing; the right password empties the trash; the requests the API saw were
      confirm-opaque-start, confirm-opaque-finish, then the delete, and /auth/confirm was never
      called. With the session ended on the server after the prompt, bb printed the "run bb login"
      line, not "incorrect password".
  • Not verified: Finder was not run against bb webdav in this release (rclone and curl were).
    Windows: the bb.exe is cross-compiled and is not executed on a Windows machine by this release
    process. The Linux binaries are cross-compiled and not executed here either, and bb webdav was not
    run on Linux or Windows. The plaintext fallback of the step-up confirm (an account with no OPAQUE
    credential) is covered by tests and was not run against a live API, and neither was bb account update. This release has not been run against production. Please report a problem if you see one.

Install / Update

curl -fsSL https://get.beebeeb.io | sh           # macOS / Linux
brew upgrade beebeeb-io/tap/bb                   # macOS, Homebrew
scoop update bb                                  # Windows, Scoop

macOS and Linux installs (shell installer or Homebrew) self-update on next run via the built-in OTA
updater, so bb webdav will behave as described above the next time you start it after that. Windows
installs do not self-update yet: run scoop update bb to get 0.13.3. The Scoop manifest
(scoop/bb.json) is bumped by a follow-up pull request; until that pull request is merged,
scoop update bb still installs 0.13.2.

If you mount your vault through bb webdav and save files to it, restart it with bb webdav --read-write and enter the printed password when your client asks.

Full changelog: v0.13.2...v0.13.3

0.13.2 - 2026-10-09

Choose a tag to compare

@guuslangelaar0 guuslangelaar0 released this 09 Oct 20:01
7ad2258

Beebeeb CLI 0.13.2 — bb sync stops when the server has ended your session

A patch release that fixes one problem: a background bb sync service whose session the server
no longer accepts used to be restarted by launchd or systemd every 10 to 20 seconds, forever,
each time asking the server to register the device and being refused. On production this showed
up as bb 0.13.0 clients sending the same refused request around six times a minute. bb sync
now stops, says why in one line, and the service managers are told not to bring it back. Three
pull requests landed on main since v0.13.1: #71 (the fix), #73 (follow-up
hardening of the fix) and #70 (vendored contract data, nothing at run time), plus the Scoop
manifest bump for 0.13.1 (#69), which does not touch the binary. This is a patch release: no new commands, flags or JSON keys.

What's New

  • Nothing new to use. The one behaviour change is below, under Bug Fixes.

Bug Fixes / Hardening

  • bb sync stops, once, when the server has ended the session. If the server answers the
    device registration at startup with 401 (session revoked, expired or signed out elsewhere),
    bb sync now prints one line and exits with code 77 (EX_NOPERM) instead of carrying on and
    being restarted. Run directly in a terminal the line is "Your session has ended. Run bb login
    to sign in again." When bb sync runs as a background service it reads "Your session has ended.
    Run bb login, then bb sync --daemon to restart background sync." (#71) The line is written and flushed before the launchd service removes
    itself, so it reaches the service's log file (#73).
  • Background sync services no longer restart blindly. bb sync --daemon now writes:
    • macOS (launchd): KeepAlive restarts the job only after a failed exit (SuccessfulExit =
      false, it was unconditional before), ThrottleInterval 30 seconds, and a
      BEEBEEB_SYNC_SERVICE=1 marker in the job's environment. launchd cannot decline to restart on
      one specific exit code, so when a launchd-managed bb sync exits with 77 it runs
      launchctl remove on its own job. That call is bounded to 5 seconds; a launchctl that does
      not return in time is killed and reaped, so it cannot leave a helper process behind
      (#73).
    • Linux (systemd user unit): RestartPreventExitStatus=77, RestartSec=30 (it was 10) and the
      same marker. Restart=on-failure is unchanged.
  • Existing sync services are updated in place. bb sync and bb login rewrite background
    sync services that an earlier bb installed (~/Library/LaunchAgents/io.beebeeb.sync.*.plist,
    ~/.config/systemd/user/beebeeb-sync-*.service) to the same policy. Only the restart policy and the BEEBEEB_SYNC_SERVICE marker change: the
    arguments, paths, log files, and the service's other environment variables (for example
    BB_NO_UPDATE) and settings are kept. The rewritten file keeps its trailing newline. bb prints "Updated the background sync service to stop restarting after
    sign-out." Only files with Beebeeb's own name and label are touched, and a file already in the
    new form is left alone. On Linux bb also runs systemctl --user daemon-reload; on macOS it
    does not reload the job into launchd. An existing restart loop ends after you upgrade: the next
    restart runs the new bb, which gets the same 401, exits with 77 and removes its own launchd
    job, so you only need to run bb login and bb sync --daemon again.
  • Not covered yet. A 401 that first appears while bb sync is already running (the session
    ends mid-watch) is not turned into exit 77 by this release; only the refusal at startup is.
  • Vendored onboarding contract update (#70): the iOS and desktop pre_account fixtures now say
    signup is web-only. This is test data copied from the server; bb reads the server's live
    answer, so nothing changes at run time.

Verification

Code under test: 774667e (cli main, after #73). The release commits on top of it only change
the version to 0.13.2, Cargo.lock (that one line), this file, and the changelog.

This release is built and published from a maintainer's machine, the same way as 0.13.1, not by
the GitHub Actions release workflow. Artifacts and checksums use the same names and layout
dist produces, built with dist 0.31.0.

  • cargo test --locked: 492 passed, 0 failed, 2 ignored across 11 test binaries: main suite
    (bb) 424, auth_errors 8, ecdh_compat 4, mount_availability 3, move_parent 7,
    non_interactive 6, onboarding_state 9, pull_overwrite 5, pull_path_traversal 21,
    share_resolves_like_pull 1, zero_byte_files 4. 0.13.1 had 474.
  • cargo clippy --locked --all-targets -- -D warnings clean. cargo fmt -- --check clean.
  • The restart policy and the in-place migration are covered by unit tests on the generated launchd
    plist and systemd unit and on the rewrite of old ones. The 401-at-startup exit code is covered
    in tests/auth_errors.rs.
  • Verified on a real launchd (macOS, 2026-10-09): a job with the old KeepAlive policy whose
    session the server refused made exactly one request, wrote the session-ended message to its log,
    removed itself with launchctl remove and was not restarted.
  • Not verified: systemd was checked by unit tests on the generated unit and on the rewrite of old
    ones, and by Linux CI only; no live systemd was run. The Windows bb.exe is cross-compiled and
    is not executed on a Windows machine by this release process. This release has not been run
    against production. Please report a problem if you see one.

Install / Update

curl -fsSL https://get.beebeeb.io | sh           # macOS / Linux
brew upgrade beebeeb-io/tap/bb                   # macOS, Homebrew
scoop update bb                                  # Windows, Scoop

macOS and Linux installs (shell installer or Homebrew) self-update on next run via the built-in
OTA updater. Windows installs do not self-update yet: run scoop update bb to get 0.13.2. The
Scoop manifest (scoop/bb.json) is bumped by a follow-up pull request; until that pull request is
merged, scoop update bb still installs 0.13.1.

If bb sync was running as a background service and its session has ended, run bb login, then
bb sync --daemon once after updating.

Full changelog: v0.13.1...v0.13.2