Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
41 changes: 39 additions & 2 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -45,9 +45,43 @@ jobs:
name: binaries-${{ matrix.target }}
path: ${{ env.ASSET }}

build-ui-macos:
name: build menu bar app (macos)
runs-on: macos-latest
steps:
- uses: actions/checkout@v7
- uses: dtolnay/rust-toolchain@stable
- uses: Swatinem/rust-cache@v2
with:
workspaces: "apps/microbridge-ui/src-tauri -> target"
- uses: actions/setup-node@v7
with:
node-version: "22"
cache: npm
cache-dependency-path: apps/microbridge-ui/package-lock.json
- name: Build Microbridge.app
working-directory: apps/microbridge-ui
run: |
npm ci
npm run tauri build -- --bundles app
- name: Package .app
run: |
APP="$(find apps/microbridge-ui/src-tauri/target/release/bundle/macos -name 'Microbridge.app' -type d | head -n1)"
test -n "$APP"
STAGE="microbridge-ui-${GITHUB_REF_NAME}-macos"
mkdir -p "staging/${STAGE}"
cp -R "$APP" "staging/${STAGE}/"
cp README.md LICENSE-MIT LICENSE-APACHE INSTALL.md "staging/${STAGE}/"
tar -C staging -czf "${STAGE}.tar.gz" "${STAGE}"
echo "ASSET=${STAGE}.tar.gz" >> "$GITHUB_ENV"
- uses: actions/upload-artifact@v7
with:
name: ui-macos
path: ${{ env.ASSET }}

publish:
name: publish release
needs: build
needs: [build, build-ui-macos]
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v7
Expand All @@ -66,15 +100,18 @@ jobs:
body: |
## Install (macOS)

Menu bar app + daemon (not CLI-only):

```sh
brew tap DevVig/microbridge https://github.com/DevVig/microbridge
brew install microbridge
brew services start microbridge
open ~/Applications/Microbridge.app
```

Upgrade later: `brew update && brew upgrade microbridge`

Binary archive: `./scripts/install-from-release.sh ${{ github.ref_name }}`
Binary + app archive: `./scripts/install-from-release.sh ${{ github.ref_name }}`

Full guide: [INSTALL.md](INSTALL.md).

Expand Down
174 changes: 174 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

51 changes: 43 additions & 8 deletions Formula/microbridge.rb
Original file line number Diff line number Diff line change
@@ -1,33 +1,60 @@
# typed: false
# frozen_string_literal: true

# Homebrew formula for Microbridge (source build — fast enough for alpha).
# Homebrew formula for Microbridge — menu bar app + daemon (not CLI-only).
#
# brew tap DevVig/microbridge https://github.com/DevVig/microbridge
# brew install microbridge
# brew services start microbridge
# open ~/Applications/Microbridge.app
#
# Upgrade (auto-update path):
# Upgrade:
# brew update && brew upgrade microbridge
# brew autoupdate start --upgrade --cleanup # optional background updates
#
class Microbridge < Formula
desc "Open-source control plane for the Codex Micro"
desc "Open-source control plane for the Codex Micro (menu bar + daemon)"
homepage "https://github.com/DevVig/microbridge"
url "https://github.com/DevVig/microbridge/archive/refs/tags/v0.0.1.tar.gz"
sha256 "f171c275890add016045b0bbde54330f104b6d5db3a9d16c8d366cd5fcdde599"
license any_of: ["MIT", "Apache-2.0"]
head "https://github.com/DevVig/microbridge.git", branch: "main"

depends_on "rust" => :build
depends_on "node" => :build
depends_on :macos

def install
system "cargo", "build", "--release", "--locked", "-p", "microbridged", "-p", "microbridgectl"
bin.install "target/release/microbridged"
bin.install "target/release/microbridgectl"

cd "apps/microbridge-ui" do
system "npm", "ci"
system "npm", "run", "tauri", "build", "--", "--bundles", "app"
end

app = Dir["apps/microbridge-ui/src-tauri/target/release/bundle/macos/*.app"].first
odie "Microbridge.app missing after Tauri build" if app.nil?
prefix.install app

doc.install "INSTALL.md" if File.exist?("INSTALL.md")
end

def post_install
apps = Pathname.new(Dir.home)/"Applications"
apps.mkpath
dest = apps/"Microbridge.app"
# Only replace if missing or previously installed by this formula.
marker = dest/".microbridge-brew"
if dest.exist? && !marker.exist?
ohai "Leaving existing ~/Applications/Microbridge.app in place (not brew-managed)"
return
end
rm_r dest if dest.exist?
cp_r prefix/"Microbridge.app", dest
marker.write "owned-by-homebrew\n"
end

service do
run [opt_bin/"microbridged"]
keep_alive true
Expand All @@ -38,14 +65,22 @@ def install

def caveats
<<~EOS
Config and socket: ~/.microbridge/
Status: microbridgectl status
Upgrade: brew update && brew upgrade microbridge
Background updates: brew autoupdate start --upgrade --cleanup
Microbridge is the menu bar app + a local daemon (not CLI-only).

App: ~/Applications/Microbridge.app
Daemon: brew services start microbridge
Status: microbridgectl status
Config: ~/.microbridge/

Open the app once (or add Login Items) so the menu bar icon appears:
open ~/Applications/Microbridge.app

Upgrade: brew update && brew upgrade microbridge
EOS
end

test do
assert_match "Usage", shell_output("#{bin}/microbridgectl help")
assert_predicate prefix/"Microbridge.app", :exist?
end
end
13 changes: 8 additions & 5 deletions INSTALL.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,15 @@ runs on your machine.

## Recommended on macOS: Homebrew (with updates)

This is the easy path. You do **not** need to clone the repo. Homebrew owns
install, upgrades, and the launchd service.
This is the easy path. You do **not** need to clone the repo. Homebrew installs
the **menu bar app** (primary UI) and the daemon, then owns upgrades and the
daemon service. This is not a CLI-only product.

```sh
brew tap DevVig/microbridge https://github.com/DevVig/microbridge
brew install microbridge
brew services start microbridge
open ~/Applications/Microbridge.app
microbridgectl status
```

Expand Down Expand Up @@ -50,8 +52,8 @@ Governance / why this path: [docs/governance.md](docs/governance.md).

| Piece | Need |
|---|---|
| Daemon (Homebrew) | Homebrew; Rust pulled in as a build dependency |
| Full install (from source) | Rust stable, Node ≥ 20; macOS also needs Xcode CLT for the `.app` |
| macOS (Homebrew) | Homebrew + **Xcode Command Line Tools** (`xcode-select --install`); Rust + Node pulled in as **build** deps (builds `.app` + daemon) |
| From source | Rust stable, Node ≥ 20; macOS also needs Xcode CLT for the `.app` |
| Hardware LEDs | Codex Micro over USB (HID packing still landing — mock works without hardware) |

## From source (developers)
Expand Down Expand Up @@ -91,8 +93,9 @@ When a `v*` tag is published, CI attaches platform archives:

| Path | Purpose |
|---|---|
| `~/Applications/Microbridge.app` | Menu bar app (primary UI) |
| `$(brew --prefix)/bin/microbridged` | Daemon (Homebrew) |
| `~/.local/bin/microbridged` | Daemon (source install script) |
| `~/.local/bin/microbridged` | Daemon (source / release install) |
| `~/.microbridge/microbridged.sock` | Local NDJSON socket |
| `~/.microbridge/config.toml` | Key source, lighting, appearance |
| `~/.microbridge/daemon.log` | launchd / service logs |
Expand Down
Loading
Loading