Open source CLI

AI explores.
Playwright verifies.

appwalk sends an AI through your app like a real user, then keeps only the flows that survive a clean, deterministic replay.

npx @kubstack/appwalk run <url> --provider openai --model gpt-4o
Needs Node 24+, a Playwright browser, and an API key for your provider — 2-minute setup
How it works

Verification is the whole point.

Point it at your app

Give appwalk a URL, a provider, and a model. Add a persona, scope, or expectation only when you want to focus the run.

Browser exploration

An AI drives a real browser like a first-time user, or any persona you pick.

Replay in a clean session

Every discovered flow runs again, deterministically, from a blank slate.

Verified Playwright test

Only flows that survive replay become a spec you can run without AI.

Why appwalk

Coverage without the manual grind

Start fast

Get E2E coverage going for an app that has little or none today.

Cover new features

Turn a newly shipped feature into a regression test without writing the first journey by hand.

Probe the edges

Check accessibility, validation, permissions, and race conditions with focused personas.

No AI at runtime

Once verified, the generated test runs like any other Playwright spec — no model, no key.

Fits your suite

Results land in your existing Playwright project. No new runner, no new format.

Personas

Pick a lens. appwalk explores through it.

journey — a normal flow; verified flows become coverage challenge — a boundary check; becomes coverage or a finding
Everyday users
noah
The Newcomer

First-time visitor takes the most direct, obvious path.

wade
The Wanderer

Clicks around and backtracks, but still completes the flow.

rosa
The Regular

Returning user checks history, drafts, and saved state.

mia
The Mobile Baseline

Real phone profile; sweeps flows for layout and reachability.

kai
The Keyboard-only

Completes a flow using only the keyboard, never a click.

hana
The Hoverless

Checks hover-only content is reachable without hovering.

priya
The Polyglot

Enters non-Latin scripts, right-to-left text, locale formats.

Stateful flows
blake
The Backtracker

Back/forward/reload mid-flow, checks what survived.

tara
The Tweaker

Changes an earlier choice, checks downstream updates.

eli
The Expirer

Clears cookies mid-flow to simulate an expired session.

casey
The Canceller

Cancels, deletes, or unsubscribes, then verifies it took effect.

Scale & perf
max
The Maximalist

Pushes long text and large data sets looking for broken layout.

lena
The Laggard

Injects network latency, checks for duplicate submissions.

ezra
The Exporter

Triggers a real export and confirms a real file was produced.

Data integrity
freddie
The Form Breaker

Submits invalid or hostile values, records what got through.

dana
The Duplicator

Creates the same thing twice, checks for duplicate detection.

uma
The Uploader

Uploads wrong-type, empty, or oversized files.

Access control
owen
The Outsider

Never logs in, tries to reach protected pages directly.

iris
The ID Swapper

Tries a neighboring resource ID or an unlinked admin URL.

gail
The Gatecrasher

Tries to reach a plan-gated or quota-limited feature directly.

Concurrency
riley
The Rusher

Fires the same action rapidly, checks for duplicate submission.

talia
The Two-Tabber

Edits the same record from two open tabs at once.

della
The Decliner

Backs out at the last moment, checks nothing was committed.

Resilience
gabe
The Glitch

Injects a network failure, checks the app recovers cleanly.

See it run

What a run actually leaves behind

Not just a test file — a full run leaves a human-facing report, raw evidence, and machine-readable data behind. The spec is generated only for flows that passed deterministic replay.

$ npx @kubstack/appwalk run https://your-app.example --provider anthropic --model claude-opus-5 --persona noah
[noah] Exploring application
[noah] Exploration completed: 3 flow(s) found
[noah] Verifying 3 of 3 discovered flow(s) by replay in a clean session
[noah] Flow 1 replay confirmed
[noah] Flow 2 replay confirmed
[noah] Flow 3 not confirmed: expected result was not reproduced
[noah] Generating test suite
writes to appwalk-output/<run-id>/
report.html open first

The human-facing summary — flows found, replay results, and any findings.

discovered.spec.ts 2 flows

Generated only for replay-confirmed flows — an ordinary Playwright test that runs without AI.

test('Checkout: place an order', async ({ page }) => {
  await page.goto('https://your-app.example');
  await page.getByRole('button', { name: 'Place order' }).click();
  await expect(page.getByRole('heading', { name: 'Order confirmed' })).toBeVisible();
});
{ }report.json

The same data as the HTML report, for CI and tooling.

evidence/

Screenshots and traces captured for each step.