app
Pup - the AI's own browser
Public Made by Adomby adom
pup gives your AI a real browser on your desktop that it drives completely, in the background, signed in as you: windows that never jump in front of your work, one shared profile that learns your logins, and every window labeled on the taskbar with its AI thread's name.
← Commit history
Recover from the 1.9.86 mac-parity regression: rebase onto Kyle's 1.9.85 unified base and re-apply only the puppeteer 24.43.1 / CfT 148 bump. Restores darwin support, recorder-icon.ico, and the AD-base resolver that 1.9.86 dropped.
6 files changed
+313−205
adom-bridge-puppeteer-manifest.json+4−4@@ -1,10 +1,10 @@ { "manifest_version": 1, "name": "puppeteer",- "version": "1.9.86",- "url": "https://wiki.adom.inc/download/adom/adom-desktop-puppeteer-bridge/1.9.86/adom-bridge-puppeteer-v1.9.86.zip",- "sha256": "3445f41a6e84f5712bdceb1a5ac8e0fbbf9959520926c79b7ec16aad7046a470",- "size": 317379,+ "version": "1.9.87",+ "url": "https://wiki.adom.inc/download/adom/adom-desktop-puppeteer-bridge/1.9.87/adom-bridge-puppeteer-v1.9.87.zip",+ "sha256": "ff2f07358ce80cd7b7308bc428f2ee08e30aebfef6f9fee507ea784ce8db2b71",+ "size": 358865, "verbPrefixes": [ "browser_", "desktop_recorder_",
src/BRIDGE_VERSION+1−1@@ -1 +1 @@-1.9.86+1.9.87
src/bridge.json+2−2@@ -2,8 +2,8 @@ "manifest_version": 1, "name": "puppeteer", "displayName": "Puppeteer (Chrome for Testing + Native)",- "version": "1.9.86",- "description": "Drives a browser ALREADY on the machine \u2014 installed Chrome, else Microsoft Edge (every Windows PC ships with Edge) \u2014 launched with a FRESH isolated profile, so the common case has NO ~150 MB Chrome-for-Testing download and it never touches the user's real tabs/logins. Binds its local server to LOOPBACK (127.0.0.1) only, so no Windows Firewall 'allow Node through the firewall' prompt ever pops. Chrome for Testing is fetched only as a LAST RESORT if the machine has no Chromium browser at all. SPAWN-VERIFIED fallback: pup tries each detected browser (Chrome \u2192 Edge \u2192 CfT) and actually launches it, falling through to the next if one won't start (and handling browsers like Edge that relaunch onto another PID), so a corrupt/partial install never hard-fails an open. The browser that launches is cached as the default (persisted across restarts) so it isn't re-probed each time. On spawn the bridge SELF-WARMS: detects browsers + disk, and only if the box has no Chrome/Edge and no cached CfT does it background-fetch CfT so the first open is instant. browser_use pins a specific browser (chrome | edge | cft | auto); {browser:'chrome',install:true} downloads & installs REAL Google Chrome (user-scoped, no admin) on an Edge-only box. browser_readiness (READ-ONLY) reports which browser will be used + the full candidate list + the default + free disk. Every failure returns a specific errorCode + _hint (chrome_install_no_disk, chrome_download_network, chrome_install_permission, chrome_stable_not_detected, \u2026). Launches with FULL browser permissions by default for full debug (strictPermissions:true opts out). Headful automation: open/close windows+tabs, navigate, screenshot, eval JS, record. pup is a GENERIC, non-profile browser only \u2014 every session is a fresh isolated Chrome/Edge process, never the user's real signed-in browser; profile defaults to sessionId. To drive the user's REAL Chrome/Edge (their profile, cookies, SSO), use the Adom browser EXTENSION's nbrowser_* verbs \u2014 a separate bridge, not pup's job.",+ "version": "1.9.87",+ "description": "Drives a browser ALREADY on the machine \u2014 installed Chrome, else Microsoft Edge (every Windows PC ships with Edge) \u2014 launched with a FRESH isolated profile, so the common case has NO ~150 MB Chrome-for-Testing download and it never touches the user's real tabs/logins. Binds its local server to LOOPBACK (127.0.0.1) only, so no Windows Firewall 'allow Node through the firewall' prompt ever pops. Chrome for Testing is fetched only as a LAST RESORT if the machine has no Chromium browser at all. SPAWN-VERIFIED fallback: pup tries each detected browser (Chrome \u2192 Edge \u2192 CfT) and actually launches it, falling through to the next if one won't start (and handling browsers like Edge that relaunch onto another PID), so a corrupt/partial install never hard-fails an open. The browser that launches is cached as the default (persisted across restarts) so it isn't re-probed each time. On spawn the bridge SELF-WARMS: detects browsers + disk, and only if the box has no Chrome/Edge and no cached CfT does it background-fetch CfT so the first open is instant. browser_use pins a specific browser (chrome | edge | cft | auto); {browser:'chrome',install:true} downloads & installs REAL Google Chrome (user-scoped, no admin) on an Edge-only box. browser_readiness (READ-ONLY) reports which browser will be used + the full candidate list + the default + free disk. Every failure returns a specific errorCode + _hint (chrome_install_no_disk, chrome_download_network, chrome_install_permission, chrome_stable_not_detected, \u2026). Launches with FULL browser permissions by default for full debug (strictPermissions:true opts out). Headful automation: open/close windows+tabs, navigate, screenshot, eval JS, record. pup is a GENERIC, non-profile browser only \u2014 every session is a fresh isolated Chrome/Edge process, never the user's real signed-in browser; profile defaults to sessionId. To drive the user's REAL Chrome/Edge (their profile, cookies, SSO), use the Adom browser EXTENSION's nbrowser_* verbs \u2014 a separate bridge, not pup's job. macOS (v1.9.74+): full parity with mac-native mechanics \u2014 background-by-default is the app-level hide (windows stay drivable/screenshottable while hidden), raise/lower map to unhide+activate/hide, browser_alert_window posts a native toast whose click focuses the window, browser_use {browser:'chrome',install:true} installs Chrome from the official dmg, and taskbar identity/badging remains Windows-only.", "homepage": "https://wiki.adom.inc/adom/adom-desktop", "author": "Adom Inc.", "license": "MIT",
src/package-lock.json+141−187@@ -8,8 +8,10 @@ "name": "adom-puppeteer-bridge", "version": "1.0.0", "dependencies": {+ "puppeteer": "^24.43.1"+ },+ "optionalDependencies": { "keytar": "^7.9.0",- "puppeteer": "^24.38.0", "sharp": "^0.34.5" } },@@ -51,6 +53,7 @@ "resolved": "https://registry.npmjs.org/@img/colour/-/colour-1.1.0.tgz", "integrity": "sha512-Td76q7j57o/tLVdgS746cYARfSyxk8iEfRxewL9h4OMzYhbW4TAcppl0mT4eyqXddh6L/jwoM75mo7ixa/pCeQ==", "license": "MIT",+ "optional": true, "engines": { "node": ">=18" }@@ -512,10 +515,9 @@ } }, "node_modules/@puppeteer/browsers": {- "version": "2.13.0",- "resolved": "https://registry.npmjs.org/@puppeteer/browsers/-/browsers-2.13.0.tgz",- "integrity": "sha512-46BZJYJjc/WwmKjsvDFykHtXrtomsCIrwYQPOP7VfMJoZY2bsDF9oROBABR3paDjDcmkUye1Pb1BqdcdiipaWA==",- "license": "Apache-2.0",+ "version": "2.13.2",+ "resolved": "https://registry.npmjs.org/@puppeteer/browsers/-/browsers-2.13.2.tgz",+ "integrity": "sha512-5EUZSUIc37H6aIXyWO0Z4y8NlF8NnjgmqeQgOGiswAU7pY0HOo16ho4+alIWmSfdZnjqBRawMsP3I5YqLSn6kw==", "dependencies": { "debug": "^4.4.3", "extract-zip": "^2.0.1",@@ -535,24 +537,21 @@ "node_modules/@tootallnate/quickjs-emscripten": { "version": "0.23.0", "resolved": "https://registry.npmjs.org/@tootallnate/quickjs-emscripten/-/quickjs-emscripten-0.23.0.tgz",- "integrity": "sha512-C5Mc6rdnsaJDjO3UpGW/CQTHtCKaYlScZTly4JIu97Jxo/odCiH0ITnDXSJPTOrEKk/ycSZ0AOgTmkDtkOsvIA==",- "license": "MIT"+ "integrity": "sha512-C5Mc6rdnsaJDjO3UpGW/CQTHtCKaYlScZTly4JIu97Jxo/odCiH0ITnDXSJPTOrEKk/ycSZ0AOgTmkDtkOsvIA==" }, "node_modules/@types/node": {- "version": "25.5.0",- "resolved": "https://registry.npmjs.org/@types/node/-/node-25.5.0.tgz",- "integrity": "sha512-jp2P3tQMSxWugkCUKLRPVUpGaL5MVFwF8RDuSRztfwgN1wmqJeMSbKlnEtQqU8UrhTmzEmZdu2I6v2dpp7XIxw==",- "license": "MIT",+ "version": "26.1.1",+ "resolved": "https://registry.npmjs.org/@types/node/-/node-26.1.1.tgz",+ "integrity": "sha512-nxAkRSVkN1Y0JC1W8ky/fTfkGsMmcrRsbx+3XoZE+rMOX71kLYTV7fLXpqud1GpbpP5TuffXFqfX7fH2GgZREw==", "optional": true, "dependencies": {- "undici-types": "~7.18.0"+ "undici-types": "~8.3.0" } }, "node_modules/@types/yauzl": { "version": "2.10.3", "resolved": "https://registry.npmjs.org/@types/yauzl/-/yauzl-2.10.3.tgz", "integrity": "sha512-oJoftv0LSuaDZE3Le4DbKX+KS9G36NzOeSap90UIK0yMA/NhKJhqlSGtNDORNRaIbQfzjXDrQa0ytJ6mNRGz/Q==",- "license": "MIT", "optional": true, "dependencies": { "@types/node": "*"@@ -562,7 +561,6 @@ "version": "7.1.4", "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.4.tgz", "integrity": "sha512-MnA+YT8fwfJPgBx3m60MNqakm30XOkyIoH1y6huTQvC0PwZG7ki8NacLBcrPbNoo8vEZy7Jpuk7+jMO+CUovTQ==",- "license": "MIT", "engines": { "node": ">= 14" }@@ -571,7 +569,6 @@ "version": "5.0.1", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==",- "license": "MIT", "engines": { "node": ">=8" }@@ -580,7 +577,6 @@ "version": "4.3.0", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",- "license": "MIT", "dependencies": { "color-convert": "^2.0.1" },@@ -601,7 +597,6 @@ "version": "0.13.4", "resolved": "https://registry.npmjs.org/ast-types/-/ast-types-0.13.4.tgz", "integrity": "sha512-x1FCFnFifvYDDzTaLII71vG5uvDwgtmDTEVWAxrgeiR8VjMONcCXJx7E+USjDtHlwFmt9MysbqgF9b9Vjr6w+w==",- "license": "MIT", "dependencies": { "tslib": "^2.0.1" },@@ -610,10 +605,9 @@ } }, "node_modules/b4a": {- "version": "1.8.0",- "resolved": "https://registry.npmjs.org/b4a/-/b4a-1.8.0.tgz",- "integrity": "sha512-qRuSmNSkGQaHwNbM7J78Wwy+ghLEYF1zNrSeMxj4Kgw6y33O3mXcQ6Ie9fRvfU/YnxWkOchPXbaLb73TkIsfdg==",- "license": "Apache-2.0",+ "version": "1.8.1",+ "resolved": "https://registry.npmjs.org/b4a/-/b4a-1.8.1.tgz",+ "integrity": "sha512-aiqre1Nr0B/6DgE2N5vwTc+2/oQZ4Wh1t4NznYY4E00y8LCt6NqdRv81so00oo27D8MVKTpUa/MwUUtBLXCoDw==", "peerDependencies": { "react-native-b4a": "*" },@@ -624,10 +618,9 @@ } }, "node_modules/bare-events": {- "version": "2.8.2",- "resolved": "https://registry.npmjs.org/bare-events/-/bare-events-2.8.2.tgz",- "integrity": "sha512-riJjyv1/mHLIPX4RwiK+oW9/4c3TEUeORHKefKAKnZ5kyslbN+HXowtbaVEqt4IMUB7OXlfixcs6gsFeo/jhiQ==",- "license": "Apache-2.0",+ "version": "2.9.1",+ "resolved": "https://registry.npmjs.org/bare-events/-/bare-events-2.9.1.tgz",+ "integrity": "sha512-Z0oHEHAFDZkffN8Qc39zNZjQlMDkPJRyyyZieU1VH7u8c5S+qHZ2S8ixdKIAxEjfHO7FJxXmJWgteOghVanIsg==", "peerDependencies": { "bare-abort-controller": "*" },@@ -638,10 +631,9 @@ } }, "node_modules/bare-fs": {- "version": "4.5.5",- "resolved": "https://registry.npmjs.org/bare-fs/-/bare-fs-4.5.5.tgz",- "integrity": "sha512-XvwYM6VZqKoqDll8BmSww5luA5eflDzY0uEFfBJtFKe4PAAtxBjU3YIxzIBzhyaEQBy1VXEQBto4cpN5RZJw+w==",- "license": "Apache-2.0",+ "version": "4.7.4",+ "resolved": "https://registry.npmjs.org/bare-fs/-/bare-fs-4.7.4.tgz",+ "integrity": "sha512-y1kC+ffIx/tPLdTE693uNjHfzTfr+ravR5tvWlMXe25nELbkqV400S71qHDwbkAQ1FVEZobB1NFRzFbCCcyBCQ==", "dependencies": { "bare-events": "^2.5.4", "bare-path": "^3.0.0",@@ -661,38 +653,29 @@ } } },- "node_modules/bare-os": {- "version": "3.8.0",- "resolved": "https://registry.npmjs.org/bare-os/-/bare-os-3.8.0.tgz",- "integrity": "sha512-Dc9/SlwfxkXIGYhvMQNUtKaXCaGkZYGcd1vuNUUADVqzu4/vQfvnMkYYOUnt2VwQ2AqKr/8qAVFRtwETljgeFg==",- "license": "Apache-2.0",- "engines": {- "bare": ">=1.14.0"- }- }, "node_modules/bare-path": {- "version": "3.0.0",- "resolved": "https://registry.npmjs.org/bare-path/-/bare-path-3.0.0.tgz",- "integrity": "sha512-tyfW2cQcB5NN8Saijrhqn0Zh7AnFNsnczRcuWODH0eYAXBsJ5gVxAUuNr7tsHSC6IZ77cA0SitzT+s47kot8Mw==",- "license": "Apache-2.0",- "dependencies": {- "bare-os": "^3.0.1"- }+ "version": "3.1.1",+ "resolved": "https://registry.npmjs.org/bare-path/-/bare-path-3.1.1.tgz",+ "integrity": "sha512-JprUlveX3QjApC1cTpsUOiscADftCGVWkzitbHsRqv84hzYwYHw2mbluddsq5TvI8mH/8Ov1f4BiMAdcB0oYnQ==" }, "node_modules/bare-stream": {- "version": "2.8.1",- "resolved": "https://registry.npmjs.org/bare-stream/-/bare-stream-2.8.1.tgz",- "integrity": "sha512-bSeR8RfvbRwDpD7HWZvn8M3uYNDrk7m9DQjYOFkENZlXW8Ju/MPaqUPQq5LqJ3kyjEm07siTaAQ7wBKCU59oHg==",- "license": "Apache-2.0",+ "version": "2.13.3",+ "resolved": "https://registry.npmjs.org/bare-stream/-/bare-stream-2.13.3.tgz",+ "integrity": "sha512-Kc+brLqvEqGkjyfiwJmImAOqLZL7OsoLKuavx+hJjgVV3nLTOjloJyPMFxjUPerGGHrNH0fLU06jjykMLWrERQ==", "dependencies": {- "streamx": "^2.21.0",+ "b4a": "^1.8.1",+ "streamx": "^2.25.0", "teex": "^1.0.1" }, "peerDependencies": {+ "bare-abort-controller": "*", "bare-buffer": "*", "bare-events": "*" }, "peerDependenciesMeta": {+ "bare-abort-controller": {+ "optional": true+ }, "bare-buffer": { "optional": true },@@ -702,10 +685,9 @@ } }, "node_modules/bare-url": {- "version": "2.3.2",- "resolved": "https://registry.npmjs.org/bare-url/-/bare-url-2.3.2.tgz",- "integrity": "sha512-ZMq4gd9ngV5aTMa5p9+UfY0b3skwhHELaDkhEHetMdX0LRkW9kzaym4oo/Eh+Ghm0CCDuMTsRIGM/ytUc1ZYmw==",- "license": "Apache-2.0",+ "version": "2.4.6",+ "resolved": "https://registry.npmjs.org/bare-url/-/bare-url-2.4.6.tgz",+ "integrity": "sha512-iQxPClE07hETVpbRoX7JXX3v/ZQViCxe/SYCxylRLzdEx1xJAufPptfiOqR8tqiCtmbtMDANKWszzjLu1PMAZQ==", "dependencies": { "bare-path": "^3.0.0" }@@ -728,13 +710,13 @@ "url": "https://feross.org/support" } ],- "license": "MIT"+ "license": "MIT",+ "optional": true }, "node_modules/basic-ftp": {- "version": "5.2.0",- "resolved": "https://registry.npmjs.org/basic-ftp/-/basic-ftp-5.2.0.tgz",- "integrity": "sha512-VoMINM2rqJwJgfdHq6RiUudKt2BV+FY5ZFezP/ypmwayk68+NzzAQy4XXLlqsGD4MCzq3DrmNFD/uUmBJuGoXw==",- "license": "MIT",+ "version": "5.3.1",+ "resolved": "https://registry.npmjs.org/basic-ftp/-/basic-ftp-5.3.1.tgz",+ "integrity": "sha512-bopVNp6ugyA150DDuZfPFdt1KZ5a94ZDiwX4hMgZDzF+GttD80lEy8kj98kbyhLXnPvhtIo93mdnLIjpCAeeOw==", "engines": { "node": ">=10.0.0" }@@ -744,6 +726,7 @@ "resolved": "https://registry.npmjs.org/bl/-/bl-4.1.0.tgz", "integrity": "sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==", "license": "MIT",+ "optional": true, "dependencies": { "buffer": "^5.5.0", "inherits": "^2.0.4",@@ -769,6 +752,7 @@ } ], "license": "MIT",+ "optional": true, "dependencies": { "base64-js": "^1.3.1", "ieee754": "^1.1.13"@@ -778,7 +762,6 @@ "version": "0.2.13", "resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-0.2.13.tgz", "integrity": "sha512-VO9Ht/+p3SN7SKWqcrgEzjGbRSJYTx+Q1pTQC0wrWqHx0vpJraQ6GtHx8tvcg1rlK1byhU5gccxgOgj7B0TDkQ==",- "license": "MIT", "engines": { "node": "*" }@@ -796,13 +779,13 @@ "version": "1.1.4", "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.4.tgz", "integrity": "sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==",- "license": "ISC"+ "license": "ISC",+ "optional": true }, "node_modules/chromium-bidi": { "version": "14.0.0", "resolved": "https://registry.npmjs.org/chromium-bidi/-/chromium-bidi-14.0.0.tgz", "integrity": "sha512-9gYlLtS6tStdRWzrtXaTMnqcM4dudNegMXJxkR0I/CXObHalYeYcAMPrL19eroNZHtJ8DQmu1E+ZNOYu/IXMXw==",- "license": "Apache-2.0", "dependencies": { "mitt": "^3.0.1", "zod": "^3.24.1"@@ -815,7 +798,6 @@ "version": "8.0.1", "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz", "integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==",- "license": "ISC", "dependencies": { "string-width": "^4.2.0", "strip-ansi": "^6.0.1",@@ -829,7 +811,6 @@ "version": "2.0.1", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",- "license": "MIT", "dependencies": { "color-name": "~1.1.4" },@@ -840,8 +821,7 @@ "node_modules/color-name": { "version": "1.1.4", "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",- "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",- "license": "MIT"+ "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" }, "node_modules/cosmiconfig": { "version": "9.0.1",@@ -873,7 +853,6 @@ "version": "6.0.2", "resolved": "https://registry.npmjs.org/data-uri-to-buffer/-/data-uri-to-buffer-6.0.2.tgz", "integrity": "sha512-7hvf7/GW8e86rW0ptuwS3OcBGDjIi6SZva7hCyWC0yYry2cOPmLIjXAUHI6DK2HsnwJd9ifmt57i8eV2n4YNpw==",- "license": "MIT", "engines": { "node": ">= 14" }@@ -882,7 +861,6 @@ "version": "4.4.3", "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz", "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==",- "license": "MIT", "dependencies": { "ms": "^2.1.3" },@@ -900,6 +878,7 @@ "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-6.0.0.tgz", "integrity": "sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ==", "license": "MIT",+ "optional": true, "dependencies": { "mimic-response": "^3.1.0" },@@ -915,6 +894,7 @@ "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz", "integrity": "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==", "license": "MIT",+ "optional": true, "engines": { "node": ">=4.0.0" }@@ -923,7 +903,6 @@ "version": "5.0.1", "resolved": "https://registry.npmjs.org/degenerator/-/degenerator-5.0.1.tgz", "integrity": "sha512-TllpMR/t0M5sqCXfj85i4XaAzxmS5tVA16dqvdkMwGmzI+dXLXnw3J+3Vdv7VKw+ThlTMboK6i9rnZ6Nntj5CQ==",- "license": "MIT", "dependencies": { "ast-types": "^0.13.4", "escodegen": "^2.1.0",@@ -938,21 +917,20 @@ "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.1.2.tgz", "integrity": "sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ==", "license": "Apache-2.0",+ "optional": true, "engines": { "node": ">=8" } }, "node_modules/devtools-protocol": {- "version": "0.0.1581282",- "resolved": "https://registry.npmjs.org/devtools-protocol/-/devtools-protocol-0.0.1581282.tgz",- "integrity": "sha512-nv7iKtNZQshSW2hKzYNr46nM/Cfh5SEvE2oV0/SEGgc9XupIY5ggf84Cz8eJIkBce7S3bmTAauFD6aysMpnqsQ==",- "license": "BSD-3-Clause"+ "version": "0.0.1608973",+ "resolved": "https://registry.npmjs.org/devtools-protocol/-/devtools-protocol-0.0.1608973.tgz",+ "integrity": "sha512-Tpm17fxYzt+J7VrGdc1k8YdRqS3YV7se/M6KeemEqvUbq/n7At1rWVuXMxQgpWkdwSdIEKYbU//Bve+Shm4YNQ==" }, "node_modules/emoji-regex": { "version": "8.0.0", "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz",- "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==",- "license": "MIT"+ "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==" }, "node_modules/end-of-stream": { "version": "1.4.5",@@ -985,7 +963,6 @@ "version": "3.2.0", "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz", "integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==",- "license": "MIT", "engines": { "node": ">=6" }@@ -994,7 +971,6 @@ "version": "2.1.0", "resolved": "https://registry.npmjs.org/escodegen/-/escodegen-2.1.0.tgz", "integrity": "sha512-2NlIDTwUWJN0mRPQOdtQBzbUHvdGY2P1VXSyU83Q3xKxM7WHX2Ql8dKq782Q9TgQUNOLEzEYu9bzLNj1q88I5w==",- "license": "BSD-2-Clause", "dependencies": { "esprima": "^4.0.1", "estraverse": "^5.2.0",@@ -1015,7 +991,6 @@ "version": "4.0.1", "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==",- "license": "BSD-2-Clause", "bin": { "esparse": "bin/esparse.js", "esvalidate": "bin/esvalidate.js"@@ -1028,7 +1003,6 @@ "version": "5.3.0", "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==",- "license": "BSD-2-Clause", "engines": { "node": ">=4.0" }@@ -1037,7 +1011,6 @@ "version": "2.0.3", "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==",- "license": "BSD-2-Clause", "engines": { "node": ">=0.10.0" }@@ -1046,7 +1019,6 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/events-universal/-/events-universal-1.0.1.tgz", "integrity": "sha512-LUd5euvbMLpwOF8m6ivPCbhQeSiYVNb8Vs0fQ8QjXo0JTkEHpz8pxdQf0gStltaPpw0Cca8b39KxvK9cfKRiAw==",- "license": "Apache-2.0", "dependencies": { "bare-events": "^2.7.0" }@@ -1056,6 +1028,7 @@ "resolved": "https://registry.npmjs.org/expand-template/-/expand-template-2.0.3.tgz", "integrity": "sha512-XYfuKMvj4O35f/pOXLObndIRvyQ+/+6AhODh+OKWj9S9498pHHn/IMszH+gt0fBCRWMNfk1ZSp5x3AifmnI2vg==", "license": "(MIT OR WTFPL)",+ "optional": true, "engines": { "node": ">=6" }@@ -1064,7 +1037,6 @@ "version": "2.0.1", "resolved": "https://registry.npmjs.org/extract-zip/-/extract-zip-2.0.1.tgz", "integrity": "sha512-GDhU9ntwuKyGXdZBUgTIe+vXnWj0fppUEtMDL0+idd5Sta8TGpHssn/eusA9mrPr9qNDym6SxAYZjNvCn/9RBg==",- "license": "BSD-2-Clause", "dependencies": { "debug": "^4.1.1", "get-stream": "^5.1.0",@@ -1083,14 +1055,12 @@ "node_modules/fast-fifo": { "version": "1.3.2", "resolved": "https://registry.npmjs.org/fast-fifo/-/fast-fifo-1.3.2.tgz",- "integrity": "sha512-/d9sfos4yxzpwkDkuN7k2SqFKtYNmCTzgfEpz82x34IM9/zc8KGxQoXg1liNC/izpRM/MBdt44Nmx41ZWqk+FQ==",- "license": "MIT"+ "integrity": "sha512-/d9sfos4yxzpwkDkuN7k2SqFKtYNmCTzgfEpz82x34IM9/zc8KGxQoXg1liNC/izpRM/MBdt44Nmx41ZWqk+FQ==" }, "node_modules/fd-slicer": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/fd-slicer/-/fd-slicer-1.1.0.tgz", "integrity": "sha512-cE1qsB/VwyQozZ+q1dGxR8LBYNZeofhEdUNGSMbQD3Gw2lAzX9Zb3uIU6Ebc/Fmyjo9AWWfnn0AUCHqtevs/8g==",- "license": "MIT", "dependencies": { "pend": "~1.2.0" }@@ -1099,13 +1069,13 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/fs-constants/-/fs-constants-1.0.0.tgz", "integrity": "sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==",- "license": "MIT"+ "license": "MIT",+ "optional": true }, "node_modules/get-caller-file": { "version": "2.0.5", "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==",- "license": "ISC", "engines": { "node": "6.* || 8.* || >= 10.*" }@@ -1114,7 +1084,6 @@ "version": "5.2.0", "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz", "integrity": "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==",- "license": "MIT", "dependencies": { "pump": "^3.0.0" },@@ -1129,7 +1098,6 @@ "version": "6.0.5", "resolved": "https://registry.npmjs.org/get-uri/-/get-uri-6.0.5.tgz", "integrity": "sha512-b1O07XYq8eRuVzBNgJLstU6FYc1tS6wnMtF1I1D9lE8LxZSOGZ7LhxN54yPP6mGw5f2CkXY2BQUL9Fx41qvcIg==",- "license": "MIT", "dependencies": { "basic-ftp": "^5.0.2", "data-uri-to-buffer": "^6.0.2",@@ -1143,13 +1111,13 @@ "version": "0.0.0", "resolved": "https://registry.npmjs.org/github-from-package/-/github-from-package-0.0.0.tgz", "integrity": "sha512-SyHy3T1v2NUXn29OsWdxmK6RwHD+vkj3v8en8AOBZ1wBQ/hCAQ5bAQTD02kW4W9tUp/3Qh6J8r9EvntiyCmOOw==",- "license": "MIT"+ "license": "MIT",+ "optional": true }, "node_modules/http-proxy-agent": { "version": "7.0.2", "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-7.0.2.tgz", "integrity": "sha512-T1gkAiYYDWYx3V5Bmyu7HcfcvL7mUrTWiM6yOfa3PIphViJ/gFPbvidQ+veqSOHci/PxBcDabeUNCzpOODJZig==",- "license": "MIT", "dependencies": { "agent-base": "^7.1.0", "debug": "^4.3.4"@@ -1162,7 +1130,6 @@ "version": "7.0.6", "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-7.0.6.tgz", "integrity": "sha512-vK9P5/iUfdl95AI+JVyUuIcVtd4ofvtrOr3HNtM2yxC9bnMbEdp3x01OhQNnjb8IJYi38VlTE3mBXwcfvywuSw==",- "license": "MIT", "dependencies": { "agent-base": "^7.1.2", "debug": "4"@@ -1189,7 +1156,8 @@ "url": "https://feross.org/support" } ],- "license": "BSD-3-Clause"+ "license": "BSD-3-Clause",+ "optional": true }, "node_modules/import-fresh": { "version": "3.3.1",@@ -1211,19 +1179,20 @@ "version": "2.0.4", "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==",- "license": "ISC"+ "license": "ISC",+ "optional": true }, "node_modules/ini": { "version": "1.3.8", "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz", "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==",- "license": "ISC"+ "license": "ISC",+ "optional": true }, "node_modules/ip-address": {- "version": "10.1.0",- "resolved": "https://registry.npmjs.org/ip-address/-/ip-address-10.1.0.tgz",- "integrity": "sha512-XXADHxXmvT9+CRxhXg56LJovE+bmWnEWB78LB83VZTprKTmaC5QfruXocxzTZ2Kl0DNwKuBdlIhjL8LeY8Sf8Q==",- "license": "MIT",+ "version": "10.2.0",+ "resolved": "https://registry.npmjs.org/ip-address/-/ip-address-10.2.0.tgz",+ "integrity": "sha512-/+S6j4E9AHvW9SWMSEY9Xfy66O5PWvVEJ08O0y5JGyEKQpojb0K0GKpz/v5HJ/G0vi3D2sjGK78119oXZeE0qA==", "engines": { "node": ">= 12" }@@ -1238,7 +1207,6 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==",- "license": "MIT", "engines": { "node": ">=8" }@@ -1273,6 +1241,7 @@ "integrity": "sha512-VPD8mtVtm5JNtA2AErl6Chp06JBfy7diFQ7TQQhdpWOl6MrCRB+eRbvAZUsbGQS9kiMq0coJsy0W0vHpDCkWsQ==", "hasInstallScript": true, "license": "MIT",+ "optional": true, "dependencies": { "node-addon-api": "^4.3.0", "prebuild-install": "^7.0.1"@@ -1288,7 +1257,6 @@ "version": "7.18.3", "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-7.18.3.tgz", "integrity": "sha512-jumlc0BIUrS3qJGgIkWZsyfAM7NCWiBcCDhnd+3NNM5KbBmLTgHVfWBcg6W+rLUsIpzpERPsvwUP7CckAQSOoA==",- "license": "ISC", "engines": { "node": ">=12" }@@ -1298,6 +1266,7 @@ "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-3.1.0.tgz", "integrity": "sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ==", "license": "MIT",+ "optional": true, "engines": { "node": ">=10" },@@ -1310,6 +1279,7 @@ "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==", "license": "MIT",+ "optional": true, "funding": { "url": "https://github.com/sponsors/ljharb" }@@ -1317,32 +1287,31 @@ "node_modules/mitt": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/mitt/-/mitt-3.0.1.tgz",- "integrity": "sha512-vKivATfr97l2/QBCYAkXYDbrIWPM2IIKEl7YPhjCvKlG3kE2gm+uBo6nEXK3M5/Ffh/FLpKExzOQ3JJoJGFKBw==",- "license": "MIT"+ "integrity": "sha512-vKivATfr97l2/QBCYAkXYDbrIWPM2IIKEl7YPhjCvKlG3kE2gm+uBo6nEXK3M5/Ffh/FLpKExzOQ3JJoJGFKBw==" }, "node_modules/mkdirp-classic": { "version": "0.5.3", "resolved": "https://registry.npmjs.org/mkdirp-classic/-/mkdirp-classic-0.5.3.tgz", "integrity": "sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A==",- "license": "MIT"+ "license": "MIT",+ "optional": true }, "node_modules/ms": { "version": "2.1.3", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",- "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==",- "license": "MIT"+ "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" }, "node_modules/napi-build-utils": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/napi-build-utils/-/napi-build-utils-2.0.0.tgz", "integrity": "sha512-GEbrYkbfF7MoNaoh2iGG84Mnf/WZfB0GdGEsM8wz7Expx/LlWf5U8t9nvJKXSp3qr5IsEbK04cBGhol/KwOsWA==",- "license": "MIT"+ "license": "MIT",+ "optional": true }, "node_modules/netmask": {- "version": "2.0.2",- "resolved": "https://registry.npmjs.org/netmask/-/netmask-2.0.2.tgz",- "integrity": "sha512-dBpDMdxv9Irdq66304OLfEmQ9tbNRFnFTuZiLo+bD+r332bBmMJ8GBLXklIXXgxd3+v9+KUnZaUR5PJMa75Gsg==",- "license": "MIT",+ "version": "2.1.1",+ "resolved": "https://registry.npmjs.org/netmask/-/netmask-2.1.1.tgz",+ "integrity": "sha512-eonl3sLUha+S1GzTPxychyhnUzKyeQkZ7jLjKrBagJgPla13F+uQ71HgpFefyHgqrjEbCPkDArxYsjY8/+gLKA==", "engines": { "node": ">= 0.4.0" }@@ -1352,6 +1321,7 @@ "resolved": "https://registry.npmjs.org/node-abi/-/node-abi-3.90.0.tgz", "integrity": "sha512-pZNQT7UnYlMwMBy5N1lV5X/YLTbZM5ncytN3xL7CHEzhDN8uVe0u55yaPUJICIJjaCW8NrM5BFdqr7HLweStNA==", "license": "MIT",+ "optional": true, "dependencies": { "semver": "^7.3.5" },@@ -1363,7 +1333,8 @@ "version": "4.3.0", "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-4.3.0.tgz", "integrity": "sha512-73sE9+3UaLYYFmDsFZnqCInzPyh3MqIwZO9cw58yIqAZhONrrabrYyYe3TuIqtIiOuTXVhsGau8hcrhhwSsDIQ==",- "license": "MIT"+ "license": "MIT",+ "optional": true }, "node_modules/once": { "version": "1.4.0",@@ -1378,7 +1349,6 @@ "version": "7.2.0", "resolved": "https://registry.npmjs.org/pac-proxy-agent/-/pac-proxy-agent-7.2.0.tgz", "integrity": "sha512-TEB8ESquiLMc0lV8vcd5Ql/JAKAoyzHFXaStwjkzpOpC5Yv+pIzLfHvjTSdf3vpa2bMiUQrg9i6276yn8666aA==",- "license": "MIT", "dependencies": { "@tootallnate/quickjs-emscripten": "^0.23.0", "agent-base": "^7.1.2",@@ -1397,7 +1367,6 @@ "version": "7.0.1", "resolved": "https://registry.npmjs.org/pac-resolver/-/pac-resolver-7.0.1.tgz", "integrity": "sha512-5NPgf87AT2STgwa2ntRMr45jTKrYBGkVU36yT0ig/n/GMAa3oPqhZfIQ2kMEimReg0+t9kZViDVZ83qfVUlckg==",- "license": "MIT", "dependencies": { "degenerator": "^5.0.0", "netmask": "^2.0.2"@@ -1439,8 +1408,7 @@ "node_modules/pend": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/pend/-/pend-1.2.0.tgz",- "integrity": "sha512-F3asv42UuXchdzt+xXqfW1OGlVBe+mxa2mqI0pg5yAHZPvFmY3Y6drSf/GQ1A86WgWEN9Kzh/WrgKa6iGcHXLg==",- "license": "MIT"+ "integrity": "sha512-F3asv42UuXchdzt+xXqfW1OGlVBe+mxa2mqI0pg5yAHZPvFmY3Y6drSf/GQ1A86WgWEN9Kzh/WrgKa6iGcHXLg==" }, "node_modules/picocolors": { "version": "1.1.1",@@ -1454,6 +1422,7 @@ "integrity": "sha512-8Mf2cbV7x1cXPUILADGI3wuhfqWvtiLA1iclTDbFRZkgRQS0NqsPZphna9V+HyTEadheuPmjaJMsbzKQFOzLug==", "deprecated": "No longer maintained. Please contact the author of the relevant native addon; alternatives are available.", "license": "MIT",+ "optional": true, "dependencies": { "detect-libc": "^2.0.0", "expand-template": "^2.0.3",@@ -1480,6 +1449,7 @@ "resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-2.1.4.tgz", "integrity": "sha512-mDAjwmZdh7LTT6pNleZ05Yt65HC3E+NiQzl672vQG38jIrehtJk/J3mNwIg+vShQPcLF/LV7CMnDW6vjj6sfYQ==", "license": "MIT",+ "optional": true, "dependencies": { "chownr": "^1.1.1", "mkdirp-classic": "^0.5.2",@@ -1492,6 +1462,7 @@ "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-2.2.0.tgz", "integrity": "sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ==", "license": "MIT",+ "optional": true, "dependencies": { "bl": "^4.0.3", "end-of-stream": "^1.4.1",@@ -1507,7 +1478,6 @@ "version": "2.0.3", "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz", "integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==",- "license": "MIT", "engines": { "node": ">=0.4.0" }@@ -1516,7 +1486,6 @@ "version": "6.5.0", "resolved": "https://registry.npmjs.org/proxy-agent/-/proxy-agent-6.5.0.tgz", "integrity": "sha512-TmatMXdr2KlRiA2CyDu8GqR8EjahTG3aY3nXjdzFyoZbmB8hrBsTyMezhULIXKnC0jpfjlmiZ3+EaCzoInSu/A==",- "license": "MIT", "dependencies": { "agent-base": "^7.1.2", "debug": "^4.3.4",@@ -1534,8 +1503,7 @@ "node_modules/proxy-from-env": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz",- "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==",- "license": "MIT"+ "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==" }, "node_modules/pump": { "version": "3.0.4",@@ -1548,18 +1516,17 @@ } }, "node_modules/puppeteer": {- "version": "24.39.1",- "resolved": "https://registry.npmjs.org/puppeteer/-/puppeteer-24.39.1.tgz",- "integrity": "sha512-68Zc9QpcVvfxp2C+3UL88TyUogEAn5tSylXidbEuEXvhiqK1+v65zeBU5ubinAgEHMGr3dcSYqvYrGtdzsPI3w==",+ "version": "24.43.1",+ "resolved": "https://registry.npmjs.org/puppeteer/-/puppeteer-24.43.1.tgz",+ "integrity": "sha512-/FSOViCrqRdb1HDocpsM9Z1giA71gTQPUt3SpHGVRALKAy/rJr1fLFYZW9F23qPxqVxTHQnbh/5B5opJST3kAw==", "hasInstallScript": true,- "license": "Apache-2.0", "dependencies": {- "@puppeteer/browsers": "2.13.0",+ "@puppeteer/browsers": "2.13.2", "chromium-bidi": "14.0.0", "cosmiconfig": "^9.0.0",- "devtools-protocol": "0.0.1581282",- "puppeteer-core": "24.39.1",- "typed-query-selector": "^2.12.1"+ "devtools-protocol": "0.0.1608973",+ "puppeteer-core": "24.43.1",+ "typed-query-selector": "^2.12.2" }, "bin": { "puppeteer": "lib/cjs/puppeteer/node/cli.js"@@ -1569,18 +1536,17 @@ } }, "node_modules/puppeteer-core": {- "version": "24.39.1",- "resolved": "https://registry.npmjs.org/puppeteer-core/-/puppeteer-core-24.39.1.tgz",- "integrity": "sha512-AMqQIKoEhPS6CilDzw0Gd1brLri3emkC+1N2J6ZCCuY1Cglo56M63S0jOeBZDQlemOiRd686MYVMl9ELJBzN3A==",- "license": "Apache-2.0",+ "version": "24.43.1",+ "resolved": "https://registry.npmjs.org/puppeteer-core/-/puppeteer-core-24.43.1.tgz",+ "integrity": "sha512-T5ScUMAsmhdNbgDR41AGESYeS6V9MSgetkSnVhhW+gXvzC42VesKCn5ld87gAZDJ6vLHL9GkRvY9WtQWSnwFbw==", "dependencies": {- "@puppeteer/browsers": "2.13.0",+ "@puppeteer/browsers": "2.13.2", "chromium-bidi": "14.0.0", "debug": "^4.4.3",- "devtools-protocol": "0.0.1581282",- "typed-query-selector": "^2.12.1",+ "devtools-protocol": "0.0.1608973",+ "typed-query-selector": "^2.12.2", "webdriver-bidi-protocol": "0.4.1",- "ws": "^8.19.0"+ "ws": "^8.20.0" }, "engines": { "node": ">=18"@@ -1591,6 +1557,7 @@ "resolved": "https://registry.npmjs.org/rc/-/rc-1.2.8.tgz", "integrity": "sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==", "license": "(BSD-2-Clause OR MIT OR Apache-2.0)",+ "optional": true, "dependencies": { "deep-extend": "^0.6.0", "ini": "~1.3.0",@@ -1606,6 +1573,7 @@ "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", "license": "MIT",+ "optional": true, "dependencies": { "inherits": "^2.0.3", "string_decoder": "^1.1.1",@@ -1619,7 +1587,6 @@ "version": "2.1.1", "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==",- "license": "MIT", "engines": { "node": ">=0.10.0" }@@ -1651,7 +1618,8 @@ "url": "https://feross.org/support" } ],- "license": "MIT"+ "license": "MIT",+ "optional": true }, "node_modules/semver": { "version": "7.7.4",@@ -1671,6 +1639,7 @@ "integrity": "sha512-Ou9I5Ft9WNcCbXrU9cMgPBcCK8LiwLqcbywW3t4oDV37n1pzpuNLsYiAV8eODnjbtQlSDwZ2cUEeQz4E54Hltg==", "hasInstallScript": true, "license": "Apache-2.0",+ "optional": true, "dependencies": { "@img/colour": "^1.0.0", "detect-libc": "^2.1.2",@@ -1727,7 +1696,8 @@ "url": "https://feross.org/support" } ],- "license": "MIT"+ "license": "MIT",+ "optional": true }, "node_modules/simple-get": { "version": "4.0.1",@@ -1748,6 +1718,7 @@ } ], "license": "MIT",+ "optional": true, "dependencies": { "decompress-response": "^6.0.0", "once": "^1.3.1",@@ -1758,19 +1729,17 @@ "version": "4.2.0", "resolved": "https://registry.npmjs.org/smart-buffer/-/smart-buffer-4.2.0.tgz", "integrity": "sha512-94hK0Hh8rPqQl2xXc3HsaBoOXKV20MToPkcXvwbISWLEs+64sBq5kFgn2kJDHb1Pry9yrP0dxrCI9RRci7RXKg==",- "license": "MIT", "engines": { "node": ">= 6.0.0", "npm": ">= 3.0.0" } }, "node_modules/socks": {- "version": "2.8.7",- "resolved": "https://registry.npmjs.org/socks/-/socks-2.8.7.tgz",- "integrity": "sha512-HLpt+uLy/pxB+bum/9DzAgiKS8CX1EvbWxI4zlmgGCExImLdiad2iCwXT5Z4c9c3Eq8rP2318mPW2c+QbtjK8A==",- "license": "MIT",+ "version": "2.8.9",+ "resolved": "https://registry.npmjs.org/socks/-/socks-2.8.9.tgz",+ "integrity": "sha512-LJhUYUvItdQ0LkJTmPeaEObWXAqFyfmP85x0tch/ez9cahmhlBBLbIqDFnvBnUJGagb0JbIQrkBs1wJ+yRYpEw==", "dependencies": {- "ip-address": "^10.0.1",+ "ip-address": "^10.1.1", "smart-buffer": "^4.2.0" }, "engines": {@@ -1782,7 +1751,6 @@ "version": "8.0.5", "resolved": "https://registry.npmjs.org/socks-proxy-agent/-/socks-proxy-agent-8.0.5.tgz", "integrity": "sha512-HehCEsotFqbPW9sJ8WVYB6UbmIMv7kUUORIF2Nncq4VQvBfNBLibW9YZR5dlYCSUhwcD628pRllm7n+E+YTzJw==",- "license": "MIT", "dependencies": { "agent-base": "^7.1.2", "debug": "^4.3.4",@@ -1796,17 +1764,15 @@ "version": "0.6.1", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",- "license": "BSD-3-Clause", "optional": true, "engines": { "node": ">=0.10.0" } }, "node_modules/streamx": {- "version": "2.23.0",- "resolved": "https://registry.npmjs.org/streamx/-/streamx-2.23.0.tgz",- "integrity": "sha512-kn+e44esVfn2Fa/O0CPFcex27fjIL6MkVae0Mm6q+E6f0hWv578YCERbv+4m02cjxvDsPKLnmxral/rR6lBMAg==",- "license": "MIT",+ "version": "2.28.0",+ "resolved": "https://registry.npmjs.org/streamx/-/streamx-2.28.0.tgz",+ "integrity": "sha512-1Yowhzjf0ivGMrTIkY9hav5TxobO9qIVqUE41fiCGMGgc3CLlf4MY+9AHmZqBWgDTue0fY9zWjYFVyf6Diuobw==", "dependencies": { "events-universal": "^1.0.0", "fast-fifo": "^1.3.2",@@ -1818,6 +1784,7 @@ "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", "license": "MIT",+ "optional": true, "dependencies": { "safe-buffer": "~5.2.0" }@@ -1826,7 +1793,6 @@ "version": "4.2.3", "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==",- "license": "MIT", "dependencies": { "emoji-regex": "^8.0.0", "is-fullwidth-code-point": "^3.0.0",@@ -1840,7 +1806,6 @@ "version": "6.0.1", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==",- "license": "MIT", "dependencies": { "ansi-regex": "^5.0.1" },@@ -1853,15 +1818,15 @@ "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", "integrity": "sha512-4gB8na07fecVVkOI6Rs4e7T6NOTki5EmL7TUduTs6bu3EdnSycntVJ4re8kgZA+wx9IueI2Y11bfbgwtzuE0KQ==", "license": "MIT",+ "optional": true, "engines": { "node": ">=0.10.0" } }, "node_modules/tar-fs": {- "version": "3.1.2",- "resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-3.1.2.tgz",- "integrity": "sha512-QGxxTxxyleAdyM3kpFs14ymbYmNFrfY+pHj7Z8FgtbZ7w2//VAgLMac7sT6nRpIHjppXO2AwwEOg0bPFVRcmXw==",- "license": "MIT",+ "version": "3.1.3",+ "resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-3.1.3.tgz",+ "integrity": "sha512-/hU4AXnIdZu+Gvl1pk0oI5f5HxWsCJRtY2aFaJdk9VvyL48DWU6iU5WAIPG+wIi1YvWA6eTJvIviP/tMAZZNwQ==", "dependencies": { "pump": "^3.0.0", "tar-stream": "^3.1.5"@@ -1872,10 +1837,9 @@ } }, "node_modules/tar-stream": {- "version": "3.1.8",- "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-3.1.8.tgz",- "integrity": "sha512-U6QpVRyCGHva435KoNWy9PRoi2IFYCgtEhq9nmrPPpbRacPs9IH4aJ3gbrFC8dPcXvdSZ4XXfXT5Fshbp2MtlQ==",- "license": "MIT",+ "version": "3.2.0",+ "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-3.2.0.tgz",+ "integrity": "sha512-ojzvCvVaNp6aOTFmG7jaRD0meowIAuPc3cMMhSgKiVWws1GyHbGd/xvnyuRKcKlMpt3qvxx6r0hreCNITP9hIg==", "dependencies": { "b4a": "^1.6.4", "bare-fs": "^4.5.5",@@ -1887,7 +1851,6 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/teex/-/teex-1.0.1.tgz", "integrity": "sha512-eYE6iEI62Ni1H8oIa7KlDU6uQBtqr4Eajni3wX7rpfXD8ysFx8z0+dri+KWEPWpBsxXfxu58x/0jvTVT1ekOSg==",- "license": "MIT", "dependencies": { "streamx": "^2.12.5" }@@ -1896,7 +1859,6 @@ "version": "1.2.7", "resolved": "https://registry.npmjs.org/text-decoder/-/text-decoder-1.2.7.tgz", "integrity": "sha512-vlLytXkeP4xvEq2otHeJfSQIRyWxo/oZGEbXrtEEF9Hnmrdly59sUbzZ/QgyWuLYHctCHxFF4tRQZNQ9k60ExQ==",- "license": "Apache-2.0", "dependencies": { "b4a": "^1.6.4" }@@ -1912,6 +1874,7 @@ "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", "integrity": "sha512-McnNiV1l8RYeY8tBgEpuodCC1mLUdbSN+CYBL7kJsJNInOP8UjDDEwdk6Mw60vdLLrr5NHKZhMAOSrR2NZuQ+w==", "license": "Apache-2.0",+ "optional": true, "dependencies": { "safe-buffer": "^5.0.1" },@@ -1920,35 +1883,32 @@ } }, "node_modules/typed-query-selector": {- "version": "2.12.1",- "resolved": "https://registry.npmjs.org/typed-query-selector/-/typed-query-selector-2.12.1.tgz",- "integrity": "sha512-uzR+FzI8qrUEIu96oaeBJmd9E7CFEiQ3goA5qCVgc4s5llSubcfGHq9yUstZx/k4s9dXHVKsE35YWoFyvEqEHA==",- "license": "MIT"+ "version": "2.12.2",+ "resolved": "https://registry.npmjs.org/typed-query-selector/-/typed-query-selector-2.12.2.tgz",+ "integrity": "sha512-EOPFbyIub4ngnEdqi2yOcNeDLaX/0jcE1JoAXQDDMIthap7FoN795lc/SHfIq2d416VufXpM8z/lD+WRm2gfOQ==" }, "node_modules/undici-types": {- "version": "7.18.2",- "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-7.18.2.tgz",- "integrity": "sha512-AsuCzffGHJybSaRrmr5eHr81mwJU3kjw6M+uprWvCXiNeN9SOGwQ3Jn8jb8m3Z6izVgknn1R0FTCEAP2QrLY/w==",- "license": "MIT",+ "version": "8.3.0",+ "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-8.3.0.tgz",+ "integrity": "sha512-j375ScV60dom+YkPFIfTLcOiPxkN/buHz5GobjLhixFuANaNs3C9l4GmrWqejgXWJ7BbJcFYpTEUkS1Ge8bpZQ==", "optional": true }, "node_modules/util-deprecate": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==",- "license": "MIT"+ "license": "MIT",+ "optional": true }, "node_modules/webdriver-bidi-protocol": { "version": "0.4.1", "resolved": "https://registry.npmjs.org/webdriver-bidi-protocol/-/webdriver-bidi-protocol-0.4.1.tgz",- "integrity": "sha512-ARrjNjtWRRs2w4Tk7nqrf2gBI0QXWuOmMCx2hU+1jUt6d00MjMxURrhxhGbrsoiZKJrhTSTzbIrc554iKI10qw==",- "license": "Apache-2.0"+ "integrity": "sha512-ARrjNjtWRRs2w4Tk7nqrf2gBI0QXWuOmMCx2hU+1jUt6d00MjMxURrhxhGbrsoiZKJrhTSTzbIrc554iKI10qw==" }, "node_modules/wrap-ansi": { "version": "7.0.0", "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==",- "license": "MIT", "dependencies": { "ansi-styles": "^4.0.0", "string-width": "^4.1.0",@@ -1968,10 +1928,9 @@ "license": "ISC" }, "node_modules/ws": {- "version": "8.19.0",- "resolved": "https://registry.npmjs.org/ws/-/ws-8.19.0.tgz",- "integrity": "sha512-blAT2mjOEIi0ZzruJfIhb3nps74PRWTCz1IjglWEEpQl5XS/UNama6u2/rjFkDDouqr4L67ry+1aGIALViWjDg==",- "license": "MIT",+ "version": "8.21.1",+ "resolved": "https://registry.npmjs.org/ws/-/ws-8.21.1.tgz",+ "integrity": "sha512-+0NTnW77fFN/DjQi6k/Sq/Yvk4Sgajw7urW8V+asjXnRgDs9gyGkdb7EzgfhA4goXsRIZKE28fzIXBHEzhuiWw==", "engines": { "node": ">=10.0.0" },@@ -1992,16 +1951,14 @@ "version": "5.0.8", "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==",- "license": "ISC", "engines": { "node": ">=10" } }, "node_modules/yargs": {- "version": "17.7.2",- "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz",- "integrity": "sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==",- "license": "MIT",+ "version": "17.7.3",+ "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.3.tgz",+ "integrity": "sha512-GZtjxm/J/4TSxuL3FNYjCmLktBTnIw/rVmKSIyKeYAZpmJB2ig9VauCC5xsa82GNKVKDAqpOn3KVzNt0zmrU0g==", "dependencies": { "cliui": "^8.0.1", "escalade": "^3.1.1",@@ -2019,7 +1976,6 @@ "version": "21.1.1", "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz", "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==",- "license": "ISC", "engines": { "node": ">=12" }@@ -2028,7 +1984,6 @@ "version": "2.10.0", "resolved": "https://registry.npmjs.org/yauzl/-/yauzl-2.10.0.tgz", "integrity": "sha512-p4a9I6X6nu6IhoGmBqAcbJy1mlC4j27vEPZX9F4L4/vZT3Lyq1VkFHw/V/PUcB9Buo+DG3iHkT0x3Qya58zc3g==",- "license": "MIT", "dependencies": { "buffer-crc32": "~0.2.3", "fd-slicer": "~1.1.0"@@ -2038,7 +1993,6 @@ "version": "3.25.76", "resolved": "https://registry.npmjs.org/zod/-/zod-3.25.76.tgz", "integrity": "sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ==",- "license": "MIT", "funding": { "url": "https://github.com/sponsors/colinhacks" }
src/package.json+1−1@@ -7,7 +7,7 @@ "start": "node server.js" }, "dependencies": {- "puppeteer": "^24.38.0"+ "puppeteer": "^24.43.1" }, "optionalDependencies": { "keytar": "^7.9.0",
src/server.js+164−10@@ -51,6 +51,50 @@ function runPsHiddenPromise(scriptPath, { timeout = 8000 } = {}) { }); }); }+// ── macOS window-management primitives (the darwin analogs of the Win32 helpers) ──+// Strategy on macOS: no cross-process per-window z-bottom API exists, and AppKit CLAMPS+// windows onto a visible screen (the -32000 off-screen launch trick doesn't hold). The+// reliable "background by default" primitive is the APP-LEVEL HIDE (the Cmd+H state):+// every pup session runs its own browser process (one per profile), so hiding that+// process hides exactly that session's windows — while CDP keeps driving + rendering+// them (--disable-backgrounding-occluded-windows), so screenshot/eval still work.+// Raise = unhide + activate. Driven via System Events (rides the Automation grant the+// embedding Adom Desktop already holds; a denied grant degrades to applied:false, never+// a throw). Hide is PER-PROCESS, so multi-session shared-profile windows hide/show as a+// group on mac — a documented DEGRADED vs the per-hwnd Windows path.+function runOsascript(script, { timeout = 6000 } = {}) {+ try { return execFileSync('/usr/bin/osascript', ['-e', script], { encoding: 'utf8', timeout }).trim(); }+ catch (e) { return null; }+}+function runOsascriptPromise(script, { timeout = 8000 } = {}) {+ return new Promise(resolve => {+ execFile('/usr/bin/osascript', ['-e', script], { encoding: 'utf8', timeout }, (err, stdout) => resolve(err ? null : (stdout || '').trim()));+ });+}+// Hide (true) / unhide (false) every window of a process. Resolves true if the script ran.+async function macSetAppHiddenByPid(pid, hidden) {+ if (!pid) return false;+ const r = await runOsascriptPromise(`tell application "System Events" to set visible of (first process whose unix id is ${Number(pid)}) to ${hidden ? 'false' : 'true'}`);+ return r !== null;+}+// Unhide + bring the process's windows to the foreground (the user-asked-to-watch path).+async function macActivateByPid(pid) {+ if (!pid) return false;+ await runOsascriptPromise(`tell application "System Events" to set visible of (first process whose unix id is ${Number(pid)}) to true`);+ const r = await runOsascriptPromise(`tell application "System Events" to set frontmost of (first process whose unix id is ${Number(pid)}) to true`);+ return r !== null;+}+// The pid that owns a session's browser (detached launches record it; puppeteer.launch+// exposes process()). Null when unresolvable — callers report applied:false.+function macSessionPid(session) {+ try {+ const be = browsers.get(session.profileName);+ const b = be && be.browser;+ if (!b) return null;+ return b._detachedPid || (b.process() && b.process().pid) || null;+ } catch (e) { return null; }+}+ const puppeteer = require('puppeteer'); const credentialVault = require('./credential_vault'); const chrome = require('./chrome'); // Chrome-for-Testing self-heal: detect / auto-install / readiness (cold-start fix)@@ -874,7 +918,8 @@ async function findChromesByProfile(profileName) { const result = spawnSync('ps', ['-eo', 'pid,command'], { encoding: 'utf8', timeout: 5_000 }); if (result.stdout) { for (const line of result.stdout.split('\n')) {- if (!line.includes('chrome')) continue;+ // Case-insensitive: mac system Chrome is ".../MacOS/Google Chrome" (no lowercase hit).+ if (!/chrome|msedge|Microsoft Edge/i.test(line)) continue; if (/--type=/.test(line)) continue; const portMatch = line.match(/--remote-debugging-port=(\d+)/); if (!portMatch) continue;@@ -1158,7 +1203,8 @@ async function rescanAllProfiles({ adoptOrphans = false } = {}) { if (result.stdout) { const seen = new Set(); for (const line of result.stdout.split('\n')) {- if (!line.includes('chrome')) continue;+ // Case-insensitive: mac system Chrome is ".../MacOS/Google Chrome" (no lowercase hit).+ if (!/chrome|msedge|Microsoft Edge/i.test(line)) continue; if (line.includes('--type=')) continue; if (!line.includes('remote-debugging-port')) continue; if (!line.includes(PROFILES_DIR)) continue;@@ -2807,6 +2853,13 @@ async function osRaiseSessionWindow(session, sessionId) { try { await session.page.evaluate(() => { const a = document.activeElement; if (a && a.blur) a.blur(); }); } catch (e) {} try { await session.page.bringToFront(); } catch (e) {} session._foreground = true;+ if (process.platform === 'darwin') {+ // macOS: unhide + activate the session's browser process (the CDP part above sized it).+ const pid = macSessionPid(session);+ const ok = await macActivateByPid(pid);+ console.log(`[foreground] "${sessionId}" mac activate pid=${pid} → ${ok}`);+ return;+ } if (process.platform !== 'win32') return; // v1.9.66 — RAISE BY HWND. The CDP-only path above (setWindowBounds + bringToFront) happens to // surface a CHROME window, but it does NOT raise an EDGE one: bringToFront activates the TAB@@ -3775,6 +3828,43 @@ setInterval(() => { }, 30000); async function parkSessionWindowDirect(page, sessionId) {+ // ── macOS park ── the whole background contract is one primitive: (re-)hide the+ // session's browser process. The window was born hidden (pre-window hide in+ // tryDetachedLaunch); here we size it full-screen via CDP while STILL hidden — so a+ // later raise shows a properly-sized window — then re-assert the hide and verify.+ // No z-order machinery: a hidden app has no on-screen windows to cover the user.+ if (process.platform === 'darwin') {+ try {+ // The session may not be registered in `sessions` yet at launch-park time — resolve+ // the pid from the page's OWN browser (detached pid, else puppeteer's child process).+ let pid = null;+ try { const b = page.browser(); pid = b._detachedPid || (b.process() && b.process().pid) || null; } catch (e) {}+ if (!pid) { const session = sessions.get(sessionId); pid = session ? macSessionPid(session) : null; }+ try {+ const cdp2 = await page.target().createCDPSession();+ const { windowId } = await cdp2.send('Browser.getWindowForTarget');+ let s = null;+ for (let i = 0; i < 4 && !s; i++) {+ s = await page.evaluate(() => ({ w: screen.availWidth, h: screen.availHeight })).catch(() => null);+ if (s && !(s.w > 400 && s.h > 300)) s = null;+ if (!s) await new Promise(r2 => setTimeout(r2, 300));+ }+ await cdp2.send('Browser.setWindowBounds', { windowId, bounds: { windowState: 'normal' } });+ if (s) await cdp2.send('Browser.setWindowBounds', { windowId, bounds: { left: 0, top: 0, width: Math.round(s.w), height: Math.round(s.h) } });+ try { await cdp2.detach(); } catch (e) {}+ } catch (e) {}+ if (!pid) { console.log(`[park] "${sessionId}": no pid to hide (mac) — park-failed`); return 'park-failed'; }+ const hidden = await macSetAppHiddenByPid(pid, true);+ if (!hidden) {+ console.log(`[park] "${sessionId}": mac hide failed (System Events denied? grant Automation to Adom Desktop) — park-failed`);+ return 'park-failed';+ }+ return 'backgrounded';+ } catch (e) {+ console.error(`[park] ${sessionId} (mac): ${e.message}`);+ return 'error';+ }+ } if (process.platform !== 'win32') return null; let cdp = null; try {@@ -4507,6 +4597,16 @@ async function getOrLaunchBrowser(profileName, { freshProfile = false, strictPer b._bgResult = 'parking'; b._needsPark = true; }+ if (!foreground && process.platform === 'darwin') {+ // macOS background-by-default: hide the app NOW, while --no-startup-window means it+ // has no window yet — windows created by a hidden app are born hidden, so the launch+ // is truly invisible (AppKit clamps the -32000 off-screen coords, so only the hide+ // covers the gap here). The park then sizes the window + re-asserts the hide.+ b._bgResult = 'parking';+ b._needsPark = true;+ b._macHidden = await macSetAppHiddenByPid(child.pid, true);+ if (!b._macHidden) console.log(`[launch] mac pre-window hide failed for pid ${child.pid} (Automation grant missing?) — park will retry`);+ } return b; }; @@ -4514,7 +4614,9 @@ async function getOrLaunchBrowser(profileName, { freshProfile = false, strictPer // attempts each (with orphan/lock cleanup between attempts). If a browser can't // actually spawn (corrupt install, wrong arch, locked), fall THROUGH to the next // candidate rather than failing the open. First one that launches wins + is cached.- const isWinDetached = process.platform === 'win32' && userDataDir;+ // v1.9.74: the detached launch runs on macOS too (same --no-startup-window contract;+ // the mac park is the app-level hide instead of the off-screen/z-bottom dance).+ const isDetachedLaunch = (process.platform === 'win32' || process.platform === 'darwin') && userDataDir; const MAX_ATTEMPTS = 3; let lastErr = null; let chosen = null;@@ -4529,7 +4631,7 @@ async function getOrLaunchBrowser(profileName, { freshProfile = false, strictPer lastErr = null; for (let attempt = 1; attempt <= MAX_ATTEMPTS; attempt++) { try {- if (isWinDetached) {+ if (isDetachedLaunch) { browser = await tryDetachedLaunch(attempt, cand.executablePath); } else { browser = await puppeteer.launch(launchOpts);@@ -4563,7 +4665,7 @@ async function getOrLaunchBrowser(profileName, { freshProfile = false, strictPer // v1.8.71 (#202): a BRANDED-browser launch means CfT wasn't cached — kick a background // CfT install (once per bridge process) so this box converges to the deterministic // CfT-first order by its next session. Never blocks or stalls the current open.- if (chosen.kind !== 'chrome-for-testing' && !global._cftPrewarmKicked && process.platform === 'win32') {+ if (chosen.kind !== 'chrome-for-testing' && !global._cftPrewarmKicked && (process.platform === 'win32' || process.platform === 'darwin')) { global._cftPrewarmKicked = true; try { console.log(`[prewarm] branded fallback (${chosen.kind}) — starting background CfT install so future opens use Chrome for Testing`);@@ -4801,7 +4903,7 @@ async function launchSession(sessionId, url, { freshProfile = false, profile, st // full-size, z-bottomed, and z-confirmed. Only for a freshly launched browser (_needsPark) — // a reused window is already placed, and re-parking it could hide a window the user has up. const kickoffPark = () => {- if (foreground || process.platform !== 'win32') return;+ if (foreground || (process.platform !== 'win32' && process.platform !== 'darwin')) return; try { const be = browsers.get(profileName); if (be && be.browser && be.browser._needsPark) {@@ -6523,6 +6625,32 @@ const server = http.createServer(async (req, res) => { const session = sessions.get(sessionId); try { const stop = !!(args.stop || args.clear);+ // ── macOS ── there is no taskbar to flash and macOS has no API to bounce ANOTHER+ // app's Dock tile. The mac analog: unhide the window at its z-position (visible but+ // NOT focused — the non-intrusive nudge) + a native AD toast whose click focuses it.+ // {stop} dismisses the toast.+ if (process.platform === 'darwin') {+ const sid = session._sessionId || sessionId;+ const toastId = `pup-alert-${sid}`;+ let applied = false;+ if (stop) {+ try { const r2 = await chrome.adCommand('notify_dismiss', { id: toastId }, { timeoutMs: 5000 }); applied = !!r2; } catch (e) {}+ sendJSON(res, { success: true, output: JSON.stringify({ ok: true, sessionId, alerted: false, cleared: applied, applied, clearMethod: applied ? 'toast-dismissed' : null, _hint: applied ? 'Alert toast dismissed.' : 'No toast to dismiss (or AD unreachable).' }) });+ return;+ }+ try { await macSetAppHiddenByPid(macSessionPid(session), false); } catch (e) {}+ try {+ const r2 = await chrome.adCommand('notify_user', {+ id: toastId, level: 'info', scenario: 'reminder',+ title: 'A pup window wants your attention',+ body: `Session "${sid}" has something to show — click to bring it up.`,+ focus: { titleContains: `(session: ${sid}` },+ }, { timeoutMs: 6000 });+ applied = !!(r2 && r2.success !== false);+ } catch (e) {}+ sendJSON(res, { success: true, output: JSON.stringify({ ok: true, sessionId, alerted: true, cleared: false, applied, clearMethod: null, _hint: applied ? 'macOS nudge: window un-hidden (not focused) + a native toast posted — its click focuses the window. Pass {stop:true} to dismiss the toast.' : 'Window un-hidden, but the AD toast could not be posted (AD unreachable or notify unsupported).' }) });+ return;+ } // v1.8.43: route the FLASH through AD's desktop_flash_window (reliable, native). const r = await flashViaAD(session._sessionId || sessionId, { stop }); let applied = false;@@ -6566,7 +6694,14 @@ const server = http.createServer(async (req, res) => { // a deliberate re-park, so clear the user-foreground latch too. const be = browsers.get(session.profileName); if (be && be.browser) be.browser._userForeground = false;- const ok = (be && be.browser) ? (osBackgroundWindowByPid(be.browser._detachedPid, be.browser._cdpPort, be.browser._priorForeground) === 'backgrounded') : osSendWindowToBack(session.profileName);+ let ok;+ if (process.platform === 'darwin') {+ // macOS lower = hide the session's browser process (still fully drivable — CDP+ // keeps rendering hidden windows). Per-process, so shared-profile siblings hide too.+ ok = await macSetAppHiddenByPid(macSessionPid(session), true);+ } else {+ ok = (be && be.browser) ? (osBackgroundWindowByPid(be.browser._detachedPid, be.browser._cdpPort, be.browser._priorForeground) === 'backgrounded') : osSendWindowToBack(session.profileName);+ } session._foreground = false; sendJSON(res, { success: true, output: JSON.stringify({ ok: true, sessionId, placement: 'background', applied: ok, _hint: 'Window sent behind the user\'s windows (still drivable/screenshottable). Keep pup in the background unless the user asked to watch.' }) }); return;@@ -6635,6 +6770,13 @@ const server = http.createServer(async (req, res) => { // handing the hwnd to AD, because backgrounded pup windows carry WS_EX_NOACTIVATE — structurally // unable to take focus until that style is CLEARED, which is exactly what Raise() does. let _raisedByHwnd = false;+ if (process.platform === 'darwin') {+ // macOS raise = unhide the session's process + make it frontmost. The CDP+ // bounds/maximize above already sized it; System Events does the activation.+ const pid = macSessionPid(session);+ _raisedByHwnd = await macActivateByPid(pid);+ console.log(`[foreground] "${sessionId}" mac activate pid=${pid} → ${_raisedByHwnd}`);+ } if (process.platform === 'win32') { try { const fw = adPayload(await chrome.adCommand('desktop_find_window', { titleContains: `(session: ${sessionId}` }, { timeoutMs: 5000 }));@@ -8361,7 +8503,19 @@ function detectFFmpeg() { const r = spawnSync('ffmpeg', ['-version'], { stdio: ['ignore', 'pipe', 'ignore'] }); if (r.status === 0) { FFMPEG_PATH = 'ffmpeg'; return; } } catch {}- // 2. Common Windows install paths+ // 2. Common macOS install paths (Homebrew arm64/x64, MacPorts) — AD spawns the bridge+ // outside a login shell, so /opt/homebrew/bin is usually NOT on PATH here.+ if (process.platform === 'darwin') {+ for (const p of ['/opt/homebrew/bin/ffmpeg', '/usr/local/bin/ffmpeg', '/opt/local/bin/ffmpeg']) {+ try {+ if (fs.existsSync(p)) {+ const r = spawnSync(p, ['-version'], { stdio: ['ignore', 'pipe', 'ignore'] });+ if (r.status === 0) { FFMPEG_PATH = p; return; }+ }+ } catch {}+ }+ }+ // 3. Common Windows install paths if (process.platform === 'win32') { const candidates = [ 'C:\\Program Files\\ffmpeg\\bin\\ffmpeg.exe',@@ -8407,7 +8561,7 @@ function detectFFmpeg() { } detectFFmpeg(); if (FFMPEG_PATH) console.log(`[recorder] ffmpeg available at: ${FFMPEG_PATH}`);-else console.warn(`[recorder] ffmpeg NOT FOUND — desktop WebMs will play fine but ffprobe format=duration will be N/A. Install via 'winget install Gyan.FFmpeg' to enable Duration metadata.`);+else console.warn(`[recorder] ffmpeg NOT FOUND — desktop WebMs will play fine but ffprobe format=duration will be N/A. Install via '${process.platform === 'darwin' ? 'brew install ffmpeg' : 'winget install Gyan.FFmpeg'}' to enable Duration metadata.`); /** * Remux a WebM file in place to add a SegmentDuration tag.@@ -8872,7 +9026,7 @@ async function tabRecordStartImpl({ }) { if (!FFMPEG_PATH) detectFFmpeg(); // lazy re-scan: ffmpeg may have been installed since the bridge started if (!FFMPEG_PATH) {- throw new Error('ffmpeg not found on Windows. Install it (winget install Gyan.FFmpeg), then just retry — the bridge re-detects it, no restart needed.');+ throw new Error(`ffmpeg not found. Install it (${process.platform === 'darwin' ? 'brew install ffmpeg' : 'winget install Gyan.FFmpeg'}), then just retry — the bridge re-detects it, no restart needed.`); } const session = sessions.get(sessionId);