/**
 * Content-addressed attachment storage for CLEO tasks.db.
 *
 * Blobs are stored on disk at:
 *   `.cleo/attachments/sha256/<sha256[0..2]>/<sha256[2..]>.<ext>`
 *
 * The SQLite `attachments` + `attachment_refs` tables (tasks.db) act as the
 * registry and ref-count ledger.  Two `put` calls with identical bytes produce
 * one row and one file — the ref-count increments rather than duplicating.
 *
 * This module has NO dependency on the `llmtxt` npm package — it uses Node's
 * built-in `crypto.createHash('sha256')` for hashing and plain `node:fs`
 * for storage.
 *
 * @epic T760
 * @task T796
 */
import type { Attachment, AttachmentMetadata, AttachmentRef } from '@cleocode/contracts';
/**
 * Error thrown when a retrieved blob's SHA-256 hash does not match
 * the expected value stored in metadata.
 *
 * This indicates possible disk corruption or that the wrong file
 * was stored at the expected path.
 */
export declare class AttachmentIntegrityError extends Error {
    readonly expectedSha256: string;
    readonly actualSha256: string;
    readonly path: string;
    /**
     * @param expectedSha256 - The SHA-256 stored in the attachment metadata
     * @param actualSha256   - The SHA-256 computed from the retrieved bytes
     * @param path           - The file path where the mismatch was detected
     */
    constructor(expectedSha256: string, actualSha256: string, path: string);
}
/**
 * Discriminated union for the result of a `deref` operation.
 */
export type DerefResult = {
    status: 'not-found';
} | {
    status: 'derefd';
    refCountAfter: number;
} | {
    status: 'removed';
};
/**
 * Content-addressed attachment store backed by tasks.db + the filesystem.
 *
 * All methods accept an optional `cwd` parameter for path resolution — the
 * same convention used throughout `@cleocode/core`.
 */
export interface AttachmentStore {
    /**
     * Store bytes and register the attachment in tasks.db.
     *
     * If an attachment with the same SHA-256 already exists, the existing row is
     * returned unchanged (content-addressed deduplication).  A new
     * `attachment_refs` row is created for each call so that the caller's owning
     * entity receives its own ref even when the blob is shared.
     *
     * @param bytes      - Content to store (Buffer or UTF-8 string)
     * @param attachment - Attachment descriptor **without** `sha256` pre-filled
     * @param ownerType  - Entity type for the initial ref (e.g., `"task"`)
     * @param ownerId    - Entity ID for the initial ref (e.g., `"T766"`)
     * @param attachedBy - Optional agent identity that created the ref
     * @param cwd        - Optional working directory for path resolution
     * @returns Resolved {@link AttachmentMetadata} (with `sha256` and `id` set)
     */
    put(bytes: Buffer | string, attachment: Omit<Attachment, 'sha256'>, ownerType: AttachmentRef['ownerType'], ownerId: string, attachedBy?: string, cwd?: string): Promise<AttachmentMetadata>;
    /**
     * Retrieve a blob's bytes and metadata by SHA-256 hash.
     *
     * @param sha256 - 64-character hex SHA-256 digest
     * @param cwd    - Optional working directory for path resolution
     * @returns `{ bytes, metadata }` or `null` if not found
     */
    get(sha256: string, cwd?: string): Promise<{
        bytes: Buffer;
        metadata: AttachmentMetadata;
    } | null>;
    /**
     * Retrieve attachment metadata by attachment ID.
     *
     * @param attachmentId - The `att_<...>` or UUID attachment ID
     * @param cwd          - Optional working directory for path resolution
     * @returns {@link AttachmentMetadata} or `null` if not found
     */
    getMetadata(attachmentId: string, cwd?: string): Promise<AttachmentMetadata | null>;
    /**
     * List all attachments associated with a given owner entity.
     *
     * @param ownerType - Entity type (e.g., `"task"`)
     * @param ownerId   - Entity ID (e.g., `"T766"`)
     * @param cwd       - Optional working directory for path resolution
     * @returns Array of {@link AttachmentMetadata} (may be empty)
     */
    listByOwner(ownerType: string, ownerId: string, cwd?: string): Promise<AttachmentMetadata[]>;
    /**
     * Create an `attachment_refs` row linking an attachment to an owner.
     *
     * Also increments `attachments.ref_count`.
     *
     * @param attachmentId - ID of the attachment to reference
     * @param ownerType    - Entity type for the ref
     * @param ownerId      - Entity ID for the ref
     * @param attachedBy   - Optional agent identity
     * @param cwd          - Optional working directory for path resolution
     */
    ref(attachmentId: string, ownerType: AttachmentRef['ownerType'], ownerId: string, attachedBy?: string, cwd?: string): Promise<void>;
    /**
     * Remove an `attachment_refs` row and decrement `attachments.ref_count`.
     *
     * When `ref_count` reaches zero the blob file is deleted from disk and the
     * `attachments` row is removed.
     *
     * @param attachmentId - ID of the attachment to dereference
     * @param ownerType    - Entity type of the ref to remove
     * @param ownerId      - Entity ID of the ref to remove
     * @param cwd          - Optional working directory for path resolution
     * @returns Discriminated union:
     *   - `{ status: 'not-found' }` if the attachment does not exist
     *   - `{ status: 'derefd', refCountAfter: N }` when refCount decreased but blob remains
     *   - `{ status: 'removed' }` when the blob was purged (refCount → 0)
     */
    deref(attachmentId: string, ownerType: string, ownerId: string, cwd?: string): Promise<DerefResult>;
}
/**
 * Create a concrete {@link AttachmentStore} instance.
 *
 * The store is stateless — each method opens the tasks.db singleton via
 * `getDb(cwd)` for consistency with the rest of `@cleocode/core`.
 *
 * @example
 * ```ts
 * const store = createAttachmentStore();
 * const meta = await store.put(
 *   Buffer.from('# Hello'),
 *   { kind: 'blob', storageKey: '', mime: 'text/markdown', size: 7 },
 *   'task', 'T796',
 * );
 * ```
 */
export declare function createAttachmentStore(): AttachmentStore;
//# sourceMappingURL=attachment-store.d.ts.map