import type { Drawer, Tunnel, KGTriple, Scope, WingMeta, RoomMeta, SearchOptions, SearchHit } from './types.js';
/** ~/.grawkus/memory/store.json — cross-project knowledge */
export declare function globalStorePath(): string;
/** <cwd>/.grawkus/memory/store.json — per-repo knowledge */
export declare function projectStorePath(cwd: string): string;
/**
 * Time-ordered ID: hex timestamp + 8 random hex chars. Sorts naturally by
 * creation time, no UUID library needed. ~96 bits of entropy total which
 * is overkill for a single-user store but keeps collision chances at
 * effective zero even across machines.
 */
export declare function newId(prefix: string): string;
/**
 * A single-file MemPalace store backed by JSON. Mutations are immediately
 * persisted to disk — there's no in-memory cache to flush. Trades a small
 * amount of throughput for crash safety, which matters more for a memory
 * system.
 */
export declare class JsonStore {
    private readonly path;
    readonly scope: Scope;
    constructor(path: string, scope: Scope);
    private read;
    private write;
    addDrawer(input: Omit<Drawer, 'id' | 'createdAt' | 'updatedAt' | 'scope'>): Drawer;
    getDrawer(id: string): Drawer | null;
    updateDrawer(id: string, patch: Partial<Omit<Drawer, 'id' | 'createdAt' | 'scope'>>): Drawer | null;
    deleteDrawer(id: string): boolean;
    listDrawers(filter?: {
        wing?: string;
        room?: string;
        tag?: string;
    }): Drawer[];
    listWings(): WingMeta[];
    listRooms(wing?: string): RoomMeta[];
    addTunnel(fromDrawerId: string, toDrawerId: string, relation: string): Tunnel;
    /**
     * Find all tunnels touching a drawer, in either direction. Useful for
     * "what is this drawer related to?" queries.
     */
    findTunnels(drawerId: string): {
        outgoing: Tunnel[];
        incoming: Tunnel[];
    };
    /**
     * Walk outgoing tunnels from a start drawer for up to maxDepth hops,
     * returning every drawer reached and the path that got us there.
     * Bounded by visited-set so cycles don't loop forever.
     */
    traverse(startId: string, maxDepth?: number): {
        drawer: Drawer;
        depth: number;
        via: string[];
    }[];
    deleteTunnel(id: string): boolean;
    addTriple(t: Omit<KGTriple, 'id' | 'createdAt' | 'scope'>): KGTriple;
    /**
     * Query triples with optional s/p/o filters. Any field left undefined
     * acts as a wildcard. Matching is case-insensitive equality on each
     * specified field.
     *
     * If `asOf` is provided (ISO string), only triples whose validity
     * interval CONTAINS asOf are returned. Semantics:
     *   include if (validFrom undefined OR validFrom <= asOf)
     *           AND (validTo   undefined OR validTo   >  asOf)
     *
     * If `asOf` is omitted, "current" facts are returned (validTo undef).
     * Pass `asOf: 'all'` to return everything regardless of temporal state.
     */
    queryTriples(q: {
        subject?: string;
        predicate?: string;
        object?: string;
        asOf?: string | 'all';
    }): KGTriple[];
    /**
     * Invalidate a triple by id — sets validTo to now (or a caller-
     * supplied ISO timestamp). The triple is preserved in the store so
     * historical queries (asOf in the past) still find it; "current"
     * queries (asOf default) will exclude it.
     */
    invalidateTriple(id: string, endedAt?: string): KGTriple | null;
    /** Most-recent triples first. For "what have I been learning?" views. */
    recentTriples(limit?: number): KGTriple[];
    search(query: string, opts?: SearchOptions): SearchHit[];
    stats(): {
        drawers: number;
        tunnels: number;
        triples: number;
        wings: number;
        rooms: number;
    };
}
