Skip to main content

How MonoSurf Works

MonoSurf is a Rust-native client for Chrome DevTools Protocol (CDP). Standalone monosurf and embedded kernel-cli websurf share the lib-monosurf facade for canonical help, docs, and the profile TUI, then call the same lib-monosurf-core engine. The engine connects directly to a Chromium page for navigation, JavaScript, DOM extraction, screenshots, console and network evidence, and selector-based verification. Verified against monosurf 0.11.3, OpenCLIs build 2026-07-19-222928.

The Core Loop

MonoSurf does not require Node.js or a Playwright process to run its normal CDP page loop. It can still discover Chromium builds installed by Playwright or Puppeteer and use those browser binaries as engines.

Choose a Session

For site-plugin commands, the full profile ladder can also select the single registered profile or ask a person on an interactive terminal. Browse ends in ephemeral mode instead of silently adopting that single profile.

Managed Profile Lifecycle

The first successful launch pins the browser kind and signing identity that protect the profile’s encrypted cookies. If discovery later resolves a different kind, the launch fails clearly. --allow-binary-change accepts the new engine and the likely need to sign in again.

Managed CDP port ownership

An open TCP port is not ownership proof. MonoSurf 0.11.3 reads the listener command line and looks for the exact, boundary-aware --user-data-dir argument of the selected profile. A new unregistered profile first skips active ports, then carries the exact selected port through launch verification and failed-launch cleanup instead of allocating a second time after Chrome binds: A live pid-file number whose readable command line belongs to another process is treated as a recycled pid: MonoSurf removes the stale record and never signals that process. Listener discovery also asks for the process in LISTEN state, avoiding a connected CDP client socket being mistaken for the browser server. A known foreign owner is refused immediately. Unknown ownership gets a bounded one-second settle window; it never turns into implicit trust. Explicit browse --cdp-url <endpoint> is the separate intentional foreign-attach path.

Login State: Live Session First

monosurf login <domain> keeps the authenticated browser session and can save an encrypted session snapshot as a bootstrap backup. The explicit bridge path (bridge install, then bridge [domain] [--keep] before a user clicks Sync) stores the active tab’s matching cookies through the same protected snapshot boundary. It is available only when Monolex desktop has staged the shared ~/.niia/bin/monolex-native-host (.exe on Windows); the standalone 0.11.3 archive does not contain that prerequisite.
Hydration happens before navigation, preserves domain/path, HttpOnly, Secure, SameSite, and expiry, and fails on any invalid scope or CDP write error. Login does not empty the browser jar after saving a snapshot; a live session wins. The bridge copies cookies only. It does not copy localStorage, IndexedDB, service workers, passwords, a Chrome profile, or the Chrome process. The Monolex Agent Browser’s managed login is the separate same-profile reuse path.

Browse Execution

Browse builds one page session and layers the requested work onto it:
  1. Resolve ephemeral, managed-profile, or external-CDP ownership; a managed listener passes the exact-port ownership guard before attachment.
  2. Configure viewport, console capture, and network logging before navigation.
  3. Navigate under strict TLS unless --insecure was explicitly requested.
  4. Wait for asynchronous content when --wait is present.
  5. Capture screenshots, console messages, network health, or expectations.
  6. Produce text, structured extraction, evaluated JavaScript, or collected JSONL.
  7. Return non-zero when the requested output, expectation, navigation, or write fails.
  8. Tear down only the session MonoSurf owns.
--timeout is the deadline of the work requested by the command: selector waits and expectations use it, and evaluation or extraction uses a deterministic deadline rather than waiting indefinitely. postcondition navigation binds one exact normalized-text control to the evidence expected after its real CDP click: canonical URL/history, scroll, viewport intersection, destination target text, and fixed-header clearance. Duplicate controls, covered/off-screen or missing targets, URL drift, and timeouts fail closed. postcondition toast applies the same one-write/one-proof model to a visible toast when success intentionally keeps the URL unchanged.

Harvest and Network Capture

Collection and network logging observe different evidence in the same pass:
The collection output flushes item by item, so an interrupted long run retains the items already written. The final report states why the loop stopped.

Site Plugin Execution

A site command adds a reusable contract around the page loop:
Supported action shapes are: Legacy JSON may still parse a pw action and the installed plugin help may list it for compatibility. CDP mode does not execute that action; convert it to a supported js, click, type, or wait sequence.

Browser Selection

No browser engine bypasses a website’s access rules, bot defenses, or rate policies.

Outside the Page

CDP cannot see native file pickers, print/save dialogs, Face ID or Keychain prompts, browser tabs and menus, or another desktop application. Hand those surfaces to Kernel CLI, then return to monosurf or kernel-cli websurf to verify the page result.

Usage and Command Reference

See every supported command family, option group, and exit boundary.

Kernel CLI

Continue through native observation, accessibility, OCR, input, apps, and windows outside the page.