/**
 * Base types and interfaces for asset management
 */
export interface AssetInfo {
    filename: string;
    size: number;
    contentType: string;
    url: string;
    path: string;
    mediaType: 'image' | 'video' | 'audio' | 'document' | 'font' | 'design' | 'archive' | 'data' | 'text' | 'other';
}
/**
 * Assets enumerated across the whole backend with their (type, id) origin
 * parsed out of the storage key. Used by the asset manager to avoid
 * per-entity round-trips.
 */
export interface AssetRecord extends AssetInfo {
    entityType: string;
    entityId: string;
}
export interface AssetBackend {
    /**
     * Upload asset to storage
     */
    upload(key: string, buffer: Buffer, contentType: string): Promise<AssetInfo>;
    /**
     * List assets with a given prefix
     */
    list(prefix: string): Promise<AssetInfo[]>;
    /**
     * List every asset under the backend's root, parsed into
     * `{type}/{id}/{filename}` components. Single round-trip for R2 (via
     * paginated ListObjectsV2), single filesystem walk for local. Used by
     * the asset manager to enumerate without per-entity queries.
     */
    listAll(): Promise<AssetRecord[]>;
    /**
     * Download an object's bytes into a Buffer. Used by server-side consumers
     * that need the actual content (e.g. converting a stored .docx/.xlsx to a
     * derived note/dataset). Throws when the key doesn't exist. Both backends
     * implement it — local reads from disk, R2 issues a GetObject.
     */
    download(key: string): Promise<Buffer>;
    /**
     * Server-side copy from one key to another (no download round-trip).
     * Used by the asset re-key migration and cross-repo transfer-copy.
     * Overwrites the destination if it exists (idempotent re-runs).
     */
    copy(srcKey: string, destKey: string): Promise<void>;
    /**
     * Delete a single asset
     */
    delete(key: string): Promise<void>;
    /**
     * Delete all assets with a given prefix
     */
    deleteAll(prefix: string): Promise<number>;
    /**
     * Check if an asset exists
     */
    exists(key: string): Promise<boolean>;
    /**
     * Generate a short-lived pre-signed URL for a stored object.
     * Implemented by remote backends (R2/S3); local backend leaves this
     * undefined since files are streamed directly by the HTTP server.
     * `method` selects the HTTP verb the URL is signed against.
     */
    getSignedUrl?(key: string, expiresIn?: number, method?: 'GET' | 'HEAD'): Promise<string>;
    /**
     * Generate a short-lived pre-signed URL the *client* can PUT to directly,
     * bypassing the app server. Implemented by remote backends (R2/S3) so
     * external agents can upload large binaries without bytes passing through
     * the API. `contentType` is pinned into the signature so the client must
     * send a matching `Content-Type` header; the returned `headers` map tells
     * the client which headers to set verbatim.
     */
    getSignedPutUrl?(key: string, contentType: string, expiresIn?: number): Promise<{
        uploadUrl: string;
        headers: Record<string, string>;
    }>;
    /**
     * Fetch object metadata without downloading bytes. Returns `null` when
     * the key doesn't exist (matches HEAD 404 semantics). The MCP finalize
     * flow uses this to verify the agent's PUT actually landed AND that the
     * stored `Content-Type` + `Content-Length` match the pre-signed contract
     * before promoting `pending/` → canonical. Remote-only.
     */
    head?(key: string): Promise<{
        contentType: string;
        size: number;
    } | null>;
    /**
     * Bucket-level object-lifecycle rules summarized into a flat list of
     * `{ prefix, expirationDays, enabled }`. Used by the MCP presign flow's
     * boot-time backstop (asset-lifecycle-check) to confirm the operator has
     * configured the `pending/` quarantine rule. `enabled` reflects the S3
     * `Status` field — a disabled rule does not fire even if its prefix and
     * TTL look right, so callers must check `enabled` before treating a rule
     * as covering anything. `null` when the bucket has no lifecycle
     * configuration at all. Remote-only — local FS has no notion of lifecycle.
     */
    getBucketLifecycle?(): Promise<Array<{
        prefix: string | undefined;
        expirationDays: number | undefined;
        enabled: boolean;
    }> | null>;
}
export interface AssetConfig {
    storage: 'local' | 'r2';
    localPath?: string;
    r2Config?: R2Config;
}
export interface R2Config {
    accountId: string;
    bucket: string;
    publicUrl: string;
    accessKeyId: string;
    secretAccessKey: string;
}
/**
 * Content type mappings.
 *
 * TODO(import-refactor): this map + `detectAssetKind` are a second source of
 * truth for per-extension MIME / kind alongside the format registry
 * (`src/core/format-registry.ts`, which owns `mimeTypes`). Folding them into
 * the registry is deferred because it would change observable behavior the
 * P0 parity refactor must preserve (e.g. svg's asset_kind `other`→`image`,
 * tsv's Content-Type `octet-stream`→`text/tab-separated-values`). Until that
 * unification lands, `format-registry.test.ts` guards the two against drift
 * on every shared extension.
 */
