import {
  d as LifecycleRouteContext,
  s as LifecycleCapability
} from "./capability-runner-BiVUtjqC.js";
import {
  n as InternalHostInfo,
  r as InternalHostMessage,
  s as InternalHostsOptions
} from "./internal-hosts-Kfp5A392.js";
import {
  O as CdpConnection,
  a as ListableBrowserSessionStore,
  d as BrowserBinding,
  m as BrowserSessionGuardrails,
  s as BrowserLiveView,
  u as LiveViewMode
} from "./session-store-B7Ca-u1t.js";

//#region src/browser/spec.d.ts
/**
 * The element type of an array field or type. `$ref` is always
 * domain-qualified (`"Network.Cookie"`), matching a type's `name`.
 */
interface CdpItems {
  type?: string;
  $ref?: string;
  enum?: string[];
}
/**
 * A command parameter, return value, event parameter, or type property.
 * Either `type` (a JSON type such as `"string"` or `"array"`) or `$ref`
 * (a domain-qualified type name matching a type's `name`) is set.
 */
interface CdpField {
  name: string;
  description?: string;
  optional?: boolean;
  experimental?: boolean;
  deprecated?: boolean;
  type?: string;
  $ref?: string;
  enum?: string[];
  items?: CdpItems;
}
interface SearchableCdpSpec {
  domains: Array<{
    name: string;
    description?: string;
    experimental?: boolean;
    deprecated?: boolean;
    commands: Array<{
      name: string;
      method: string;
      description?: string;
      experimental?: boolean;
      deprecated?: boolean;
      parameters: CdpField[];
      returns: CdpField[];
    }>;
    events: Array<{
      name: string;
      event: string;
      description?: string;
      experimental?: boolean;
      deprecated?: boolean;
      parameters: CdpField[];
    }>;
    types: Array<{
      id: string;
      name: string;
      description?: string;
      experimental?: boolean;
      deprecated?: boolean /** JSON type of the value, e.g. `"string"`, `"object"`, `"array"`. */;
      type?: string;
      enum?: string[];
      properties: CdpField[];
      items?: CdpItems;
    }>;
  }>;
}
interface CdpSpecSource {
  /** Browser Rendering binding (Fetcher) — used in production */
  browser?: BrowserBinding;
  /** CDP base URL override (e.g. http://localhost:9222) */
  cdpUrl?: string;
  /** Headers to send with CDP URL discovery requests */
  cdpHeaders?: Record<string, string>;
  /**
   * An existing Browser Run session to read the protocol from. Without it,
   * loading through the binding creates (and deletes) a throwaway session.
   */
  sessionId?: string;
}
/** Load the (cached) searchable CDP spec for a browser source. */
declare function loadCdpSpec(source: CdpSpecSource): Promise<SearchableCdpSpec>;
//#endregion
//#region src/browser/session.d.ts
/**
 * What a {@link BrowserSession} connects to. Usually a `Browser` installed on
 * the host's Lifecycle.
 */
