proxy

package
v0.12.20 Latest Latest
Warning

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

Go to latest
Published: Mar 24, 2026 License: Apache-2.0 Imports: 35 Imported by: 0

Documentation

Index

Constants

View Source
const (
	MaxInteractionsPerSession = 200
	MaxMutationsPerSession    = 100
)

Limits for interaction and mutation history per session

View Source
const AuditDirName = "audit"

AuditDirName is the directory name for storing audit data within .agnt

View Source
const AuditSummaryFile = "SUMMARY.md"

AuditSummaryFile is the name of the summary file in the audit directory.

View Source
const LargeResultThreshold = 50 * 1024 // 50KB

LargeResultThreshold is the size in bytes above which results are saved to file.

Variables

View Source
var (
	// ErrProxyExists is returned when trying to create a proxy with an existing ID.
	ErrProxyExists = errors.New("proxy already exists")
	// ErrProxyNotFound is returned when a proxy ID is not found.
	ErrProxyNotFound = errors.New("proxy not found")
	// ErrProxyAmbiguous is returned when a fuzzy lookup matches multiple proxies.
	ErrProxyAmbiguous = errors.New("proxy ID is ambiguous - multiple matches")
)
View Source
var ChaosPresets = map[string]*ChaosConfig{

	"mobile-3g": {
		Enabled: true,
		Rules: []*ChaosRule{
			{
				ID:           "mobile-3g-latency",
				Name:         "3G Network Latency",
				Type:         ChaosLatency,
				Enabled:      true,
				Probability:  1.0,
				MinLatencyMs: 200,
				MaxLatencyMs: 2000,
				JitterMs:     500,
			},
			{
				ID:          "mobile-3g-packet-loss",
				Name:        "3G Packet Loss",
				Type:        ChaosPacketLoss,
				Enabled:     true,
				Probability: 0.02,
			},
		},
		LoggingMode: LoggingModeTesting,
	},

	"mobile-4g": {
		Enabled: true,
		Rules: []*ChaosRule{
			{
				ID:           "mobile-4g-latency",
				Name:         "4G Network Latency",
				Type:         ChaosLatency,
				Enabled:      true,
				Probability:  1.0,
				MinLatencyMs: 50,
				MaxLatencyMs: 500,
				JitterMs:     100,
			},
			{
				ID:          "mobile-4g-packet-loss",
				Name:        "4G Packet Loss",
				Type:        ChaosPacketLoss,
				Enabled:     true,
				Probability: 0.005,
			},
		},
		LoggingMode: LoggingModeTesting,
	},

	"flaky-api": {
		Enabled: true,
		Rules: []*ChaosRule{
			{
				ID:          "flaky-http-errors",
				Name:        "Random HTTP Errors",
				Type:        ChaosHTTPError,
				Enabled:     true,
				Probability: 0.05,
				ErrorCodes:  []int{500, 502, 503, 504},
			},
			{
				ID:           "flaky-latency",
				Name:         "Variable Latency",
				Type:         ChaosLatency,
				Enabled:      true,
				Probability:  0.3,
				MinLatencyMs: 100,
				MaxLatencyMs: 5000,
				JitterMs:     1000,
			},
			{
				ID:          "flaky-timeout",
				Name:        "Occasional Timeouts",
				Type:        ChaosTimeout,
				Enabled:     true,
				Probability: 0.02,
			},
		},
		LoggingMode: LoggingModeTesting,
	},

	"race-condition": {
		Enabled: true,
		Rules: []*ChaosRule{
			{
				ID:                 "reorder-responses",
				Name:               "Out-of-Order Responses",
				Type:               ChaosOutOfOrder,
				Enabled:            true,
				Probability:        0.5,
				ReorderMinRequests: 2,
				ReorderMaxWaitMs:   500,
			},
			{
				ID:           "variable-latency",
				Name:         "High Variance Latency",
				Type:         ChaosLatency,
				Enabled:      true,
				Probability:  0.7,
				MinLatencyMs: 0,
				MaxLatencyMs: 3000,
				JitterMs:     1000,
			},
		},
		LoggingMode: LoggingModeTesting,
	},

	"stale-tab": {
		Enabled: true,
		Rules: []*ChaosRule{
			{
				ID:           "stale-delay",
				Name:         "Stale Tab Delay",
				Type:         ChaosStale,
				Enabled:      true,
				Probability:  1.0,
				StaleDelayMs: 10800000,
			},
		},
		LoggingMode: LoggingModeTesting,
	},

	"slow-connection": {
		Enabled: true,
		Rules: []*ChaosRule{
			{
				ID:         "slow-drip",
				Name:       "Slow Data Transfer",
				Type:       ChaosSlowDrip,
				Enabled:    true,
				BytesPerMs: 5,
				ChunkSize:  10,
			},
			{
				ID:           "connection-latency",
				Name:         "Connection Latency",
				Type:         ChaosLatency,
				Enabled:      true,
				Probability:  1.0,
				MinLatencyMs: 500,
				MaxLatencyMs: 1000,
			},
		},
		LoggingMode: LoggingModeTesting,
	},

	"connection-drops": {
		Enabled: true,
		Rules: []*ChaosRule{
			{
				ID:               "drop-mid-response",
				Name:             "Drop Connection Mid-Response",
				Type:             ChaosDisconnect,
				Enabled:          true,
				Probability:      0.1,
				DropAfterPercent: 0.5,
			},
		},
		LoggingMode: LoggingModeTesting,
	},

	"data-corruption": {
		Enabled: true,
		Rules: []*ChaosRule{
			{
				ID:              "truncate-response",
				Name:            "Truncate Responses",
				Type:            ChaosTruncate,
				Enabled:         true,
				Probability:     0.05,
				TruncatePercent: 0.8,
			},
		},
		LoggingMode: LoggingModeTesting,
	},

	"rate-limited": {
		Enabled: true,
		Rules: []*ChaosRule{
			{
				ID:           "rate-limit-429",
				Name:         "Rate Limit Errors",
				Type:         ChaosHTTPError,
				Enabled:      true,
				Probability:  0.2,
				ErrorCodes:   []int{429},
				ErrorMessage: `{"error": "Too Many Requests", "retry_after": 60}`,
			},
		},
		LoggingMode: LoggingModeTesting,
	},

	"auth-failures": {
		Enabled: true,
		Rules: []*ChaosRule{
			{
				ID:          "auth-error",
				Name:        "Authentication Failures",
				Type:        ChaosHTTPError,
				Enabled:     true,
				Probability: 0.1,
				ErrorCodes:  []int{401, 403},
			},
		},
		LoggingMode: LoggingModeTesting,
	},

	"service-degradation": {
		Enabled:    true,
		GlobalOdds: 0.3,
		Rules: []*ChaosRule{
			{
				ID:           "degraded-latency",
				Name:         "Degraded Response Times",
				Type:         ChaosLatency,
				Enabled:      true,
				Probability:  0.5,
				MinLatencyMs: 1000,
				MaxLatencyMs: 10000,
			},
			{
				ID:          "degraded-errors",
				Name:        "Intermittent Errors",
				Type:        ChaosHTTPError,
				Enabled:     true,
				Probability: 0.1,
				ErrorCodes:  []int{503},
			},
			{
				ID:              "degraded-truncation",
				Name:            "Partial Responses",
				Type:            ChaosTruncate,
				Enabled:         true,
				Probability:     0.05,
				TruncatePercent: 0.5,
			},
		},
		LoggingMode: LoggingModeTesting,
	},

	"pressure-test": {
		Enabled:    true,
		GlobalOdds: 0.5,
		Rules: []*ChaosRule{
			{
				ID:           "pressure-latency",
				Name:         "Random Latency",
				Type:         ChaosLatency,
				Enabled:      true,
				Probability:  0.4,
				MinLatencyMs: 100,
				MaxLatencyMs: 2000,
				JitterMs:     500,
			},
			{
				ID:          "pressure-errors",
				Name:        "Random Errors",
				Type:        ChaosHTTPError,
				Enabled:     true,
				Probability: 0.1,
				ErrorCodes:  []int{500, 502, 503, 504, 429},
			},
			{
				ID:                 "pressure-reorder",
				Name:               "Response Reordering",
				Type:               ChaosOutOfOrder,
				Enabled:            true,
				Probability:        0.3,
				ReorderMinRequests: 3,
				ReorderMaxWaitMs:   300,
			},
			{
				ID:          "pressure-drops",
				Name:        "Connection Drops",
				Type:        ChaosDisconnect,
				Enabled:     true,
				Probability: 0.02,
			},
		},
		LoggingMode: LoggingModeCoordinated,
	},
}

ChaosPresets contains built-in chaos configurations for common testing scenarios

Functions

func DefaultPortForURL

func DefaultPortForURL(targetURL string) int

DefaultPortForURL computes a stable default port based on the target URL. The port is derived from a hash of the URL, mapped to the range 10000-60000. This ensures the same URL always gets the same default port while avoiding conflicts with common ports and ephemeral port ranges.

func FormatAuditReference added in v0.10.0

func FormatAuditReference() string

