import { type Embedder, type MemoryNoteHeader, type MemoryNoteRecord, type MemoryStore, type MemoryVectorMode, type ScoredMemory, type StructuredNoteInput } from "../../core/memory.js"; export declare class FileMemoryStore implements MemoryStore { private readonly root; private readonly tmpDir; /** Optional injected embedder (design/81 Slice 5). When present, note bodies are embedded (in the background, * after the durable note write) into a rebuildable sidecar index and `searchScored` ranks by cosine distance * (portable / in-process, mirrors PgMemoryStore's jsonb mode). Absent ⇒ lexical, byte-identical to before. */ private readonly embedder?; /** ms budget for a background embed; a slower/stuck endpoint yields no vector (row stays lexical), never * blocking the durable note write (which already completed). */ private readonly embedTimeoutMs; /** In-flight background embeds (so tests can flush + `close` can drain). */ private readonly pending; private readonly scopes; /** Set by {@link close}: a background embed that resolves AFTER close must NOT writeSync to the (now closed) * vlog fd — a stray write on a recycled fd could corrupt an unrelated file. */ private closed; constructor(root: string, opts?: { embedder?: Embedder; embedTimeoutMs?: number; }); /** design/81 Slice 5 rung: `portable` (in-process cosine over the sidecar) when an embedder is injected, * else `lexical`. File never reaches `native` (no backend index). */ get vectorMode(): MemoryVectorMode; /** True when an embedder was injected. Exposed so a consumer/test can confirm it was accepted. */ get hasEmbedder(): boolean; /** Await all in-flight background embeds (tests / `close`). */ flushEmbeds(): Promise; /** Open (replay) a scope's notes + sidecar vectors once and cache it. */ private scopeState; /** Queue a background embed of `body` → sidecar vector for `id` (best-effort, timeout-bounded, non-blocking). * Only when an embedder is injected; a failure/timeout leaves the row lexical (fail-open). The durable note * write has ALREADY happened before this is called, so this never gates durability. */ private queueEmbed; /** Rewrite the derived `MEMORY.md` projection atomically (CC markdown parity). */ private writeProjection; read(scope: string): string | null; append(scope: string, note: string): string | void; appendStructured(scope: string, note: StructuredNoteInput): string; /** Append + fsync the note event BEFORE updating the in-memory list, then refresh the projection. */ private commit; clear(scope: string): void; /** design/84 Seam B: read the cached periodic-consolidation cursor (replayed from the last `op:cursor`). */ getConsolidationCursor(scope: string): string | undefined; /** design/84 Seam B: persist the periodic-consolidation cursor via a durable `op:cursor` append-log event, * then update the cached state (durable FIRST, like `commit`). */ setConsolidationCursor(scope: string, cursor: string): void; /** * Keyword search backing the `recall` tool. design/81 Slice 2b — uses the SHARED synonym/stem-aware * {@link import("../../core/memory.js").lexicalSearchMatch} (the SAME matcher as * {@link import("../../core/memory.js").InMemoryMemoryStore.search}, ZERO model/native/embedder dep) so * "auth token" matches a note saying "credentials" / "bearer", and the `recall` tool returns IDENTICAL * results across the File and InMemory backends. A bullet matches a query term iff it contains ANY of that * term's expansions, and must match EVERY query term (AND across terms, OR within a term's synonyms). With * no synonym/stem hit this is byte-identical to the plain substring filter. */ search(scope: string, query: string, limit?: number): string[]; /** Manifest (design/65 §2.2): a header per note, body excluded — in-memory parity. */ listStructuredNotes(scope: string): MemoryNoteHeader[]; getByIds(scope: string, ids: string[]): MemoryNoteRecord[]; /** * Id-addressable similarity retrieval (design/81 Slice 2 — the consolidation candidate source). The * `score` is a cosine **DISTANCE** ∈ [0,2], **0 = identical** ({@link ScoredMemory} contract): it is the * lexical `1 - Jaccard(terms)` ∈ [0,1] ⊂ [0,2] stand-in (byte-identical to * {@link InMemoryMemoryStore.searchScored} / the lexical {@link import("../pg.js").PgMemoryStore} fallback), * so the `{0.05, 0.3}` consolidation band needs no retune. An injected embedder is ACCEPTED but vector * ranking is the DEFERRED Slice 5 — so this method ALWAYS uses the lexical distance for now (an injected * embedder is harmless, NOT a throw). Excludes the query's own id (a note must not self-match — see below) * and zero-overlap entries; returns the `limit` nearest, ascending by distance. * * **Self-id exclusion:** byte-identical to {@link InMemoryMemoryStore.searchScored} / the lexical * {@link import("../pg.js").PgMemoryStore} fallback, the SOLE consumer (consolidation) excludes the * query note's own id (and its sibling this-task ids) by filtering the returned `ScoredMemory[]` on its * `thisTaskIds` set — keeping the store's ranking pure and the cross-backend contract identical. */ searchScored(scope: string, query: string, limit?: number): ScoredMemory[] | Promise; /** * Consolidation UPDATE (design/81 Slice 2): replace a note's body by id, keeping the id stable. Appends a * durable `update` event FIRST, then mutates the in-memory replay + refreshes the projection — same * durable-before-visible order as {@link commit}. An auto-derived description is re-derived from the new * body (so the manifest doesn't drift); an explicit one is preserved (design/65 [79], in-memory parity). * Unknown id → no-op (defensive). NB: no `sanitizeUntrustedText` here — the fence lives at the * inlets/recall, NOT in `update` (design/81 §1; in-memory `update` only trims). */ update(scope: string, id: string, text: string): void; /** * Consolidation DELETE (design/81 Slice 2): remove a note by id (id never reused afterward). Appends a * durable `delete` tombstone FIRST, then drops it from the in-memory replay + refreshes the projection. * Unknown id → no-op. */ delete(scope: string, id: string): void; /** Release all open scope handles (best-effort). */ close(): void; } //# sourceMappingURL=memory-store.d.ts.map