interface BrowserSource {
  /** The browser's name, for log messages. */
  readonly name: string;
  /**
   * Reattach to the browser (or replace it) and open a CDP connection for
   * a scope. A source that ignores `scope` shares one active tab between
   * every caller.
   */
  connect(options?: BrowserConnectOptions): Promise<BrowserConnection>;
  /**
   * The browser's internal hostnames, when it has any. The docs list them,
   * and {@link BrowserSession.functions} adds the hosts functions.
   */
  readonly internalHosts?: BrowserInternalHosts;
}
interface BrowserSessionOptions {
  /**
   * Who is driving: sessions with the same scope share an active tab, and
   * each scope keeps its own. Cookies and logins are shared by every scope.
   * Defaults to the browser's default scope.
   */
  scope?: string;
  /**
   * The largest `Page.captureScreenshot` result `send` returns, measured as
   * JSON. Defaults to 1,000,000 bytes.
   */
  maxResultBytes?: number;
  /**
   * Lock the scope on this browser: the session takes the scope's lock at
   * its first call (or at {@link BrowserSession.lock}) and holds it until it
   * closes. Other locking sessions in the scope wait for the lock, in order,
   * rather than fail, so their calls never interleave. Sessions without it
   * don't wait and aren't waited for. Locks are per isolate, which is per
   * Durable Object.
   *
   * Use it when several runs in one scope can start together (parallel
   * tool calls, say) and must not see each other's navigation.
   *
   * Only `close()` releases the lock: not aborting a signal, losing the
   * browser, or dropping the session. Close a locking session in `finally`,
   * even when connecting failed, or its scope stays locked until the
   * isolate restarts.
   */
  lock?: boolean;
}
/** {@link BrowserSession.lock}'s options. */
interface BrowserLockOptions {
  /**
   * Bounds this call's wait: when it aborts, this call rejects with its
   * reason. The session keeps waiting while other calls still are; once
   * none is, it leaves the queue at once, so it doesn't hold up the
   * sessions behind it. A call without a signal, including the wait a
   * session's first function call makes, never gives up. The signal does
   * nothing once the lock is held: only `close()` releases it.
   */
  signal?: AbortSignal;
}
/** `send`'s input. */
interface BrowserSendInput {
  /** CDP method, e.g. `"Page.navigate"`. */
  method: string;
  /** CDP command parameters. */
  params?: Record<string, unknown>;
  /**
   * `"active"` for the current tab, or a handle from `attachToTarget`. Omit
   * for `Browser.*` and `Target.*` commands.
   */
  sessionId?: string;
  /** Per-command timeout in milliseconds. */
  timeoutMs?: number;
}
/** `attachToTarget`'s input. */
interface BrowserAttachInput {
  /** Target id from `Target.getTargets` or `Target.createTarget`. */
  targetId: string;
  timeoutMs?: number;
}
/** `getDebugLog`'s input. */
interface BrowserDebugLogInput {
  /** Most entries to return, newest last. Defaults to 50; 400 are kept. */
  limit?: number;
}
/** A tab a page opened on its own during a session. */
interface BrowserNewTab {
  targetId: string;
  url?: string;
  title?: string;
}
/**
 * What happened to the browser during one session, beyond the results of its
 * calls. {@link BrowserSession.close} returns it.
 */
interface BrowserSessionReport {
  /** The browser was replaced before this session; earlier page state is gone. */
  restarted: boolean;
  /** Tabs the page opened itself (popups, `target=_blank`). */
  newTabs: BrowserNewTab[];
  /**
   * The tab this scope was working in was closed by someone else (another
   * scope, or a person in Live View), so `"active"` will be a new blank tab.
   */
  tabClosed: boolean;
  /** Another scope is working in this scope's active tab too. */
  tabShared: boolean;
  /**
   * The report as sentences for the model, one per thing that happened,
   * empty when nothing did. Show them after the run's result.
   */
  notices: string[];
}
/** `sessionId` value that addresses the tab the agent is working in. */
declare const ACTIVE_PAGE_SESSION = "active";
/**
 * One run's connection to a persistent browser, for one scope.
 *
 * It connects on its first call and stays connected until {@link close}.
 * Concurrent first calls share one connect. Every method takes one options
 * object, validated before anything touches the browser, because the input
 * usually comes from model-written code.
 *
 * Create one per run with `browser.session({ scope })`, and close it when
 * the run ends. The browser itself stays open. Pass `lock: true` when
 * runs in one scope may overlap; see {@link BrowserSessionOptions.lock}.
 *
 * @experimental The API surface may change before stabilizing.
 */
