/** * Shared Type Definitions for Sweetlink * * These types are used by both the server (server.ts), the browser bridge * (SweetlinkBridge.ts), and the devbar package (GlobalDevBar.ts). */ /** Default WebSocket port for Sweetlink connection */ export declare const DEFAULT_WS_PORT = 9223; /** Port offset from app port to calculate WebSocket port */ export declare const WS_PORT_OFFSET = 6223; /** Maximum ports to try when scanning for matching server */ export declare const MAX_PORT_RETRIES = 10; /** Delay between port scan attempts (ms) */ export declare const PORT_RETRY_DELAY_MS = 100; /** Same-origin WebSocket path used when an app server can proxy Sweetlink. */ export declare const SWEETLINK_WS_PATH = "/__sweetlink"; export interface SweetlinkLocationLike { protocol: string; port: string; host?: string; } export interface SweetlinkRuntimeConfig { appPort?: number | string | null; wsPort?: number | string | null; wsUrl?: string | null; wsPath?: string | null; } export declare function parsePortNumber(value: number | string | null | undefined): number | null; export declare function getDefaultPortForProtocol(protocol: string): number | null; export declare function resolveAppPortFromLocation(location: SweetlinkLocationLike): number; export declare function resolveSweetlinkWsPortForAppPort(appPort: number | null | undefined): number; export declare function resolveSweetlinkWsPortFromLocation(location: SweetlinkLocationLike): number; /** * Read Sweetlink connection hints injected by framework integrations. * * Vite injects `window.__SWEETLINK__`; Next.js exposes the same values through * `NEXT_PUBLIC_SWEETLINK_*` env replacement. Explicit user options should still * take precedence over these hints. */ export declare function getSweetlinkRuntimeConfig(globalValue?: unknown): SweetlinkRuntimeConfig; export declare function resolveAppPortFromRuntimeConfig(location: SweetlinkLocationLike, config: SweetlinkRuntimeConfig): number; export declare function createSameOriginSweetlinkWsUrl(location: SweetlinkLocationLike, path?: string): string | null; export declare function isLocalDevelopmentHostname(hostname: string): boolean; export declare function parseLocalDevelopmentUrl(value: string | null | undefined): URL | null; export declare function isLocalDevelopmentOrigin(origin: string | null | undefined): boolean; export declare function resolveAppPortFromLocalUrl(value: string | null | undefined): number | null; export declare function localOriginMatchesAppPort(origin: string | null | undefined, appPort: number | null | undefined): boolean; /** * Structure for captured console log entries */ export type ConsoleLogLevel = 'log' | 'error' | 'warn' | 'info' | 'debug' | 'trace'; export interface ConsoleLog { level: ConsoleLogLevel; message: string; timestamp: number; stack?: string; source?: string; } /** * Individual command interfaces for the discriminated union. * Each command type declares only the fields it actually uses. */ /** * Optional pass-through for screenshot/refresh sub-protocol. Tightened to a * known shape so the WS contract is no longer an opaque escape hatch. * Add fields here as new options ship; downstream callers that pass * unknown keys will fail to typecheck instead of silently dropping them. */ export interface ScreenshotOptions { /** Capture full page (vs viewport-only). */ fullPage?: boolean; /** Output format. */ format?: 'jpeg' | 'png'; /** JPEG quality 0-100; ignored for PNG. */ quality?: number; /** Device-pixel scale factor. */ scale?: number; /** Whether to include the captured page metadata in the response. */ includeMetadata?: boolean; /** Run an a11y audit after capturing. */ a11y?: boolean; } export interface ScreenshotCommand { type: 'screenshot'; selector?: string; hideDevbar?: boolean; options?: ScreenshotOptions; } export interface QueryDomCommand { type: 'query-dom'; selector?: string; property?: string; } export interface GetLogsCommand { type: 'get-logs'; filter?: string; } export interface ExecJsCommand { type: 'exec-js'; code?: string; } export interface GetNetworkCommand { type: 'get-network'; } export interface BrowserClientReadyCommand { type: 'browser-client-ready'; } /** * Generic "save artifact" variant. * * The optional second type parameter narrows the `data` payload for callers * that have it. Default is `unknown` because the wire protocol delivers * data as JSON — receivers still call the `is*Data` type guards. Producers * (the browser building the message) get full type-checking via the * payload generic. */ export interface SaveCommand { type: T; data?: P; } export type SaveScreenshotCommand = SaveCommand<'save-screenshot', ScreenshotPayload>; export type DesignReviewScreenshotCommand = SaveCommand<'design-review-screenshot', ScreenshotPayload>; export interface CheckApiKeyCommand { type: 'check-api-key'; } export interface ApiKeyStatusCommand { type: 'api-key-status'; } export type SaveOutlineCommand = SaveCommand<'save-outline', MarkdownSavePayload & { outline: unknown[]; }>; export type SaveSchemaCommand = SaveCommand<'save-schema', MarkdownSavePayload & { schema: unknown; }>; export type SaveSettingsCommand = SaveCommand<'save-settings', { settings: Record; }>; export interface LoadSettingsCommand { type: 'load-settings'; } export interface SettingsLoadedCommand { type: 'settings-loaded'; /** * Settings payload as opaque key/value record. Receivers parse it with * the SettingsManager-side validator; the type guarantees a non-string, * non-null payload at compile time but does not constrain the keys * (DevBar's settings shape lives in the consumer package). */ settings?: Record; } export interface SettingsSavedCommand { type: 'settings-saved'; settingsPath?: string; } /** * Generic error variant. Every "X-error" command has the same shape — a * literal `type` discriminator and an optional `error` message — so we * express each one as `ErrorCommand<'X-error'>` instead of declaring six * structurally identical interfaces. Adding a new error variant becomes * a one-line alias. */ export interface ErrorCommand { type: T; error?: string; } export type SettingsErrorCommand = ErrorCommand<'settings-error'>; export interface RefreshOptions { /** Force a full hard reload (bypass cache). */ hard?: boolean; } export interface RefreshCommand { type: 'refresh'; options?: RefreshOptions; } export interface RequestScreenshotCommand { type: 'request-screenshot'; requestId?: string; selector?: string; hideDevbar?: boolean; format?: ScreenshotOptions['format']; quality?: number; scale?: number; includeMetadata?: boolean; options?: ScreenshotOptions; } export interface ScreenshotResponseCommand { type: 'screenshot-response'; requestId?: string; data?: unknown; } export interface LogSubscribeCommand { type: 'log-subscribe'; subscriptionId?: string; filters?: { levels?: ConsoleLogLevel[]; pattern?: string; source?: string; }; } export interface LogUnsubscribeCommand { type: 'log-unsubscribe'; subscriptionId?: string; } export interface LogEventCommand { type: 'log-event'; data?: unknown; } export interface HmrScreenshotCommand { type: 'hmr-screenshot'; data?: unknown; } export interface ChannelSubscribeCommand { type: 'subscribe'; channel?: string; } export interface ChannelUnsubscribeCommand { type: 'unsubscribe'; channel?: string; } export interface ScreenshotSavedCommand { type: 'screenshot-saved'; path?: string; } export interface DesignReviewSavedCommand { type: 'design-review-saved'; reviewPath?: string; } export type DesignReviewErrorCommand = ErrorCommand<'design-review-error'>; export interface OutlineSavedCommand { type: 'outline-saved'; outlinePath?: string; } export type OutlineErrorCommand = ErrorCommand<'outline-error'>; export interface SchemaSavedCommand { type: 'schema-saved'; schemaPath?: string; } export type SchemaErrorCommand = ErrorCommand<'schema-error'>; export type SaveConsoleLogsCommand = SaveCommand<'save-console-logs', MarkdownSavePayload & { logs: unknown[]; }>; export interface ConsoleLogsSavedCommand { type: 'console-logs-saved'; consoleLogsPath?: string; } export type ConsoleLogsErrorCommand = ErrorCommand<'console-logs-error'>; export type SaveA11yCommand = SaveCommand<'save-a11y', MarkdownSavePayload>; export interface A11ySavedCommand { type: 'a11y-saved'; a11yPath?: string; } export type A11yErrorCommand = ErrorCommand<'a11y-error'>; export interface GetSchemaCommand { type: 'get-schema'; } export interface GetOutlineCommand { type: 'get-outline'; } export interface GetA11yCommand { type: 'get-a11y'; forceRefresh?: boolean; } export interface GetVitalsCommand { type: 'get-vitals'; } export interface RecordStartCommand { type: 'record-start'; /** * Optional recording options forwarded browser→daemon over the WS bridge. * Intentionally limited to `label`/`viewport`: the daemon's HTTP API also * accepts `storageState` (a daemon-side auth-replay file path) and `trace`, * but those are CLI/HTTP-only and must NOT be reachable from a browser * origin — the WS proxy allow-lists to these two keys (see * `handleRecordCommand` in `server/index.ts`). */ params?: { label?: string; viewport?: string; }; } export interface RecordStopCommand { type: 'record-stop'; } export interface DemoInitCommand { type: 'demo-init'; data?: { title?: string; }; } export interface DemoScreenshotCommand { type: 'demo-screenshot'; } export interface HifiScreenshotCommand { type: 'hifi-screenshot'; } /** * Commands that can be sent over the Sweetlink WebSocket connection. * * This is a discriminated union on the `type` field. Each variant carries * only the fields that are relevant for that particular command. */ export type SweetlinkCommand = ScreenshotCommand | QueryDomCommand | GetLogsCommand | ExecJsCommand | GetNetworkCommand | BrowserClientReadyCommand | SaveScreenshotCommand | DesignReviewScreenshotCommand | CheckApiKeyCommand | ApiKeyStatusCommand | SaveOutlineCommand | SaveSchemaCommand | SaveSettingsCommand | LoadSettingsCommand | SettingsLoadedCommand | SettingsSavedCommand | SettingsErrorCommand | RefreshCommand | RequestScreenshotCommand | ScreenshotResponseCommand | LogSubscribeCommand | LogUnsubscribeCommand | LogEventCommand | HmrScreenshotCommand | ChannelSubscribeCommand | ChannelUnsubscribeCommand | ScreenshotSavedCommand | DesignReviewSavedCommand | DesignReviewErrorCommand | OutlineSavedCommand | OutlineErrorCommand | SchemaSavedCommand | SchemaErrorCommand | SaveConsoleLogsCommand | ConsoleLogsSavedCommand | ConsoleLogsErrorCommand | GetSchemaCommand | GetOutlineCommand | GetA11yCommand | GetVitalsCommand | SaveA11yCommand | A11ySavedCommand | A11yErrorCommand | RecordStartCommand | RecordStopCommand | DemoInitCommand | DemoScreenshotCommand | HifiScreenshotCommand; /** * Response structure for Sweetlink commands */ export interface SweetlinkResponse { success: boolean; data?: unknown; error?: string; timestamp: number; consoleLogs?: ConsoleLog[]; duration?: number; } /** * Data structure for HMR-triggered screenshots */ export interface HmrScreenshotData { trigger: string; changedFile?: string; screenshot: string; url: string; timestamp: number; sequenceNumber: number; logs: { all: ConsoleLog[]; errors: ConsoleLog[]; warnings: ConsoleLog[]; sinceLastCapture: number; }; hmrMetadata?: { modulesUpdated?: string[]; fullReload?: boolean; updateDuration?: number; }; } /** * Server information sent to browser clients */ export interface ServerInfo { type: 'server-info'; appPort: number | null; wsPort: number; projectDir: string; /** Git branch name (or worktree branch if running inside a git worktree) */ gitBranch?: string; /** Logical app name, e.g. "el-lander" (from portless or package.json name) */ appName?: string; timestamp: number; } /** * Semantic category assigned to an outline node by getSemanticCategory. */ export type OutlineCategory = 'heading' | 'sectioning' | 'landmark' | 'grouping' | 'form' | 'table' | 'list' | 'other'; /** * Node in the document outline tree */ export interface OutlineNode { tagName: string; level: number; text: string; id?: string; children: OutlineNode[]; category?: OutlineCategory; } /** * A single microdata item extracted from the page */ export interface MicrodataItem { type?: string; properties?: Record; } /** * Extracted page schema information */ export interface PageSchema { jsonLd: unknown[]; metaTags: Record; openGraph: Record; twitter: Record; microdata: MicrodataItem[]; } /** * A meta image found on the page (OG, Twitter, favicon, etc.) */ export interface MetaImage { label: string; url: string; size?: string; } /** * A missing recommended meta tag */ export interface MissingTag { tag: string; severity: 'error' | 'warning'; hint: string; } /** * Axe-core violation result (simplified) */ export interface AxeViolation { id: string; impact: 'critical' | 'serious' | 'moderate' | 'minor'; description: string; help: string; helpUrl: string; tags: string[]; nodes: Array<{ html: string; target: string[]; failureSummary?: string; }>; } /** * Axe-core audit result */ export interface AxeResult { violations: AxeViolation[]; passes: Array<{ id: string; description: string; }>; incomplete: AxeViolation[]; inapplicable: Array<{ id: string; }>; timestamp: string; url: string; } /** * Log subscription for streaming logs to CLI clients */ export interface LogSubscription { subscriptionId: string; filters?: { levels?: ConsoleLogLevel[]; pattern?: string; source?: string; }; } /** * Channel subscription for generic event streams */ export interface ChannelSubscription { channel: string; } /** * Check if a value is a valid SweetlinkCommand */ export declare function isSweetlinkCommand(value: unknown): value is SweetlinkCommand; /** * Check if a value is a valid ConsoleLog */ export declare function isConsoleLog(value: unknown): value is ConsoleLog; /** * Check if a value is a valid HmrScreenshotData */ export declare function isHmrScreenshotData(value: unknown): value is HmrScreenshotData; /** * Shared shape for screenshot-like command data (screenshot + url + dimensions + timestamp). * Used by both save-screenshot and design-review-screenshot commands. * * Exported so producers (the browser) can construct typed save commands * instead of passing `data: unknown`. The receiver still calls the * `isScreenshotPayload`-based type guard at runtime — trust between the * browser and the daemon is unidirectional. */ export type ScreenshotPayload = { screenshot: string; url: string; timestamp: number; width: number; height: number; }; /** * Shared shape for markdown-based save commands. */ export type MarkdownSavePayload = { markdown: string; url: string; title: string; timestamp: number; }; /** * Type guard for save-screenshot command data */ export declare function isSaveScreenshotData(value: unknown): value is ScreenshotPayload; /** * Type guard for design-review-screenshot command data */ export declare function isDesignReviewScreenshotData(value: unknown): value is ScreenshotPayload; /** * Type guard for save-outline command data */ export declare function isSaveOutlineData(value: unknown): value is MarkdownSavePayload & { outline: unknown[]; }; /** * Type guard for save-schema command data */ export declare function isSaveSchemaData(value: unknown): value is MarkdownSavePayload & { schema: unknown; }; /** * Type guard for save-console-logs command data */ export declare function isSaveConsoleLogsData(value: unknown): value is MarkdownSavePayload & { logs: unknown[]; }; /** * Type guard for save-a11y command data */ export declare function isSaveA11yData(value: unknown): value is MarkdownSavePayload; /** * Type guard for save-settings command data * Validates minimum required fields for handleSaveSettings */ export declare function isSaveSettingsData(value: unknown): value is { settings: Record; }; /** * Safely extract error message from unknown error type */ export declare function getErrorMessage(error: unknown): string; //# sourceMappingURL=types.d.ts.map