@taprun/from-stagehand
v1.0.1
Published
Migrate Stagehand (Browserbase) AI flows to MCP-compatible plans. Deterministic Playwright calls compile to plan ops; stagehand.act/extract/observe preserve their natural-language prompts. Run agent flows at zero LLM tokens in Claude Code, Cursor, and any
Maintainers
Readme
@taprun/from-stagehand
Convert Stagehand scripts into Tap Plan v2 objects. Complement to Stagehand, not a replacement.
npm install @taprun/from-stagehand @taprun/specWhat this is for
Stagehand (Browserbase) ships natural-language browser automation on top of Playwright. Two API surfaces coexist in user scripts:
- Deterministic Playwright —
page.goto / click / fill / type / press / waitForSelector / waitForTimeout. These have fixed selectors and stable behavior. - Natural-language Stagehand —
stagehand.act("..."),stagehand.extract("...", schema),stagehand.observe(),stagehand.agent().execute("..."). These resolve to actions only at runtime via an LLM.
This adapter takes a pragmatic stance:
| Stagehand API | → plan-v2 op | Verifiable? |
|---|---|---|
| page.goto(url) | { op: "nav", url } | ✓ |
| page.click(s) | { op: "input", kind: "click", target } | ✓ |
| page.fill(s, v) | { op: "input", kind: "fill", target, value } | ✓ |
| page.type / press / waitForSelector / waitForTimeout | (same as @taprun/from-playwright) | ✓ |
| stagehand.act(prompt) | { op: "eval", returns: { type: "object" }, fn: TODO with prompt } | ✗ |
| stagehand.extract(prompt, schema) | { op: "eval", returns: { type: "object" }, fn: TODO } | ✗ |
| stagehand.observe(...) | { op: "eval", returns: { type: "array" }, fn: TODO } | ✗ |
| stagehand.agent().execute(prompt) | { op: "eval", returns: { type: "object" }, fn: TODO } | ✗ |
Result: a partially deterministic v2 Plan. Tap can doctor and heal the deterministic portions. The NL portions land on op:eval with a TODO marker in fn — author refines returns.type and replaces the stub with deterministic ops or a real eval body before runtime. v2 has no op:exec and no allowUnverifiable flag; the LLM-required steps are visible by inspecting op types.
Positioning
This is not a Stagehand replacement. It's a Tap-side bridge so Stagehand users can:
- Add structural drift detection on the deterministic portions of their scripts
- Audit which steps in their automation actually require an LLM
- Produce a portable
.tap.jsonartifact for compliance / reproducibility logs
Usage
import { readFile, writeFile } from "node:fs/promises";
import { stagehandToTap } from "@taprun/from-stagehand";
import { runConformance } from "@taprun/spec";
const source = await readFile("scripts/my-stagehand-script.ts", "utf8");
const plan = stagehandToTap(source, {
site: "github",
name: "browserbase-search",
intent: "read",
});
const v = runConformance(plan);
if (!v.pass) throw new Error(JSON.stringify(v.failures));
await writeFile("github/browserbase-search.plan.json", JSON.stringify(plan, null, 2));Scope notes
- Lifecycle calls (
stagehand.init,stagehand.close,browser.newPage, etc.) are silently dropped — they're scaffolding, not user actions. - Plain Playwright deterministic calls follow exactly the same regex as
@taprun/from-playwright(no behavioral divergence). - The MVP regex scanner has the same limitations as the Playwright/Puppeteer adapters: variable-bound selectors, template-string interpolation, and trailing line comments are best-effort.
Part of the Tap ecosystem
Tap is local-first browser automation — compile your scraper once, run it in your own browser forever, and diff the drift when sites change. The local-first runtime means your act() and extract() calls hit your already-logged-in session — no Browserbase egress, no shared cloud browser.
- Format spec:
@taprun/spec— W3C-compliant validator for.tap.json - Sibling adapters:
@taprun/from-playwright·@taprun/from-puppeteer - Scaffold a fresh plan:
npx create-tap-script <site>/<name> <url> - Run locally: Tap Chrome extension — credentials never leave your machine
- Why Tap vs Stagehand / Browserbase: https://taprun.dev/compare/stagehand/?utm_source=jsr&utm_medium=readme&utm_campaign=from-stagehand
- Source: https://github.com/LeonTing1010/tap · npm: https://www.npmjs.com/~taprun
Rather have it run for you?
If your scraper keeps breaking and you'd rather buy the outcome than maintain the tool, we set up the automation on your machine and keep it working when sites change — flat monthly, cancel anytime: taprun.dev/done-for-you.
License
MIT.