declare class BrowserSession {
  #private;
  constructor(browser: BrowserSource, options?: BrowserSessionOptions);
  /**
   * The `browser.*` functions bound to this session, by name: the ones
   * `Browser.functionDocs()` describes. Each takes one input object and
   * validates it, so model-written code can call them directly. Like the
   * session's methods, every one rejects once the session is closed, and
   * waits for the scope's lock when the session locks.
   */
  get functions(): Readonly<Record<string, BrowserFunction>>;
  /**
   * Take this scope's lock now rather than at the first call, and hold it
   * until {@link close}. For sessions opened with `lock: true`; a
   * caller with its own time limit calls it first, so the wait doesn't count
   * against the limit, or passes `signal` to bound the wait.
   *
   * Resolves once the session holds the lock, after the locking sessions
   * ahead of it close; later and concurrent calls resolve with the same
   * lock. Rejects when the session closes while waiting. Each call's
   * `signal` bounds only that call's wait: it rejects with the signal's
   * reason, and the session leaves the queue once no call is still
   * waiting (see {@link BrowserLockOptions.signal}); a later call or first
   * call waits again.
   */
  lock(options?: BrowserLockOptions): Promise<void>;
  /**
   * How long this session waited for its lock, in milliseconds: `0` until
   * it has waited, and for sessions that don't lock.
   */
  get waitedForLockMs(): number;
  /**
   * Send a CDP command and resolve with its result, without the JSON-RPC
   * envelope. `sessionId: "active"` runs it in the scope's tab.
   */
  send(input: BrowserSendInput): Promise<unknown>;
  /**
   * Make an open tab the scope's active tab, and resolve with a `sessionId`
   * handle for it that keeps working in later runs.
   */
  attachToTarget(input: BrowserAttachInput): Promise<{
    sessionId: string;
  }>;
  /** The Chrome DevTools Protocol description the browser serves. */
  spec(): Promise<SearchableCdpSpec>;
  /** Recent CDP traffic on this session's connection, newest last. */
  getDebugLog(input?: BrowserDebugLogInput): Promise<unknown[]>;
  /** Forget the CDP traffic recorded so far. */
  clearDebugLog(): Promise<null>;
  /**
   * End the session: save the scope's active tab, work out what happened to
   * the browser, and close the connection. The browser stays open.
   *
   * Resolves with the report, or `undefined` when the session never
   * connected. Never rejects: failures to read the browser's state are
   * logged and leave the report incomplete. Later calls resolve with
   * `undefined`, and other methods reject.
   *
   * A locking session releases the lock once the active tab is saved, or
   * stops waiting for it if it was still waiting.
   */
  close(): Promise<BrowserSessionReport | undefined>;
}
//#endregion
//#region src/browser/browser-functions.d.ts
/**
 * One function on the `browser` object, as the host runs it: it takes one
 * input object (usually from model-written code, so it's validated) and
 * resolves with a JSON-safe result.
 *
 * @experimental The API surface may change before stabilizing.
 */
type BrowserFunction = (input: unknown) => Promise<unknown>;
/**
 * What the model needs to know to use the `browser` object, for a tool or
 * module description. `Browser.functionDocs()` returns it.
 *
 * @experimental The API surface may change before stabilizing.
 */
interface BrowserFunctionDocs {
  /**
   * The `browser.*` functions in Markdown, one bullet per function, then the
   * browser's internal sites when it has any.
   */
  functions: string;
  /**
   * How to use the browser, one rule per entry, without bullets. Rules about
   * how the code runs (timeouts, how screenshots reach the model) belong to
   * whatever runs it, so add those yourself.
   */
  rules: string[];
}
//#endregion
//#region src/browser/providers/browser-run.d.ts
/**
 * Browser Run settings applied every time a browser is created — including
 * when a lost browser is replaced — so options like guardrails survive a
 * restart.
 */
