/**
 * Asset Import Service — the asset-as-embed core (Phase B).
 *
 * Replaced the old "upload as a self-owning `asset` entity, convert later"
 * flow (the `uploadAsset` primitive + a `convertAsset` orchestrator, both
 * removed in Phase B2/E). An import now:
 *
 *   1. Stores the binary as a FREE-STANDING asset owned by the FOLDER (the
 *      repo), via graph.uploadAsset's `owner` override (Phase A). The blob +
 *      assets.db row belong to the folder, never to any entity — so deleting
 *      the entity that embeds it leaves the asset intact + re-embeddable.
 *   2. Seeds a properly-TYPED graph entity whose BODY embeds the asset, exactly
 *      as a user would type it — the reference lives in the markdown, not the
 *      frontmatter:
 *        image                 → `material`, body `![name](url)` (inline embed)
 *        opaque binary         → `material`, body `[name](url)` (download link)
 *        docx / pdf            → `document`, body = a `[name](url)` source link
 *                                (extraction is lossy) + an "Extracted text"
 *                                heading + the extracted text
 *        xlsx                  → `dataset` × N (pure-CSV body; the CSV is a
 *                                faithful translation so no body reference —
 *                                the source xlsx is invisible `asset_ref`
 *                                provenance in frontmatter, the lone exception)
 *
 * Decisions (see ~/.claude/plans/asset-as-embed.md; body-embed model 2026-06-01):
 *   - NO asset-text sidecar is written. Extraction runs in-memory ONLY to seed
 *     the body, which the vector indexer indexes natively.
 *   - Body embeds point at the FREE-STANDING, folder-owned asset (Phase A/B
 *     storage is unchanged → still delete-safe, re-embeddable, many-to-many).
 *     A broken/missing embed renders as a compact inline note via the editor's
 *     image-render layer (live-preview.ts), NOT detail-page chrome.
 *   - On entity-create failure AFTER the blob is stored, roll back with the same
 *     3-step compensating delete asset-finalize-service uses: delete any created
 *     entity (keepAssets) → delete the blob → delete the index row. (Relaxes to
 *     "leave the folder-owned asset" once Phase D surfaces ownerless assets.)
 *   - xlsx with more than XLSX_SHEET_CAP sheets does NOT fan out — it falls back
 *     to a single `material` (the binary is preserved; no unbounded entity churn).
 *
 *   IMPORT(file, folder)
 *     ├─ store bytes  → {assetId}/{filename}   owner = { folder, repo }
 *     ├─ seed body (in-memory; NO sidecar) — embed/link in the markdown
 *     └─ create typed entity(ies)
 *          image/opaque → material · docx/pdf → document · xlsx → dataset×N
 *   FAIL after store  → delete created entities (keepAssets) → delete blob → delete index row
 */
import type { BaseGraphManager } from '../core/graph.js';
import type { EntityType } from '../core/validation.js';
import type { GitUser } from './git.js';
export interface ImportAssetAsEntityOptions {
    graph: BaseGraphManager;
    /** Original filename from the client. Only the basename is used. */
    filename: string;
    buffer: Buffer;
    /** Repo-relative subfolder for the new entity's .md file(s). */
    folderPath?: string;
    /** Override entity name; defaults to the title-cased filename stem. */
    name?: string;
    user?: GitUser;
    /** Defer the git commit so the caller can batch (multi-file import). */
    skipCommit?: boolean;
    /** Auth user id of the uploader (web). Recorded in assets.db for the
     *  uploader+owner delete rule. Null for CLI/import/agent. */
    uploaderUserId?: string | null;
}
/** One typed entity created by the import (1 for doc/material, N for xlsx). */
export interface ImportedEntity {
    entityId: string;
    entityType: EntityType;
    /** Absolute path of the created `.md` file (for the batched commit). */
    filePath: string;
}
export interface ImportAssetAsEntityResult {
    /** The free-standing asset's immutable storage UUID. */
    assetId: string;
    /** Canonical serving URL for the stored asset. */
    asset_url: string;
    /** Every typed entity created (body embeds the asset; only `dataset` carries
     *  `asset_ref` frontmatter — see seedUnits). */
    entities: ImportedEntity[];
}
/**
 * Import a binary as a typed graph entity that embeds a free-standing,
 * folder-owned asset. Returns the assetId + every created entity. Throws on
 * unsupported extension / empty buffer / unconfigured asset storage, and on
 * entity-create failure (after rolling back the stored blob + index row).
 */
export declare function importAssetAsEntity(opts: ImportAssetAsEntityOptions): Promise<ImportAssetAsEntityResult>;
export interface CreateEntityFromAssetOptions {
    graph: BaseGraphManager;
    /** Immutable id of an EXISTING free-standing asset (assets.db row + blob). */
    assetId: string;
    /** Override entity name; defaults to the asset's stored name / filename stem. */
    name?: string;
    /** Repo-relative subfolder; defaults to the asset's own folder (repo root). */
    folderPath?: string;
    user?: GitUser;
    skipCommit?: boolean;
}
/**
 * The second import "door": create a properly-TYPED entity that embeds an asset
 * ALREADY in the store — by its assetId — instead of fresh bytes. This is what
 * makes deletion reversible: delete an entry, the free-standing asset survives
 * in the manager, and this re-embeds it into a new entry. Same body-seeding as
 * the import door (auto-derived type, re-extracted text for docs/sheets), but
 * NO upload and NO asset-rollback — the asset pre-exists and may be embedded
 * elsewhere, so a create failure only rolls back the new entities.
 *
 * Throws if the asset doesn't exist, storage isn't configured, or the stored
 * bytes can't be read back for extraction.
 */
export declare function createEntityFromAsset(opts: CreateEntityFromAssetOptions): Promise<ImportAssetAsEntityResult>;
