AI fixes, delivered as pull requests

Browser Automation That Fixes Itself

Change one import in your Playwright script. When it breaks, Autowright captures the evidence, diagnoses the failure, and opens a pull request with the fix.

scraper.ts
// The only change: import chromium from Autowright instead of Playwright
import { chromium } from '@autowright/browser';

const browser = await chromium.launch({
  headless: true,
  autowright: {
    scriptId: 'loan-scraper',
    repoUrl: 'https://github.com/your-org/scrapers',
    scriptPath: 'src/loan-scraper.ts',
  },
});

// Normal Playwright from here. Capture is invisible.
const page = await browser.newPage();
await page.goto('https://portal.example.com');
await page.locator('#login-btn').click();
// ...if that selector breaks tomorrow, a PR with the fix shows up.
await browser.close();

Everything You Need for Self-Healing Automation

Capture, diagnosis, and AI-powered fixing work together to keep your Playwright scripts running.

One-Line Integration

Swap one import and keep writing plain Playwright. No framework, no step DSL, no rewrite of your existing scripts.

Full-Context Capture

Every run invisibly records actions, screenshots, DOM snapshots, network requests, and console logs — bundled as evidence when something fails.

AI Fixes as Pull Requests

A Claude-powered agent clones your repo, reasons over the captured evidence, and opens a real PR with the fix for you to review.

Never Blocks Your Script

Errors are re-thrown, never swallowed, and fixing happens out-of-band. A confident fix becomes a PR; anything else becomes triage with evidence attached.

Smart Error Classification

Failures are classified — broken selectors, timeouts, network errors, bad credentials — and deduplicated by hash so one incident means one fix.

Cost Transparency

Every fix reports its real AI spend — dollars, tokens, and turns — on the dashboard and in Slack. No surprise bills.

See It In Action

You write plain Playwright. Autowright handles what happens when it breaks.

// Plain Playwright — one import change, one config block
import { chromium } from '@autowright/browser';

const browser = await chromium.launch({
  headless: true,
  autowright: {
    scriptId: 'portal-login',
    serviceUrl: 'http://localhost:4400',
    repoUrl: 'https://github.com/your-org/scrapers',
    scriptPath: 'src/portal-login.ts',
    capture: { screenshotCount: 3, dom: true, network: true },
  },
});

const page = await browser.newPage();
await page.goto('https://portal.example.com/login');
await page.fill('#username', process.env.PORTAL_USER!);
await page.fill('#password', process.env.PORTAL_PASS!);
await page.locator('#login-btn').click();
await browser.close();

// Every action, request, console line, and screenshot is
// captured invisibly. Your code stays 100% Playwright.
// The site changed. Your selector broke. Here's what happens:

 locator('#login-btn').click() — TimeoutError

autowright classified error      SELECTOR_NOT_FOUND
autowright captured evidence     3 screenshots · DOM · network · console
autowright uploaded bundle       portal-login/a1b2c3d4.tar.gz
autowright reported to service   deduped by error hash · queued

fixer      cloned repo            github.com/your-org/scrapers
fixer      agent analyzed DOM     found '#signin-button' replaced '#login-btn'
fixer      verdict                FIX_OUTCOME: FIXED

 Pull request opened    fix: update login selector for portal redesign
 Slack notified         cost $0.09 · 6 turns · 48s

// You review the PR against the live site and merge.
// No confident fix? You get triage + evidence instead — never silence.

Get Started in Minutes

One package in your script, one stack to run the healing service.

1

Install the browser package

npm install github:nawaaz-korvol/autowright-browser playwright
2

Change one import in your script

import { chromium } from '@autowright/browser';

Add the autowright config block to launch() — the rest of your Playwright code is untouched.

3

Run the healing stack

docker compose up service fixer minio

The service coordinates failures; the fixer turns them into pull requests.

+

Break something — get a PR

ANTHROPIC_API_KEY=… GITHUB_TOKEN=… SLACK_WEBHOOK_URL=…

With these set, failed runs come back as reviewable pull requests with Slack notifications and per-fix cost.

Ready to Automate?

Stop babysitting broken selectors. Let your Playwright scripts heal themselves.