export declare const CONTENT_TYPES: Record<string, string>;
/**
 * Detect content type from filename
 */
export declare function detectContentType(filename: string): string;
import type { AssetKind } from '../../core/validation.js';
/**
 * Map a filename to the high-level `asset_kind` written into the asset
 * entity's frontmatter. Drives icon and viewer selection; coarser than
 * MIME so the UI doesn't need to enumerate every format. The kind set
 * is canonical in `ASSET_KINDS` in src/core/validation.ts.
 */
export declare function detectAssetKind(filename: string): AssetKind;
/**
 * Extension set the asset upload route accepts (bare, no leading dot).
 *
 * The format registry (`src/core/format-registry.ts`) is the single source
 * of truth for this set — it owns the canonical disposition of every format.
 * This re-export keeps `isAssetUploadExtension` and the (untouched) agent
 * `import_file` tool working against the same data, with no parallel list to
 * drift. The registry's `assetUploadExtensions()` reproduces the historical
 * membership exactly (including `.csv`, which the agent tool stores as an
 * opaque asset even though the web path writes it as a dataset).
 */
export declare const ASSET_UPLOAD_EXTENSIONS: Set<string>;
export declare function isAssetUploadExtension(filename: string): boolean;
/**
 * Whether an asset row should be vision-captioned for search: a raster IMAGE
 * that is not SVG (SVG stays transitional until sanitize-html is wired). The
 * single predicate the live caption trigger
 * (`VectorService.ensureInitialAssetIndexState`) and the boot/recovery sweep
 * (`asset-index-sweep.ts`) share, so they can't drift on which assets get
 * captioned.
 */
export declare function isCaptionableImage(mediaType: string, filename: string): boolean;
/**
 * Determine media type (the user-facing Library category) from content type,
 * with an extension fallback for octet-stream families. The category is
 * DERIVED at read time wherever it reaches the UI (asset-listing re-computes
 * it from contentType + filename), so refining these rules re-categorizes
 * existing assets with no migration; the stored assets.db `media_type`
 * column remains for internal queries (e.g. the caption sweep's image check).
 */
export declare function getMediaType(contentType: string, filename?: string): AssetInfo['mediaType'];
/**
 * Sanitize a filename for use as a storage key segment.
 *
 * Replaces every character that's not `[a-zA-Z0-9._-]` with `_`. Preserves
 * the extension via the `.` allowlist; preserves common separators (`_` and
 * `-`) so display titles derived from the slug stay readable.
 *
 * NOT a security boundary — `validateFilename()` above is the gate that
 * throws on traversal / hidden / forbidden chars / length. `safeFilename`
 * is the post-validation key builder. Promoted from
 * `asset-sidecar-service.ts` so the MCP presign flow can share it.
 */
export declare function safeFilename(name: string): string;
/**
 * Validate filename for security
 */
export declare function validateFilename(filename: string): void;
/**
 * Build asset key from components
 */
export declare function buildAssetKey(entityType: string, entityId: string, filename: string, keyPrefix?: string): string;
/**
 * Build asset prefix for listing
 */
export declare function buildAssetPrefix(entityType: string, entityId: string, keyPrefix?: string): string;