interface BrowserRunOptions<S = Record<string, unknown>> {
  /**
   * Platform `keep_alive` in milliseconds: how long an idle browser lives.
   * Defaults to {@link BROWSER_SESSION_KEEP_ALIVE_DEFAULT_MS} (10 minutes).
   * Browser Run accepts up to {@link BROWSER_SESSION_KEEP_ALIVE_MAX_MS}
   * (20 minutes).
   */
  keepAliveMs?: number;
  /** Opt into Browser Run session recording (rrweb capture). */
  recording?: boolean;
  /**
   * Hostname guardrails, fixed at launch for every connection. They don't
   * apply to `internalHosts`: `allowedDomains: []` leaves the browser able
   * to open internal hostnames only.
   */
  guardrails?: BrowserSessionGuardrails;
  /**
   * Hostnames only this browser can open, served by your agent or a Worker
   * instead of the internet. Plain http on port 80; no HTTPS or WebSockets.
   * Deployed Workers only: in local dev the browser starts without them.
   *
   * Any http page open in the browser can send requests to these hosts, so
   * a host whose requests have side effects should check `Origin` (see
   * `InternalHost.fetch`).
   *
   * @example
   * ```ts
   * browserRun(this.env.BROWSER, {
   *   internalHosts: {
   *     router: this.ctx.exports.InternalHostRouter,
   *     hosts: {
   *       "preview.internal": {
   *         description: "A dev server in your sandbox",
   *         target: z.object({ port: z.number().int() }),
   *         fetch: (request, { port }) => this.sandboxPort(port, request)
   *       }
   *     }
   *   }
   * });
   * ```
   */
  internalHosts?: InternalHostsOptions<S>;
}
/** A {@link Browser} provider backed by Cloudflare Browser Run. */
interface BrowserRunProvider {
  readonly kind: "browser-run";
  readonly binding: BrowserBinding;
  readonly options: BrowserRunOptions;
}
/**
 * Run the browser on Cloudflare Browser Run.
 *
 * @example
 * ```ts
 * new Browser({ provider: browserRun(env.BROWSER, { recording: true }) });
 * ```
 */
declare function browserRun<const S extends Record<string, unknown> = {}>(
  binding: BrowserBinding,
  options?: BrowserRunOptions<S>
): BrowserRunProvider;
//#endregion
//#region src/browser/scope.d.ts
/**
 * Browser scopes: who is driving a shared `Browser`. Sessions with the same
 * scope share an active tab (and, when they lock, a lock); each scope
 * keeps its own. Cookies and logins are shared by every scope.
 */
/**
 * The scope used when a caller doesn't pick one: every caller that leaves
 * `scope` out shares this one active tab. See `BrowserConnectOptions`.
 */
declare const DEFAULT_BROWSER_SCOPE = "shared";
/**
 * The scope for one conversation: `conversation:<id>`. pi's `browserTool`
 * gives each conversation this scope by default, so app code that opens
 * sessions with the same scope (a Workspace's `codemode:browser`, say) lands
 * in the same tab as the tool. pi's conversation ids are numbers: pass
 * `String(conversationId)`.
 *
 * Throws on a missing or empty id rather than returning
 * `"conversation:undefined"`, which would quietly put every conversation
 * without an id in one tab.
 *
 * @experimental The API surface may change before stabilizing.
 */
declare function conversationScope(id: string): string;
//#endregion
//#region src/browser/browser.d.ts
/**
 * Scope records kept per browser. Writing a new one past the cap deletes the
 * least recently used; a scope that comes back afterwards starts fresh.
 */
