Skip to content

Conversation

@dhanushchalicheemala
Copy link

@dhanushchalicheemala dhanushchalicheemala commented Jan 10, 2026

why :

In env: "LOCAL" mode, Stagehand always launches Chrome on a random CDP debugging port. This makes it hard to attach external tools or configure chrome://inspect with a fixed port.

what changed :

  • Add an optional port?: number to LocalBrowserLaunchOptions.
  • Thread this value through to the local Chrome launcher and pass it as the port option to chrome-launcher.
  • Update V3 docs to document localBrowserLaunchOptions.port.

Usage

const stagehand = new Stagehand({
env: "LOCAL",
localBrowserLaunchOptions: {
headless: true,
port: 9222,
},
model: "openai/gpt-4.1-mini",
});

Test plan

  • pnpm --filter @browserbasehq/stagehand run build
  • pnpm --filter @browserbasehq/stagehand lint (passes)
  • pnpm --filter @browserbasehq/stagehand test:vitest

Summary by cubic

Adds an optional localBrowserLaunchOptions.port to pin the local Chrome CDP debugging port in LOCAL mode. This makes it easy to attach external tools or use chrome://inspect with a fixed port, while keeping the default random port if unset.

  • New Features
    • Added port?: number to LocalBrowserLaunchOptions and passed it through launchLocalChrome to chrome-launcher.
    • Updated docs to describe localBrowserLaunchOptions.port and its usage.

Written for commit b27abed. Summary will update on new commits.

@changeset-bot
Copy link

changeset-bot bot commented Jan 10, 2026

⚠️ No Changeset found

Latest commit: b27abed

Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. If these changes should result in a version bump, you need to add a changeset.

This PR includes no changesets

When changesets are added to this PR, you'll see the packages that this PR includes changesets for and the associated semver types

Click here to learn what changesets are, and how to add one.

Click here if you're a maintainer who wants to add a changeset to this PR

@greptile-apps
Copy link
Contributor

greptile-apps bot commented Jan 10, 2026

Greptile Overview

Greptile Summary

This PR adds a configurable port parameter to LocalBrowserLaunchOptions for Stagehand V3, allowing users to specify a fixed CDP debugging port when running in LOCAL mode. Previously, Chrome was always launched on a random port, making it difficult to attach external debugging tools or configure chrome://inspect with a fixed port.

Changes Overview

The implementation properly threads the optional port parameter through three layers:

  1. Type Definition (api.ts): Added port: z.number().optional() to the Zod schema for LocalBrowserLaunchOptions
  2. Launch Layer (local.ts): Added port?: number to the internal LaunchLocalOptions interface and passes it to the chrome-launcher library
  3. Orchestrator (v3.ts): Threads lbo.port from user options through to launchLocalChrome()
  4. Documentation (stagehand.mdx): Documents the new parameter with usage examples

Implementation Quality

The implementation is clean and follows established patterns in the codebase:

  • The parameter is consistently optional throughout the chain
  • Type safety is maintained via Zod validation
  • The parameter is passed directly to chrome-launcher without transformation
  • When unset, chrome-launcher uses its default behavior (random port)
  • Documentation clearly explains the use case

Minor Issue

One style issue found: extra space in documentation text ("When set ," should be "When set,").

Confidence Score: 5/5

  • This PR is safe to merge with minimal risk - it's a straightforward additive change with proper type safety
  • The implementation is clean, well-typed, and follows existing patterns. The change is purely additive (optional parameter), maintains backward compatibility, and delegates to the well-tested chrome-launcher library. Only one minor style issue (extra space in docs) was found.
  • No files require special attention - all changes are straightforward parameter threading

Important Files Changed

File Analysis

Filename Score Overview
packages/core/lib/v3/launch/local.ts 5/5 Added optional port parameter to LaunchLocalOptions interface and correctly passes it to chrome-launcher. Implementation is straightforward and safe.
packages/core/lib/v3/types/public/api.ts 5/5 Added port field to LocalBrowserLaunchOptionsSchema with correct Zod validation. Type definition is sound and consistent with other optional numeric fields.
packages/core/lib/v3/v3.ts 5/5 Correctly threads the port parameter from LocalBrowserLaunchOptions through to launchLocalChrome. No logic changes, just proper parameter forwarding.
packages/docs/v3/references/stagehand.mdx 4/5 Documents the new port parameter with clear description of its purpose. Minor typo with extra space after "set".

Sequence Diagram

