@taprun/from-stagehand
v1.0.0
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
License
MIT.
