/**
 * Shared repo-asset listing.
 *
 * Builds the list of assets owned by entries in a single repo, merging the two
 * storage schemes (legacy `{type}/{id}/{filename}` blobs surfaced by the
 * backend's listAll, and immutable-keyed assets tracked only in the ownership
 * index). Extracted from the asset-api route so the HTTP endpoints and the MCP
 * `list_assets` tool return an identical shape — including a render-safe
 * `embed` string callers can paste straight into an entry body.
 */
import type { WorkspaceManager } from '../core/workspace-manager.js';
/** Owner kinds that mean "free-standing" — the asset is owned by a folder or
 *  the workspace, not by an entity, so it has no owning markdown file and is
 *  deleted/managed by its assetId rather than an entity coordinate. */
export declare const FREE_STANDING_OWNER_TYPES: Set<string>;
export declare function isFreeStandingOwner(ownerType: string): boolean;
export interface RepoAsset {
    filename: string;
    size: number;
    contentType: string;
    url: string;
    /** Render-safe markdown embed: `![filename](url)`. Paste verbatim. */
    embed: string;
    /** Immutable asset id when the asset is index-tracked; null for legacy blobs. */
    assetId: string | null;
    /** Raw owner kind from the index: an entity type when the asset is embedded
     *  in an entity, or 'folder'/'workspace' when the asset is free-standing
     *  (owned by a folder/workspace, not an entity). Drives free-standing
     *  detection on the client (render + delete-by-assetId routing). */
    ownerType: string;
    entityType: string;
    entityId: string;
    entityName: string;
    mediaType: string;
    /** Owning entity's `created_at` (ISO), or null if absent. For sorting. */
    createdAt: string | null;
}
/**
 * Build the asset list for a single repo. Returns [] if the repo's graph can't
 * be loaded (right for the bulk endpoint; single-repo callers should check
 * repo existence themselves first if they want a 404).
 *
 * Algorithm (works for both local and R2 backends):
 *   1. One listAllAssets() call — single filesystem walk or one paginated S3
 *      ListObjectsV2 request. No HEAD round-trips, no markdown parsing.
 *   2. Resolve each asset's entity markdown path via the graph's file index
 *      (not a `{plural}/{id}.md` guess, which misses root/nested entries).
 *   3. Merge in immutable-keyed assets from the ownership index — these live
 *      under an `{assetId}/` prefix the backend's listAll can't see.
 */
export declare function listRepoAssets(repo: string, workspaceManager: WorkspaceManager): Promise<RepoAsset[]>;
/** A `RepoAsset` tagged with the folder (repo) that owns it. */
export type WorkspaceAsset = RepoAsset & {
    repo: string;
};
/** Drop the cached legacy-bucket walk(s) (tests; post-delete/cleanup refresh). */
export declare function clearLegacyBucketCache(): void;
/**
 * List assets across MANY repos for the workspace-wide manager — index-first.
 *
 * The fast path is the local ownership index (`assets.db`): one cheap scan per
 * repo yields every immutable-keyed asset with no network I/O. On top of that we
 * fold in any surviving *legacy* blobs via the cached bucket walk above (see
 * `getLegacyBucketSnapshot`) so un-migrated assets still appear. Dedup prefers
 * the immutable entry, so a legacy blob that has already been migrated collapses
 * into its index row rather than double-listing.
 *
 * A legacy blob whose owning entity exists in K accessible repos surfaces under
 * each of those K (entity ids can — rarely — collide across folders), matching
 * the old per-repo behaviour.
 */
export declare function listWorkspaceAssets(repos: string[], workspaceManager: WorkspaceManager): Promise<WorkspaceAsset[]>;