declare const MAX_BROWSER_SCOPES = 100;
/** Where a {@link Browser} gets its browser from. */
type BrowserProvider = BrowserRunProvider;
interface BrowserOptions {
  /** Where the browser runs. Create one with `browserRun()`. */
  provider: BrowserProvider;
  /**
   * Which browser this is. Two `Browser` objects on the same Durable Object
   * need different names. Defaults to {@link DEFAULT_BROWSER_NAME}.
   */
  name?: string;
  /**
   * Where the browser's record lives. Defaults to a
   * {@link DurableBrowserSessionStore} over the host object's storage, which
   * requires installing the `Browser` with `Lifecycle.use()`. Passing a store
   * lets the `Browser` work without Lifecycle. It must implement `list`.
   */
  store?: ListableBrowserSessionStore;
  /** Default CDP command timeout for {@link Browser.connect}. */
  timeoutMs?: number;
  /**
   * Minimum interval between activity-driven `updatedAt` refreshes.
   * Defaults to {@link SESSION_TOUCH_INTERVAL_MS}, capped at half the
   * keep-alive window.
   *
   * @internal For tests.
   */
  touchIntervalMs?: number;
}
interface ResolvedBrowser {
  name: string;
  /** The provider's session id — host-side only, never model-visible. */
  sessionId: string;
  /**
   * `true` when this resolution had to create a fresh browser to replace one
   * that previously existed (was closed, or expired or died upstream). Page
   * state from the prior browser is gone; surface this loudly to the model.
   * `false` only on first-ever use of the name — nothing was lost.
   */
  restarted: boolean;
  createdAt: number;
  updatedAt: number;
}
interface BrowserConnectOptions {
  /**
   * Who is driving. Connections with the same scope share an active tab, and
   * each scope keeps its own, so two conversations on one browser don't
   * drive each other's page. Cookies, logins, and the tabs themselves are
   * shared by every scope: a scope splits "which tab is mine", not the
   * browser. Defaults to {@link DEFAULT_BROWSER_SCOPE}.
   */
  scope?: string;
}
interface BrowserConnection {
  name: string;
  sessionId: string;
  /** The scope this connection works in; see {@link BrowserConnectOptions}. */
  scope: string;
  /**
   * `true` when this scope worked in an earlier browser that has since been
   * replaced, whichever scope's connection replaced it. Its tabs and page
   * state are gone; surface this loudly to the model. `false` on a scope's
   * first connection, even one that replaced a lost browser: the scope had
   * nothing to lose. This is per scope, not a browser-wide signal.
   */
  restarted: boolean;
  /**
   * The tab this scope last worked in, when it recorded one in this
   * browser.
   */
  activeTargetId?: string;
  /** Closing this connection does NOT close the browser. */
  cdp: CdpConnection;
  /**
   * Record the tab this scope is working in (or clear it with `undefined`).
   * Never resurrects: returns `false` when the browser was closed or
   * replaced since this connection resolved it.
   */
  setActiveTarget(targetId: string | undefined): Promise<boolean>;
  /** The tabs other scopes are working in, in this browser. */
  targetsInOtherScopes(): Promise<Set<string>>;
  /**
   * The Chrome DevTools Protocol description this browser serves, read from
   * the browser itself (cached).
   */
  spec(): Promise<SearchableCdpSpec>;
}
/**
 * A browser's internal hostnames (`browserRun({ internalHosts })`), for the
 * host and the browser tool. Assignments are stored with the agent, so they
 * survive the browser being replaced, eviction, and redeploys.
 */
interface BrowserInternalHosts {
  /** Every hostname with its description, schema, and current target. */
  list(): Promise<InternalHostInfo[]>;
  /**
   * Point an assignable host somewhere: `target` is checked against the
   * host's `target` schema and stored. The browser's next request to the
   * host uses it. Throws with what's wrong when the target doesn't match.
   */
  assign(
    host: string,
    target: unknown
  ): Promise<{
    url: string;
  }>;
  /** Forget a host's target; its requests answer 502 until assigned again. */
  clear(host: string): Promise<boolean>;
  /** The hostnames with their descriptions and schemas, without reading storage. */
  describe(): InternalHostInfo[];
}
/**
 * One named, persistent browser.
 *
 * Install it with `Lifecycle.use()` — on an Agent subclass or any Durable
 * Object that composes `Lifecycle` — and it stores its record in the
 * object's own storage. It schedules nothing: the provider reclaims idle
 * browsers itself (Browser Run once `keep_alive` elapses), and the next use
 * replaces the lost browser with `restarted: true`.
 *
 * Everything here is host-side. Models never see browser names, provider
 * session ids, or Live View URLs through this surface.
 *
 * Store discipline: locks wrap storage operations only — liveness probes and
 * provider create/close calls always happen outside any lock, with a commit
 * re-check to detect concurrent swaps.
 *
 * @experimental The API surface may change before stabilizing.
 */
