Help us shape the future of Go! Take the 2026 Go Developer Survey

cdp

package
v0.2.9 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Aug 16, 2026 License: Apache-2.0 Imports: 15 Imported by: 0

Documentation

Overview

Package cdp is a minimal Chrome DevTools Protocol client used by rysh's headless web mode: it launches a Chromium with --remote-debugging-port, attaches over the browser-level WebSocket (flat session mode), and executes browser_action requests (see actions.go) without needing the desktop app.

Deliberately dependency-free beyond gorilla/websocket (already a rysh-cli dependency): rysh needs a dozen CDP methods, not a full protocol binding.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func FindChromium

func FindChromium() string

FindChromium locates a Chromium/Chrome binary: RYSH_CHROMIUM_PATH first, then PATH candidates, then platform install locations. Returns "" when nothing is found.

func LaunchInteractive

func LaunchInteractive(userDataDir, url string) (int, error)

LaunchInteractive starts a HEADED Chromium on the profile directory without attaching CDP — the interactive-login helper (`##web headless login`). The process is detached; the user logs in and closes the window, and the auth lands in the profile dir for subsequent headless runs.

func SweepOrphanedHeadless

func SweepOrphanedHeadless(browserRoot string) []int

SweepOrphanedHeadless scans a browser-instances root (…/.rysh/browser-instances) for headless pidfiles (<root>/<profile>/headless/headless-chromium.pid) and kills any Chromium that outlived its daemon. Returns the PIDs that were killed. Best-effort: unreadable entries are skipped, stale pidfiles are always removed.

Types

type Browser

type Browser struct {
	// contains filtered or unexported fields
}

Browser is a live CDP connection to a launched Chromium plus the process handle. Goroutine-safe: Call serializes writes and correlates responses by id, so the headless actor can execute actions from worker goroutines.

func Launch

func Launch(ctx context.Context, o LaunchOptions) (*Browser, error)

Launch starts Chromium and connects to its DevTools WebSocket. The caller owns the returned Browser and must Close it (which kills the process).

func (*Browser) AllCookies

func (b *Browser) AllCookies() ([]Cookie, error)

AllCookies returns every cookie in the browser's default context via Storage.getCookies. Unlike document.cookie this includes httpOnly cookies — which is exactly the set that matters for a Google login (SID, SAPISID, __Secure-1PSID, …). Sent at the browser level (no attached tab needed).

func (*Browser) Close

func (b *Browser) Close()

Close shuts the browser down: graceful Browser.close, then a hard kill after a short grace period. The headless pidfile is removed so the orphan sweep never chases a browser that exited cleanly.

func (*Browser) CurrentTargetID

func (b *Browser) CurrentTargetID() string

CurrentTargetID returns the attached tab's target id.

func (*Browser) Do

func (b *Browser) Do(action string, rawParams json.RawMessage) (json.RawMessage, string, error)

Do executes one browser_action request against the browser and returns the action result (JSON for the model), an optional base64 PNG screenshot, and an error. The action names, param shapes, and selector formats match the browser_action tool spec (rysh-shared/tools/browser_action.go) exactly, so the headless executor is a drop-in peer of the desktop app / extension.

func (*Browser) Page

func (b *Browser) Page(method string, params any) (json.RawMessage, error)

Page calls a CDP method on the current tab's session.

type Cookie struct {
	Name     string  `json:"name"`
	Value    string  `json:"value"`
	Domain   string  `json:"domain"`
	Path     string  `json:"path"`
	Expires  float64 `json:"expires"` // unix seconds; <=0 means a session cookie
	HTTPOnly bool    `json:"httpOnly"`
	Secure   bool    `json:"secure"`
	SameSite string  `json:"sameSite"` // "Strict" | "Lax" | "None" | "" (unspecified)
}

Cookie is the subset of CDP's Network.Cookie that we transfer into the desktop app's Electron session partition. Field names/tags mirror the CDP response so they unmarshal directly from Storage.getCookies; the JSON tags are also what we send over the message bus to the app.

func ExtractCookies

func ExtractCookies(ctx context.Context, userDataDir string) ([]Cookie, error)

ExtractCookies launches a headless Chromium on an existing profile directory and reads its cookie jar. The dir must already hold a logged-in session (populated by `##web headless login <profile> <url>` in real Chrome). We only read here — no navigation, no sign-in — so automation detection is irrelevant.

Fails clearly if the profile dir is missing (never logged in) or still locked by an open login window / live headless browser.

func GoogleIdentityCookies

func GoogleIdentityCookies(all []Cookie) []Cookie

GoogleIdentityCookies keeps only the cookies that belong to Google's identity domains — the ones a third-party "Sign in with Google" flow consults. Dropping everything else keeps the transfer tight and avoids importing unrelated jars.

type LaunchOptions

type LaunchOptions struct {
	BinPath     string // Chromium binary ("" → FindChromium)
	UserDataDir string // profile directory (required — this is where auth persists)
	Headless    bool   // --headless=new when true; headed for interactive login
	URL         string // initial URL ("" → about:blank)
	// WaitTimeout bounds the wait for Chromium's "DevTools listening on"
	// line (0 → 20s). Cold starts on loaded machines — CI runners under
	// -race, several browsers launching at once — can exceed the default;
	// callers that can afford to wait longer pass a larger bound. The
	// caller's ctx still cancels earlier if it expires first.
	WaitTimeout time.Duration
}

LaunchOptions configures a browser launch.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL