browserskill

package
v0.9.0 Latest Latest
Warning

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

Go to latest
Published: Oct 29, 2026 License: Apache-2.0, MIT Imports: 26 Imported by: 0

Documentation

Overview

Package browserskill connects authenticated users to an unmodified BrowserSkill daemon. Browser operations, tab consent and command scheduling remain upstream.

Index

Constants

View Source
const (
	// HumanStepWait matches BrowserSkill's default help window.
	HumanStepWait = 5 * time.Minute
	// HumanStepTimeout leaves time for the native result before cancellation.
	HumanStepTimeout = HumanStepWait + 15*time.Second
)
View Source
const (
	AuthProtocol = "bsk-auth."
)

AuthProtocol identifies the credential-bearing WebSocket subprotocol.

Variables

View Source
var ErrAuthorization = errors.New("browser authorization is invalid or expired")

ErrAuthorization indicates an invalid, expired or revoked browser grant.

View Source
var ErrLeaseHeld = errors.New("browser connection is owned by another node; reconnect shortly")

ErrLeaseHeld indicates that another replica still owns the device connection.

Functions

func IsHumanStep

func IsHumanStep(method string) bool

IsHumanStep identifies browser operations that can wait for user input.

func NavigationIncomplete(method string, raw json.RawMessage) bool

NavigationIncomplete checks the known lifecycle result, never arbitrary page text.

Types

type AccountStatus

type AccountStatus struct {
	ExtensionAvailable bool `json:"extension_available"`
	Status
	Device *DeviceRecord `json:"device,omitempty"`
}

AccountStatus combines durable device metadata with live connection status.

type DeviceRecord

type DeviceRecord struct {
	ScopeKey      string     `gorm:"primaryKey;size:32"  json:"-"`
	ID            string     `gorm:"uniqueIndex;size:32" json:"id"`
	Tenant        uint64     `                           json:"-"`
	User          string     `gorm:"size:36"             json:"-"`
	Label         string     `gorm:"size:100"            json:"label"`
	TokenHash     string     `gorm:"uniqueIndex;size:64" json:"-"`
	PreviousHash  string     `gorm:"size:64"             json:"-"`
	PreviousUntil time.Time  `                           json:"-"`
	ExpiresAt     time.Time  `                           json:"expires_at"`
	RenewAfter    time.Time  `                           json:"renew_after"`
	CreatedAt     time.Time  `                           json:"created_at"`
	LastSeenAt    time.Time  `                           json:"last_seen_at"`
	RevokedAt     *time.Time `                           json:"revoked_at,omitempty"`
	Owner         string     `gorm:"size:32"             json:"-"`
	LeaseKey      string     `gorm:"size:32"             json:"-"`
	OwnerURL      string     `gorm:"size:500"            json:"-"`
	LeaseUntil    time.Time  `                           json:"-"`
}

DeviceRecord stores authorization metadata and SHA-256 token hashes, never secrets. One registered device per tenant/user remains the current product contract.

func (DeviceRecord) TableName

func (DeviceRecord) TableName() string

TableName selects the durable browser device table.

type Manager

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

Manager owns transient browser connections; authorization and interruption markers are durable. Other replicas route commands to the lease owner.

func NewManager

func NewManager(stores ...*Store) *Manager

NewManager configures the gateway from environment variables and a durable store.

func (*Manager) Account

func (m *Manager) Account(ctx context.Context, s Scope) (AccountStatus, error)

Account reads the member's device authorization independently of a conversation.

func (*Manager) AuthorizeHTTP

func (m *Manager) AuthorizeHTTP(w http.ResponseWriter, r *http.Request)

AuthorizeHTTP is extension-only, independent of browser cookies. Device tokens stay in extension-origin storage; only hashes are committed to the DB.

func (*Manager) Call

func (m *Manager) Call(
	ctx context.Context,
	s Scope,
	session, method string,
	params map[string]any,
) (json.RawMessage, error)

Call serializes authorized automation commands within a conversation task.

func (*Manager) Close

func (m *Manager) Close()

Close disconnects all users and stops the single process owned by this manager.

func (*Manager) Control

func (m *Manager) Control(ctx context.Context, s Scope, session, action string) error

Control selects, starts, pauses, resumes or ends a conversation task.

func (*Manager) DownloadExtension

func (m *Manager) DownloadExtension(w http.ResponseWriter, r *http.Request)

DownloadExtension serves the configured extension archive to an authenticated user.

func (*Manager) Enabled

func (m *Manager) Enabled() bool

Enabled reports whether the browser integration has been configured.

func (*Manager) FinishTurn

func (m *Manager) FinishTurn(ctx context.Context, s Scope, session string, keepOpen bool) error

