Documentation
¶
Index ¶
- Constants
- Variables
- func AcquireContext(b *rod.Browser, name string) (*rod.Browser, error)
- func AcquireSession(name string, opts SessionSpawnOpts) (string, error)
- func AddInitScript(srcPath string) (string, error)
- func AnnotateScreenshot(page *rod.Page, snapshot *PageSnapshot, screenshotPNG []byte) ([]byte, error)
- func ApplyColorScheme(page *rod.Page, scheme string) error
- func ApplyDefaultPageProfile(page *rod.Page) error
- func ApplyDevice(page *rod.Page, d Device) error
- func ApplyInitScriptFiles(page *rod.Page, paths []string) error
- func ApplyInitScripts(page *rod.Page) error
- func ApplyLocale(page *rod.Page, locale string) error
- func ApplyProxyAuth(page *rod.Page, proxyURL string) error
- func ApplyServiceWorkersMode(page *rod.Page, mode string) error
- func ApplyStealth(page *rod.Page) error
- func ApplyTimezone(page *rod.Page, tz string) error
- func ApplyUserAgent(page *rod.Page, ua string) error
- func ApplyUserAgentLocale(page *rod.Page, ua string, locale string) error
- func BuildHTTPClient(opts HTTPClientOpts) (*http.Client, error)
- func CleanupFailedLauncher(l *launcher.Launcher, removeProfile bool)
- func CleanupLauncher(l *launcher.Launcher, removeProfile bool)
- func ClickElement(page *rod.Page, el *rod.Element) error
- func ClickElementWithButton(page *rod.Page, el *rod.Element, button proto.InputMouseButton) error
- func ClickRef(page *rod.Page, ref string, snapshot *PageSnapshot) error
- func ClipboardRead(page *rod.Page) (string, error)
- func ClipboardWrite(page *rod.Page, text string) error
- func CloseContext(b *rod.Browser, name string) error
- func CloseTab(browser *rod.Browser, index int) (proto.TargetTargetID, error)
- func CountSelector(page *rod.Page, selector string) int
- func DblClickRef(page *rod.Page, ref string, snapshot *PageSnapshot) error
- func DblClickRefWithButton(page *rod.Page, ref string, snapshot *PageSnapshot, ...) error
- func DecryptCookiesInPlace(cookiesPath string) (total, decrypted, failed int, err error)
- func DefaultExtensionPaths() ([]string, error)
- func DefaultExtensionsDir() (string, error)
- func DefaultSession() (string, bool)
- func DetachSysProcAttr() *syscall.SysProcAttr
- func DetectAgent() bool
- func DiscoverCDP(ports []int, timeout time.Duration) (string, error)
- func DiscoverCDPChannel(channel string, ports []int, timeout time.Duration) (string, error)
- func DismissCookieBanner(page *rod.Page) bool
- func DragDrop(page *rod.Page, fromRef, toRef string, snapshot *PageSnapshot, steps int) error
- func DragDropCoords(page *rod.Page, sx, sy, dx, dy float64, steps int) error
- func EvadeRuntimeEnable() bool
- func EvalJS(page *rod.Page, expr string, elementRef string, snapshot *PageSnapshot) (string, error)
- func EvalJSTimeout(page *rod.Page, expr string, elementRef string, snapshot *PageSnapshot, ...) (string, error)
- func ExtractNextData(html string) []byte
- func FindSystemChromeBinary() string
- func FormatCollect(r *CollectResult) string
- func FormatDiff(d SnapshotDiff) string
- func FormatErrors(errors []ErrorEntry) string
- func FormatMultiCollect(r *MultiCollectResult) string
- func FormatPlaywrightSnapshot(result *ExtractionResult) string
- func FormatPreview(r *PreviewResult) string
- func FormatPreviewProfile(r *PreviewResult, p RenderProfile) string
- func FormatText(result *ExtractionResult) string
- func FormatTextProfile(result *ExtractionResult, p RenderProfile) string
- func GetResponseBodyByRequestID(page *rod.Page, requestID string) (string, bool, error)
- func GhostchromeDataDirs() []string
- func GrantPlaywrightPermissions(browser *rod.Browser, names []string) error
- func HasSelector(page *rod.Page, selector string) bool
- func HoverElement(page *rod.Page, el *rod.Element) error
- func HoverRef(page *rod.Page, ref string, snapshot *PageSnapshot) error
- func HumanMode() bool
- func InitScriptsDir() (string, error)
- func InjectCookies(page *rod.Page, cookies []CookieRecord) (int, error)
- func InternalRef(ref string) string
- func IsStaticNetworkEntry(resourceType, mimeType string) bool
- func KillAllSessions() (int, error)
- func KillProcess(pid int) error
- func LauncherOwnsRodTempProfile(l *launcher.Launcher, userDataDir string, launchArgs []string) bool
- func ListInitScripts() ([]string, error)
- func LoadFulfillBody(value string) ([]byte, error)
- func LoadRules(rulesPath, baseDir string) ([]compiledRule, error)
- func LoadStorageState(browser *rod.Browser, page *rod.Page, state *StorageState) error
- func MapPlaywrightPermissions(names []string) (mapped []proto.BrowserPermissionType, unsupported []string)
- func MatchRule(rules []compiledRule, url, method string) (*compiledRule, bool)
- func MustReadResponseBody(resp *http.Response) ([]byte, error)
- func NewLauncher(opts LauncherOpts) *launcher.Launcher
- func NewTab(browser *rod.Browser, url string) (*rod.Page, error)
- func ParseBlockList(s string) []string
- func ParseMouseButton(name string) (proto.InputMouseButton, error)
- func ParseProxyList(s string) []string
- func PlaywrightRef(ref string) string
- func PressKey(page *rod.Page, key string, ref string, snapshot *PageSnapshot) error
- func PrewarmDomains(page *rod.Page)
- func ProfileUsesSystemChrome(userDataDir string) bool
- func PruneSessions() (int, error)
- func ReactSuspense(page *rod.Page) ([]map[string]any, error)
- func RecoverBotChallenge(ctx RecoveryContext) (bool, error)
- func RecoverDialogAccept(ctx RecoveryContext) (bool, error)
- func RecoverNetworkSettle(ctx RecoveryContext) (bool, error)
- func RecoverStaleRef(ctx RecoveryContext) (bool, error)
- func RecoveryChain(ctx RecoveryContext, hooks []RecoveryHook) (retry bool, err error)
- func RemoveInitScript(name string) error
- func RemoveProfile(name string) error
- func RenderTraceHTML(entries []TraceEntry, sourcePath string) string
- func ResolveByLocator(page *rod.Page, loc Locator) (*rod.Element, error)
- func ResolveCDPEndpoint(raw string, timeout time.Duration) (string, error)
- func ResolveProfileDir(name string) (string, error)
- func ResolveRef(page *rod.Page, ref string, snapshot *PageSnapshot) (*rod.Element, error)
- func SaveCookiesJSON(profileDir string, cookies []CookieRecord) error
- func ScrollBy(page *rod.Page, dy int) (int, error)
- func ScrollToRef(page *rod.Page, ref string, snapshot *PageSnapshot) error
- func ScrollToY(page *rod.Page, y int, bottomSentinel bool) (int, error)
- func SelectOption(page *rod.Page, ref string, values []string, snapshot *PageSnapshot) error
- func SetCheckedRef(page *rod.Page, ref string, checked bool, snapshot *PageSnapshot) error
- func SetEvadeRuntimeEnable(on bool)
- func SetHumanMode(enabled bool)
- func SetStealthTimezone(tz string)
- func SetViewport(page *rod.Page, width, height int) error
- func StopSession(name string) error
- func SubmitOnElement(page *rod.Page, el *rod.Element) error
- func SwitchTab(browser *rod.Browser, index int) (*rod.Page, error)
- func TakeScreenshot(page *rod.Page, fullPage bool, elementRef string, quality int, ...) ([]byte, error)
- func TakeScreenshotFormat(page *rod.Page, fullPage bool, elementRef string, format string, quality int, ...) ([]byte, error)
- func TakeScreenshotScaled(page *rod.Page, fullPage bool, elementRef string, quality int, scale float64, ...) ([]byte, error)
- func TruncateURL(u string, maxLen int) string
- func TypeElement(page *rod.Page, el *rod.Element, text string) error
- func TypeFocused(page *rod.Page, text string) error
- func TypeRef(page *rod.Page, ref string, text string, snapshot *PageSnapshot) error
- func UploadRef(page *rod.Page, ref string, selector string, files []string, ...) error
- func ValidateExtractLevel(level ExtractLevel) error
- func WaitForBotChallenge(page *rod.Page, timeout time.Duration) bool
- func WaitForLocator(page *rod.Page, loc Locator, state ElementState, timeout time.Duration) (*rod.Element, error)
- func WaitForPage(page *rod.Page, waitStrategy string) error
- func WaitForRef(page *rod.Page, ref string, snapshot *PageSnapshot, state ElementState, ...) (*rod.Element, error)
- func WaitForSelector(page *rod.Page, selector string, timeoutSec int) error
- func WriteHAR(h *HAR, path string) error
- type APIRequest
- type APIResponse
- type AlgoliaOpts
- type Browser
- func (b *Browser) Alive(d time.Duration) bool
- func (b *Browser) AppendConsoleLog(events []ObserverEvent) error
- func (b *Browser) AppendNetworkLog(entries []*CapturedEntry) error
- func (b *Browser) BrowserTraceState() BrowserTraceState
- func (b *Browser) CachedExtract(page *rod.Page) *ExtractionResult
- func (b *Browser) ClearConsoleLog() error
- func (b *Browser) ClearNetworkLog() error
- func (b *Browser) Close()
- func (b *Browser) Connected() bool
- func (b *Browser) ConsoleLog() []ObserverEvent
- func (b *Browser) CurrentTargetID() string
- func (b *Browser) DeleteSnapshot(targetID proto.TargetTargetID) error
- func (b *Browser) NetworkLog() []*CapturedEntry
- func (b *Browser) Page() (*rod.Page, error)
- func (b *Browser) RodBrowser() *rod.Browser
- func (b *Browser) SaveSnapshot(page *rod.Page, result *ExtractionResult) error
- func (b *Browser) SetBrowserTraceState(state BrowserTraceState) error
- func (b *Browser) SetCurrentPage(page *rod.Page) error
- func (b *Browser) SetVideoState(state VideoState) error
- func (b *Browser) Snapshot(page *rod.Page) *PageSnapshot
- func (b *Browser) StartBackgroundObserver(page *rod.Page)
- func (b *Browser) VideoState() VideoState
- type BrowserOpts
- type BrowserTraceState
- type CaptureSession
- type CaptureSpec
- type CapturedEntry
- type CollectResult
- type CollectedItem
- type ContextEntry
- type ContextRegistryEntry
- type CookieRecord
- type Device
- type DialogResult
- type DiffEntry
- type DiffNode
- type DiffStats
- type ElementState
- type ErrorCollector
- type ErrorEntry
- type ExtractLevel
- type ExtractedNode
- type ExtractionResult
- func Extract(page *rod.Page, level ExtractLevel, selector string, includeSSR bool) (*ExtractionResult, error)
- func ExtractWithTimeout(page *rod.Page, level ExtractLevel, selector string, timeout time.Duration, ...) (*ExtractionResult, error)
- func ExtractionForRef(result *ExtractionResult, ref string) (*ExtractionResult, bool)
- func LimitExtractionDepth(result *ExtractionResult, maxDepth int) *ExtractionResult
- type ExtractionStats
- type FastFetchOpts
- type FastResult
- type HAR
- type HARContent
- type HARCreator
- type HAREntry
- type HARLog
- type HARPage
- type HARRequest
- type HARResponse
- type HARTimings
- type HTTPClientOpts
- type ImageDiffResult
- type InterceptSession
- type InterceptSpec
- type InterceptStats
- type LauncherOpts
- type Locator
- type MultiCollectResult
- type NetworkEntry
- type Observation
- type Observer
- func (o *Observer) Drain(afterMs int64) []ObserverEvent
- func (o *Observer) Events() <-chan ObserverEvent
- func (o *Observer) Start(ctx context.Context) error
- func (o *Observer) Stats() ObserverStats
- func (o *Observer) Stop() error
- func (o *Observer) WriteNDJSON(ctx context.Context, w io.Writer) error
- type ObserverEvent
- type ObserverFilters
- type ObserverKind
- type ObserverOpts
- type ObserverStats
- type PageInfo
- type PageSnapshot
- type PlaywrightLogState
- type PreviewResult
- type PreviewSummary
- type ProfileGCCandidate
- type ProfileInfo
- type ProxyPool
- type ReactComponent
- type Recorder
- type RecorderOp
- type RecorderOpts
- type RecoveryContext
- type RecoveryHook
- type RefSnapshot
- type RenderProfile
- type RuleMatchType
- type RuleSpec
- type RulesFile
- type SSRPayload
- type SSRSource
- type ScreenRecorder
- type ScreenRecorderOpts
- type SessionEntry
- type SessionRegistryEntry
- type SessionSpawnOpts
- type SiteResult
- type SnapshotDiff
- type StorageCookie
- type StorageKeyValue
- type StorageOrigin
- type StorageState
- type TabInfo
- type TraceEntry
- type VideoChapter
- type VideoState
Constants ¶
const ( ContentBoundaryOpen = "⟦page⟧" ContentBoundaryClose = "⟦/page⟧" )
ContentBoundaryOpen and ContentBoundaryClose are the sentinel markers used to fence untrusted page-derived text when ContentBoundary is enabled. They use Unicode brackets (U+27E6 / U+27E7) that are unlikely to appear in real page content and are visually distinct from tool output.
⟦page⟧ <untrusted text here> ⟦/page⟧
const CookiesJSONFilename = ".ghostchrome-cookies.json"
CookiesJSONFilename is the filename written by import-profile inside the ghostchrome profile dir. openPage() reads this on startup and replays the cookies into Chrome via CDP Network.setCookies.
const DefaultSessionName = "default"
Variables ¶
var ActivePolicy *policy.Policy
ActivePolicy is the session-wide policy enforced on navigation and actions. Set by the CLI or MCP server at startup. Nil means no restrictions.
var AntiBotPatterns = []string{
"*://js.datadome.co/*",
"*://*.datado.me/*",
"*://api-js.datadome.co/*",
"*://geo.captcha-delivery.com/*",
"*://*.perimeterx.net/*",
"*://client.perimeterx.net/*",
"*://collector-pxk*.px-cloud.net/*",
"*://*.imperva.com/v2/*",
"*://*.incapsula.com/_Incapsula_Resource*",
"*://*.akamaihd.net/akam/*",
"*://googletagservices.com/tag/js/gpt.js*",
"*://*.googletagservices.com/*",
"*://securepubads.g.doubleclick.net/*",
"*://*.googlesyndication.com/*",
"*://cdn.taboola.com/libtrc/*",
"*://cdn.outbrain.com/outbrain-loader.js*",
"*://static.criteo.net/js/*",
}
AntiBotPatterns is the curated list of glob URL patterns for scripts whose only purpose is detection/fingerprinting/heavy tracking. Blocking them at the network layer prevents the main thread from being monopolised by fingerprinting bursts that hang Runtime.evaluate calls.
Conservative list — only includes well-known anti-bot vendors and the heaviest analytics. Does NOT block CMP frameworks (OneTrust, Cookiebot, ...) because some sites' page rendering is gated on consent state.
var DefaultDiscoverPorts = []int{9222, 9223, 9224, 9225, 9226, 9227, 9228, 9229}
DefaultDiscoverPorts is the list of common Chrome remote debugging ports scanned by DiscoverCDP when no explicit port is supplied.
var DefaultExtensionNames = []string{"ublock", "icdc", "force-bg"}
DefaultExtensionNames lists the bundled extension slugs ghostchrome looks for under ~/.ghostchrome/extensions/<name>/ when --default-extensions is set. Mirrors browser-use's defaults.
var ErrSessionNotFound = errors.New("session not found in registry")
var ErrStaleRef = errors.New("stale ref: snapshot is missing or no longer matches the page")
ErrStaleRef indicates that a ref no longer maps to a live element.
Functions ¶
func AcquireContext ¶ added in v0.1.1
AcquireContext returns a *rod.Browser view scoped to the named isolated context. It reuses an existing context if the registry entry is still alive in Chrome, otherwise creates a new one and persists it.
The caller must have already connected b to Chrome before calling this.
func AcquireSession ¶ added in v0.1.1
func AcquireSession(name string, opts SessionSpawnOpts) (string, error)
AcquireSession resolves a named session to a browser WebSocket URL. If the session is already running it is reused; otherwise a detached `serve` process is spawned, bound to the disk profile of the same name, and probed until its CDP endpoint is ready.
func AddInitScript ¶ added in v0.1.1
AddInitScript copies a JS file into the init-scripts directory.
func AnnotateScreenshot ¶ added in v0.1.1
func AnnotateScreenshot(page *rod.Page, snapshot *PageSnapshot, screenshotPNG []byte) ([]byte, error)
AnnotateScreenshot overlays numbered borders on each interactive element identified by the snapshot's refs. Input must be PNG; output is always PNG.
func ApplyColorScheme ¶ added in v0.1.1
ApplyColorScheme emulates prefers-color-scheme. Accepts "dark", "light", "no-preference" (case-insensitive).
func ApplyDefaultPageProfile ¶ added in v0.1.1
ApplyDefaultPageProfile installs the baseline browser profile used by normal pages. Stealth mode can still layer stronger anti-detection overrides later.
Caller responsibility: do NOT call this on a page belonging to a connected (foreign) Chrome unless the user explicitly opted in via --apply-profile. Mutating an existing user tab's UA / viewport breaks the runtime policy stated in CLAUDE.md.
func ApplyDevice ¶ added in v0.1.1
ApplyDevice applies viewport metrics, UA, and touch emulation from a preset.
func ApplyInitScriptFiles ¶ added in v0.4.1
ApplyInitScriptFiles registers JavaScript files to run before future page scripts. This mirrors Playwright's addInitScript-style behavior for config supplied init scripts.
func ApplyInitScripts ¶ added in v0.1.1
ApplyInitScripts loads and evaluates all init scripts on the page.
func ApplyLocale ¶ added in v0.4.1
ApplyLocale emulates Playwright's browser.contextOptions.locale for a page. Without a User-Agent override, CDP has no standalone AcceptLanguage command, so this applies the HTTP header plus navigator.language(s) for new documents.
func ApplyProxyAuth ¶ added in v0.1.1
ApplyProxyAuth wires CDP Fetch interception on the page so that basic-auth challenges issued by an upstream proxy (e.g. Bright Data, Smartproxy) are answered automatically with the credentials embedded in proxyURL.
Chromium ignores user:password embedded in --proxy-server URLs and instead surfaces a blocking basic-auth dialog. The work-around is to enable Fetch.enable{handleAuthRequests:true} and respond to Fetch.authRequired via Fetch.continueWithAuth.
If proxyURL is empty or carries no credentials, this is a silent no-op.
func ApplyServiceWorkersMode ¶ added in v0.4.1
ApplyServiceWorkersMode applies the subset of Playwright's contextOptions.serviceWorkers that CDP can honor directly.
func ApplyStealth ¶
ApplyStealth applies anti-detection patches to a page via CDP. Targets DataDome, Akamai, and similar bot-detection systems.
func ApplyTimezone ¶ added in v0.1.1
ApplyTimezone overrides the JavaScript Date/Intl timezone.
func ApplyUserAgent ¶ added in v0.1.1
ApplyUserAgent overrides navigator.userAgent and the HTTP User-Agent header.
func ApplyUserAgentLocale ¶ added in v0.4.1
ApplyUserAgentLocale overrides the User-Agent and optionally the browser Accept-Language value using the same CDP call Playwright-backed contexts use.
func BuildHTTPClient ¶ added in v0.1.1
func BuildHTTPClient(opts HTTPClientOpts) (*http.Client, error)
BuildHTTPClient returns an http.Client honoring the supplied proxy URL. Supports http://, https:// (HTTP CONNECT) and socks5:// schemes. http(s) proxies may carry user:pass; socks5 auth is taken from URL too.
func CleanupFailedLauncher ¶ added in v0.4.1
CleanupFailedLauncher releases resources after Launcher.Launch returned an error. A non-zero PID means Chrome did start, so wait for Rod's exit channel before deleting. With PID zero no process can still write the generated dir.
func CleanupLauncher ¶ added in v0.4.1
CleanupLauncher synchronously terminates a successfully launched Chrome and optionally removes its Rod-owned temporary profile. Kill must precede Cleanup: Rod's Cleanup waits on the launcher exit channel and has no context or cancellation mechanism of its own.
func ClickElement ¶ added in v0.1.1
ClickElement performs a click on an already-resolved element (used by the locator path so the same scroll+click+wait logic is shared).
func ClickElementWithButton ¶ added in v0.4.1
ClickElementWithButton performs a click with an explicit mouse button.
func ClickRef ¶
func ClickRef(page *rod.Page, ref string, snapshot *PageSnapshot) error
ClickRef clicks the element at the given ref.
func ClipboardRead ¶ added in v0.1.1
ClipboardRead returns the current clipboard text content.
func ClipboardWrite ¶ added in v0.1.1
ClipboardWrite sets the clipboard text content.
func CloseContext ¶ added in v0.1.1
CloseContext disposes the named context in Chrome (if alive) and removes it from the registry.
func CountSelector ¶ added in v0.1.1
CountSelector returns the number of elements matching selector. Errors are swallowed and reported as 0 so the polling caller can distinguish "not-yet-rendered" from "match count below threshold".
func DblClickRef ¶ added in v0.1.1
func DblClickRef(page *rod.Page, ref string, snapshot *PageSnapshot) error
DblClickRef double-clicks the element at the given ref.
func DblClickRefWithButton ¶ added in v0.4.1
func DblClickRefWithButton(page *rod.Page, ref string, snapshot *PageSnapshot, button proto.InputMouseButton) error
DblClickRefWithButton double-clicks an element with an explicit mouse button.
func DecryptCookiesInPlace ¶ added in v0.1.1
DecryptCookiesInPlace opens the SQLite Cookies database at path, decrypts every v10-tagged encrypted_value using the macOS Keychain Chrome key, and rewrites the row with the plaintext in `value` (encrypted_value cleared). Kept for backward compat with profiles imported before the JSON export scheme. Returns counts: total, decrypted, failed.
func DefaultExtensionPaths ¶ added in v0.1.1
DefaultExtensionPaths returns absolute paths to the bundled extensions (uBlock Origin Lite, "I still don't care about cookies", Force Background Tab) that exist on disk. Missing entries are silently skipped. When none are found a hint is printed to stderr.
func DefaultExtensionsDir ¶ added in v0.1.1
DefaultExtensionsDir returns the absolute path to the per-user extensions directory: ~/.ghostchrome/extensions.
func DefaultSession ¶ added in v0.4.1
DefaultSession returns the default attached/session WS URL when it exists and is alive. It does not spawn a new browser.
func DetachSysProcAttr ¶ added in v0.4.1
func DetachSysProcAttr() *syscall.SysProcAttr
DetachSysProcAttr returns platform-specific process attributes for a child that should survive the parent CLI process.
func DetectAgent ¶ added in v0.1.1
func DetectAgent() bool
DetectAgent reports whether the current process runs inside an LLM agent. Detection order:
- GHOSTCHROME_PROFILE=agent|human (explicit override).
- GHOSTCHROME_AGENT=1|true (explicit opt-in).
- Known agent environment variables set by Claude Code, Cursor, Aider, Devin, Gemini CLI, and similar tools.
func DiscoverCDP ¶ added in v0.1.1
DiscoverCDP probes 127.0.0.1 on the given ports for a running Chrome exposing /json/version, and returns the first webSocketDebuggerUrl found. When ports is nil/empty, DefaultDiscoverPorts is used. Returns an error when no endpoint responds within timeout.
func DiscoverCDPChannel ¶ added in v0.4.1
DiscoverCDPChannel probes local Chrome remote-debugging ports for a browser matching a playwright-cli channel name. It attaches only to already running browsers with remote debugging enabled.
func DismissCookieBanner ¶
DismissCookieBanner attempts to find and click a cookie accept button. Returns true if a banner was found and dismissed.
func DragDropCoords ¶ added in v0.1.1
DragDropCoords drags from one coordinate to another.
func EvadeRuntimeEnable ¶ added in v0.4.1
func EvadeRuntimeEnable() bool
EvadeRuntimeEnable reports whether Runtime.* subscriptions must be skipped.
func EvalJS ¶
EvalJS evaluates JavaScript on the page or in an element context. If elementRef is non-empty, the JS runs with `this` bound to that element.
func EvalJSTimeout ¶ added in v0.1.1
func EvalJSTimeout(page *rod.Page, expr string, elementRef string, snapshot *PageSnapshot, d time.Duration) (string, error)
EvalJSTimeout runs EvalJS with a per-call deadline. When the page's main thread is busy (anti-bot fingerprinting, infinite analytics loop, ...), the underlying CDP Runtime.evaluate call hangs until the deadline fires instead of blocking the server-wide timeout. Returns a typed timeout error the caller can surface clearly to the LLM.
func ExtractNextData ¶ added in v0.1.1
ExtractNextData scans for the canonical Next.js SSR data island in arbitrary HTML and returns the raw JSON payload. Returns nil when the marker is absent. Exported so callers that obtain HTML through a different path (e.g. Chrome page.HTML()) can reuse the same parser.
func FindSystemChromeBinary ¶ added in v0.1.1
func FindSystemChromeBinary() string
FindSystemChromeBinary returns the absolute path to a real, installed Google Chrome / Chromium binary, or "" if none is found. Preferring the system Chrome over rod's bundled Chromium matters for anti-bot: the bundled build can lag many versions behind, and an outdated Chrome version is itself a signal Cloudflare-style challenges score against.
func FormatCollect ¶ added in v0.1.1
func FormatCollect(r *CollectResult) string
FormatCollect renders a compact text table from collected items.
func FormatDiff ¶ added in v0.1.1
func FormatDiff(d SnapshotDiff) string
FormatDiff renders a SnapshotDiff as compact text.
func FormatErrors ¶
func FormatErrors(errors []ErrorEntry) string
FormatErrors formats errors as compact text lines.
func FormatMultiCollect ¶ added in v0.1.1
func FormatMultiCollect(r *MultiCollectResult) string
FormatMultiCollect renders a compact text report for multi-URL results.
func FormatPlaywrightSnapshot ¶ added in v0.4.1
func FormatPlaywrightSnapshot(result *ExtractionResult) string
FormatPlaywrightSnapshot renders an accessibility tree in the documented playwright-cli snapshot style:
- heading "Title" [level=1]
- textbox "Search" [ref=e2]
- listitem:
- text: "Item"
func FormatPreview ¶
func FormatPreview(r *PreviewResult) string
FormatPreview renders a compact text report (human profile).
func FormatPreviewProfile ¶ added in v0.1.1
func FormatPreviewProfile(r *PreviewResult, p RenderProfile) string
FormatPreviewProfile renders the preview using the given profile. In agent mode, empty sections and zero-stat headers are dropped, failed requests are grouped by status code and the DOM dump uses one-letter role tags.
func FormatText ¶
func FormatText(result *ExtractionResult) string
FormatText renders the extraction result as compact text (human profile).
func FormatTextProfile ¶ added in v0.1.1
func FormatTextProfile(result *ExtractionResult, p RenderProfile) string
FormatTextProfile renders the extraction result using the given profile. The agent profile uses one-letter role tags, truncates long labels and shortens hrefs (see TruncateURL).
func GetResponseBodyByRequestID ¶ added in v0.4.1
GetResponseBodyByRequestID fetches a response body from the current CDP session.
func GhostchromeDataDirs ¶ added in v0.4.1
func GhostchromeDataDirs() []string
GhostchromeDataDirs returns the data directories a full uninstall removes: ~/.ghostchrome (profiles, contexts, sessions registry) and the ~/.cache/ghostchrome session-snapshot cache. Missing dirs are omitted.
func GrantPlaywrightPermissions ¶ added in v0.4.1
GrantPlaywrightPermissions grants context-wide permissions using CDP. The origin is intentionally omitted to match Playwright config semantics.
func HasSelector ¶ added in v0.1.1
HasSelector reports whether at least one element matches selector. It is a non-throwing alternative to page.Element used by polling loops.
func HoverElement ¶ added in v0.1.1
HoverElement hovers on an already-resolved element.
func HoverRef ¶
func HoverRef(page *rod.Page, ref string, snapshot *PageSnapshot) error
HoverRef hovers over the element at the given ref.
func InitScriptsDir ¶ added in v0.1.1
InitScriptsDir returns the directory for user init scripts.
func InjectCookies ¶ added in v0.1.1
func InjectCookies(page *rod.Page, cookies []CookieRecord) (int, error)
InjectCookies sets the given cookies on the browser via CDP, one at a time. A bad cookie (binary garbage from a misdecoded entry, mismatched domain, etc.) doesn't poison the rest of the batch. Returns the number of successful injections.
func InternalRef ¶ added in v0.4.1
InternalRef maps playwright-cli eN refs back to ghostchrome's internal @N refs.
func IsStaticNetworkEntry ¶ added in v0.4.1
IsStaticNetworkEntry reports whether a request is usually noise for Playwright CLI-style network inspection.
func KillAllSessions ¶ added in v0.1.1
KillAllSessions stops every registered session.
func KillProcess ¶ added in v0.4.1
KillProcess signals a managed background process.
func LauncherOwnsRodTempProfile ¶ added in v0.4.1
LauncherOwnsRodTempProfile reports whether the launcher's final user data directory is the ephemeral direct child generated by Rod. Explicit profile inputs are never owned, even when they happen to live under Rod's prefix.
func ListInitScripts ¶ added in v0.1.1
ListInitScripts returns the names of installed init scripts.
func LoadFulfillBody ¶ added in v0.1.1
LoadFulfillBody returns raw bytes from a @path literal or the string otherwise. Useful so CLI flags can take `"@mock.json"` or an inline payload.
func LoadRules ¶ added in v0.1.1
LoadRules parses path, validates each rule, loads bodyFile contents, and compiles match patterns. baseDir is used to resolve relative bodyFile paths.
func LoadStorageState ¶ added in v0.1.1
LoadStorageState restores cookies browser-wide and localStorage per origin. For each origin referenced, the current page is navigated there briefly so the localStorage write lands in the right context.
func MapPlaywrightPermissions ¶ added in v0.4.1
func MapPlaywrightPermissions(names []string) (mapped []proto.BrowserPermissionType, unsupported []string)
MapPlaywrightPermissions converts Playwright permission names to CDP Browser.grantPermissions values. Unknown permissions are returned so callers can report them instead of silently overclaiming parity.
func MatchRule ¶ added in v0.1.1
MatchRule returns the first compiledRule whose pattern and method match url+method. method may be empty to skip method filtering.
func MustReadResponseBody ¶ added in v0.1.1
MustReadResponseBody is exposed so callers building atypical clients can reuse the gzip handling. We keep readResponseBody (lowercase) for the internal call sites in FastFetch.
func NewLauncher ¶ added in v0.1.1
func NewLauncher(opts LauncherOpts) *launcher.Launcher
NewLauncher returns a configured launcher with the shared anti-detection flags used by both auto-launch (NewBrowser) and the `serve` command. --no-sandbox is auto-enabled when running inside a CI runner (env GITHUB_ACTIONS / CI) or as root, because those environments disable the Chrome sandbox.
func NewTab ¶ added in v0.1.1
NewTab opens a new tab, optionally navigating to url (blank when empty), activates it, and returns the page.
func ParseBlockList ¶ added in v0.1.1
ParseBlockList splits a comma-separated glob list, trimming spaces and dropping empty entries.
func ParseMouseButton ¶ added in v0.4.1
func ParseMouseButton(name string) (proto.InputMouseButton, error)
ParseMouseButton validates Playwright-compatible mouse buttons and returns the corresponding Rod protocol enum.
func ParseProxyList ¶ added in v0.4.1
ParseProxyList splits a proxy list on commas, newlines and spaces, trims each entry and drops empties. Accepts the value of --proxy-list or the GHOSTCHROME_PROXY_LIST env (or the contents of a file passed to either).
func PlaywrightRef ¶ added in v0.4.1
PlaywrightRef maps ghostchrome's internal @N refs to playwright-cli's eN refs.
func PressKey ¶
PressKey sends a keyboard key press. If ref is non-empty, focuses the element first.
func PrewarmDomains ¶ added in v0.1.1
PrewarmDomains enables the CDP domains the engine will need lazily on its first call (Accessibility, DOM, Page lifecycle events). Each enable is idempotent and cheap, so calling this at session start removes the per-domain round-trip from the first extract / navigate / screenshot.
Best-effort: failures are silently ignored — every consumer re-enables the domain it needs anyway.
func ProfileUsesSystemChrome ¶ added in v0.1.1
ProfileUsesSystemChrome returns true when the profile dir was created by `ghostchrome import-profile` and is bound to the system Chrome binary. We keep this for backward compatibility but with the cookie decryption path it's no longer required — the bundled Chromium can now read the imported cookies because they were rewritten as plaintext.
func PruneSessions ¶ added in v0.1.1
PruneSessions removes registry entries whose Chrome is no longer reachable, killing any lingering serve process and its log. Returns the count pruned.
func ReactSuspense ¶ added in v0.1.1
ReactSuspense returns the current Suspense boundary states.
func RecoverBotChallenge ¶ added in v0.1.1
func RecoverBotChallenge(ctx RecoveryContext) (bool, error)
RecoverBotChallenge handles DataDome 403 / Cloudflare 503 bot-challenge pages. It waits up to 10s for the challenge to resolve, then signals retry.
func RecoverDialogAccept ¶ added in v0.1.1
func RecoverDialogAccept(ctx RecoveryContext) (bool, error)
RecoverDialogAccept handles the case where a JS dialog is blocking the page. It accepts the dialog and signals retry=true so the op can be retried.
func RecoverNetworkSettle ¶ added in v0.1.1
func RecoverNetworkSettle(ctx RecoveryContext) (bool, error)
RecoverNetworkSettle handles transient network timeouts by waiting 2s for the network to become idle, then signalling retry.
func RecoverStaleRef ¶ added in v0.1.1
func RecoverStaleRef(ctx RecoveryContext) (bool, error)
RecoverStaleRef handles ErrStaleRef. Per the spec: it must NEVER silently remap refs. Instead it returns retry=false with an informative error so the agent can decide to run an explicit re-extract op.
func RecoveryChain ¶ added in v0.1.1
func RecoveryChain(ctx RecoveryContext, hooks []RecoveryHook) (retry bool, err error)
RecoveryChain runs hooks in order until one returns retry=true or all are exhausted. Returns (true, nil) if a hook signalled recovery, (false, nil) if no hook could help, or (false, err) if a hook returned an error.
func RemoveInitScript ¶ added in v0.1.1
RemoveInitScript removes a script by name from the init-scripts directory.
func RemoveProfile ¶ added in v0.4.1
RemoveProfile deletes a profile directory. The name is validated and the resolved path is confirmed to live under the profiles dir before any removal, so it can never escape via traversal.
func RenderTraceHTML ¶ added in v0.1.1
func RenderTraceHTML(entries []TraceEntry, sourcePath string) string
RenderTraceHTML produces a self-contained HTML viewer of a trace. No external deps; opens directly in a browser.
func ResolveByLocator ¶ added in v0.1.1
ResolveByLocator returns the first element matching the locator. Matching strategy:
- If Text is set: XPath text contains (case-insensitive). Matches <button>, <a>, <label>, generic text containers.
- Else: extract the a11y tree at skeleton level, filter by (role, name|label) and return the first hit.
Snapshot is updated as a side-effect only for the Text branch when a new Extract is triggered.
func ResolveCDPEndpoint ¶ added in v0.4.1
ResolveCDPEndpoint returns a browser WebSocket debugger URL for a CDP endpoint. ws:// and wss:// inputs are already resolved; http(s) inputs are probed via /json/version.
func ResolveProfileDir ¶ added in v0.1.1
ResolveProfileDir converts a short profile name into the canonical persistent Chrome user_data_dir path under ~/.ghostchrome/profiles/<name>. The directory is created with 0700 perms if missing.
func ResolveRef ¶
ResolveRef finds an element by its ref (@1, @2, etc.) using a persisted snapshot.
func SaveCookiesJSON ¶ added in v0.1.1
func SaveCookiesJSON(profileDir string, cookies []CookieRecord) error
SaveCookiesJSON writes a portable cookie snapshot inside the profile dir.
func ScrollToRef ¶ added in v0.1.1
func ScrollToRef(page *rod.Page, ref string, snapshot *PageSnapshot) error
ScrollToRef scrolls the element at the given ref into view without performing any other interaction.
func ScrollToY ¶ added in v0.1.1
ScrollToY scrolls the page to an absolute Y pixel position. When bottomSentinel is true, the page is scrolled to document.body.scrollHeight regardless of the y argument — use this for "scroll-to bottom". Returns the final window.scrollY as observed after the scroll.
func SelectOption ¶
SelectOption selects option(s) in a <select> element by visible text.
func SetCheckedRef ¶ added in v0.1.1
SetCheckedRef brings a checkbox/radio to the desired checked state. It is idempotent: if the element is already in the target state it does nothing, so "check" never accidentally toggles a box that was already ticked.
func SetEvadeRuntimeEnable ¶ added in v0.4.1
func SetEvadeRuntimeEnable(on bool)
SetEvadeRuntimeEnable toggles Runtime.enable evasion process-wide. Wired from the root `--evade-runtime` flag / GHOSTCHROME_EVADE_RUNTIME env.
func SetHumanMode ¶ added in v0.1.1
func SetHumanMode(enabled bool)
SetHumanMode toggles the human-input simulation globally. When false the engine uses the original Rod fast path; when true ClickElement / TypeElement / HoverElement dispatch human-shaped events.
func SetStealthTimezone ¶ added in v0.4.1
func SetStealthTimezone(tz string)
SetStealthTimezone sets the explicit --timezone override applied by ApplyStealth. An empty value falls back to a locale-derived default.
func SetViewport ¶
SetViewport overrides the page viewport dimensions.
func StopSession ¶ added in v0.1.1
StopSession terminates the named session's process and removes it from the registry (best-effort: the process may already be gone).
func SubmitOnElement ¶ added in v0.1.1
SubmitOnElement focuses el and presses Enter on it. TypeElement blurs the field after writing (so change/validation handlers fire), which means a follow-up Enter would otherwise land on document.body — re-focus first so the keydown reaches the input and submits its form.
func TakeScreenshot ¶
func TakeScreenshot(page *rod.Page, fullPage bool, elementRef string, quality int, snapshot *PageSnapshot) ([]byte, error)
TakeScreenshot captures the page or a specific element. If elementRef is non-empty, captures only that element. If fullPage is true, captures the full scrollable page. quality controls JPEG/WebP quality (1-100); PNG is used if quality <= 0.
func TakeScreenshotFormat ¶ added in v0.1.1
func TakeScreenshotFormat(page *rod.Page, fullPage bool, elementRef string, format string, quality int, snapshot *PageSnapshot) ([]byte, error)
TakeScreenshotFormat is the explicit-format variant. format is "png", "jpeg", "webp", or "" to default (webp when quality > 0, png otherwise). WebP at q=60 is typically 30-50% smaller than JPEG at the same visual quality — preferred when the consumer is an LLM agent that pays per byte.
func TakeScreenshotScaled ¶ added in v0.4.1
func TakeScreenshotScaled(page *rod.Page, fullPage bool, elementRef string, quality int, scale float64, snapshot *PageSnapshot) ([]byte, error)
TakeScreenshotScaled is like TakeScreenshot but accepts a device scale factor. scale <= 0 or == 1 means native resolution. scale = 0.5 halves both dimensions (quartering pixel count and file size).
func TruncateURL ¶ added in v0.1.1
TruncateURL strips common scheme/www prefixes and shortens the URL to maxLen. Used by formatted output from preview and collect.
func TypeElement ¶ added in v0.1.1
TypeElement writes text into an already-resolved element.
func TypeFocused ¶ added in v0.4.1
TypeFocused writes text into the currently focused element without changing focus or clearing existing content.
func TypeRef ¶
TypeRef types text into the element at the given ref. Uses focus + select all + keyboard typing to work with React/Vue/Angular.
func UploadRef ¶ added in v0.1.1
func UploadRef(page *rod.Page, ref string, selector string, files []string, snapshot *PageSnapshot) error
UploadRef sets the files on a file-input element.
The target can be identified either by:
- ref: a @N reference from the current snapshot (works when the input is a native, visible <input type=file>).
- selector: a CSS selector (use this when the visible widget is a styled button wrapping a hidden input — common pattern).
Exactly one of ref or selector must be non-empty.
func ValidateExtractLevel ¶ added in v0.1.1
func ValidateExtractLevel(level ExtractLevel) error
ValidateExtractLevel ensures the extraction level is supported.
func WaitForBotChallenge ¶ added in v0.1.1
WaitForBotChallenge detects bot-challenge pages (DataDome, Cloudflare, etc.) and waits for the challenge to clear.
Two behaviours make it materially more reliable than a plain poll loop:
- Reload of a wedged challenge. Cloudflare hands out an independent challenge token per navigation; an instance that hasn't cleared in ~20s almost never un-sticks on its own, but a fresh reload usually gets a solvable one. We reload up to 3 times within the budget.
- A one-off pointer nudge. A few Cloudflare variants only progress once the page has observed a genuine input event.
Returns true if a challenge was detected and ultimately cleared.
func WaitForLocator ¶ added in v0.1.1
func WaitForLocator(page *rod.Page, loc Locator, state ElementState, timeout time.Duration) (*rod.Element, error)
WaitForLocator resolves a Locator with retry-until-found-or-stable logic.
It polls every 100 ms with exponential backoff up to 500 ms per interval. Deadline is set by timeout (0 = no wait, resolve once and return).
Returns the resolved element or a timeout/context error.
func WaitForPage ¶ added in v0.1.1
WaitForPage applies a supported page wait strategy.
Strategies (ordered fastest → slowest typically):
- "domcontentloaded": fires when HTML parsed, before sub-resources. ~200-500ms faster than "load" on real-world pages with images/iframes/3P scripts.
- "load": "load" event — DOM + sub-resources fetched.
- "stable": DOM mutations have settled for 500ms.
- "idle": network has been idle for 500ms.
- "none": return immediately.
Defaults to "domcontentloaded" for empty input — that's the right trade-off for an LLM agent: parsing is done, refs are extractable, but we don't pay for late-loading ads/analytics.
func WaitForRef ¶ added in v0.1.1
func WaitForRef(page *rod.Page, ref string, snapshot *PageSnapshot, state ElementState, timeout time.Duration) (*rod.Element, error)
WaitForRef waits until the element identified by ref in snapshot reaches the desired state.
IMPORTANT: This function PRESERVES the original ref → backendNodeID mapping. It never re-extracts or remaps refs — if the element is stale it returns ErrStaleRef so the caller can decide to re-extract.
Returns the resolved element once it satisfies state, or an error.
func WaitForSelector ¶
WaitForSelector waits for a CSS selector to appear in the DOM.
Types ¶
type APIRequest ¶ added in v0.1.1
type APIRequest struct {
Method string // GET, POST, PUT, DELETE, … (default GET)
URL string // absolute, with query string
Headers map[string]string // any custom headers
Body []byte // request body, plain bytes
Timeout time.Duration // per-request deadline (default 8s)
Proxy string // optional http(s):// or socks5:// proxy URL
}
APIRequest is the cross-method, JSON-aware request shape used by FastFetchAPI. Headers and Body are sent as-is; the helper only owns transport-level details (gzip handling, timeout, JSON detection).
type APIResponse ¶ added in v0.1.1
type APIResponse struct {
Status int `json:"status"`
URL string `json:"url"`
Headers http.Header `json:"headers,omitempty"`
Body []byte `json:"-"`
BodyText string `json:"body_text,omitempty"`
JSON json.RawMessage `json:"json,omitempty"`
IsJSON bool `json:"is_json"`
Elapsed time.Duration `json:"-"`
ElapsedMs int64 `json:"elapsed_ms"`
ContentLength int64 `json:"content_length"`
}
APIResponse is what FastFetchAPI returns. Body is the decoded payload (gzip handled). JSON is non-nil when Body parses cleanly as JSON, regardless of the response Content-Type — many APIs lie about the type.
func AlgoliaQuery ¶ added in v0.1.1
func AlgoliaQuery(ctx context.Context, opts AlgoliaOpts) (*APIResponse, error)
AlgoliaQuery is a small convenience wrapper around FastFetchAPI for the common Algolia search shape used by capcar / starterre / aramis-style recipes:
POST https://<appId>-dsn.algolia.net/1/indexes/<index>/query
X-Algolia-Application-Id: <appId>
X-Algolia-API-Key: <apiKey>
{"params":"<urlencoded form>"}
We construct the params payload from the supplied params map and let FastFetchAPI do the actual HTTP work. Returns the parsed Algolia response (typically `{ hits: [...], nbHits: N, nbPages: P }`).
func FastFetchAPI ¶ added in v0.1.1
func FastFetchAPI(ctx context.Context, req APIRequest) (*APIResponse, error)
FastFetchAPI is the JSON-API counterpart to FastFetch. Use it to replay XHR endpoints captured via `ghostchrome --observe` or to hit a known API directly (Algolia, vendor JSON APIs, public REST). It does not attempt anti-bot detection — APIs that need cookies/tokens fail with a clean status code that the caller acts on.
Differences from FastFetch:
- generic method (GET/POST/PUT/…)
- no SSR / __NEXT_DATA__ scanning
- tries to JSON-parse the body opportunistically; falls back to text
type AlgoliaOpts ¶ added in v0.1.1
type AlgoliaOpts struct {
AppID string
APIKey string
Index string
Endpoint string
Params map[string]string // raw params, joined with `=&`; alternative to ParamsForm
ParamsForm string // pre-built `query=&hitsPerPage=20&page=0` string
ExtraHeaders map[string]string
Timeout time.Duration
Proxy string
}
AlgoliaOpts groups the Algolia-specific knobs. AppID/APIKey/Index are required; Endpoint can be overridden if the site uses a custom DSN.
type Browser ¶
type Browser struct {
// contains filtered or unexported fields
}
Browser wraps a Rod browser with connect/launch logic.
func NewBrowser ¶
NewBrowser creates a browser instance. If connectURL is set, connects to an existing Chrome via CDP. Otherwise, auto-launches a new Chrome process.
func NewBrowserWith ¶ added in v0.1.1
func NewBrowserWith(opts BrowserOpts) (*Browser, error)
NewBrowserWith creates a browser instance with full options. Persistent user_data_dir and upstream proxy only apply in auto-launch mode (i.e., when opts.ConnectURL is empty).
func (*Browser) Alive ¶ added in v0.4.1
Alive reports whether the underlying Chrome still answers CDP within d. A crashed or killed Chrome leaves the rod handle poisoned — every call on it fails with a context error — so callers holding a long-lived Browser use this cheap probe (one Browser.getVersion round-trip, ~1ms on a live process, instant failure on a dead one) before trusting it.
func (*Browser) AppendConsoleLog ¶ added in v0.4.1
func (b *Browser) AppendConsoleLog(events []ObserverEvent) error
AppendConsoleLog appends console events to the persistent session log.
func (*Browser) AppendNetworkLog ¶ added in v0.4.1
func (b *Browser) AppendNetworkLog(entries []*CapturedEntry) error
AppendNetworkLog appends network entries to the persistent session log.
func (*Browser) BrowserTraceState ¶ added in v0.4.1
func (b *Browser) BrowserTraceState() BrowserTraceState
BrowserTraceState returns the persisted CDP tracing state for this session.
func (*Browser) CachedExtract ¶ added in v0.4.1
func (b *Browser) CachedExtract(page *rod.Page) *ExtractionResult
CachedExtract returns the cached ExtractionResult for the current page if the URL has not changed since the last extraction. Returns nil when no cache exists or the page has navigated. This avoids the expensive CDP AccessibilityGetFullAXTree call when the page content is unchanged.
The URL check uses a lightweight JS eval instead of page.Info() to minimize CDP round-trips.
func (*Browser) ClearConsoleLog ¶ added in v0.4.1
ClearConsoleLog removes the persistent console log for this session.
func (*Browser) ClearNetworkLog ¶ added in v0.4.1
ClearNetworkLog removes the persistent network log for this session.
func (*Browser) Connected ¶
Connected returns true if connected to external Chrome (not launched by us).
func (*Browser) ConsoleLog ¶ added in v0.4.1
func (b *Browser) ConsoleLog() []ObserverEvent
ConsoleLog returns a copy of the persistent console log.
func (*Browser) CurrentTargetID ¶ added in v0.1.1
CurrentTargetID returns the persisted current tab target, if any.
func (*Browser) DeleteSnapshot ¶ added in v0.1.1
func (b *Browser) DeleteSnapshot(targetID proto.TargetTargetID) error
DeleteSnapshot removes stored ref state for a closed page target.
func (*Browser) NetworkLog ¶ added in v0.4.1
func (b *Browser) NetworkLog() []*CapturedEntry
NetworkLog returns a copy of the persistent network log.
func (*Browser) Page ¶
Page returns the active page or creates a new one. When connected to an existing Chrome, it prefers the persisted active tab.
func (*Browser) RodBrowser ¶ added in v0.1.1
RodBrowser returns the underlying rod.Browser for advanced operations.
func (*Browser) SaveSnapshot ¶ added in v0.1.1
func (b *Browser) SaveSnapshot(page *rod.Page, result *ExtractionResult) error
SaveSnapshot persists the latest ref snapshot for the page.
SSRPayloads are stripped from the persisted copy before caching (see stripSSRForCache) — the caller's result, used for the immediate command response, is left untouched; only the copy written to disk is stripped, so a later non-SSR command reading this cache via CachedExtract can never leak SSR data it didn't ask for.
func (*Browser) SetBrowserTraceState ¶ added in v0.4.1
func (b *Browser) SetBrowserTraceState(state BrowserTraceState) error
SetBrowserTraceState stores the CDP tracing state for this session.
func (*Browser) SetCurrentPage ¶ added in v0.1.1
SetCurrentPage marks the provided page as the current tab for the session.
func (*Browser) SetVideoState ¶ added in v0.4.1
func (b *Browser) SetVideoState(state VideoState) error
SetVideoState stores video metadata for this session.
func (*Browser) Snapshot ¶ added in v0.1.1
func (b *Browser) Snapshot(page *rod.Page) *PageSnapshot
Snapshot returns the last persisted snapshot for the current page.
func (*Browser) StartBackgroundObserver ¶ added in v0.4.1
Close cleans up the browser resources. External Chrome keeps running; the CLI process owns the websocket lifetime.
func (*Browser) VideoState ¶ added in v0.4.1
func (b *Browser) VideoState() VideoState
VideoState returns the persisted video metadata for this session.
type BrowserOpts ¶ added in v0.1.1
type BrowserOpts struct {
ConnectURL string
Headless bool
Invisible bool
TimeoutSec int
CDPHeaders map[string]string
CDPTimeoutMS int
UserDataDir string // absolute path; ignored when ConnectURL is set
Proxy string // upstream proxy URL; ignored when ConnectURL is set
ProxyBypass string // Chromium proxy bypass list; ignored when ConnectURL is set
ExecutablePath string // Chrome/Chromium binary path; ignored when ConnectURL is set
LaunchArgs []string // extra Chromium switches; ignored when ConnectURL is set
Extensions []string // absolute paths to unpacked extensions; ignored when ConnectURL is set
SystemChrome bool // force /Applications/Google Chrome.app binary; ignored when ConnectURL is set
// AttachFresh is set when ConnectURL points at a Chrome we don't own
// (the user's personal browser, discovered via DiscoverCDP). In that
// case we must NOT reuse any existing tab — every command works in a
// freshly created background target so the user's foreground tab is
// left untouched. Ignored in auto-launch mode.
AttachFresh bool
// ContextName, when non-empty, routes all page operations through a
// named isolated BrowserContext (incognito). The name→contextID mapping
// is persisted in ~/.ghostchrome/contexts.json across CLI invocations.
// Only meaningful in connected mode (ConnectURL != ""). In auto-launch
// mode each process already gets its own profile; the flag is ignored.
ContextName string
// TargetTabIndex selects an explicit tab index in connected mode.
// Nil means "use persisted state or auto-select when unambiguous".
TargetTabIndex *int
// ApplyProfile, when true, installs ghostchrome's default UA / viewport
// profile on whichever page Page() resolves to. In auto-launch mode it
// is on by default (the page is ours). In connected mode it must be
// explicit — mutating a foreign Chrome tab violates the runtime policy
// stated in CLAUDE.md.
ApplyProfile bool
// ProviderFunc, when set, replaces the local launcher for Chrome
// provisioning. Returns a WS URL and a cleanup function. Ignored
// when ConnectURL is set (direct connection takes precedence).
ProviderFunc func(ctx context.Context) (wsURL string, cleanup func(), err error)
}
BrowserOpts configures NewBrowserWith. It supersedes the positional parameters of NewBrowser and adds persistent profile + upstream proxy support for auto-launch.
type BrowserTraceState ¶ added in v0.4.1
type BrowserTraceState struct {
Active bool `json:"active,omitempty"`
StartedAt string `json:"started_at,omitempty"`
Output string `json:"output,omitempty"`
}
BrowserTraceState tracks whether CDP browser tracing is currently active for a persistent session.
type CaptureSession ¶ added in v0.1.1
type CaptureSession struct {
// contains filtered or unexported fields
}
CaptureSession owns the goroutine that listens to Network events.
func StartCapture ¶ added in v0.1.1
func StartCapture(page *rod.Page, spec CaptureSpec) (*CaptureSession, error)
StartCapture enables the Network domain and begins listening.
func (*CaptureSession) Entries ¶ added in v0.1.1
func (s *CaptureSession) Entries() []*CapturedEntry
Entries returns a snapshot of collected entries.
func (*CaptureSession) ReachedMax ¶ added in v0.1.1
func (s *CaptureSession) ReachedMax() <-chan struct{}
ReachedMax fires once Max matches have been collected.
func (*CaptureSession) Stop ¶ added in v0.1.1
func (s *CaptureSession) Stop() ([]*CapturedEntry, error)
Stop detaches listeners, closes the output file, and returns any write errors.
type CaptureSpec ¶ added in v0.1.1
type CaptureSpec struct {
// URLMatch is a regex applied to the full request URL. Empty = match all.
URLMatch string
// MimeMatch is a regex applied to the response MIME type. Empty = match all.
MimeMatch string
// Max is the number of MATCHING entries to collect before ReachedMax fires.
// 0 = unlimited.
Max int
// IncludeBody, when true, fetches the response body via
// Network.getResponseBody for every matching entry.
IncludeBody bool
// ExcludeStatic drops script, stylesheet, font, image, and media requests from
// matching entries. It is intended for Playwright CLI-compatible network
// output; raw capture keeps static resources by default.
ExcludeStatic bool
// OutputPath, if set, streams each entry as it is captured (NDJSON).
OutputPath string
}
CaptureSpec configures a passive network capture session. Generic DevTools-Network-tab style recorder: no request modification, no auth bypass — just observation of what the page already requested.
type CapturedEntry ¶ added in v0.1.1
type CapturedEntry struct {
RequestID string `json:"request_id"`
Method string `json:"method"`
URL string `json:"url"`
ResourceType string `json:"resource_type"`
Status int `json:"status"`
StatusText string `json:"status_text,omitempty"`
MimeType string `json:"mime_type,omitempty"`
ReqHeaders map[string]string `json:"request_headers,omitempty"`
ResHeaders map[string]string `json:"response_headers,omitempty"`
PostData string `json:"post_data,omitempty"`
Body string `json:"body,omitempty"`
BodyBase64 bool `json:"body_base64,omitempty"`
BodyError string `json:"body_error,omitempty"`
StartedAt string `json:"started_at"`
}
CapturedEntry is one fully-hydrated request/response pair.
type CollectResult ¶ added in v0.1.1
type CollectResult struct {
PageURL string `json:"page_url"`
ItemCount int `json:"item_count"`
Items []CollectedItem `json:"items"`
}
CollectResult holds all collected items from a listing page.
func Collect ¶ added in v0.1.1
func Collect(page *rod.Page, limit int) (*CollectResult, error)
Collect auto-detects repeated listing cards on a page and extracts structured data. It finds elements containing price patterns (€, $, £), groups them by common ancestor, and extracts title, price, URL, and metadata from each card.
type CollectedItem ¶ added in v0.1.1
type CollectedItem struct {
Title string `json:"title"`
Price string `json:"price,omitempty"`
URL string `json:"url,omitempty"`
Fields map[string]string `json:"fields,omitempty"`
}
CollectedItem is a single listing item extracted from a page.
type ContextEntry ¶ added in v0.1.1
type ContextEntry struct {
ID string `json:"id"`
}
ContextEntry maps a user-supplied name to a CDP BrowserContextID.
type ContextRegistryEntry ¶ added in v0.1.1
type ContextRegistryEntry struct {
Name string `json:"name"`
ID string `json:"id"`
Alive bool `json:"alive"`
Unknown bool `json:"unknown,omitempty"` // true when Chrome is unreachable
}
ContextRegistryEntry is the public-facing representation used by the CLI.
func ListContexts ¶ added in v0.1.1
func ListContexts(b *rod.Browser) ([]ContextRegistryEntry, error)
ListContexts returns all registry entries annotated with liveness. b may be nil — in that case all entries are reported as unknown/false.
func (ContextRegistryEntry) AliveStr ¶ added in v0.1.1
func (e ContextRegistryEntry) AliveStr() string
AliveStr returns "yes", "no", or "?" depending on liveness state.
type CookieRecord ¶ added in v0.1.1
type CookieRecord struct {
Name string `json:"name"`
Value string `json:"value"`
Domain string `json:"domain"`
Path string `json:"path"`
Expires float64 `json:"expires"` // CDP unix seconds, 0 = session
Secure bool `json:"secure"`
HTTPOnly bool `json:"httpOnly"`
SameSite string `json:"sameSite,omitempty"` // "Strict"|"Lax"|"None"|""
}
CookieRecord holds the subset of fields ghostchrome injects via CDP at session start. Mirrors the relevant columns of Chrome's Cookies SQLite schema, plus the decrypted plaintext value.
func ExportDecryptedCookies ¶ added in v0.1.1
func ExportDecryptedCookies(cookiesPath string) ([]CookieRecord, error)
ExportDecryptedCookies opens the SQLite Cookies db at path, decrypts every v10-tagged encrypted_value via macOS Keychain, and returns the list as portable CookieRecord values. Source file is not modified.
func LoadCookiesJSON ¶ added in v0.1.1
func LoadCookiesJSON(profileDir string) ([]CookieRecord, error)
LoadCookiesJSON reads the snapshot if present. Returns nil, nil when the file is absent (no import done on this profile).
type Device ¶ added in v0.1.1
type Device struct {
Name string
Width int
Height int
DPR float64
UserAgent string
Mobile bool
Touch bool
}
Device describes a hardware profile used by the emulate command. Dimensions are CSS pixels; DPR is devicePixelRatio.
func DeviceByName ¶ added in v0.1.1
DeviceByName looks up a Device preset by its canonical name.
func ListDevices ¶ added in v0.1.1
func ListDevices() []Device
ListDevices returns a copy of the registered device presets.
type DialogResult ¶ added in v0.1.1
type DialogResult struct {
Handled bool `json:"handled"`
Action string `json:"action"`
Type string `json:"type,omitempty"`
Message string `json:"message,omitempty"`
URL string `json:"url,omitempty"`
DefaultPrompt string `json:"default_prompt,omitempty"`
TimedOut bool `json:"timed_out,omitempty"`
}
DialogResult describes how a JS dialog handler completed.
func HandleNextDialog ¶
func HandleNextDialog(page *rod.Page, accept bool, promptText string, timeout time.Duration) (*DialogResult, error)
HandleNextDialog waits for the next JavaScript dialog and handles it. The timeout is propagated via context so wait() unblocks cleanly on timeout and no goroutine is leaked.
type DiffNode ¶ added in v0.1.1
type DiffNode struct {
Ref string `json:"ref"`
Role string `json:"role"`
Name string `json:"name,omitempty"`
Href string `json:"href,omitempty"`
Value string `json:"value,omitempty"`
}
DiffNode is the minimal payload we return for added nodes.
type DiffStats ¶ added in v0.1.1
type DiffStats struct {
AddedCount int `json:"added"`
RemovedCount int `json:"removed"`
ChangedCount int `json:"changed"`
KeptCount int `json:"kept"`
}
DiffStats summarises a diff for agent consumption.
type ElementState ¶ added in v0.1.1
type ElementState string
ElementState describes the desired element state for WaitForLocator.
const ( // StateAttached waits until the element is present in the DOM. StateAttached ElementState = "attached" // StateVisible waits until the element is visible (not display:none, not hidden). StateVisible ElementState = "visible" // StateHidden waits until the element is hidden or removed. StateHidden ElementState = "hidden" // StateEnabled waits until the element is not disabled. StateEnabled ElementState = "enabled" // StateStable waits until the element's bounding box stops moving for 100ms. StateStable ElementState = "stable" )
func ParseElementState ¶ added in v0.1.1
func ParseElementState(s string) (ElementState, error)
ParseElementState validates and normalises the string form of a state. Empty string defaults to StateAttached.
type ErrorCollector ¶
type ErrorCollector struct {
// contains filtered or unexported fields
}
ErrorCollector collects console-side errors from a page via CDP events.
func NewErrorCollector ¶
func NewErrorCollector(page *rod.Page) *ErrorCollector
NewErrorCollector creates a collector and starts listening on the page. It hooks into RuntimeConsoleAPICalled, RuntimeExceptionThrown, and LogEntryAdded. The Log domain carries browser-side messages (CORS, mixed content, CSP violations, deprecation, network ERR_*, cookie warnings) that the Runtime domain does NOT surface — they show up in DevTools Console but go through a different CDP channel. The caller must call Close() to detach the listeners.
func (*ErrorCollector) Close ¶ added in v0.1.1
func (c *ErrorCollector) Close()
Close detaches the error listeners and waits for the dispatch goroutine to drain any in-flight events before returning, so callers that snapshot just before Close see a consistent view.
func (*ErrorCollector) Errors ¶
func (c *ErrorCollector) Errors() []ErrorEntry
Errors returns all collected errors (snapshot).
type ErrorEntry ¶
type ErrorEntry struct {
Type string `json:"type"` // "console" or "network"
Level string `json:"level"` // "error", "warning", "4xx", "5xx"
Message string `json:"message"` // error message or URL
Source string `json:"source"` // file:line for console, URL for network
Status int `json:"status,omitempty"` // HTTP status for network errors
Method string `json:"method,omitempty"` // HTTP method for network
TimeMs int64 `json:"time_ms"` // timestamp relative to collector start
}
ErrorEntry represents a single console or network error.
type ExtractLevel ¶
type ExtractLevel string
ExtractLevel controls how much of the accessibility tree is returned.
const ( LevelSkeleton ExtractLevel = "skeleton" LevelContent ExtractLevel = "content" LevelFull ExtractLevel = "full" )
type ExtractedNode ¶
type ExtractedNode struct {
Ref string `json:"ref,omitempty"`
Role string `json:"role"`
Name string `json:"name,omitempty"`
Value string `json:"value,omitempty"`
Level int `json:"level,omitempty"`
Href string `json:"href,omitempty"`
Type string `json:"type,omitempty"`
Checked *bool `json:"checked,omitempty"`
Disabled bool `json:"disabled,omitempty"`
BackendNodeID proto.DOMBackendNodeID `json:"-"`
Children []ExtractedNode `json:"children,omitempty"`
}
ExtractedNode represents a filtered accessibility node.
type ExtractionResult ¶
type ExtractionResult struct {
Nodes []ExtractedNode `json:"nodes"`
Refs map[string]ExtractedNode `json:"refs"`
Stats ExtractionStats `json:"stats"`
// SSRPayloads is populated as a fallback when the accessibility tree
// comes back empty or fails to load — e.g. an SSR/hydration-driven page
// (Next.js, Nuxt, ...) still mid-hydration behind an unresolved bot
// challenge. See ssrFallbackPayloads. Only populated when the caller
// opts in (includeSSR) — these payloads (__NEXT_DATA__, __APOLLO_STATE__,
// RSC chunks, ...) can carry tokens/PII on an authenticated page, so they
// must not be exposed to the LLM by default.
SSRPayloads []SSRPayload `json:"ssr_payloads,omitempty"`
}
ExtractionResult holds the extraction output.
func Extract ¶
func Extract(page *rod.Page, level ExtractLevel, selector string, includeSSR bool) (*ExtractionResult, error)
Extract retrieves the accessibility tree from the page and filters it. The CDP call uses its own 30 s timeout so a slow navigation doesn't eat into the extraction budget. includeSSR controls whether the SSR-fallback payloads (see ExtractionResult.SSRPayloads) are returned; pass false unless the caller explicitly wants them exposed.
func ExtractWithTimeout ¶ added in v0.4.1
func ExtractWithTimeout(page *rod.Page, level ExtractLevel, selector string, timeout time.Duration, includeSSR bool) (*ExtractionResult, error)
ExtractWithTimeout is like Extract but accepts an explicit timeout for the CDP AccessibilityGetFullAXTree call. Use 0 to inherit the page's context deadline (previous behavior).
func ExtractionForRef ¶ added in v0.4.1
func ExtractionForRef(result *ExtractionResult, ref string) (*ExtractionResult, bool)
ExtractionForRef returns a single-root extraction result for ref.
func LimitExtractionDepth ¶ added in v0.4.1
func LimitExtractionDepth(result *ExtractionResult, maxDepth int) *ExtractionResult
LimitExtractionDepth returns a copy of result whose node children are cut after maxDepth. A negative maxDepth returns result unchanged; 0 keeps only root nodes.
func (ExtractionResult) MarshalJSON ¶ added in v0.4.1
func (r ExtractionResult) MarshalJSON() ([]byte, error)
MarshalJSON serializes the extraction result for the wire: the JSONL `agent` protocol (what the TS/Python SDKs speak), `extract --json`, and the MCP surface. In memory every entry in Refs carries the interactive node's full Children subtree — ExtractionForRef relies on it to scope output to a single ref — but that subtree is already present in Nodes, so serializing it again for every interactive element duplicated a large slice of the payload the agent/SDK receives (the SDK's lightweight RefEntry type never modeled those children). Strip Children from Refs on the wire only; the in-memory struct is left untouched, so ExtractionForRef and other internal readers still see the subtree. Every interactive node already has its own top-level key in Refs, so dropping the nested subtree loses no ref.
type ExtractionStats ¶
type ExtractionStats struct {
TotalNodes int `json:"total_nodes"`
FilteredNodes int `json:"filtered_nodes"`
InteractiveCount int `json:"interactive_count"`
}
ExtractionStats provides extraction metrics.
type FastFetchOpts ¶ added in v0.1.1
type FastFetchOpts struct {
UserAgent string // "" → derived from runtime.GOOS like ApplyDefaultPageProfile
AcceptLanguage string // default "fr-FR,fr;q=0.9,en-US;q=0.8,en;q=0.7"
Timeout time.Duration // default 8s
ExtraHeaders map[string]string
Proxy string // optional http(s):// or socks5:// proxy URL
}
FastFetchOpts tunes the no-browser HTTP path.
type FastResult ¶ added in v0.1.1
type FastResult struct {
Status int
URL string // final URL after redirects
HTML string
NextData []byte // raw JSON from <script id="__NEXT_DATA__">; nil if absent
SSRPayloads []SSRPayload
Blocked bool // anti-bot challenge detected
Reason string // human-readable explanation when Blocked or no payload extracted
Elapsed time.Duration
}
FastResult is what FastFetch returns. Blocked means "this page is gated by an anti-bot challenge — do NOT trust the body, fall back to a real browser".
NextData is the raw __NEXT_DATA__ JSON when present; SSRPayloads holds the full set of structured data islands found in the body (Next, Nuxt, Apollo, Initial-State, JSON-LD…). Modern recipes pick the first match they understand; legacy callers can keep using NextData.
func FastFetch ¶ added in v0.1.1
func FastFetch(ctx context.Context, url string, opts FastFetchOpts) (*FastResult, error)
FastFetch performs a single GET with realistic browser headers and inspects the response for SSR data and anti-bot markers. It's a best-effort fast path: callers must check (Blocked || NextData == nil) and decide whether to fall back to a Chrome-driven recipe.
type HAR ¶ added in v0.1.1
type HAR struct {
Log HARLog `json:"log"`
}
HAR follows the HAR 1.2 specification (W3C Web Performance Working Group). It's intentionally minimal: we only populate what NetworkEntry knows about, leaving the optional fields (headers, cookies, content text) empty so parsers treat them as "not captured" rather than "empty".
func BuildHAR ¶ added in v0.1.1
func BuildHAR(entries []NetworkEntry, pageURL, pageTitle, creatorVersion string) *HAR
BuildHAR constructs a HAR from the passive NetworkEntry slice collected by requestTracker. pageURL and pageTitle name the top-level page.
type HARContent ¶ added in v0.1.1
HARContent carries the payload summary (size, MIME).
type HARCreator ¶ added in v0.1.1
HARCreator identifies the tool that recorded the trace.
type HAREntry ¶ added in v0.1.1
type HAREntry struct {
PageRef string `json:"pageref,omitempty"`
StartedDateTime string `json:"startedDateTime"`
Time int64 `json:"time"`
Request HARRequest `json:"request"`
Response HARResponse `json:"response"`
Cache struct{} `json:"cache"`
Timings HARTimings `json:"timings"`
}
HAREntry is one network request + response.
type HARLog ¶ added in v0.1.1
type HARLog struct {
Version string `json:"version"`
Creator HARCreator `json:"creator"`
Pages []HARPage `json:"pages"`
Entries []HAREntry `json:"entries"`
}
HARLog is the top-level container.
type HARPage ¶ added in v0.1.1
type HARPage struct {
StartedDateTime string `json:"startedDateTime"`
ID string `json:"id"`
Title string `json:"title"`
}
HARPage groups entries by the top-level navigation that produced them.
type HARRequest ¶ added in v0.1.1
type HARRequest struct {
Method string `json:"method"`
URL string `json:"url"`
HTTPVersion string `json:"httpVersion"`
Headers []string `json:"headers"`
QueryString []string `json:"queryString"`
HeadersSize int `json:"headersSize"`
BodySize int `json:"bodySize"`
}
HARRequest describes the outgoing request.
type HARResponse ¶ added in v0.1.1
type HARResponse struct {
Status int `json:"status"`
StatusText string `json:"statusText"`
HTTPVersion string `json:"httpVersion"`
Headers []string `json:"headers"`
Cookies []string `json:"cookies"`
Content HARContent `json:"content"`
RedirectURL string `json:"redirectURL"`
HeadersSize int `json:"headersSize"`
BodySize int `json:"bodySize"`
}
HARResponse describes the incoming response.
type HARTimings ¶ added in v0.1.1
type HARTimings struct {
Send int `json:"send"`
Wait int64 `json:"wait"`
Receive int `json:"receive"`
}
HARTimings models per-phase durations. We only know the total so we put it on "wait".
type HTTPClientOpts ¶ added in v0.1.1
HTTPClientOpts configures the proxy-aware http.Client used by the no-browser commands (fastfetch, fetchapi). Empty Proxy means direct.
type ImageDiffResult ¶ added in v0.1.1
type ImageDiffResult struct {
Width int `json:"width"`
Height int `json:"height"`
PixelsTotal int `json:"pixels_total"`
PixelsChanged int `json:"pixels_changed"`
DiffRatio float64 `json:"diff_ratio"`
DiffPath string `json:"diff_path,omitempty"`
Skipped bool `json:"skipped,omitempty"`
SkipReason string `json:"skip_reason,omitempty"`
}
ImageDiffResult summarises a pixel-by-pixel comparison.
func DiffImages ¶ added in v0.1.1
func DiffImages(baselinePNG, currentPNG []byte, tolerance int, diffPath string) (*ImageDiffResult, error)
DiffImages compares two images pixel by pixel. When dimensions differ, the result is flagged Skipped so the caller can decide (usually: fail or use the new image as the new baseline).
If diffPath is non-empty, a PNG is written there highlighting every pixel where delta >= tolerance in red (original otherwise).
type InterceptSession ¶ added in v0.1.1
type InterceptSession struct {
// contains filtered or unexported fields
}
InterceptSession owns the router lifetime. Stop() must be called to release resources.
func StartAntiBotBlocker ¶ added in v0.1.1
func StartAntiBotBlocker(browser *rod.Browser, extraPatterns ...string) (*InterceptSession, error)
StartAntiBotBlocker installs a request blocker for AntiBotPatterns on the given browser. Returns the InterceptSession so the caller can Stop() it and read the Stats() to know how many requests were blocked.
extraPatterns lets callers extend the curated list (e.g. site-specific trackers known to cause issues).
func StartIntercept ¶ added in v0.1.1
func StartIntercept(browser *rod.Browser, spec InterceptSpec) (*InterceptSession, error)
StartIntercept enables Fetch interception on the browser and returns an InterceptSession. The caller is responsible for Stop().
func (*InterceptSession) Stats ¶ added in v0.1.1
func (s *InterceptSession) Stats() *InterceptStats
Stats returns the live counters.
func (*InterceptSession) Stop ¶ added in v0.1.1
func (s *InterceptSession) Stop() error
Stop disables interception and waits for the background goroutine.
type InterceptSpec ¶ added in v0.1.1
type InterceptSpec struct {
// BlockPatterns list glob URL patterns to block with
// NetworkErrorReasonBlockedByClient.
BlockPatterns []string
// FulfillPattern optionally matches requests to be answered with the
// FulfillBody payload and FulfillStatus response code. Only set one pattern.
FulfillPattern string
FulfillBody []byte
FulfillStatus int
FulfillContentType string
FulfillHeaders map[string]string
RemoveRequestHeaders []string
// Rules are pre-compiled rule-file entries. When non-empty, each incoming
// request is matched against them before falling through to FulfillPattern /
// BlockPatterns. Populated by LoadRules; callers should not build this slice
// manually.
Rules []compiledRule
}
InterceptSpec configures a request interception router.
type InterceptStats ¶ added in v0.1.1
type InterceptStats struct {
Blocked int
Fulfilled int
Passed int
// contains filtered or unexported fields
}
InterceptStats are cumulative counters updated by the router goroutine.
func (*InterceptStats) Snapshot ¶ added in v0.1.1
func (s *InterceptStats) Snapshot() (blocked, fulfilled, passed int)
Snapshot returns a concurrent-safe copy of the counters.
type LauncherOpts ¶ added in v0.1.1
type LauncherOpts struct {
Headless bool
RemotePort int // 0 = random
// Invisible forces headful Chrome (real rendering pipeline, harder to
// fingerprint as a bot) but positions the window far off-screen so it
// stays out of sight. Overrides Headless when set.
Invisible bool
// UserDataDir is the absolute Chrome --user-data-dir path. Empty means
// ephemeral. Use ResolveProfileDir to convert a short profile name into
// the canonical path under ~/.ghostchrome/profiles/<name>.
UserDataDir string
// Proxy is the upstream proxy URL passed to Chrome via --proxy-server.
// Examples: "http://user:pass@host:port", "socks5://host:1080".
// Empty means no proxy.
Proxy string
// ProxyBypass is passed to Chrome as --proxy-bypass-list when Proxy is set.
// It uses Chromium's bypass list syntax, matching Playwright's proxy.bypass.
ProxyBypass string
// ExecutablePath forces a specific Chrome/Chromium binary. It maps
// Playwright's browser.launchOptions.executablePath and overrides
// ghostchrome's system-Chrome preference.
ExecutablePath string
// Args are extra Chromium command-line switches, normalized as --flag or
// --flag=value. They map Playwright's browser.launchOptions.args.
Args []string
// Extensions is a list of absolute paths to unpacked Chrome extensions
// (each path must contain a manifest.json at its root). When non-empty,
// Chrome is launched with --load-extension and --disable-extensions-except
// so only the listed extensions are active. Note: requires HeadlessNew
// (the modern headless mode); old --headless ignores extensions.
Extensions []string
// SystemChrome forces the launcher to use the system's Google Chrome
// binary (com.google.Chrome bundle) instead of rod's bundled Chromium.
// Required when reusing a profile imported from the user's real Chrome
// — only com.google.Chrome can decrypt cookies sealed by macOS Keychain
// "Chrome Safe Storage". Auto-detected via the .ghostchrome-system-chrome
// marker file in the profile dir.
SystemChrome bool
}
LauncherOpts configures a stealth-flavored Chrome launcher.
type Locator ¶ added in v0.1.1
type Locator struct {
// Role matches the ARIA role (see engine.interactiveRoles, engine.skeletonRoles).
// Accepts canonical role strings or their one-letter agent abbreviation
// ("b"=button, "a"=link, "t"=textbox, etc.).
Role string
// Name matches the accessible name. Comparison is case-insensitive and uses
// substring matching, so "Sign in" matches "Sign in now".
Name string
// Label matches the accessible label derived from <label for=...> or
// aria-labelledby. In Chromium's a11y tree, that's exposed as the name of
// a textbox / combobox — so this is equivalent to Name for inputs.
// Included as a separate field for ergonomic CLI flags (--by-label).
Label string
// Text matches via page-wide text search — like Playwright's getByText.
// When set, Role is ignored.
Text string
}
Locator describes a semantic element match. At least one field must be set. When multiple fields are set, the match is conjunctive (all must hold).
type MultiCollectResult ¶ added in v0.1.1
type MultiCollectResult struct {
TotalItems int `json:"total_items"`
TotalTimeMs int64 `json:"total_time_ms"`
Sites []SiteResult `json:"sites"`
}
MultiCollectResult holds results from parallel multi-URL collection.
func MultiCollect ¶ added in v0.1.1
func MultiCollect(browser *rod.Browser, urls []string, limit int, stealth bool, maxParallel int) *MultiCollectResult
MultiCollect scrapes multiple URLs in parallel using separate browser tabs. Each URL gets its own tab, navigates, collects, and closes. maxParallel caps the number of concurrent tabs; <= 0 falls back to 5.
type NetworkEntry ¶
type NetworkEntry struct {
Method string `json:"method,omitempty"`
URL string `json:"url"`
Status int `json:"status"`
Size int `json:"size_bytes"`
TimeMs int64 `json:"time_ms"`
MimeType string `json:"mime_type,omitempty"`
Error string `json:"error,omitempty"`
}
NetworkEntry represents a captured network request.
type Observation ¶ added in v0.1.1
type Observation struct {
// ConsoleErrors holds runtime errors or uncaught exceptions observed during
// the op (kind=error from the Observer).
ConsoleErrors []ObserverEvent `json:"console_errors,omitempty"`
// NetworkFailed holds network requests that failed (4xx/5xx or transport
// error) during the op.
NetworkFailed []ObserverEvent `json:"network_failed,omitempty"`
// A11yDiff is the compact text diff of the a11y tree between before and
// after the op (FormatDiff output). Empty when there is no change.
A11yDiff string `json:"a11y_diff,omitempty"`
// Dialog is the text of a pending JS dialog detected on the page ("alert
// open: <message>"). Empty when no dialog is open.
Dialog string `json:"dialog,omitempty"`
// CaptchaHint is set when a bot-challenge page is detected
// ("datadome", "cloudflare", or a generic "captcha").
CaptchaHint string `json:"captcha_hint,omitempty"`
// URL is the current page URL at the time the observation was built.
URL string `json:"url,omitempty"`
}
Observation is the structured feedback packet returned after each agent op. All fields are omitempty so an empty observation serialises to `{}`.
func BuildObservation ¶ added in v0.1.1
func BuildObservation(page *rod.Page, before, after *PageSnapshot, events []ObserverEvent) Observation
BuildObservation constructs an Observation from the observer events that occurred during a single op, the a11y snapshots taken before and after, and the current page state.
before may be nil (first op, no prior snapshot). after may be nil if the op failed before extraction. events is the slice from Observer.Drain().
type Observer ¶ added in v0.1.1
type Observer struct {
// contains filtered or unexported fields
}
Observer multiplexes CDP Network + Runtime + Page events into a unified channel.
func NewObserver ¶ added in v0.1.1
func NewObserver(page *rod.Page, opts ObserverOpts) *Observer
NewObserver creates an Observer for page. Call Start to begin listening.
func (*Observer) Drain ¶ added in v0.1.1
func (o *Observer) Drain(afterMs int64) []ObserverEvent
Drain returns all events whose TS >= afterMs without removing them.
func (*Observer) Events ¶ added in v0.1.1
func (o *Observer) Events() <-chan ObserverEvent
Events returns the read-only event channel.
func (*Observer) Start ¶ added in v0.1.1
Start enables CDP domains and begins listening. It must be called once.
func (*Observer) Stats ¶ added in v0.1.1
func (o *Observer) Stats() ObserverStats
Stats returns a snapshot of event counters.
func (*Observer) Stop ¶ added in v0.1.1
Stop cancels listening, waits for goroutines, and closes the channel. Idempotent.
func (*Observer) WriteNDJSON ¶ added in v0.1.1
WriteNDJSON streams events from the channel to w as NDJSON until ctx is done or the channel is closed. It flushes after every line if w implements http.Flusher or has a Flush() method.
type ObserverEvent ¶ added in v0.1.1
type ObserverEvent struct {
TS int64 `json:"ts"` // unix ms
Kind ObserverKind `json:"kind"`
Method string `json:"method,omitempty"`
URL string `json:"url,omitempty"`
Status int `json:"status,omitempty"`
MimeType string `json:"mime_type,omitempty"`
Type string `json:"type,omitempty"`
RequestID string `json:"request_id,omitempty"`
Body string `json:"body,omitempty"`
BodyBase64 bool `json:"body_base64,omitempty"`
BodyError string `json:"body_error,omitempty"`
Size int64 `json:"size,omitempty"`
DurationMs int64 `json:"duration_ms,omitempty"`
Failed string `json:"failed,omitempty"`
Level string `json:"level,omitempty"`
Text string `json:"text,omitempty"`
Source string `json:"source,omitempty"`
Event string `json:"event,omitempty"`
Frame string `json:"frame,omitempty"`
ReqHeaders map[string]string `json:"request_headers,omitempty"`
ResHeaders map[string]string `json:"response_headers,omitempty"`
PostData string `json:"post_data,omitempty"`
}
ObserverEvent is one emitted CDP event in a unified format.
type ObserverFilters ¶ added in v0.1.1
type ObserverFilters struct {
// NetTypes filters by network resource type (e.g. "xhr", "fetch", "document").
// Empty means accept all.
NetTypes []string
// NetURLRegex filters net events by URL. Nil means accept all.
NetURLRegex *regexp.Regexp
// ConsoleLevels filters console events (e.g. "error", "warning", "info").
// Empty means accept all.
ConsoleLevels []string
// Kinds limits event kinds emitted. Empty means accept all.
Kinds []ObserverKind
}
ObserverFilters selectively narrows which events are emitted.
type ObserverKind ¶ added in v0.1.1
type ObserverKind string
ObserverKind classifies an ObserverEvent.
const ( KindNet ObserverKind = "net" KindConsole ObserverKind = "console" KindError ObserverKind = "error" KindPage ObserverKind = "page" )
type ObserverOpts ¶ added in v0.1.1
type ObserverOpts struct {
Filters ObserverFilters
MaxEvents int // 0 = unlimited
Duration time.Duration // 0 = unlimited
BufferSize int // channel buffer; default 256
}
ObserverOpts configures an Observer.
type ObserverStats ¶ added in v0.1.1
type ObserverStats struct {
Net int
Console int
Error int
Page int
Total int
Dropped int // events discarded due to MaxEvents or channel full
}
ObserverStats holds counters for each kind.
type PageInfo ¶
type PageInfo struct {
URL string `json:"url"`
Title string `json:"title"`
Status int `json:"status"`
TimeMs int64 `json:"time_ms"`
}
PageInfo holds the result of a navigation.
type PageSnapshot ¶ added in v0.1.1
type PageSnapshot struct {
TargetID string `json:"target_id"`
URL string `json:"url,omitempty"`
Title string `json:"title,omitempty"`
Refs map[string]RefSnapshot `json:"refs,omitempty"`
// CachedExtraction is the last ExtractionResult for this page, persisted so
// subsequent commands can skip the expensive CDP AccessibilityGetFullAXTree
// call when the URL has not changed.
CachedExtraction *ExtractionResult `json:"cached_extraction,omitempty"`
}
PageSnapshot stores the last known interactive refs for a page target.
func BuildSnapshot ¶ added in v0.1.1
func BuildSnapshot(page *rod.Page, result *ExtractionResult) (*PageSnapshot, error)
BuildSnapshot creates an in-memory ref snapshot from an extraction result.
type PlaywrightLogState ¶ added in v0.4.1
type PlaywrightLogState struct {
Console []ObserverEvent `json:"console,omitempty"`
Network []CapturedEntry `json:"network,omitempty"`
}
PlaywrightLogState stores bounded command-observation buffers for Playwright CLI-compatible console/network inspection.
type PreviewResult ¶
type PreviewResult struct {
PageInfo *PageInfo `json:"page"`
Errors []ErrorEntry `json:"errors"`
Network []NetworkEntry `json:"network"`
DOM *ExtractionResult `json:"dom"`
Summary PreviewSummary `json:"summary"`
}
PreviewResult is the all-in-one dev report for a page.
type PreviewSummary ¶
type PreviewSummary struct {
TotalRequests int `json:"total_requests"`
FailedRequests int `json:"failed_requests"`
ErrorCount int `json:"error_count"`
WarningCount int `json:"warning_count"`
InteractiveCount int `json:"interactive_count"`
}
PreviewSummary provides quick stats.
type ProfileGCCandidate ¶ added in v0.4.1
type ProfileGCCandidate struct {
Name string `json:"name"`
Bytes int64 `json:"bytes"`
Modified time.Time `json:"modified"`
}
ProfileGCCandidate is an orphan profile eligible for reclamation.
func GCProfiles ¶ added in v0.4.1
func GCProfiles(ttl time.Duration, dryRun bool) ([]ProfileGCCandidate, error)
GCProfiles finds — and, unless dryRun, deletes — orphan profile directories that are safe to reclaim: never the implicit "default" daemon profile, never a profile backing a currently-live session, and only those idle for at least ttl (no file modified within the window). The idle gate protects persistent login profiles that are still in active rotation even when no session is up right now. Callers should surface the returned candidates before deleting (the CLI defaults to a dry run) so a login profile is never removed silently.
type ProfileInfo ¶ added in v0.4.1
type ProfileInfo struct {
Name string `json:"name"`
Path string `json:"path"`
Bytes int64 `json:"bytes"`
}
ProfileInfo describes a persistent Chrome profile on disk (~/.ghostchrome/profiles/<name>).
func ListProfiles ¶ added in v0.4.1
func ListProfiles() ([]ProfileInfo, error)
ListProfiles returns every persistent profile with its on-disk size.
type ProxyPool ¶ added in v0.4.1
type ProxyPool struct {
// contains filtered or unexported fields
}
ProxyPool hands out proxy URLs round-robin across sessions. Residential / mobile proxies are usually sold as a pool; rotating the egress IP is the #1 lever against IP-reputation anti-bot layers (DataDome & co.), which a single static --proxy cannot provide. Thread-safe.
func NewProxyPool ¶ added in v0.4.1
NewProxyPool builds a pool from already-parsed entries. A nil/empty list yields an empty pool whose Next() returns "".
type ReactComponent ¶ added in v0.1.1
type ReactComponent struct {
Name string `json:"name"`
Type string `json:"type"`
Key string `json:"key,omitempty"`
Props json.RawMessage `json:"props,omitempty"`
State json.RawMessage `json:"state,omitempty"`
Children []ReactComponent `json:"children,omitempty"`
}
ReactComponent represents a React component in the fiber tree.
type Recorder ¶ added in v0.1.1
type Recorder struct {
// contains filtered or unexported fields
}
Recorder injects a JS listener into the page, coalesces typing, and emits JSONL ops to w. It uses Runtime.addBinding so the JS → Go channel is clean (no console-log pollution).
Call Start() once then either Wait() (blocks until done) or Stop().
func NewRecorder ¶ added in v0.1.1
NewRecorder creates a recorder but does not start it.
func (*Recorder) Done ¶ added in v0.1.1
func (r *Recorder) Done() <-chan struct{}
Done returns a channel closed when the recorder stops.
type RecorderOp ¶ added in v0.1.1
RecorderOp is a single user-action op, ready to be written as JSONL. The schema matches the agentRequest format consumed by `ghostchrome agent`.
type RecorderOpts ¶ added in v0.1.1
RecorderOpts configures a Recorder session.
type RecoveryContext ¶ added in v0.1.1
type RecoveryContext struct {
// Page is the active Rod page.
Page *rod.Page
// Err is the error returned by the original op.
Err error
// OpName is the JSONL op name for logging (e.g. "click", "navigate").
OpName string
}
RecoveryContext carries the inputs available to a RecoveryHook.
type RecoveryHook ¶ added in v0.1.1
type RecoveryHook func(ctx RecoveryContext) (retry bool, err error)
RecoveryHook is a function that inspects the failure context and optionally performs a repair action.
Return values:
- retry=true: the hook resolved the issue; the caller should retry the op.
- retry=false, err=nil: the hook ran but did not fix anything; try next hook.
- retry=false, err=non-nil: the hook itself failed with a new error; abort.
func DefaultRecoveryHooks ¶ added in v0.1.1
func DefaultRecoveryHooks() []RecoveryHook
DefaultRecoveryHooks returns the standard set of hooks in priority order:
- RecoverDialogAccept — dialogs block everything
- RecoverBotChallenge — captcha/CF interstitial
- RecoverNetworkSettle — transient timeout
- RecoverStaleRef — stale ref is last (never silently remaps)
type RefSnapshot ¶ added in v0.1.1
type RefSnapshot struct {
BackendNodeID proto.DOMBackendNodeID `json:"backend_node_id"`
Role string `json:"role,omitempty"`
Name string `json:"name,omitempty"`
}
RefSnapshot stores a stable backend node mapping for a single ref.
type RenderProfile ¶ added in v0.1.1
type RenderProfile struct {
// Agent is true when the output is being consumed by an LLM agent runner
// (Claude Code, Cursor, Aider, etc.) rather than a human terminal.
Agent bool
// Format is "text" or "json".
Format string
// MaxLabelLen truncates node names / values to this length in agent mode.
// 0 means no truncation.
MaxLabelLen int
// AbbrevRoles uses 1-2 character role abbreviations (b/a/t/c/s/r/m/x/h).
AbbrevRoles bool
// DropEmptyStats omits "[errors] 0 ..." / "[network] ... 0 failed" headers
// when counts are zero.
DropEmptyStats bool
// ContentBoundary wraps page-derived text (node names / values) with sentinel
// markers so an LLM consuming the snapshot can distinguish tool output from
// untrusted page content (prompt-injection defense). Default false = opt-in only.
// Markers used: ⟦page⟧ … ⟦/page⟧
ContentBoundary bool
}
RenderProfile controls how output is rendered for the calling environment. It is resolved once per CLI invocation (see ResolveProfile) and then threaded into formatters.
func ProfileAgent ¶ added in v0.1.1
func ProfileAgent(format string) RenderProfile
ProfileAgent returns the compact agent-optimised profile.
func ProfileHuman ¶ added in v0.1.1
func ProfileHuman(format string) RenderProfile
ProfileHuman returns the default human-friendly profile.
func ResolveProfile ¶ added in v0.1.1
func ResolveProfile(explicit, format string) RenderProfile
ResolveProfile picks a RenderProfile from an explicit flag ("auto", "human", "agent") with environment-variable fallback for "auto".
type RuleMatchType ¶ added in v0.1.1
type RuleMatchType string
RuleMatchType controls how the match field is interpreted.
const ( RuleMatchGlob RuleMatchType = "glob" RuleMatchRegex RuleMatchType = "regex" RuleMatchExact RuleMatchType = "exact" )
type RuleSpec ¶ added in v0.1.1
type RuleSpec struct {
Match string `json:"match"`
MatchType RuleMatchType `json:"matchType"`
Method string `json:"method"`
Status int `json:"status"`
ContentType string `json:"contentType"`
Headers map[string]string `json:"headers"`
Body string `json:"body"`
BodyFile string `json:"bodyFile"`
}
RuleSpec is the JSON schema for one entry in the rules file.
type RulesFile ¶ added in v0.1.1
type RulesFile struct {
Rules []RuleSpec `json:"rules"`
}
RulesFile is the top-level JSON structure.
type SSRPayload ¶ added in v0.1.1
type SSRPayload struct {
Source SSRSource `json:"source"`
Data json.RawMessage `json:"data"`
IsJSON bool `json:"is_json"`
// Type is set for JSON-LD payloads to surface schema.org @type
// without forcing the caller to re-parse.
Type string `json:"type,omitempty"`
}
SSRPayload is one structured data island found in HTML. Data is the raw payload as it appeared in the page — JSON for the *Data sources and JSON-LD, plain JS expression for *State / Nuxt 2. IsJSON tells the caller whether they can json.Unmarshal it directly.
func ExtractRSCPayloads ¶ added in v0.1.1
func ExtractRSCPayloads(html string) []SSRPayload
ExtractRSCPayloads decodes Next.js App Router RSC chunks and returns one SSRPayload per logical entry (`<id>:<value>`). Values that parse as JSON (object, array, string) are surfaced with IsJSON=true; module refs and element trees are returned as raw strings (callers that care can run them through V8 — but the JSON ones cover most data needs).
Stream format reference:
0:["$","html",null,{...}] RSC element tree
1:I[123,[...],"Comp"] module / chunk reference
2:[...listings JSON...] plain JSON data island
3:T82a,Lorem ipsum… text token
We keep all of them; downstream extractors filter by id or by "starts with `[` / `{`" depending on what they need.
func ExtractSSRPayloads ¶ added in v0.1.1
func ExtractSSRPayloads(html string) []SSRPayload
ExtractSSRPayloads finds every supported SSR data island in the HTML and returns them in order of appearance. Sites that ship multiple frameworks (e.g. Next + Apollo, or several JSON-LD blocks) get one entry per island.
Always-safe: returns nil on absence rather than an error. Callers decide what to do with the empty list (often: fall back to Chrome).
type SSRSource ¶ added in v0.1.1
type SSRSource string
SSRSource classifies the origin of an SSR data payload found in a page's HTML. Different frameworks expose their state in different shapes; we surface the source so downstream tooling can pick a parser per format.
const ( SourceNextData SSRSource = "next" // <script id="__NEXT_DATA__" type="application/json"> SourceNuxtData SSRSource = "nuxt" // <script id="__NUXT_DATA__" type="application/json"> (Nuxt 3) SourceNuxtJS SSRSource = "nuxt-js" // window.__NUXT__=... (Nuxt 2; raw JS, not JSON) SourceApolloState SSRSource = "apollo" // window.__APOLLO_STATE__=... SourceInitialState SSRSource = "initial-state" // window.__INITIAL_STATE__=... SourcePreloaded SSRSource = "preloaded" // window.__PRELOADED_STATE__=... SourceReduxState SSRSource = "redux" // window.__REDUX_STATE__=... SourceJSONLD SSRSource = "jsonld" // <script type="application/ld+json"> SourceRSC SSRSource = "rsc" // self.__next_f.push([1, "<chunks>"]) (Next.js App Router) )
type ScreenRecorder ¶ added in v0.4.1
type ScreenRecorder struct {
// contains filtered or unexported fields
}
func NewScreenRecorder ¶ added in v0.4.1
func NewScreenRecorder(page *rod.Page, opts ScreenRecorderOpts) *ScreenRecorder
func (*ScreenRecorder) FrameCount ¶ added in v0.4.1
func (r *ScreenRecorder) FrameCount() int64
func (*ScreenRecorder) OutputDir ¶ added in v0.4.1
func (r *ScreenRecorder) OutputDir() string
func (*ScreenRecorder) Start ¶ added in v0.4.1
func (r *ScreenRecorder) Start() error
func (*ScreenRecorder) Stop ¶ added in v0.4.1
func (r *ScreenRecorder) Stop() int64
type ScreenRecorderOpts ¶ added in v0.4.1
type SessionEntry ¶ added in v0.1.1
type SessionEntry struct {
Name string `json:"name"`
Port int `json:"port"`
PID int `json:"pid"`
WSURL string `json:"ws_url"`
Profile string `json:"profile"`
LaunchedAt string `json:"launched_at"`
}
SessionEntry is one named, auto-managed Chrome in the session registry. A session is a long-lived `serve` process bound to a disk profile of the same name (so cookies persist), reused across CLI invocations.
func AttachSession ¶ added in v0.4.1
func AttachSession(name string, wsURL string) (SessionEntry, error)
AttachSession registers an existing CDP endpoint as a named session. It does not spawn or own the browser process; StopSession removes the registry entry but will not terminate an external browser because PID/Port are zero.
type SessionRegistryEntry ¶ added in v0.1.1
type SessionRegistryEntry struct {
Name string `json:"name"`
Port int `json:"port"`
PID int `json:"pid"`
WSURL string `json:"ws_url"`
Profile string `json:"profile"`
LaunchedAt string `json:"launched_at,omitempty"`
Alive bool `json:"alive"`
}
SessionRegistryEntry is the public-facing representation used by the CLI.
func ListSessions ¶ added in v0.1.1
func ListSessions() ([]SessionRegistryEntry, error)
ListSessions returns every registry entry annotated with current liveness.
func ResolveSession ¶ added in v0.4.1
func ResolveSession(name string) (SessionRegistryEntry, error)
ResolveSession returns the live browser WebSocket URL for an existing registered session. It never spawns a new browser.
func (SessionRegistryEntry) AliveStr ¶ added in v0.1.1
func (e SessionRegistryEntry) AliveStr() string
AliveStr returns "yes" or "no".
type SessionSpawnOpts ¶ added in v0.1.1
type SessionSpawnOpts struct {
Headless bool
Stealth bool
Proxy string
ProxyBypass string
ExecutablePath string
ConfigPath string
}
SessionSpawnOpts carries the global flags propagated to a spawned serve.
type SiteResult ¶ added in v0.1.1
type SiteResult struct {
URL string `json:"url"`
Items []CollectedItem `json:"items"`
Count int `json:"count"`
TimeMs int64 `json:"time_ms"`
Error string `json:"error,omitempty"`
}
SiteResult holds the collect result for a single URL in a multi-collect.
type SnapshotDiff ¶ added in v0.1.1
type SnapshotDiff struct {
Unchanged bool `json:"unchanged,omitempty"`
Added []DiffNode `json:"added,omitempty"`
Removed []string `json:"removed,omitempty"`
Changed map[string]DiffEntry `json:"changed,omitempty"`
Stats DiffStats `json:"stats"`
}
SnapshotDiff reports the changes between two ref maps of a page. All fields are optional in JSON output so an unchanged page serialises to `{"unchanged":true}`.
func DiffRefs ¶ added in v0.1.1
func DiffRefs(prev, curr map[string]RefSnapshot) SnapshotDiff
DiffRefs compares two ref maps (typically the persisted PageSnapshot.Refs). Refs are reassigned in document order by the extractor, so a key match indicates the same logical node slot. A role or name change on the same key counts as "changed"; disappearing or new keys count as removed/added.
type StorageCookie ¶ added in v0.1.1
type StorageCookie struct {
Name string `json:"name"`
Value string `json:"value"`
Domain string `json:"domain"`
Path string `json:"path"`
Expires float64 `json:"expires,omitempty"`
HTTPOnly bool `json:"httpOnly,omitempty"`
Secure bool `json:"secure,omitempty"`
SameSite string `json:"sameSite,omitempty"`
}
StorageCookie uses the Playwright-compatible field names (sameSite as string, expires as float64 seconds-since-epoch).
type StorageKeyValue ¶ added in v0.1.1
StorageKeyValue is a single localStorage entry.
type StorageOrigin ¶ added in v0.1.1
type StorageOrigin struct {
Origin string `json:"origin"`
LocalStorage []StorageKeyValue `json:"localStorage"`
}
StorageOrigin groups localStorage entries by origin. sessionStorage is NOT persisted: it's per-tab and generally not replayable.
type StorageState ¶ added in v0.1.1
type StorageState struct {
Cookies []StorageCookie `json:"cookies"`
Origins []StorageOrigin `json:"origins"`
}
StorageState mirrors the Playwright storageState JSON shape so a state file produced by ghostchrome can be loaded by Playwright (and vice versa, within reasonable limits).
func SaveStorageState ¶ added in v0.1.1
SaveStorageState captures cookies (browser-wide) and localStorage for the origin of the current page. Callers can concatenate multiple SaveStorageState runs if they need multiple origins.
type TabInfo ¶
type TabInfo struct {
Index int `json:"index"`
URL string `json:"url"`
Title string `json:"title"`
TargetID string `json:"target_id,omitempty"`
Active bool `json:"active,omitempty"`
}
TabInfo holds metadata about a browser tab.
type TraceEntry ¶ added in v0.1.1
type TraceEntry struct {
TS int64 `json:"ts"`
Op string `json:"op"`
Args map[string]any `json:"args,omitempty"`
OK bool `json:"ok"`
DurationMs int64 `json:"duration_ms"`
Summary string `json:"summary,omitempty"`
Error string `json:"error,omitempty"`
Shot string `json:"shot,omitempty"`
}
TraceEntry is one line of a ghostchrome MCP session trace (JSONL).
type VideoChapter ¶ added in v0.4.1
type VideoChapter struct {
Title string `json:"title"`
Description string `json:"description,omitempty"`
DurationMs int `json:"duration_ms,omitempty"`
AtMs int64 `json:"at_ms"`
CreatedAt string `json:"created_at"`
}
VideoChapter is one requested video chapter marker.
type VideoState ¶ added in v0.4.1
type VideoState struct {
Active bool `json:"active,omitempty"`
StartedAt string `json:"started_at,omitempty"`
Filename string `json:"filename,omitempty"`
Size string `json:"size,omitempty"`
Auto bool `json:"auto,omitempty"`
Source string `json:"source,omitempty"`
Chapters []VideoChapter `json:"chapters,omitempty"`
}
VideoState tracks Playwright CLI-compatible video command metadata. A true WebM recorder is not implemented yet; commands use this to persist chapter markers and requested output metadata.
Source Files
¶
- annotate.go
- antibot_blocker.go
- browser.go
- capture.go
- clipboard.go
- collector.go
- context_registry.go
- cookies.go
- cookies_decrypt.go
- cookies_inject.go
- discover.go
- drag.go
- emulate.go
- errors.go
- evasion.go
- extractor.go
- extractor_domfallback.go
- fastfetch.go
- fetchapi.go
- format.go
- har.go
- httpclient.go
- human.go
- imagediff.go
- initscript.go
- interactor.go
- intercept.go
- intercept_rules.go
- locator.go
- locator_wait.go
- mouse.go
- navigator.go
- network_tracker.go
- observation.go
- observer.go
- page_profile.go
- permissions.go
- preview.go
- prewarm.go
- profile.go
- profiles.go
- proxy_auth.go
- proxypool.go
- react.go
- recorder.go
- recovery.go
- rsc_extract.go
- screenrecord.go
- service_workers.go
- session_registry.go
- session_spawn_unix.go
- session_state.go
- snapshot_diff.go
- ssr_extract.go
- stealth.go
- storage.go
- trace.go
- wait.go
Directories
¶
| Path | Synopsis |
|---|---|
|
Package ai implements an autonomous LLM-driven browser agent that drives the existing ghostchrome agent ops.
|
Package ai implements an autonomous LLM-driven browser agent that drives the existing ghostchrome agent ops. |
|
Package dashboard provides a live browser viewport stream over WebSocket.
|
Package dashboard provides a live browser viewport stream over WebSocket. |
|
Package mcp exposes ghostchrome as a Model Context Protocol server so that LLM agents (Claude Code, Codex, Cursor, ...) can drive the browser via stdio JSON-RPC instead of forking the CLI per call.
|
Package mcp exposes ghostchrome as a Model Context Protocol server so that LLM agents (Claude Code, Codex, Cursor, ...) can drive the browser via stdio JSON-RPC instead of forking the CLI per call. |
|
Package provider defines the interface for connecting to a Chrome instance.
|
Package provider defines the interface for connecting to a Chrome instance. |
|
Package sites provides generic, site-agnostic discovery and replay helpers.
|
Package sites provides generic, site-agnostic discovery and replay helpers. |