← Commit history

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 ·a3ee5bd384 ·3mo ago ·parent f75cd10
4 files changed +92
install.sh+1
@@ -25,6 +25,7 @@ deploy_into() {   install_skill pup-screenshots-recording  skills/pup-screenshots-recording/SKILL.md   install_skill pup-browsers-and-chrome    skills/pup-browsers-and-chrome/SKILL.md   install_skill pup-adom-wiki              skills/pup-adom-wiki/SKILL.md+  install_skill pup-vendor-login          skills/pup-vendor-login/SKILL.md   echo "  -> $BASE (pup + 4 sub-skills)" } 
package.json+1
@@ -25,6 +25,7 @@     "skills/pup-screenshots-recording/SKILL.md",     "skills/pup-browsers-and-chrome/SKILL.md",     "skills/pup-adom-wiki/SKILL.md",+    "skills/pup-vendor-login/SKILL.md",     "install.sh",     "uninstall.sh",     "README.md",
skills/pup-vendor-login/SKILL.mdadded+89
@@ -0,0 +1,89 @@+---+name: pup-vendor-login+description: "How to sign a user into a third-party vendor portal (Autodesk, Fusion, Mouser, DigiKey, and other SSO sites) inside a pup window, so the login PERSISTS and later visits are automatic. Covers the autonomous 'Continue with Google/Microsoft' path that needs no typed password (it reuses the profile's existing Google session), the OAuth-popup behaviour pup shows, driving Google's account chooser (which ignores synthetic clicks), which profile to use for crash-isolation, and the hard limit that some heavy account-admin SPAs (Autodesk's Kepler/React portal) JAM CDP so pup cannot drive the in-portal admin UI. Read this before opening any vendor login in pup. Trigger words: log into autodesk, autodesk sign in, sign into fusion, continue with google, vendor login, portal login, sso login in pup, log into mouser, digikey login, assign a license, autodesk account, manage.autodesk.com, store my login, oauth popup, account chooser."+---++# pup-vendor-login — signing a user into a vendor portal that persists++Goal: get the user signed into a third-party site (Autodesk, Fusion, Mouser, DigiKey, …) inside a+pup window so the session is **stored in the durable profile** and every later window is already+signed in. Autodesk is the worked example; the pattern generalises.++## The one-paragraph model++A vendor login is an OAuth/SSO flow. The **fastest autonomous path is "Continue with Google"** (or+Microsoft/Apple) because pup's durable `adom-you` profile usually already holds the user's Google+session — so no password is typed. The click sends the window (or an OAuth popup) to Google's+account chooser; you click the user's account; it redirects back signed-in; and the vendor cookie+persists on disk. Email+password works too but needs a credential you do not have — prefer SSO.++## The recipe (Autodesk, proven 2026-07-28)++1. **Open the login page in a durable profile, FRESH window, and pace slowly.**+   ```+   browser_open_window {"sessionId":"autodesk","url":"https://accounts.autodesk.com/logon"}+   ```+   Then WAIT ~10s before the first probe. Do NOT machine-gun navigate+eval+screenshot — rapid ops+   on these heavy SSO pages destabilise the CDP connection (measured: three Chrome crashes from+   churn alone). One op, settle, next op.++2. **Click the SSO button** (trusted CDP click via a text match; the button text often has hidden+   whitespace so match with a regex, not `===`):+   ```+   browser_eval {"sessionId":"autodesk","expr":"(()=>{const b=[...document.querySelectorAll('button,a,[role=button]')].find(e=>/continue with google/i.test(e.textContent||'')&&e.offsetParent!==null); b.click(); return 'clicked';})()"}+   ```+   Wait ~8s.++3. **Find where the OAuth landed — TWO shapes, handle both:**+   - The main window navigates to `accounts.google.com/.../accountchooser` (most common), OR+   - An OAuth **popup** opens. Autodesk's popup has **no opener**, so pup's popup-tracker skips it+     and the reclaim sweep adopts it as its **own session** named like `adom-you-win<rand>` at+     `signin.autodesk.com`. Run `browser_list_windows` and look for the new session; drive THAT one.++4. **Click the account in Google's chooser — Google IGNORES a bare `.click()`.** Dispatch the full+   trusted pointer sequence:+   ```+   browser_eval {"sessionId":"autodesk","expr":"(()=>{const el=document.querySelector('[data-identifier=\"USER@EMAIL\"]'); const r=el.getBoundingClientRect(),cx=r.x+r.width/2,cy=r.y+r.height/2; for(const t of ['pointerdown','mousedown','pointerup','mouseup','click']) el.dispatchEvent(new MouseEvent(t,{bubbles:true,cancelable:true,view:window,clientX:cx,clientY:cy,buttons:1})); return 'clicked';})()"}+   ```+   List the accounts first with `[...document.querySelectorAll('[data-identifier]')].map(e=>e.getAttribute('data-identifier'))`.++5. **Confirm the redirect landed** by SCREENSHOT, not eval — the eval often reads one beat before the+   redirect completes and reports the stale chooser URL while the screenshot already shows the+   signed-in dashboard ("Hi, <name>"). Trust the picture.++6. **Done. The login persists.** The vendor cookie is now in the durable profile and survives window+   close, Chrome kill, and bridge restart — same as the Google/Gmail session.++## Which profile — and why NOT the shared one for a crashy portal++- **Persistence needs a durable profile** (default `adom-you`, or a named one). Never `isolated:true`+  for a login you want to keep.+- **Crash isolation argues for a DEDICATED durable profile per vendor**, e.g.+  `browser_open_window {"profile":"autodesk", ...}`. A crash/hang during a vendor login on the SHARED+  `adom-you` profile takes down EVERY other session in that one Chrome process — measured live: the+  Autodesk flow crashed the shared Chrome and killed the user's Gmail session twice, and lost the+  in-flight Autodesk login because its cookie had not flushed before the crash. A per-vendor durable+  profile keeps the login persistent AND contains the blast radius. The one cost: SSO in a dedicated+  profile only reuses an existing Google session if that profile already has one; the very first+  Google sign-in there is a real login.++## HARD LIMIT: heavy account-admin SPAs jam CDP++`manage.autodesk.com/billing/user-management/...` (Autodesk's "Kepler"/React account portal) reliably+**jams pup's CDP pipe**: the window signature is HUNG-alive / CDP-DEAD — the process lives, the log+shows `KEPLER: Auth is not yet ready to mount providers`, and every `page.eval`/`page.screenshot`+times out (20s), then the frame detaches. pup CANNOT reliably drive the in-portal admin UI (assigning+a license seat, editing users). Do not promise to click through it. Options, in order:+1. **Hand the in-portal action to the USER** — pup got them signed in; the window is theirs to finish+   the seat assignment by hand. This is the honest, reliable answer today.+2. **Use the vendor's API** instead of the web UI where one exists (Autodesk has account-management+   APIs) — no CDP, no jam.+3. Never deep-link straight to the admin URL right after login; even navigating there is what jams it.++## Pitfalls recap (each paid for on 2026-07-28)+- Rapid ops crash the Chrome → pace slowly, one op + settle.+- Shared-profile crash kills all sessions + loses un-flushed logins → dedicated durable profile.+- Google chooser ignores synthetic clicks → full pointer-event sequence.+- Button text has hidden whitespace → regex match, not `===`.+- Eval reads stale mid-redirect → confirm with a screenshot.+- The account-admin SPA jams CDP → hand off to the user or the API; do not fight it.
uninstall.sh+1
@@ -7,6 +7,7 @@ remove_from() {   rm -rf "$BASE/pup" \          "$BASE/adom-desktop-puppeteer-bridge" \          "$BASE/pup-windows-sessions-tabs" "$BASE/pup-screenshots-recording" "$BASE/pup-browsers-and-chrome" "$BASE/pup-adom-wiki" \+  rm -rf "$BASE/pup-vendor-login"          "$BASE/pup-bridge-dev" "$BASE/pup-bridge-publish"   echo "  <- $BASE" }