sequenceDiagram
    participant User
    participant V3
    participant launchLocalChrome
    participant ChromeLauncher as chrome-launcher

    User->>V3: new Stagehand({ env: "LOCAL", localBrowserLaunchOptions: { port: 9222 } })
    User->>V3: init()
    activate V3
    
    V3->>V3: Extract lbo.port from localBrowserLaunchOptions
    V3->>launchLocalChrome: launchLocalChrome({ port: 9222, ... })
    activate launchLocalChrome
    
    launchLocalChrome->>ChromeLauncher: launch({ port: 9222, chromePath, chromeFlags, userDataDir })
    activate ChromeLauncher
    ChromeLauncher-->>ChromeLauncher: Start Chrome on specified port 9222
    ChromeLauncher-->>launchLocalChrome: { port: 9222, ... }
    deactivate ChromeLauncher
    
    launchLocalChrome->>launchLocalChrome: waitForWebSocketDebuggerUrl(chrome.port, timeout)
    launchLocalChrome-->>V3: { ws, chrome }
    deactivate launchLocalChrome
    
    V3->>V3: Create V3Context with WebSocket URL
    V3-->>User: Initialized (Chrome listening on port 9222)
    deactivate V3
    
    Note over User,ChromeLauncher: External tools can now connect to chrome://inspect on port 9222
Loading

Copy link
Contributor

@greptile-apps greptile-apps bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

1 file reviewed, 1 comment

Edit Code Review Agent Settings | Greptile

Comment on lines 126 to 127
<ParamField path="port" type="number" optional>
When set , the browser will always listen on this port, making it easy to attach external tools or configure
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There's an extra space after "set" in the description. The text should read "When set, the browser will..." instead of "When set , the browser will...".

Suggested change
<ParamField path="port" type="number" optional>
When set , the browser will always listen on this port, making it easy to attach external tools or configure
When set, the browser will always listen on this port, making it easy to attach external tools or configure
Prompt To Fix With AI
This is a comment left during a code review.
Path: packages/docs/v3/references/stagehand.mdx
Line: 126:127

Comment:
There's an extra space after "set" in the description. The text should read "When set, the browser will..." instead of "When set , the browser will...".

```suggestion
      When set, the browser will always listen on this port, making it easy to attach external tools or configure
```

How can I resolve this? If you propose a fix, please make it concise.

Copy link
Contributor

@cubic-dev-ai cubic-dev-ai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

2 issues found across 4 files

Prompt for AI agents (all issues)

Check if these issues are valid — if so, understand the root cause of each and fix them.


<file name="packages/core/lib/v3/v3.ts">

<violation number="1" location="packages/core/lib/v3/v3.ts:799">
P2: Local launch uses unvalidated `port`: passing 0/invalid values causes Chrome polling on an unusable port and connection timeouts instead of auto-selecting a port.</violation>
</file>

<file name="packages/docs/v3/references/stagehand.mdx">

<violation number="1" location="packages/docs/v3/references/stagehand.mdx:127">
P3: Extra space after "set" - should be "When set, the browser" instead of "When set , the browser".</violation>
</file>

Since this is your first cubic review, here's how it works:

  • cubic automatically reviews your code and comments on bugs and improvements
  • Teach cubic by replying to its comments. cubic learns from your replies and gets better over time
  • Ask questions if you need clarification on any suggestion

Reply with feedback, questions, or to request a fix. Tag @cubic-dev-ai to re-run a review.

const { ws, chrome } = await launchLocalChrome({
chromePath: lbo.executablePath,
chromeFlags,
port: lbo.port,
Copy link
Contributor

@cubic-dev-ai cubic-dev-ai bot Jan 10, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2: Local launch uses unvalidated port: passing 0/invalid values causes Chrome polling on an unusable port and connection timeouts instead of auto-selecting a port.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At packages/core/lib/v3/v3.ts, line 799:

<comment>Local launch uses unvalidated `port`: passing 0/invalid values causes Chrome polling on an unusable port and connection timeouts instead of auto-selecting a port.</comment>

<file context>
@@ -796,6 +796,7 @@ export class V3 {
           const { ws, chrome } = await launchLocalChrome({
             chromePath: lbo.executablePath,
             chromeFlags,
+            port: lbo.port,
             headless: lbo.headless,
             userDataDir,
</file context>
Suggested change
port: lbo.port,
port:
typeof lbo.port === "number" &&
Number.isInteger(lbo.port) &&
lbo.port > 0 &&
lbo.port <= 65_535
? lbo.port
: undefined,
Fix with Cubic

@dhanushchalicheemala
Copy link
Author

Fixes #1489

Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant