← Commit history

v2.0.535 (insiders): Proven on AdomLapper: 20 of 20 vendor sites as tabs in ONE extension-lane window on adom-you, opened cold with plain pup_open_window + pup_open_tab (18 load; analog serves Access Denied and avnet an Akamai challenge); the window survives a pup restart by re-adoption (same hwnd, 20 tabs, one Chrome window); the identity button wears the user's avatar; parity 55/56 (pre-existing clearMethod drift in untouched code); ab-smoke ALL PASS on the default lane including login and download.

John Lauer ·5ad945ac81 ·1mo ago ·parent 3a85057
2 files changed +17−1
src/extension/manifest.json+2−1
@@ -15,7 +15,8 @@     "tabs",     "alarms",     "scripting",-    "system.display"+    "system.display",+    "downloads"   ],   "host_permissions": [     "<all_urls>",
src/extension/worker.js+15
@@ -239,6 +239,21 @@ async function pupExtPoll() {       const wins = await chrome.windows.getAll({});       for (const w of wins) { try { await chrome.windows.remove(w.id); } catch (e) {} }       out = { id: cmd.id, ok: true, closed: wins.length };+    } else if (cmd.action === 'download') {+      // chrome.downloads: the lane's download path (no CDP Browser.setDownloadBehavior here). Resolves when the+      // item completes, with its saved path and byte count, or fails with the interrupt reason.+      const opts = { url: cmd.url, conflictAction: 'uniquify' }; if (cmd.filename) opts.filename = cmd.filename;+      const id = await chrome.downloads.download(opts);+      const deadline = Date.now() + (cmd.waitMs || 30000);+      let item = null;+      while (Date.now() < deadline) {+        const items = await chrome.downloads.search({ id });+        item = items && items[0];+        if (item && (item.state === 'complete' || item.state === 'interrupted')) break;+        await new Promise((r) => setTimeout(r, 300));+      }+      if (!item || item.state !== 'complete') out = { id: cmd.id, ok: false, error: 'download ' + (item ? item.state + (item.error ? ': ' + item.error : '') : 'did not start') };+      else out = { id: cmd.id, ok: true, savedTo: item.filename, filename: (item.filename || '').split(/[\\/]/).pop(), bytes: item.fileSize || item.totalBytes || 0 };     } else if (cmd.action === 'fit') {       // Size the lane's window to the primary display's WORK AREA, normal state.       // Deliberately NOT chrome.windows.update({state:'maximized'}) and NOT ab's