import { z } from 'zod';
import type { EntityParserContract } from './snapshot.js';
import type { OnProgress } from '../../progress-event.js';
import type { CodeFileGuardrails } from '../parsers.js';
import type { LineageState } from './lineage.js';
import type { EntityBounds, EntityCommitRecord, EntityCounters, EntityIndexStatus, EntityRecord, LineageEvent, LineageThresholds } from './types.js';
/**
 * Cache directory, resolved outside the analyzed repository by default.
 *
 * A cache is derived data about a repository, not part of it; writing it into
 * the working tree would show up in `git status` and in every subsequent diff.
 * A caller who wants it there can always say so explicitly.
 */
export { resolveEntityCacheDir } from '../cache-paths.js';
declare const EntityCacheMetaSchema: z.ZodObject<{
    schemaVersion: z.ZodNumber;
    hashVersion: z.ZodNumber;
    occVersion: z.ZodString;
    repoRoot: z.ZodString;
    repoIdentity: z.ZodString;
    optionsFingerprint: z.ZodString;
    indexedHead: z.ZodOptional<z.ZodString>;
    commitCount: z.ZodNumber;
    eventCount: z.ZodNumber;
    lineageCount: z.ZodNumber;
    truncated: z.ZodBoolean;
    builtAt: z.ZodString;
}, z.core.$strip>;
export type EntityCacheMeta = z.infer<typeof EntityCacheMetaSchema>;
export { TRUNCATION_CODES } from './evidence.js';
export interface EntityStoreOptions {
    repoRoot: string;
    /** Defaults to `resolveEntityCacheDir()`. Pass `false` to stay in memory. */
    cacheDir?: string | false;
    head?: string;
    bounds?: EntityBounds;
    thresholds?: LineageThresholds;
    guardrails?: CodeFileGuardrails;
    signal?: AbortSignal;
    onProgress?: OnProgress;
}
/**
 * Whether the persisted index still describes the repository's current head.
 *
 * Deliberately a commit comparison and nothing more: it is what a long-lived
 * caller polls before every request, so it must cost one `rev-parse` and never
 * touch the index bodies.
 */
export interface EntityStoreFreshness {
    fresh: boolean;
    /** The commit the repository is at now, absent in a repository with no commits. */
    head?: string;
    /** The commit the loaded or persisted index covers. */
    indexedHead?: string;
}
/** A loaded lineage index, ready to answer history, blame, and diff questions. */
export interface EntityIndex {
    /**
     * Declaration parser contract that produced every record in this index.
     * Optional so an index value constructed against an earlier OCC release
     * remains assignable; an absent contract means `ENTITY_PARSER_CONTRACT`.
     */
    parserContract?: EntityParserContract;
    status: EntityIndexStatus;
    state: LineageState;
    byPath: Map<string, EntityRecord[]>;
    commits: EntityCommitRecord[];
    events: LineageEvent[];
    eventsByLineage: Map<string, LineageEvent[]>;
    commitBySha: Map<string, EntityCommitRecord>;
    counters: EntityCounters;
}
export interface EntityStore {
    readonly cacheDir: string | undefined;
    /** Build, extend, or reuse the index so it covers the current head. */
    index(options?: {
        signal?: AbortSignal;
        refresh?: boolean;
        onProgress?: OnProgress;
    }): Promise<EntityIndex>;
    /**
     * The persisted entry's metadata without deserializing any of it. Resolves
     * null when there is no cache, or when the entry belongs to another
     * repository, another set of bounds, or another occ version.
     */
    peekMetadata(options?: {
        signal?: AbortSignal;
    }): Promise<EntityCacheMeta | null>;
    /** One `rev-parse` against the head this index covers. Never loads the index. */
    isFresh(options?: {
        signal?: AbortSignal;
    }): Promise<EntityStoreFreshness>;
    clear(): Promise<void>;
    dispose(): void;
}
export declare function openEntityStore(options: EntityStoreOptions): EntityStore;
