/** * Read-only memory lookup for pi-subagents child sessions. * * The full extension also indexes sessions, injects memory policy, runs background review, * consolidation and correction detection, and registers write tools. A delegated child must * not do any of that. This entrypoint registers only `memory_search` and `session_search` over * the parent's database, records no usage hits, and never migrates, backfills or indexes. */ import type { ExtensionAPI } from "@earendil-works/pi-coding-agent"; import { loadConfig } from "./config.js"; import { isDatabaseMigrationPending } from "./extension-root-migration.js"; import { AGENT_ROOT, resolveMemoryRoots } from "./paths.js"; import { DatabaseManager } from "./store/db.js"; import { registerMemorySearchTool } from "./tools/memory-search-tool.js"; import { registerSessionSearchTool } from "./tools/session-search-tool.js"; import type { MemoryConfig } from "./types.js"; export const CHILD_SEARCH_TOOLS = ["memory_search", "session_search"] as const; export interface ChildSearchOptions { /** Defaults to the user's memory config; tests pass their own. */ config?: MemoryConfig; agentRoot?: string; } export default function hermesMemoryChildSearch(pi: ExtensionAPI, options: ChildSearchOptions = {}): void { const config = options.config ?? loadConfig(); const agentRoot = options.agentRoot ?? AGENT_ROOT; const { legacyGlobalDir, globalDir, shouldMigrateExtensionRoot } = resolveMemoryRoots(config.memoryDir, agentRoot); const dbManager = new DatabaseManager(globalDir); // The parent session owns the full-database scan; a child only reads. dbManager.setQuickCheckOnOpen(false); let closed = false; dbManager.setOpenGuard(() => { if (closed) throw new Error("Memory session has shut down"); // Only the parent migrates; opening first would create an empty database in the new root. if (shouldMigrateExtensionRoot && isDatabaseMigrationPending(legacyGlobalDir, globalDir)) { throw new Error("Legacy sessions.db migration is pending; the parent session completes it"); } }); registerSessionSearchTool(pi, dbManager, config.sessionSearch ?? { variant: "legacy" }); registerMemorySearchTool(pi, dbManager, { usageTrackingEnabled: false }); pi.on("session_shutdown", async () => { closed = true; dbManager.close(); }); }