backend

package
v0.5.3 Latest Latest
Warning

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

Go to latest
Published: Jul 17, 2026 License: MIT Imports: 24 Imported by: 0

Documentation

Overview

Package backend obtains a reachable local CDP/VNC endpoint for a browser that runs in one of four places: a local docker container, a Kubernetes Deployment, docker on an ssh host, or a pre-exposed direct URL. Every CDP/VNC-facing operation runs against the Endpoint a backend yields, so the rest of cuttle is transport-agnostic.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type Backend

type Backend interface {
	State(ctx context.Context) (State, error)
	Start(ctx context.Context, opts StartOpts) error
	Stop(ctx context.Context, purge bool) error
	// Reach yields a local endpoint plus a release func that tears down any
	// tunnel opened to reach it. release is always safe to call (no-op for
	// direct/local). cdpPort/vncPort request specific local ports for a tunneled
	// backend (k8s/ssh) so a held forward is deterministic and `cuttle mcp` can
	// point a driver at it; 0 auto-picks a free port (used by the ephemeral
	// status/login/up forwards, which never collide with a local container).
	// local/direct ignore the requested ports and return their fixed endpoint.
	Reach(ctx context.Context, cdpPort, vncPort int) (Endpoint, func(), error)
}

Backend manages one browser's lifecycle and reachability.

func New

func New(name string, ctx config.Context, r Runner, cdpPort, vncPort int, image string) (Backend, error)

New builds the backend for a resolved context. Ports are the host-side CDP/VNC ports for the local backend (and the remote container ports for ssh).

type Direct

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

Direct targets a pre-exposed CDP/VNC endpoint from config as-is. It is the escape hatch for any browser cuttle does not itself manage (e.g. reached over a tailnet), so Start/Stop are errors.

func (*Direct) Reach

func (d *Direct) Reach(context.Context, int, int) (Endpoint, func(), error)

Reach uses the configured URLs as-is; there is no tunnel to release.

func (*Direct) Start

func (d *Direct) Start(context.Context, StartOpts) error

func (*Direct) State

func (d *Direct) State(ctx context.Context) (State, error)

func (*Direct) Stop

func (d *Direct) Stop(context.Context, bool) error

type Endpoint

type Endpoint struct {
	CDPHost string
	CDPPort int
	VNCHost string
	VNCPort int // 0 = no VNC
}

Endpoint is a reachable CDP (and optional VNC) address. For tunneled backends the host is loopback and the ports are auto-picked local forwards; for direct it is the configured host/port as-is.

type ExecRunner

type ExecRunner struct{}

ExecRunner is the production Runner backed by os/exec.

func (ExecRunner) LookPath

func (ExecRunner) LookPath(name string) (string, error)

func (ExecRunner) Output

func (ExecRunner) Output(ctx context.Context, name string, args ...string) (Result, error)

func (ExecRunner) Start

func (ExecRunner) Start(ctx context.Context, name string, args ...string) (Process, error)

type K8s

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

K8s runs the browser as a Helm-managed Deployment in a cluster, reached via kubectl port-forward. It shells out to kubectl/helm and inherits the user's kube context (and thus their routing) with zero cuttle-specific setup.

func (*K8s) Reach

func (k *K8s) Reach(ctx context.Context, cdpPort, vncPort int) (Endpoint, func(), error)

Reach opens a kubectl port-forward. cdpPort/vncPort pin the local ports (so a held `cuttle connect` forward is deterministic and mcp can target it); 0 auto-picks free ports for the ephemeral status/login forwards, which then never collide with a local container already on 9222.

func (*K8s) Start

func (k *K8s) Start(ctx context.Context, opts StartOpts) error

func (*K8s) State

func (k *K8s) State(ctx context.Context) (State, error)

func (*K8s) Stop

func (k *K8s) Stop(ctx context.Context, purge bool) error

type Local

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

Local runs the browser in a docker container on this host. It is a faithful port of the Python cuttle CLI's docker lifecycle, so existing behavior does not regress when no config file is present.

func (*Local) Diagnostics

func (l *Local) Diagnostics(ctx context.Context) []string

Diagnostics returns human-readable triage lines for an unhealthy container: the real host<-container port bindings and a log tail, so triage never needs a raw docker command. It is used by `status` via an optional interface.

func (*Local) Image

func (l *Local) Image(ctx context.Context) string

Image reports the image an existing container was created with, or "".

func (*Local) Reach

func (l *Local) Reach(_ context.Context, _, _ int) (Endpoint, func(), error)

Reach for local is a direct loopback endpoint on the host-mapped ports; no tunnel, so release is a no-op.

func (*Local) Start

func (l *Local) Start(ctx context.Context, opts StartOpts) error

Start ensures the container is up, idempotently. A stopped container is restarted (profile preserved); a zombie (a run that died before a clean exit) is removed and re-run; --recreate forces a fresh container.

func (*Local) State

func (l *Local) State(ctx context.Context) (State, error)

func (*Local) Stop

func (l *Local) Stop(ctx context.Context, purge bool) error

type Native added in v0.5.3

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

Native runs the browser as a local `cuttle serve` daemon on this macOS host - no Docker, no Xvfb, no VNC. It runs clark's native darwin-arm64 stealth Chromium directly, so the browser opens as a real desktop window (surfaced for handoff via `cuttle view`) and pays no Rosetta emulation tax. The persona is macOS (see fingerprint.ForkParityArgs): on Apple Silicon the real Metal GPU is unspoofable, so a genuine Mac is the only coherent identity.

Unlike the docker/ssh backends, the daemon must OUTLIVE the CLI invocation that starts it, so Native spawns a detached process (new session) and tracks it by pidfile rather than going through the Runner seam.

func (*Native) Diagnostics added in v0.5.3

func (n *Native) Diagnostics(_ context.Context) []string

Diagnostics tails the serve log for `cuttle status` triage, mirroring the docker backend's log tail.

func (*Native) RaiseWindow added in v0.5.3

func (n *Native) RaiseWindow(ctx context.Context, seed string) (bool, error)

RaiseWindow surfaces the seed's real Chrome window on the desktop for handoff (captcha, Cloudflare, login) - the native-backend replacement for the VNC viewer. It returns raised=true when it brought the exact seed window to the foreground; raised=false (with a nil error) means it fell back to activating the app because the precise raise needs macOS Automation permission that has not been granted. The window surfaces either way.

func (*Native) Reach added in v0.5.3

func (n *Native) Reach(_ context.Context, _, _ int) (Endpoint, func(), error)

Reach is a direct loopback CDP endpoint; the native backend has no VNC (the browser is a real desktop window), so VNCPort is 0 and release is a no-op.

func (*Native) Start added in v0.5.3

func (n *Native) Start(ctx context.Context, opts StartOpts) error

func (*Native) State added in v0.5.3

func (n *Native) State(_ context.Context) (State, error)

func (*Native) Stop added in v0.5.3

func (n *Native) Stop(_ context.Context, purge bool) error

type Process

type Process interface {
	Stop() error
}

Process is a running command that can be stopped.

type Result

type Result struct {
	Stdout string
	Stderr string
	Code   int
}

Result is a finished command's captured output and exit code.

type Runner

type Runner interface {
	// Output runs a command to completion and captures its output. A non-zero
	// exit is reported in Result.Code with a nil error (mirroring the Python
	// check=False); a nil error means only that the command ran.
	Output(ctx context.Context, name string, args ...string) (Result, error)
	// Start launches a long-running command (a tunnel) and returns a handle to
	// stop it.
	Start(ctx context.Context, name string, args ...string) (Process, error)
	// LookPath reports the resolved path of an executable, or an error if absent.
	LookPath(name string) (string, error)
}

Runner is the exec seam every backend goes through, so command construction is unit-testable without docker/kubectl/ssh installed.

type SSH

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

SSH runs the browser in docker on a remote host reached over ssh, tunneled to this machine with ssh -L. It inherits ~/.ssh/config (keys, jump hosts, and any routing the user provides), so cuttle needs no ssh setup of its own.

func (*SSH) Reach

func (s *SSH) Reach(ctx context.Context, cdpPort, vncPort int) (Endpoint, func(), error)

Reach opens an ssh -L tunnel from local ports to the remote container's published ports, establishing the ControlMaster the other calls reuse. cdpPort/vncPort pin the local ports (so a held `cuttle connect` forward is deterministic and mcp can target it); 0 auto-picks free ports for the ephemeral status/login forwards.

func (*SSH) Start

func (s *SSH) Start(ctx context.Context, opts StartOpts) error

func (*SSH) State

func (s *SSH) State(ctx context.Context) (State, error)

func (*SSH) Stop

func (s *SSH) Stop(ctx context.Context, purge bool) error

type StartOpts

type StartOpts struct {
	Image       string
	Recreate    bool
	KeepProfile *bool // nil = backend default (on)
	NoVNC       bool
	Proxy       string
	IdleTimeout string // local only
	Storage     string // profile storage: "local" | "remote"
}

StartOpts carries the per-invocation choices for Start. Not every field applies to every backend (e.g. IdleTimeout is local-only, Recreate is docker- only); a backend ignores what it does not use.

type State

type State string

State is a browser's lifecycle state as a backend sees it.

const (
	StateRunning State = "running"
	StateStopped State = "stopped"
	StateAbsent  State = "absent"
)

Jump to

Keyboard shortcuts

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