FormatAuditReference formats a reference to the audit directory for AI agent messages.

func GetAuditDir added in v0.10.0

func GetAuditDir() (string, error)

GetAuditDir returns the audit directory path for a project. Creates the directory if it doesn't exist. Returns absolute path to .agnt/audit in the current working directory.

func InjectInstrumentation

func InjectInstrumentation(body []byte, wsPort int) []byte

InjectInstrumentation adds monitoring JavaScript to HTML responses. The wsPort parameter is deprecated and unused (kept for backward compatibility). The script now uses relative URLs via window.location.host.

func InjectProxyMeta added in v0.12.0

func InjectProxyMeta(body []byte, proxyID string) []byte

InjectProxyMeta inserts a small script tag setting window.__devtool_proxy_id after the last </script> in the body. This is called after InjectInstrumentation so the instrumentation script's closing tag is the insertion point.

func ListPresets

func ListPresets() []string

ListPresets returns the names of all available presets

func SaveAuditData added in v0.10.0

func SaveAuditData(auditType, label string, result json.RawMessage) (string, error)

SaveAuditData saves audit data as a JSON file in the .agnt/audit directory. Returns the file path and any error.

func ShouldInject

func ShouldInject(contentType string) bool

ShouldInject determines if JavaScript should be injected based on content type.

func UpdateAuditSummary added in v0.10.0

func UpdateAuditSummary() error

UpdateAuditSummary creates or updates the SUMMARY.md file in .agnt/audit/ with a listing of all files and their descriptions.

Types

type AttributeChange

type AttributeChange struct {
	Name     string `json:"name"`
	OldValue string `json:"old_value,omitempty"`
	NewValue string `json:"new_value,omitempty"`
}

AttributeChange describes a changed attribute.

type ChaosConfig

type ChaosConfig struct {
	Enabled     bool         `json:"enabled"`
	Rules       []*ChaosRule `json:"rules"`
	GlobalOdds  float64      `json:"global_odds,omitempty"` // 0.0-1.0, applies to all
	Seed        int64        `json:"seed,omitempty"`        // For reproducible chaos
	LoggingMode LoggingMode  `json:"logging_mode,omitempty"`
}

ChaosConfig defines chaos rules for a proxy

func GetPreset

func GetPreset(name string) *ChaosConfig

GetPreset returns a copy of the named preset configuration

type ChaosEngine

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

ChaosEngine manages chaos rules and injection

func NewChaosEngine

func NewChaosEngine(logger *TrafficLogger) *ChaosEngine

NewChaosEngine creates a new chaos engine

func (*ChaosEngine) AddRule

func (ce *ChaosEngine) AddRule(rule *ChaosRule) error

AddRule adds a single rule

func (*ChaosEngine) Clear

func (ce *ChaosEngine) Clear()

Clear clears all chaos rules

func (*ChaosEngine) Disable

func (ce *ChaosEngine) Disable()

Disable disables chaos injection

func (*ChaosEngine) DisableRule

func (ce *ChaosEngine) DisableRule(ruleID string) bool

DisableRule disables a specific rule

func (*ChaosEngine) Enable

func (ce *ChaosEngine) Enable()

Enable enables chaos injection

func (*ChaosEngine) EnableRule

func (ce *ChaosEngine) EnableRule(ruleID string) bool

EnableRule enables a specific rule

func (*ChaosEngine) GetConfig

func (ce *ChaosEngine) GetConfig() *ChaosConfig

GetConfig returns the current configuration

func (*ChaosEngine) GetDropConfig

func (ce *ChaosEngine) GetDropConfig(rules []*ChaosRule) (afterPercent float64, afterBytes int64)

GetDropConfig returns connection drop configuration

func (*ChaosEngine) GetHTTPError

func (ce *ChaosEngine) GetHTTPError(rules []*ChaosRule) (int, string)

GetHTTPError returns an HTTP error code to inject, or 0 if none

func (*ChaosEngine) GetLatencyDelay

func (ce *ChaosEngine) GetLatencyDelay(rules []*ChaosRule) time.Duration

GetLatencyDelay calculates latency delay for matching rules

func (*ChaosEngine) GetLoggingMode

func (ce *ChaosEngine) GetLoggingMode() LoggingMode

GetLoggingMode returns the current logging mode

func (*ChaosEngine) GetReorderConfig

func (ce *ChaosEngine) GetReorderConfig(rules []*ChaosRule) (minRequests int, maxWait time.Duration)

GetReorderConfig returns out-of-order configuration

func (*ChaosEngine) GetSlowDripConfig

func (ce *ChaosEngine) GetSlowDripConfig(rules []*ChaosRule) (bytesPerMs, chunkSize int)

GetSlowDripConfig returns slow-drip configuration

func (*ChaosEngine) GetStaleDelay

func (ce *ChaosEngine) GetStaleDelay(rules []*ChaosRule) time.Duration

GetStaleDelay returns stale response delay

func (*ChaosEngine) GetStats

func (ce *ChaosEngine) GetStats() ChaosStats

GetStats returns current statistics

func (*ChaosEngine) GetTruncateConfig

func (ce *ChaosEngine) GetTruncateConfig(rules []*ChaosRule) float64

GetTruncateConfig returns truncation configuration

func (*ChaosEngine) HasRuleType

func (ce *ChaosEngine) HasRuleType(rules []*ChaosRule, ruleType ChaosType) bool

HasRuleType checks if any matching rule has the specified type

func (*ChaosEngine) IncrementReordered

func (ce *ChaosEngine) IncrementReordered()

IncrementReordered increments the reordered counter

func (*ChaosEngine) IsEnabled

func (ce *ChaosEngine) IsEnabled() bool

IsEnabled returns whether chaos is enabled

func (*ChaosEngine) MatchingRules

func (ce *ChaosEngine) MatchingRules(req *http.Request) []*ChaosRule

MatchingRules returns all rules that match the request

func (*ChaosEngine) RemoveRule

func (ce *ChaosEngine) RemoveRule(ruleID string) bool

RemoveRule removes a rule by ID

func (*ChaosEngine) ResetStats

func (ce *ChaosEngine) ResetStats()

ResetStats resets all statistics

func (*ChaosEngine) SetConfig

func (ce *ChaosEngine) SetConfig(config *ChaosConfig) error

SetConfig sets the chaos configuration

func (*ChaosEngine) SetLoggingMode

func (ce *ChaosEngine) SetLoggingMode(mode LoggingMode)

SetLoggingMode sets the logging mode

func (*ChaosEngine) ShouldDrop

func (ce *ChaosEngine) ShouldDrop(rules []*ChaosRule) bool

ShouldDrop returns true if the connection should be dropped

func (*ChaosEngine) ShouldReorder

func (ce *ChaosEngine) ShouldReorder(rules []*ChaosRule) bool

ShouldReorder returns true if responses should be reordered

type ChaosRule

type ChaosRule struct {
	ID      string    `json:"id"`
	Name    string    `json:"name"`
	Type    ChaosType `json:"type"`
	Enabled bool      `json:"enabled"`

	// Matching criteria
	URLPattern  string   `json:"url_pattern,omitempty"` // Regex pattern for URL
	Methods     []string `json:"methods,omitempty"`     // HTTP methods (empty = all)
	Probability float64  `json:"probability,omitempty"` // 0.0-1.0, default 1.0

	// Latency config
	MinLatencyMs int `json:"min_latency_ms,omitempty"`
	MaxLatencyMs int `json:"max_latency_ms,omitempty"`
	JitterMs     int `json:"jitter_ms,omitempty"`

	// Slow-drip config
	BytesPerMs int `json:"bytes_per_ms,omitempty"` // Bytes to write per millisecond
	ChunkSize  int `json:"chunk_size,omitempty"`   // Size of each write chunk

	// Connection drop config
	DropAfterPercent float64 `json:"drop_after_percent,omitempty"` // Drop after % of body
	DropAfterBytes   int64   `json:"drop_after_bytes,omitempty"`   // Drop after N bytes

	// Error injection config
	ErrorCodes   []int  `json:"error_codes,omitempty"` // HTTP status codes
	ErrorMessage string `json:"error_message,omitempty"`

	// Truncation config
	TruncatePercent float64 `json:"truncate_percent,omitempty"` // Keep this % of response

	// Out-of-order config
	ReorderMinRequests int `json:"reorder_min_requests,omitempty"` // Min concurrent to reorder
	ReorderMaxWaitMs   int `json:"reorder_max_wait_ms,omitempty"`  // Max wait for batch

	// Stale config
	StaleDelayMs int64 `json:"stale_delay_ms,omitempty"` // Delay in milliseconds
	// contains filtered or unexported fields
}

ChaosRule defines a single chaos behavior

type ChaosStats

type ChaosStats struct {
	TotalRequests   int64            `json:"total_requests"`
	AffectedCount   int64            `json:"affected_count"`
	LatencyInjected int64            `json:"latency_injected_ms"`
	ErrorsInjected  int64            `json:"errors_injected"`
	DropsInjected   int64            `json:"drops_injected"`
	TruncatedCount  int64            `json:"truncated_count"`
	ReorderedCount  int64            `json:"reordered_count"`
	RuleStats       map[string]int64 `json:"rule_stats"` // Rule ID -> times applied
}

