个人 GitHub 账号下公开仓库的所有者可以登录并验证所有权,自行管理介绍,无需管理员批准。
登录并生成验证文件,在 30 分钟内将其提交到此仓库的默认分支。其他分支或分叉仓库中的文件无效。然后在下方检查文件,即可无需管理员批准直接管理项目。请保留文件以维持管理权限。
如需登录,将前往登录页面。登录后请回到此处,再次点击所选的验证按钮。
在项目文件夹中运行 /nomorevibe verify,即可验证所有权并自行管理介绍。
一分钟完成验证Direct Android to Mac link: notifications, clipboard, files over BLE + Wi-Fi. No cloud, no account.
翻译准备中
取自仓库 README
正在加载完整 README。
查看完整 README ↗Website: https://bridge-mac-android.vercel.app
Bridge makes any Mac and any Android phone behave as one machine when they are in the same room. No network, no account, no cloud: BLE for control, Wi-Fi for bulk, speaking the KDE Connect wire format. It mirrors notifications, syncs the clipboard, shares the battery level, and transfers files over a mutually-authenticated (pinned-cert) link.
Installing the app on both devices is the only setup step — the two find each other over Bluetooth LE and pair. Nothing device-specific is baked into either build.
brew install --cask deepakk33/tap/bridge-link # Mac
# Android: sideload the APK from the latest release
connectedDevice foreground service, NotificationListenerServicebridge.* packet types. Mutual TLS with pinned
certificates on the out-of-band payload connection; the BLE L2CAP control channel is
currently unencrypted| Feature | Direction | Packets |
|---|---|---|
| Notification mirroring, with inline reply from the Mac | phone → Mac (reply Mac → phone) | bridge.notification, .notification.reply, .notification.request |
| Clipboard sync — manual on Android 16, see limitation | both | bridge.clipboard, .clipboard.connect |
| Battery level in the menu bar | phone → Mac | bridge.battery |
| File transfer from the share sheet | both | bridge.share.request |
| Pairing, identity, link liveness | both | bridge.identity, .pair, .ping |
Control packets ride a BLE L2CAP channel (always on, ~1 m range). File bodies take a tier: under 500 KB over Bluetooth RFCOMM, at or above over Wi-Fi LAN (mDNS + TCP) when both devices share a network — otherwise it falls back to RFCOMM and says so. Both ends pin each other's certificate; everything is mutually authenticated TLS.
Full requirements and decisions: docs/PRD.md. What each iteration built: docs/ITERATIONS.md. Specs and change history: openspec/.
mac/ Xcode project (Swift) — Bridge.xcodeproj, generated from project.yml
android/ Gradle project (Kotlin) — android/Bridge
protocol/ Shared test vectors + BLE UUIDs (constants.json)
docs/ PRD, BACKLOG, DEVELOPMENT, ITERATIONS, spike notes
openspec/ Specs + archived changes (one per iteration)
scripts/ Build / install / release / cert helpers
packaging/ Homebrew cask (bridge-link.rb)
web/ Landing page (static)
dist/ Built release artifacts (.zip + .apk)
project.yml).adb on PATH.scripts/create-signing-cert.sh
open mac/Bridge/Bridge.xcodeproj # then select the "Bridge" scheme → Run
(If Bridge.xcodeproj is missing or stale: cd mac/Bridge && xcodegen generate.)The app lives in the menu bar, not the Dock.
Quit from the menu-bar panel, then relaunch the built app:
open ~/Library/Developer/Xcode/DerivedData/Bridge-*/Build/Products/Debug/Bridge.app
This is a local Xcode dev build (not a distributed .app). In Xcode: Product → Clean
Build Folder, then Run. A full reset of pairing state:
defaults delete com.bridge.mac trustedDevices (key
com.bridge.mac.trustedDevices in UserDefaults).create-signing-cert.sh.Grant when prompted, or in System Settings:
scripts/adb-install.sh # gradle assembleDebug → adb install -r → launch
# or:
cd android/Bridge && ./gradlew assembleDebug
adb install -r app/build/outputs/apk/debug/app-debug.apk
On first launch, grant when prompted and enable the manual ones:
Pairing is Mac-initiated and auto-accepted — there are no device IDs to configure.
Automatic background clipboard sync is not possible on Android 16 / One UI 8.5
without rooting the phone. The OS made READ_CLIPBOARD_IN_BACKGROUND role-managed, so it
cannot be granted to a sideloaded app — pm grant refuses it with a SecurityException, and
the READ_CLIPBOARD app op is no substitute because every app already has it. Shizuku can't
either; only root. There is no setup step, no script and no adb command: this is the state a
fresh install is in and stays in. Clipboard therefore works manually:
Opening the Android app runs a quick handshake (ping + 3 s timeout): if the Mac is gone it drops the stale "Connected", re-advertises, and reconnects. The foreground service is set to survive being swiped from recents.
Work is queued in docs/BACKLOG.md — one row plus one detail block per
item — and driven end to end by the /work BR-n command in Claude Code: clarify → branch
→ OpenSpec proposal → implement test-first → review → archive → push. Three human gates
and nothing else interrupts: plan (the spec artifacts), review (the diff plus a
real-hardware test), hand-off (push). Phase is re-derived from disk every run, so a
half-finished item survives a closed terminal.
Full rules: docs/DEVELOPMENT.md. Shipped history: docs/ITERATIONS.md and openspec/changes/archive/. Requirements and architecture decisions: docs/PRD.md.
House rules: never commit to main (branch work/<id>-<slug>); Swift 6 strict
concurrency with no force unwraps; Kotlin coroutines and sealed classes, no !!; a
protocol change lands a vector in protocol/test-vectors/ and is
checked on both sides.
xcodebuild -project mac/Bridge/Bridge.xcodeproj -scheme Bridge test
(cd android/Bridge && ./gradlew test assembleDebug)
openspec validate --change <change-name>
scripts/build-release.sh 0.1.2 # → dist/Bridge-0.1.2.zip + dist/bridge-0.1.2.apk, prints the sha256
The Mac app is ad-hoc signed; the APK needs ~/.bridge/keystore.properties (the script
refuses to produce a debug-signed APK). Paste the printed sha256 into
packaging/homebrew/bridge-link.rb, bump the version
there and in android/Bridge/app/build.gradle.kts, then attach both artifacts to a
GitHub release. The cask is served from deepakk33/tap.
Issues and pull requests are welcome. Read docs/DEVELOPMENT.md first — a change starts as a backlog item and an OpenSpec change, not as a diff. The website source is in web/.
MIT © deepakk33