Files
2026-03-03 23:49:13 +01:00

143 lines
4.4 KiB
TypeScript

/**
* PlaywrightExecutor - Manages browser connection and code execution per session.
* Used by both MCP and CLI to execute Playwright code with persistent state.
*/
import { Page, BrowserContext } from '@xmorse/playwright-core';
import { type SnapshotFormat } from './aria-snapshot.js';
export type { SnapshotFormat };
export declare class CodeExecutionTimeoutError extends Error {
constructor(timeout: number);
}
/**
* Parse code and check if it's a single expression that should be auto-returned.
* Returns the exact expression source (without trailing semicolon) using AST
* node offsets, or null if the code should not be auto-wrapped. See #58.
*/
export declare function getAutoReturnExpression(code: string): string | null;
/** Backward-compatible helper: returns true if code should be auto-wrapped. */
export declare function shouldAutoReturn(code: string): boolean;
/**
* Wraps user code in an async IIFE for vm execution.
* Uses AST node offsets to extract the expression without trailing semicolons,
* avoiding SyntaxError when embedding inside `return await (...)`. See #58.
*/
export declare function wrapCode(code: string): string;
export interface ExecuteResult {
text: string;
images: Array<{
data: string;
mimeType: string;
}>;
isError: boolean;
}
export interface ExecutorLogger {
log(...args: any[]): void;
error(...args: any[]): void;
}
export interface CdpConfig {
host?: string;
port?: number;
token?: string;
extensionId?: string | null;
}
export interface SessionMetadata {
extensionId: string | null;
browser: string | null;
profile: {
email: string;
id: string;
} | null;
}
export interface ExecutorOptions {
cdpConfig: CdpConfig;
sessionMetadata?: SessionMetadata;
logger?: ExecutorLogger;
/** Working directory for scoped fs access */
cwd?: string;
}
export declare class PlaywrightExecutor {
private isConnected;
private page;
private browser;
private context;
private userState;
private browserLogs;
private lastSnapshots;
private lastRefToLocator;
private warningEvents;
private nextWarningEventId;
private lastDeliveredWarningEventId;
private recordingStartedAt;
private executionTimestamps;
private activeWarningScopes;
private pagesWithListeners;
private suppressPageCloseWarnings;
private scopedFs;
private sandboxedRequire;
private cdpConfig;
private logger;
private sessionMetadata;
private hasWarnedExtensionOutdated;
constructor(options: ExecutorOptions);
private createSandboxedRequire;
private setDeviceScaleFactorForMacOS;
private clearUserState;
private clearConnectionState;
private enqueueWarning;
private beginWarningScope;
private flushWarningsForScope;
private pruneDeliveredWarnings;
private warnIfExtensionOutdated;
private setupPageListeners;
private setupPageCloseDetection;
private setupPopupDetection;
private setupPageConsoleListener;
private checkExtensionStatus;
private ensureConnection;
private getCurrentPage;
reset(): Promise<{
page: Page;
context: BrowserContext;
}>;
execute(code: string, timeout?: number): Promise<ExecuteResult>;
private ensurePageForContext;
/** Get info about current connection state */
getStatus(): {
connected: boolean;
pageUrl: string | null;
pagesCount: number;
};
/** Get keys of user-defined state */
getStateKeys(): string[];
getSessionMetadata(): SessionMetadata;
}
/**
* Session manager for multiple executors, keyed by session ID (typically cwd hash)
*/
export declare class ExecutorManager {
private executors;
private cdpConfig;
private logger;
constructor(options: {
cdpConfig: CdpConfig | ((sessionId: string) => CdpConfig);
logger?: ExecutorLogger;
});
getExecutor(options: {
sessionId: string;
cwd?: string;
sessionMetadata?: SessionMetadata;
}): PlaywrightExecutor;
deleteExecutor(sessionId: string): boolean;
getSession(sessionId: string): PlaywrightExecutor | null;
listSessions(): Array<{
id: string;
stateKeys: string[];
extensionId: string | null;
browser: string | null;
profile: {
email: string;
id: string;
} | null;
}>;
}
//# sourceMappingURL=executor.d.ts.map