export type SiteSourceKind = 'static' | 'proxy'; export interface SiteStaticSource { kind: 'static'; /** Absolute filesystem root of the static site directory. */ rootDir: string; /** Workspace root captured at creation for re-validation. */ workspaceRoot: string; /** Workspace-relative POSIX path for display. */ workspaceRelativePath: string; /** Send index.html (status 200) for unmatched paths under root (SPA). */ spaFallback: boolean; /** Whether HTML/CSS absolute-path rewriting is applied. */ rewriteMode: 'none' | 'html-only' | 'html-css'; /** Regex string matched against URL path; matches get an immutable cache. */ immutableAssetsRegex?: string; } export interface SiteProxySource { kind: 'proxy'; /** Upstream base URL (e.g. http://127.0.0.1:3000). */ upstreamUrl: string; /** Forward Set-Cookie path attribute (subpath mode only). */ rewriteSetCookiePath: boolean; /** Whether to handle WebSocket upgrades. */ forwardWebSocket: boolean; /** Per-request forwarded headers strategy. */ forwardedHeaders: 'minimal' | 'full'; } export type SiteSource = SiteStaticSource | SiteProxySource; export interface SiteShareRecord { id: string; /** Token used both as the URL subdomain label (subdomain mode) and as `/site/:token/` subpath fallback. */ token: string; /** Optional creator-chosen subdomain (must be unique, only [a-z0-9-]). */ subdomain: string | null; source: SiteSource; createdAt: string; expiresAt: string; revoked: boolean; description?: string; createdByTokenHash: string; requestCount: number; uniqueClientCount: number; /** Hard cap on total requests served (null = unlimited). */ maxRequests: number | null; /** Cached client IPs that have counted toward uniqueClientCount (last 200). */ recentClientIps?: string[]; /** Thumbnail generation status (parallels ShareRecord). */ thumbnailStatus?: 'pending' | 'ready' | 'failed'; thumbnailGeneratedAt?: string; thumbnailFailedAt?: string; } export interface SiteShareStoreData { version: 1; shares: SiteShareRecord[]; } export interface CreateSiteShareParams { /** 'static' uses workspace path; 'proxy' uses upstreamUrl. */ kind: SiteSourceKind; /** Static: workspace-relative path of build output. */ path?: string; /** Proxy: full upstream URL (must be loopback or whitelisted). */ upstreamUrl?: string; /** Default 24h. */ ttlMs?: number; /** Optional friendly description. */ description?: string; /** Optional preferred subdomain (will fall back to token if taken). */ subdomain?: string; /** Optional max request count. */ maxRequests?: number | null; /** Static: SPA fallback (default true for static). */ spaFallback?: boolean; /** Static: rewrite mode (default 'none'). */ rewriteMode?: 'none' | 'html-only' | 'html-css'; /** Proxy: forward WS (default true if enabled in config). */ forwardWebSocket?: boolean; sessionKey?: string; agentId?: string; } export interface SiteShareConfig { enabled: boolean; publicHostSuffix: string; defaultTtlMs: number; maxTtlMs: number; maxActiveSites: number; static: { enabled: boolean; maxRootDirSize: number; maxFileCount: number; rewriteEnabledByDefault: boolean; }; proxy: { enabled: boolean; allowedUpstreamHosts: string[]; allowedUpstreamPorts: number[]; forwardWebSocket: boolean; bodySizeLimit: number; requestTimeoutMs: number; wsIdleTimeoutMs: number; rewriteSetCookiePath: boolean; }; } export declare const SITE_SHARE_CONFIG_DEFAULTS: SiteShareConfig;