/** * Asset System - Fast-path preview architecture * * Assets are files produced by workers with metadata for instant preview. * The preview-worker generates thumbnails/metadata WITHOUT using the LLM. */ export interface AssetManifest { /** Unique asset ID (content-addressed) */ id: string; /** Absolute path to the file (INTERNAL ONLY - never send to client) */ path: string; /** Filename */ name: string; /** MIME type */ mime: string; /** SHA256 content hash for caching */ sha256: string; /** File size in bytes */ size: number; /** Creation timestamp */ createdAt: number; /** Worker/run group ID for grouping related assets */ groupId?: string; /** Label for the asset (old, new, diff, etc.) */ label?: 'old' | 'new' | 'diff' | 'output' | 'source'; /** Asset kind */ kind: 'file' | 'view'; /** For kind=view, the ViewSpec */ viewSpec?: ViewSpec; } /** * Client-safe asset manifest - no absolute paths exposed */ export interface ClientAssetManifest { id: string; name: string; mime: string; sha256: string; size: number; createdAt: number; groupId?: string; label?: 'old' | 'new' | 'diff' | 'output' | 'source'; kind: 'file' | 'view'; viewSpec?: ViewSpec; } /** * Convert internal manifest to client-safe version (strips path) */ export declare function toClientManifest(manifest: AssetManifest): ClientAssetManifest; /** * Validate that a resolved path is within an allowed root (prevents traversal/symlink escapes) */ export declare function isPathWithinRoot(filePath: string, rootDir: string): boolean; export interface AssetPreview { /** Reference to the asset */ assetId: string; /** Thumbnail path (for images/PDFs) */ thumbnailPath?: string; /** Thumbnail as base64 data URL (for inline display) */ thumbnailData?: string; /** Extracted text snippet (first ~500 chars) */ textSnippet?: string; /** Image dimensions */ dimensions?: { width: number; height: number; }; /** PDF page count */ pageCount?: number; /** Additional metadata */ metadata?: Record; /** When preview was generated */ generatedAt: number; /** Cache key: sha256 + transform params */ cacheKey: string; } export interface ViewSpec { /** View ID */ id: string; /** Display title */ title: string; /** Layout type */ layout: 'single' | 'grid' | 'twoColumn' | 'compare' | 'stack' | 'tabs'; /** Items in the view */ items?: ViewItem[]; /** For twoColumn layout */ left?: ViewItem[]; right?: ViewItem[]; /** For compare layout */ before?: ViewItem; after?: ViewItem; /** Optional description */ description?: string; /** Created timestamp */ createdAt: number; } export interface ViewItem { /** Item type */ type: 'asset' | 'markdown' | 'text' | 'html'; /** For type=asset, the asset ID */ assetId?: string; /** For type=markdown/text/html, the content */ content?: string; /** Viewer to use */ viewer?: 'image' | 'pdf' | 'code' | 'markdown' | 'text' | 'video' | 'audio'; /** Viewer params (overlays, annotations, etc.) */ params?: ViewerParams; /** Optional label */ label?: string; } export interface ViewerParams { /** Scale bar overlay for microscopy images */ overlay?: 'scaleBar' | 'grid' | 'ruler'; /** Brightness adjustment (-100 to 100) */ brightness?: number; /** Contrast adjustment (-100 to 100) */ contrast?: number; /** Crop region */ crop?: { x: number; y: number; width: number; height: number; }; /** Zoom level */ zoom?: number; /** Highlight lines (for code) */ highlightLines?: number[]; /** Annotations */ annotations?: Annotation[]; } export interface Annotation { type: 'box' | 'circle' | 'arrow' | 'text'; x: number; y: number; width?: number; height?: number; label?: string; color?: string; } /** * Generate SHA256 hash of file contents */ export declare function hashFile(filePath: string): string; /** * Get MIME type from file extension */ export declare function getMimeType(filePath: string): string; /** * Generate deterministic asset ID from content hash + relative path * Content-addressed: same file always gets same ID */ export declare function generateAssetId(sha256: string, relativePath?: string): string; /** * Create asset manifest for a file * @param rootDir - Root directory for computing relative path (for ID stability) */ export declare function createAssetManifest(filePath: string, options?: { groupId?: string; label?: AssetManifest['label']; rootDir?: string; }): AssetManifest; /** * Write asset manifest alongside the file */ export declare function writeAssetManifest(manifest: AssetManifest): void; /** * Read asset manifest for a file */ export declare function readAssetManifest(filePath: string): AssetManifest | null; /** * Get preview cache directory */ export declare function getPreviewCacheDir(): string; /** * Generate cache key for preview * Uses canonical stringify for stable key generation regardless of key order */ export declare function getPreviewCacheKey(sha256: string, params?: ViewerParams): string; /** * Check if preview exists in cache */ export declare function getPreviewFromCache(cacheKey: string): AssetPreview | null; /** * Save preview to cache */ export declare function savePreviewToCache(preview: AssetPreview): void; /** * Create a ViewSpec for comparing two assets */ export declare function createCompareView(beforeAssetId: string, afterAssetId: string, title?: string): ViewSpec; /** * Create a ViewSpec for a grid of assets */ export declare function createGridView(assetIds: string[], title?: string): ViewSpec; /** * Create a ViewSpec for a report with markdown and assets */ export declare function createReportView(title: string, sections: Array<{ markdown?: string; assetId?: string; label?: string; }>): ViewSpec;