feat(mac): gate Peekaboo Bridge on Computer Control (#106531)

Both settings grant local UI automation, so run PeekabooBridge only while
Allow Computer Control is on. The toggle now reflects the effective state and
is disabled when Computer Control is off; users drive Peekaboo via its own Mac
app in that case. Removes the confusing standalone bridge switch.
This commit is contained in:
Peter Steinberger
2026-07-13 08:56:27 -07:00
committed by GitHub
parent 2d5803a250
commit 0fe2132d5f
4 changed files with 34 additions and 6 deletions
+13 -1
View File
@@ -264,8 +264,20 @@ final class AppState {
didSet {
self.ifNotPreview {
UserDefaults.standard.set(self.peekabooBridgeEnabled, forKey: peekabooBridgeEnabledKey)
Task { await PeekabooBridgeHostCoordinator.shared.setEnabled(self.peekabooBridgeEnabled) }
}
self.applyPeekabooBridgeHostState()
}
}
/// PeekabooBridge shares Computer Control's local UI-automation surface, so the host only
/// runs while Computer Control is enabled. With Computer Control off, users drive Peekaboo
/// via its own Mac app instead of a second, separately toggled bridge here.
func applyPeekabooBridgeHostState() {
self.ifNotPreview {
let computerControlEnabled = UserDefaults.standard
.object(forKey: computerControlEnabledKey) as? Bool ?? false
let shouldRun = self.peekabooBridgeEnabled && computerControlEnabled
Task { await PeekabooBridgeHostCoordinator.shared.setEnabled(shouldRun) }
}
}
@@ -59,6 +59,10 @@ struct GeneralSettings: View {
CanvasManager.shared.hideAll()
}
}
.onChange(of: self.computerControlEnabled) { _, _ in
// Turning Computer Control on/off must start or stop the gated PeekabooBridge host.
self.state.applyPeekabooBridgeHostState()
}
.onDisappear { self.gatewayDiscovery.stop() }
}
@@ -114,9 +118,13 @@ struct GeneralSettings: View {
SettingsCardToggleRow(
title: "Enable Peekaboo Bridge",
subtitle: "Allow signed tools (e.g. `peekaboo`) to drive UI automation via PeekabooBridge.",
binding: self.$state.peekabooBridgeEnabled,
subtitle: """
Allow signed tools (e.g. `peekaboo`) to drive UI automation via PeekabooBridge. \
Requires Computer Control; otherwise run Peekaboo's own Mac app.
""",
binding: self.peekabooBridgeBinding,
showsDivider: false)
.disabled(!self.computerControlEnabled)
}
SettingsCardGroup("Browser") {
@@ -247,6 +255,14 @@ struct GeneralSettings: View {
set: { self.state.isPaused = !$0 })
}
// Reflect the effective bridge state: off (and disabled) whenever Computer Control is off,
// so the row matches the host that actually runs instead of a standalone toggle.
private var peekabooBridgeBinding: Binding<Bool> {
Binding(
get: { self.computerControlEnabled && self.state.peekabooBridgeEnabled },
set: { self.state.peekabooBridgeEnabled = $0 })
}
private func updateActiveWork(active: Bool) {
guard !self.isPreview else { return }
if active {
+1 -1
View File
@@ -450,7 +450,7 @@ final class AppDelegate: NSObject, NSApplicationDelegate {
Task { PresenceReporter.shared.start() }
Task { await HealthStore.shared.refresh(onDemand: true) }
Task { await PortGuardian.shared.sweep(mode: AppStateStore.shared.connectionMode) }
Task { await PeekabooBridgeHostCoordinator.shared.setEnabled(AppStateStore.shared.peekabooBridgeEnabled) }
AppStateStore.shared.applyPeekabooBridgeHostState()
DispatchQueue.main.asyncAfter(deadline: .now() + 1.0) {
CLIInstallPrompter.shared.checkAndPromptIfNeeded(reason: "launch")
}
+2 -2
View File
@@ -29,9 +29,9 @@ Use Peekaboo for the broad macOS automation surface via OpenClaw.app's permissio
## Enable the bridge
In the macOS app: **Settings -> Enable Peekaboo Bridge**.
In the macOS app: **Settings -> Enable Peekaboo Bridge**. The toggle requires **Allow Computer Control** to be on, since both grant local UI automation; with Computer Control off the toggle is disabled and the host does not run. To drive Peekaboo without Computer Control, run Peekaboo's own Mac app as the host instead.
When enabled, OpenClaw starts a local UNIX socket server at `~/Library/Application Support/OpenClaw/<socket-name>`. If disabled, the host stops and `peekaboo` falls back to other available hosts. The coordinator also maintains legacy socket symlinks (`clawdbot`, `clawdis`, `moltbot` under Application Support) pointing at the current socket for older `peekaboo` installs.
When enabled (and Computer Control is on), OpenClaw starts a local UNIX socket server at `~/Library/Application Support/OpenClaw/<socket-name>`. If disabled, the host stops and `peekaboo` falls back to other available hosts. The coordinator also maintains legacy socket symlinks (`clawdbot`, `clawdis`, `moltbot` under Application Support) pointing at the current socket for older `peekaboo` installs.
## Client discovery order