[fix]: discover extension automatically & deprecate extension id param
Merged
SE
14d ago+914+914+012345678901234567890123456789-216-216-012345678901234567890123456789
why
localBrowser.connect()currently loads the bundled extension even when Stagehand is already installed- the
extensionIdparam was also opaque (often confused with the browserbase extension ID), & users should not need to know what the extension ID is to connect to a browser
what changed
- discover the installed Stagehand extension before loading the bundle in TypeScript, Python, & Go
- load the bundled extension on local connect only when none is installed or discovery is unsupported
- keep disabled, ambiguous, & incompatible installations as errors
- deprecate and ignore extension IDs on local & Browserbase connect; supplied IDs no longer select an extension or bypass discovery
- keep Browserbase launch's uploaded-extension ID supported
- defer Python bundle lookup & Go extraction until fallback loading, with Go cleanup on failure & shutdown
test plan
cdpClient.test.ts,test_cdp_client.py, &cdp_client_test.gouse fake CDP responses to verify installed extensions are reused, missing extensions trigger loading, & unsupported discovery falls back only for local connections. disabled, ambiguous, malformed, & permission-error responses fail without loading.- factory tests in all three SDKs now check supplied & empty connect IDs are ignored and never forwarded to CDP. Browserbase connect always selects discovery, while launch keeps its uploaded-extension ID & client options.
- Python tests verify bundle lookup is deferred & cancellation during discovery or loading closes the connection. Go tests verify extraction happens only on fallback, its directory stays available during initialization, & cleanup runs once on close, initialization failure, or cancellation.
- connection tests verify discovered IDs select the correct worker & incompatible runtimes fail without loading a replacement. loading failures propagate without retrying, & cancellation prevents further loading work.
localExtensionDiscovery.test.tsruns against real Chrome with & without Stagehand already installed. it connects with an ignored ID, opens a page through Stagehand, & checks that the browser has exactly one Stagehand installation, preserving the existing installation's ID when reusing it
Summary by cubic
Local connects now discover an installed Stagehand extension before falling back to the bundled one, and the extensionId parameter on connect calls is deprecated and ignored across all SDKs.
- Reuses the installed extension in local and Browserbase connections, falling back to loading the bundled extension only for local connects when none is installed or discovery is unsupported.
- Disabled, ambiguous, malformed, and permission-error extension inventories fail without loading a fallback.
localBrowser.connect()andbrowserbase.connect()ignore extension IDs, including empty strings, and always discover; Browserbase launch keeps its uploaded-extension ID.- TypeScript connect options accept the ignored
extensionIdat the type level, so code can passundefinedor an empty string without compiler errors. - Python and Go defer bundle lookup/extraction until fallback loading, with Go cleanup on failure and shutdown.
- Users no longer need to know the extension ID to connect.