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.
master
Gusto (gusto.com) — payroll
- Login entry URL:
https://app.gusto.com/login(redirects tologin.gusto.com, a Keycloak IdP) - Flow type: email-first → account-picker → password → 2FA
- 2FA: TOTP authenticator (6-digit code); "Remember device for 30 days" checkbox offered — check it on adom-you so future logins skip 2FA
- Anti-automation notes: the password field is a React-controlled masked input and is
type="text"(nottype=password), withautocomplete="current-password". Setting.valuedoes NOT register with React's state — you MUST use real keystrokes (pup_type) and then read the value back to confirm it landed before submitting.
Steps
- Open on adom-you (never isolated) —
pup_open_window {url:"https://app.gusto.com/login"}. AUTO-APPROVES. If adom-you already has a Gusto session you land signed in; done. - Email step — fill the email field (benign, AI may enter it) and click Continue.
pup_typeor a fill; AUTO-APPROVES (username is not a secret). - Account picker — Gusto often shows "Select your email address" with your account as a row. Click the row for your email (a
<button>). AUTO-APPROVES. - Password step ("Enter your password") — the field is
#password,type=text, masked by React. Usepup_login {username, password, submit:true, submitReason:"…confirm login.gusto.com is the intended site…"}(structured verb → passes the safety check) ORpup_type {selector:"#password", text, clear:true}then verify#passwordvalue length, then click Continue. This is the step that PAUSES for the human under Auto mode (typing a credential) — surface it for one-tap approval, or the human types it. Real keystrokes are mandatory;.value-set silently fails. - 2FA — "Enter the 6-digit code in your authenticator app." pup CANNOT generate this; the human enters the 6-digit code from their authenticator (PAUSES). Check "Remember device" so it is a one-time step on adom-you.
- Redirects to
app.gusto.com/…dashboard = signed in.
Field selectors
- username/email:
input[type=email], input[name=username](type: email) - password:
#password— NOTE:type="text",autocomplete="current-password", nottype=password - submit: button with text "Continue"
Gotchas
type=passwordselectors miss the password field entirely (it istype=text). pup ≥2.0.123 also matchesautocomplete=current-password/name=password.- Setting
.valueon the password field passes React's display but submits EMPTY ("Password is required"). Use real keystrokes and verify the value landed. - On the email step, the value can reset on reload — re-enter and submit via the form, then poll for the password field.
- It is a cross-origin SSO redirect (
login.gusto.com→app.gusto.com); capture on password blur (pup ≥2.0.121) so the credential is vaulted before the redirect.
# Gusto (gusto.com) — payroll
- **Login entry URL:** `https://app.gusto.com/login` (redirects to `login.gusto.com`, a Keycloak IdP)
- **Flow type:** email-first → account-picker → password → 2FA
- **2FA:** TOTP authenticator (6-digit code); "Remember device for 30 days" checkbox offered — check it on adom-you so future logins skip 2FA
- **Anti-automation notes:** the password field is a **React-controlled masked input** and is `type="text"` (not `type=password`), with `autocomplete="current-password"`. Setting `.value` does NOT register with React's state — you MUST use real keystrokes (`pup_type`) and then read the value back to confirm it landed before submitting.
## Steps
1. Open on **adom-you** (never isolated) — `pup_open_window {url:"https://app.gusto.com/login"}`. AUTO-APPROVES. If adom-you already has a Gusto session you land signed in; done.
2. **Email step** — fill the email field (benign, AI may enter it) and click **Continue**. `pup_type` or a fill; AUTO-APPROVES (username is not a secret).
3. **Account picker** — Gusto often shows "Select your email address" with your account as a row. Click the row for your email (a `<button>`). AUTO-APPROVES.
4. **Password step** ("Enter your password") — the field is `#password`, `type=text`, masked by React. Use `pup_login {username, password, submit:true, submitReason:"…confirm login.gusto.com is the intended site…"}` (structured verb → passes the safety check) OR `pup_type {selector:"#password", text, clear:true}` then verify `#password` value length, then click Continue. This is the step that **PAUSES for the human under Auto mode** (typing a credential) — surface it for one-tap approval, or the human types it. Real keystrokes are mandatory; `.value`-set silently fails.
5. **2FA** — "Enter the 6-digit code in your authenticator app." pup CANNOT generate this; the **human enters the 6-digit code** from their authenticator (PAUSES). Check "Remember device" so it is a one-time step on adom-you.
6. Redirects to `app.gusto.com/…` dashboard = signed in.
## Field selectors
- username/email: `input[type=email], input[name=username]` (type: email)
- password: `#password` — **NOTE: `type="text"`, `autocomplete="current-password"`, not `type=password`**
- submit: button with text "Continue"
## Gotchas
- `type=password` selectors miss the password field entirely (it is `type=text`). pup ≥2.0.123 also matches `autocomplete=current-password` / `name=password`.
- Setting `.value` on the password field passes React's display but submits EMPTY ("Password is required"). Use real keystrokes and verify the value landed.
- On the email step, the value can reset on reload — re-enter and submit via the form, then poll for the password field.
- It is a cross-origin SSO redirect (`login.gusto.com` → `app.gusto.com`); capture on password blur (pup ≥2.0.121) so the credential is vaulted before the redirect.