/** * Cross-agent shared memory for Hippo. * Global store is shared across all projects. * Resolution: $HIPPO_HOME > $XDG_DATA_HOME/hippo > ~/.hippo/ * Local .hippo/ stores are per-project. */ import { MemoryEntry } from './memory.js'; import { SearchResult } from './search.js'; /** * Returns the path to the global Hippo store. * Resolution order: $HIPPO_HOME > $XDG_DATA_HOME/hippo > ~/.hippo/ */ export declare function getGlobalRoot(): string; /** * Ensure the global store exists. */ export declare function initGlobal(): void; /** * Copy a local memory entry to the global store. * Assigns a new ID (prefixed with 'g_') to avoid collisions. * Returns the new global entry. */ export declare function promoteToGlobal(localRoot: string, id: string, opts?: { actor?: string; tenantId?: string; }): MemoryEntry; export interface SearchOptions { budget?: number; now?: Date; minResults?: number; /** Tenant scope for both stores. Undefined = no filter (legacy single-tenant). */ tenantId?: string; } /** * Search across both local and global stores, merging results. * Local results are boosted by 1.2x to prefer project-specific context. * Returns results sorted by adjusted score, within combined token budget. */ export declare function searchBoth(query: string, localRoot: string, globalRoot: string, options?: SearchOptions): SearchResult[]; export interface HybridSearchOptions extends SearchOptions { embeddingWeight?: number; explain?: boolean; mmr?: boolean; mmrLambda?: number; /** Multiplier applied to local-store scores when merging with global. * Defaults to 1.2. Use 1.0 to remove the local bias for eval comparisons. */ localBump?: number; /** Active scope for scope-boost scoring. Auto-detected if not provided. */ scope?: string | null; /** Include superseded memories in results. Default false. */ includeSuperseded?: boolean; /** Filter to memories current at this ISO date string. */ asOf?: string; /** v0.30 / E4 — propagated to underlying hybridSearch calls. * Per-call > env HIPPO_SUMMARY_DEBOOST > 0.85 default. */ summaryDeboost?: number; /** v0.30 / E4 — propagated. Default true (1.05 boost if rebuilt within 7d). */ summaryFreshness?: boolean; /** v39 memory scope isolation: optional admission predicate applied to the * loaded candidate entries of BOTH stores BEFORE ranking, cross-store * content-dedupe, and budgeting. Without it, an excluded row can shadow * its admitted duplicate in the dedupe pass, or saturate the budget. * Default undefined = unchanged behavior (recall paths never set it). */ entryFilter?: (entry: MemoryEntry) => boolean; /** v1.25.0 — recall-mode scope filter, consumed by `searchBothHybrid` only. * ABSENT (undefined) is the only unfiltered mode: both stores load via * `loadSearchEntries` unchanged (background pipelines / eval callers). * PRESENT switches the internal loads to `loadRecallSearchEntries` (SQL * scope predicate) plus the recall-scope JS post-filter: * `{}` = default-deny (`unknown:legacy` * + `:private:*` excluded) * `{ requested: 'X' }` = exact match on scope X * (api.recall semantics) * `{ requested: 'X', additive: true }` = default-admitted set PLUS * scope X (CLI --scope * semantics; see recall-scope.ts * passesCliRecallScopeFilter) * Object form on purpose — the sibling `scope` option above already gives * `null` a different meaning (boost-neutral), so a flat `string | null` * here would overload null with contradictory semantics. Do NOT pass an * empty object casually from non-recall paths. */ recallScope?: { requested?: string; additive?: boolean; }; } /** * Hybrid search across both local and global stores, using embeddings when available. * Async version of searchBoth that calls hybridSearch instead of search. */ export declare function searchBothHybrid(query: string, localRoot: string, globalRoot: string, options?: HybridSearchOptions): Promise; /** * Estimate how well a memory would transfer to other projects. * Returns 0..1 where >0.5 = good candidate for sharing. */ export declare function transferScore(entry: MemoryEntry): number; /** * Share a memory to the global store with attribution. * Enriches the source field with project path and timestamp. * Returns the new global entry, or null if transfer score is too low. */ export declare function shareMemory(localRoot: string, id: string, options?: { force?: boolean; tenantId?: string; skipEmbed?: boolean; }): MemoryEntry | null; /** * List all projects that have contributed memories to the global store. * Parses the source field for 'shared::' or 'promoted:' patterns. * * D4 v1.12.10: `tenantId` is now optional. When provided, the global entries * are filtered to that tenant before aggregation — matches every other * read path's default-safe behaviour. When undefined, host-wide (back-compat * for legacy callers like CLI standalone + dashboard internal use). Operators * who genuinely want cross-tenant peer discovery can pass undefined or * use direct SQL. */ export declare function listPeers(globalRoot?: string, tenantId?: string): Array<{ project: string; count: number; latest: string; }>; /** * Auto-share: find local memories with high transfer scores that aren't already global. * Returns the list of shared entries. * * L9: `options.tenantId` is opt-in. When provided, the LOCAL-entries read is * scoped to that tenant. When undefined, the local read is host-wide (current * behaviour). The GLOBAL-entries read is always unioned — the global root IS * the cross-tenant aggregate by design. The only intentional unscoped * internal caller as of v1.12.1 is `api.sleep` (`src/api.ts:2041`), which * passes options without tenantId because `sleep` is host-wide by intent; * see `src/api.ts:2073-2077` for the cross-tenant dedup rationale. * * v1.25.0: `options.stats` is an opt-in out-param. When provided, * `stats.secretSkipped` is incremented once per row that passed every OTHER * admission gate (transfer score, not-already-global) and was withheld SOLELY * by the secret veto — i.e. it counts shares actually prevented, not secret * rows merely present. Filled identically under `dryRun`. * * AT1: `stats.rejectedSkipped` (optional) is incremented once per candidate * refused by the GLOBAL store's rejection tombstone (RejectedValueError from * shareMemory -> writeEntry). Unlike secretSkipped, this can only be * detected by attempting the write — `dryRun` returns candidates before the * write loop runs, so `rejectedSkipped` stays at its initial value under * `dryRun` (candidates that WOULD be refused are not distinguished in the * dry-run preview). */ export declare function autoShare(localRoot: string, options?: { minScore?: number; dryRun?: boolean; tenantId?: string; stats?: { secretSkipped: number; rejectedSkipped?: number; }; }): MemoryEntry[]; /** * Copy all global memories into the local store. * Skips entries that already exist locally (by ID or by near-identical content). * Returns the count of newly copied entries. */ export declare function syncGlobalToLocal(localRoot: string, globalRoot: string, opts?: { includeCrossProject?: boolean; }): number; //# sourceMappingURL=shared.d.ts.map