ChaosStats tracks chaos injection statistics

type ChaosTransport

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

ChaosTransport wraps http.RoundTripper to inject chaos at the transport level. This enables latency injection, request reordering, and full request/response control.

func NewChaosTransport

func NewChaosTransport(underlying http.RoundTripper, engine *ChaosEngine) *ChaosTransport

NewChaosTransport creates a new chaos transport wrapping the given transport

func (*ChaosTransport) RoundTrip

func (ct *ChaosTransport) RoundTrip(req *http.Request) (*http.Response, error)

RoundTrip implements http.RoundTripper with chaos injection

type ChaosType

type ChaosType string

ChaosType defines the type of chaos to inject

const (
	// Network chaos
	ChaosLatency    ChaosType = "latency"     // Add delays to responses
	ChaosBandwidth  ChaosType = "bandwidth"   // Limit data transfer rate
	ChaosPacketLoss ChaosType = "packet_loss" // Drop random requests
	ChaosDisconnect ChaosType = "disconnect"  // Drop connection mid-response
	ChaosSlowClose  ChaosType = "slow_close"  // Delay TCP close

	// Response timing
	ChaosSlowDrip   ChaosType = "slow_drip"    // Trickle bytes slowly
	ChaosTimeout    ChaosType = "timeout"      // Never respond (simulate timeout)
	ChaosStale      ChaosType = "stale"        // Very long delays (hours)
	ChaosOutOfOrder ChaosType = "out_of_order" // Reorder responses

	// HTTP errors
	ChaosHTTPError ChaosType = "http_error" // Inject HTTP error codes
	ChaosRateLimit ChaosType = "rate_limit" // Simulate rate limiting (429)

	// Data corruption
	ChaosBitFlip     ChaosType = "bit_flip"     // Random byte changes
	ChaosTruncate    ChaosType = "truncate"     // Cut off response body
	ChaosCorruptJSON ChaosType = "corrupt_json" // Malform JSON responses

	// Protocol edge cases
	ChaosChunkedAbort ChaosType = "chunked_abort" // No terminal chunk
	ChaosPartialBody  ChaosType = "partial_body"  // Incomplete body
	ChaosHeaderBomb   ChaosType = "header_bomb"   // Many headers
)

type ConnectionDropWriter

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

ConnectionDropWriter wraps http.ResponseWriter to drop connection mid-response. This simulates network failures, connection resets, or abrupt disconnections.

func NewConnectionDropWriter

func NewConnectionDropWriter(w http.ResponseWriter, dropAfterPercent float64, dropAfterBytes int64, expectedSize int64) *ConnectionDropWriter

NewConnectionDropWriter creates a new connection drop writer

func (*ConnectionDropWriter) BytesWritten

func (cdw *ConnectionDropWriter) BytesWritten() int64

BytesWritten returns total bytes written

func (*ConnectionDropWriter) Flush

func (cdw *ConnectionDropWriter) Flush()

Flush implements http.Flusher

func (*ConnectionDropWriter) Header

func (cdw *ConnectionDropWriter) Header() http.Header

Header returns the header map

func (*ConnectionDropWriter) Hijack

func (cdw *ConnectionDropWriter) Hijack() (net.Conn, *bufio.ReadWriter, error)

Hijack implements http.Hijacker

func (*ConnectionDropWriter) IsDropped

func (cdw *ConnectionDropWriter) IsDropped() bool

IsDropped returns whether the connection has been dropped

func (*ConnectionDropWriter) Write

func (cdw *ConnectionDropWriter) Write(p []byte) (int, error)

Write writes data and may drop the connection mid-write

func (*ConnectionDropWriter) WriteHeader

func (cdw *ConnectionDropWriter) WriteHeader(statusCode int)

WriteHeader sends the HTTP response header

type CustomLog

type CustomLog struct {
	ID        string                 `json:"id"`
	Timestamp time.Time              `json:"timestamp"`
	Level     string                 `json:"level"` // debug, info, warn, error
	Message   string                 `json:"message"`
	Data      map[string]interface{} `json:"data,omitempty"`
	URL       string                 `json:"url"`
}

CustomLog represents a custom log message from the frontend.

type DeepgramConfig

type DeepgramConfig struct {
	Model          string
	Language       string
	Punctuate      bool
	SmartFormat    bool
	InterimResults bool
	Encoding       string
	SampleRate     int
	Channels       int
}

DeepgramConfig holds configuration for Deepgram connection.

func DefaultDeepgramConfig

func DefaultDeepgramConfig() DeepgramConfig

DefaultDeepgramConfig returns sensible defaults for voice transcription.

type DeepgramMessage

type DeepgramMessage struct {
	Type    string `json:"type"`
	Channel struct {
		Alternatives []struct {
			Transcript string  `json:"transcript"`
			Confidence float64 `json:"confidence"`
			Words      []struct {
				Word       string  `json:"word"`
				Start      float64 `json:"start"`
				End        float64 `json:"end"`
				Confidence float64 `json:"confidence"`
			} `json:"words"`
		} `json:"alternatives"`
	} `json:"channel"`
	IsFinal     bool    `json:"is_final"`
	SpeechFinal bool    `json:"speech_final"`
	Start       float64 `json:"start"`
	Duration    float64 `json:"duration"`
}

DeepgramMessage represents a message from Deepgram.

type DesignChat

type DesignChat struct {
	ID           string                `json:"id"`
	Timestamp    time.Time             `json:"timestamp"`
	Message      string                `json:"message"` // User's chat message
	Selector     string                `json:"selector"`
	XPath        string                `json:"xpath"`
	CurrentHTML  string                `json:"current_html"`
	OriginalHTML string                `json:"original_html"`
	ContextHTML  string                `json:"context_html"`
	Metadata     DesignElementMetadata `json:"metadata"`
	ChatHistory  []DesignChatMessage   `json:"chat_history,omitempty"`
	URL          string                `json:"url"`
}

DesignChat represents a chat message about the selected element.

type DesignChatMessage

type DesignChatMessage struct {
	Timestamp int64  `json:"timestamp"`
	Message   string `json:"message"`
	Role      string `json:"role"` // user or assistant
}

DesignChatMessage represents a chat message in the design iteration history.

type DesignElementMetadata

type DesignElementMetadata struct {
	Tag        string            `json:"tag"`
	ID         string            `json:"id,omitempty"`
	Classes    []string          `json:"classes,omitempty"`
	Attributes map[string]string `json:"attributes,omitempty"`
	Text       string            `json:"text,omitempty"` // Truncated text content
	Rect       struct {
		Width  int `json:"width"`
		Height int `json:"height"`
	} `json:"rect,omitempty"`
}

DesignElementMetadata describes metadata about a selected element for design iteration.

type DesignRequest

type DesignRequest struct {
	ID                string                `json:"id"`
	Timestamp         time.Time             `json:"timestamp"`
	Selector          string                `json:"selector"`
	XPath             string                `json:"xpath"`
	CurrentHTML       string                `json:"current_html"`  // Current HTML being displayed
	OriginalHTML      string                `json:"original_html"` // Original HTML before any changes
	ContextHTML       string                `json:"context_html"`  // Parent context
	Metadata          DesignElementMetadata `json:"metadata"`
	AlternativesCount int                   `json:"alternatives_count"` // How many alternatives already exist
	ChatHistory       []DesignChatMessage   `json:"chat_history,omitempty"`
	URL               string                `json:"url"`
}

DesignRequest represents a request for new design alternatives.

type DesignState

type DesignState struct {
	ID           string                `json:"id"`
	Timestamp    time.Time             `json:"timestamp"`
	Selector     string                `json:"selector"` // CSS selector
	XPath        string                `json:"xpath"`    // XPath for robustness
	OriginalHTML string                `json:"original_html"`
	ContextHTML  string                `json:"context_html"` // Parent element with siblings for context
	Metadata     DesignElementMetadata `json:"metadata"`
	URL          string                `json:"url"`
}

DesignState represents the initial state when an element is selected for design iteration.

type ElementCapture

type ElementCapture struct {
	ID        string    `json:"id"` // Reference ID for use in messages
	Timestamp time.Time `json:"timestamp"`
	URL       string    `json:"url"`
	Summary   string    `json:"summary"`  // Human-readable summary
	Selector  string    `json:"selector"` // CSS selector
	Tag       string    `json:"tag"`
	ElementID string    `json:"element_id,omitempty"` // DOM element id attribute
	Classes   []string  `json:"classes,omitempty"`
	Text      string    `json:"text,omitempty"` // Truncated text content
	Rect      struct {
		X      float64 `json:"x"`
		Y      float64 `json:"y"`
		Width  float64 `json:"width"`
		Height float64 `json:"height"`
	} `json:"rect,omitempty"`
}

ElementCapture represents an element capture from the panel with a reference ID.

type ErrorInjectionWriter

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

ErrorInjectionWriter wraps http.ResponseWriter to inject HTTP errors. Instead of proxying the actual response, it returns an error response.

