import { type McpAttachment } from "./mcp-bridge.js"; export declare const BROWSER_TOOL_PREFIX = "mcp__browser__"; export declare const DEFAULT_BROWSER_MCP_PACKAGE = "chrome-devtools-mcp@latest"; export declare const BROWSER_DEFAULT_TIMEOUT_MS = 120000; /** * Whether the browser bridge is enabled for this session. Default-ON: attach * unless FORGE_BROWSER_MCP is explicitly set to a falsey token * (0 / false / off / no). Absent or empty → enabled. Attach itself stays * graceful, so default-on is safe where no browser can launch. */ export declare function isBrowserBridgeEnabled(env?: NodeJS.ProcessEnv): boolean; /** * Whether this session's browser is a surface a human can SEE and act in — * i.e. an auth handoff ("finish logging in, then continue") is possible. * * True when EITHER: * - connect-mode is active (FORGE_BROWSER_URL set) — the bridge drives the * user's own already-running Chrome, so the human is already looking at it; or * - Chrome is launched headed (FORGE_BROWSER_HEADLESS explicitly falsey) — a * real visible window the human can click through. * * The default headless+isolated launch is NOT interactive: no window, no * persisted login, nothing for a human to drive — so the auth-handoff steering * is withheld (it would be a lie to tell the agent it can ask a human to log in). */ export declare function isBrowserInteractive(env?: NodeJS.ProcessEnv): boolean; /** A resolved launcher for the browser MCP server: how to spawn it. */ export interface ResolvedBrowserCommand { /** Executable to spawn (resolved against PATH by child_process). */ command: string; /** Args that precede the server's own launch flags (e.g. `npx -y `). */ baseArgs: string[]; } /** * Resolve how to launch the browser MCP server, or null when nothing is usable. * * Precedence: * 1. Explicit binary (arg → FORGE_BROWSER_MCP_BIN) — a direct * chrome-devtools-mcp launcher. Trusted as-is (no pre-verify: probing it * could cost a Chrome launch); baseArgs is empty. * 2. `npx` on PATH → `npx -y `. * "Usable" means `npx --version` exits 0. * * Returns null when neither is reachable — the caller treats that as a graceful * no-op (no browser tools this session), never an error. */ export declare function resolveBrowserMcpCommand(opts?: { bin?: string; }): ResolvedBrowserCommand | null; /** Chrome launch shape passed through to chrome-devtools-mcp's CLI flags. */ export interface BrowserLaunchOptions { /** Run Chrome headless. Default true (faster, no window for agent runs). */ headless?: boolean; /** Fresh temp user-data-dir cleared on exit. Default true (reproducible). */ isolated?: boolean; /** Release channel: stable | canary | beta | dev. */ channel?: string; /** Path to a specific Chrome/Chromium executable. */ executablePath?: string; /** * Connect to an already-running Chrome's CDP endpoint instead of launching * one. When set, launch flags (headless/isolated/channel/executablePath) do * NOT apply — chrome-devtools-mcp attaches to the existing browser — so only * `--browserUrl` is passed. */ browserUrl?: string; /** Initial viewport as `WIDTHxHEIGHT` (e.g. `1280x800`). */ viewport?: string; } /** * Build the chrome-devtools-mcp launch flags from options, with env fallbacks * (FORGE_BROWSER_HEADLESS, _ISOLATED, _CHANNEL, _EXECUTABLE, _URL, _VIEWPORT). * * Connect-mode short-circuit: when a browserUrl is resolved, ONLY `--browserUrl` * is emitted — the launch flags are meaningless (and rejected) when attaching to * an existing browser. */ export declare function buildBrowserArgs(opts?: BrowserLaunchOptions): string[]; /** * The browser UI-verification steering block — injected ONCE into the system * prompt (via project-orientation → setBrowserSteering), reaching both the main * thread and every subagent dispatch. Mirrors grove's steering discipline: no * per-tool promptGuidelines (pi would repeat the block once per active tool). * * Frames the surface as a VERIFICATION loop, not a browsing toy: after a UI * change, drive the running app and confirm what rendered — snapshot the DOM, * screenshot the viewport, read console/network for errors. */ export declare function buildBrowserSteering(toolNames: string[], opts?: { interactive?: boolean; }): string; /** Options for attaching the browser bridge to a pi session. */ export interface AttachBrowserOptions extends BrowserLaunchOptions { /** Working directory for the MCP server child (project root). */ cwd: string; /** Explicit launcher override (else FORGE_BROWSER_MCP_BIN → npx). */ bin?: string; /** Override the tool name prefix (default "mcp__browser__"). */ namePrefix?: string; /** Per-call request timeout (default BROWSER_DEFAULT_TIMEOUT_MS). */ requestTimeoutMs?: number; } /** * Attach the Chrome DevTools browser bridge to a pi session: resolve a launcher * → spawn the MCP server → discover its tools → synthesize pi ToolDefinitions. * * Returns null — a graceful no-op — when no launcher is reachable or the * handshake/discovery fails (e.g. npx cold-fetch exceeded the timeout, Node * version too old, Chrome unavailable). Callers register the returned tools on * the host session and inject them into subagent dispatch. */ export declare function attachBrowser(opts: AttachBrowserOptions): Promise;