@edihasaj/recall 0.5.7 → 0.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (35) hide show
  1. package/dist/{chunk-K5FZ47NN.js → chunk-7XCLKPJ3.js} +6 -8
  2. package/dist/{chunk-K5FZ47NN.js.map → chunk-7XCLKPJ3.js.map} +1 -1
  3. package/dist/{chunk-A5UIRZU6.js → chunk-A6XEULA4.js} +3 -2
  4. package/dist/chunk-A6XEULA4.js.map +1 -0
  5. package/dist/{chunk-F56Y3SHS.js → chunk-E4HJDGCW.js} +7 -9
  6. package/dist/{chunk-F56Y3SHS.js.map → chunk-E4HJDGCW.js.map} +1 -1
  7. package/dist/{chunk-IILLSHLM.js → chunk-KAGIAOD7.js} +2583 -84
  8. package/dist/chunk-KAGIAOD7.js.map +1 -0
  9. package/dist/{chunk-FHKV6ELT.js → chunk-MJ4GGBTL.js} +11 -13
  10. package/dist/{chunk-FHKV6ELT.js.map → chunk-MJ4GGBTL.js.map} +1 -1
  11. package/dist/{chunk-LVQW6WHK.js → chunk-XUM7JEJU.js} +2 -2
  12. package/dist/{cleanup-TVOX2S2S.js → cleanup-MYSQ44EP.js} +4 -4
  13. package/dist/cli.js +206 -33
  14. package/dist/cli.js.map +1 -1
  15. package/dist/daemon.js +60 -49
  16. package/dist/daemon.js.map +1 -1
  17. package/dist/dispatcher-SUUX5AX6.js +16 -0
  18. package/dist/mcp.js +5 -5
  19. package/dist/{quality-Z7LPMMBC.js → quality-YTQKAEY6.js} +3 -3
  20. package/dist/{tasks-UOLSPXJQ.js → tasks-GSQUHD4F.js} +6 -3
  21. package/dist/{usage-CY3V72YN.js → usage-DU4TKVJH.js} +2 -2
  22. package/package.json +1 -1
  23. package/dist/chunk-A5UIRZU6.js.map +0 -1
  24. package/dist/chunk-GC5XMBG4.js +0 -551
  25. package/dist/chunk-GC5XMBG4.js.map +0 -1
  26. package/dist/chunk-IILLSHLM.js.map +0 -1
  27. package/dist/chunk-VEPXEHRZ.js +0 -1763
  28. package/dist/chunk-VEPXEHRZ.js.map +0 -1
  29. package/dist/dispatcher-UGMU6THT.js +0 -15
  30. /package/dist/{chunk-LVQW6WHK.js.map → chunk-XUM7JEJU.js.map} +0 -0
  31. /package/dist/{cleanup-TVOX2S2S.js.map → cleanup-MYSQ44EP.js.map} +0 -0
  32. /package/dist/{dispatcher-UGMU6THT.js.map → dispatcher-SUUX5AX6.js.map} +0 -0
  33. /package/dist/{quality-Z7LPMMBC.js.map → quality-YTQKAEY6.js.map} +0 -0
  34. /package/dist/{tasks-UOLSPXJQ.js.map → tasks-GSQUHD4F.js.map} +0 -0
  35. /package/dist/{usage-CY3V72YN.js.map → usage-DU4TKVJH.js.map} +0 -0
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/daemon.ts","../src/maintenance/lifecycle.ts","../src/maintenance/logging.ts","../src/mcp/http.ts"],"sourcesContent":["import { createServer } from \"node:http\";\nimport type { RecallDb } from \"./db/client.js\";\nimport { compileContext, compileContextHybrid } from \"./compiler/context.js\";\nimport { processCorrection, processReviewFeedback } from \"./capture/correction.js\";\nimport {\n confirmMemory,\n rejectMemory,\n queryMemories,\n recordFeedback,\n getMemory,\n} from \"./models/memory.js\";\nimport { scanAndStore } from \"./scanner/repo.js\";\nimport { computeMetrics, formatMetricsReport, startEvalSession, endEvalSession, incrementEvalCounter } from \"./eval/harness.js\";\nimport { recordSignal, getSignalStats, recordTestSignals, runTests } from \"./feedback/implicit.js\";\nimport { createPolicy, listPolicies, evaluatePolicy, requestApproval, resolveApproval, listPendingApprovals } from \"./policy/engine.js\";\nimport { computeHealthScore, computeAllHealthScores } from \"./health/scoring.js\";\nimport { detectContradictions, resolveContradiction, autoResolveContradictions, listContradictions } from \"./contradictions/detector.js\";\nimport { pruneMemories } from \"./pruning/pruner.js\";\nimport { getAuditTrail, getRecentAudit, rollbackMemory } from \"./audit/trail.js\";\nimport { getRepoQualityProfile } from \"./repo/quality.js\";\nimport { createActivityEvent, listActivityEvents, listActivitySessions } from \"./models/activity.js\";\nimport { ensureRepoBootstrapped, inferRepoSlugFromPath } from \"./repo/discovery.js\";\nimport { ensureEmbeddingProviderReady, getEmbeddingModelInfo, loadEmbeddingConfigFromEnv } from \"./embeddings/embeddings.js\";\nimport {\n endSessionLifecycle,\n recordSessionLifecycleEvent,\n startSessionLifecycle,\n} from \"./session/lifecycle.js\";\nimport { writeRepoContextArtifact } from \"./artifacts/context.js\";\nimport { loadMaintenanceConfigFromEnv, runMaintenanceCycle } from \"./maintenance/lifecycle.js\";\nimport { formatMaintenanceSummary, shouldLogMaintenance } from \"./maintenance/logging.js\";\nimport { dispatchPendingTasks } from \"./maintenance/dispatcher.js\";\nimport { runDeterministicCleanup } from \"./maintenance/cleanup.js\";\nimport { computeQualityReport, listQualitySnapshots, recordQualitySnapshot } from \"./maintenance/quality.js\";\nimport { hasProviderConfigured } from \"./credentials/keychain.js\";\nimport { initDb } from \"./db/client.js\";\nimport { ensureDailyBackup } from \"./backups/snapshot.js\";\nimport { handleRecallMcpHttpRequest } from \"./mcp/http.js\";\nimport {\n handlePromptHook,\n handleSessionEndHook,\n handleSessionStartHook,\n handleToolHook,\n} from \"./cli/hook.js\";\n\nlet db: RecallDb;\nconst PORT = parseInt(process.env.RECALL_PORT ?? \"7890\", 10);\nconst maintenanceConfig = loadMaintenanceConfigFromEnv();\nlet maintenanceRunning = false;\n\nconst dispatcherConfig = {\n enabled: process.env.RECALL_DISPATCHER_ENABLED !== \"false\",\n intervalSeconds: parseInt(process.env.RECALL_DISPATCHER_INTERVAL_SECONDS ?? \"86400\", 10),\n maxTasksPerRun: parseInt(process.env.RECALL_DISPATCHER_MAX_TASKS_PER_RUN ?? \"5\", 10),\n};\nlet dispatcherRunning = false;\n\nconst cleanupConfig = {\n enabled: process.env.RECALL_CLEANUP_ENABLED !== \"false\",\n intervalSeconds: parseInt(process.env.RECALL_CLEANUP_INTERVAL_SECONDS ?? \"86400\", 10),\n};\nlet cleanupRunning = false;\n\nconst qualitySnapshotConfig = {\n enabled: process.env.RECALL_QUALITY_SNAPSHOT_ENABLED !== \"false\",\n intervalSeconds: parseInt(process.env.RECALL_QUALITY_SNAPSHOT_INTERVAL_SECONDS ?? \"604800\", 10),\n};\nlet qualitySnapshotRunning = false;\n\nfunction parseBody(req: import(\"node:http\").IncomingMessage): Promise<any> {\n return new Promise((resolve, reject) => {\n const chunks: Buffer[] = [];\n req.on(\"data\", (c: Buffer) => chunks.push(c));\n req.on(\"end\", () => {\n try {\n resolve(JSON.parse(Buffer.concat(chunks).toString()));\n } catch {\n resolve({});\n }\n });\n req.on(\"error\", reject);\n });\n}\n\nfunction resolveRepo(body: Record<string, any>): string | undefined {\n return body.repo ?? inferRepoSlugFromPath(body.repo_path) ?? undefined;\n}\n\nfunction scheduleMaintenanceLoop() {\n if (!maintenanceConfig.enabled) return;\n\n const run = async () => {\n if (maintenanceRunning) return;\n maintenanceRunning = true;\n try {\n const result = await runMaintenanceCycle(db, maintenanceConfig);\n if (shouldLogMaintenance(result)) {\n console.log(formatMaintenanceSummary(result));\n }\n } catch (error) {\n const message = error instanceof Error ? error.stack ?? error.message : String(error);\n console.error(`[recall] maintenance failed: ${message}`);\n } finally {\n maintenanceRunning = false;\n }\n };\n\n const intervalMs = Math.max(30, maintenanceConfig.interval_seconds) * 1000;\n // Defer first run so startup health checks can succeed before embedding\n // verification or history refresh work can occupy the event loop.\n setTimeout(() => void run(), intervalMs).unref?.();\n const timer = setInterval(() => {\n void run();\n }, intervalMs);\n timer.unref?.();\n}\n\nlet dispatcherDormantLogged = false;\nfunction scheduleDispatcherLoop() {\n if (!dispatcherConfig.enabled) return;\n\n const run = async () => {\n if (dispatcherRunning) return;\n // Skip if no provider is currently configured — picked up again next tick.\n const hasKey =\n hasProviderConfigured(\"anthropic\") ||\n hasProviderConfigured(\"azure-openai\") ||\n hasProviderConfigured(\"openai\");\n if (!hasKey) {\n if (!dispatcherDormantLogged) {\n console.log(\"[recall] dispatcher dormant: no LLM provider configured (set one via 'recall maintenance credentials set <provider> <key>'; preview prompts via 'recall maintenance dispatch --preview')\");\n dispatcherDormantLogged = true;\n }\n return;\n }\n dispatcherDormantLogged = false;\n\n dispatcherRunning = true;\n try {\n const report = await dispatchPendingTasks(db, {\n maxTasks: dispatcherConfig.maxTasksPerRun,\n });\n if (report.attempted > 0 || report.applied > 0) {\n console.log(\n `[recall] dispatcher ${report.provider}: attempted=${report.attempted} applied=${report.applied} rejected=${report.rejected} released=${report.released}`,\n );\n }\n } catch (error) {\n const message = error instanceof Error ? error.stack ?? error.message : String(error);\n console.error(`[recall] dispatcher failed: ${message}`);\n } finally {\n dispatcherRunning = false;\n }\n };\n\n const timer = setInterval(() => {\n void run();\n }, Math.max(60, dispatcherConfig.intervalSeconds) * 1000);\n timer.unref?.();\n}\n\nfunction scheduleCleanupLoop() {\n if (!cleanupConfig.enabled) return;\n\n const run = async () => {\n if (cleanupRunning) return;\n cleanupRunning = true;\n try {\n const report = runDeterministicCleanup(db, { dryRun: false });\n const c = report.counts;\n const total =\n c.dedupe_clusters +\n c.fragment_rejections +\n c.repeat_promotions +\n c.command_suppressions +\n c.globalizations;\n if (total > 0) {\n console.log(\n `[recall] cleanup run=${report.run_id.slice(0, 8)} merges=${c.dedupe_clusters}/${c.dedupe_losers} fragments=${c.fragment_rejections} promotions=${c.repeat_promotions} suppress=${c.command_suppressions} globalize=${c.globalizations}/${c.globalize_losers}`,\n );\n }\n // Surface logical conflicts after each tick. Cheap (O(n²) over active\n // memories) and lets users see \"Use pnpm\" vs \"Use bun\" before the\n // model gets the contradictory pair injected.\n const newContradictions = detectContradictions(db);\n if (newContradictions.length > 0) {\n console.log(\n `[recall] contradictions detected: ${newContradictions.length} new pair(s)`,\n );\n for (const c of newContradictions.slice(0, 5)) {\n console.log(` [${c.severity}] ${c.contradiction_type}: ${c.description.slice(0, 120)}`);\n }\n }\n } catch (error) {\n const message = error instanceof Error ? error.stack ?? error.message : String(error);\n console.error(`[recall] cleanup failed: ${message}`);\n } finally {\n cleanupRunning = false;\n }\n };\n\n // Defer the first run so we don't fight startup migrations.\n setTimeout(() => void run(), 30_000).unref?.();\n const timer = setInterval(() => {\n void run();\n }, Math.max(60, cleanupConfig.intervalSeconds) * 1000);\n timer.unref?.();\n}\n\nfunction scheduleQualitySnapshotLoop() {\n if (!qualitySnapshotConfig.enabled) return;\n\n const intervalMs = Math.max(60, qualitySnapshotConfig.intervalSeconds) * 1000;\n\n const run = () => {\n if (qualitySnapshotRunning) return;\n qualitySnapshotRunning = true;\n try {\n // Only snapshot if the most recent snapshot is older than the interval.\n const last = listQualitySnapshots(db, 1)[0];\n if (last) {\n const ageMs = Date.now() - new Date(last.taken_at).getTime();\n if (ageMs < intervalMs) return;\n }\n const report = computeQualityReport(db);\n const row = recordQualitySnapshot(db, report, \"auto\");\n console.log(\n `[recall] quality snapshot ${row.id.slice(0, 8)} followed=${row.followed_rate_resolved != null ? (row.followed_rate_resolved * 100).toFixed(1) + \"%\" : \"n/a\"} resolved=${row.injections_resolved} history=${row.history_injections_total} rules=${row.active_rule_count} cand=${row.candidate_correction_count}`,\n );\n } catch (error) {\n const message = error instanceof Error ? error.stack ?? error.message : String(error);\n console.error(`[recall] quality snapshot failed: ${message}`);\n } finally {\n qualitySnapshotRunning = false;\n }\n };\n\n setTimeout(run, 60_000).unref?.();\n // Re-check hourly; the age gate keeps actual writes weekly.\n const timer = setInterval(run, 3600 * 1000);\n timer.unref?.();\n}\n\nconst server = createServer(async (req, res) => {\n const url = new URL(req.url ?? \"/\", `http://localhost:${PORT}`);\n const path = url.pathname;\n const method = req.method ?? \"GET\";\n\n // CORS for browser extension\n res.setHeader(\"Access-Control-Allow-Origin\", \"*\");\n res.setHeader(\"Access-Control-Allow-Methods\", \"GET, POST, DELETE, OPTIONS\");\n res.setHeader(\n \"Access-Control-Allow-Headers\",\n \"Content-Type, Authorization, MCP-Protocol-Version, MCP-Session-Id, Last-Event-ID\",\n );\n\n if (method === \"OPTIONS\") {\n res.statusCode = 204;\n res.end();\n return;\n }\n\n try {\n if (path === \"/mcp\") {\n return await handleRecallMcpHttpRequest(req, res, db);\n }\n\n res.setHeader(\"Content-Type\", \"application/json\");\n\n // Health\n if (path === \"/health\" && method === \"GET\") {\n return send(res, 200, {\n status: \"ok\",\n version: \"0.5.0\",\n embeddings: getEmbeddingModelInfo(),\n });\n }\n\n // Compile context (hook injection endpoint)\n if (path === \"/compile\" && method === \"POST\") {\n const body = await parseBody(req);\n const repo = resolveRepo(body);\n if (!repo) return send(res, 400, { error: \"repo or repo_path required\" });\n\n const bootstrap = ensureRepoBootstrapped(db, {\n repo,\n repoPathHint: body.repo_path,\n });\n if (bootstrap.status === \"bootstrapped\" || bootstrap.status === \"scanned_empty\") {\n createActivityEvent(db, {\n session_id: body.session_id ?? null,\n repo,\n source: \"daemon\",\n event_type: \"scan\",\n memory_ids: bootstrap.created_ids,\n request: {\n repo_path: bootstrap.repo_path,\n trigger: \"compile_auto_bootstrap\",\n },\n result: {\n created: bootstrap.created_ids.length,\n status: bootstrap.status,\n },\n });\n }\n\n const result = body.query_text || body.config?.include_candidates\n ? await compileContextHybrid(db, {\n repo,\n path: body.path,\n session_id: body.session_id,\n query_text: body.query_text,\n config: body.config,\n })\n : compileContext(db, {\n repo,\n path: body.path,\n session_id: body.session_id,\n config: body.config,\n });\n createActivityEvent(db, {\n session_id: body.session_id ?? null,\n repo,\n path: body.path ?? null,\n source: \"daemon\",\n event_type: \"compile\",\n memory_ids: result.memories_included,\n request: {\n config: body.config ?? {},\n query_text: body.query_text ?? null,\n bootstrap_status: bootstrap.status,\n },\n result: {\n included: result.memories_included,\n dropped: result.memories_dropped,\n history_included: result.history_included,\n token_estimate: result.token_estimate,\n repo_path: bootstrap.repo_path,\n },\n });\n return send(res, 200, {\n ...result,\n repo,\n repo_path: bootstrap.repo_path ?? body.repo_path ?? null,\n bootstrap_status: bootstrap.status,\n });\n }\n\n // Session start\n if (path === \"/session/start\" && method === \"POST\") {\n const body = await parseBody(req);\n if (!body.session_id) {\n return send(res, 400, { error: \"session_id required\" });\n }\n const result = startSessionLifecycle(db, {\n session_id: body.session_id,\n client: body.client ?? null,\n repo: body.repo ?? null,\n repo_path: body.repo_path ?? null,\n path: body.path ?? null,\n meta: body.meta ?? {},\n });\n return send(res, 200, result);\n }\n\n // Session event\n if (path === \"/session/event\" && method === \"POST\") {\n const body = await parseBody(req);\n if (!body.session_id || !body.name) {\n return send(res, 400, { error: \"session_id and name required\" });\n }\n const result = recordSessionLifecycleEvent(db, {\n session_id: body.session_id,\n client: body.client ?? null,\n repo: body.repo ?? null,\n repo_path: body.repo_path ?? null,\n path: body.path ?? null,\n meta: body.meta ?? {},\n name: body.name,\n payload: body.payload ?? {},\n });\n return send(res, 200, result);\n }\n\n // Session end\n if (path === \"/session/end\" && method === \"POST\") {\n const body = await parseBody(req);\n if (!body.session_id) {\n return send(res, 400, { error: \"session_id required\" });\n }\n const result = endSessionLifecycle(db, {\n session_id: body.session_id,\n client: body.client ?? null,\n repo: body.repo ?? null,\n repo_path: body.repo_path ?? null,\n path: body.path ?? null,\n meta: body.meta ?? {},\n payload: body.payload ?? {},\n });\n return send(res, 200, result);\n }\n\n // Hook prompt\n if (path === \"/hook/prompt\" && method === \"POST\") {\n const body = await parseBody(req);\n if (!body.text) {\n return send(res, 400, { error: \"text required\" });\n }\n const result = await handlePromptHook(body, {\n db,\n source: \"daemon\",\n });\n return send(res, 200, { ...result, transport: \"daemon\" });\n }\n\n // Hook tool\n if (path === \"/hook/tool\" && method === \"POST\") {\n const body = await parseBody(req);\n if (!body.name || typeof body.exit_code !== \"number\") {\n return send(res, 400, { error: \"name and numeric exit_code required\" });\n }\n const result = await handleToolHook(body, {\n db,\n source: \"daemon\",\n });\n return send(res, 200, { ...result, transport: \"daemon\" });\n }\n\n // Hook session start\n if (path === \"/hook/session-start\" && method === \"POST\") {\n const body = await parseBody(req);\n if (!body.session_id || !body.agent) {\n return send(res, 400, { error: \"session_id and agent required\" });\n }\n const result = await handleSessionStartHook(body, {\n db,\n source: \"daemon\",\n });\n return send(res, 200, { ...result, transport: \"daemon\" });\n }\n\n // Hook session end\n if (path === \"/hook/session-end\" && method === \"POST\") {\n const body = await parseBody(req);\n if (!body.session_id) {\n return send(res, 400, { error: \"session_id required\" });\n }\n const result = await handleSessionEndHook(body, {\n db,\n source: \"daemon\",\n });\n return send(res, 200, { ...result, transport: \"daemon\" });\n }\n\n // Report correction\n if (path === \"/correct\" && method === \"POST\") {\n const body = await parseBody(req);\n const repo = resolveRepo(body);\n const ids = await processCorrection(db, body.text, {\n sessionId: body.session_id ?? \"hook\",\n repo,\n path: body.path,\n });\n createActivityEvent(db, {\n session_id: body.session_id ?? \"hook\",\n repo: repo ?? null,\n path: body.path ?? null,\n source: \"daemon\",\n event_type: \"correction\",\n memory_ids: ids,\n request: { text: body.text },\n result: { created: ids },\n });\n return send(res, 200, { created: ids });\n }\n\n // Report review feedback\n if (path === \"/review\" && method === \"POST\") {\n const body = await parseBody(req);\n const repo = resolveRepo(body);\n const ids = await processReviewFeedback(db, body.feedback, {\n sessionId: body.session_id ?? \"hook-review\",\n repo,\n path: body.path,\n reviewer: body.reviewer,\n });\n createActivityEvent(db, {\n session_id: body.session_id ?? \"hook-review\",\n repo: repo ?? null,\n path: body.path ?? null,\n source: \"daemon\",\n event_type: \"review\",\n memory_ids: ids,\n request: { feedback: body.feedback, reviewer: body.reviewer ?? null },\n result: { created: ids },\n });\n return send(res, 200, { created: ids });\n }\n\n // Confirm memory\n if (path === \"/confirm\" && method === \"POST\") {\n const body = await parseBody(req);\n const ok = confirmMemory(db, body.memory_id);\n return send(res, ok ? 200 : 404, { success: ok });\n }\n\n // Reject memory\n if (path === \"/reject\" && method === \"POST\") {\n const body = await parseBody(req);\n const ok = rejectMemory(db, body.memory_id);\n return send(res, ok ? 200 : 404, { success: ok });\n }\n\n // Record feedback\n if (path === \"/feedback\" && method === \"POST\") {\n const body = await parseBody(req);\n const id = recordFeedback(\n db,\n body.memory_id,\n body.session_id,\n body.injected,\n body.outcome,\n );\n createActivityEvent(db, {\n session_id: body.session_id,\n source: \"daemon\",\n event_type: \"feedback\",\n memory_ids: [body.memory_id],\n request: { injected: body.injected, outcome: body.outcome },\n result: { feedback_id: id },\n });\n return send(res, 200, { feedback_id: id });\n }\n\n // List memories\n if (path === \"/memories\" && method === \"GET\") {\n const repo = url.searchParams.get(\"repo\") ?? undefined;\n const status = url.searchParams.get(\"status\") as any;\n const limit = url.searchParams.get(\"limit\");\n const offset = url.searchParams.get(\"offset\");\n const items = queryMemories(db, {\n repo,\n status,\n limit: limit ? parseInt(limit, 10) : undefined,\n offset: offset ? parseInt(offset, 10) : undefined,\n });\n return send(res, 200, { memories: items });\n }\n\n // Get single memory\n if (path.startsWith(\"/memory/\") && method === \"GET\") {\n const id = path.slice(\"/memory/\".length);\n const mem = getMemory(db, id);\n if (!mem) return send(res, 404, { error: \"not found\" });\n return send(res, 200, mem);\n }\n\n // Scan repo\n if (path === \"/scan\" && method === \"POST\") {\n const body = await parseBody(req);\n const ids = scanAndStore(db, body.repo_path);\n const mem = ids[0] ? getMemory(db, ids[0]) : undefined;\n const artifact = writeRepoContextArtifact(db, {\n repo: mem?.repo ?? null,\n repo_path: body.repo_path,\n });\n createActivityEvent(db, {\n session_id: body.session_id ?? null,\n repo: mem?.repo ?? null,\n source: \"daemon\",\n event_type: \"scan\",\n memory_ids: ids,\n request: { repo_path: body.repo_path },\n result: {\n created: ids.length,\n artifact_path: artifact.output_path,\n artifact_written: artifact.written,\n },\n });\n return send(res, 200, {\n created: ids,\n count: ids.length,\n artifact_path: artifact.output_path,\n artifact_written: artifact.written,\n });\n }\n\n // --- Phase 2 endpoints ---\n\n // Eval metrics\n if (path === \"/eval/metrics\" && method === \"GET\") {\n const repo = url.searchParams.get(\"repo\") ?? undefined;\n const since = url.searchParams.get(\"since\") ?? undefined;\n const metrics = computeMetrics(db, { repo, since });\n return send(res, 200, metrics);\n }\n\n // Eval session start\n if (path === \"/eval/start\" && method === \"POST\") {\n const body = await parseBody(req);\n const id = startEvalSession(db, body.repo);\n return send(res, 200, { session_id: id });\n }\n\n // Eval session end\n if (path === \"/eval/end\" && method === \"POST\") {\n const body = await parseBody(req);\n endEvalSession(db, body.session_id);\n return send(res, 200, { success: true });\n }\n\n // Eval counter increment\n if (path === \"/eval/increment\" && method === \"POST\") {\n const body = await parseBody(req);\n incrementEvalCounter(db, body.session_id, body.field, body.amount ?? 1);\n return send(res, 200, { success: true });\n }\n\n // Record implicit signal\n if (path === \"/signal\" && method === \"POST\") {\n const body = await parseBody(req);\n const id = recordSignal(\n db,\n body.memory_id,\n body.session_id ?? \"daemon\",\n body.signal_type,\n body.context,\n );\n const mem = getMemory(db, body.memory_id);\n createActivityEvent(db, {\n session_id: body.session_id ?? \"daemon\",\n repo: mem?.repo ?? null,\n path: mem?.path_scope ?? null,\n source: \"daemon\",\n event_type: \"signal\",\n memory_ids: [body.memory_id],\n request: { signal_type: body.signal_type, context: body.context ?? null },\n result: { signal_id: id },\n });\n return send(res, 200, { signal_id: id });\n }\n\n // Signal stats\n if (path.startsWith(\"/signal/stats/\") && method === \"GET\") {\n const memId = path.slice(\"/signal/stats/\".length);\n const stats = getSignalStats(db, memId);\n return send(res, 200, stats);\n }\n\n // Run tests + record signals\n if (path === \"/test\" && method === \"POST\") {\n const body = await parseBody(req);\n const testResult = runTests(body.repo_path, body.command);\n const signalIds = recordTestSignals(\n db,\n body.session_id ?? \"daemon\",\n body.memory_ids ?? [],\n testResult,\n );\n return send(res, 200, {\n passed: testResult.passed,\n signals: signalIds,\n output: testResult.output?.slice(0, 1000),\n });\n }\n\n // Quality profile\n if (path === \"/quality\" && method === \"GET\") {\n const repo = url.searchParams.get(\"repo\") ?? undefined;\n return send(res, 200, getRepoQualityProfile(db, repo));\n }\n\n if (path === \"/activity\" && method === \"GET\") {\n const repo = url.searchParams.get(\"repo\") ?? undefined;\n const session_id = url.searchParams.get(\"session_id\") ?? undefined;\n const source = url.searchParams.get(\"source\") as any;\n const event_type = url.searchParams.get(\"event_type\") as any;\n const since = url.searchParams.get(\"since\") ?? undefined;\n const limit = parseInt(url.searchParams.get(\"limit\") ?? \"20\", 10);\n return send(res, 200, {\n events: listActivityEvents(db, { repo, session_id, source, event_type, since, limit }),\n });\n }\n\n if (path === \"/sessions\" && method === \"GET\") {\n const repo = url.searchParams.get(\"repo\") ?? undefined;\n const source = url.searchParams.get(\"source\") as any;\n const event_type = url.searchParams.get(\"event_type\") as any;\n const since = url.searchParams.get(\"since\") ?? undefined;\n const limit = parseInt(url.searchParams.get(\"limit\") ?? \"20\", 10);\n return send(res, 200, {\n sessions: listActivitySessions(db, { repo, source, event_type, since, limit }),\n });\n }\n\n // --- Phase 3 endpoints ---\n\n // Policy: list\n if (path === \"/policy/list\" && method === \"GET\") {\n const orgId = url.searchParams.get(\"org_id\") ?? \"\";\n return send(res, 200, { policies: listPolicies(db, orgId) });\n }\n\n // Policy: create\n if (path === \"/policy\" && method === \"POST\") {\n const body = await parseBody(req);\n const id = createPolicy(db, body.org_id, body.rule_type, body.config);\n return send(res, 200, { policy_id: id });\n }\n\n // Policy: evaluate\n if (path === \"/policy/check\" && method === \"POST\") {\n const body = await parseBody(req);\n const mem = getMemory(db, body.memory_id);\n if (!mem) return send(res, 404, { error: \"memory not found\" });\n const violations = evaluatePolicy(db, body.org_id, mem);\n return send(res, 200, { violations });\n }\n\n // Approval: request\n if (path === \"/approval/request\" && method === \"POST\") {\n const body = await parseBody(req);\n const id = requestApproval(db, body.memory_id, body.org_id, body.requested_by ?? \"daemon\");\n return send(res, 200, { approval_id: id });\n }\n\n // Approval: list pending\n if (path === \"/approval/pending\" && method === \"GET\") {\n const orgId = url.searchParams.get(\"org_id\") ?? \"\";\n return send(res, 200, { approvals: listPendingApprovals(db, orgId) });\n }\n\n // Approval: resolve\n if (path === \"/approval/resolve\" && method === \"POST\") {\n const body = await parseBody(req);\n const ok = resolveApproval(db, body.approval_id, body.status, body.reviewed_by ?? \"daemon\", body.reason);\n return send(res, ok ? 200 : 404, { success: ok });\n }\n\n // Health: single memory\n if (path.startsWith(\"/health/\") && method === \"GET\") {\n const memId = path.slice(\"/health/\".length);\n const score = computeHealthScore(db, memId);\n if (!score) return send(res, 404, { error: \"not found\" });\n return send(res, 200, score);\n }\n\n // Health: all\n if (path === \"/health\" && method === \"GET\") {\n const repo = url.searchParams.get(\"repo\") ?? undefined;\n const scores = computeAllHealthScores(db, repo);\n return send(res, 200, { scores });\n }\n\n // Contradictions: detect\n if (path === \"/contradictions/detect\" && method === \"POST\") {\n const body = await parseBody(req);\n const found = detectContradictions(db, body.repo);\n return send(res, 200, { contradictions: found });\n }\n\n // Contradictions: list\n if (path === \"/contradictions\" && method === \"GET\") {\n const resolved = url.searchParams.get(\"resolved\");\n const items = listContradictions(db, {\n resolved: resolved === \"true\" ? true : resolved === \"false\" ? false : undefined,\n });\n return send(res, 200, { contradictions: items });\n }\n\n // Contradictions: resolve\n if (path === \"/contradictions/resolve\" && method === \"POST\") {\n const body = await parseBody(req);\n const ok = resolveContradiction(db, body.contradiction_id, body.keep_memory_id, body.actor ?? \"daemon\", body.resolution);\n return send(res, ok ? 200 : 404, { success: ok });\n }\n\n // Contradictions: auto-resolve\n if (path === \"/contradictions/auto-resolve\" && method === \"POST\") {\n const body = await parseBody(req);\n const count = autoResolveContradictions(db, body.repo);\n return send(res, 200, { resolved: count });\n }\n\n // Prune\n if (path === \"/prune\" && method === \"POST\") {\n const body = await parseBody(req);\n const result = pruneMemories(db, body.config);\n return send(res, 200, result);\n }\n\n // Audit: trail for memory\n if (path.startsWith(\"/audit/memory/\") && method === \"GET\") {\n const memId = path.slice(\"/audit/memory/\".length);\n const entries = getAuditTrail(db, memId);\n return send(res, 200, { entries });\n }\n\n // Audit: recent\n if (path === \"/audit/recent\" && method === \"GET\") {\n const limit = parseInt(url.searchParams.get(\"limit\") ?? \"50\");\n const entries = getRecentAudit(db, limit);\n return send(res, 200, { entries });\n }\n\n // Audit: rollback\n if (path === \"/audit/rollback\" && method === \"POST\") {\n const body = await parseBody(req);\n const ok = rollbackMemory(db, body.memory_id, body.audit_entry_id, body.actor ?? \"daemon\");\n return send(res, ok ? 200 : 404, { success: ok });\n }\n\n send(res, 404, { error: \"not found\" });\n } catch (err: any) {\n send(res, 500, { error: err.message });\n }\n});\n\nfunction send(\n res: import(\"node:http\").ServerResponse,\n status: number,\n data: any,\n) {\n res.statusCode = status;\n res.end(JSON.stringify(data));\n}\n\nasync function startDaemon() {\n const backup = ensureDailyBackup();\n if (backup.created) {\n console.log(`[recall] backup created ${backup.created} (retained ${backup.retained.length})`);\n }\n\n db = initDb();\n\n server.listen(PORT, () => {\n console.log(`Recall daemon listening on http://localhost:${PORT}`);\n scheduleMaintenanceLoop();\n scheduleDispatcherLoop();\n scheduleCleanupLoop();\n scheduleQualitySnapshotLoop();\n\n setTimeout(() => {\n const embeddingConfig = loadEmbeddingConfigFromEnv();\n if (!embeddingConfig) return;\n\n const info = getEmbeddingModelInfo(embeddingConfig);\n if (info && !info.cached) {\n const approx = info.estimated_size_mb ? `~${info.estimated_size_mb}MB` : \"download\";\n console.log(`[recall] Fetching embedding model (one-time, ${approx}) -> ${info.cache_path}`);\n }\n void ensureEmbeddingProviderReady(embeddingConfig).catch((error: unknown) => {\n const message = error instanceof Error ? error.stack ?? error.message : String(error);\n console.error(`[recall] embedding provider warmup failed: ${message}`);\n });\n }, 60_000).unref?.();\n });\n}\n\nvoid startDaemon().catch((error: unknown) => {\n const message = error instanceof Error ? error.stack ?? error.message : String(error);\n console.error(`[recall] daemon startup failed: ${message}`);\n process.exit(1);\n});\n","import { statSync } from \"node:fs\";\nimport { eq, lt } from \"drizzle-orm\";\nimport type { RecallDb } from \"../db/client.js\";\nimport { activityEvents, feedbackEvents, historySnippets, implicitSignals, memories } from \"../db/schema.js\";\nimport {\n bootstrapEmbeddings,\n loadEmbeddingConfigFromEnv,\n rebuildEmbeddingIndex,\n verifyEmbeddings,\n} from \"../embeddings/embeddings.js\";\nimport {\n createHistorySnippet,\n findHistorySnippetByRepoKind,\n findHistorySnippetBySession,\n listHistorySnippets,\n updateHistorySnippet,\n} from \"../history/snippets.js\";\nimport { bootstrapHistoryEmbeddings, verifyHistoryEmbeddings } from \"../history/retrieval.js\";\nimport { pruneMemories } from \"../pruning/pruner.js\";\nimport { listActivityEvents } from \"../models/activity.js\";\nimport { getMemory, promoteMemory, queryMemories, rejectMemory, statusFromConfidence } from \"../models/memory.js\";\nimport { recordAuditWithSnapshot } from \"../audit/trail.js\";\nimport { getRepoQualityProfile } from \"../repo/quality.js\";\nimport { removeHistoryFtsRow, syncHistoryFtsIndex } from \"../vector/sqlite-fts-history.js\";\nimport { removeHistoryVecRow } from \"../vector/sqlite-vec-history.js\";\nimport { queueMemoryEmbeddingSync } from \"../embeddings/embeddings.js\";\nimport { evaluateScannedMemory } from \"../scanner/signal.js\";\nimport { detectCorrections } from \"../capture/correction.js\";\nimport {\n DEFAULT_ENQUEUE_CONFIG,\n enqueueMaintenanceTasks,\n type EnqueueConfig,\n} from \"./tasks.js\";\n\nexport interface MaintenanceConfig {\n enabled: boolean;\n interval_seconds: number;\n stale_days: number;\n min_health_score: number;\n activity_retention_days: number;\n feedback_retention_days: number;\n signal_retention_days: number;\n history_session_retention_days: number;\n sqlite_analyze_enabled: boolean;\n sqlite_optimize_enabled: boolean;\n sqlite_wal_checkpoint_enabled: boolean;\n sqlite_wal_truncate_bytes: number;\n sqlite_vacuum_enabled: boolean;\n sqlite_vacuum_min_free_pages: number;\n sqlite_vacuum_min_free_ratio: number;\n llm_tasks_enabled: boolean;\n llm_task_config: EnqueueConfig;\n}\n\nexport interface MaintenanceResult {\n prune_total: number;\n stale_rejected: number;\n rejected_pruned: number;\n transient_pruned: number;\n unhealthy_demoted: number;\n scanned_memories_normalized: number;\n scanned_memories_demoted: number;\n scanned_memories_rejected: number;\n activity_pruned: number;\n feedback_pruned: number;\n signals_pruned: number;\n embeddings_refreshed: number;\n vector_rows_rebuilt: number;\n lexical_rows_rebuilt: number;\n embedding_stale: number;\n vector_drift: number;\n lexical_drift: number;\n history_snippets_created: number;\n history_summaries_created: number;\n history_session_deleted: number;\n history_embeddings_refreshed: number;\n history_vector_drift: number;\n history_lexical_drift: number;\n candidates_promoted: number;\n sqlite_analyze_ran: boolean;\n sqlite_optimize_ran: boolean;\n sqlite_checkpoint_ran: boolean;\n sqlite_vacuum_ran: boolean;\n sqlite_page_count: number;\n sqlite_freelist_count: number;\n maintenance_tasks_enqueued: number;\n maintenance_leases_swept: number;\n maintenance_tasks_dropped: number;\n maintenance_tasks_expired: number;\n}\n\nconst DAY_MS = 86_400_000;\n\nexport function loadMaintenanceConfigFromEnv(): MaintenanceConfig {\n return {\n enabled: process.env.RECALL_MAINTENANCE_ENABLED !== \"false\",\n interval_seconds: parseInt(process.env.RECALL_MAINTENANCE_INTERVAL_SECONDS ?? \"300\", 10),\n stale_days: parseInt(process.env.RECALL_MAINTENANCE_STALE_DAYS ?? \"90\", 10),\n min_health_score: parseFloat(process.env.RECALL_MAINTENANCE_MIN_HEALTH_SCORE ?? \"0.2\"),\n activity_retention_days: parseInt(process.env.RECALL_ACTIVITY_RETENTION_DAYS ?? \"90\", 10),\n feedback_retention_days: parseInt(process.env.RECALL_FEEDBACK_RETENTION_DAYS ?? \"180\", 10),\n signal_retention_days: parseInt(process.env.RECALL_SIGNAL_RETENTION_DAYS ?? \"180\", 10),\n history_session_retention_days: parseInt(process.env.RECALL_HISTORY_SESSION_RETENTION_DAYS ?? \"30\", 10),\n sqlite_analyze_enabled: process.env.RECALL_SQLITE_ANALYZE_ENABLED !== \"false\",\n sqlite_optimize_enabled: process.env.RECALL_SQLITE_OPTIMIZE_ENABLED !== \"false\",\n sqlite_wal_checkpoint_enabled: process.env.RECALL_SQLITE_CHECKPOINT_ENABLED !== \"false\",\n sqlite_wal_truncate_bytes: parseInt(\n process.env.RECALL_SQLITE_WAL_TRUNCATE_BYTES ?? String(32 * 1024 * 1024),\n 10,\n ),\n sqlite_vacuum_enabled: process.env.RECALL_SQLITE_VACUUM_ENABLED === \"true\",\n sqlite_vacuum_min_free_pages: parseInt(process.env.RECALL_SQLITE_VACUUM_MIN_FREE_PAGES ?? \"100\", 10),\n sqlite_vacuum_min_free_ratio: parseFloat(process.env.RECALL_SQLITE_VACUUM_MIN_FREE_RATIO ?? \"0.1\"),\n llm_tasks_enabled: process.env.RECALL_MAINTENANCE_LLM_DISABLED !== \"true\",\n llm_task_config: {\n max_pending: parseInt(process.env.RECALL_MAINTENANCE_MAX_PENDING ?? String(DEFAULT_ENQUEUE_CONFIG.max_pending), 10),\n max_per_kind: parseInt(process.env.RECALL_MAINTENANCE_MAX_PER_KIND ?? String(DEFAULT_ENQUEUE_CONFIG.max_per_kind), 10),\n refine_min_repetition: parseInt(process.env.RECALL_MAINTENANCE_REFINE_MIN_REPETITION ?? String(DEFAULT_ENQUEUE_CONFIG.refine_min_repetition), 10),\n summary_max_age_days: parseInt(process.env.RECALL_MAINTENANCE_SUMMARY_MAX_AGE_DAYS ?? String(DEFAULT_ENQUEUE_CONFIG.summary_max_age_days), 10),\n merge_similarity_threshold: parseFloat(process.env.RECALL_MAINTENANCE_MERGE_SIMILARITY_THRESHOLD ?? String(DEFAULT_ENQUEUE_CONFIG.merge_similarity_threshold)),\n session_min_activity_events: parseInt(process.env.RECALL_MAINTENANCE_SESSION_MIN_EVENTS ?? String(DEFAULT_ENQUEUE_CONFIG.session_min_activity_events), 10),\n repo_synthesis_min_memories: parseInt(process.env.RECALL_MAINTENANCE_REPO_SYNTHESIS_MIN_MEMORIES ?? String(DEFAULT_ENQUEUE_CONFIG.repo_synthesis_min_memories), 10),\n repo_synthesis_refresh_days: parseInt(process.env.RECALL_MAINTENANCE_REPO_SYNTHESIS_REFRESH_DAYS ?? String(DEFAULT_ENQUEUE_CONFIG.repo_synthesis_refresh_days), 10),\n },\n };\n}\n\nexport async function runMaintenanceCycle(\n db: RecallDb,\n config: MaintenanceConfig = loadMaintenanceConfigFromEnv(),\n): Promise<MaintenanceResult> {\n const prune = pruneMemories(db, {\n stale_days: config.stale_days,\n min_health_score: config.min_health_score,\n });\n const scannedMemoryCleanup = reconcileScannedMemories(db);\n const candidates_promoted = promoteRepetitionCandidates(db);\n\n const activity_pruned = pruneOldActivityEvents(db, config.activity_retention_days);\n const feedback_pruned = pruneOldFeedbackEvents(db, config.feedback_retention_days);\n const signals_pruned = pruneOldImplicitSignals(db, config.signal_retention_days);\n const sqliteMaintenance = runSqliteMaintenance(db, config);\n\n let embeddings_refreshed = 0;\n let vector_rows_rebuilt = 0;\n let lexical_rows_rebuilt = 0;\n let embedding_stale = 0;\n let vector_drift = 0;\n let lexical_drift = 0;\n const history_snippets_created = rollupSessionHistory(db);\n const history_summaries_created = summarizeHistorySnippets(db);\n const history_session_deleted = cleanupSessionHistory(db, config.history_session_retention_days);\n let history_embeddings_refreshed = 0;\n let history_vector_drift = 0;\n let history_lexical_drift = 0;\n\n const embeddingConfig = loadEmbeddingConfigFromEnv();\n if (embeddingConfig) {\n const verify = verifyEmbeddings(db, embeddingConfig);\n embedding_stale = verify.stale;\n vector_drift = verify.index_drift;\n lexical_drift = verify.lexical_drift;\n\n if (embedding_stale > 0) {\n embeddings_refreshed = await bootstrapEmbeddings(db, embeddingConfig);\n }\n\n if (vector_drift !== 0 || lexical_drift !== 0) {\n const rebuilt = rebuildEmbeddingIndex(db, embeddingConfig);\n vector_rows_rebuilt = rebuilt.vector_rows;\n lexical_rows_rebuilt = rebuilt.lexical_rows;\n }\n\n const historyVerify = verifyHistoryEmbeddings(db, embeddingConfig);\n history_vector_drift = historyVerify.index_drift;\n history_lexical_drift = historyVerify.lexical_drift;\n if (\n historyVerify.stale > 0 ||\n history_snippets_created > 0 ||\n history_summaries_created > 0 ||\n history_session_deleted > 0\n ) {\n history_embeddings_refreshed = await bootstrapHistoryEmbeddings(db, embeddingConfig);\n }\n }\n\n const tasks = config.llm_tasks_enabled\n ? await enqueueMaintenanceTasks(db, config.llm_task_config)\n : { tasks_enqueued: 0, per_kind: {}, expired_leases_swept: 0, dropped_over_cap: 0, expired_pending_tasks: 0 };\n\n return {\n prune_total: prune.total,\n stale_rejected: prune.stale_rejected.length,\n rejected_pruned: prune.rejected_pruned.length,\n transient_pruned: prune.transient_pruned.length,\n unhealthy_demoted: prune.unhealthy_demoted.length,\n scanned_memories_normalized: scannedMemoryCleanup.normalized,\n scanned_memories_demoted: scannedMemoryCleanup.demoted,\n scanned_memories_rejected: scannedMemoryCleanup.rejected,\n activity_pruned,\n feedback_pruned,\n signals_pruned,\n embeddings_refreshed,\n vector_rows_rebuilt,\n lexical_rows_rebuilt,\n embedding_stale,\n vector_drift,\n lexical_drift,\n history_snippets_created,\n history_summaries_created,\n history_session_deleted,\n history_embeddings_refreshed,\n history_vector_drift,\n history_lexical_drift,\n candidates_promoted,\n sqlite_analyze_ran: sqliteMaintenance.analyze_ran,\n sqlite_optimize_ran: sqliteMaintenance.optimize_ran,\n sqlite_checkpoint_ran: sqliteMaintenance.checkpoint_ran,\n sqlite_vacuum_ran: sqliteMaintenance.vacuum_ran,\n sqlite_page_count: sqliteMaintenance.page_count,\n sqlite_freelist_count: sqliteMaintenance.freelist_count,\n maintenance_tasks_enqueued: tasks.tasks_enqueued,\n maintenance_leases_swept: tasks.expired_leases_swept,\n maintenance_tasks_dropped: tasks.dropped_over_cap,\n maintenance_tasks_expired: tasks.expired_pending_tasks,\n };\n}\n\nexport function promoteRepetitionCandidates(db: RecallDb): number {\n const candidates = queryMemories(db, { status: \"candidate\" });\n let promoted = 0;\n\n for (const candidate of candidates) {\n if (!candidate.repo) continue;\n const profile = getRepoQualityProfile(db, candidate.repo);\n if (candidate.repetition_count < profile.repeat_sessions_required) continue;\n\n const before = getMemory(db, candidate.id);\n if (!before || before.status !== \"candidate\") continue;\n const ok = promoteMemory(db, candidate.id, \"repeat_correction\");\n if (!ok) continue;\n const after = getMemory(db, candidate.id);\n recordAuditWithSnapshot(\n db,\n candidate.id,\n \"promoted\",\n \"system\",\n `repetition:${candidate.repetition_count}`,\n before,\n after ?? null,\n );\n promoted += 1;\n }\n\n return promoted;\n}\n\nexport function reconcileScannedMemories(db: RecallDb): {\n normalized: number;\n demoted: number;\n rejected: number;\n} {\n const scanned = queryMemories(db, {})\n .filter((memory) =>\n memory.status !== \"rejected\" &&\n (memory.source === \"repo_scan\" || memory.source === \"config_parse\")\n );\n\n let normalized = 0;\n let demoted = 0;\n let rejected = 0;\n\n for (const memory of scanned) {\n const evaluated = evaluateScannedMemory({\n text: memory.text,\n type: memory.type,\n source: memory.source,\n confidence: memory.confidence,\n });\n\n if (evaluated.action === \"reject\") {\n if (memory.status !== \"rejected\") {\n rejectMemory(db, memory.id);\n rejected += 1;\n }\n continue;\n }\n\n const nextStatus = statusFromConfidence(evaluated.confidence);\n const updates: Partial<typeof memories.$inferInsert> = {};\n\n if (memory.text !== evaluated.text) {\n updates.text = evaluated.text;\n normalized += 1;\n }\n if (memory.confidence !== evaluated.confidence) {\n updates.confidence = evaluated.confidence;\n }\n if (memory.status !== nextStatus) {\n updates.status = nextStatus;\n if (memory.status === \"active\" && nextStatus === \"candidate\") {\n demoted += 1;\n }\n }\n\n if (Object.keys(updates).length === 0) continue;\n\n updates.updated_at = new Date().toISOString();\n db.update(memories)\n .set(updates)\n .where(eq(memories.id, memory.id))\n .run();\n queueMemoryEmbeddingSync(db, memory.id);\n }\n\n return { normalized, demoted, rejected };\n}\n\nexport function runSqliteMaintenance(\n db: RecallDb,\n config: Pick<\n MaintenanceConfig,\n | \"sqlite_analyze_enabled\"\n | \"sqlite_optimize_enabled\"\n | \"sqlite_wal_checkpoint_enabled\"\n | \"sqlite_wal_truncate_bytes\"\n | \"sqlite_vacuum_enabled\"\n | \"sqlite_vacuum_min_free_pages\"\n | \"sqlite_vacuum_min_free_ratio\"\n >,\n) {\n const sqlite = db.$client;\n\n const pageCount = Number((sqlite.pragma(\"page_count\", { simple: true }) as number | bigint) ?? 0);\n const freelistCount = Number((sqlite.pragma(\"freelist_count\", { simple: true }) as number | bigint) ?? 0);\n const freeRatio = pageCount > 0 ? freelistCount / pageCount : 0;\n\n let analyzeRan = false;\n let optimizeRan = false;\n let checkpointRan = false;\n let vacuumRan = false;\n\n if (config.sqlite_analyze_enabled) {\n sqlite.exec(\"ANALYZE;\");\n analyzeRan = true;\n }\n\n if (config.sqlite_wal_checkpoint_enabled) {\n const mode = shouldTruncateWal(sqlite, config.sqlite_wal_truncate_bytes)\n ? \"TRUNCATE\"\n : \"PASSIVE\";\n sqlite.pragma(`wal_checkpoint(${mode})`);\n checkpointRan = true;\n }\n\n if (config.sqlite_optimize_enabled) {\n sqlite.pragma(\"optimize\");\n optimizeRan = true;\n }\n\n if (\n config.sqlite_vacuum_enabled &&\n freelistCount >= config.sqlite_vacuum_min_free_pages &&\n freeRatio >= config.sqlite_vacuum_min_free_ratio\n ) {\n sqlite.exec(\"VACUUM;\");\n vacuumRan = true;\n }\n\n return {\n analyze_ran: analyzeRan,\n optimize_ran: optimizeRan,\n checkpoint_ran: checkpointRan,\n vacuum_ran: vacuumRan,\n page_count: pageCount,\n freelist_count: freelistCount,\n };\n}\n\nfunction shouldTruncateWal(\n sqlite: { name: string },\n thresholdBytes: number,\n): boolean {\n if (!Number.isFinite(thresholdBytes) || thresholdBytes <= 0) return false;\n try {\n return statSync(`${sqlite.name}-wal`).size >= thresholdBytes;\n } catch {\n return false;\n }\n}\n\nexport function pruneOldActivityEvents(\n db: RecallDb,\n retentionDays: number,\n): number {\n const cutoff = new Date(Date.now() - (retentionDays * DAY_MS)).toISOString();\n return db.delete(activityEvents)\n .where(lt(activityEvents.created_at, cutoff))\n .run().changes;\n}\n\nexport function pruneOldFeedbackEvents(\n db: RecallDb,\n retentionDays: number,\n): number {\n const cutoff = new Date(Date.now() - (retentionDays * DAY_MS)).toISOString();\n return db.delete(feedbackEvents)\n .where(lt(feedbackEvents.timestamp, cutoff))\n .run().changes;\n}\n\nexport function pruneOldImplicitSignals(\n db: RecallDb,\n retentionDays: number,\n): number {\n const cutoff = new Date(Date.now() - (retentionDays * DAY_MS)).toISOString();\n return db.delete(implicitSignals)\n .where(lt(implicitSignals.timestamp, cutoff))\n .run().changes;\n}\n\nexport function rollupSessionHistory(db: RecallDb): number {\n const sessionEnds = listActivityEvents(db, { event_type: \"session_end\", limit: 500 });\n let createdOrUpdated = 0;\n\n for (const end of sessionEnds) {\n if (!end.session_id) continue;\n const existing = findHistorySnippetBySession(db, end.session_id, \"session_summary\");\n\n const events = listActivityEvents(db, { session_id: end.session_id })\n .sort((a, b) => a.created_at.localeCompare(b.created_at));\n if (events.length === 0) continue;\n\n const repo = end.repo ?? events.find((event) => event.repo)?.repo ?? null;\n const summary = summarizeSessionEvents(events);\n const sourceActivityIds = events.map((event) => event.id);\n\n if (existing) {\n if (existing.text !== summary) {\n updateHistorySnippet(db, existing.id, {\n text: summary,\n source_activity_ids: sourceActivityIds,\n });\n syncHistoryFtsIndex(db, existing.id);\n createdOrUpdated++;\n }\n continue;\n }\n\n const id = createHistorySnippet(db, {\n repo,\n session_id: end.session_id,\n kind: \"session_summary\",\n text: summary,\n source_activity_ids: sourceActivityIds,\n });\n syncHistoryFtsIndex(db, id);\n createdOrUpdated++;\n }\n\n return createdOrUpdated;\n}\n\nexport function summarizeHistorySnippets(db: RecallDb): number {\n const sessionSnippets = listHistorySnippets(db, {\n kind: \"session_summary\",\n limit: 1000,\n });\n\n const byRepo = new Map<string, typeof sessionSnippets>();\n for (const snippet of sessionSnippets) {\n if (!snippet.repo) continue;\n const bucket = byRepo.get(snippet.repo) ?? [];\n bucket.push(snippet);\n byRepo.set(snippet.repo, bucket);\n }\n\n let createdOrUpdated = 0;\n for (const [repo, snippets] of byRepo.entries()) {\n const aggregated = aggregateRepoHistory(repo, snippets);\n for (const item of aggregated) {\n if (!item.text) continue;\n\n const existing = findHistorySnippetByRepoKind(db, repo, item.kind);\n if (existing) {\n if (existing.text !== item.text) {\n updateHistorySnippet(db, existing.id, {\n text: item.text,\n source_activity_ids: item.source_activity_ids,\n });\n syncHistoryFtsIndex(db, existing.id);\n createdOrUpdated++;\n }\n continue;\n }\n\n const id = createHistorySnippet(db, {\n repo,\n kind: item.kind,\n text: item.text,\n source_activity_ids: item.source_activity_ids,\n });\n syncHistoryFtsIndex(db, id);\n createdOrUpdated++;\n }\n }\n\n return createdOrUpdated;\n}\n\nexport function cleanupSessionHistory(\n db: RecallDb,\n retentionDays: number,\n): number {\n const cutoff = new Date(Date.now() - (retentionDays * DAY_MS)).toISOString();\n const sessionSnippets = listHistorySnippets(db, {\n kind: \"session_summary\",\n limit: 1000,\n });\n\n let deleted = 0;\n for (const snippet of sessionSnippets) {\n if (!snippet.repo) continue;\n if (snippet.created_at >= cutoff) continue;\n\n const hasRepoSummary =\n findHistorySnippetByRepoKind(db, snippet.repo, \"correction_summary\") ||\n findHistorySnippetByRepoKind(db, snippet.repo, \"decision_summary\") ||\n findHistorySnippetByRepoKind(db, snippet.repo, \"review_summary\") ||\n findHistorySnippetByRepoKind(db, snippet.repo, \"compile_summary\");\n if (!hasRepoSummary) continue;\n\n removeHistoryFtsRow(db, snippet.id);\n removeHistoryVecRow(db, snippet.id);\n db.delete(historySnippets)\n .where(eq(historySnippets.id, snippet.id))\n .run();\n deleted++;\n }\n\n return deleted;\n}\n\nfunction summarizeSessionEvents(\n events: Array<ReturnType<typeof listActivityEvents>[number]>,\n) {\n const repo = events.find((event) => event.repo)?.repo ?? \"unknown\";\n const eventTypes = [...new Set(events.map((event) => event.event_type))];\n const corrections = events\n .filter((event) => event.event_type === \"correction\")\n .map((event) => String(event.request.text ?? \"\"))\n .filter(Boolean);\n const reviews = events\n .filter((event) => event.event_type === \"review\")\n .map((event) => String(event.request.feedback ?? \"\"))\n .filter(Boolean);\n const decisions = extractPromptDecisions(events);\n const compileEvents = events.filter((event) => event.event_type === \"compile\");\n\n const lines = [\n `Repo: ${repo}`,\n `Event types: ${eventTypes.join(\", \")}`,\n ];\n\n if (compileEvents.length > 0) {\n const latestCompile = compileEvents.at(-1);\n const included = Array.isArray(latestCompile?.result.included)\n ? latestCompile.result.included.length\n : 0;\n lines.push(`Latest compile included ${included} memories.`);\n }\n\n if (corrections.length > 0) {\n lines.push(`Corrections: ${corrections.slice(0, 3).join(\" | \")}`);\n }\n\n if (reviews.length > 0) {\n lines.push(`Reviews: ${reviews.slice(0, 3).join(\" | \")}`);\n }\n\n if (decisions.length > 0) {\n lines.push(`Decisions: ${decisions.slice(0, 5).join(\" | \")}`);\n }\n\n return lines.join(\"\\n\");\n}\n\nfunction aggregateRepoHistory(\n repo: string,\n snippets: ReturnType<typeof listHistorySnippets>,\n): Array<{\n kind: \"correction_summary\" | \"decision_summary\" | \"review_summary\" | \"compile_summary\";\n text: string;\n source_activity_ids: string[];\n}> {\n const corrections = new Map<string, number>();\n const decisions = new Map<string, number>();\n const reviews = new Map<string, number>();\n let compileObservations = 0;\n let compileIncludedTotal = 0;\n const sourceActivityIds = new Set<string>();\n\n for (const snippet of snippets) {\n for (const id of snippet.source_activity_ids) {\n sourceActivityIds.add(id);\n }\n\n const lines = snippet.text.split(\"\\n\");\n const correctionsLine = lines.find((line) => line.startsWith(\"Corrections: \"));\n if (correctionsLine) {\n for (const item of correctionsLine.replace(\"Corrections: \", \"\").split(\" | \").filter(Boolean)) {\n corrections.set(item, (corrections.get(item) ?? 0) + 1);\n }\n }\n\n const reviewsLine = lines.find((line) => line.startsWith(\"Reviews: \"));\n if (reviewsLine) {\n for (const item of reviewsLine.replace(\"Reviews: \", \"\").split(\" | \").filter(Boolean)) {\n reviews.set(item, (reviews.get(item) ?? 0) + 1);\n }\n }\n\n const decisionsLine = lines.find((line) => line.startsWith(\"Decisions: \"));\n if (decisionsLine) {\n for (const item of decisionsLine.replace(\"Decisions: \", \"\").split(\" | \").filter(Boolean)) {\n decisions.set(item, (decisions.get(item) ?? 0) + 1);\n }\n }\n\n const compileLine = lines.find((line) => line.startsWith(\"Latest compile included \"));\n if (compileLine) {\n compileObservations++;\n const match = compileLine.match(/included (\\d+) memories/);\n if (match) compileIncludedTotal += parseInt(match[1], 10);\n }\n }\n\n return [\n {\n kind: \"correction_summary\",\n text: renderSummary(repo, \"Frequent corrections\", corrections),\n source_activity_ids: [...sourceActivityIds],\n },\n {\n kind: \"review_summary\",\n text: renderSummary(repo, \"Frequent review guidance\", reviews),\n source_activity_ids: [...sourceActivityIds],\n },\n {\n kind: \"decision_summary\",\n text: renderSummary(repo, \"Frequent user decisions\", decisions),\n source_activity_ids: [...sourceActivityIds],\n },\n {\n kind: \"compile_summary\",\n text: compileObservations > 0\n ? [\n `Repo: ${repo}`,\n `Compile observations: ${compileObservations}`,\n `Average included memories: ${(compileIncludedTotal / compileObservations).toFixed(1)}`,\n ].join(\"\\n\")\n : \"\",\n source_activity_ids: [...sourceActivityIds],\n },\n ];\n}\n\nfunction renderSummary(\n repo: string,\n heading: string,\n counts: Map<string, number>,\n) {\n if (counts.size === 0) return \"\";\n const top = [...counts.entries()]\n .sort((a, b) => b[1] - a[1])\n .slice(0, 5)\n .map(([text, count]) => `- (${count}) ${text}`);\n\n return [\n `Repo: ${repo}`,\n `${heading}:`,\n ...top,\n ].join(\"\\n\");\n}\n\nfunction extractPromptDecisions(\n events: Array<ReturnType<typeof listActivityEvents>[number]>,\n): string[] {\n const seen = new Set<string>();\n const decisions: string[] = [];\n\n for (const event of events) {\n if (event.event_type !== \"session_event\") continue;\n if (event.request.name !== \"prompt_submitted\") continue;\n const text = String(event.result.text ?? \"\").trim();\n if (!text) continue;\n\n const durable = detectCorrections(text)\n .filter((match) => match.type === \"decision\")\n .map((match) => match.text);\n for (const item of durable) {\n addUniqueDecision(seen, decisions, item);\n }\n\n const directive = extractDurablePromptDirective(text);\n if (directive) {\n addUniqueDecision(seen, decisions, directive);\n }\n }\n\n return decisions;\n}\n\nfunction addUniqueDecision(seen: Set<string>, decisions: string[], text: string) {\n const normalized = text.toLowerCase().replace(/\\s+/g, \" \").trim();\n if (!normalized || seen.has(normalized)) return;\n seen.add(normalized);\n decisions.push(text);\n}\n\nfunction extractDurablePromptDirective(text: string): string | null {\n const compact = text\n .replace(/\\s+/g, \" \")\n .replace(/^[-*]\\s+/, \"\")\n .trim();\n const phaseDirective = /\\b(?:do\\s+phase|phase\\s+\\d+)\\b/i.test(compact);\n if ((!phaseDirective && compact.length < 14) || compact.length > 240) return null;\n if (!DURABLE_PROMPT_DIRECTIVE.test(compact)) return null;\n if (!DURABLE_PROMPT_DOMAIN.test(compact)) return null;\n if (/^(?:can|could|would|should|why|what|how)\\b.*\\?$/i.test(compact)) return null;\n return `User direction: ${compact.replace(/[.!?]+$/u, \"\")}.`;\n}\n\nconst DURABLE_PROMPT_DIRECTIVE =\n /\\b(?:let's|lets|let us|we should|we need to|make|improve|add|change|implement|ship|do phase|phase\\s+\\d+|production ready|open source|self[- ]healing|self healing)\\b/i;\n\nconst DURABLE_PROMPT_DOMAIN =\n /\\b(?:recall|memory|memories|dedupe|duplicate|question|prompt|capture|history|summary|quality|maintenance|cleanup|doctor|daemon|dispatcher|migration|test|phase|production|open source|self[- ]healing|self healing)\\b/i;\n","import type { MaintenanceResult } from \"./lifecycle.js\";\n\nexport function maintenanceChangeCount(result: MaintenanceResult): number {\n return (\n result.prune_total +\n result.scanned_memories_normalized +\n result.scanned_memories_demoted +\n result.scanned_memories_rejected +\n result.activity_pruned +\n result.feedback_pruned +\n result.signals_pruned +\n result.embeddings_refreshed +\n result.vector_rows_rebuilt +\n result.lexical_rows_rebuilt +\n result.history_snippets_created +\n result.history_embeddings_refreshed\n );\n}\n\nexport function shouldLogMaintenance(result: MaintenanceResult): boolean {\n return (\n maintenanceChangeCount(result) > 0 ||\n result.vector_drift !== 0 ||\n result.lexical_drift !== 0 ||\n result.embedding_stale > 0 ||\n result.history_vector_drift !== 0 ||\n result.history_lexical_drift !== 0\n );\n}\n\nexport function formatMaintenanceSummary(result: MaintenanceResult): string {\n return (\n `[recall] maintenance ` +\n `prune=${result.prune_total} ` +\n `scanned(normalized=${result.scanned_memories_normalized},demoted=${result.scanned_memories_demoted},rejected=${result.scanned_memories_rejected}) ` +\n `activity=${result.activity_pruned} ` +\n `feedback=${result.feedback_pruned} ` +\n `signals=${result.signals_pruned} ` +\n `refreshed=${result.embeddings_refreshed} ` +\n `rebuilt(vec=${result.vector_rows_rebuilt},fts=${result.lexical_rows_rebuilt}) ` +\n `drift(vec=${result.vector_drift},fts=${result.lexical_drift}) ` +\n `stale=${result.embedding_stale} ` +\n `history(created=${result.history_snippets_created},refreshed=${result.history_embeddings_refreshed},drift_vec=${result.history_vector_drift},drift_fts=${result.history_lexical_drift})`\n );\n}\n","import type { IncomingMessage, ServerResponse } from \"node:http\";\nimport { StreamableHTTPServerTransport } from \"@modelcontextprotocol/sdk/server/streamableHttp.js\";\nimport type { RecallDb } from \"../db/client.js\";\nimport { createRecallMcpServer } from \"./factory.js\";\n\nexport async function handleRecallMcpHttpRequest(\n req: IncomingMessage,\n res: ServerResponse,\n db: RecallDb,\n) {\n if (req.method !== \"POST\") {\n return sendJsonRpcError(res, 405, -32000, \"Method not allowed\");\n }\n\n const mcpServer = createRecallMcpServer(db);\n const transport = new StreamableHTTPServerTransport({\n sessionIdGenerator: undefined,\n enableJsonResponse: true,\n });\n\n try {\n await mcpServer.connect(transport);\n await transport.handleRequest(req, res);\n } catch (error) {\n if (!res.headersSent) {\n sendJsonRpcError(\n res,\n 500,\n -32603,\n error instanceof Error ? error.message : \"Internal server error\",\n );\n }\n } finally {\n await transport.close().catch(() => {});\n await mcpServer.close().catch(() => {});\n }\n}\n\nfunction sendJsonRpcError(\n res: ServerResponse,\n status: number,\n code: number,\n message: string,\n) {\n res.statusCode = status;\n res.setHeader(\"Content-Type\", \"application/json\");\n res.end(JSON.stringify({\n jsonrpc: \"2.0\",\n error: { code, message },\n id: null,\n }));\n}\n"],"mappings":"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","names":["db","db","c"]}
1
+ {"version":3,"sources":["../src/daemon.ts","../src/maintenance/lifecycle.ts","../src/maintenance/logging.ts","../src/mcp/http.ts"],"sourcesContent":["import { createServer } from \"node:http\";\nimport type { RecallDb } from \"./db/client.js\";\nimport { compileContext, compileContextHybrid } from \"./compiler/context.js\";\nimport { processCorrection, processReviewFeedback } from \"./capture/correction.js\";\nimport {\n confirmMemory,\n rejectMemory,\n queryMemories,\n recordFeedback,\n getMemory,\n} from \"./models/memory.js\";\nimport { scanAndStore } from \"./scanner/repo.js\";\nimport { computeMetrics, formatMetricsReport, startEvalSession, endEvalSession, incrementEvalCounter } from \"./eval/harness.js\";\nimport { recordSignal, getSignalStats, recordTestSignals, runTests } from \"./feedback/implicit.js\";\nimport { createPolicy, listPolicies, evaluatePolicy, requestApproval, resolveApproval, listPendingApprovals } from \"./policy/engine.js\";\nimport { computeHealthScore, computeAllHealthScores } from \"./health/scoring.js\";\nimport { detectContradictions, resolveContradiction, autoResolveContradictions, listContradictions } from \"./contradictions/detector.js\";\nimport { pruneMemories } from \"./pruning/pruner.js\";\nimport { getAuditTrail, getRecentAudit, rollbackMemory } from \"./audit/trail.js\";\nimport { getRepoQualityProfile } from \"./repo/quality.js\";\nimport { createActivityEvent, listActivityEvents, listActivitySessions } from \"./models/activity.js\";\nimport { ensureRepoBootstrapped, inferRepoSlugFromPath } from \"./repo/discovery.js\";\nimport { ensureEmbeddingProviderReady, getEmbeddingModelInfo, loadEmbeddingConfigFromEnv } from \"./embeddings/embeddings.js\";\nimport {\n endSessionLifecycle,\n recordSessionLifecycleEvent,\n startSessionLifecycle,\n} from \"./session/lifecycle.js\";\nimport { writeRepoContextArtifact } from \"./artifacts/context.js\";\nimport { loadMaintenanceConfigFromEnv, runMaintenanceCycle } from \"./maintenance/lifecycle.js\";\nimport { formatMaintenanceSummary, shouldLogMaintenance } from \"./maintenance/logging.js\";\nimport { dispatchPendingTasks } from \"./maintenance/dispatcher.js\";\nimport { runDeterministicCleanup } from \"./maintenance/cleanup.js\";\nimport { computeQualityReport, listQualitySnapshots, recordQualitySnapshot } from \"./maintenance/quality.js\";\nimport { hasProviderConfigured } from \"./credentials/keychain.js\";\nimport { initDb } from \"./db/client.js\";\nimport { ensureDailyBackup } from \"./backups/snapshot.js\";\nimport { handleRecallMcpHttpRequest } from \"./mcp/http.js\";\nimport {\n handlePromptHook,\n handleSessionEndHook,\n handleSessionStartHook,\n handleToolHook,\n} from \"./cli/hook.js\";\n\nlet db: RecallDb;\nconst PORT = parseInt(process.env.RECALL_PORT ?? \"7890\", 10);\nconst maintenanceConfig = loadMaintenanceConfigFromEnv();\nlet maintenanceRunning = false;\n\nconst dispatcherConfig = {\n enabled: process.env.RECALL_DISPATCHER_ENABLED !== \"false\",\n intervalSeconds: parseInt(process.env.RECALL_DISPATCHER_INTERVAL_SECONDS ?? \"86400\", 10),\n maxTasksPerRun: parseInt(process.env.RECALL_DISPATCHER_MAX_TASKS_PER_RUN ?? \"5\", 10),\n};\nlet dispatcherRunning = false;\n\nconst cleanupConfig = {\n enabled: process.env.RECALL_CLEANUP_ENABLED !== \"false\",\n intervalSeconds: parseInt(process.env.RECALL_CLEANUP_INTERVAL_SECONDS ?? \"86400\", 10),\n};\nlet cleanupRunning = false;\n\nconst qualitySnapshotConfig = {\n enabled: process.env.RECALL_QUALITY_SNAPSHOT_ENABLED !== \"false\",\n intervalSeconds: parseInt(process.env.RECALL_QUALITY_SNAPSHOT_INTERVAL_SECONDS ?? \"604800\", 10),\n};\nlet qualitySnapshotRunning = false;\n\nfunction parseBody(req: import(\"node:http\").IncomingMessage): Promise<any> {\n return new Promise((resolve, reject) => {\n const chunks: Buffer[] = [];\n req.on(\"data\", (c: Buffer) => chunks.push(c));\n req.on(\"end\", () => {\n try {\n resolve(JSON.parse(Buffer.concat(chunks).toString()));\n } catch {\n resolve({});\n }\n });\n req.on(\"error\", reject);\n });\n}\n\nfunction resolveRepo(body: Record<string, any>): string | undefined {\n return body.repo ?? inferRepoSlugFromPath(body.repo_path) ?? undefined;\n}\n\nfunction scheduleMaintenanceLoop() {\n if (!maintenanceConfig.enabled) return;\n\n const run = async () => {\n if (maintenanceRunning) return;\n maintenanceRunning = true;\n try {\n const result = await runMaintenanceCycle(db, maintenanceConfig);\n if (shouldLogMaintenance(result)) {\n console.log(formatMaintenanceSummary(result));\n }\n } catch (error) {\n const message = error instanceof Error ? error.stack ?? error.message : String(error);\n console.error(`[recall] maintenance failed: ${message}`);\n } finally {\n maintenanceRunning = false;\n }\n };\n\n const intervalMs = Math.max(30, maintenanceConfig.interval_seconds) * 1000;\n // Defer first run so startup health checks can succeed before embedding\n // verification or history refresh work can occupy the event loop.\n setTimeout(() => void run(), intervalMs).unref?.();\n const timer = setInterval(() => {\n void run();\n }, intervalMs);\n timer.unref?.();\n}\n\nlet dispatcherDormantLogged = false;\n\nasync function runDispatcherOnce(): Promise<void> {\n if (dispatcherRunning) return;\n const hasKey =\n hasProviderConfigured(\"anthropic\") ||\n hasProviderConfigured(\"azure-openai\") ||\n hasProviderConfigured(\"openai\");\n if (!hasKey) {\n if (!dispatcherDormantLogged) {\n console.log(\"[recall] dispatcher dormant: no LLM provider configured (set one via 'recall maintenance credentials set <provider> <key>'; preview prompts via 'recall maintenance dispatch --preview')\");\n dispatcherDormantLogged = true;\n }\n return;\n }\n dispatcherDormantLogged = false;\n\n dispatcherRunning = true;\n try {\n const report = await dispatchPendingTasks(db, {\n maxTasks: dispatcherConfig.maxTasksPerRun,\n });\n if (report.attempted > 0 || report.applied > 0) {\n console.log(\n `[recall] dispatcher ${report.provider}: attempted=${report.attempted} applied=${report.applied} rejected=${report.rejected} released=${report.released}`,\n );\n }\n } catch (error) {\n const message = error instanceof Error ? error.stack ?? error.message : String(error);\n console.error(`[recall] dispatcher failed: ${message}`);\n } finally {\n dispatcherRunning = false;\n }\n}\n\n// Wake-up: triggered by the hook after enqueuing a task. Debounced so a\n// burst of hook calls (e.g. parallel sessions) collapses to one dispatch\n// run a few seconds later — that lets the dispatcher batch tasks and not\n// hammer the LLM provider per prompt.\nlet dispatchWakeTimer: NodeJS.Timeout | null = null;\nconst DISPATCH_WAKE_DEBOUNCE_MS = 3_000;\nfunction wakeDispatcherDebounced(): void {\n if (!dispatcherConfig.enabled) return;\n if (dispatchWakeTimer) return;\n dispatchWakeTimer = setTimeout(() => {\n dispatchWakeTimer = null;\n void runDispatcherOnce();\n }, DISPATCH_WAKE_DEBOUNCE_MS);\n dispatchWakeTimer.unref?.();\n}\n\nfunction scheduleDispatcherLoop() {\n if (!dispatcherConfig.enabled) return;\n const timer = setInterval(() => {\n void runDispatcherOnce();\n }, Math.max(60, dispatcherConfig.intervalSeconds) * 1000);\n timer.unref?.();\n}\n\nfunction scheduleCleanupLoop() {\n if (!cleanupConfig.enabled) return;\n\n const run = async () => {\n if (cleanupRunning) return;\n cleanupRunning = true;\n try {\n const report = runDeterministicCleanup(db, { dryRun: false });\n const c = report.counts;\n const total =\n c.dedupe_clusters +\n c.fragment_rejections +\n c.repeat_promotions +\n c.command_suppressions +\n c.globalizations;\n if (total > 0) {\n console.log(\n `[recall] cleanup run=${report.run_id.slice(0, 8)} merges=${c.dedupe_clusters}/${c.dedupe_losers} fragments=${c.fragment_rejections} promotions=${c.repeat_promotions} suppress=${c.command_suppressions} globalize=${c.globalizations}/${c.globalize_losers}`,\n );\n }\n // Surface logical conflicts after each tick. Cheap (O(n²) over active\n // memories) and lets users see \"Use pnpm\" vs \"Use bun\" before the\n // model gets the contradictory pair injected.\n const newContradictions = detectContradictions(db);\n if (newContradictions.length > 0) {\n console.log(\n `[recall] contradictions detected: ${newContradictions.length} new pair(s)`,\n );\n for (const c of newContradictions.slice(0, 5)) {\n console.log(` [${c.severity}] ${c.contradiction_type}: ${c.description.slice(0, 120)}`);\n }\n }\n } catch (error) {\n const message = error instanceof Error ? error.stack ?? error.message : String(error);\n console.error(`[recall] cleanup failed: ${message}`);\n } finally {\n cleanupRunning = false;\n }\n };\n\n // Defer the first run so we don't fight startup migrations.\n setTimeout(() => void run(), 30_000).unref?.();\n const timer = setInterval(() => {\n void run();\n }, Math.max(60, cleanupConfig.intervalSeconds) * 1000);\n timer.unref?.();\n}\n\nfunction scheduleQualitySnapshotLoop() {\n if (!qualitySnapshotConfig.enabled) return;\n\n const intervalMs = Math.max(60, qualitySnapshotConfig.intervalSeconds) * 1000;\n\n const run = () => {\n if (qualitySnapshotRunning) return;\n qualitySnapshotRunning = true;\n try {\n // Only snapshot if the most recent snapshot is older than the interval.\n const last = listQualitySnapshots(db, 1)[0];\n if (last) {\n const ageMs = Date.now() - new Date(last.taken_at).getTime();\n if (ageMs < intervalMs) return;\n }\n const report = computeQualityReport(db);\n const row = recordQualitySnapshot(db, report, \"auto\");\n console.log(\n `[recall] quality snapshot ${row.id.slice(0, 8)} followed=${row.followed_rate_resolved != null ? (row.followed_rate_resolved * 100).toFixed(1) + \"%\" : \"n/a\"} resolved=${row.injections_resolved} history=${row.history_injections_total} rules=${row.active_rule_count} cand=${row.candidate_correction_count}`,\n );\n } catch (error) {\n const message = error instanceof Error ? error.stack ?? error.message : String(error);\n console.error(`[recall] quality snapshot failed: ${message}`);\n } finally {\n qualitySnapshotRunning = false;\n }\n };\n\n setTimeout(run, 60_000).unref?.();\n // Re-check hourly; the age gate keeps actual writes weekly.\n const timer = setInterval(run, 3600 * 1000);\n timer.unref?.();\n}\n\nconst server = createServer(async (req, res) => {\n const url = new URL(req.url ?? \"/\", `http://localhost:${PORT}`);\n const path = url.pathname;\n const method = req.method ?? \"GET\";\n\n // CORS for browser extension\n res.setHeader(\"Access-Control-Allow-Origin\", \"*\");\n res.setHeader(\"Access-Control-Allow-Methods\", \"GET, POST, DELETE, OPTIONS\");\n res.setHeader(\n \"Access-Control-Allow-Headers\",\n \"Content-Type, Authorization, MCP-Protocol-Version, MCP-Session-Id, Last-Event-ID\",\n );\n\n if (method === \"OPTIONS\") {\n res.statusCode = 204;\n res.end();\n return;\n }\n\n try {\n if (path === \"/mcp\") {\n return await handleRecallMcpHttpRequest(req, res, db);\n }\n\n res.setHeader(\"Content-Type\", \"application/json\");\n\n // Health\n if (path === \"/health\" && method === \"GET\") {\n return send(res, 200, {\n status: \"ok\",\n version: \"0.5.0\",\n embeddings: getEmbeddingModelInfo(),\n });\n }\n\n // Compile context (hook injection endpoint)\n if (path === \"/compile\" && method === \"POST\") {\n const body = await parseBody(req);\n const repo = resolveRepo(body);\n if (!repo) return send(res, 400, { error: \"repo or repo_path required\" });\n\n const bootstrap = ensureRepoBootstrapped(db, {\n repo,\n repoPathHint: body.repo_path,\n });\n if (bootstrap.status === \"bootstrapped\" || bootstrap.status === \"scanned_empty\") {\n createActivityEvent(db, {\n session_id: body.session_id ?? null,\n repo,\n source: \"daemon\",\n event_type: \"scan\",\n memory_ids: bootstrap.created_ids,\n request: {\n repo_path: bootstrap.repo_path,\n trigger: \"compile_auto_bootstrap\",\n },\n result: {\n created: bootstrap.created_ids.length,\n status: bootstrap.status,\n },\n });\n }\n\n const result = body.query_text || body.config?.include_candidates\n ? await compileContextHybrid(db, {\n repo,\n path: body.path,\n session_id: body.session_id,\n query_text: body.query_text,\n config: body.config,\n })\n : compileContext(db, {\n repo,\n path: body.path,\n session_id: body.session_id,\n config: body.config,\n });\n createActivityEvent(db, {\n session_id: body.session_id ?? null,\n repo,\n path: body.path ?? null,\n source: \"daemon\",\n event_type: \"compile\",\n memory_ids: result.memories_included,\n request: {\n config: body.config ?? {},\n query_text: body.query_text ?? null,\n bootstrap_status: bootstrap.status,\n },\n result: {\n included: result.memories_included,\n dropped: result.memories_dropped,\n history_included: result.history_included,\n token_estimate: result.token_estimate,\n repo_path: bootstrap.repo_path,\n },\n });\n return send(res, 200, {\n ...result,\n repo,\n repo_path: bootstrap.repo_path ?? body.repo_path ?? null,\n bootstrap_status: bootstrap.status,\n });\n }\n\n // Session start\n if (path === \"/session/start\" && method === \"POST\") {\n const body = await parseBody(req);\n if (!body.session_id) {\n return send(res, 400, { error: \"session_id required\" });\n }\n const result = startSessionLifecycle(db, {\n session_id: body.session_id,\n client: body.client ?? null,\n repo: body.repo ?? null,\n repo_path: body.repo_path ?? null,\n path: body.path ?? null,\n meta: body.meta ?? {},\n });\n return send(res, 200, result);\n }\n\n // Session event\n if (path === \"/session/event\" && method === \"POST\") {\n const body = await parseBody(req);\n if (!body.session_id || !body.name) {\n return send(res, 400, { error: \"session_id and name required\" });\n }\n const result = recordSessionLifecycleEvent(db, {\n session_id: body.session_id,\n client: body.client ?? null,\n repo: body.repo ?? null,\n repo_path: body.repo_path ?? null,\n path: body.path ?? null,\n meta: body.meta ?? {},\n name: body.name,\n payload: body.payload ?? {},\n });\n return send(res, 200, result);\n }\n\n // Session end\n if (path === \"/session/end\" && method === \"POST\") {\n const body = await parseBody(req);\n if (!body.session_id) {\n return send(res, 400, { error: \"session_id required\" });\n }\n const result = endSessionLifecycle(db, {\n session_id: body.session_id,\n client: body.client ?? null,\n repo: body.repo ?? null,\n repo_path: body.repo_path ?? null,\n path: body.path ?? null,\n meta: body.meta ?? {},\n payload: body.payload ?? {},\n });\n return send(res, 200, result);\n }\n\n // Dispatch wake: called by the capture hook after enqueuing a task.\n // Debounced 3s so a burst of hook calls collapses to one dispatch run.\n if (path === \"/dispatch/wake\" && method === \"POST\") {\n wakeDispatcherDebounced();\n return send(res, 202, { status: \"queued\", debounce_ms: DISPATCH_WAKE_DEBOUNCE_MS });\n }\n\n // Hook prompt\n if (path === \"/hook/prompt\" && method === \"POST\") {\n const body = await parseBody(req);\n if (!body.text) {\n return send(res, 400, { error: \"text required\" });\n }\n const result = await handlePromptHook(body, {\n db,\n source: \"daemon\",\n });\n return send(res, 200, { ...result, transport: \"daemon\" });\n }\n\n // Hook tool\n if (path === \"/hook/tool\" && method === \"POST\") {\n const body = await parseBody(req);\n if (!body.name || typeof body.exit_code !== \"number\") {\n return send(res, 400, { error: \"name and numeric exit_code required\" });\n }\n const result = await handleToolHook(body, {\n db,\n source: \"daemon\",\n });\n return send(res, 200, { ...result, transport: \"daemon\" });\n }\n\n // Hook session start\n if (path === \"/hook/session-start\" && method === \"POST\") {\n const body = await parseBody(req);\n if (!body.session_id || !body.agent) {\n return send(res, 400, { error: \"session_id and agent required\" });\n }\n const result = await handleSessionStartHook(body, {\n db,\n source: \"daemon\",\n });\n return send(res, 200, { ...result, transport: \"daemon\" });\n }\n\n // Hook session end\n if (path === \"/hook/session-end\" && method === \"POST\") {\n const body = await parseBody(req);\n if (!body.session_id) {\n return send(res, 400, { error: \"session_id required\" });\n }\n const result = await handleSessionEndHook(body, {\n db,\n source: \"daemon\",\n });\n return send(res, 200, { ...result, transport: \"daemon\" });\n }\n\n // Report correction\n if (path === \"/correct\" && method === \"POST\") {\n const body = await parseBody(req);\n const repo = resolveRepo(body);\n const ids = await processCorrection(db, body.text, {\n sessionId: body.session_id ?? \"hook\",\n repo,\n path: body.path,\n });\n createActivityEvent(db, {\n session_id: body.session_id ?? \"hook\",\n repo: repo ?? null,\n path: body.path ?? null,\n source: \"daemon\",\n event_type: \"correction\",\n memory_ids: ids,\n request: { text: body.text },\n result: { created: ids },\n });\n return send(res, 200, { created: ids });\n }\n\n // Report review feedback\n if (path === \"/review\" && method === \"POST\") {\n const body = await parseBody(req);\n const repo = resolveRepo(body);\n const ids = await processReviewFeedback(db, body.feedback, {\n sessionId: body.session_id ?? \"hook-review\",\n repo,\n path: body.path,\n reviewer: body.reviewer,\n });\n createActivityEvent(db, {\n session_id: body.session_id ?? \"hook-review\",\n repo: repo ?? null,\n path: body.path ?? null,\n source: \"daemon\",\n event_type: \"review\",\n memory_ids: ids,\n request: { feedback: body.feedback, reviewer: body.reviewer ?? null },\n result: { created: ids },\n });\n return send(res, 200, { created: ids });\n }\n\n // Confirm memory\n if (path === \"/confirm\" && method === \"POST\") {\n const body = await parseBody(req);\n const ok = confirmMemory(db, body.memory_id);\n return send(res, ok ? 200 : 404, { success: ok });\n }\n\n // Reject memory\n if (path === \"/reject\" && method === \"POST\") {\n const body = await parseBody(req);\n const ok = rejectMemory(db, body.memory_id);\n return send(res, ok ? 200 : 404, { success: ok });\n }\n\n // Record feedback\n if (path === \"/feedback\" && method === \"POST\") {\n const body = await parseBody(req);\n const id = recordFeedback(\n db,\n body.memory_id,\n body.session_id,\n body.injected,\n body.outcome,\n );\n createActivityEvent(db, {\n session_id: body.session_id,\n source: \"daemon\",\n event_type: \"feedback\",\n memory_ids: [body.memory_id],\n request: { injected: body.injected, outcome: body.outcome },\n result: { feedback_id: id },\n });\n return send(res, 200, { feedback_id: id });\n }\n\n // List memories\n if (path === \"/memories\" && method === \"GET\") {\n const repo = url.searchParams.get(\"repo\") ?? undefined;\n const status = url.searchParams.get(\"status\") as any;\n const limit = url.searchParams.get(\"limit\");\n const offset = url.searchParams.get(\"offset\");\n const items = queryMemories(db, {\n repo,\n status,\n limit: limit ? parseInt(limit, 10) : undefined,\n offset: offset ? parseInt(offset, 10) : undefined,\n });\n return send(res, 200, { memories: items });\n }\n\n // Get single memory\n if (path.startsWith(\"/memory/\") && method === \"GET\") {\n const id = path.slice(\"/memory/\".length);\n const mem = getMemory(db, id);\n if (!mem) return send(res, 404, { error: \"not found\" });\n return send(res, 200, mem);\n }\n\n // Scan repo\n if (path === \"/scan\" && method === \"POST\") {\n const body = await parseBody(req);\n const ids = scanAndStore(db, body.repo_path);\n const mem = ids[0] ? getMemory(db, ids[0]) : undefined;\n const artifact = writeRepoContextArtifact(db, {\n repo: mem?.repo ?? null,\n repo_path: body.repo_path,\n });\n createActivityEvent(db, {\n session_id: body.session_id ?? null,\n repo: mem?.repo ?? null,\n source: \"daemon\",\n event_type: \"scan\",\n memory_ids: ids,\n request: { repo_path: body.repo_path },\n result: {\n created: ids.length,\n artifact_path: artifact.output_path,\n artifact_written: artifact.written,\n },\n });\n return send(res, 200, {\n created: ids,\n count: ids.length,\n artifact_path: artifact.output_path,\n artifact_written: artifact.written,\n });\n }\n\n // --- Phase 2 endpoints ---\n\n // Eval metrics\n if (path === \"/eval/metrics\" && method === \"GET\") {\n const repo = url.searchParams.get(\"repo\") ?? undefined;\n const since = url.searchParams.get(\"since\") ?? undefined;\n const metrics = computeMetrics(db, { repo, since });\n return send(res, 200, metrics);\n }\n\n // Eval session start\n if (path === \"/eval/start\" && method === \"POST\") {\n const body = await parseBody(req);\n const id = startEvalSession(db, body.repo);\n return send(res, 200, { session_id: id });\n }\n\n // Eval session end\n if (path === \"/eval/end\" && method === \"POST\") {\n const body = await parseBody(req);\n endEvalSession(db, body.session_id);\n return send(res, 200, { success: true });\n }\n\n // Eval counter increment\n if (path === \"/eval/increment\" && method === \"POST\") {\n const body = await parseBody(req);\n incrementEvalCounter(db, body.session_id, body.field, body.amount ?? 1);\n return send(res, 200, { success: true });\n }\n\n // Record implicit signal\n if (path === \"/signal\" && method === \"POST\") {\n const body = await parseBody(req);\n const id = recordSignal(\n db,\n body.memory_id,\n body.session_id ?? \"daemon\",\n body.signal_type,\n body.context,\n );\n const mem = getMemory(db, body.memory_id);\n createActivityEvent(db, {\n session_id: body.session_id ?? \"daemon\",\n repo: mem?.repo ?? null,\n path: mem?.path_scope ?? null,\n source: \"daemon\",\n event_type: \"signal\",\n memory_ids: [body.memory_id],\n request: { signal_type: body.signal_type, context: body.context ?? null },\n result: { signal_id: id },\n });\n return send(res, 200, { signal_id: id });\n }\n\n // Signal stats\n if (path.startsWith(\"/signal/stats/\") && method === \"GET\") {\n const memId = path.slice(\"/signal/stats/\".length);\n const stats = getSignalStats(db, memId);\n return send(res, 200, stats);\n }\n\n // Run tests + record signals\n if (path === \"/test\" && method === \"POST\") {\n const body = await parseBody(req);\n const testResult = runTests(body.repo_path, body.command);\n const signalIds = recordTestSignals(\n db,\n body.session_id ?? \"daemon\",\n body.memory_ids ?? [],\n testResult,\n );\n return send(res, 200, {\n passed: testResult.passed,\n signals: signalIds,\n output: testResult.output?.slice(0, 1000),\n });\n }\n\n // Quality profile\n if (path === \"/quality\" && method === \"GET\") {\n const repo = url.searchParams.get(\"repo\") ?? undefined;\n return send(res, 200, getRepoQualityProfile(db, repo));\n }\n\n if (path === \"/activity\" && method === \"GET\") {\n const repo = url.searchParams.get(\"repo\") ?? undefined;\n const session_id = url.searchParams.get(\"session_id\") ?? undefined;\n const source = url.searchParams.get(\"source\") as any;\n const event_type = url.searchParams.get(\"event_type\") as any;\n const since = url.searchParams.get(\"since\") ?? undefined;\n const limit = parseInt(url.searchParams.get(\"limit\") ?? \"20\", 10);\n return send(res, 200, {\n events: listActivityEvents(db, { repo, session_id, source, event_type, since, limit }),\n });\n }\n\n if (path === \"/sessions\" && method === \"GET\") {\n const repo = url.searchParams.get(\"repo\") ?? undefined;\n const source = url.searchParams.get(\"source\") as any;\n const event_type = url.searchParams.get(\"event_type\") as any;\n const since = url.searchParams.get(\"since\") ?? undefined;\n const limit = parseInt(url.searchParams.get(\"limit\") ?? \"20\", 10);\n return send(res, 200, {\n sessions: listActivitySessions(db, { repo, source, event_type, since, limit }),\n });\n }\n\n // --- Phase 3 endpoints ---\n\n // Policy: list\n if (path === \"/policy/list\" && method === \"GET\") {\n const orgId = url.searchParams.get(\"org_id\") ?? \"\";\n return send(res, 200, { policies: listPolicies(db, orgId) });\n }\n\n // Policy: create\n if (path === \"/policy\" && method === \"POST\") {\n const body = await parseBody(req);\n const id = createPolicy(db, body.org_id, body.rule_type, body.config);\n return send(res, 200, { policy_id: id });\n }\n\n // Policy: evaluate\n if (path === \"/policy/check\" && method === \"POST\") {\n const body = await parseBody(req);\n const mem = getMemory(db, body.memory_id);\n if (!mem) return send(res, 404, { error: \"memory not found\" });\n const violations = evaluatePolicy(db, body.org_id, mem);\n return send(res, 200, { violations });\n }\n\n // Approval: request\n if (path === \"/approval/request\" && method === \"POST\") {\n const body = await parseBody(req);\n const id = requestApproval(db, body.memory_id, body.org_id, body.requested_by ?? \"daemon\");\n return send(res, 200, { approval_id: id });\n }\n\n // Approval: list pending\n if (path === \"/approval/pending\" && method === \"GET\") {\n const orgId = url.searchParams.get(\"org_id\") ?? \"\";\n return send(res, 200, { approvals: listPendingApprovals(db, orgId) });\n }\n\n // Approval: resolve\n if (path === \"/approval/resolve\" && method === \"POST\") {\n const body = await parseBody(req);\n const ok = resolveApproval(db, body.approval_id, body.status, body.reviewed_by ?? \"daemon\", body.reason);\n return send(res, ok ? 200 : 404, { success: ok });\n }\n\n // Health: single memory\n if (path.startsWith(\"/health/\") && method === \"GET\") {\n const memId = path.slice(\"/health/\".length);\n const score = computeHealthScore(db, memId);\n if (!score) return send(res, 404, { error: \"not found\" });\n return send(res, 200, score);\n }\n\n // Health: all\n if (path === \"/health\" && method === \"GET\") {\n const repo = url.searchParams.get(\"repo\") ?? undefined;\n const scores = computeAllHealthScores(db, repo);\n return send(res, 200, { scores });\n }\n\n // Contradictions: detect\n if (path === \"/contradictions/detect\" && method === \"POST\") {\n const body = await parseBody(req);\n const found = detectContradictions(db, body.repo);\n return send(res, 200, { contradictions: found });\n }\n\n // Contradictions: list\n if (path === \"/contradictions\" && method === \"GET\") {\n const resolved = url.searchParams.get(\"resolved\");\n const items = listContradictions(db, {\n resolved: resolved === \"true\" ? true : resolved === \"false\" ? false : undefined,\n });\n return send(res, 200, { contradictions: items });\n }\n\n // Contradictions: resolve\n if (path === \"/contradictions/resolve\" && method === \"POST\") {\n const body = await parseBody(req);\n const ok = resolveContradiction(db, body.contradiction_id, body.keep_memory_id, body.actor ?? \"daemon\", body.resolution);\n return send(res, ok ? 200 : 404, { success: ok });\n }\n\n // Contradictions: auto-resolve\n if (path === \"/contradictions/auto-resolve\" && method === \"POST\") {\n const body = await parseBody(req);\n const count = autoResolveContradictions(db, body.repo);\n return send(res, 200, { resolved: count });\n }\n\n // Prune\n if (path === \"/prune\" && method === \"POST\") {\n const body = await parseBody(req);\n const result = pruneMemories(db, body.config);\n return send(res, 200, result);\n }\n\n // Audit: trail for memory\n if (path.startsWith(\"/audit/memory/\") && method === \"GET\") {\n const memId = path.slice(\"/audit/memory/\".length);\n const entries = getAuditTrail(db, memId);\n return send(res, 200, { entries });\n }\n\n // Audit: recent\n if (path === \"/audit/recent\" && method === \"GET\") {\n const limit = parseInt(url.searchParams.get(\"limit\") ?? \"50\");\n const entries = getRecentAudit(db, limit);\n return send(res, 200, { entries });\n }\n\n // Audit: rollback\n if (path === \"/audit/rollback\" && method === \"POST\") {\n const body = await parseBody(req);\n const ok = rollbackMemory(db, body.memory_id, body.audit_entry_id, body.actor ?? \"daemon\");\n return send(res, ok ? 200 : 404, { success: ok });\n }\n\n send(res, 404, { error: \"not found\" });\n } catch (err: any) {\n send(res, 500, { error: err.message });\n }\n});\n\nfunction send(\n res: import(\"node:http\").ServerResponse,\n status: number,\n data: any,\n) {\n res.statusCode = status;\n res.end(JSON.stringify(data));\n}\n\nasync function startDaemon() {\n const backup = ensureDailyBackup();\n if (backup.created) {\n console.log(`[recall] backup created ${backup.created} (retained ${backup.retained.length})`);\n }\n\n db = initDb();\n\n server.listen(PORT, () => {\n console.log(`Recall daemon listening on http://localhost:${PORT}`);\n scheduleMaintenanceLoop();\n scheduleDispatcherLoop();\n scheduleCleanupLoop();\n scheduleQualitySnapshotLoop();\n\n setTimeout(() => {\n const embeddingConfig = loadEmbeddingConfigFromEnv();\n if (!embeddingConfig) return;\n\n const info = getEmbeddingModelInfo(embeddingConfig);\n if (info && !info.cached) {\n const approx = info.estimated_size_mb ? `~${info.estimated_size_mb}MB` : \"download\";\n console.log(`[recall] Fetching embedding model (one-time, ${approx}) -> ${info.cache_path}`);\n }\n void ensureEmbeddingProviderReady(embeddingConfig).catch((error: unknown) => {\n const message = error instanceof Error ? error.stack ?? error.message : String(error);\n console.error(`[recall] embedding provider warmup failed: ${message}`);\n });\n }, 60_000).unref?.();\n });\n}\n\nvoid startDaemon().catch((error: unknown) => {\n const message = error instanceof Error ? error.stack ?? error.message : String(error);\n console.error(`[recall] daemon startup failed: ${message}`);\n process.exit(1);\n});\n","import { statSync } from \"node:fs\";\nimport { eq, lt } from \"drizzle-orm\";\nimport type { RecallDb } from \"../db/client.js\";\nimport { activityEvents, feedbackEvents, historySnippets, implicitSignals, memories } from \"../db/schema.js\";\nimport {\n bootstrapEmbeddings,\n loadEmbeddingConfigFromEnv,\n rebuildEmbeddingIndex,\n verifyEmbeddings,\n} from \"../embeddings/embeddings.js\";\nimport {\n createHistorySnippet,\n findHistorySnippetByRepoKind,\n findHistorySnippetBySession,\n listHistorySnippets,\n updateHistorySnippet,\n} from \"../history/snippets.js\";\nimport { bootstrapHistoryEmbeddings, verifyHistoryEmbeddings } from \"../history/retrieval.js\";\nimport { pruneMemories } from \"../pruning/pruner.js\";\nimport { listActivityEvents } from \"../models/activity.js\";\nimport { getMemory, promoteMemory, queryMemories, rejectMemory, statusFromConfidence } from \"../models/memory.js\";\nimport { recordAuditWithSnapshot } from \"../audit/trail.js\";\nimport { getRepoQualityProfile } from \"../repo/quality.js\";\nimport { removeHistoryFtsRow, syncHistoryFtsIndex } from \"../vector/sqlite-fts-history.js\";\nimport { removeHistoryVecRow } from \"../vector/sqlite-vec-history.js\";\nimport { queueMemoryEmbeddingSync } from \"../embeddings/embeddings.js\";\nimport { evaluateScannedMemory } from \"../scanner/signal.js\";\nimport { detectCorrections } from \"../capture/correction.js\";\nimport {\n DEFAULT_ENQUEUE_CONFIG,\n enqueueMaintenanceTasks,\n type EnqueueConfig,\n} from \"./tasks.js\";\n\nexport interface MaintenanceConfig {\n enabled: boolean;\n interval_seconds: number;\n stale_days: number;\n min_health_score: number;\n activity_retention_days: number;\n feedback_retention_days: number;\n signal_retention_days: number;\n history_session_retention_days: number;\n sqlite_analyze_enabled: boolean;\n sqlite_optimize_enabled: boolean;\n sqlite_wal_checkpoint_enabled: boolean;\n sqlite_wal_truncate_bytes: number;\n sqlite_vacuum_enabled: boolean;\n sqlite_vacuum_min_free_pages: number;\n sqlite_vacuum_min_free_ratio: number;\n llm_tasks_enabled: boolean;\n llm_task_config: EnqueueConfig;\n}\n\nexport interface MaintenanceResult {\n prune_total: number;\n stale_rejected: number;\n rejected_pruned: number;\n transient_pruned: number;\n unhealthy_demoted: number;\n scanned_memories_normalized: number;\n scanned_memories_demoted: number;\n scanned_memories_rejected: number;\n activity_pruned: number;\n feedback_pruned: number;\n signals_pruned: number;\n embeddings_refreshed: number;\n vector_rows_rebuilt: number;\n lexical_rows_rebuilt: number;\n embedding_stale: number;\n vector_drift: number;\n lexical_drift: number;\n history_snippets_created: number;\n history_summaries_created: number;\n history_session_deleted: number;\n history_embeddings_refreshed: number;\n history_vector_drift: number;\n history_lexical_drift: number;\n candidates_promoted: number;\n sqlite_analyze_ran: boolean;\n sqlite_optimize_ran: boolean;\n sqlite_checkpoint_ran: boolean;\n sqlite_vacuum_ran: boolean;\n sqlite_page_count: number;\n sqlite_freelist_count: number;\n maintenance_tasks_enqueued: number;\n maintenance_leases_swept: number;\n maintenance_tasks_dropped: number;\n maintenance_tasks_expired: number;\n}\n\nconst DAY_MS = 86_400_000;\n\nexport function loadMaintenanceConfigFromEnv(): MaintenanceConfig {\n return {\n enabled: process.env.RECALL_MAINTENANCE_ENABLED !== \"false\",\n interval_seconds: parseInt(process.env.RECALL_MAINTENANCE_INTERVAL_SECONDS ?? \"300\", 10),\n stale_days: parseInt(process.env.RECALL_MAINTENANCE_STALE_DAYS ?? \"90\", 10),\n min_health_score: parseFloat(process.env.RECALL_MAINTENANCE_MIN_HEALTH_SCORE ?? \"0.2\"),\n activity_retention_days: parseInt(process.env.RECALL_ACTIVITY_RETENTION_DAYS ?? \"90\", 10),\n feedback_retention_days: parseInt(process.env.RECALL_FEEDBACK_RETENTION_DAYS ?? \"180\", 10),\n signal_retention_days: parseInt(process.env.RECALL_SIGNAL_RETENTION_DAYS ?? \"180\", 10),\n history_session_retention_days: parseInt(process.env.RECALL_HISTORY_SESSION_RETENTION_DAYS ?? \"30\", 10),\n sqlite_analyze_enabled: process.env.RECALL_SQLITE_ANALYZE_ENABLED !== \"false\",\n sqlite_optimize_enabled: process.env.RECALL_SQLITE_OPTIMIZE_ENABLED !== \"false\",\n sqlite_wal_checkpoint_enabled: process.env.RECALL_SQLITE_CHECKPOINT_ENABLED !== \"false\",\n sqlite_wal_truncate_bytes: parseInt(\n process.env.RECALL_SQLITE_WAL_TRUNCATE_BYTES ?? String(32 * 1024 * 1024),\n 10,\n ),\n sqlite_vacuum_enabled: process.env.RECALL_SQLITE_VACUUM_ENABLED === \"true\",\n sqlite_vacuum_min_free_pages: parseInt(process.env.RECALL_SQLITE_VACUUM_MIN_FREE_PAGES ?? \"100\", 10),\n sqlite_vacuum_min_free_ratio: parseFloat(process.env.RECALL_SQLITE_VACUUM_MIN_FREE_RATIO ?? \"0.1\"),\n llm_tasks_enabled: process.env.RECALL_MAINTENANCE_LLM_DISABLED !== \"true\",\n llm_task_config: {\n max_pending: parseInt(process.env.RECALL_MAINTENANCE_MAX_PENDING ?? String(DEFAULT_ENQUEUE_CONFIG.max_pending), 10),\n max_per_kind: parseInt(process.env.RECALL_MAINTENANCE_MAX_PER_KIND ?? String(DEFAULT_ENQUEUE_CONFIG.max_per_kind), 10),\n refine_min_repetition: parseInt(process.env.RECALL_MAINTENANCE_REFINE_MIN_REPETITION ?? String(DEFAULT_ENQUEUE_CONFIG.refine_min_repetition), 10),\n summary_max_age_days: parseInt(process.env.RECALL_MAINTENANCE_SUMMARY_MAX_AGE_DAYS ?? String(DEFAULT_ENQUEUE_CONFIG.summary_max_age_days), 10),\n merge_similarity_threshold: parseFloat(process.env.RECALL_MAINTENANCE_MERGE_SIMILARITY_THRESHOLD ?? String(DEFAULT_ENQUEUE_CONFIG.merge_similarity_threshold)),\n session_min_activity_events: parseInt(process.env.RECALL_MAINTENANCE_SESSION_MIN_EVENTS ?? String(DEFAULT_ENQUEUE_CONFIG.session_min_activity_events), 10),\n repo_synthesis_min_memories: parseInt(process.env.RECALL_MAINTENANCE_REPO_SYNTHESIS_MIN_MEMORIES ?? String(DEFAULT_ENQUEUE_CONFIG.repo_synthesis_min_memories), 10),\n repo_synthesis_refresh_days: parseInt(process.env.RECALL_MAINTENANCE_REPO_SYNTHESIS_REFRESH_DAYS ?? String(DEFAULT_ENQUEUE_CONFIG.repo_synthesis_refresh_days), 10),\n },\n };\n}\n\nexport async function runMaintenanceCycle(\n db: RecallDb,\n config: MaintenanceConfig = loadMaintenanceConfigFromEnv(),\n): Promise<MaintenanceResult> {\n const prune = pruneMemories(db, {\n stale_days: config.stale_days,\n min_health_score: config.min_health_score,\n });\n const scannedMemoryCleanup = reconcileScannedMemories(db);\n const candidates_promoted = promoteRepetitionCandidates(db);\n\n const activity_pruned = pruneOldActivityEvents(db, config.activity_retention_days);\n const feedback_pruned = pruneOldFeedbackEvents(db, config.feedback_retention_days);\n const signals_pruned = pruneOldImplicitSignals(db, config.signal_retention_days);\n const sqliteMaintenance = runSqliteMaintenance(db, config);\n\n let embeddings_refreshed = 0;\n let vector_rows_rebuilt = 0;\n let lexical_rows_rebuilt = 0;\n let embedding_stale = 0;\n let vector_drift = 0;\n let lexical_drift = 0;\n const history_snippets_created = rollupSessionHistory(db);\n const history_summaries_created = summarizeHistorySnippets(db);\n const history_session_deleted = cleanupSessionHistory(db, config.history_session_retention_days);\n let history_embeddings_refreshed = 0;\n let history_vector_drift = 0;\n let history_lexical_drift = 0;\n\n const embeddingConfig = loadEmbeddingConfigFromEnv();\n if (embeddingConfig) {\n const verify = verifyEmbeddings(db, embeddingConfig);\n embedding_stale = verify.stale;\n vector_drift = verify.index_drift;\n lexical_drift = verify.lexical_drift;\n\n if (embedding_stale > 0) {\n embeddings_refreshed = await bootstrapEmbeddings(db, embeddingConfig);\n }\n\n if (vector_drift !== 0 || lexical_drift !== 0) {\n const rebuilt = rebuildEmbeddingIndex(db, embeddingConfig);\n vector_rows_rebuilt = rebuilt.vector_rows;\n lexical_rows_rebuilt = rebuilt.lexical_rows;\n }\n\n const historyVerify = verifyHistoryEmbeddings(db, embeddingConfig);\n history_vector_drift = historyVerify.index_drift;\n history_lexical_drift = historyVerify.lexical_drift;\n if (\n historyVerify.stale > 0 ||\n history_snippets_created > 0 ||\n history_summaries_created > 0 ||\n history_session_deleted > 0\n ) {\n history_embeddings_refreshed = await bootstrapHistoryEmbeddings(db, embeddingConfig);\n }\n }\n\n const tasks = config.llm_tasks_enabled\n ? await enqueueMaintenanceTasks(db, config.llm_task_config)\n : { tasks_enqueued: 0, per_kind: {}, expired_leases_swept: 0, dropped_over_cap: 0, expired_pending_tasks: 0 };\n\n return {\n prune_total: prune.total,\n stale_rejected: prune.stale_rejected.length,\n rejected_pruned: prune.rejected_pruned.length,\n transient_pruned: prune.transient_pruned.length,\n unhealthy_demoted: prune.unhealthy_demoted.length,\n scanned_memories_normalized: scannedMemoryCleanup.normalized,\n scanned_memories_demoted: scannedMemoryCleanup.demoted,\n scanned_memories_rejected: scannedMemoryCleanup.rejected,\n activity_pruned,\n feedback_pruned,\n signals_pruned,\n embeddings_refreshed,\n vector_rows_rebuilt,\n lexical_rows_rebuilt,\n embedding_stale,\n vector_drift,\n lexical_drift,\n history_snippets_created,\n history_summaries_created,\n history_session_deleted,\n history_embeddings_refreshed,\n history_vector_drift,\n history_lexical_drift,\n candidates_promoted,\n sqlite_analyze_ran: sqliteMaintenance.analyze_ran,\n sqlite_optimize_ran: sqliteMaintenance.optimize_ran,\n sqlite_checkpoint_ran: sqliteMaintenance.checkpoint_ran,\n sqlite_vacuum_ran: sqliteMaintenance.vacuum_ran,\n sqlite_page_count: sqliteMaintenance.page_count,\n sqlite_freelist_count: sqliteMaintenance.freelist_count,\n maintenance_tasks_enqueued: tasks.tasks_enqueued,\n maintenance_leases_swept: tasks.expired_leases_swept,\n maintenance_tasks_dropped: tasks.dropped_over_cap,\n maintenance_tasks_expired: tasks.expired_pending_tasks,\n };\n}\n\nexport function promoteRepetitionCandidates(db: RecallDb): number {\n const candidates = queryMemories(db, { status: \"candidate\" });\n let promoted = 0;\n\n for (const candidate of candidates) {\n if (!candidate.repo) continue;\n const profile = getRepoQualityProfile(db, candidate.repo);\n if (candidate.repetition_count < profile.repeat_sessions_required) continue;\n\n const before = getMemory(db, candidate.id);\n if (!before || before.status !== \"candidate\") continue;\n const ok = promoteMemory(db, candidate.id, \"repeat_correction\");\n if (!ok) continue;\n const after = getMemory(db, candidate.id);\n recordAuditWithSnapshot(\n db,\n candidate.id,\n \"promoted\",\n \"system\",\n `repetition:${candidate.repetition_count}`,\n before,\n after ?? null,\n );\n promoted += 1;\n }\n\n return promoted;\n}\n\nexport function reconcileScannedMemories(db: RecallDb): {\n normalized: number;\n demoted: number;\n rejected: number;\n} {\n const scanned = queryMemories(db, {})\n .filter((memory) =>\n memory.status !== \"rejected\" &&\n (memory.source === \"repo_scan\" || memory.source === \"config_parse\")\n );\n\n let normalized = 0;\n let demoted = 0;\n let rejected = 0;\n\n for (const memory of scanned) {\n const evaluated = evaluateScannedMemory({\n text: memory.text,\n type: memory.type,\n source: memory.source,\n confidence: memory.confidence,\n });\n\n if (evaluated.action === \"reject\") {\n if (memory.status !== \"rejected\") {\n rejectMemory(db, memory.id);\n rejected += 1;\n }\n continue;\n }\n\n const nextStatus = statusFromConfidence(evaluated.confidence);\n const updates: Partial<typeof memories.$inferInsert> = {};\n\n if (memory.text !== evaluated.text) {\n updates.text = evaluated.text;\n normalized += 1;\n }\n if (memory.confidence !== evaluated.confidence) {\n updates.confidence = evaluated.confidence;\n }\n if (memory.status !== nextStatus) {\n updates.status = nextStatus;\n if (memory.status === \"active\" && nextStatus === \"candidate\") {\n demoted += 1;\n }\n }\n\n if (Object.keys(updates).length === 0) continue;\n\n updates.updated_at = new Date().toISOString();\n db.update(memories)\n .set(updates)\n .where(eq(memories.id, memory.id))\n .run();\n queueMemoryEmbeddingSync(db, memory.id);\n }\n\n return { normalized, demoted, rejected };\n}\n\nexport function runSqliteMaintenance(\n db: RecallDb,\n config: Pick<\n MaintenanceConfig,\n | \"sqlite_analyze_enabled\"\n | \"sqlite_optimize_enabled\"\n | \"sqlite_wal_checkpoint_enabled\"\n | \"sqlite_wal_truncate_bytes\"\n | \"sqlite_vacuum_enabled\"\n | \"sqlite_vacuum_min_free_pages\"\n | \"sqlite_vacuum_min_free_ratio\"\n >,\n) {\n const sqlite = db.$client;\n\n const pageCount = Number((sqlite.pragma(\"page_count\", { simple: true }) as number | bigint) ?? 0);\n const freelistCount = Number((sqlite.pragma(\"freelist_count\", { simple: true }) as number | bigint) ?? 0);\n const freeRatio = pageCount > 0 ? freelistCount / pageCount : 0;\n\n let analyzeRan = false;\n let optimizeRan = false;\n let checkpointRan = false;\n let vacuumRan = false;\n\n if (config.sqlite_analyze_enabled) {\n sqlite.exec(\"ANALYZE;\");\n analyzeRan = true;\n }\n\n if (config.sqlite_wal_checkpoint_enabled) {\n const mode = shouldTruncateWal(sqlite, config.sqlite_wal_truncate_bytes)\n ? \"TRUNCATE\"\n : \"PASSIVE\";\n sqlite.pragma(`wal_checkpoint(${mode})`);\n checkpointRan = true;\n }\n\n if (config.sqlite_optimize_enabled) {\n sqlite.pragma(\"optimize\");\n optimizeRan = true;\n }\n\n if (\n config.sqlite_vacuum_enabled &&\n freelistCount >= config.sqlite_vacuum_min_free_pages &&\n freeRatio >= config.sqlite_vacuum_min_free_ratio\n ) {\n sqlite.exec(\"VACUUM;\");\n vacuumRan = true;\n }\n\n return {\n analyze_ran: analyzeRan,\n optimize_ran: optimizeRan,\n checkpoint_ran: checkpointRan,\n vacuum_ran: vacuumRan,\n page_count: pageCount,\n freelist_count: freelistCount,\n };\n}\n\nfunction shouldTruncateWal(\n sqlite: { name: string },\n thresholdBytes: number,\n): boolean {\n if (!Number.isFinite(thresholdBytes) || thresholdBytes <= 0) return false;\n try {\n return statSync(`${sqlite.name}-wal`).size >= thresholdBytes;\n } catch {\n return false;\n }\n}\n\nexport function pruneOldActivityEvents(\n db: RecallDb,\n retentionDays: number,\n): number {\n const cutoff = new Date(Date.now() - (retentionDays * DAY_MS)).toISOString();\n return db.delete(activityEvents)\n .where(lt(activityEvents.created_at, cutoff))\n .run().changes;\n}\n\nexport function pruneOldFeedbackEvents(\n db: RecallDb,\n retentionDays: number,\n): number {\n const cutoff = new Date(Date.now() - (retentionDays * DAY_MS)).toISOString();\n return db.delete(feedbackEvents)\n .where(lt(feedbackEvents.timestamp, cutoff))\n .run().changes;\n}\n\nexport function pruneOldImplicitSignals(\n db: RecallDb,\n retentionDays: number,\n): number {\n const cutoff = new Date(Date.now() - (retentionDays * DAY_MS)).toISOString();\n return db.delete(implicitSignals)\n .where(lt(implicitSignals.timestamp, cutoff))\n .run().changes;\n}\n\nexport function rollupSessionHistory(db: RecallDb): number {\n const sessionEnds = listActivityEvents(db, { event_type: \"session_end\", limit: 500 });\n let createdOrUpdated = 0;\n\n for (const end of sessionEnds) {\n if (!end.session_id) continue;\n const existing = findHistorySnippetBySession(db, end.session_id, \"session_summary\");\n\n const events = listActivityEvents(db, { session_id: end.session_id })\n .sort((a, b) => a.created_at.localeCompare(b.created_at));\n if (events.length === 0) continue;\n\n const repo = end.repo ?? events.find((event) => event.repo)?.repo ?? null;\n const summary = summarizeSessionEvents(events);\n const sourceActivityIds = events.map((event) => event.id);\n\n if (existing) {\n if (existing.text !== summary) {\n updateHistorySnippet(db, existing.id, {\n text: summary,\n source_activity_ids: sourceActivityIds,\n });\n syncHistoryFtsIndex(db, existing.id);\n createdOrUpdated++;\n }\n continue;\n }\n\n const id = createHistorySnippet(db, {\n repo,\n session_id: end.session_id,\n kind: \"session_summary\",\n text: summary,\n source_activity_ids: sourceActivityIds,\n });\n syncHistoryFtsIndex(db, id);\n createdOrUpdated++;\n }\n\n return createdOrUpdated;\n}\n\nexport function summarizeHistorySnippets(db: RecallDb): number {\n const sessionSnippets = listHistorySnippets(db, {\n kind: \"session_summary\",\n limit: 1000,\n });\n\n const byRepo = new Map<string, typeof sessionSnippets>();\n for (const snippet of sessionSnippets) {\n if (!snippet.repo) continue;\n const bucket = byRepo.get(snippet.repo) ?? [];\n bucket.push(snippet);\n byRepo.set(snippet.repo, bucket);\n }\n\n let createdOrUpdated = 0;\n for (const [repo, snippets] of byRepo.entries()) {\n const aggregated = aggregateRepoHistory(repo, snippets);\n for (const item of aggregated) {\n if (!item.text) continue;\n\n const existing = findHistorySnippetByRepoKind(db, repo, item.kind);\n if (existing) {\n if (existing.text !== item.text) {\n updateHistorySnippet(db, existing.id, {\n text: item.text,\n source_activity_ids: item.source_activity_ids,\n });\n syncHistoryFtsIndex(db, existing.id);\n createdOrUpdated++;\n }\n continue;\n }\n\n const id = createHistorySnippet(db, {\n repo,\n kind: item.kind,\n text: item.text,\n source_activity_ids: item.source_activity_ids,\n });\n syncHistoryFtsIndex(db, id);\n createdOrUpdated++;\n }\n }\n\n return createdOrUpdated;\n}\n\nexport function cleanupSessionHistory(\n db: RecallDb,\n retentionDays: number,\n): number {\n const cutoff = new Date(Date.now() - (retentionDays * DAY_MS)).toISOString();\n const sessionSnippets = listHistorySnippets(db, {\n kind: \"session_summary\",\n limit: 1000,\n });\n\n let deleted = 0;\n for (const snippet of sessionSnippets) {\n if (!snippet.repo) continue;\n if (snippet.created_at >= cutoff) continue;\n\n const hasRepoSummary =\n findHistorySnippetByRepoKind(db, snippet.repo, \"correction_summary\") ||\n findHistorySnippetByRepoKind(db, snippet.repo, \"decision_summary\") ||\n findHistorySnippetByRepoKind(db, snippet.repo, \"review_summary\") ||\n findHistorySnippetByRepoKind(db, snippet.repo, \"compile_summary\");\n if (!hasRepoSummary) continue;\n\n removeHistoryFtsRow(db, snippet.id);\n removeHistoryVecRow(db, snippet.id);\n db.delete(historySnippets)\n .where(eq(historySnippets.id, snippet.id))\n .run();\n deleted++;\n }\n\n return deleted;\n}\n\nfunction summarizeSessionEvents(\n events: Array<ReturnType<typeof listActivityEvents>[number]>,\n) {\n const repo = events.find((event) => event.repo)?.repo ?? \"unknown\";\n const eventTypes = [...new Set(events.map((event) => event.event_type))];\n const corrections = events\n .filter((event) => event.event_type === \"correction\")\n .map((event) => String(event.request.text ?? \"\"))\n .filter(Boolean);\n const reviews = events\n .filter((event) => event.event_type === \"review\")\n .map((event) => String(event.request.feedback ?? \"\"))\n .filter(Boolean);\n const decisions = extractPromptDecisions(events);\n const compileEvents = events.filter((event) => event.event_type === \"compile\");\n\n const lines = [\n `Repo: ${repo}`,\n `Event types: ${eventTypes.join(\", \")}`,\n ];\n\n if (compileEvents.length > 0) {\n const latestCompile = compileEvents.at(-1);\n const included = Array.isArray(latestCompile?.result.included)\n ? latestCompile.result.included.length\n : 0;\n lines.push(`Latest compile included ${included} memories.`);\n }\n\n if (corrections.length > 0) {\n lines.push(`Corrections: ${corrections.slice(0, 3).join(\" | \")}`);\n }\n\n if (reviews.length > 0) {\n lines.push(`Reviews: ${reviews.slice(0, 3).join(\" | \")}`);\n }\n\n if (decisions.length > 0) {\n lines.push(`Decisions: ${decisions.slice(0, 5).join(\" | \")}`);\n }\n\n return lines.join(\"\\n\");\n}\n\nfunction aggregateRepoHistory(\n repo: string,\n snippets: ReturnType<typeof listHistorySnippets>,\n): Array<{\n kind: \"correction_summary\" | \"decision_summary\" | \"review_summary\" | \"compile_summary\";\n text: string;\n source_activity_ids: string[];\n}> {\n const corrections = new Map<string, number>();\n const decisions = new Map<string, number>();\n const reviews = new Map<string, number>();\n let compileObservations = 0;\n let compileIncludedTotal = 0;\n const sourceActivityIds = new Set<string>();\n\n for (const snippet of snippets) {\n for (const id of snippet.source_activity_ids) {\n sourceActivityIds.add(id);\n }\n\n const lines = snippet.text.split(\"\\n\");\n const correctionsLine = lines.find((line) => line.startsWith(\"Corrections: \"));\n if (correctionsLine) {\n for (const item of correctionsLine.replace(\"Corrections: \", \"\").split(\" | \").filter(Boolean)) {\n corrections.set(item, (corrections.get(item) ?? 0) + 1);\n }\n }\n\n const reviewsLine = lines.find((line) => line.startsWith(\"Reviews: \"));\n if (reviewsLine) {\n for (const item of reviewsLine.replace(\"Reviews: \", \"\").split(\" | \").filter(Boolean)) {\n reviews.set(item, (reviews.get(item) ?? 0) + 1);\n }\n }\n\n const decisionsLine = lines.find((line) => line.startsWith(\"Decisions: \"));\n if (decisionsLine) {\n for (const item of decisionsLine.replace(\"Decisions: \", \"\").split(\" | \").filter(Boolean)) {\n decisions.set(item, (decisions.get(item) ?? 0) + 1);\n }\n }\n\n const compileLine = lines.find((line) => line.startsWith(\"Latest compile included \"));\n if (compileLine) {\n compileObservations++;\n const match = compileLine.match(/included (\\d+) memories/);\n if (match) compileIncludedTotal += parseInt(match[1], 10);\n }\n }\n\n return [\n {\n kind: \"correction_summary\",\n text: renderSummary(repo, \"Frequent corrections\", corrections),\n source_activity_ids: [...sourceActivityIds],\n },\n {\n kind: \"review_summary\",\n text: renderSummary(repo, \"Frequent review guidance\", reviews),\n source_activity_ids: [...sourceActivityIds],\n },\n {\n kind: \"decision_summary\",\n text: renderSummary(repo, \"Frequent user decisions\", decisions),\n source_activity_ids: [...sourceActivityIds],\n },\n {\n kind: \"compile_summary\",\n text: compileObservations > 0\n ? [\n `Repo: ${repo}`,\n `Compile observations: ${compileObservations}`,\n `Average included memories: ${(compileIncludedTotal / compileObservations).toFixed(1)}`,\n ].join(\"\\n\")\n : \"\",\n source_activity_ids: [...sourceActivityIds],\n },\n ];\n}\n\nfunction renderSummary(\n repo: string,\n heading: string,\n counts: Map<string, number>,\n) {\n if (counts.size === 0) return \"\";\n const top = [...counts.entries()]\n .sort((a, b) => b[1] - a[1])\n .slice(0, 5)\n .map(([text, count]) => `- (${count}) ${text}`);\n\n return [\n `Repo: ${repo}`,\n `${heading}:`,\n ...top,\n ].join(\"\\n\");\n}\n\nfunction extractPromptDecisions(\n events: Array<ReturnType<typeof listActivityEvents>[number]>,\n): string[] {\n const seen = new Set<string>();\n const decisions: string[] = [];\n\n for (const event of events) {\n if (event.event_type !== \"session_event\") continue;\n if (event.request.name !== \"prompt_submitted\") continue;\n const text = String(event.result.text ?? \"\").trim();\n if (!text) continue;\n\n const durable = detectCorrections(text)\n .filter((match) => match.type === \"decision\")\n .map((match) => match.text);\n for (const item of durable) {\n addUniqueDecision(seen, decisions, item);\n }\n\n const directive = extractDurablePromptDirective(text);\n if (directive) {\n addUniqueDecision(seen, decisions, directive);\n }\n }\n\n return decisions;\n}\n\nfunction addUniqueDecision(seen: Set<string>, decisions: string[], text: string) {\n const normalized = text.toLowerCase().replace(/\\s+/g, \" \").trim();\n if (!normalized || seen.has(normalized)) return;\n seen.add(normalized);\n decisions.push(text);\n}\n\nfunction extractDurablePromptDirective(text: string): string | null {\n const compact = text\n .replace(/\\s+/g, \" \")\n .replace(/^[-*]\\s+/, \"\")\n .trim();\n const phaseDirective = /\\b(?:do\\s+phase|phase\\s+\\d+)\\b/i.test(compact);\n if ((!phaseDirective && compact.length < 14) || compact.length > 240) return null;\n if (!DURABLE_PROMPT_DIRECTIVE.test(compact)) return null;\n if (!DURABLE_PROMPT_DOMAIN.test(compact)) return null;\n if (/^(?:can|could|would|should|why|what|how)\\b.*\\?$/i.test(compact)) return null;\n return `User direction: ${compact.replace(/[.!?]+$/u, \"\")}.`;\n}\n\nconst DURABLE_PROMPT_DIRECTIVE =\n /\\b(?:let's|lets|let us|we should|we need to|make|improve|add|change|implement|ship|do phase|phase\\s+\\d+|production ready|open source|self[- ]healing|self healing)\\b/i;\n\nconst DURABLE_PROMPT_DOMAIN =\n /\\b(?:recall|memory|memories|dedupe|duplicate|question|prompt|capture|history|summary|quality|maintenance|cleanup|doctor|daemon|dispatcher|migration|test|phase|production|open source|self[- ]healing|self healing)\\b/i;\n","import type { MaintenanceResult } from \"./lifecycle.js\";\n\nexport function maintenanceChangeCount(result: MaintenanceResult): number {\n return (\n result.prune_total +\n result.scanned_memories_normalized +\n result.scanned_memories_demoted +\n result.scanned_memories_rejected +\n result.activity_pruned +\n result.feedback_pruned +\n result.signals_pruned +\n result.embeddings_refreshed +\n result.vector_rows_rebuilt +\n result.lexical_rows_rebuilt +\n result.history_snippets_created +\n result.history_embeddings_refreshed\n );\n}\n\nexport function shouldLogMaintenance(result: MaintenanceResult): boolean {\n return (\n maintenanceChangeCount(result) > 0 ||\n result.vector_drift !== 0 ||\n result.lexical_drift !== 0 ||\n result.embedding_stale > 0 ||\n result.history_vector_drift !== 0 ||\n result.history_lexical_drift !== 0\n );\n}\n\nexport function formatMaintenanceSummary(result: MaintenanceResult): string {\n return (\n `[recall] maintenance ` +\n `prune=${result.prune_total} ` +\n `scanned(normalized=${result.scanned_memories_normalized},demoted=${result.scanned_memories_demoted},rejected=${result.scanned_memories_rejected}) ` +\n `activity=${result.activity_pruned} ` +\n `feedback=${result.feedback_pruned} ` +\n `signals=${result.signals_pruned} ` +\n `refreshed=${result.embeddings_refreshed} ` +\n `rebuilt(vec=${result.vector_rows_rebuilt},fts=${result.lexical_rows_rebuilt}) ` +\n `drift(vec=${result.vector_drift},fts=${result.lexical_drift}) ` +\n `stale=${result.embedding_stale} ` +\n `history(created=${result.history_snippets_created},refreshed=${result.history_embeddings_refreshed},drift_vec=${result.history_vector_drift},drift_fts=${result.history_lexical_drift})`\n );\n}\n","import type { IncomingMessage, ServerResponse } from \"node:http\";\nimport { StreamableHTTPServerTransport } from \"@modelcontextprotocol/sdk/server/streamableHttp.js\";\nimport type { RecallDb } from \"../db/client.js\";\nimport { createRecallMcpServer } from \"./factory.js\";\n\nexport async function handleRecallMcpHttpRequest(\n req: IncomingMessage,\n res: ServerResponse,\n db: RecallDb,\n) {\n if (req.method !== \"POST\") {\n return sendJsonRpcError(res, 405, -32000, \"Method not allowed\");\n }\n\n const mcpServer = createRecallMcpServer(db);\n const transport = new StreamableHTTPServerTransport({\n sessionIdGenerator: undefined,\n enableJsonResponse: true,\n });\n\n try {\n await mcpServer.connect(transport);\n await transport.handleRequest(req, res);\n } catch (error) {\n if (!res.headersSent) {\n sendJsonRpcError(\n res,\n 500,\n -32603,\n error instanceof Error ? error.message : \"Internal server error\",\n );\n }\n } finally {\n await transport.close().catch(() => {});\n await mcpServer.close().catch(() => {});\n }\n}\n\nfunction sendJsonRpcError(\n res: ServerResponse,\n status: number,\n code: number,\n message: string,\n) {\n res.statusCode = status;\n res.setHeader(\"Content-Type\", \"application/json\");\n res.end(JSON.stringify({\n jsonrpc: \"2.0\",\n error: { code, message },\n id: null,\n }));\n}\n"],"mappings":"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","names":["db","db","c"]}
@@ -0,0 +1,16 @@
1
+ import {
2
+ buildPrompt,
3
+ dispatchPendingTasks,
4
+ formatDispatchReport,
5
+ hasAnyLlmProvider
6
+ } from "./chunk-KAGIAOD7.js";
7
+ import "./chunk-A6XEULA4.js";
8
+ import "./chunk-DNFKAHS6.js";
9
+ import "./chunk-4CV4JOE5.js";
10
+ export {
11
+ buildPrompt,
12
+ dispatchPendingTasks,
13
+ formatDispatchReport,
14
+ hasAnyLlmProvider
15
+ };
16
+ //# sourceMappingURL=dispatcher-SUUX5AX6.js.map
package/dist/mcp.js CHANGED
@@ -1,10 +1,10 @@
1
1
  import {
2
2
  createRecallMcpServer
3
- } from "./chunk-FHKV6ELT.js";
4
- import "./chunk-F56Y3SHS.js";
5
- import "./chunk-VEPXEHRZ.js";
6
- import "./chunk-IILLSHLM.js";
7
- import "./chunk-A5UIRZU6.js";
3
+ } from "./chunk-MJ4GGBTL.js";
4
+ import "./chunk-E4HJDGCW.js";
5
+ import "./chunk-KAGIAOD7.js";
6
+ import "./chunk-A6XEULA4.js";
7
+ import "./chunk-DNFKAHS6.js";
8
8
  import "./chunk-4CV4JOE5.js";
