Skip to content

BenchBar 0.5.0

Choose a tag to compare

@github-actions github-actions released this 26 Sep 07:34
· 41 commits to main since this release
a9f672d

BenchBar grows from a start and stop button into the place you run your
benches from: a window with every bench's sites, apps and health, Repair
from the app, a log window, apps from any GitHub repository (private
ones too), team profiles and a lockfile for the whole team, benchbar pull for a production copy, and benchbar mcp for coding agents. A new
app icon, and the window uses the macOS 27 tab style and Liquid Glass
buttons (older macOS versions get the classic look).

Added: the app

  • The BenchBar window replaces the sparse Settings window: General,
    Menu Bar, Team Profiles and About, then a page per bench with Overview
    (actions, ports, the scheduler), Sites (add a site with its
    Administrator password, make one the default, the hosts fix), Apps (add
    from the registry or any GitHub URL, public or private, install on a
    site, update after a changelog preview) and Health (doctor, and Repair
    with the plan first and a live step list). The popover links into it
    (⌘M) and offers Repair when doctor found something repairable.

  • A new app icon: the menu bar runner, a park bench on the run, drawn
    for Icon Composer (macos/BenchBar/Resources/AppIcon.icon,
    scripts/app-icon.py).

  • A log window per bench (⌘L): follows logs/bench.log with smart
    scroll, search with a match count and next and previous (⌘G, ⇧⌘G), a
    filter per honcho process, errors and tracebacks in red, the previous
    log, clear, select and copy, and Open in Terminal. It survives the
    runner's log rotation and keeps at most 5000 lines.