func NewErrorInjectionWriter

func NewErrorInjectionWriter(w http.ResponseWriter, statusCode int, message string) *ErrorInjectionWriter

NewErrorInjectionWriter creates a new error injection writer

func (*ErrorInjectionWriter) Flush

func (ew *ErrorInjectionWriter) Flush()

Flush implements http.Flusher

func (*ErrorInjectionWriter) Header

func (ew *ErrorInjectionWriter) Header() http.Header

Header returns the header map

func (*ErrorInjectionWriter) Hijack

func (ew *ErrorInjectionWriter) Hijack() (net.Conn, *bufio.ReadWriter, error)

Hijack implements http.Hijacker

func (*ErrorInjectionWriter) StatusCode

func (ew *ErrorInjectionWriter) StatusCode() int

StatusCode returns the injected status code

func (*ErrorInjectionWriter) Write

func (ew *ErrorInjectionWriter) Write(p []byte) (int, error)

Write discards the actual response and writes the error message

func (*ErrorInjectionWriter) WriteHeader

func (ew *ErrorInjectionWriter) WriteHeader(statusCode int)

WriteHeader ignores the status code and writes the error status

type ExecutionResponse

type ExecutionResponse struct {
	ID        string        `json:"id"`
	Timestamp time.Time     `json:"timestamp"`
	ExecID    string        `json:"exec_id"` // Original execution ID
	Success   bool          `json:"success"`
	Result    string        `json:"result,omitempty"`
	Error     string        `json:"error,omitempty"`
	Duration  time.Duration `json:"duration"`
}

ExecutionResponse represents a response sent back to MCP client.

type ExecutionResult

type ExecutionResult struct {
	ID        string                 `json:"id"`
	Timestamp time.Time              `json:"timestamp"`
	Code      string                 `json:"code"`   // The code that was executed
	Result    string                 `json:"result"` // String representation of result
	Error     string                 `json:"error,omitempty"`
	Duration  time.Duration          `json:"duration"`
	URL       string                 `json:"url"`
	Data      map[string]interface{} `json:"data,omitempty"`
	FilePath  string                 `json:"file_path,omitempty"` // Path to file if result was too large
}

ExecutionResult represents the result of executing JavaScript.

type FrontendError

type FrontendError struct {
	ID        string    `json:"id"`
	Timestamp time.Time `json:"timestamp"`
	Message   string    `json:"message"`
	Source    string    `json:"source,omitempty"`
	LineNo    int       `json:"lineno,omitempty"`
	ColNo     int       `json:"colno,omitempty"`
	Error     string    `json:"error,omitempty"`
	Stack     string    `json:"stack,omitempty"`
	URL       string    `json:"url"` // Page URL where error occurred
}

FrontendError represents a JavaScript error from the frontend.

type HTTPLogEntry

type HTTPLogEntry struct {
	ID              string            `json:"id"`
	Timestamp       time.Time         `json:"timestamp"`
	Method          string            `json:"method"`
	URL             string            `json:"url"`
	RequestHeaders  map[string]string `json:"request_headers"`
	RequestBody     string            `json:"request_body,omitempty"`
	StatusCode      int               `json:"status_code"`
	ResponseHeaders map[string]string `json:"response_headers"`
	ResponseBody    string            `json:"response_body,omitempty"`
	Duration        time.Duration     `json:"duration"`
	Error           string            `json:"error,omitempty"`
}

HTTPLogEntry represents a logged HTTP request/response pair.

type InteractionEvent

type InteractionEvent struct {
	ID        string                 `json:"id"`
	Timestamp time.Time              `json:"timestamp"`
	EventType string                 `json:"event_type"` // click, dblclick, keydown, input, scroll, focus, blur, submit, contextmenu, mousemove
	Target    InteractionTarget      `json:"target"`
	Position  *InteractionPosition   `json:"position,omitempty"` // For mouse events
	Key       *KeyboardInfo          `json:"key,omitempty"`      // For keyboard events
	Value     string                 `json:"value,omitempty"`    // For input events (sanitized, no passwords)
	URL       string                 `json:"url"`
	Data      map[string]interface{} `json:"data,omitempty"` // Extra data (scroll_position, etc.)
}

InteractionEvent represents a user interaction (click, keyboard, etc.).

type InteractionPosition

type InteractionPosition struct {
	ClientX int `json:"client_x"`
	ClientY int `json:"client_y"`
	PageX   int `json:"page_x"`
	PageY   int `json:"page_y"`
}

InteractionPosition describes the mouse position during an interaction.

type InteractionTarget

type InteractionTarget struct {
	Selector   string            `json:"selector"`
	Tag        string            `json:"tag"`
	ID         string            `json:"id,omitempty"`
	Classes    []string          `json:"classes,omitempty"`
	Text       string            `json:"text,omitempty"`       // Truncated innerText
	Attributes map[string]string `json:"attributes,omitempty"` // Relevant attrs only (href, src, type, etc.)
}

InteractionTarget describes the DOM element that was interacted with.

type KeyboardInfo

type KeyboardInfo struct {
	Key   string `json:"key"`
	Code  string `json:"code"`
	Ctrl  bool   `json:"ctrl,omitempty"`
	Alt   bool   `json:"alt,omitempty"`
	Shift bool   `json:"shift,omitempty"`
	Meta  bool   `json:"meta,omitempty"`
}

KeyboardInfo describes keyboard event details.

type LogEntry

type LogEntry struct {
	Type              LogEntryType       `json:"type"`
	HTTP              *HTTPLogEntry      `json:"http,omitempty"`
	Error             *FrontendError     `json:"error,omitempty"`
	Performance       *PerformanceMetric `json:"performance,omitempty"`
	Custom            *CustomLog         `json:"custom,omitempty"`
	Screenshot        *Screenshot        `json:"screenshot,omitempty"`
	Execution         *ExecutionResult   `json:"execution,omitempty"`
	Response          *ExecutionResponse `json:"response,omitempty"`
	Interaction       *InteractionEvent  `json:"interaction,omitempty"`
	Mutation          *MutationEvent     `json:"mutation,omitempty"`
	PanelMessage      *PanelMessage      `json:"panel_message,omitempty"`
	Sketch            *SketchEntry       `json:"sketch,omitempty"`
	ScreenshotCapture *ScreenshotCapture `json:"screenshot_capture,omitempty"`
	ElementCapture    *ElementCapture    `json:"element_capture,omitempty"`
	SketchCapture     *SketchCapture     `json:"sketch_capture,omitempty"`
	DesignState       *DesignState       `json:"design_state,omitempty"`
	DesignRequest     *DesignRequest     `json:"design_request,omitempty"`
	DesignChat        *DesignChat        `json:"design_chat,omitempty"`
	Diagnostic        *ProxyDiagnostic   `json:"diagnostic,omitempty"`
}

LogEntry is a union type for all log entry types.

type LogEntryType

type LogEntryType string

LogEntryType categorizes different types of log entries.

const (
	// LogTypeHTTP represents an HTTP request/response.
	LogTypeHTTP LogEntryType = "http"
	// LogTypeError represents a frontend JavaScript error.
	LogTypeError LogEntryType = "error"
	// LogTypePerformance represents frontend performance metrics.
	LogTypePerformance LogEntryType = "performance"
	// LogTypeCustom represents a custom log message from frontend.
	LogTypeCustom LogEntryType = "custom"
	// LogTypeScreenshot represents a screenshot capture.
	LogTypeScreenshot LogEntryType = "screenshot"
	// LogTypeExecution represents JavaScript execution result.
	LogTypeExecution LogEntryType = "execution"
	// LogTypeResponse represents JavaScript execution responses returned to MCP client.
	LogTypeResponse LogEntryType = "response"
	// LogTypeInteraction represents a user interaction event (click, keyboard, etc.).
	LogTypeInteraction LogEntryType = "interaction"
	// LogTypeMutation represents a DOM mutation event.
	LogTypeMutation LogEntryType = "mutation"
	// LogTypePanelMessage represents a message from the floating indicator panel.
	LogTypePanelMessage LogEntryType = "panel_message"
	// LogTypeSketch represents a sketch/wireframe from the sketch mode.
	LogTypeSketch LogEntryType = "sketch"
	// LogTypeScreenshotCapture represents an area capture with a reference ID.
	LogTypeScreenshotCapture LogEntryType = "screenshot_capture"
	// LogTypeElementCapture represents an element capture with a reference ID.
	LogTypeElementCapture LogEntryType = "element_capture"
	// LogTypeSketchCapture represents a sketch capture with a reference ID.
	LogTypeSketchCapture LogEntryType = "sketch_capture"
	// LogTypeDesignState represents the initial state when an element is selected for design iteration.
	LogTypeDesignState LogEntryType = "design_state"
	// LogTypeDesignRequest represents a request for new design alternatives.
	LogTypeDesignRequest LogEntryType = "design_request"
	// LogTypeDesignChat represents a chat message about the selected element.
	LogTypeDesignChat LogEntryType = "design_chat"
	// LogTypeDiagnostic represents a server-side diagnostic event (proxy errors, connection issues, etc.).
	LogTypeDiagnostic LogEntryType = "diagnostic"
)

