← Commit history

v1.2.1: launch pup with FULL browser permissions by default (all granted, was denying notifications/geolocation/midi) for full debug; per-permission grant tolerates rejected descriptors; strictPermissions opts out

John Lauer ·5cb4eebfc6 · ·parent c985c6f
6 files changed +58−20
SKILL.md+4
@@ -195,3 +195,7 @@ plain "open in pup" — that's CfT.   reflexively; `browser_reload` or `browser_navigate` instead. - **Surface `_hint` verbatim** when a verb reports it isn't ready or failed. - **Never broadly kill Chrome** — use `browser_close_window` for a specific session.+- **Pup launches with FULL browser permissions by default** (notifications, geolocation, camera, mic,+  midi, sensors, clipboard, wake-lock, …) so no permission prompt ever blocks a debug flow — you don't+  need to grant anything. Pass `strictPermissions:true` to `browser_open_window` only for the rare+  untrusted-site audit where you want Chromium's default prompts back.
adom-bridge-puppeteer-manifest.json+4−4
@@ -1,10 +1,10 @@ {   "manifest_version": 1,   "name": "puppeteer",-  "version": "1.2.0",-  "url": "https://wiki.adom.inc/download/adom/adom-desktop-puppeteer-bridge/1.2.0/adom-bridge-puppeteer-v1.2.0.zip",-  "sha256": "57d27ac4bb22b9bea1138c4b8260224e14ff0e680f5a731a8356005b510bf469",-  "size": 127304,+  "version": "1.2.1",+  "url": "https://wiki.adom.inc/download/adom/adom-desktop-puppeteer-bridge/1.2.1/adom-bridge-puppeteer-v1.2.1.zip",+  "sha256": "207965598b9496411a75238eb86ecaa43e5e5299061837d5749bd82a284072c6",+  "size": 127910,   "verbPrefixes": [     "browser_",     "desktop_recorder_",
package.json+1−1
@@ -1,6 +1,6 @@ {   "slug": "adom-desktop-puppeteer-bridge",-  "version": "1.2.0",+  "version": "1.2.1",   "type": "app",   "description": "CONTAINER-SIDE install — the everyday `pup` user skill only. This pkg drops the `pup` skill (drive the browser bridge: open/close/tabs/screenshot/record, background-by-default) into ~/.claude/skills/ AND ~/.codex/skills/. It does NOT install the developer/publishing skills (pup-bridge-dev, pup-bridge-publish) — those are source-only; clone the repo (adom-wiki repo clone adom/adom-desktop-puppeteer-bridge) to get them from dev-skills/. It also does NOT contain the bridge runtime: the bridge (Node + Chrome for Testing) lives on the DESKTOP — bundled inside Adom Desktop and published here on the Releases tab as adom-bridge-puppeteer-v<ver>.zip, which Adom Desktop streams into its bridges-cache. TL;DR: `pkg install` = the pup user skill; dev skills = clone the source; the bridge = the Release zip + bundled in Adom Desktop.",   "keywords": [
src/BRIDGE_VERSION+1−1
@@ -1 +1 @@-1.2.0\ No newline at end of file+1.2.1\ No newline at end of file
src/bridge.json+6−4
@@ -2,8 +2,8 @@   "manifest_version": 1,   "name": "puppeteer",   "displayName": "Puppeteer (Chrome for Testing + Native)",-  "version": "1.2.0",-  "description": "Tier-1 cold-start (v1.2.0, for AD v1.9.47+ two-tier model): pup brings its OWN browser (Chrome for Testing), so it needs no detect-block. It declares prewarm:[chrome-for-testing] so Adom Desktop fetches Chrome in the BACKGROUND and reports readiness via bridge_readiness. The bridge server starts fine WITHOUT Chrome; browser_readiness is a READ-ONLY probe (ready = server-up AND Chrome cached; never triggers a download); browser_open returns a non-blocking {installing:true} (never blocks/crashes) until Chrome is cached; browser_prewarm is an explicit bridge-side fetch fallback. Headful browser automation. Default path drives Chrome for Testing (CfT) with managed pup profiles. v1.0.6+ optional native-drive: pass nativeBrowser+nativeProfile (from desktop_list_browsers) to browser_open_window to drive the user's REAL Chrome/Edge/Brave with the actual signed-in account + org policies + device enrollment intact. Smart flow: if the browser is CLOSED, AD launches it fresh immediately with NO prompt (nothing to disrupt) and reports back ready-to-drive (launchedFresh:true); if it's OPEN without the port, AD returns errorCode:'native_relaunch_required' so the caller asks the user, then re-call with nativeRelaunch:true. AD then closes only that browser's own PIDs cleanly (WM_CLOSE — Sessions saved; CfT bridge sessions + other Chromium left untouched) and relaunches with --restore-last-session so every tab/window comes back. If the debug port is policy-blocked (e.g. Google Workspace's RemoteDebuggingAllowed disabled — affects Chrome browser-wide, all profiles), native drive returns errorCode:'native_cdp_blocked' with a `diagnosis` plus an `alternatives` list of other installed browsers — Edge usually escapes Google management. The generic CfT path (browser_open_window with no nativeBrowser) always works as a fallback.",+  "version": "1.2.1",+  "description": "v1.2.1: Launches with FULL browser permissions by default (all granted — notifications/geolocation/camera/mic/midi/sensors/clipboard/wake-lock/…) so no permission prompt ever blocks full debug; strictPermissions:true opts out. Tier-1 cold-start (for AD v1.9.47+ two-tier model): pup brings its OWN browser (Chrome for Testing), so it needs no detect-block. It declares prewarm:[chrome-for-testing] so Adom Desktop fetches Chrome in the BACKGROUND and reports readiness via bridge_readiness. The bridge server starts fine WITHOUT Chrome; browser_readiness is a READ-ONLY probe (ready = server-up AND Chrome cached; never triggers a download); browser_open returns a non-blocking {installing:true} (never blocks/crashes) until Chrome is cached; browser_prewarm is an explicit bridge-side fetch fallback. Headful browser automation. Default path drives Chrome for Testing (CfT) with managed pup profiles. v1.0.6+ optional native-drive: pass nativeBrowser+nativeProfile (from desktop_list_browsers) to browser_open_window to drive the user's REAL Chrome/Edge/Brave with the actual signed-in account + org policies + device enrollment intact. Smart flow: if the browser is CLOSED, AD launches it fresh immediately with NO prompt (nothing to disrupt) and reports back ready-to-drive (launchedFresh:true); if it's OPEN without the port, AD returns errorCode:'native_relaunch_required' so the caller asks the user, then re-call with nativeRelaunch:true. AD then closes only that browser's own PIDs cleanly (WM_CLOSE — Sessions saved; CfT bridge sessions + other Chromium left untouched) and relaunches with --restore-last-session so every tab/window comes back. If the debug port is policy-blocked (e.g. Google Workspace's RemoteDebuggingAllowed disabled — affects Chrome browser-wide, all profiles), native drive returns errorCode:'native_cdp_blocked' with a `diagnosis` plus an `alternatives` list of other installed browsers — Edge usually escapes Google management. The generic CfT path (browser_open_window with no nativeBrowser) always works as a fallback.",   "homepage": "https://github.com/adom-inc/adom-desktop",   "author": "Adom Inc.",   "license": "MIT",@@ -16,7 +16,9 @@     "killImageName": "node.exe"   },   "prewarm": {-    "assets": ["chrome-for-testing"]+    "assets": [+      "chrome-for-testing"+    ]   },   "verbPrefixes": [     "browser_",@@ -77,4 +79,4 @@       "reason": "Linux port pending — same killImageName + Chrome resolution issues as macOS."     }   }-}+}\ No newline at end of file
src/server.js+42−10
@@ -1154,13 +1154,14 @@ async function closeRestoredLeftoverTabs(browser, keepPage) { // // Two CDP mechanisms together give us this: //-//   1. Browser.setPermission (per-origin permissions) — granted for-//      clipboard-read/write so paste-into-input-via-eval works; DENIED-//      for notifications + geolocation so prompts don't fire mid-flow.-//      Per-permission so a single unknown-name failure doesn't break-//      the others (the v1.4.12 Browser.grantPermissions array form-//      failed on Chrome 146 because "automaticDownloads" was-//      unrecognized — taking the whole grant down with it).+//   1. Browser.setPermission (per-origin permissions) — FULL DEBUG: every+//      permission Chrome accepts is GRANTED (notifications, geolocation,+//      camera, mic, midi, sensors, clipboard, wake-lock, …) so no permission+//      prompt EVER blocks a debug flow. Per-permission so an unknown/rejected+//      descriptor (e.g. clipboard-sanitized-write on some builds) only drops+//      itself, never the rest (the v1.4.12 Browser.grantPermissions array form+//      failed wholesale on Chrome 146 when one name was unrecognized).+//      Opt-out for the rare untrusted-site case: strictPermissions:true. // //   2. Page.setDownloadBehavior — see applyDownloadBehavior below. This //      is the actual mechanism for unblocking scripted downloads. The@@ -1179,13 +1180,44 @@ async function closeRestoredLeftoverTabs(browser, keepPage) { // grant down. v1.6.3 fixes by switching to Browser.setPermission per- // permission and dropping the unhelpful automaticDownloads (which we // replace with the actually-effective Page.setDownloadBehavior).+// FULL-DEBUG default: grant EVERYTHING Chrome will accept (John: always launch+// pup with full permissions for full debug). All 'granted', none denied. Applied+// per-permission below so any descriptor a given Chrome build rejects (e.g.+// clipboard-sanitized-write) only drops itself — the rest still land. Opt-out via+// strictPermissions:true on browser_open_window for an untrusted site you're auditing. const PERMISSIVE_DEFAULT_PERMISSIONS = [   { name: 'clipboard-read', setting: 'granted' },   { name: 'clipboard-write', setting: 'granted' },   { name: 'clipboard-sanitized-write', setting: 'granted' },-  { name: 'notifications', setting: 'denied' },-  { name: 'geolocation', setting: 'denied' },-  { name: 'midi', setting: 'denied' },+  { name: 'notifications', setting: 'granted' },+  { name: 'geolocation', setting: 'granted' },+  { name: 'camera', setting: 'granted' },+  { name: 'microphone', setting: 'granted' },+  { name: 'midi', setting: 'granted' },+  { name: 'midiSysex', setting: 'granted' },+  { name: 'background-sync', setting: 'granted' },+  { name: 'background-fetch', setting: 'granted' },+  { name: 'periodic-background-sync', setting: 'granted' },+  { name: 'payment-handler', setting: 'granted' },+  { name: 'persistent-storage', setting: 'granted' },+  { name: 'durable-storage', setting: 'granted' },+  { name: 'storage-access', setting: 'granted' },+  { name: 'top-level-storage-access', setting: 'granted' },+  { name: 'idle-detection', setting: 'granted' },+  { name: 'display-capture', setting: 'granted' },+  { name: 'window-management', setting: 'granted' },+  { name: 'local-fonts', setting: 'granted' },+  { name: 'nfc', setting: 'granted' },+  { name: 'screen-wake-lock', setting: 'granted' },+  { name: 'system-wake-lock', setting: 'granted' },+  { name: 'accelerometer', setting: 'granted' },+  { name: 'gyroscope', setting: 'granted' },+  { name: 'magnetometer', setting: 'granted' },+  { name: 'ambient-light-sensor', setting: 'granted' },+  { name: 'sensors', setting: 'granted' },+  { name: 'protected-media-identifier', setting: 'granted' },+  { name: 'captured-surface-control', setting: 'granted' },+  { name: 'speaker-selection', setting: 'granted' }, ]; async function applyDefaultPermissions(browser, profileName, { strictPermissions = false } = {}) {   if (strictPermissions) {