Lightpanda and your own browser
The Lightpanda engine; your own browser, --attach and --profile.
--engine lightpanda(experimental; tested on Lightpanda’s newest stable release) startslightpanda servewith iframes and stylesheets loaded and telemetry off (LIGHTPANDA_DISABLE_TELEMETRY). The binary comes from$LIGHTPANDA_BINorPATH, or from--chromium; no X server is needed.gotowaits for load as on Chrome. Differences from Chrome:- one tab: a page opened with
target=_blankorwindow.openis loaded in the current tab, and the response says so innotes;tab-newfails. - dialogs are answered from a response armed before they open: one per
dialog, re-armed after each, so a script that opens two dialogs in a row
gets the policy for the first and a dismissal for the second (
dialogsin the response reports what the page got). - no layout: clicks go straight to DOM events where the hit test can’t work (inside shadow roots), without the settle wait and without the “covered” warning.
- shadow roots: the engine’s accessibility tree stops at one and gives the
nodes inside no ids, so
axlists what an open shadow root holds after the tree, under- shadow root of <tag>, without refs; target those elements with--text. - password fields: the engine reports
*****for every one, filled or not;axshows a dot per character, as on Chrome, and no value for an empty field. - infinite scroll: with no layout, an
IntersectionObserversees every target as on screen, so a page that loads more as you scroll loads all of it (60 products where Chrome shows 12), andaxis that much longer. statusreports the engine of a running session;starton a session that runs the other engine fails instead of reusing it.
- one tab: a page opened with
Your own browser: --attach and --profile (with start, or serve):
| Way | what it connects to | closes the browser? |
|---|---|---|
--auto-connect / --attach / --attach auto | whichever of your browsers serves remote debugging, looked for in this order: Chrome, Chrome Beta, Dev and Canary, Chromium, Edge and Brave by their default profiles (Chrome 144+ serves its default profile once you turn it on at chrome://inspect/#remote-debugging, and asks you to Allow each connection; navigera reads the endpoint from DevToolsActivePort in the browser’s user data directory), then a browser started with --remote-debugging-port 9222 or 9229. $NAVIGERA_AUTO_CONNECT=1 does the same for every start and mcp given no other browser | never |
--attach chrome | your running Chrome (also beta, dev, canary, chromium, edge, brave) and no other | never |
--attach <dir> | a Chrome started with --remote-debugging-port and --user-data-dir=<dir> | never |
--attach ws://… / http://host:port / host:port / <port> | that DevTools endpoint | never |
--attach wss://… (or $NAVIGERA_ATTACH) | a browser in the cloud, at the WebSocket endpoint its service hands out (the CDP URL, often with the key in its query: ?apiKey=…, ?token=…), over TLS with the certificate checked against the system’s store (on Linux the system bundle, or $SSL_CERT_FILE). Give it through $NAVIGERA_ATTACH (also read by serve and mcp; a flag wins) to keep the key off the command line; navigera shows the endpoint with its query values as *** in every message, status included, and hands it to its session server through the environment, not the command line. An https:// address is refused with the fix. Behind a proxy, the connection goes through $HTTPS_PROXY (or $ALL_PROXY) as an HTTP CONNECT tunnel, as curl’s would: $NO_PROXY names hosts to reach directly, and credentials go in the proxy’s URL (http://user:password@host:port, percent-encoded), never shown. An https:// or SOCKS proxy is refused with a message | never |
--attach ws://host:port/devtools/page/<id> | that one tab, worked in as it is (no window of its own): a tab another program left open for a look, like a paused test run | never |
--profile <name> --from <browser> | the same, its profile first replaced with a copy of one of your browser’s profiles (chrome, beta, dev, canary, chromium, edge, or a user data directory; --from-profile picks one by directory, name or email, default the one used last): cookies (HttpOnly too), Local Storage, IndexedDB, saved logins and autofill, bookmarks, preferences, and Local State with the cookie key. Not caches, history, tabs, sync or extensions. The key stays where Chrome keeps it (Keychain, DPAPI, the desktop keyring), so the copy opens for the same user on the same machine. Refused while that profile’s browser runs, and for a directory that is not a browser profile. On Windows close Chrome for the copy; it locks its cookie database | only with quit --close-browser |
--profile <name> | a visible Chrome on its own persistent profile (%LOCALAPPDATA%\navigera\profiles\<name>, ~/Library/Application Support/navigera/profiles/<name>, ~/.local/share/navigera/profiles/<name>; a path works too), started when it isn’t running and reused when it is. Sign in once; cookies, settings and extensions stay. --headless hides it | only with quit --close-browser |
In your own browser the agent gets a window of its own, opened behind
yours so the window you are typing in keeps the keyboard; tab-new opens
another such window rather than a tab among yours. start says which
browser it found and how many of your tabs are open. tab-list lists your
other tabs under user_tabs and marks the one you are on current, and
tab-select current (or a target id from user_tabs) works in that tab:
it becomes the session’s active tab and stays yours, and a window of
navigera’s own that was never used closes. start --attach --tab current
starts in the tab you are on and opens no window at all. The tab you are on
is one of yours on screen, the one whose window has your keyboard, else
the one you switched to last; navigera’s window counts only when none of
yours is on screen. tab-select never brings a tab forward here: the tab
you look at and the window you type in stay as they are, and a tab behind
another still reads, takes clicks and typing, and gives screenshots
(Chrome slows its timers). show brings the session’s tab to the front
when the agent wants you to look at it, and it is yours from then on. Only
popups from the session’s tabs are adopted, and popups from a tab of yours
are yours too.
quit closes the tabs navigera opened and leaves yours open (--keep-tabs
leaves its own too, --close-browser closes the browser); the browser’s
last tab is never closed. An idle or --parent shutdown does the same as
quit. reset lets go of your tabs rather than closing them. Because
Chrome asks to Allow every new connection, these modes need a session (one
connection for all commands): a one-shot command with --attach is
refused. Chrome 136–143 can’t serve its default profile at all (the
--remote-debugging-port switch is ignored for it, and the inspect toggle
arrives in 144): use --profile there, which works on any version.
Made from docs/navigera.md.