type LogFilter

type LogFilter struct {
	Types            []LogEntryType `json:"types,omitempty"`       // Filter by entry type
	Methods          []string       `json:"methods,omitempty"`     // HTTP methods
	URLPattern       string         `json:"url_pattern,omitempty"` // URL substring match
	StatusCodes      []int          `json:"status_codes,omitempty"`
	Since            *time.Time     `json:"since,omitempty"`
	Until            *time.Time     `json:"until,omitempty"`
	Limit            int            `json:"limit,omitempty"`             // Max results (0 = all)
	InteractionTypes []string       `json:"interaction_types,omitempty"` // click, keydown, scroll, etc.
	MutationTypes    []string       `json:"mutation_types,omitempty"`    // added, removed, attributes
	DiagnosticLevels []string       `json:"diagnostic_levels,omitempty"` // info, warning, error
	ErrorsOnly       bool           `json:"errors_only,omitempty"`       // Filter to errors from all sources
}

LogFilter specifies criteria for querying logs.

func (LogFilter) Matches

func (f LogFilter) Matches(entry LogEntry) bool

Matches returns true if the entry matches the filter.

type LoggerStats

type LoggerStats struct {
	TotalEntries     int64 `json:"total_entries"`
	AvailableEntries int64 `json:"available_entries"`
	MaxSize          int64 `json:"max_size"`
	Dropped          int64 `json:"dropped"`
}

LoggerStats holds logger statistics.

type LoggingMode

type LoggingMode int32

LoggingMode defines how chaos events are logged

const (
	LoggingModeSilent      LoggingMode = 0 // No chaos-specific logging
	LoggingModeTesting     LoggingMode = 1 // Log session start/stop + stats
	LoggingModeCoordinated LoggingMode = 2 // Minimal logging
)

type MutationEvent

type MutationEvent struct {
	ID           string           `json:"id"`
	Timestamp    time.Time        `json:"timestamp"`
	MutationType string           `json:"mutation_type"` // added, removed, attributes, characterData
	Target       MutationTarget   `json:"target"`
	Added        []MutationNode   `json:"added,omitempty"`
	Removed      []MutationNode   `json:"removed,omitempty"`
	Attribute    *AttributeChange `json:"attribute,omitempty"`
	URL          string           `json:"url"`
}

MutationEvent represents a DOM mutation.

type MutationNode

type MutationNode struct {
	Selector string `json:"selector,omitempty"`
	Tag      string `json:"tag"`
	ID       string `json:"id,omitempty"`
	HTML     string `json:"html,omitempty"` // Truncated outerHTML
}

MutationNode describes a node that was added or removed.

type MutationTarget

type MutationTarget struct {
	Selector string `json:"selector"`
	Tag      string `json:"tag"`
	ID       string `json:"id,omitempty"`
}

MutationTarget describes the parent element where a mutation occurred.

type OverlayEvent

type OverlayEvent struct {
	Type      string      `json:"type"`
	ProxyID   string      `json:"proxy_id"`
	Timestamp time.Time   `json:"timestamp"`
	Data      interface{} `json:"data"`
}

OverlayEvent represents an event to send to the overlay.

type OverlayNotifier

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

OverlayNotifier sends events to the agent overlay server via Unix socket.

func NewOverlayNotifier

func NewOverlayNotifier() *OverlayNotifier

NewOverlayNotifier creates a new overlay notifier.

func (*OverlayNotifier) GetEndpoint

func (n *OverlayNotifier) GetEndpoint() string

GetEndpoint returns the current socket path.

func (*OverlayNotifier) IsEnabled

func (n *OverlayNotifier) IsEnabled() bool

IsEnabled returns whether the notifier is enabled.

func (*OverlayNotifier) NotifyCustom

func (n *OverlayNotifier) NotifyCustom(proxyID, eventType string, data interface{}) error

NotifyCustom sends a custom event to the overlay.

func (*OverlayNotifier) NotifyDesignChat

func (n *OverlayNotifier) NotifyDesignChat(proxyID string, chat *DesignChat) error

NotifyDesignChat sends a design chat message to the overlay.

func (*OverlayNotifier) NotifyDesignRequest

func (n *OverlayNotifier) NotifyDesignRequest(proxyID string, request *DesignRequest) error

NotifyDesignRequest sends a design request to the overlay.

func (*OverlayNotifier) NotifyDesignState

func (n *OverlayNotifier) NotifyDesignState(proxyID string, state *DesignState) error

NotifyDesignState sends design state to the overlay.

func (*OverlayNotifier) NotifyInteraction

func (n *OverlayNotifier) NotifyInteraction(proxyID string, interaction *InteractionEvent) error

NotifyInteraction sends an interaction event to the overlay.

func (*OverlayNotifier) NotifyPanelMessage

func (n *OverlayNotifier) NotifyPanelMessage(proxyID string, msg *PanelMessage) error

NotifyPanelMessage sends a panel message to the overlay.

func (*OverlayNotifier) NotifySketch

func (n *OverlayNotifier) NotifySketch(proxyID string, sketch *SketchEntry) error

NotifySketch sends a sketch to the overlay.

func (*OverlayNotifier) SendKeyToOverlay

func (n *OverlayNotifier) SendKeyToOverlay(key string, ctrl, alt, shift bool) error

SendKeyToOverlay sends a key to the overlay.

func (*OverlayNotifier) SetEndpoint

func (n *OverlayNotifier) SetEndpoint(socketPath string)

SetEndpoint sets the overlay socket path. Example: "/run/user/1000/devtool-overlay.sock" or "\\.\pipe\devtool-overlay-user"

func (*OverlayNotifier) TypeToOverlay

func (n *OverlayNotifier) TypeToOverlay(text string, enter bool) error

TypeToOverlay sends a type command to the overlay. The overlay will inject this text into the PTY.

type PageSession

type PageSession struct {
	ID             string    `json:"id"`
	URL            string    `json:"url"`                       // Current/most recent URL
	BrowserSession string    `json:"browser_session,omitempty"` // Browser tab session ID (from cookie)
	PageTitle      string    `json:"page_title,omitempty"`
	StartTime      time.Time `json:"start_time"`
	LastActivity   time.Time `json:"last_activity"`
	Active         bool      `json:"active"`

	// Navigation history - all document requests in this tab session
	Navigations     []HTTPLogEntry     `json:"navigations,omitempty"`
	DocumentRequest *HTTPLogEntry      `json:"document_request,omitempty"` // Most recent document request (for backwards compat)
	Resources       []HTTPLogEntry     `json:"resources"`
	Errors          []FrontendError    `json:"errors,omitempty"`
	Performance     *PerformanceMetric `json:"performance,omitempty"`

	// User interaction tracking
	Interactions     []InteractionEvent `json:"interactions,omitempty"`
	InteractionCount int                `json:"interaction_count"` // Total count (may exceed slice length)

	// DOM mutation tracking
	Mutations     []MutationEvent `json:"mutations,omitempty"`
	MutationCount int             `json:"mutation_count"` // Total count (may exceed slice length)
}

PageSession represents a browser tab session and its navigation history. All navigations within the same browser tab are grouped together.

type PageSessionSummary added in v0.10.0

type PageSessionSummary struct {
	ID             string    `json:"id"`
	URL            string    `json:"url"`
	PageTitle      string    `json:"page_title,omitempty"`
	StartTime      time.Time `json:"start_time"`
	LastActivity   time.Time `json:"last_activity"`
	Active         bool      `json:"active"`
	ResourceCount  int       `json:"resource_count"`
	ErrorCount     int       `json:"error_count"`
	HasPerformance bool      `json:"has_performance"`
	LoadTimeMs     int64     `json:"load_time_ms,omitempty"`
	// Counts only, no detailed arrays
	InteractionCount int `json:"interaction_count"`
	MutationCount    int `json:"mutation_count"`
}

PageSessionSummary is a lightweight representation of a page session for list views. It omits detailed arrays (interactions, mutations, errors, resources) to reduce token usage.

type PageTracker

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

PageTracker tracks page sessions and groups requests by page.

func NewPageTracker

func NewPageTracker(maxSessions int, sessionTimeout time.Duration) *PageTracker

NewPageTracker creates a new page tracker.

func (*PageTracker) Clear

func (pt *PageTracker) Clear()

Clear removes all page sessions.

func (*PageTracker) GetActiveSessionSummaries added in v0.10.0

func (pt *PageTracker) GetActiveSessionSummaries() []PageSessionSummary

GetActiveSessionSummaries returns lightweight summaries of active sessions. Use this for list views to avoid sending massive arrays of interactions/mutations.

func (*PageTracker) GetActiveSessions

func (pt *PageTracker) GetActiveSessions() []*PageSession

GetActiveSessions returns all currently active page sessions.

func (*PageTracker) GetSession

func (pt *PageTracker) GetSession(sessionID string) (*PageSession, bool)

GetSession returns a specific page session by ID.

func (*PageTracker) ResolveSession added in v0.8.0

func (pt *PageTracker) ResolveSession(browserSessionID, url string) string

