← Commit history

2.0.408 on insiders: recovered tabs get their page scripts back; plan status

John Lauer ·2ae6a68f55 ·1mo ago ·parent fd4a72c
3 files changed +15−4
CHANGELOG.md+1−1
@@ -1,6 +1,6 @@ # Changelog — Puppeteer Bridge -## 2.0.407 — 2026-09-05 — pup as ONE Rust exe (spawn.kind exe): the Node runtime leaves the package+## 2.0.408 — 2026-09-05 — pup as ONE Rust exe (spawn.kind exe): the Node runtime leaves the package  The bridge package is now a single sha256-verified Windows binary (`adom-pup-bridge.exe`, about 4.6 MB) plus its manifest: no Node, no npm, no postinstall, no 90 MB of node_modules, so a first
docs/PLAN-rust-port.md+4−3
@@ -1,6 +1,6 @@ # pup in Rust: the port plan -**Status (2026-09-05, late night): SHIPPED TO INSIDERS as 2.0.407, the first Rust-exe build.** Phases 0+**Status (2026-09-05, late night): SHIPPED TO INSIDERS as 2.0.408, the first Rust-exe build (2.0.407 went first; 2.0.408 adds the recovered-tab script injection).** Phases 0 to 4 are done; the public tier stays on the Node build (2.0.396) until a Rust build is promoted on John's words. Written 2026-09-05 against pup 2.0.396; John approved the plan the same day ("lets get back to the plan").@@ -68,14 +68,15 @@ John's words. Written 2026-09-05 against pup 2.0.396; John approved the plan the   builds the Rust package by default (`--shell node` keeps the Node path) and gained `--candidate`   (everything except the insiders push; the manifest lands on the product page as   adom-bridge-puppeteer-manifest-candidate.json for ONE desktop to install) and-  `--insiders-from-candidate`. Seven candidates (2.0.401 to 2.0.407) went through ab's real+  `--insiders-from-candidate`. Eight candidates (2.0.401 to 2.0.408) went through ab's real   `bridge_install` path on winvm before insiders saw one; each found something: ab's relay computes   success from `success` and the CLI returns the parsed `output` alone (so every success now carries   both); the Node-era Chrome had no DevToolsActivePort file (recovery now reads the session file's   cdpPort); a window whose Chrome is gone must come back (relaunch from the file at boot and from   the health loop, twice at most, with `_cleanupReport`); a killed exe could lose the port for a   second (bind retry); panics now land in ~/.adom/bridge-logs/pup-rust-panic.log; the wiki's CSP-  blocks inline scripts in a pup_render_html document (hint added). Measured on 2.0.407 through ab:+  blocks inline scripts in a pup_render_html document (hint added); a window recovered across an+  update had lost its owner chip, floaty and login capture (recovered tabs get them back). Measured on 2.0.408 through ab:   `tools/parity.py --via-ab` 37 of 37, `tools/ab-smoke.sh` all pass (vault, cards, wiki auto-sign   and view flip, annotate, recording, recorder HUD, download, dashboard, taskbar identity),   exe kill then respawn with the window reattached, Chrome kill then every window relaunched, and
rust/verbs/src/recovery.rs+10
@@ -79,6 +79,16 @@ fn recover_one(ctx: &Ctx, file: &Value, h: &BrowserHandle, taken: &mut Vec<Strin     let hwnd = file["_hwnd"].as_i64().filter(|&h| h > 0 && ctx.host.is_alive(h))         .or_else(|| ctx.host.windows_for_pids(&[], Some("Chrome_WidgetWin_1")).into_iter().find(|w| ctx.host.has_tag(w.hwnd, &tag)).map(|w| w.hwnd));     if let Some(hh) = hwnd { s.hwnd = Some(hh); ctx.host.tag(hh, &tag); if !s.foreground { ctx.host.send_to_bottom_no_activate(hh); } }+    // A recovered tab is a fresh CDP session: give it what attach_tab gives a new one (the login+    // capture + floaty bindings, the owner chip, the floaty) or the window silently loses them+    // (measured 2026-09-05: no owner chip on a window recovered across the 2.0.407 update).+    if let Some(t) = s.tabs.last() {+        for name in ["__pupCredCapture", "__pupFloatyPush"] { let _ = h.cdp.send(Some(&t.cdp_session), "Runtime.addBinding", json!({ "name": name }), Duration::from_secs(5)); }+        let capture = crate::vault::capture_login_script();+        let _ = h.cdp.send(Some(&t.cdp_session), "Page.addScriptToEvaluateOnNewDocument", json!({ "source": capture }), Duration::from_secs(5));+        let _ = h.cdp.evaluate(&t.cdp_session, &capture, Duration::from_secs(5));+        crate::inject_page_scripts(ctx, &s, &h.cdp, &t.cdp_session);+    }     Some(s) }