9
9
 
10
10
  // src/mcp/server.ts
@@ -4,8 +4,8 @@ import {
4
4
  formatQualityReport,
5
5
  listQualitySnapshots,
6
6
  recordQualitySnapshot
7
- } from "./chunk-LVQW6WHK.js";
8
- import "./chunk-A5UIRZU6.js";
7
+ } from "./chunk-XUM7JEJU.js";
8
+ import "./chunk-A6XEULA4.js";
9
9
  import "./chunk-4CV4JOE5.js";
10
10
  export {
11
11
  computeQualityReport,
@@ -14,4 +14,4 @@ export {
14
14
  listQualitySnapshots,
15
15
  recordQualitySnapshot
16
16
  };
17
- //# sourceMappingURL=quality-Z7LPMMBC.js.map
17
+ //# sourceMappingURL=quality-YTQKAEY6.js.map
@@ -7,6 +7,7 @@ import {
7
7
  applyBacklogCaps,
8
8
  claimTask,
9
9
  deleteTask,
10
+ enqueueExtractRulesFromPrompt,
10
11
  enqueueMaintenanceTasks,
11
12
  enqueueVerifyCapture,
12
13
  expireStalePendingTasks,
@@ -26,8 +27,9 @@ import {
26
27
  submitTask,
27
28
  sweepExpiredLeases,
28
29
  targetKey
29
- } from "./chunk-IILLSHLM.js";
30
- import "./chunk-A5UIRZU6.js";
30
+ } from "./chunk-KAGIAOD7.js";
31
+ import "./chunk-A6XEULA4.js";
32
+ import "./chunk-DNFKAHS6.js";
31
33
  import "./chunk-4CV4JOE5.js";
32
34
  export {
33
35
  DEFAULT_ENQUEUE_CONFIG,
@@ -38,6 +40,7 @@ export {
38
40
  applyBacklogCaps,
39
41
  claimTask,
40
42
  deleteTask,
43
+ enqueueExtractRulesFromPrompt,
41
44
  enqueueMaintenanceTasks,
42
45
  enqueueVerifyCapture,
43
46
  expireStalePendingTasks,
@@ -58,4 +61,4 @@ export {
58
61
  sweepExpiredLeases,
59
62
  targetKey
60
63
  };
61
- //# sourceMappingURL=tasks-UOLSPXJQ.js.map
64
+ //# sourceMappingURL=tasks-GSQUHD4F.js.map
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  llmUsage
3
- } from "./chunk-A5UIRZU6.js";
3
+ } from "./chunk-A6XEULA4.js";
4
4
  import "./chunk-4CV4JOE5.js";
5
5
 
6
6
  // src/llm/usage.ts
@@ -98,4 +98,4 @@ export {
98
98
  formatUsageReport,
99
99
  summarizeUsage
100
100
  };
101
- //# sourceMappingURL=usage-CY3V72YN.js.map
101
+ //# sourceMappingURL=usage-DU4TKVJH.js.map
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@edihasaj/recall",
3
- "version": "0.5.7",
3
+ "version": "0.6.0",
4
4
  "description": "Cross-tool coding memory and instruction compiler",
5
5
  "license": "MIT",
6
6
  "homepage": "https://recallmemory.dev/",