FinishTurn retains the official session for unfinished work, or stops a completed task through native RPC. Idle is only a host-side preview/turn marker: retaining a session does not detach its debugger or clear its refs.

func (*Manager) Focus

func (m *Manager) Focus(ctx context.Context, s Scope, session string) error

Focus is user initiated. Only the server-owned task ID is sent to Chrome.

func (*Manager) Forget

func (m *Manager) Forget(s Scope, sessions []string)

Forget stops and removes the specified deleted conversations' browser tasks.

func (*Manager) ForgetAll

func (m *Manager) ForgetAll(s Scope)

ForgetAll prevents further agent calls when all of a member's conversations are deleted. BrowserSkill performs the actual tab-return/Agent Window cleanup.

func (*Manager) GetStatus

func (m *Manager) GetStatus(ctx context.Context, s Scope, session string) (Status, error)

GetStatus resolves task status from the connection owner and interruption store.

func (*Manager) InternalHTTP

func (m *Manager) InternalHTTP(w http.ResponseWriter, r *http.Request)

InternalHTTP accepts authenticated, replay-protected requests for this node's connections.

func (*Manager) Pair

func (m *Manager) Pair(ctx context.Context, s Scope, origin string) (string, error)

Pair issues a five-minute, single-use activation link. Existing device authorization is replaced only when the extension redeems it successfully.

func (*Manager) Preview

func (m *Manager) Preview(ctx context.Context, s Scope, session string) (json.RawMessage, error)

Preview is read-only and remains available while the user has paused actions.

func (*Manager) Revoke

func (m *Manager) Revoke(ctx context.Context, s Scope) error

Revoke invalidates the member's durable grant and closes its local connection.

func (*Manager) ServeHTTP

func (m *Manager) ServeHTTP(w http.ResponseWriter, r *http.Request)

ServeHTTP authenticates each extension before dialing the shared daemon. Only the handshake identity is rewritten; browser execution stays upstream.

func (*Manager) Status

func (m *Manager) Status(s Scope, session string) Status

Status reads this node's transient task state without creating a task.

func (*Manager) ValidateConfiguration

func (m *Manager) ValidateConfiguration() error

ValidateConfiguration checks storage, transport and replica routing requirements.

type PairingRecord

type PairingRecord struct {
	ScopeKey  string `gorm:"primaryKey;size:32"`
	TokenHash string `gorm:"uniqueIndex;size:64"`
	Tenant    uint64
	User      string `gorm:"size:36"`
	ExpiresAt time.Time
}

PairingRecord stores a short-lived, single-use pairing token hash.

func (PairingRecord) TableName

func (PairingRecord) TableName() string

TableName selects the one-use browser pairing table.

type RPCError

type RPCError struct {
	Code    string          `json:"code"`
	Message string          `json:"message"`
	Data    json.RawMessage `json:"data,omitempty"`
}

RPCError preserves the daemon's error classification across local and cluster transports. Error keeps the legacy string contract for older peers and callers.

func (*RPCError) BoundDetails

func (e *RPCError) BoundDetails()

BoundDetails keeps useful recovery evidence without forwarding an unbounded page-controlled payload into model context. Oversized details retain only the protocol's recovery discriminators.

func (*RPCError) Error

func (e *RPCError) Error() string

type Scope

type Scope struct {
	Tenant uint64
	User   string
}

Scope isolates browser ownership by tenant and user.

type Status

type Status struct {
	Action           string `json:"action,omitempty"`
	ActionElapsedMS  int64  `json:"action_elapsed_ms"`
	PageURL          string `json:"page_url,omitempty"`
	LastError        string `json:"last_error,omitempty"`
	Stopping         bool   `json:"stopping"`
	HelpPrompt       string `json:"help_prompt,omitempty"`
	Idle             bool   `json:"idle"` // Between turns; does not imply debugger release.
	NeedsHelp        bool   `json:"needs_help"`
	Enabled          bool   `json:"enabled"`
	Selected         bool   `json:"selected"`
	Connected        bool   `json:"connected"`
	ExtensionVersion string `json:"extension_version,omitempty"`
	Paused           bool   `json:"paused"`
	SessionID        string `json:"task_id,omitempty"`
}

Status describes the connection and current conversation task.

type Store

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

Store also checks the current user/membership, so suspended accounts cannot continue using a previously issued device credential.

func NewStore

func NewStore(db *gorm.DB) *Store

NewStore enables durable authorization with current membership checks.

type TaskRecord

type TaskRecord struct {
	ScopeKey string `gorm:"primaryKey;size:32"`
	Session  string `gorm:"primaryKey;size:36"`
}

TaskRecord marks tasks that require explicit resume after interruption.

func (TaskRecord) TableName

func (TaskRecord) TableName() string

TableName selects the durable task interruption table.

Jump to

Keyboard shortcuts

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