ResolveSession finds a session by browser session ID with URL fallback. Returns empty string if no session found.

func (*PageTracker) TrackError

func (pt *PageTracker) TrackError(err FrontendError, browserSessionID string)

TrackError associates a frontend error with a page session. browserSessionID is the unique ID from the browser tab's sessionStorage.

func (*PageTracker) TrackHTTPRequest

func (pt *PageTracker) TrackHTTPRequest(entry HTTPLogEntry)

TrackHTTPRequest processes an HTTP request and associates it with a page session.

func (*PageTracker) TrackInteraction

func (pt *PageTracker) TrackInteraction(interaction InteractionEvent, browserSessionID string)

TrackInteraction associates a user interaction event with a page session. browserSessionID is the unique ID from the browser tab's sessionStorage.

func (*PageTracker) TrackMutation

func (pt *PageTracker) TrackMutation(mutation MutationEvent, browserSessionID string)

TrackMutation associates a DOM mutation event with a page session. browserSessionID is the unique ID from the browser tab's sessionStorage.

func (*PageTracker) TrackPerformance

func (pt *PageTracker) TrackPerformance(perf PerformanceMetric, browserSessionID string)

TrackPerformance associates performance metrics with a page session. browserSessionID is the unique ID from the browser tab's sessionStorage.

type PanelAttachment

type PanelAttachment struct {
	Type     string                 `json:"type"` // element, screenshot_area
	Selector string                 `json:"selector,omitempty"`
	Tag      string                 `json:"tag,omitempty"`
	ID       string                 `json:"id,omitempty"`
	Classes  []string               `json:"classes,omitempty"`
	Text     string                 `json:"text,omitempty"`
	Summary  string                 `json:"summary,omitempty"`
	FilePath string                 `json:"filePath,omitempty"` // Browser-side file path from capture_ack
	Area     *ScreenshotArea        `json:"area,omitempty"`
	Data     map[string]interface{} `json:"data,omitempty"`
}

PanelAttachment represents an attachment to a panel message.

type PanelMessage

type PanelMessage struct {
	ID                  string            `json:"id"`
	Timestamp           time.Time         `json:"timestamp"`
	Message             string            `json:"message"`
	Attachments         []PanelAttachment `json:"attachments,omitempty"`
	URL                 string            `json:"url"`
	RequestNotification bool              `json:"request_notification,omitempty"`
}

PanelMessage represents a message from the floating indicator panel.

type PerformanceMetric

type PerformanceMetric struct {
	ID                   string                 `json:"id"`
	Timestamp            time.Time              `json:"timestamp"`
	URL                  string                 `json:"url"` // Page URL
	NavigationStart      int64                  `json:"navigation_start,omitempty"`
	LoadEventEnd         int64                  `json:"load_event_end,omitempty"`
	DOMContentLoaded     int64                  `json:"dom_content_loaded,omitempty"`
	FirstPaint           int64                  `json:"first_paint,omitempty"`
	FirstContentfulPaint int64                  `json:"first_contentful_paint,omitempty"`
	Resources            []ResourceTiming       `json:"resources,omitempty"`
	Custom               map[string]interface{} `json:"custom,omitempty"`
}

PerformanceMetric represents frontend performance data.

type ProxyConfig

type ProxyConfig struct {
	ID            string
	TargetURL     string
	ListenPort    int
	MaxLogSize    int
	AutoRestart   bool   // Enable automatic restart on crash (default: true)
	Path          string // Working directory where proxy was created
	BindAddress   string // Bind address: "127.0.0.1" (default, localhost only) or "0.0.0.0" (all interfaces)
	PublicURL     string // Optional public URL for tunnel services (e.g., "https://abc123.trycloudflare.com")
	AllowExternal bool   // Allow binding to non-localhost addresses (0.0.0.0, ::). Requires explicit opt-in for security.
	SkipTLSVerify bool   // Skip TLS certificate verification (default: false, verifies certs). Set true for self-signed/expired certs in dev.
	Tunnel        *protocol.TunnelConfig
}

ProxyConfig holds configuration for creating a proxy server.

type ProxyDiagnostic added in v0.11.3

type ProxyDiagnostic struct {
	Timestamp time.Time            `json:"timestamp"`
	Level     ProxyDiagnosticLevel `json:"level"`
	Category  string               `json:"category"` // "proxy", "connection", "request"
	Event     string               `json:"event"`    // "error", "timeout", "refused", etc.
	Message   string               `json:"message"`
	RequestID string               `json:"request_id,omitempty"`
	Method    string               `json:"method,omitempty"`
	URL       string               `json:"url,omitempty"`
	Target    string               `json:"target,omitempty"`
	Data      map[string]any       `json:"data,omitempty"`
}

ProxyDiagnostic represents a diagnostic event from the proxy server.

type ProxyDiagnosticLevel added in v0.11.3

type ProxyDiagnosticLevel string

ProxyDiagnosticLevel indicates the severity of a diagnostic event.

const (
	DiagnosticInfo    ProxyDiagnosticLevel = "info"
	DiagnosticWarning ProxyDiagnosticLevel = "warning"
	DiagnosticError   ProxyDiagnosticLevel = "error"
)

type ProxyManager

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

ProxyManager manages multiple reverse proxy servers with lock-free access.

func NewProxyManager

func NewProxyManager() *ProxyManager

NewProxyManager creates a new proxy manager.

func (*ProxyManager) ActiveCount

func (pm *ProxyManager) ActiveCount() int64

ActiveCount returns the number of running proxies.

func (*ProxyManager) Create

func (pm *ProxyManager) Create(ctx context.Context, config ProxyConfig) (*ProxyServer, error)

Create creates and starts a new proxy server.

func (*ProxyManager) Get

func (pm *ProxyManager) Get(id string) (*ProxyServer, error)

Get retrieves a proxy by ID with fuzzy matching support. First tries exact match, then looks for proxies where the ID contains the search string as a component (for compound IDs like "project:name:host-port").

func (*ProxyManager) GetWithPathFilter added in v0.8.0

func (pm *ProxyManager) GetWithPathFilter(id, pathFilter string) (*ProxyServer, error)

GetWithPathFilter retrieves a proxy by ID with fuzzy matching, filtered by path. If pathFilter is non-empty, only proxies with matching Path are considered for fuzzy lookup. Exact matches are always returned regardless of path filter.

func (*ProxyManager) List

func (pm *ProxyManager) List() []*ProxyServer

List returns all managed proxy servers.

func (*ProxyManager) Shutdown

func (pm *ProxyManager) Shutdown(ctx context.Context) error

Shutdown stops all managed proxies.

func (*ProxyManager) Stop

func (pm *ProxyManager) Stop(ctx context.Context, id string) error

Stop stops a proxy server and removes it from the registry.

func (*ProxyManager) StopAll added in v0.7.6

func (pm *ProxyManager) StopAll(ctx context.Context) ([]string, error)

StopAll stops all running proxies and removes them from the registry. Unlike Shutdown, this does NOT set shuttingDown flag, allowing new proxies to be started afterward. This is used for cleanup when the last client disconnects. Returns the list of stopped proxy IDs for state persistence cleanup.

func (*ProxyManager) StopByProjectPath added in v0.7.8

func (pm *ProxyManager) StopByProjectPath(ctx context.Context, projectPath string) ([]string, error)

StopByProjectPath stops all running proxies for a specific project path and removes them. This is used for session-scoped cleanup when a client disconnects. Returns the list of stopped proxy IDs.

func (*ProxyManager) TotalStarted

func (pm *ProxyManager) TotalStarted() int64

TotalStarted returns the total number of proxies ever started.

type ProxyServer

type ProxyServer struct {
	ID            string
	TargetURL     *url.URL
	ListenAddr    string
	Path          string
	BindAddress   string // Bind address used (127.0.0.1 or 0.0.0.0)
	AllowExternal bool   // Whether external binding was explicitly allowed
	PublicURL     string // Optional public URL for tunnel services
	// contains filtered or unexported fields
}

ProxyServer is a reverse proxy that logs traffic and injects instrumentation.

func NewProxyServer

func NewProxyServer(config ProxyConfig) (*ProxyServer, error)

NewProxyServer creates a new reverse proxy server.

func (*ProxyServer) BroadcastActivityState

func (ps *ProxyServer) BroadcastActivityState(active bool) int

BroadcastActivityState sends an activity state update to all connected browser clients. Returns the number of clients that received the update.

func (*ProxyServer) BroadcastOutputPreview added in v0.8.0

func (ps *ProxyServer) BroadcastOutputPreview(lines []string) int

BroadcastOutputPreview sends output preview lines to all connected browser clients. Returns the number of clients that received the preview.

func (*ProxyServer) BroadcastProxyDiagnostic added in v0.11.3

func (ps *ProxyServer) BroadcastProxyDiagnostic(diag *ProxyDiagnostic) int

BroadcastProxyDiagnostic sends a diagnostic event to all connected browser clients. This allows the browser to receive server-side proxy errors for debugging. Returns the number of clients that received the diagnostic.

func (*ProxyServer) BroadcastToast

