NewYour coding agent can read the release notes before it upgrades.Set up the MCP server →
PyPI · #3618 most downloaded on PyPI
Browserbase's SDK for building browser agents
Last release today
04 Oct 2026
Release timing varies
gaps range from 8 days to 2 months
Rarely documented
notes for 9 of 48 stable releases
Nothing withdrawn
no release was ever pulled
1 years old
102 releases · first in 2025
One column per month.
Nothing published for this version
Adds Amel Bajramovic to the contributors list in the README Acknowledgements section.
Adds Amel Bajramovic to the
contributors list in the README Acknowledgements section.
feat(eve): publish native Browserbase extension with session cleanup …
feat(eve): publish native Browserbase extension with session cleanup …
Browse 0.10.0 uploaded successfully in the Release workflow , but the following tag step saw a temporary npm 404 and returned unpublished . The job fi
Browse 0.10.0 uploaded successfully in the Release
workflow,
but the following tag step saw a temporary npm 404 and returned
unpublished. The job finished green without pushing the release tag.
Push the validated local tag that Changesets creates after a successful
upload without requiring immediate registry visibility. When no local
tag exists, retain the registry check and original version-bump commit
guard for recovery.
Validation: reproduced the failure with a real HTTP server returning 404
and a bare Git remote, then verified the fix; all 67 release tests,
tooling typecheck, targeted lint/format, and diff checks pass. The diff
changes only the helper and its existing regression test.
The current browse@0.10.0 tag has been repaired separately to the
exact commit verified in npm provenance. No npm upload or package
version change is part of this PR.
Fixes the release workflow so an existing local Browse tag is pushed
without waiting for npm registry reads to converge. Previously a
temporary 404 from npm during propagation made the tag step return
unpublished, finishing green without creating the release tag. When no
local tag exists, the registry check and the version-bump-commit guard
still run as before.
Written for commit 345a953.
Summary will update on new commits.
page.snapshot() had no timeout param, nor did some of its internal helpers. the helpers that it calls are also called by other functions in the codeba
page.snapshot() had no timeout param, nor did some of its internal
helpers. the helpers that it calls are also called by other functions in
the codebase that require timeout handling. this PR wires the progress
object through the shared downstream helpers, and also exposes a user
facing timeout param in page.snapshot()
0 keeps snapshots unlimited.capture.test.ts checks public & inherited deadlines, unlimiteddomTree.test.ts & a11yTree.test.ts check that expired reads cannotfocusSelectors.test.ts checks that both selector lookup pathsAdds an optional timeout param to page.snapshot() so callers can
bound the entire snapshot operation. Omitted timeouts now default to 20
seconds instead of running unlimited.
timeout in the TypeScript, Python, and Go SDKs; passing 0Written for commit 4054cdb.
Summary will update on new commits.
ci: restore Browse alphas for CLI changes
ci: restore Browse alphas for CLI changes (#3082)
docs(examples): add packages/examples/ for stagehand.dev/showcase (…
docs(examples): add packages/examples/ for stagehand.dev/showcase (…
[feat]: evals welcome — animated onboarding on the agent benchmarks…
[feat]: evals welcome — animated onboarding on the agent benchmarks…
[fix]: enforce screenshot & pdf deadlines across downstream steps…
[fix]: enforce screenshot & pdf deadlines across downstream steps…
this PR adds the timeout param to the protocol, & exposes it publicly in ts. the default timeout is 20 seconds
this PR adds the timeout param to the protocol, & exposes it publicly
in ts. the default timeout is 20 seconds
click({ timeout: 5000 }),fill("hello", { timeout: 5000 }), or count({ timeout: 0 }).locator-timeouts.test.ts checks every registered locator methodruntime-locator-timeouts.test.ts uses controlled time to verifyiframeLocatorReadiness.test.ts runs against real chrome withlocatorActions.test.ts exercises highlight & upload cleanup throughAdds a timeout option to all terminal locator methods across the
protocol and the TypeScript, Python, and Go SDKs, and updates the v4
docs. The default is 20 seconds, and { timeout: 0 } disables the
deadline.
What changed
0 disabling it; long timeouts work aroundSetInputFiles now takes a file-input slice, and Python rejectsTimeoutError name and message.Written for commit 0d7d1ec.
Summary will update on new commits.
Three links in the v3 docs are broken, and two Go code samples were rewritten into links, so they no longer show valid Go.
Three links in the v3 docs are broken, and two Go code samples were
rewritten into links, so they no longer show valid Go.
v3/sdk/go.mdx: restore param.Override[T](value) andparam.Override[stagehand.FooParams](12). Both had been turned intostagehand-go/blob/main/value and /12).v3/sdk/java.mdx: the OkHttp logging interceptor link pointed atsquare/okhttp/tree/master. That repo's default branch is main, andmaster no longer resolves.v3/basics/evals.mdx: evals.config.json moved topackages/evals/evals.config.json. The link used the old top-levelChecked each new target on GitHub (packages/evals/evals.config.json on
main, okhttp-logging-interceptor on okhttp main) and compared the Go
snippets against the stagehand-go README. Docs-only change, no Changeset
needed per CONTRIBUTING.md.
Fixes three broken links in the v3 docs.
param.Override[T](value) andparam.Override[stagehand.FooParams](12) code samples were accidentallymain instead ofmaster.evals.config.json link now points topackages/evals/evals.config.json.Written for commit c427fb1.
Summary will update on new commits.
Fixing a prose issue surfaced in another PR, and while in there, added clarity about the functions starter code and what could be replaced
Fixing a prose issue surfaced in another PR, and while in there, added
clarity about the functions starter code and what could be replaced
Fixes prose in the deployment guide and clarifies that the Functions
template is starter code you replace.
defineFn call and update the function nameWritten for commit 1f6ff65.
Summary will update on new commits.
Release Browse independently of the Stagehand SDKs. Merging this PR publishes the CLI from the merged commit.
Release Browse independently of the Stagehand SDKs. Merging this PR
publishes the CLI from the merged commit.
#3055
8308d8d
Thanks @akeimach! - functions init now
scaffolds a Stagehand project. It installs @browserbasehq/stagehand
instead of playwright-core, installs the zod version that Stagehand
uses, and writes a Stagehand starter function.
#3055
8308d8d
Thanks @akeimach! - Fix Functions builds
that failed because of how functions publish generated
package-lock.json or how functions init set up pnpm:
functions publish now generates package-lock.json without registry
URLs, so private npm registries work.
functions publish now resolves local file: dependencies by
building package-lock.json from the uploaded files rather than just
package.json.
functions publish now prints npm's error output when it can't
generate package-lock.json.
functions init now writes a pnpm-workspace.yaml that allows the
esbuild build script, required by pnpm 11+.
#2542
514970e
Thanks @shrey150! - Fix local browser
discovery (--auto-connect, browse doctor) trusting a stale cached
debugging port after a different Chrome process later reuses that same
port.
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
The release of Function Secrets enables us to support Stagehand deployments on Browserbase. This PR showcases that in the new deployment guide
Updates the Stagehand deployment guide to recommend Browserbase
Functions with encrypted project secrets as the primary deployment path
instead of Vercel.
Written for commit 83c9e20.
Summary will update on new commits.
Before Browserbase had secrets support, functions init would install a playwright template. But now we support secrets so we can update the starter te
functions init would installfunctions publish commandIt works if nothing in this path errors:
pnpm build && cd packages/clialias browse-dev="node $HOME/[your dev path]/stagehand/packages/cli/bin/run.js" to set a local version of thebrowse cli called browse-devcd [your dev path, _not_ in stagehand repo] && browse-dev functions init branch-test && cd branch-testbrowse-dev cloud extensions upload node_modules/@browserbasehq/stagehand/dist/assets/stagehand-extension.zipyour-extension-id in index.tsbrowse-dev cloud secrets create BROWSERBASE_API_KEY --env BROWSERBASE_API_KEY to store your secret API key for use in thebrowse-dev functions dev index.tscurl -X POST http://127.0.0.1:14113/v1/functions/my-function/invoke -H 'Content-Type: application/json' --data '{}' to make sure it works locallynpm_config_min_release_age=0 browse-dev functions publish index.tsbrowse-dev functions secrets attach <functionId> <secretId>browse-dev functions invoke <functionId> to make sure you got theSwaps the Playwright starter in functions init for a Stagehand one,
and fixes functions init and functions publish on pnpm 11 and
private npm registries.
secrets object to invocations, matchingcontext.secrets.BROWSERBASE_API_KEYprocess.env.BROWSERBASE_API_KEY.functions init installs @browserbasehq/stagehand instead ofplaywright-core, pins zod to Stagehand's version so schemas pass typebrowserbase.connect intoStagehand.create and expects you to upload the Stagehand extension andindex.ts.functions init writes pnpm-workspace.yaml so pnpm 11 allowsbrowse commands.functions publish builds package-lock.json from the uploaded filesfile: dependencies resolve), omits registry-resolved URLsWritten for commit b630e73.
Summary will update on new commits.
example.com changed, this broke some smoke tests in our ci
Fixes failing CI smoke tests by replacing https://example.com with a
hosted eval site that mirrors example.com across the Go, Python, and
TypeScript SDK examples and the TypeScript Browserbase smoke test.
Written for commit dfd525e.
Summary will update on new commits.
Make the integrations overview a general directory for connecting Stagehand to agents, frameworks, and application workflows. Organize the overview an
Make the integrations overview a general directory for connecting
Stagehand to agents, frameworks, and application workflows. Organize the
overview and sidebar into Agent Frameworks, CLI Agents, and Automations.
mint validatemint broken-links --check-anchors --check-redirects --check-snippetsmint a11y --skip-contrastdocs.json and git diff --checkAll passed using Node.js 24. Checkout was not executed; the Stripe guide
was verified against the upstream sample source.
Co-authored-by: cubic-dev-ai[bot] <191113872+cubic-dev-ai[bot]@users.noreply.github.com>
Co-authored-by: Cursor cursoragent@cursor.com
[chore]: use absolute gh URLs for readme links
[chore]: use absolute gh URLs for readme links (#3066)
Expose PDF rendering through the existing Stagehand SDK conventions after the internal extension implementation is in place.
Expose PDF rendering through the existing Stagehand SDK conventions
after the internal extension implementation is in place.
This is PR2 of 2, stacked directly on #3034
(amel/pdf-render-extension). Merge the parent first and follow the
repository's stacked-PR handoff rules when moving this PR to main.
page.pdf protocol operation and connect the extensionpage.pdf() and Go Page.PDF(), returningtimeout: 0 disabling theThe capture implementation and recovery tests are reviewed in #3034, not
repeated in this diff. The complete stack's Git tree is identical to the
previously reviewed implementation at 2b416e172; this split changes
review boundaries, not behavior.
pnpm check: 36 tasks passed. Generated Go extension matches thegit diff --check passes.go vet, and generated-artifact checks.thanks @mikhail-koviazin for the contribution here!
thanks @mikhail-koviazin for the contribution here!
The composed-tree XPath parser evaluates text() and . through the
same helper, element.textContent. In XPath these are not the same
thing: . is the string-value of the element, so it covers the whole
subtree, while text() is the node-set of the element's direct child
text nodes.
This parser is not a rare path. It takes over whenever the document
contains a shadow root anywhere, so a single unrelated web component on
the page changes what a locator matches, silently and with no error.
Measured against document.evaluate() on a build of main
(a73da68b), fixture served over http. The only difference between a
run that matches native and a run that does not is one unrelated
attachShadow() call elsewhere in the same document:
| XPath | document.evaluate() |
Stagehand |
|---|---|---|
//button[text()='Save'] |
1 | 2 |
//div[text()='a'] |
1 | 0 |
//div[contains(text(),'b')] |
0 | 1 |
//div[@id='split'][text()='y'] |
1 | 0 |
//div[@id='split'][contains(text(),'y')] |
0 | 1 |
//div[@id='split'][normalize-space(text())='x'] |
1 | 0 |
//button[.='Save'] |
2 | 2 (control: . is already correct) |
Fixture: <button id="wrapped"><span>Save</span></button> before
<button id="direct">Save</button>, plus <div id="mixed">a<span>b</span></div> and <div id="split">x<br/>y</div>.
The count is not the worst part. The button whose label sits inside a
<span> comes first in document order, so //button[text()='Save']
returns it first and .first().click() clicks the wrong button. Nothing
throws, nothing logs, and the run continues on the wrong element. The
other direction is a silent zero on markup as ordinary as
a<span>b</span>.
text() now reads its own node-set, and . keeps exactly the meaning
it has today:
text()='v' is true when any direct child text node equals v.contains(text(),'v') and normalize-space(text())='v' read the.='v', contains(.,'v') and normalize-space(.)='v' keep readingMechanically, in packages/extension/dom/locatorScripts/xpathParser.ts:
the three patterns that accepted (?:text\(\)|\.) now capture which
token they matched, and textEquals / textContains carry a source: "self" | "text" field that evaluatePredicate reads. The field is
optional and absent means self, so predicates constructed anywhere
else keep their current behavior. and, or and not carry it through
without changes.
packages/extension/tests/xpath-text-predicates.test.ts (new, unit):
the parser keeps text() and . apart for =, contains() and
normalize-space(), and carries the source through or and not.
packages/sdk-ts/tests/integration/locatorXPathTextPredicates.test.ts
(new, integration): the table above against real Chrome. It has to be
served over http, since data: URLs stay on the native engine and never
reach this parser at all. Registered in scripts/test-integration.ts
next to the other locator groups.
Both are red on main and green with the change. On main the
wrong-button case fails with expected 2 to be 1 and the silent-zero
case with expected +0 to be 1.
Context: #1679 consolidated the parser copies and #1683 taught this one
text(), contains() and normalize-space(). This is the same layer,
one step further in.
Fixes the composed-tree XPath parser so text() reads only direct child
text nodes. Previously it read element.textContent (same as .),
causing diverging matches and wrong clicks on pages with any shadow
root.
text() behaved like .. New: text() evaluates direct child. still reads the element's subtree string-value. Thisdocument.evaluate().text() to match nested text, use . instead.text()='v' is existential across child text nodes;contains(text(),'v') and normalize-space(text())='v' collapse to thescripts/test-integration.ts.Written for commit 482e0a9.
Summary will update on new commits.
Co-authored-by: Mikhail Koviazin mikhail.koviazin@gmail.com
Mirrored from external contributor PR #2738 after approval by @miguelg719 .
Mirrored from external contributor PR #2738 after approval by
@miguelg719.
Original author: @abhinavkr26104
Original PR: #2738
Approved source head SHA: e77c269fcc7ab33d2b76f213f26da62b77b1e826
@abhinavkr26104, please continue any follow-up discussion on this
mirrored PR. When the external PR gets new commits, this same internal
PR will be marked stale until the latest external commit is approved and
refreshed here.
The v4 init schema supplied https://example.com/v1/traces whenever
callers omitted telemetry. The extension treated that placeholder as an
intentional OTLP destination, creating guaranteed-failing background
exports and possible shutdown delays for otherwise default Stagehand
instances.
Fixes #2732
stagehand.init telemetry optional instead of injecting agit diff --checkMakes telemetry export opt-in so omitted telemetry no longer injects a
placeholder endpoint that caused guaranteed-failing exports and shutdown
delays. stagehand.init no longer defaults to
https://example.com/v1/traces; omitting telemetry leaves tracing
inert, while explicit telemetry keeps OTLP export.
stagehand.init.telemetry is now optional with no default;createStagehandTracing.configure accepts undefined andtelemetry from the wire when unset; Go'sStagehandInitParams.Telemetry is now *TelemetryConfig and omits theoptionalTelemetry, while CreateOptions.Telemetrytelemetry as Optional with theMigration
telemetry.traces.endpoint to an OTLP collector (ending in/v1/traces) with required headers to enable export.nil to omit telemetry or set a non-empty endpoint/headersStagehandInitParams construction now requires*TelemetryConfig.Written for commit fecc5a6.
Summary will update on new commits.
Co-authored-by: Abhinav Kumar Singh abhinav.kr.singh.2610@gmail.com
Co-authored-by: miguel miguelg71921@gmail.com
Co-authored-by: Miguel 36487034+miguelg719@users.noreply.github.com
clean up copy & test the editorial docs change workflow
Cleans up the introduction copy by removing redundant phrasing and tests
the editorial docs change workflow.
Written for commit aff9504.
Summary will update on new commits.
SDK changes must include documentation, but merging those docs into main should not publish unreleased APIs to the public site
SDK changes must include documentation, but merging those docs into
main should not publish unreleased APIs to the public site
main and a persistentmain. Report the URL and wait formain-only guards to SDK publishing jobs, including theSeparates docs previews from production publishing so unreleased API
docs aren't published to the public site.
main and persistentmain, reporting the URL and waiting formain-only guards to SDK publishing jobs.Written for commit 6fd167a.
Summary will update on new commits.
Browse can fail to connect to a healthy local Chrome because it trusts an old browser connection URL saved in the profile's DevToolsActivePort file. T
Browse can fail to connect to a healthy local Chrome because it trusts
an old browser connection URL saved in the profile's
DevToolsActivePort file. The existing check only confirms that
something is listening on the cached port; it does not confirm that the
saved browser target still exists.
For example, the file points to
ws://127.0.0.1:9222/devtools/browser/old-id, while the running Chrome
exposes /devtools/browser/new-id. Browse selects old-id, and the
connection fails with a 404 or connection reset.
This PR checks the cached target against Chrome's live /json/version
response. If they disagree, Browse discards the stale candidate and uses
its existing live-endpoint fallback. It compares URL paths so
localhost versus 127.0.0.1 does not invalidate a matching target,
and probes each port only once per discovery call.
DevToolsActivePort file behind afterbrowse open --auto-connect or the discovery used bybrowse doctor.The port is reachable, so the old check accepts the file even though its
target is gone. A restart alone is not sufficient to trigger this: the
stale file must remain visible and its port must be reused.
Local browser attachment fails even though Chrome is running and its
debugging endpoint works. Users and agents cannot reliably reuse that
browser session, and diagnostics can select a dead endpoint. Validating
the browser target prevents leftover profile state from making a working
browser look broken.
This is a reproduced connection-correctness bug; we have not established
how frequently users encounter it.
Verification on September 23, 2026, for head b96dea6:
fbcdf6169 selected the stale target and failed with 404 /Browser.getVersion (Chrome/153.0.8010.12). This was a Linux ChromiumThe diff contains the discovery fix, its regression tests, and a Browse
patch changeset. The PR targets main.
Release Browse independently of the Stagehand SDKs. Merging this PR publishes the CLI from the merged commit.
Release Browse independently of the Stagehand SDKs. Merging this PR
publishes the CLI from the merged commit.
#3021
2c098f4
Thanks @AzamAbdul! - Add browse functions secrets attach to attach an existing project secret to a
function by ID.
#3021
2c098f4
Thanks @AzamAbdul! - Add browse cloud secrets create with public-key lookup, local encryption, and secret
input from stdin, a named environment variable, or a hidden prompt.
#3021
2c098f4
Thanks @AzamAbdul! - Add browse functions secrets detach to remove a function-secret attachment without
deleting the project secret.
#3021
2c098f4
Thanks @AzamAbdul! - Add commands to
retrieve project secret metadata and delete a project secret by ID.
#3021
2c098f4
Thanks @AzamAbdul! - Add browse functions secrets list to list attached secret metadata with cursor
pagination and creation-time filters.
#3021
2c098f4
Thanks @AzamAbdul! - Add browse cloud secrets list to list project secret metadata with pagination and date
filters.
#3021
2c098f4
Thanks @AzamAbdul! - Add browse cloud secrets update to replace a secret value by ID with local encryption
and stdin, environment variable, or hidden prompt input.
21f4443Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
[fix]: wait for the locator world when a deep XPath crosses an iframe…
[fix]: wait for the locator world when a deep XPath crosses an iframe…
browse templates clone playwright passes the public catalog slug playwright to the scaffolder, although the catalog entry identifies its source as pla
browse templates clone playwright passes the public catalog slug
playwright to the scaffolder, although the catalog
entry identifies
its source as playwright/quickstart-playwright. The scaffolder expects
quickstart-playwright. Puppeteer and Selenium have the same mismatch.
The printed setup instructions also ignore the generated project's
package manager and Python environment: TypeScript always gets npm
commands, and Python can get uv sync followed by bare python main.py.
Users select a valid catalog template but can receive the wrong project
or instructions that run outside its dependency environment. The CLI
should translate the catalog's public identifier into the source
identifier and print commands consistent with the generated project.
This change targets V4 main and:
sourcePath, falling back toslug when absent. For example, playwright/quickstart-playwrightquickstart-playwright; an entry without sourcePath keeps itspackage.json#packageManager to choose npm, pnpm, yarn, or bunuv sync for a Python project, or uv venv && uv pip install -r requirements.txt for requirements, then uv run python main.py.README dependency parsing is outside this change; README-only Python
dependency instructions remain a separate follow-up.
Validated on September 23, 2026, against V4 main
2c098f44857665045dbed31168ac36af920774d9:
d35dd22 produced the Playwright project. OnlyPublished Node create-browser-app@3.0.0 still silently generates the
basic Stagehand starter for the corrected nested template name. The live
check reproduced this. That separate bug is fixed in merged
create-browser-app
#43, but
release PR
#44,
proposing 3.0.1, is still open. Publish that release before shipping
this as a complete TypeScript quickstart fix. Browse already invokes
create-browser-app@latest, so no dependency pin changes are needed
here.
Browse needs commands to manage project secrets and attach them to Functions. The seven component PRs were merged into agent/browse-v4-7-context-names
Browse needs commands to manage project secrets and attach them to
Functions. The seven component PRs were merged into
agent/browse-v4-7-context-names; this PR brings those changes onto
current main at fbcdf61.
browse cloud secrets commands to list, get, create, update, andbrowse functions secrets commands to attach, detach, and listCherry-picked in order from #2946, #2949, #2967, #2990, #3006, #3007,
and #3009. All seven applied without conflicts. The secrets
implementation is unchanged from the original branch. This branch
retains main's Browse 0.10.0 release and excludes the old parent
branch's context-name and eval changes.
Validated locally on macOS with Node 24.18.0 and pnpm 11.23.0:
pnpm install --frozen-lockfile — passed.pnpm exec turbo run build --filter=browse — all four tasks passedpnpm --filter browse lint — formatting, ESLint, and TypeScriptpnpm --filter browse test:cli — 36 files / 471 tests passed, usingpnpm exec node --import tsx scripts/release/check-changesets.ts andgit diff --check — passed.Validation covers the built CLI and local contract fixtures; no
production secrets were created or modified.
Co-authored-by: cubic-dev-ai[bot] <191113872+cubic-dev-ai[bot]@users.noreply.github.com>
Release Browse independently of the Stagehand SDKs. Merging this PR publishes the CLI from the merged commit.
Release Browse independently of the Stagehand SDKs. Merging this PR
publishes the CLI from the merged commit.
38e3a20--return-xpath option fromReleases browse@0.10.0, publishing the Browse CLI independently from
the Stagehand SDKs.
--return-xpath option from coordinate actions; scriptsWritten for commit 4210c97.
Summary will update on new commits.
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Browse currently shares the SDK release PR and publisher. This separates it into a Release browse@… PR on release/browse and an independent publishing
Browse currently shares the SDK release PR and publisher. This separates
it into a Release browse@… PR on release/browse and an independent
publishing job. The remaining packages retain the existing Stagehand
release group, including Python/Go releases and SDK alphas.
The coordinator uses Changesets' official release planner, changelog
writer, and publisher. It selects changesets by group and temporarily
excludes other public packages from publishing. It also prevents pending
Browse notes from blocking SDK publication. Already published Browse
versions skip rebuilding, so an SDK version bump does not unnecessarily
block the CLI job.
A feature PR can change both Browse and SDK code. It needs two
changeset files, because merging either release PR must leave the
other group's notes available. The mixed-file rejection protects that
ownership boundary; most new tests exercise successful independent
releases.
Git, pnpm, and GitHub CLI operations use argument arrays without a
shell. GitHub PR creation/update is custom coordination; version
calculation and changelog generation remain Changesets' responsibility.
| Command / flow | Observed output | Confidence / sufficiency |
|---|---|---|
pnpm exec vitest run scripts/release |
67 passing tests | Both |
| release orders, retained notes/manifests, SDK-only snapshots, | ||
| mixed/pre-mode rejection, restoration after publish success/failure, | ||
| registry failures, Python/Go gates | ||
pnpm --filter browse test:cli |
395 passing tests | Existing CLI |
| suite passes | ||
pnpm exec turbo run build --filter=browse |
**4 successful build | |
| tasks** | Protocol, extension, SDK, and CLI build together | |
Real pending changesets: version cli |
**Browse 0.10.0; SDK stays | |
| 4.1.0; exactly 3 changed files** | Actual Changesets engine and | |
| authenticated GitHub changelog generation; SDK notes retained | ||
Real pending changesets: version sdk, consolidation, Python sync, |
||
uv lock |
SDK 4.2.0; Browse stays 0.9.6 | CLI note and manifest |
| preserved | ||
prepare-cli-release.ts, twice against a local bare Git remote |
||
| Create/update both produce a 3-file Browse release | Actual | |
| versioning, commits, branch creation, and force-with-lease push. GitHub | ||
| PR API calls were intercepted; live release-PR automation remains | ||
| unproven | ||
Actual publish cli using pnpm 11.10 and an isolated registry |
||
| browse@0.10.0 published; SDK endpoint remains 404 | Real tarball | |
| upload and Git tag; does not exercise production OIDC | ||
Actual publish sdk using a second isolated registry |
**SDK 4.2.0 | |
| published; Browse endpoint remains 404** | Proves SDK publisher excludes | |
| Browse despite pending CLI notes | ||
| Repeat both publish commands | No unpublished projects to publish | |
| No duplicate upload; manifests restored after publishing | ||
SDK snapshot build and publish sdk --alpha |
**4.2.0-alpha- | |
| published; latest stays 4.2.0; Browse absent** | Real alpha publication | |
| and dist-tag isolation | ||
| Install the published Browse tarball outside the workspace | ||
| browse/0.10.0 with SDK 4.1.0 from public npm | Tests the | |
| distributable against a released SDK, not a workspace link | ||
| Installed tarball: local Chrome and Browserbase, | ||
| open/eval/snapshot/stop | **Both return “Example Domain”, expose its | |
| heading, and stop successfully** | Real browser runtime smoke on | |
| example.com; local container required Chrome's no-sandbox flag | ||
GitHub CI on final review fixes (0acad1acc) |
**51 successful | |
| checks, 6 skipped, no failures or pending checks** | Full repository CI, | |
| including TypeScript/Python/Go and browser/integration checks; Cubic | ||
| completed without new findings | ||
| Review fix: registry dependency wait | **404 followed by 200 succeeds; | |
| timeout/503 fail; stalled request aborts** | Real HTTP-server tests, | |
| including a server that accepts a connection but never responds; only | ||
| CLI publication waits for its dependency | ||
| Review fix: partial publication and tag recovery | **5 tests pass | |
| against real Git checkouts/bare remotes and HTTP** | Covers missing | |
| upload, accepted upload without tag, remote-tag retry, original local | ||
| tag, and refusal to tag a later/wrong-version commit | ||
| Review fix: standalone smoke after deleting CLI dist/manifest | ||
| Build, pack, isolated install, version/help/open-help pass | Proves | |
| the script rebuilds its own artifacts | ||
| Frozen pnpm 11.10 install, tooling typecheck/lint/format, actionlint | ||
| Pass | Lockfile and workflow syntax validated | |
| Inspect current npm provenance for Browse 0.9.6 and SDK 4.1.0 | **Both | |
identify .github/workflows/release.yml on main** |
New CLI job | |
| preserves the existing workflow identity; this does not prove the next | ||
| OIDC exchange |
The isolated registry tests explicitly set package publish registries to
loopback addresses in disposable checkouts. Those overrides are absent
from this PR. No public npm publication or merge was performed.
Merge this infrastructure before either pending release PR. Let the next
Release run regenerate the existing combined Stagehand PR without Browse
and create the Browse-only PR; inspect both diffs before merging either.
Browse retains workspace:* for the SDK. Packing resolves that to the
workspace SDK's exact version, which must be published before Browse.
The CLI publication path waits up to 15 minutes for a concurrent SDK
upload, without depending on unrelated SDK jobs. A CLI change requiring
unreleased SDK functionality still needs an SDK release first. The
clean-install smoke checks entry points; the manual browser smoke is
broader, but neither proves every CLI command.
My current estimate is 90% confidence in the first production release
succeeding, with higher confidence in the version/publish isolation
itself. Production npm OIDC and the GitHub Actions release-PR lifecycle
remain the main unexercised paths. Tag recovery runs after partial
publish failures; if both the remote and local tag are missing, retry
the original version-bump workflow so recovery never labels a later main
commit as the release. Full GitHub CI and Cubic review passed on the
latest commit (0acad1acc). All 15 review threads have replies. The
updated local release suite, smoke script, typecheck, lint, format, and
actionlint passed.
v4 shipped with server-side caching opt-in , where v3 had it on by default. Anyone who upgraded without passing cache lost caching without an error.
v4 shipped with server-side caching opt-in, where v3 had it on by
default. Anyone who upgraded without passing cache lost caching
without an error.
Both defaults flip to true, so v4 matches v3: caching runs unless the
instance or the call opts out.
v4/best-practices/caching.mdx described opt-in, which this makes
wrong.
The v3 migration guide also mapped enableCaching → cache.
enableCaching was a v2-era local option that v3 had already
replaced with cacheDir; the server-side option v3 users actually had
was serverCache, which appeared nowhere in the v4 docs. Corrected the
mapping and the diff example.
🤖 Generated with Claude Code
Fixes AP-2925 by restoring v3's caching default in v4: caching was
opt-in and is now enabled unless the instance or call opts out. This
prevents upgrades from silently losing caching; the server's project
feature flag still controls availability.
serverCache to cache andenableCaching/cacheDir mappings; updates cachingDISABLED status, the stagehand.actcreate() examples that show the default doing thecache: false on calls carrying credentials.Written for commit a4ee44f.
Summary will update on new commits.
Co-authored-by: Claude Opus 5 (1M context) noreply@anthropic.com
Remove the unsupported --return-xpath option from Browse's coordinate click, hover, scroll, and drag commands. The CLI rejects the flag, and strict dr
Remove the unsupported --return-xpath option from Browse's coordinate
click, hover, scroll, and drag commands. The CLI rejects the flag, and
strict driver schemas reject stale returnXPath payloads before
performing a mouse action. Update the examples and the Browse minor
changeset for the V4 migration and flag removal.
XPath selectors and snapshot xpathMap remain supported.
The cursor overlay (#2869) and network sidecar (#2849) are already
merged into main. This branch includes the final parent and reconciles
its squash merge, preserving the current cursor fixes. The final diff
against main is 8 files, +17/−62, limited to the XPath flag
removal, documentation, removal of the obsolete XPath test, and release
metadata.
db5e592ce4359e1340ef4e921aad4b98581ee94a: focused driver-commandgit diff --check passed.c15d1ef8ca8a53a25a2f5f05722ef45df9a89605, which passed a frozen--return-xpathNonexistent flag, without starting a daemon.Restore Browse V3 network-capture behavior on Stagehand V4 through a CLI-private CDP sidecar, without committing core Stagehand, its protocol, or gene
Restore Browse V3 network-capture behavior on Stagehand V4 through a
CLI-private CDP sidecar, without committing core Stagehand, its
protocol, or generated SDKs to a public network-event schema.
--return-xpath; supported V3 parity/releaseon / off /send session shape.network off, remove listeners, send Network.disable, and detachThe request correlation and request/response JSON writer are inherited
from the V3 CLI. No public protocol schema, extension, SDK, or
generated-client changes are included. #2832 remains open outside the
landing stack for that separate API-design discussion.
The V3 command and file surface is retained:
browse network on
browse network path
browse network clear
browse network offEach request directory contains request.json and, when available,
response.json, including the existing treatment of POST bodies,
response bodies, failures, redirects, cache hits, and binary responses.
Full post-propagation implementation verification ran against exact
clean #2849 head adbe80d8bbfc337fea9dc38e41a88da18c287046. Its
seven-file network patch has the same stable patch ID
(f062ac789108ddf640bc912776dafa210411f50c) as the previously
stress-tested head, so the deterministic V3/V4 and MSN/CNN evidence
below applies unchanged. Frozen install, fresh builds, focused/full
tests, and the real Browserbase lifecycle were rerun on adbe80d8b.
Current review-fix head 9887732b6f0c32cdef0966ebfd2ac2c454321d4b
changes only the test helper timeout diagnostic; on that exact head, the
targeted network-capture tests passed 2/2 and Browse formatting, ESLint,
and TypeScript checks passed. The comparison CLI was the exact built V3
implementation at 7365a20d52955c10d72606f2e6ddd74791609d13. Every CLI
flow used a unique daemon directory; no pre-existing daemon was reused
or stopped.
| Command / flow | Observed output | Confidence / sufficiency |
|---|---|---|
pnpm install --frozen-lockfile; build extension, local Stagehand |
||
SDK, then browse |
Frozen install and all three builds passed; the CLI | |
| manifest was generated from the tested workspace. | Proves the clean | |
| stacked head installs from its lockfile and the subprocess tests | ||
exercised fresh V4 SDK/extension/CLI artifacts, not stale dist output. |
|
| Built V3 vs built V4 deterministic fixture: open → network on → eval(GET, cached GET twice, POST, redirect, binary, abort) → path → off → path → clear → stop | V3: 8 requests / 7 responses. V4: 8 requests /
7 responses. Evaluation results matched; normalized request/response
diff count was 0; command-shape diff was []; clear left 0 entries
for both. | Exact parity for the stable V3 command and on-disk contract.
Normalization was limited to request ID, timestamp/duration, HTTP
Date, and fixture origin/port. |
| Concurrent real CLI enables: two browse network on subprocesses
launched together, followed by one marked navigation | One subprocess
returned { enabled: true }; the other returned { alreadyEnabled: true, enabled: true }. The marked navigation produced exactly 1 request
record with 1 unique request ID. | Proves overlapping network on calls
serialize and attach listeners once rather than duplicating capture. |
| Real CLI on → navigate → off → on → navigate → off without clearing
| The two records were numbered 000 and 001; both URLs remained
present, and the SHA-256 of the first request.json was unchanged after
the second cycle. | Proves off/on resumes at the next on-disk counter
and does not overwrite retained captures. |
| Real CLI permissions and lifecycle | Capture directories were 0700;
request.json and response.json were 0600; network clear left 0
entries; browse stop reported stopped. | Proves the V3 private-file
contract and cleanup behavior through the built CLI. |
| Real Browserbase, two network on → open Example Domain → off cycles
in one session, then navigation with capture off | Both cycles captured
GET 200 and the complete Example Domain body; the Browserbase session
stayed stable; post-off open --wait networkidle worked; final status
was connected, initialized, and remote; stop completed. | Proves the
auxiliary sidecar survives real remote off/on while the owning Stagehand
browser remains usable. No session ID or signed endpoint is included
here. |
| Real Browserbase stress, V3 and V4, public MSN then CNN; each cycle
ran on → path → open → scroll → collect 12s → off → path → navigate while off → status → clear | All 21 commands completed for each CLI. V3
captured MSN 415/401 and CNN 192/187 request/response records. V4
captured MSN 498/481 and CNN 194/187. Across all four cycles: 0
malformed request JSON, 0 malformed response JSON, 0 response-ID
mismatches, 0 new records after off, and 0 entries after clear. Both
sessions stayed remote/connected, stopped cleanly, and emitted no
WebSocket endpoint. | Proves bounded high-concurrency, cross-origin
Document/Script/Fetch/XHR/Image/Font/Media traffic. Live request counts
are intentionally not expected to match because sites and ad auctions
are nondeterministic; contract invariants and command shapes matched. |
| pnpm --filter browse lint | Passed formatting, ESLint, and
TypeScript checks at full-verification head adbe80d8b; passed again at
current review-fix head 9887732b6. | Static support for both the fully
exercised implementation head and the exact current head. |
| pnpm --filter browse test with isolated daemon directory | At
full-verification head adbe80d8b: 27 files / 390 tests passed;
focused network subset: 3 files / 30 tests passed. At current
review-fix head 9887732b6: targeted network-capture tests passed
2/2. | Covers sidecar routing, response bodies, listener teardown,
attach/detach, request-write races, counter reuse, and overlapping
enable serialization in addition to the real flows above; the
current-head rerun is scoped to the test-only diagnostic change. |
The deterministic artifact comparison includes method, URL/path,
request/response headers and bodies, status/status text, MIME type,
resource type, error shape, counter naming, and file modes. The live
stress test also observed GET/POST/OPTIONS, failures, base64 bodies,
cross-origin documents, and request-only records for traffic still in
flight at the bounded off point.
This matrix does not claim WebSocket-frame, SSE-message, service-worker,
or every out-of-process-iframe edge-case coverage; those are outside the
V3 JSON request/response file contract proven here.
Restore the original Trendshift badge below the README badges.
Documentation-only change.
Restores the Trendshift badge below the existing README badges and adds
a linked screenshot of the Stagehand website stored as
media/stagehand-website-banner.png with transparent rounded corners.
Simplifies the header tagline to "Stagehand is the SDK for browser
agents" (no trailing period). Documentation-only change with no behavior
or dependency impact.
Written for commit a68ee08.
Summary will update on new commits.
Mirrored from external contributor PR #2987 after approval by @miguelg719 .
Mirrored from external contributor PR #2987 after approval by
@miguelg719.
Original author: @antonvishal
Original PR: #2987
Approved source head SHA: ff8d7771e96c597b1adbcf7819fbe179b84d640a
@antonvishal, please continue any follow-up discussion on this mirrored
PR. When the external PR gets new commits, this same internal PR will be
marked stale until the latest external commit is approved and refreshed
here.
The Python SDK excluded generated models from ty, leaving
schema-to-Python typing errors undetected. Upgrading to ty 0.0.82 also
exposed type errors in Chrome process handling. Since generated models
ship as part of the typed SDK, these issues can affect downstream type
checking.
@override decorators, and run ty immediately after Python generation.Verified with generate.py --check, ty, Ruff, the Python test suite
(531 passed, 1 skipped), and just check.
Starts type-checking generated Python SDK models and upgrades and pins
ty to 0.0.82. The generated models were previously excluded from ty,
so schema-to-Python typing errors went undetected and could affect
downstream type checking.
ty rules for override enforcement and return@override decorators and typing_extensions as aty as part of just generate.Written for commit ff8d777.
Summary will update on new commits.
Co-authored-by: Vishal Anton vishalanton@appexert.com
Co-authored-by: VIshal Anton 166398166+antonvishal@users.noreply.github.com
The TypeScript unit job currently runs turbo run test:unit and then runs root vitest run . The second command repeats the package unit tests, so this
The TypeScript unit job currently runs turbo run test:unit and then
runs root vitest run. The second command repeats the package unit
tests, so this change removes it along with the unused Chrome output ID.
Chrome setup and the separate browser job remain unchanged.
The baseline repeated root Vitest step took 81 seconds after Turbo
unit tests had already completed. With this change, the TypeScript unit
job took 2m 53s, compared with 4m 16s in the baseline.
We verified that removing the root Vitest run does not drop the relevant
unit coverage:
test:unit tasks collectpackages/sdk-ts/tests/browser-runtime, which is already covered by thetest:browser task.BROWSERBASE_SMOKE=1.test:unit command rather than replacingOn a branch based on the current upstream main:
pnpm install --frozen-lockfile passedpnpm build — 14 tasks passedpnpm check — 36 tasks passedpnpm exec turbo run test:unit — 33 tasks passedThe only fork limitation is the Browserbase smoke test, which requires
BROWSERBASE_API_KEY.
Removes the duplicate root vitest run step from the TypeScript unit
job so package unit tests run only once. The browser-runtime specs that
root Vitest picked up are already covered by the browser-ts job, so
coverage is unchanged.
Written for commit de3f999.
Summary will update on new commits.
Nothing published for this version
This PR was opened by the Changesets release GitHub action. When you're ready to do a release, you can merge this and the packages will be published t
This PR was opened by the Changesets
release GitHub action. When
you're ready to do a release, you can merge this and the packages will
be published to npm automatically. If you're not ready to do a release
yet, that's fine, whenever you add more changesets to main, this PR will
be updated.
e2c8946#2827
6555e81
Thanks @seanmcguire12! - make
browser.close() and browser.context.close() always terminate the browser
regardless of keepAlive.
#2878
50146e4
Thanks @seanmcguire12! - support
discovering and invoking WebMCP tools in out-of-process iframes (OOPIFs)
#2912
67a4668
Thanks @miguelg719! - Fail fast on
protocol compatibility errors
#2790
1011177
Thanks @seanmcguire12! - fail fast
on browserbase.connect() when extension is not present
#2818
341433a
Thanks @seanmcguire12! - make
stagehand.close() preserve the browser and allow another Stagehand
instance to attach later
#2754
a21633d
Thanks @monadoid! - remove the redundant
image type from page screenshot protocol responses.
#2827
6555e81
Thanks @seanmcguire12! - make
browser.close() and browser.context.close() always terminate the browser
regardless of keepAlive.
#2754
a21633d
Thanks @monadoid! - remove the redundant
image type from page screenshot protocol responses.
e2c8946#2827
6555e81
Thanks @seanmcguire12! - make
browser.close() and browser.context.close() always terminate the browser
regardless of keepAlive.
#2878
50146e4
Thanks @seanmcguire12! - support
discovering and invoking WebMCP tools in out-of-process iframes (OOPIFs)
#2912
67a4668
Thanks @miguelg719! - Fail fast on
protocol compatibility errors
#2790
1011177
Thanks @seanmcguire12! - fail fast
on browserbase.connect() when extension is not present
#2818
341433a
Thanks @seanmcguire12! - make
stagehand.close() preserve the browser and allow another Stagehand
instance to attach later
#2754
a21633d
Thanks @monadoid! - remove the redundant
image type from page screenshot protocol responses.
#2864
d2d9169
Thanks @seanmcguire12! - Make python
and golang SDKs reject occupied local chrome debugging ports, and make
local browser launch wait for readiness in python.
e2c8946#2827
6555e81
Thanks @seanmcguire12! - make
browser.close() and browser.context.close() always terminate the browser
regardless of keepAlive.
#2878
50146e4
Thanks @seanmcguire12! - support
discovering and invoking WebMCP tools in out-of-process iframes (OOPIFs)
#2912
67a4668
Thanks @miguelg719! - Fail fast on
protocol compatibility errors
#2790
1011177
Thanks @seanmcguire12! - fail fast
on browserbase.connect() when extension is not present
#2818
341433a
Thanks @seanmcguire12! - make
stagehand.close() preserve the browser and allow another Stagehand
instance to attach later
#2754
a21633d
Thanks @monadoid! - remove the redundant
image type from page screenshot protocol responses.
#2864
d2d9169
Thanks @seanmcguire12! - Make python
and golang SDKs reject occupied local chrome debugging ports, and make
local browser launch wait for readiness in python.
#2827
6555e81
Thanks @seanmcguire12! - make
browser.close() and browser.context.close() always terminate the browser
regardless of keepAlive.
#2878
50146e4
Thanks @seanmcguire12! - support
discovering and invoking WebMCP tools in out-of-process iframes (OOPIFs)
#2818
341433a
Thanks @seanmcguire12! - make
stagehand.close() preserve the browser and allow another Stagehand
instance to attach later
#2754
a21633d
Thanks @monadoid! - remove the redundant
image type from page screenshot protocol responses.
@browserbasehq/stagehand-integrations-example-claude-code-facade@4.0.3
6555e81,50146e4,67a4668,1011177,341433a,a21633d,e2c8946]:
6555e81,50146e4,67a4668,1011177,341433a,a21633d,e2c8946]:
6555e81,50146e4,67a4668,1011177,341433a,a21633d,e2c8946]:
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
test: cross-version compatibility check against the last published ex…
test: cross-version compatibility check against the last published ex…
[fix]: fail fast on incompatible Stagehand runtime instead of polling…
[fix]: fail fast on incompatible Stagehand runtime instead of polling…
test: fix remaining release protocol handshake fixtures
test: fix remaining release protocol handshake fixtures (#2909)
test: make runtime compatibility fixtures resilient to protocol bumps…
test: make runtime compatibility fixtures resilient to protocol bumps…
Generalize the system and types to handle more than "console" events for Page.on listeners.
Generalize the system and types to handle more than "console" events
for Page.on listeners.
PageCDPEvent schema now has method: z.enum parameter."console")This refactor introduces no functional changes. We update existing tests
to in preparation for more events. All tests should continue passing.
before this PR, WebMCP tools registered inside of iframes were unable to be discovered or invoked
before this PR, WebMCP tools registered inside of iframes were unable to
be discovered or invoked
WebMCP tools registered in out-of-process iframes (OOPIFs) are now
discoverable and invokable; previously iframe tools were invisible and
unusable. Invocation, response handling, and cancellation use the CDP
session that owns the frame, while stale or detached frames fail instead
of falling back to the main frame.
Written for commit 2a0744a.
Summary will update on new commits.
expose Browserbase Search and Fetch through the TypeScript and Python browserbase facades
Implements AP-2921 by exposing Browserbase Search and Fetch through the
TypeScript and Python browserbase facades and Go's
SearchBrowserbase/FetchBrowserbase functions, without launching a
browser.
Written for commit 30fae44.
Summary will update on new commits.
This PR was opened by the Changesets release GitHub action. When you're ready to do a release, you can merge this and the packages will be published t
This PR was opened by the Changesets
release GitHub action. When
you're ready to do a release, you can merge this and the packages will
be published to npm automatically. If you're not ready to do a release
yet, that's fine, whenever you add more changesets to v4.0, this PR will
be updated.
ba73d4e@browserbasehq/stagehand-integrations-example-claude-code-facade@4.0.3
ba73d4e]:
ba73d4e]:
ba73d4e]:
ba73d4eba73d4eReleases Stagehand packages at 4.0.3 across the TypeScript, Python, and
Go SDKs and the integration facades. The SDKs now fail fast on protocol
compatibility errors, surfacing incompatible runtimes immediately
instead of failing later.
Written for commit 159babb.
Summary will update on new commits.
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
a prior merge commit left out the lockfile change which pinned the pnpm version
Adds the leftover pnpm-lock.yaml changes from a prior merge that
pinned the pnpm executable to version 11.10.0.
Written for commit 12e49a1.
Summary will update on new commits.
this PR addresses parity gaps in local launch behaviour:
this PR addresses parity gaps in local launch behaviour:
Go & Python also accepted an explicit debugging port without first
proving it was available. that could let launch continue toward a
browser endpoint the SDK did not own
about:blank, viewport behavior, & profile ownershipCHROME_PATH then platform candidates/json/version response with a non-emptywebSocketDebuggerUrl before a Python launch resolvestaskkill /T then /FCHROME_PATH, complete platform discovery order, unsupported platforms,Closes local browser-launching parity gaps across the Python, Go, and
TypeScript SDKs. Python previously returned after spawning Chrome and
could leave failed launches behind; it now waits for a usable CDP
endpoint, while Python and Go reject occupied debugging ports and all
SDKs treat empty profile paths as omitted.
Bug Fixes
Tests
Written for commit a7bccfa.
Summary will update on new commits.
feat(evals): add Cursor agent bench harness (integrations/cursor-sdk)…
feat(evals): add Cursor agent bench harness (integrations/cursor-sdk)…
the protocol package previously owned a repository-wide TypeScript config that also checked SDK TS, extension, & root tooling files. Turbo was still r
the protocol package previously owned a repository-wide TypeScript
config that also checked SDK TS, extension, & root tooling files. Turbo
was still running that typecheck as a protocol package task, so changes
outside the protocol package could reuse a stale cached result
giving each package ownership of its own TypeScript program makes the
check graph match the source graph, closes gaps in the old umbrella
config, & lets Turbo invalidate checks through declared workspace
dependencies
rules/ast-grep & scripts/releaseFixes stale Turbo typecheck caching by giving each package ownership of
its own TypeScript config. The protocol package previously ran a
repository-wide typecheck, so changes outside it could reuse a stale
cached result.
What changed
packages/protocol with@browserbasehq/stagehand-protocol subpath imports and declared theWritten for commit f514c26.
Summary will update on new commits.
Stacked on the codex-sdk extraction PR. Part 4 (final) of the harness consolidation stack — this closes the loop: evals now benchmarks the byte-identi
Stacked on the codex-sdk extraction PR. Part 4 (final) of the harness
consolidation stack — this closes the loop: evals now benchmarks the
byte-identical facade surface the claude-code/codex/pi integrations
ship.
New via:"mcp" tool surface stagehand_facade: the mount spawns the
shipped facade stdio server
(@browserbasehq/stagehand-integrations/facade/stdio-server) with an
allowlisted STAGEHAND_*/BROWSERBASE_* env (browser selection forced
to match the eval environment) and FACADE_AGENT_INSTRUCTIONS by
identity. Registered for both external harnesses, selectable alongside
stagehand_code (not replacing it). The facade server owns its browser
(tool_launch_local/tool_create_browserbase); evidence semantics
match the other external-MCP surfaces (verification via the tool_result
stream). Also ignores evals run artifacts (.trajectories/, rubric
cache) — generated output with session IDs that was dirtying trees.
evals run b:webvoyager --harness claude_code --tool stagehand_facade -l 1 -e browserbase → 3/3 trials complete, agentsmcp__stagehand__{run,snapshot,screenshot}, 2/3 graded pass,Adds stagehand_facade, an MCP tool surface that launches the shipped
facade stdio server so evals benchmark the exact surface integrations
ship. The facade owns its browser, verification uses the tool_result
stream, and it's selectable alongside stagehand_code for the agent
harnesses rather than replacing it.
stagehand_facade is mount-only: left out of the core tool list andclaude_code and codex harness mounts.FACADE_AGENT_INSTRUCTIONS andSTAGEHAND_BROWSER by environment, andstagehand_code, which was previously missing fromWritten for commit db42303.
Summary will update on new commits.
stagehand_facade no longer appears inlistCoreTools() or the TUI help — its CoreSession throws on everygetCoreTool for the agent harness mounts.Co-authored-by: Miguel Gonzalez miguel@browserbase.com
[refactor]: replace chrome-launcher with handrolled local browser l…
[refactor]: replace chrome-launcher with handrolled local browser l…
ci: restore regression evals on pull requests
ci: restore regression evals on pull requests (#2826)
browser.close() & browser.context.close() should both explicitly terminate the browser
browser.close() & browser.context.close() should both explicitly
terminate the browser
before this PR, browser.close() only terminated launched browsers when
keepAlive was false. keepalive browsers were disconnected, connected
local browsers did not receive Browser.close, & connected Browserbase
sessions were not released
browser.context.close() disposed worker state without terminating the
browser. this was semantically weird, because it was never really clear
what it was supposed to be "closing". it was not a full
stagehand.close(), nor was it a full browser.close(). this method is
being left in place so as to not break downstream callers, but it is now
just an alias for browser.close()
browser.close() & browser.context.close() invoke the same closecontext.close is also removed from the protocolkeepAlive value;Browser.close to connected local browsers;keepAlive only affects internal invalidation after initializationbrowser.close() when Stagehand.create()Stagehand.create() failure cleanup to invalidateBrowser.close handling for connected local browserscontext.closecontext.close operation from the protocol,Browser.close.context.close RPC.[fix]: make stagehand.close() dispose Stagehand without closing the…
[fix]: make stagehand.close() dispose Stagehand without closing the…
fix(ci): sync Python protocol for alpha releases
fix(ci): sync Python protocol for alpha releases (#2817)
No breaking changes. To adopt reattach behavior, upgrade the SDK and the extension together.
This PR was opened by the Changesets
release GitHub action. When
you're ready to do a release, you can merge this and the packages will
be published to npm automatically. If you're not ready to do a release
yet, that's fine, whenever you add more changesets to main, this PR will
be updated.
c0a2734c0a2734@browserbasehq/stagehand-integrations-example-claude-code-facade@4.0.2
c0a2734]:
c0a2734]:
c0a2734]:
c0a2734c0a2734Enables SDK clients to reattach to an initialized Stagehand extension
runtime to improve reconnection reliability. Previously, disconnects
required starting a new runtime; now clients can reattach to the
existing runtime without restarting.
@browserbasehq/stagehand@4.0.2,@browserbasehq/stagehand-python@4.0.2,@browserbasehq/stagehand-go@4.0.2, and@browserbasehq/stagehand-extension@1.0.1; updates all integrationstagehand-extension.zip) and version string.Written for commit 8f5ede6.
Summary will update on new commits.
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
This PR was opened by the Changesets release GitHub action. When you're ready to do a release, you can merge this and the packages will be published t
This PR was opened by the Changesets
release GitHub action. When
you're ready to do a release, you can merge this and the packages will
be published to npm automatically. If you're not ready to do a release
yet, that's fine, whenever you add more changesets to main, this PR will
be updated.
#2666
00fc44c
Thanks @miguelg719! - Allow overriding
the extension asset locations via STAGEHAND_EXTENSION_ARCHIVE_PATH and
STAGEHAND_EXTENSION_DIRECTORY_PATH
#2691
7e09557
Thanks @shrey150! - Track the Stagehand
SDK version in Browserbase session metadata.
00fc44c,7e09557]:
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Three fixes, all wanted before the 4.0.0 release run (merging this PR to main is itself the release trigger):
Three fixes, all wanted before the 4.0.0 release run (merging this
PR to main is itself the release trigger):
packages/core/CHANGELOG.md on the v3 branch (that history'sEBADDEVENGINES: devEngines.packageManager with onFail: "download" makes every npm command in the repo hard-fail (npm can'tchangeset publish preflightsnpm info (the publish itself uses pnpm publish, so catalog:getPublishTool). onFail: "warn" keeps the pnpm nudge withoutnpm info now succeeds in-repo.consolidate-changelogs.ts --check passes.
Rebuilt Stagehand around its v4 browser protocol and TypeScript SDK. Stagehand is now a protocol-first monorepo with TypeScript, Python, and Go SDKs over a shared core.
Check the migration guide for upgrading from v3.
Nothing published for this version
Your coding agent can read these notes before it upgrades. Set up the MCP server →