Types
Every boundary in Autowright is typed. These interfaces live in
@autowright/shared and are the contract between the three layers — the
browser produces them, the service routes them, the fixer consumes them.
ErrorContext
The central type: everything known about one failure. Built by the browser
package on capture, POSTed to the service, and handed to the fixing agent.
Heavy data (DOM, screenshots) is not inlined — it lives in the artifact
bundle referenced by artifacts.
interface ErrorContext { hash: string; // dedup key: scriptId + classification + step + normalized message scriptId: string; timestamp: string; // ISO 8601 classification: ErrorClassification; error: { type: string; // e.g. "TimeoutError", "TypeError" message: string; stack: string; }; step: { name: string; // human-readable, from the page action action: string; // e.g. "click", "fill", "goto" selector?: string; url: string; // page URL at time of error line?: number; // source line if resolvable }; pageState: { url: string; title: string; dom?: string; // only when extracted from the bundle screenshots?: string[]; // only when extracted from the bundle }; browserState: { totalPages: number; cpuPercent: number; memoryUsedMB: number; memoryTotalMB: number; osInfo: string; }; network: NetworkEntry[]; consoleLogs: ConsoleEntry[]; actionLog: ActionEntry[]; tracePath?: string; // if tracing was enabled artifacts?: ArtifactManifest; // where the heavy evidence lives}ErrorClassification
A string-literal union — the label that picks the fix strategy. See Error Classification for how each value is assigned.
type ErrorClassification = | 'SELECTOR_NOT_FOUND' // selector missing or changed | 'SELECTOR_TIMEOUT' // element exists but the action timed out | 'NAVIGATION_FAILED' // page navigation failed | 'NETWORK_TIMEOUT' // request/response timed out | 'NETWORK_ERROR' // DNS, SSL, connection refused | 'CREDENTIALS_INVALID' // login failed, auth rejected | 'DATA_VALIDATION' // unexpected data shape or value | 'BROWSER_CRASH' // browser process died | 'BROWSER_CLOSED' // page/browser intentionally closed mid-action | 'PERMISSION_DENIED' // clipboard, file access, etc. | 'RUNTIME_ERROR' // TypeError, ReferenceError in user code | 'UNKNOWN';Log entries
The rolling buffers the PageObserver keeps during a run:
interface NetworkEntry { timestamp: string; method: string; url: string; status?: number; responseTime?: number; // ms error?: string;}
interface ConsoleEntry { timestamp: string; level: 'log' | 'warn' | 'error' | 'info' | 'debug'; text: string;}
interface ActionEntry { timestamp: string; action: string; selector?: string; params?: Record<string, unknown>; duration?: number; error?: string;}ArtifactManifest
Attached to an ErrorContext after the evidence bundle is uploaded. Only the
URL and an inventory travel through the service — never the bytes. See
Artifacts.
interface ArtifactManifest { bundleUrl: string; // GET this for the .tar.gz bundleSize: number; // bytes uploadedAt: string; // ISO 8601 entries: ArtifactEntry[];}
interface ArtifactEntry { filename: string; sizeBytes: number; type: 'screenshot' | 'dom' | 'network' | 'console' | 'actions' | 'trace' | 'browser-state';}StorageConfig
Where bundles go. S3-compatible for real deployments, local for development without any storage service:
type StorageConfig = S3StorageConfig | LocalStorageConfig;
interface S3StorageConfig { provider: 's3'; endpoint: string; // http://minio:9000 or https://s3.amazonaws.com bucket: string; region?: string; accessKey: string; secretKey: string; forcePathStyle?: boolean; // true for MinIO, false for AWS S3}
interface LocalStorageConfig { provider: 'local'; dir: string; // default: ./autowright-artifacts/}AutowrightConfig
The config block passed to chromium.launch() — documented field-by-field in
Configuration.
Script registration
What the browser sends on launch, and what the service tracks per script:
interface ScriptRegistration { scriptId: string; repoUrl?: string; branch?: string; scriptPath?: string; maxFailures?: number; // reserved metric; Autowright never blocks metadata?: Record<string, string>;}
interface ScriptState { scriptId: string; state: 'active' | 'fixing'; // 'fixing' is transient during a fix failureCount: number; maxFailures: number; lastError?: string; pendingErrors: number; registeredAt: string;}Fix queue
The service’s unit of work and what the fixer reports back:
interface FixQueueItem { id: string; errorContext: ErrorContext; scriptId: string; status: 'pending' | 'in-progress' | 'completed' | 'failed'; createdAt: string; startedAt?: string; completedAt?: string; result?: FixResult;}
interface FixResult { success: boolean; fixType: 'branch' | 'pr'; branchName?: string; prUrl?: string; prNumber?: number; summary: string; // the agent's explanation of the fix filesChanged: string[]; cost?: FixCost;}
interface FixCost { usd: number; // total_cost_usd for this run inputTokens: number; outputTokens: number; cacheReadTokens: number; cacheCreationTokens: number; turns: number; // agent turns durationMs: number; // wall-clock time}FixCost is what powers cost transparency
on the dashboard and in Slack notifications.