import type { NeotomaApiClient } from "../shared/api_client.js";
export type MirrorKind = "entities" | "relationships" | "sources" | "timeline" | "schemas";
export declare const ALL_MIRROR_KINDS: MirrorKind[];
/**
 * A mirror profile describes a selective, filtered output path for a specific
 * entity_type. Only entities whose snapshot fields satisfy `filter` are written
 * to `output_path`. This prevents personal or cross-project entities from
 * leaking into a git-tracked directory.
 *
 * Safety rule: `allow_git_commit` must be explicitly set to `true` whenever
 * `output_path` is inside a git repository. The rebuild path warns (or errors
 * under `--strict`) when this flag is absent for a git-tracked path.
 */
export interface MirrorProfile {
    /** Unique identifier for this profile, e.g. "neotoma-plans". */
    id: string;
    /** Entity type to match, e.g. "plan". */
    entity_type: string;
    /**
     * Snapshot field equality filter. All entries must match.
     * String value: exact equality. Array value: entity field must equal one of the values.
     * e.g. { repository_name: "neotoma" }
     */
    filter: Record<string, string | string[]>;
    /**
     * Absolute or repo-relative output directory.
     * Files are written as `<output_path>/<slug>.md`.
     */
    output_path: string;
    /**
     * Fields to omit from the rendered markdown. Useful for stripping internal
     * or verbose fields (e.g. "repository_root", "user_id").
     */
    exclude_fields?: string[];
    /**
     * If set, only these snapshot fields are rendered. Mutually exclusive with
     * `exclude_fields`; if both are set, `include_fields` takes precedence.
     */
    include_fields?: string[];
    /**
     * Filename template. Defaults to `{slug}.md`.
     * Supported tokens: {slug}, {entity_id}, {canonical_name}.
     */
    filename_template?: string;
    /**
     * Whether to generate an `index.md` in `output_path` listing all matched
     * entities. Defaults to `true`.
     */
    index_enabled?: boolean;
    /**
     * Explicit opt-in required when `output_path` is inside a git repository.
     * The rebuild warns (or errors with `--strict`) when this is absent and the
     * path is git-tracked.
     */
    allow_git_commit?: boolean;
    /**
     * Controls how the entity is rendered to disk.
     * - "entity" (default): full Neotoma entity markdown via renderEntityMarkdown
     * - "frontmatter_content": YAML frontmatter (selected fields) + markdown body
     * - "content_only": bare markdown body from a single snapshot field
     */
    render_mode?: "entity" | "frontmatter_content" | "content_only";
    /**
     * For render_mode "frontmatter_content": which snapshot fields to include in
     * the YAML frontmatter block. If omitted, all scalar snapshot fields are used.
     */
    frontmatter_fields?: string[];
    /**
     * For render_mode "frontmatter_content" and "content_only": which snapshot
     * field to use as the markdown body. Defaults to "content".
     */
    content_field?: string;
}
export interface MirrorConfig {
    enabled: boolean;
    /** Absolute filesystem path. Defaults to `<dataDir>/mirror`. */
    path: string;
    kinds: MirrorKind[];
    /** Phase 3: optional git history. */
    git_enabled: boolean;
    memory_export: {
        enabled: boolean;
        path: string;
        limit_lines: number;
    };
    /**
     * Optional list of selective output profiles. Each profile writes a filtered
     * subset of entities of a given type to a dedicated directory, independent of
     * the main mirror path. Profiles are processed in addition to (not instead of)
     * the regular mirror when `kinds` includes "entities".
     */
    profiles?: MirrorProfile[];
}
/**
 * Effective mirror config. Priority (low → high):
 *   1. Defaults (disabled, dataDir/mirror, all kinds).
 *   2. `~/.config/neotoma/config.json` → `mirror` key.
 *   3. Environment variables:
 *      - `NEOTOMA_MIRROR_ENABLED=true`
 *      - `NEOTOMA_MIRROR_PATH=/path/to/mirror`
 *      - `NEOTOMA_MIRROR_KINDS=entities,relationships`
 *      - `NEOTOMA_MIRROR_GIT_ENABLED=true`
 *      - `NEOTOMA_MIRROR_MEMORY_EXPORT_ENABLED=true`
 *      - `NEOTOMA_MIRROR_MEMORY_EXPORT_PATH=MEMORY.md`
 *      - `NEOTOMA_MIRROR_MEMORY_EXPORT_LIMIT_LINES=200`
 */
export declare function getMirrorConfig(): MirrorConfig;
export declare function setMirrorConfig(patch: Partial<MirrorConfig>): MirrorConfig;
/**
 * Returns true if the entity's snapshot satisfies every entry in `profile.filter`.
 * A filter value of string means exact equality; an array means "one of".
 */
export declare function profileMatchesEntity(profile: MirrorProfile, entityType: string, snapshot: Record<string, unknown>): boolean;
/**
 * Resolve the output file path for an entity under a profile.
 * Supports filename_template tokens: {slug}, {entity_id}, {canonical_name}.
 */
export declare function profileEntityFilePath(profile: MirrorProfile, entityId: string, canonicalName: string | null | undefined, snapshot?: Record<string, unknown>): string;
/**
 * Applies include_fields / exclude_fields from a profile to a snapshot copy.
 * Returns a new snapshot object with only the desired fields.
 */
