---
name: hd-browser-picker-mac
description: >
  macOS platform companion to hd-browser-picker — the Apple-specific half of how
  Hydrogen Desktop intercepts EVERY URL and routes it through the Browser Picker.
  The picker dialog, the 3 branded variants, the 5-second auto-countdown, the
  fresh-window toggle, and the prefs API all live in hd-browser-picker
  (adom/hd-bootstrap); THIS skill carries only what's wired differently on macOS:
  the top frame is a WKWebView served over http://localhost (not WebView2), and the
  native-browser targets are launched via LaunchServices (`open -a`). Mirror of
  hd-browser-picker-windows (the WebView2 / ICoreWebView2 COM / 6-layer machinery).
  Trigger words — browser picker macos, WKWebView interception, open -a, native
  browser macos, Safari Chrome Arc Edge, localhost top frame, shell.open macos.
---

# hd-browser-picker (macOS) — WKWebView interception + `open -a`

This is the **macOS half** of `hd-browser-picker`. The user-facing behavior — every
URL routes through the Browser Picker (native browser / Hydrogen tab / HD window / Pup),
the 3 branded variants, the 5-second auto-timer, the fresh-window toggle, the prefs API
— is **identical on every host** and lives in the generic **hd-browser-picker** skill.
Read that first; this skill only documents what's Apple-specific.

## The top frame is a WKWebView over `http://localhost`

HD's webview host on macOS is **WKWebView** (via wry), and the Hydrogen frontend is
served over `http://localhost` rather than the Windows `tauri.localhost` / WebView2
origin. The picker's same-origin / external-domain decision (allow localhost·tauri·
data·about, route everything else) is the same contract, but it sits on the WKWebView
navigation surface.

## ⚠️ The interception is wired differently from Windows — not documented here

The generic skill's **6 interception layers** (`on_new_window` / `on_navigation` /
`add_FrameNavigationStarting` / `add_NewWindowRequested` /
`AddScriptToExecuteOnDocumentCreated` / `add_ContextMenuRequested`) are the **WebView2
COM machinery** — that is the *Windows* lineage. On macOS the equivalent interception
runs against WKWebView and is wired differently. **Do NOT assume a macOS COM/CDP
equivalent of those specific APIs** — there is no `ICoreWebView2_11`, no
`AddScriptToExecuteOnDocumentCreated`, no `add_ContextMenuRequested` here. The
Tauri-level wrappers (`on_new_window` / `on_navigation`) are cross-platform; the raw
per-frame COM layers are not. When you need the low-level catch-point, say plainly that
the macOS mechanism is WKWebView-based and wired differently, rather than citing a
WebView2 API that doesn't exist on this host.

## Native browsers launch via LaunchServices (`open -a`)

When the picker routes to a **native desktop browser**, macOS opens it through
LaunchServices, not by resolving an `.exe` path:

- The default/shell-open path uses `open <url>` (`screenshot.rs`, `open_in_browser_profile`).
- A named browser uses `open -a "<App Name>" <url>` — `screenshot.rs` maps
  `chrome→"Google Chrome"`, `edge→"Microsoft Edge"`, `firefox→"Firefox"`,
  `brave→"Brave Browser"`; Safari and Arc are likewise app-name targets. This handles
  user-relocated installs uniformly (no hard-coded path).
- **Fresh window** (`fresh:true`) resolves a concrete browser binary and passes
  `--new-window` (Chromium) / `-new-window` (Firefox) before the URL, instead of plain
  `open` — `open` alone can't force a new window. See `lib.rs` around the
  `open_in_browser_profile` fresh-window branch. The auto-foreground behavior of a
  freshly-launched window holds on macOS just as on Windows.

## `shell:default` still applies

The "open in native browser" path still ultimately calls the Tauri shell plugin, so
both `shell:allow-open` AND `shell:default` must be in both capability files — that
requirement is platform-agnostic and is covered in the generic skill.

## NOT here (lives in the Windows companion)

The WebView2 / `ICoreWebView2` COM detail — the 6 named interception layers, the
`AddScriptToExecuteOnDocumentCreated` cross-origin-iframe script, the
`ICoreWebView2_11` context-menu wiring, the webview2-com 0.38 `.cast()` patterns, and
launching `chrome.exe`/`msedge.exe` by resolved path — is the Windows lineage; see
`hd-browser-picker-windows`. On macOS it's WKWebView + `open -a`, full stop.