func (ps *ProxyServer) BroadcastToast(toastType, title, message string, duration int) (int, error)

BroadcastToast sends a toast notification to all connected browser clients. Returns the number of clients that received the toast.

func (*ProxyServer) ChaosEngine

func (ps *ProxyServer) ChaosEngine() *ChaosEngine

ChaosEngine returns the chaos engine for this proxy server.

func (*ProxyServer) ExecuteJavaScript

func (ps *ProxyServer) ExecuteJavaScript(code string) (string, <-chan *ExecutionResult, error)

ExecuteJavaScript sends JavaScript code to all connected clients for execution. Returns the execution ID and a channel that will receive the result.

func (*ProxyServer) FlushConnections added in v0.12.8

func (ps *ProxyServer) FlushConnections()

FlushConnections replaces the transport to kill both idle and in-flight connections to the backend. Call this when the backend restarts so requests don't hang on half-open TCP connections waiting for the OS timeout.

func (*ProxyServer) HasTunnel

func (ps *ProxyServer) HasTunnel() bool

HasTunnel returns true if a tunnel is configured.

func (*ProxyServer) IsRunning

func (ps *ProxyServer) IsRunning() bool

IsRunning returns true if the proxy is running.

func (*ProxyServer) IsTunnelRunning

func (ps *ProxyServer) IsTunnelRunning() bool

IsTunnelRunning returns true if the tunnel is currently running.

func (*ProxyServer) Logger

func (ps *ProxyServer) Logger() *TrafficLogger

Logger returns the traffic logger.

func (*ProxyServer) LookupCapture added in v0.11.4

func (ps *ProxyServer) LookupCapture(name string) string

LookupCapture returns the file path for a named screenshot, or empty string if not found. Entries are deleted after lookup — consumed once by the MCP tool handler.

func (*ProxyServer) OverlayNotifier

func (ps *ProxyServer) OverlayNotifier() *OverlayNotifier

OverlayNotifier returns the overlay notifier for direct access.

func (*ProxyServer) PageTracker

func (ps *ProxyServer) PageTracker() *PageTracker

PageTracker returns the page tracker for this proxy server.

func (*ProxyServer) Ready

func (ps *ProxyServer) Ready() <-chan struct{}

Ready returns a channel that is closed when the server is ready to accept connections. Use this to wait for server readiness instead of polling or sleeping.

func (*ProxyServer) SetOverlayEndpoint

func (ps *ProxyServer) SetOverlayEndpoint(endpoint string)

SetOverlayEndpoint configures the overlay endpoint for forwarding events. Example: "http://127.0.0.1:19191"

func (*ProxyServer) SetPublicURL

func (ps *ProxyServer) SetPublicURL(publicURL string)

SetPublicURL sets the public URL for tunnel services. This URL is used for URL rewriting when behind a tunnel. Example: "https://abc123.trycloudflare.com"

func (*ProxyServer) SetSessionClientFactory added in v0.7.0

func (ps *ProxyServer) SetSessionClientFactory(factory SessionClientFactory)

SetSessionClientFactory sets the factory for creating session clients. This is used by the browser session API to communicate with the daemon.

func (*ProxyServer) Start

func (ps *ProxyServer) Start(ctx context.Context) error

Start begins the proxy server.

func (*ProxyServer) Stats

func (ps *ProxyServer) Stats() ProxyStats

Stats returns proxy statistics.

func (*ProxyServer) Stop

func (ps *ProxyServer) Stop(ctx context.Context) error

Stop gracefully stops the proxy server.

func (*ProxyServer) TunnelURL

func (ps *ProxyServer) TunnelURL() string

TunnelURL returns the public tunnel URL if a tunnel is running.

type ProxyStats

type ProxyStats struct {
	ID            string        `json:"id"`
	TargetURL     string        `json:"target_url"`
	ListenAddr    string        `json:"listen_addr"`
	Path          string        `json:"path,omitempty"`         // Working directory where proxy was created
	BindAddress   string        `json:"bind_address,omitempty"` // Bind address (127.0.0.1 or 0.0.0.0)
	PublicURL     string        `json:"public_url,omitempty"`   // Public URL for tunnels
	Running       bool          `json:"running"`
	Uptime        time.Duration `json:"uptime"`
	TotalRequests int64         `json:"total_requests"`
	LoggerStats   LoggerStats   `json:"logger_stats"`
	LastError     string        `json:"last_error,omitempty"` // Set if server crashed
	RestartCount  int           `json:"restart_count"`        // Number of restarts in current window
	AutoRestart   bool          `json:"auto_restart"`         // Whether auto-restart is enabled
}

ProxyStats holds proxy statistics.

type ReorderQueue

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

ReorderQueue holds requests and releases them in shuffled order to simulate out-of-order response delivery

func NewReorderQueue

func NewReorderQueue(engine *ChaosEngine) *ReorderQueue

NewReorderQueue creates a new reorder queue

func (*ReorderQueue) PendingCount

func (rq *ReorderQueue) PendingCount() int

PendingCount returns the number of pending requests

func (*ReorderQueue) Stop

func (rq *ReorderQueue) Stop()

Stop stops the reorder queue and releases any pending requests

func (*ReorderQueue) Submit

func (rq *ReorderQueue) Submit(req *http.Request, transport http.RoundTripper, rules []*ChaosRule) (*http.Response, error)

Submit adds a request to the reorder queue and waits for its response

type ResourceTiming

type ResourceTiming struct {
	Name     string `json:"name"`
	Duration int64  `json:"duration"`
	Size     int64  `json:"size,omitempty"`
}

ResourceTiming represents timing for a single resource.

type Screenshot

type Screenshot struct {
	ID        string    `json:"id"`
	Timestamp time.Time `json:"timestamp"`
	Name      string    `json:"name"`
	FilePath  string    `json:"file_path"` // Path to saved screenshot file
	URL       string    `json:"url"`       // Page URL where screenshot was taken
	Width     int       `json:"width"`
	Height    int       `json:"height"`
	Format    string    `json:"format"`   // png, jpeg
	Selector  string    `json:"selector"` // CSS selector for element (or "body" for full page)
	Error     string    `json:"error,omitempty"`
}

Screenshot represents a captured screenshot.

type ScreenshotArea

type ScreenshotArea struct {
	X      int    `json:"x"`
	Y      int    `json:"y"`
	Width  int    `json:"width"`
	Height int    `json:"height"`
	Data   string `json:"data,omitempty"` // Base64 image data
}

ScreenshotArea represents a selected area for screenshot.

type ScreenshotCapture

type ScreenshotCapture struct {
	ID        string    `json:"id"` // Reference ID for use in messages
	Timestamp time.Time `json:"timestamp"`
	URL       string    `json:"url"`
	Summary   string    `json:"summary"`    // Human-readable summary
	ImageData string    `json:"image_data"` // Base64 PNG data (cleared after save)
	FilePath  string    `json:"file_path"`  // Path to saved image file
	Area      struct {
		X      int `json:"x"`
		Y      int `json:"y"`
		Width  int `json:"width"`
		Height int `json:"height"`
	} `json:"area"`
}

ScreenshotCapture represents an area capture from the panel with a reference ID.

type SessionClient added in v0.7.0

type SessionClient interface {
	SessionList(dirFilter protocol.DirectoryFilter) (map[string]interface{}, error)
	SessionGet(code string) (map[string]interface{}, error)
	SessionSend(code string, message string) (map[string]interface{}, error)
	SessionSchedule(code string, duration string, message string) (map[string]interface{}, error)
	SessionTasks(dirFilter protocol.DirectoryFilter) (map[string]interface{}, error)
	SessionCancel(taskID string) error
	StoreGet(req protocol.StoreGetRequest) (map[string]interface{}, error)
	StoreSet(req protocol.StoreSetRequest) error
	StoreDelete(req protocol.StoreDeleteRequest) error
	StoreList(req protocol.StoreListRequest) (map[string]interface{}, error)
	StoreClear(req protocol.StoreClearRequest) error
	StoreGetAll(req protocol.StoreGetAllRequest) (map[string]interface{}, error)
	Close() error
}

SessionClient defines the interface for session operations. This interface is implemented by daemon.Client to avoid import cycles.

type SessionClientFactory added in v0.7.0

type SessionClientFactory func() (SessionClient, error)

SessionClientFactory is a function that creates a new SessionClient. This is used to avoid import cycles by having the daemon package provide the factory.

type SketchCapture

type SketchCapture struct {
	ID           string                 `json:"id"` // Reference ID for use in messages
	Timestamp    time.Time              `json:"timestamp"`
	URL          string                 `json:"url"`
	Summary      string                 `json:"summary"` // Human-readable summary
	ElementCount int                    `json:"element_count"`
	Sketch       map[string]interface{} `json:"sketch,omitempty"` // Sketch data
	ImageData    string                 `json:"image_data,omitempty"`
	FilePath     string                 `json:"file_path,omitempty"`
}

SketchCapture represents a sketch capture from the panel with a reference ID.

type SketchEntry

