Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions src/actions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ import type {
FocusCommand,
DragCommand,
FrameCommand,

GetByRoleCommand,
GetByTextCommand,
GetByLabelCommand,
Expand Down
12 changes: 10 additions & 2 deletions src/browser.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1117,7 +1117,7 @@ export class BrowserManager {
}

if (cdpEndpoint) {
await this.connectViaCDP(cdpEndpoint);
await this.connectViaCDP(cdpEndpoint, options.headers);
return;
}

Expand Down Expand Up @@ -1310,7 +1310,7 @@ export class BrowserManager {
* Connect to a running browser via CDP (Chrome DevTools Protocol)
* @param cdpEndpoint Either a port number (as string) or a full WebSocket URL (ws:// or wss://)
*/
private async connectViaCDP(cdpEndpoint: string | undefined): Promise<void> {
private async connectViaCDP(cdpEndpoint: string | undefined, headers?: Record<string, string>): Promise<void> {
if (!cdpEndpoint) {
throw new Error('CDP endpoint is required for CDP connection');
}
Expand Down Expand Up @@ -1374,6 +1374,14 @@ export class BrowserManager {
}

this.activePageIndex = 0;

// Apply custom headers post-connection (Playwright's connectOverCDP doesn't support
// connection-time headers, so we set them on the context after connecting)
if (headers && Object.keys(headers).length > 0) {
for (const context of contexts) {
await context.setExtraHTTPHeaders(headers);
}
}
} catch (error) {
// Clean up browser connection if validation or setup failed
await browser.close().catch(() => {});
Expand Down
12 changes: 12 additions & 0 deletions src/daemon.ts
Original file line number Diff line number Diff line change
Expand Up @@ -417,6 +417,17 @@ export async function startDaemon(options?: {

const ignoreHTTPSErrors = process.env.AGENT_BROWSER_IGNORE_HTTPS_ERRORS === '1';
const allowFileAccess = process.env.AGENT_BROWSER_ALLOW_FILE_ACCESS === '1';

// Parse custom headers from env (JSON string)
let headers: Record<string, string> | undefined;
if (process.env.AGENT_BROWSER_HEADERS) {
try {
headers = JSON.parse(process.env.AGENT_BROWSER_HEADERS);
} catch {
/* ignore invalid JSON */
}
}

await manager.launch({
id: 'auto',
action: 'launch' as const,
Expand All @@ -430,6 +441,7 @@ export async function startDaemon(options?: {
proxy,
ignoreHTTPSErrors: ignoreHTTPSErrors,
allowFileAccess: allowFileAccess,
headers,
autoStateFilePath: getSessionAutoStatePath(),
});
}
Expand Down
7 changes: 6 additions & 1 deletion src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -540,6 +540,10 @@ export interface DeviceListCommand extends BaseCommand {
action: 'device_list';
}

export interface HelpCommand extends BaseCommand {
Copy link
Contributor

@vercel vercel bot Feb 13, 2026

Choose a reason for hiding this comment

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

The HelpCommand type was added to the Command union in types.ts, but no corresponding Zod schema or command handler was implemented, making the help command non-functional.

Fix on Vercel

Copy link
Contributor Author

Choose a reason for hiding this comment

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

✅ Fixed in commit c3e2e2a.

action: 'help';
}

// Video recording (Playwright native - requires launch-time setup)
export interface VideoStartCommand extends BaseCommand {
action: 'video_start';
Expand Down Expand Up @@ -984,7 +988,8 @@ export type Command =
| InputKeyboardCommand
| InputTouchCommand
| SwipeCommand
| DeviceListCommand;
| DeviceListCommand
| HelpCommand;

// Response types
export interface SuccessResponse<T = unknown> {
Expand Down