declare class Browser extends LifecycleCapability {
  #private;
  /** Which browser this is; see {@link BrowserOptions.name}. */
  readonly name: string;
  constructor(options: BrowserOptions);
  /**
   * Reattach to the browser when it is still alive, otherwise create a fresh
   * one. See {@link ResolvedBrowser.restarted} for the mortality signal.
   */
  resolve(): Promise<ResolvedBrowser>;
  /**
   * Resolve the browser and open a CDP connection to it for one scope (see
   * {@link BrowserConnectOptions.scope}). Commands sent over the connection
   * refresh the record's `updatedAt` (throttled to
   * {@link SESSION_TOUCH_INTERVAL_MS}), so hosts can tell an actively used
   * browser from one the platform has likely reclaimed.
   *
   * If the browser expires between the liveness probe and the WebSocket
   * upgrade, the record is retired and the browser resolved once more, so
   * the caller gets a fresh browser instead of an error.
   */
  connect(options?: BrowserConnectOptions): Promise<BrowserConnection>;
  /**
   * Start a session on this browser for one run: connects on its first
   * call, resolves `sessionId: "active"` to the scope's tab, and reports
   * what happened to the browser when you close it. `browserTool` opens
   * one per run.
   */
  session(options?: BrowserSessionOptions): BrowserSession;
  /**
   * What the model needs to know to use this browser's `browser.*`
   * functions ({@link BrowserSession.functions}): the functions in Markdown,
   * including the internal sites and hosts functions this browser has, and
   * the rules for using them. For a tool or module description; add rules
   * about how your code runs (timeouts, screenshots) yourself.
   */
  functionDocs(): BrowserFunctionDocs;
  /**
   * Close the browser: retire the record (so the next resolve reports
   * `restarted: true`) and close its provider session. Returns `false` when
   * there was nothing to close.
   *
   * The provider close is best-effort: the retired record is the durable
   * outcome, and a browser whose close failed is unreachable through this
   * store, so the provider reclaims it once idle (Browser Run: after
   * `keepAliveMs`, at most 20 minutes).
   */
  close(): Promise<boolean>;
  /**
   * Mint Live View URLs for the browser's open tabs, fresh from a target
   * listing. `undefined` when the browser was never created, is closed, or
   * is gone. The URLs are bearer credentials with a short connect window
   * (~5 min) — hand them to a trusted human, never to the model, and never
   * store them: re-mint instead.
   */
  liveView(options?: {
    mode?: LiveViewMode;
  }): Promise<BrowserLiveView | undefined>;
  /**
   * The browser's internal hostnames, or `undefined` when its provider has
   * none. See {@link BrowserInternalHosts}.
   */
  get internalHosts(): BrowserInternalHosts | undefined;
  /**
   * Serve one browser request to an internal hostname. `InternalHostRouter`
   * calls the agent's `fetchInternalHost()` with the message; `Agent` passes
   * it here on its own. A plain Durable Object passes it on itself:
   *
   * ```ts
   * fetchInternalHost(message: InternalHostMessage) {
   *   return this.browser.fetchInternalHost(message);
   * }
   * ```
   *
   * Answers 502 with the reason when this browser doesn't serve the host.
   */
  fetchInternalHost(message: InternalHostMessage): Promise<Response>;
  /**
   * `Agent.fetchInternalHost()` routes here through Lifecycle, so `Agent`
   * needn't import the browser.
   *
   * @internal Called by Lifecycle; not part of the host API.
   */
  onRoute(context: LifecycleRouteContext): Promise<unknown>;
}
//#endregion
export {
  loadCdpSpec as A,
  BrowserSessionOptions as C,
  CdpItems as D,
  CdpField as E,
  CdpSpecSource as O,
  BrowserSession as S,
  BrowserSource as T,
  BrowserAttachInput as _,
  BrowserOptions as a,
  BrowserNewTab as b,
  ResolvedBrowser as c,
  BrowserRunOptions as d,
  BrowserRunProvider as f,
  ACTIVE_PAGE_SESSION as g,
  BrowserFunctionDocs as h,
  BrowserInternalHosts as i,
  SearchableCdpSpec as k,
  DEFAULT_BROWSER_SCOPE as l,
  BrowserFunction as m,
  BrowserConnectOptions as n,
  BrowserProvider as o,
  browserRun as p,
  BrowserConnection as r,
  MAX_BROWSER_SCOPES as s,
  Browser as t,
  conversationScope as u,
  BrowserDebugLogInput as v,
  BrowserSessionReport as w,
  BrowserSendInput as x,
  BrowserLockOptions as y
};
//# sourceMappingURL=browser-CI97khiJ.d.ts.map