type SketchEntry struct {
	ID           string                 `json:"id"`
	Timestamp    time.Time              `json:"timestamp"`
	URL          string                 `json:"url"`
	Description  string                 `json:"description"`   // User description of the wireframe
	Sketch       map[string]interface{} `json:"sketch"`        // JSON-serialized sketch data
	ImageData    string                 `json:"image_data"`    // Base64 PNG of the sketch
	FilePath     string                 `json:"file_path"`     // Path to saved image file
	ElementCount int                    `json:"element_count"` // Number of elements in sketch
}

SketchEntry represents a sketch/wireframe from sketch mode.

type SlowDripWriter

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

SlowDripWriter wraps http.ResponseWriter to stream bytes with delays. This simulates slow network connections or bandwidth throttling.

func NewSlowDripWriter

func NewSlowDripWriter(w http.ResponseWriter, bytesPerMs, chunkSize int, ctx context.Context) *SlowDripWriter

NewSlowDripWriter creates a new slow-drip writer

func (*SlowDripWriter) BytesWritten

func (sdw *SlowDripWriter) BytesWritten() int64

BytesWritten returns the total bytes written

func (*SlowDripWriter) Flush

func (sdw *SlowDripWriter) Flush()

Flush implements http.Flusher

func (*SlowDripWriter) Header

func (sdw *SlowDripWriter) Header() http.Header

Header returns the header map

func (*SlowDripWriter) Hijack

func (sdw *SlowDripWriter) Hijack() (net.Conn, *bufio.ReadWriter, error)

Hijack implements http.Hijacker

func (*SlowDripWriter) Write

func (sdw *SlowDripWriter) Write(p []byte) (int, error)

Write writes data with delays between chunks

func (*SlowDripWriter) WriteHeader

func (sdw *SlowDripWriter) WriteHeader(statusCode int)

WriteHeader sends the HTTP response header with the provided status code

type TrafficLogger

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

TrafficLogger stores proxy traffic logs with bounded memory.

func NewTrafficLogger

func NewTrafficLogger(maxSize int) *TrafficLogger

NewTrafficLogger creates a new logger with specified max entries.

func (*TrafficLogger) Clear

func (tl *TrafficLogger) Clear()

Clear removes all log entries.

func (*TrafficLogger) LogCustom

func (tl *TrafficLogger) LogCustom(entry CustomLog)

LogCustom adds a custom log message.

func (*TrafficLogger) LogDesignChat

func (tl *TrafficLogger) LogDesignChat(entry DesignChat)

LogDesignChat adds a design chat entry.

func (*TrafficLogger) LogDesignRequest

func (tl *TrafficLogger) LogDesignRequest(entry DesignRequest)

LogDesignRequest adds a design request entry.

func (*TrafficLogger) LogDesignState

func (tl *TrafficLogger) LogDesignState(entry DesignState)

LogDesignState adds a design state entry.

func (*TrafficLogger) LogDiagnostic added in v0.11.3

func (tl *TrafficLogger) LogDiagnostic(entry ProxyDiagnostic)

LogDiagnostic adds a server-side diagnostic event.

func (*TrafficLogger) LogElementCapture

func (tl *TrafficLogger) LogElementCapture(entry ElementCapture)

LogElementCapture adds an element capture entry.

func (*TrafficLogger) LogError

func (tl *TrafficLogger) LogError(entry FrontendError)

LogError adds a frontend error log entry.

func (*TrafficLogger) LogExecution

func (tl *TrafficLogger) LogExecution(entry ExecutionResult)

LogExecution adds a JavaScript execution result.

func (*TrafficLogger) LogHTTP

func (tl *TrafficLogger) LogHTTP(entry HTTPLogEntry)

LogHTTP adds an HTTP request/response log entry.

func (*TrafficLogger) LogInteraction

func (tl *TrafficLogger) LogInteraction(entry InteractionEvent)

LogInteraction adds a user interaction event.

func (*TrafficLogger) LogMutation

func (tl *TrafficLogger) LogMutation(entry MutationEvent)

LogMutation adds a DOM mutation event.

func (*TrafficLogger) LogPanelMessage

func (tl *TrafficLogger) LogPanelMessage(entry PanelMessage)

LogPanelMessage adds a panel message entry.

func (*TrafficLogger) LogPerformance

func (tl *TrafficLogger) LogPerformance(entry PerformanceMetric)

LogPerformance adds a frontend performance log entry.

func (*TrafficLogger) LogResponse

func (tl *TrafficLogger) LogResponse(entry ExecutionResponse)

LogResponse adds an execution response sent to MCP client.

func (*TrafficLogger) LogScreenshot

func (tl *TrafficLogger) LogScreenshot(entry Screenshot)

LogScreenshot adds a screenshot log entry.

func (*TrafficLogger) LogScreenshotCapture

func (tl *TrafficLogger) LogScreenshotCapture(entry ScreenshotCapture)

LogScreenshotCapture adds a screenshot capture entry.

func (*TrafficLogger) LogSketch

func (tl *TrafficLogger) LogSketch(entry SketchEntry)

LogSketch adds a sketch entry.

func (*TrafficLogger) LogSketchCapture

func (tl *TrafficLogger) LogSketchCapture(entry SketchCapture)

LogSketchCapture adds a sketch capture entry.

func (*TrafficLogger) Query

func (tl *TrafficLogger) Query(filter LogFilter) []LogEntry

Query retrieves log entries matching the filter in chronological order.

func (*TrafficLogger) Stats

func (tl *TrafficLogger) Stats() LoggerStats

Stats returns logger statistics.

type TruncationWriter

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

TruncationWriter wraps http.ResponseWriter to truncate response body. This simulates partial responses, incomplete downloads, or data loss.

func NewTruncationWriter

func NewTruncationWriter(w http.ResponseWriter, truncatePercent float64, expectedSize int64) *TruncationWriter

NewTruncationWriter creates a new truncation writer

func (*TruncationWriter) BytesWritten

func (tw *TruncationWriter) BytesWritten() int64

BytesWritten returns total bytes written

func (*TruncationWriter) Flush

func (tw *TruncationWriter) Flush()

Flush implements http.Flusher

func (*TruncationWriter) Header

func (tw *TruncationWriter) Header() http.Header

Header returns the header map

func (*TruncationWriter) Hijack

func (tw *TruncationWriter) Hijack() (net.Conn, *bufio.ReadWriter, error)

Hijack implements http.Hijacker

func (*TruncationWriter) IsTruncated

func (tw *TruncationWriter) IsTruncated() bool

IsTruncated returns whether the response was truncated

func (*TruncationWriter) MaxBytes

func (tw *TruncationWriter) MaxBytes() int64

MaxBytes returns the maximum bytes limit

func (*TruncationWriter) Write

func (tw *TruncationWriter) Write(p []byte) (int, error)

Write writes data up to the truncation limit

func (*TruncationWriter) WriteHeader

func (tw *TruncationWriter) WriteHeader(statusCode int)

WriteHeader sends the HTTP response header

type TunnelManager

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

TunnelManager manages a tunnel process alongside a proxy.

func NewTunnelManager

func NewTunnelManager(config *protocol.TunnelConfig, proxyPort int) *TunnelManager

NewTunnelManager creates a new tunnel manager.

func (*TunnelManager) IsRunning

func (tm *TunnelManager) IsRunning() bool

IsRunning returns whether the tunnel is running.

func (*TunnelManager) PublicURL

func (tm *TunnelManager) PublicURL() string

PublicURL returns the detected public URL.

func (*TunnelManager) RecentOutput

func (tm *TunnelManager) RecentOutput() []string

RecentOutput returns recent output lines for debugging.

func (*TunnelManager) Start

func (tm *TunnelManager) Start(ctx context.Context) error

Start starts the tunnel process.

func (*TunnelManager) Stop

func (tm *TunnelManager) Stop() error

Stop stops the tunnel process.

func (*TunnelManager) WaitForURL

func (tm *TunnelManager) WaitForURL(timeout time.Duration) (string, error)

WaitForURL waits for the public URL to be detected with a timeout.

type VoiceSession

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

VoiceSession manages a single voice transcription session between browser and Deepgram.

func NewVoiceSession

func NewVoiceSession(id string, browserConn *websocket.Conn, config DeepgramConfig) (*VoiceSession, error)

NewVoiceSession creates a new voice session and connects to Deepgram.

func (*VoiceSession) Close

func (vs *VoiceSession) Close()

Close terminates the voice session.

func (*VoiceSession) SendAudio

func (vs *VoiceSession) SendAudio(data []byte) error

SendAudio forwards audio data to Deepgram.

type VoiceTranscript

type VoiceTranscript struct {
	Type       string  `json:"type"`
	Transcript string  `json:"transcript"`
	IsFinal    bool    `json:"is_final"`
	Confidence float64 `json:"confidence"`
	Start      float64 `json:"start"`
	Duration   float64 `json:"duration"`
}

VoiceTranscript is sent back to the browser.

Directories

Path Synopsis
Package scripts provides embedded JavaScript for the DevTool proxy instrumentation.
Package scripts provides embedded JavaScript for the DevTool proxy instrumentation.

Jump to

Keyboard shortcuts

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