Commit History

latest 1000 ← Back to Activity
Publish 1.9.166
John Lauer · 404f42b · 14d ago
Two fixes John flagged live. (1) STALE TASKBAR PROGRESS BAR ('i see you leave those stale quite often'): the busy-state idle-timer cleared by window title via desktop_taskbar, which SILENTLY FAILS if the window is not findable that instant (churned/leftover session) — leaving the OS bar lit while pup thinks it is off. Fixed: clearSessionBusy now explicitly turns the OS bar OFF on teardown, AND a 20s reconciler asserts progress:none for every live session that is not actively busy, so any stranded bar self-heals within the interval instead of lingering until John notices. (2) TOAST BEFORE FOREGROUND ('use an AD toast to get a human's attention' — told repeatedly): pup now auto-fires notify_user whenever it FOREGROUNDS a window (browser_raise_os_window grant + foreground:true open), debounced per session, with the foregroundReason as the body — so a window never appears on the user's screen silently again. Standing rule added to SKILL.md.
John Lauer · 9c53c7e · 14d ago
Publish 1.9.165
John Lauer · f1961e0 · 14d ago
Add the Adom logo badge to pup's in-page cursor (John: 'stick a tiny little adom logo next to the cursor so the user knows it is adom doing this, not Claude's browser extension'). The v1.9.164 cursor arrow now carries a small teal Adom orbital badge (the two-lobe hydrogen-2p mark + A) pinned to the pointer, so any user watching pup drive a foregrounded window can instantly tell it is ADOM controlling the mouse, not a browser extension. In-page only (pup's browser_click); the OS-level real-cursor overlay for AD's desktop_hover/desktop_click is being filed as an AD-core request.
John Lauer · 4c685e7 · 14d ago
pup-vendor-login: correctly record the FedCM breakthrough (prior push missed it on a text mismatch) — Google Sign-in-with-Google chooser rejects DOM/synthetic/page.mouse/UIA clicks; only a real desktop_hover THEN desktop_click works, hover mandatory. Proven signing John into Autodesk.
John Lauer · 08765a8 · 14d ago
Publish 1.9.164
John Lauer · 8111ea0 · 14d ago
pup-vendor-login: record the WINNING FedCM recipe — Google's Sign-in-with-Google account chooser rejects DOM/synthetic/page.mouse/UIA clicks; the only thing that works is a real OS cursor HOVER (desktop_hover) THEN desktop_click, the hover being what satisfies FedCM's user-activation check. Proven live signing John into Autodesk.
John Lauer · 2131ab4 · 14d ago
Visible animated cursor for pup's in-page clicks (John: 'you need the simulated mouse like what nb has so the user knows that you're controlling the mouse'). New showPupCursor injects a teal Adom pointer that GLIDES from its last position to the click target and PULSES a ring on click, via CDP so it rides on top of any page (pointer-events:none, max z-index, drop-shadow). browser_click now glides the cursor to the target (selector's bounding-rect center, or the x/y) and waits ~440ms before firing the real trusted click, so the user watching a foregrounded window sees pup drive the mouse just like the nbrowser extension's cursor. Default on; {showCursor:false} disables. Best-effort — a page that blocks injection just skips the visual, the click still fires. This is the in-page half (covers ~all vendor download-button clicking, John's hours-of-library-downloading use case); the OS-level cursor overlay for native dialogs / cross-origin FedCM surfaces (driven by AD's desktop_click) is an AD-core capability to be filed separately.
John Lauer · 4551a34 · 14d ago
Publish 1.9.163
John Lauer · 590afdf · 14d ago
Crash fix, part 1 — stop a single spammy page from hanging the shared Chrome and taking down every session. Root cause found in the code: (1) attachTab mirrored EVERY page console message via a synchronous console.log to the bridge's stdout — a heavy SPA (Autodesk's Kepler account portal, which repeatedly logs 'Auth is not yet ready to mount providers') floods the Node event loop with blocking writes and stalls CDP handling for ALL sessions (the measured HUNG-alive/CDP-DEAD signature); now rate-limited to ~8 console lines/sec per tab with a suppressed-count summary. (2) setupErrorCollection wired a requestfailed listener that enables the CDP Network domain, whose per-request event stream is a firehose on request-heavy SPAs and saturated pup's single shared CDP WebSocket; removed (network failures are rarely the actionable error; console.error + pageerror stay). (3) the per-tab errors array was uncapped and grew unbounded on a spammy page; now capped at 300. All three are per-page event floods over the one shared connection — exactly why one bad page jammed everything, which matters most now that ALL windows share one profile/process (1.9.162).
John Lauer · 770e0bb · 14d ago
Publish 1.9.162
John Lauer · b54d410 · 14d ago
Skills updated for the one-shared-profile model (v1.9.162): pup-adom-wiki now documents wiki-authed as the default sharing the adom-you jar (login accumulates everywhere) with wikiView:public as the explicit logged-out isolated view; pup-vendor-login notes one-shared-profile is the org default and per-vendor isolation is the opt-in safer option.
John Lauer · bffd6aa · 14d ago
ONE shared profile for ALL pup windows (John: 'i want all pup windows to use the same profile now so you have all of the users saved logins over time so the database of their logins builds up and this is pleasurable to use over time'). Every window — wiki AUTHED included — now uses the durable adom-you jar, so every login the user does anywhere (Google, Autodesk, Mouser, the wiki, anything) accumulates into one growing credential store that makes pup nicer the more it's used. The only windows that still get a separate jar are the three that definitionally require it: {webSecurity:false} (insecure per-process flags must never share the credentialed process), {isolated:true} (explicit fresh/throwaway jar for login tests or acting as another user), and the wiki PUBLIC view (logged-out by definition, needs a clean jar to show the world's view). The old separate adom-wiki-authed jar is retired for resolution; the view toggle now sends authed->the shared jar and public->an isolated logged-out jar. Accepted tradeoff, per John: one shared Chrome process means a crash takes all sessions down together (the crash-isolation the pup-vendor-login skill warned about is explicitly waived in favour of login accumulation).
John Lauer · 6fccd9f · 14d ago
Publish 1.9.161
John Lauer · 8685f22 · 14d ago
Correct pup-vendor-login: a fresh vendor login is NOT persisted until Chrome flushes it. Reaching the dashboard is not enough; a crash before flush destroys the sign-in (verified live: Autodesk came up signed OUT in a later window while Gmail survived). Mandate close+reopen+verify before claiming persistence; the admin-SPA crash makes this critical.
John Lauer · a01a6bc · 14d ago
Publish 1.9.160
John Lauer · 096b9c3 · 14d ago
Add pup-vendor-login sub-skill: how to sign a user into a vendor portal (Autodesk worked example) so the login persists — autonomous Continue-with-Google path, OAuth-popup handling, Google chooser trusted-click, dedicated-durable-profile crash isolation, and the hard CDP-jam limit on Autodesk's Kepler account-admin SPA. Learned live 2026-07-28.
John Lauer · a3ee5bd · 14d ago
Publish 1.9.159
John Lauer · f75cd10 · 14d ago
Remove --disable-blink-features=AutomationControlled — kills the yellow 'unsupported command-line flag: Stability and security will suffer' infobar John spotted on his Gmail window. Chain of causation, owned: 1.9.129 removed --test-type (ChromeDriver's hush-everything flag) to bring back the Save-Password bubble, which un-hushed this warning bar; the other two warning-triggering flags were removed in the same release, leaving AutomationControlled as the lone banner cause on every window since. It is also functionally redundant: that blink feature only activates via --enable-automation, which pup strips and never passes — navigator.webdriver reads false with the flag present (verified live pre-removal) and must read false after too, which the post-ship proof checks along with a clean top-of-window screenshot.
John Lauer · bead400 · 14d ago
Publish 1.9.158
John Lauer · db2d6b7 · 14d ago
Fix the two open defects from John's full sweep. (A) flashCount undercount: the launch flash fires 87 lines BEFORE sessions.set registers the session, so the counter's sessions.get() at flash time always missed — single-tab windows read flash:0 while the orange genuinely fired (the audit column John demanded caught its own instrumentation lying). The credit now happens at registration: if a launch flash was recorded for this sessionId within 60s, count it on the session object that now exists. (B) detached-frame armor: browser_eval caught 'Attempted to use detached Frame' and returned it as an __error RESULT instead of recovering — exactly how two sessions went permanently undrivable in the heavy run. A detached/closed handle is now a recovery signal: re-resolve the session's live page by window.name (the durable carrier from the recovery-binding fix), swap the tab's page reference, and retry the eval once; only if no live page carries pup:<sid> does it surface the error.
John Lauer · 4f6dfdc · 14d ago
Publish 1.9.157
John Lauer · 8417a5e · 14d ago
Serialize tab creation per profile — the real fix for the concurrent split (on-desk, John watching). Measured on 1.9.156: newPage() lands a tab in the session's OWN window every time single-threaded (2 tabs, 1 window, no split); the split ONLY occurs under concurrency, where interleaved newPage() calls on the shared durable profile race on Chrome's ambiguous active-window and a tab is born in the wrong window, which the drag-out handler then splits off. addTabToSession now funnels its newPage through the SAME _profileOpenChain that serializes browser_open_window (1.9.143), so tab creations on one profile run in arrival order and each tab is created against its session's settled window context. No window.open, no activateTarget, no OS foregrounding — just removing the interleave that caused it. Reverted 1.9.155's churny approach stays reverted.
John Lauer · 7e35b15 · 14d ago
Publish 1.9.156
John Lauer · 2f2a08d · 15d ago
REVERT 1.9.155 (window.open tab creation) — it churned windows, the reclaim killed a sibling (the vanished window), broke win-a identity and stranded its progress bar. Back to plain newPage; the real fix belongs in the reclaim sweep (dont split a _pupCreated attached page), to verify on-desk not while John drives. FORCE_PUSH: verified diff is only my own 1.9.155 code.
John Lauer · 78d6d27 · 15d ago
Publish 1.9.155
John Lauer · e00fe0b · 15d ago
Tabs are born in the session's OWN window — fixes the split-window race John's window-open test exposed (two of four multi-tab threads had their second page split into ai-<thread>-split1 instead of becoming a tab). Root cause: addTabToSession used browser.newPage(), which lets Chrome choose the window; under the shared durable profile with concurrent opens it lands the 'tab' in a fresh OS window, the session then spans two windows, and the drag-out reclaim splits it. Fix: create the tab FROM the session's current page (window.open in the opener's own window) so it is a same-window sibling, grab that new target, mark it _pupCreated, and navigate it if window.open left it blank; the old newPage path stays as a fallback. Deterministic same-window tab creation regardless of which thread opened last.
John Lauer · ce0fa94 · 15d ago
Publish 1.9.154
John Lauer · a6666f3 · 15d ago
Fix THE fourth matcher — the from-disk recovery binder — closing the recovery mis-bind saga (three red binding tables cornered it). It matched by saved URL with a last-page fallback and NO claim tracking, so: a session file POISONED by a prior mis-bind (docs-writer's said espn.com) URL-matched another session's page every restart, two sessions bound one page, and the genuinely-owned page was orphaned and reaped as a leftover. Now: (1) window.name ('pup:<sid>', stamped by all four injectors since 1.9.153) is matched FIRST; (2) URL matching skips pages claimed this pass and pages carrying a DIFFERENT session's pup name; (3) the last-page fallback respects both rules too; (4) a per-pass claimed-set makes double-binding structurally impossible.
John Lauer · 39b45c7 · 15d ago
recovery-binding: narrowed to the from-disk recovery loop's own binder (fourth matcher, never consults window.name; bound pages[0] and the real page got closed as leftover) — one edit remains, spec in skill
John Lauer · f088fed · 15d ago
Publish 1.9.153
John Lauer · dab022a · 15d ago
Complete the durable-session-identity fix: the LAUNCH-path title injector (and a fourth, tab-path one found in the same sweep) now stamp window.name = pup:<sessionId>. 1.9.151 stamped only the retag and periodic-reassert injectors, so brand-new windows carried NO durable id and the recovery-binding test still mis-bound docs-writer onto ship-watch's ESPN window after a restart. With all four injectors stamped, every pup page carries its session identity from birth, recovery matches window.name first, and SPA title churn cannot cross-bind sessions.
John Lauer · 0ec5652 · 15d ago
standing directive: ai-thread name is THE identifier, sessionId legacy — verb-sweep implementation item + recovery-binding scenario queued
John Lauer · 76512c8 · 15d ago
test skill: post-open table full column set — geometry, overlay, flashCount, progressBarCount, progressBarMs (v1.9.152 fields)
John Lauer · 8321ea7 · 15d ago
Audit columns for the standard test table (John: 'put a column for how many times you triggered an orange flash, and another for if you triggered a progress bar in windows taskbar' + 'and how long that prog bar ran'). Every browser_list_windows entry now carries flashCount (both flash paths counted), progressBarCount (times the agent-activity taskbar progress bar engaged), and progressBarMs (total time it ran, live-inclusive if currently running) — so the post-open table proves the window's full attention footprint (flash, progress, overlay, geometry) from one call, no log scraping.
John Lauer · f616972 · 15d ago
Publish 1.9.151
John Lauer · 26a6490 · 15d ago
Durable session identity via window.name — fixes the recovery mis-bind John's overlay audit exposed (the overlay honestly reported favicon:espncdn on docs-writer's window, and the eval confirmed the horror: docs-writer's session was attached to ship-watch's ESPN page after the upgrade restart — two sessions on one window). Root cause: recovery matches Chrome targets to sessions by the '(session: X)' tag in document.title, and SPA sites (ESPN's ticker) rewrite the title continuously; the MutationObserver that re-appends the tag dies on every navigation, so recovery during the gap guesses wrong. Fix: window.name = 'pup:<sessionId>' is now stamped at both title-injection sites — window.name SURVIVES same-tab navigations and sites never touch it — and the recovery matcher reads window.name FIRST, falling back to the title tag only when absent. The title tag remains for AD's window resolver. Found because the new overlay column told the truth about a window everyone assumed was right: the proof surface caught a deeper bug on its first day.
John Lauer · a3327ba · 15d ago
Publish 1.9.150
John Lauer · 13a1c22 · 15d ago
test skill: standing rule — every test table includes the overlay column (favicon:<host> | count:N | none+reason), re-read after reveals
John Lauer · b8bcbb0 · 15d ago
Overlays survive the reveal, and every window can PROVE what overlay it wears (John: 'prove what overlay icon you're showing and why, cuz i just now see all 3 of the pup windows you brought to fg lose their overlay icon'). Two parts. (1) The bug: browser_raise_os_window redraws the taskbar button (geometry + foreground) and nothing re-wore the favicon overlay afterward — every reveal silently stripped the icon. The raise now re-asserts the overlay (updateTabCountBadge at +1.2s, the same re-wear used after parks). (2) The proof surface: applyAppOverlay/count-badge now record WHAT is worn and WHY into session state (favicon:<host> | count:N with the no-favicon explanation | none with the reason), exposed as 'overlay' on every browser_list_windows entry — so test tables report the overlay per window instead of anyone guessing from a screenshot.
John Lauer · 65d81c9 · 15d ago
test skill: standing rule — every reveal phase reports the foreground-gate table (bare raise DENIED, reasoned raise GRANTED, exact reason string) followed by the post-raise geometry table
John Lauer · 574807e · 15d ago
test skill: standing rule — every window-opening scenario ends with the geometry table (sessionId, pos, WxH per window), all rows must equal the standard inset frame
John Lauer · e34848b · 15d ago
pup-bridge-test maintainer skill: standard scenarios with expected outputs + harness rules; scenario 2 amended per John's fg-geometry audit (assert post-raise rect == standard frame)
John Lauer · 79a1dc5 · 15d ago
Publish 1.9.149
John Lauer · c3c728c · 15d ago
Reveal geometry now equals park geometry — the one standard frame (John's audit caught it: foregrounding the three simulation windows left two at 0,0 full-screen instead of the work-area-minus-10px standard; measured 1920x1200 CSS full-screen vs the correct 15,15 2531x1499). Root cause: browser_raise_os_window still carried the pre-inset v1.8.26 block that moved the window to 0,0 1280x800 then CDP-MAXIMIZED it, clobbering the park's correct frame at the exact moment the user finally looks — the sibling-path-keeps-old-geometry pattern the placement doctrine forbids. The reveal now measures availLeft/Top/Width/Height from the page (same source as the park, per-monitor + DPI correct), sets windowState normal, and applies the identical 10px-inset rect. windowState:'maximized' no longer exists anywhere in the reveal path. One geometry standard: park, reveal, sweep — all the same frame.
John Lauer · 2ef57f3 · 15d ago
Publish 1.9.148
John Lauer · 0fe0d1d · 15d ago
Fix 1.9.147's dead-on-arrival thread-default window: a legacy 'sessionId is required' gate at the top of browser_open_window rejected every no-id call before the new thread-keyed block could run — caught because the ship-then-prove harness ran the exact three-thread scenario and all opens failed with the legacy error text. The gate now only refuses the fully anonymous case (no sessionId AND no caller identity) with the teaching caller_identity_required error; thread-identified no-id opens flow through to the thread-window logic. VERB_META's 'sessionId is required' pitfall rewritten to recommend omitting it.
John Lauer · 038337f · 15d ago
Publish 1.9.147
John Lauer · 7997cf0 · 15d ago
One window per AI thread, by construction (John: 'the ai has to send you its ai-thread name and therefore you can make 1 window for that and tabs in that window and then one ai-thread won't pollute another ai-thread's tabs'). sessionId is now OPTIONAL on browser_open_window. With no sessionId: the session keys on the caller thread (ai-<thread-slug>, from the X-Adom-Caller-Thread identity AD already requires), so the same thread always lands in ITS one window and a different thread in its own — pollution impossible by construction, on top of the 1.9.146 cross-owner guards for explicit ids. If the thread's window already exists, the url opens as a NEW TAB in it (openedAsTab:true in the response) instead of spawning another window — one window per thread, tabs accumulate, exactly the model. Anonymous callers with no sessionId are refused with a teaching caller_identity_required error: identity is the price of the default window. Explicit sessionIds keep working unchanged for deliberate multi-window workflows. browser_describe rewritten to recommend OMITTING sessionId.
John Lauer · 3fcc91f · 15d ago
Publish 1.9.146
John Lauer · 7dd8852 · 15d ago