Added: the command line

  • benchbar mcp: a Model Context Protocol server on stdio (stdlib only
    Python) with benchbar_list, benchbar_status, benchbar_doctor,
    benchbar_logs_tail, benchbar_site_list, benchbar_up,
    benchbar_down and benchbar_restart, each backed by the CLI's JSON.

  • benchbar logs --json with -nN and --process NAME.

  • benchbar repair --json streams a plan, a step event per action and a
    done event with the exit code; --dry-run --json prints only the plan.

  • App commands. benchbar app list [--json] [--no-sites] shows every
    app with its branch, commit, local changes, shallow clone, version,
    the apps.tsv branch and the sites that have it (read with
    bench list-apps, cached per bench). app add NAME|URL gets an app
    from config/apps.tsv or any git URL (GitHub over HTTPS, SSH, or an
    SSH host alias from ~/.ssh/config), with --branch, --name, and
    --site S or --all-sites: it checks access first with a git that
    never prompts, so a missing key or token fails in a second with a fix
    line, clones with bench get-app --skip-assets (never --overwrite
    or --resolve-deps), clones the required_apps of hooks.py after
    a second plan, installs on the sites, builds once and restarts a
    running bench. A half finished clone moves to the backups. app install NAME --site S installs an app the bench has. app update NAME fetches, shows the changelog, backs up every site that has the
    app, fast forwards, runs requirements, migrate and build; it refuses
    a dirty tree, a detached HEAD or a diverged branch, and on a failure
    prints (never runs) the way back. app update --dry-run --json is the
    plan for the app.

  • Doctor checks apps_txt (an apps.txt line without its folder
    fails, a git app missing from apps.txt warns) and
    app_branch_policy (an app off its apps.tsv branch warns). Both
    read only local files and git; repair has no action for them.

  • Team profiles: an organisation's bench recipe in a TOML file outside
    BenchBar, in ~/.config/benchbar/profiles/NAME.toml or a folder on
    BENCHBAR_PROFILE_PATH (a clone of the team's config repo). It names
    a built in base for Python, Node and MariaDB, an optional
    frappe_branch, a bundle or [[apps]] with repo, branch and an
    optional commit, and optional site and scheduler. benchbar install --profile NAME uses it, and the bench keeps following it.
    benchbar profile list [--json], profile show NAME and profile create NAME --from-bench PATH [--dir DIR] (reads a bench, never
    writes a credential or a commit). A team profile may not shadow a
    built in one.

  • The team lockfile benchbar.toml: every app's repo, branch and
    commit in apps.txt order, and each site with its apps, in the same
    strict TOML subset. benchbar lock write writes it from the bench
    (refuses local changes or a detached HEAD unless --allow-dirty,
    --no-commits for branches only, shows the diff, backs up the old
    file), lock check [--json] reports drift (13 kinds, from a missing
    app to a site without an app) with no network or database, and lock apply clones missing apps, switches clean apps to the locked branch
    and fast forwards to pinned commits, then runs requirements and
    build. It never touches a site, never resets local work (ahead,
    diverged and dirty apps are skipped), and prints the site steps to run
    by hand. --lock PATH (remembered per bench) or BENCHBAR_LOCK
    points at a file kept in the team's app. Doctor gains lock_parse
    and lock_drift; list --json gains benches[].lock_file.

  • Access checks before cloning (phase 01 and app add) run git with
    GIT_TERMINAL_PROMPT=0 and SSH in batch mode, so a private repo fails
    at once instead of waiting on a prompt.

Added: pull

  • benchbar pull HOST:SITE --as NAME copies a production site over SSH
    into a new local site. It uses the latest backup that already exists on
    the server, so a plain pull writes nothing there; --new-backup runs
    bench backup first, after the production site name is typed (or
    given with --confirm-site), because that also deletes older backups
    on the server. The download resumes (rsync --partial, scp when the
    server has no rsync) into <bench>/.benchbar/pulls/, mode 0700.
  • The copy keeps its stored passwords: the production encryption_key is
    written into the new site config through stdin and never shown or
    logged, and a probe counts the encrypted rows that decrypt. Encrypted
    backups are decrypted locally with gpg --passphrase-fd 0.
  • Before the restore, pull compares the production apps with the bench
    and stops with the bench get-app commands when one is missing
    (--skip-app APP restores without it and says what that leaves
    behind), and stops when production frappe is newer than the bench.
  • After the restore: mute_emails, pause_scheduler and
    disable-scheduler (unless --keep-scheduler), host_name, the
    removal of skipped apps, bench migrate when the apps differ,
    clear-cache, an optional Administrator password (ADMIN_PASSWORD or
    a prompt, on stdin), the hosts line, and a verify pass.
  • --replace restores over an existing local site after a
    bench backup --with-files of it; --from-dir DIR restores a backup
    set downloaded by hand (Frappe Cloud); --dry-run connects read only
    and prints the plan; --json streams plan, gate, progress,
    step and done events (docs/json-schema.md).

Changed

  • The window's settings panes are laid out like System Settings: a
    header per pane, Startup, Notifications, Command line tool and
    Keyboard shortcuts on General, a runner preview on Menu Bar. The
    sidebar's benches have a context menu (start, stop, restart, open,
    show, copy path).
  • app add URL for an app in config/apps.tsv follows its branch there
    when the repository has it, instead of the repository's default
    branch, so doctor does not warn about an app it just added. Raven's
    registry entry points at github.com/frappe/raven.
  • bench new-site gets the MariaDB root and Administrator passwords on
    stdin, never in its arguments.
  • CI runs the CLI tests in three parallel macOS shards (about 4 minutes
    per pull request, from about 13); the Linux job is gone.

Fixed

  • app update refuses to run when a site's app list cannot be read, so
    it never skips a site's backup or migrate.
  • pull into a running bench pauses the bench's scheduler until the
    copy has its own pause_scheduler and mute_emails.
  • A git repository or branch from a team profile or lockfile can no
    longer be read as a git option (-- everywhere, values starting with
    - refused).
  • The window no longer jumps wider when you open General, and a
    change's result shows only on the page it belongs to.

This build is not signed with an Apple Developer ID (ad hoc signature). macOS shows "Apple could not verify" on first open of the DMG: use System Settings > Privacy & Security > Open Anyway, or install with the one liner, which downloads with curl and opens without that prompt:

curl -fsSL https://raw.githubusercontent.com/askysh/benchbar/main/install.sh | bash

Checksums are in SHA256SUMS.


The app in this release was built on a Mac with Xcode 27 (the macOS 27 tab style needs its SDK; the CI runners have Xcode 26.6) and is ad hoc signed like earlier releases. SHA256SUMS covers both files.