Browser Automation
Three layers for reaching the web — static fetch, headless scripts, and the agent-driven session browser.
CareerRat reaches the web three ways. They are not interchangeable — each is right for a different layer.
Layer 1 — Static fetch (WebFetch)
Plain-HTML job postings and board listing pages. Cheapest path; always tried first when you only need the posting text. If the body comes back empty or is an SPA shell, escalate to Layer 3.
Covers: Greenhouse (boards.greenhouse.io), plain ATS URLs, RSS feed items.
Layer 2 — Headless capture (bundled Playwright)
The playwright npm dependency, driven headless and in-process from Node scripts.
No setup needed — Chromium ships with the package.
Used for:
npm run capture:search-sources/npm run capture:board— bulk-scrape a board's listing DOM- Document and packet PDF export (
careerrat export)
This is for batch, non-interactive rendering where the agent does not need to reason turn-by-turn.
Layer 3 — Interactive session browser
Anything the agent drives step-by-step: rendering JS pages, filling application forms, reading in-platform DMs, polling ATS status. The agent reads the live DOM before each action, never uses hardcoded selectors, and stays confirm-first.
Automatic provider selection: Orca's visible supervised browser is used inside an Orca workspace; CareerRat's app-owned Playwright browser is selected everywhere else. Playwright creates persistent local browser storage when a workflow first needs it. Public application forms open without a login; account-gated sites ask the candidate to sign in only when necessary. If the selected provider cannot execute a workflow, CareerRat shows a supervised/manual handoff instead of claiming it ran.
Automatic is the default. Settings shows the effective browser and allows an explicit override without requiring the candidate to understand their CLI setup during onboarding.
Job-site login
Saved job-site searches use one point-of-use choice, not the automation capability matrix. When a source is added or first used and login is needed, CareerRat asks “Do you want to log into LinkedIn so I can use it?” Yes opens that exact saved search in the visible session browser. No skips it and keeps searching the other sources.
Opt-in private-account capabilities
Reading public posting bodies requires no permission. The private-account uses
below are opt-in and default OFF. With no .careerrat/candidate/automation.yml,
none of them run.
| Capability | Skill | What it does |
|---|---|---|
status_polling | sync-status | Read application status from ATS dashboards |
messaging | ingest-messages | Read LinkedIn / Wellfound DMs |
authenticated_apply_preparation | apply-job | Prepare supported ATS forms, including LinkedIn Easy Apply, and stop before final submit |
profile_optimize | optimize-linkedin | Read LinkedIn profile for analysis |
profile_apply | optimize-linkedin | Write approved edits back to the profile |
mail_access | ingest-mail, apply-job | Webmail verification codes + Gmail/Outlook ingest |
relationship_sourcing | relationship-sourcing | Find recruiters and warm contacts |
calendar_read | schedule-meeting | Read free/busy for double-booking avoidance |
calendar_sync | calendar-sync | Write events to a calendar provider |
Enabling a capability
The desktop job review offers Allow form preparation when an otherwise-ready application needs this permission. Terminal users can manage the same underlying capability matrix with the commands below.
Three switches must all be on for a capability to run on a platform, and the setup mode must be "advanced" or the capability must have a contextual scoped grant for that platform:
- The capability's global switch is on.
- That platform's per-capability switch is on.
- That platform's one-time ToS consent is recorded.
careerrat automation status # current matrix
careerrat automation consent linkedin --write # record consent
careerrat automation enable profile_optimize linkedin --write
careerrat automation session extension --write # set providerSafety rules (always enforced)
- Never on a schedule. Automation runs only when you initiate it.
- Halt on CAPTCHA, 2FA, or unexpected interstitial. The agent stops and tells you what it hit.
- Never infer voluntary demographic answers. Race, gender identity, disability, veteran status, and similar self-identification fields stay blank by default. The local-only Profile > Application defaults editor can keep them blank or choose the form's decline option when available. Existing exact answers remain hidden and may be used only when the candidate explicitly saved them.
- Never submit an application. CareerRat prepares the form and the candidate presses the final submit control. Other outward-facing actions, such as sending a message, require explicit confirmation.
- Capture artifacts are scratch. Screenshots go to
.careerrat/workspace/captures/(gitignored), never the repo root. - No credential storage. The session browser holds your logins. CareerRat does not export or cache them.
SPA escalation
When a job link returns an SPA shell (Wellfound, Lever, Ashby), the agent:
- For Lever: fetches the JSON API (
api.lever.co/v0/postings/{company}?mode=json) - For others: escalates to Layer 3, evaluates
document.body.innerTextin the session browser