export declare function applyProfileFieldFilter(profile: MirrorProfile, snapshot: Record<string, unknown>): Record<string, unknown>;
/**
 * Checks whether a given output_path appears to be inside a git repository.
 * Uses a simple heuristic: walk parent dirs looking for a `.git` entry.
 * Returns the git root if found, null otherwise.
 */
export declare function detectGitRoot(outputPath: string): string | null;
/**
 * Validates a profile's git safety constraint. Returns a warning string when
 * the profile's output_path is inside a git repo but allow_git_commit is not
 * set to true. Returns null when the profile is safe.
 */
export declare function checkProfileGitSafety(profile: MirrorProfile): string | null;
/** Deterministic, URL-safe slug for an entity: `<canonical-slug>-<id-hash>`. */
export declare function entitySlug(entityId: string, canonicalName: string | null | undefined): string;
/** Deterministic, filesystem-safe slug for a relationship key. */
export declare function relationshipSlug(relationshipKey: string, sourceId: string, targetId: string, relationshipType: string): string;
export declare function mirrorPaths(cfg?: MirrorConfig): {
    root: string;
    entities: string;
    relationships: string;
    sources: string;
    timeline: string;
    schemas: string;
    topIndex: string;
};
export interface MirrorEntityRow {
    entity_id: string;
    entity_type: string;
    schema_version: string;
    snapshot: Record<string, unknown>;
    computed_at?: string | null;
    observation_count?: number | null;
    last_observation_at?: string | null;
    provenance?: Record<string, string> | null;
    canonical_name?: string | null;
    user_id?: string | null;
}
export declare function mirrorEntity(entity: MirrorEntityRow, cfg?: MirrorConfig): Promise<void>;
export declare function removeMirrorEntity(entityType: string, entityId: string, canonicalName: string | null | undefined, cfg?: MirrorConfig, entitySnapshot?: Record<string, unknown>): Promise<void>;
export interface MirrorRelationshipRow {
    relationship_key: string;
    relationship_type: string;
    source_entity_id: string;
    target_entity_id: string;
    schema_version?: string;
    snapshot: Record<string, unknown>;
    computed_at?: string | null;
    observation_count?: number | null;
    last_observation_at?: string | null;
    provenance?: Record<string, string> | null;
}
export declare function mirrorRelationship(rel: MirrorRelationshipRow, cfg?: MirrorConfig): Promise<void>;
export declare function removeMirrorRelationship(relationshipKey: string, relationshipType: string, sourceEntityId: string, targetEntityId: string, cfg?: MirrorConfig): Promise<void>;
export interface MirrorSourceRow {
    id: string;
    content_hash: string;
    mime_type: string;
    file_name?: string | null;
    original_filename?: string | null;
    byte_size?: number | null;
    source_type: string;
    source_agent_id?: string | null;
    source_metadata?: Record<string, unknown> | null;
    created_at?: string | null;
    storage_status?: string | null;
}
export declare function mirrorSource(source: MirrorSourceRow, cfg?: MirrorConfig): Promise<void>;
export declare function removeMirrorSource(sourceId: string, cfg?: MirrorConfig): Promise<void>;
export declare function mirrorTimelineDay(date: string, cfg?: MirrorConfig): Promise<void>;
export interface MirrorSchemaRow {
    entity_type: string;
    schema_version: string;
    schema_definition: {
        fields: Record<string, import("./canonical_markdown.js").RenderSchemaFieldDef>;
    };
    active?: boolean;
    created_at?: string;
    metadata?: {
        label?: string;
        description?: string;
        category?: string;
    };
}
export declare function mirrorSchema(schema: MirrorSchemaRow, cfg?: MirrorConfig): Promise<void>;
export declare function removeMirrorSchema(entityType: string, cfg?: MirrorConfig): Promise<void>;
export interface RebuildOptions {
    kind?: MirrorKind | "all";
    entityType?: string;
    entityId?: string;
    clean?: boolean;
    /** If set, only rebuild the profile with this id (skips regular entity mirror). */
    profileId?: string;
    /** When true, emit an error (throw) instead of a warning for git-safety violations. */
    strict?: boolean;
    /**
     * When provided, profile rebuilds fetch entity snapshots from the HTTP API
     * rather than from local SQLite. Required when entity data lives on a remote
     * server rather than the local database.
     */
    apiClient?: NeotomaApiClient;
}
export interface RebuildReport {
    kinds: MirrorKind[];
    counts: Record<MirrorKind, {
        written: number;
        unchanged: number;
        removed: number;
    }>;
    profiles: Record<string, {
        written: number;
        unchanged: number;
        removed: number;
    }>;
}
export declare function rebuildMirror(options?: RebuildOptions): Promise<RebuildReport>;
export interface MirrorStatus {
    enabled: boolean;
    path: string;
    kinds: MirrorKind[];
    git_enabled: boolean;
    counts: Record<MirrorKind, number>;
}
export declare function getMirrorStatus(cfg?: MirrorConfig): Promise<MirrorStatus>;
//# sourceMappingURL=canonical_mirror.d.ts.map