@edihasaj/recall 0.5.2
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.
- package/LICENSE +21 -0
- package/README.md +409 -0
- package/dist/chunk-4CV4JOE5.js +27 -0
- package/dist/chunk-4CV4JOE5.js.map +1 -0
- package/dist/chunk-A5UIRZU6.js +469 -0
- package/dist/chunk-A5UIRZU6.js.map +1 -0
- package/dist/chunk-AYHFPCGY.js +964 -0
- package/dist/chunk-AYHFPCGY.js.map +1 -0
- package/dist/chunk-DNFKAHS6.js +204 -0
- package/dist/chunk-DNFKAHS6.js.map +1 -0
- package/dist/chunk-GC5XMBG4.js +551 -0
- package/dist/chunk-GC5XMBG4.js.map +1 -0
- package/dist/chunk-IILLSHLM.js +3021 -0
- package/dist/chunk-IILLSHLM.js.map +1 -0
- package/dist/chunk-LVQW6WHK.js +146 -0
- package/dist/chunk-LVQW6WHK.js.map +1 -0
- package/dist/chunk-LZ6PMQRX.js +955 -0
- package/dist/chunk-LZ6PMQRX.js.map +1 -0
- package/dist/chunk-PC43MBX5.js +2960 -0
- package/dist/chunk-PC43MBX5.js.map +1 -0
- package/dist/chunk-VEPXEHRZ.js +1763 -0
- package/dist/chunk-VEPXEHRZ.js.map +1 -0
- package/dist/cleanup-TVOX2S2S.js +28 -0
- package/dist/cleanup-TVOX2S2S.js.map +1 -0
- package/dist/cli.js +3425 -0
- package/dist/cli.js.map +1 -0
- package/dist/daemon.js +1298 -0
- package/dist/daemon.js.map +1 -0
- package/dist/dispatcher-UGMU6THT.js +15 -0
- package/dist/dispatcher-UGMU6THT.js.map +1 -0
- package/dist/keychain-5QG52ANO.js +22 -0
- package/dist/keychain-5QG52ANO.js.map +1 -0
- package/dist/mcp.js +21 -0
- package/dist/mcp.js.map +1 -0
- package/dist/quality-Z7LPMMBC.js +17 -0
- package/dist/quality-Z7LPMMBC.js.map +1 -0
- package/dist/sync-server.js +225 -0
- package/dist/sync-server.js.map +1 -0
- package/dist/tasks-UOLSPXJQ.js +61 -0
- package/dist/tasks-UOLSPXJQ.js.map +1 -0
- package/dist/usage-CY3V72YN.js +101 -0
- package/dist/usage-CY3V72YN.js.map +1 -0
- package/drizzle/0000_initial_create.sql +240 -0
- package/drizzle/0001_rich_liz_osborn.sql +21 -0
- package/drizzle/0002_unknown_spot.sql +18 -0
- package/drizzle/0003_red_wendigo.sql +19 -0
- package/drizzle/0004_early_carlie_cooper.sql +1 -0
- package/drizzle/0005_simple_emma_frost.sql +96 -0
- package/drizzle/0006_keen_mongoose.sql +2 -0
- package/drizzle/0007_flawless_maximus.sql +15 -0
- package/drizzle/meta/0000_snapshot.json +1630 -0
- package/drizzle/meta/0001_snapshot.json +1773 -0
- package/drizzle/meta/0002_snapshot.json +1891 -0
- package/drizzle/meta/0003_snapshot.json +2014 -0
- package/drizzle/meta/0004_snapshot.json +2022 -0
- package/drizzle/meta/0005_snapshot.json +2064 -0
- package/drizzle/meta/0006_snapshot.json +2078 -0
- package/drizzle/meta/0007_snapshot.json +2183 -0
- package/drizzle/meta/_journal.json +62 -0
- package/package.json +64 -0
- package/scripts/recall-claude +7 -0
- package/scripts/recall-codex +7 -0
- package/scripts/recall-session +71 -0
|
@@ -0,0 +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 { 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_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_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_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 sqlite.pragma(\"wal_checkpoint(PASSIVE)\");\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\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,15 @@
|
|
|
1
|
+
import {
|
|
2
|
+
buildPrompt,
|
|
3
|
+
dispatchPendingTasks,
|
|
4
|
+
formatDispatchReport
|
|
5
|
+
} from "./chunk-GC5XMBG4.js";
|
|
6
|
+
import "./chunk-IILLSHLM.js";
|
|
7
|
+
import "./chunk-A5UIRZU6.js";
|
|
8
|
+
import "./chunk-DNFKAHS6.js";
|
|
9
|
+
import "./chunk-4CV4JOE5.js";
|
|
10
|
+
export {
|
|
11
|
+
buildPrompt,
|
|
12
|
+
dispatchPendingTasks,
|
|
13
|
+
formatDispatchReport
|
|
14
|
+
};
|
|
15
|
+
//# sourceMappingURL=dispatcher-UGMU6THT.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import {
|
|
2
|
+
deleteApiKey,
|
|
3
|
+
getApiKey,
|
|
4
|
+
getProviderConfig,
|
|
5
|
+
hasProviderConfigured,
|
|
6
|
+
init_keychain,
|
|
7
|
+
listCredentials,
|
|
8
|
+
setApiKey,
|
|
9
|
+
setAzureConfig
|
|
10
|
+
} from "./chunk-DNFKAHS6.js";
|
|
11
|
+
import "./chunk-4CV4JOE5.js";
|
|
12
|
+
init_keychain();
|
|
13
|
+
export {
|
|
14
|
+
deleteApiKey,
|
|
15
|
+
getApiKey,
|
|
16
|
+
getProviderConfig,
|
|
17
|
+
hasProviderConfigured,
|
|
18
|
+
listCredentials,
|
|
19
|
+
setApiKey,
|
|
20
|
+
setAzureConfig
|
|
21
|
+
};
|
|
22
|
+
//# sourceMappingURL=keychain-5QG52ANO.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}
|
package/dist/mcp.js
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import {
|
|
2
|
+
createRecallMcpServer
|
|
3
|
+
} from "./chunk-LZ6PMQRX.js";
|
|
4
|
+
import "./chunk-PC43MBX5.js";
|
|
5
|
+
import "./chunk-VEPXEHRZ.js";
|
|
6
|
+
import "./chunk-IILLSHLM.js";
|
|
7
|
+
import "./chunk-A5UIRZU6.js";
|
|
8
|
+
import "./chunk-4CV4JOE5.js";
|
|
9
|
+
|
|
10
|
+
// src/mcp/server.ts
|
|
11
|
+
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
|
|
12
|
+
async function main() {
|
|
13
|
+
const server = createRecallMcpServer();
|
|
14
|
+
const transport = new StdioServerTransport();
|
|
15
|
+
await server.connect(transport);
|
|
16
|
+
}
|
|
17
|
+
main().catch((error) => {
|
|
18
|
+
console.error(error);
|
|
19
|
+
process.exitCode = 1;
|
|
20
|
+
});
|
|
21
|
+
//# sourceMappingURL=mcp.js.map
|
package/dist/mcp.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/mcp/server.ts"],"sourcesContent":["import { StdioServerTransport } from \"@modelcontextprotocol/sdk/server/stdio.js\";\nimport { createRecallMcpServer } from \"./factory.js\";\n\nasync function main() {\n const server = createRecallMcpServer();\n const transport = new StdioServerTransport();\n await server.connect(transport);\n}\n\nmain().catch((error: unknown) => {\n console.error(error);\n process.exitCode = 1;\n});\n"],"mappings":";;;;;;;;;;AAAA,SAAS,4BAA4B;AAGrC,eAAe,OAAO;AACpB,QAAM,SAAS,sBAAsB;AACrC,QAAM,YAAY,IAAI,qBAAqB;AAC3C,QAAM,OAAO,QAAQ,SAAS;AAChC;AAEA,KAAK,EAAE,MAAM,CAAC,UAAmB;AAC/B,UAAQ,MAAM,KAAK;AACnB,UAAQ,WAAW;AACrB,CAAC;","names":[]}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import {
|
|
2
|
+
computeQualityReport,
|
|
3
|
+
diffQualitySnapshots,
|
|
4
|
+
formatQualityReport,
|
|
5
|
+
listQualitySnapshots,
|
|
6
|
+
recordQualitySnapshot
|
|
7
|
+
} from "./chunk-LVQW6WHK.js";
|
|
8
|
+
import "./chunk-A5UIRZU6.js";
|
|
9
|
+
import "./chunk-4CV4JOE5.js";
|
|
10
|
+
export {
|
|
11
|
+
computeQualityReport,
|
|
12
|
+
diffQualitySnapshots,
|
|
13
|
+
formatQualityReport,
|
|
14
|
+
listQualitySnapshots,
|
|
15
|
+
recordQualitySnapshot
|
|
16
|
+
};
|
|
17
|
+
//# sourceMappingURL=quality-Z7LPMMBC.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}
|
|
@@ -0,0 +1,225 @@
|
|
|
1
|
+
// src/sync/server.ts
|
|
2
|
+
import { createServer } from "http";
|
|
3
|
+
import Database from "better-sqlite3";
|
|
4
|
+
import { randomUUID } from "crypto";
|
|
5
|
+
import { join } from "path";
|
|
6
|
+
import { mkdirSync } from "fs";
|
|
7
|
+
var PORT = parseInt(process.env.RECALL_SYNC_PORT ?? "7891", 10);
|
|
8
|
+
var DATA_DIR = process.env.RECALL_SYNC_DATA_DIR ?? join(process.env.HOME ?? ".", ".recall", "sync-server");
|
|
9
|
+
mkdirSync(DATA_DIR, { recursive: true });
|
|
10
|
+
var sqlite = new Database(join(DATA_DIR, "sync.db"));
|
|
11
|
+
sqlite.pragma("journal_mode = WAL");
|
|
12
|
+
sqlite.pragma("foreign_keys = ON");
|
|
13
|
+
sqlite.exec(`
|
|
14
|
+
CREATE TABLE IF NOT EXISTS teams (
|
|
15
|
+
id TEXT PRIMARY KEY,
|
|
16
|
+
name TEXT NOT NULL,
|
|
17
|
+
created_by TEXT NOT NULL,
|
|
18
|
+
created_at TEXT NOT NULL
|
|
19
|
+
);
|
|
20
|
+
|
|
21
|
+
CREATE TABLE IF NOT EXISTS team_members (
|
|
22
|
+
id TEXT PRIMARY KEY,
|
|
23
|
+
team_id TEXT NOT NULL REFERENCES teams(id),
|
|
24
|
+
user_id TEXT NOT NULL,
|
|
25
|
+
role TEXT NOT NULL DEFAULT 'member',
|
|
26
|
+
joined_at TEXT NOT NULL,
|
|
27
|
+
UNIQUE(team_id, user_id)
|
|
28
|
+
);
|
|
29
|
+
|
|
30
|
+
CREATE TABLE IF NOT EXISTS api_keys (
|
|
31
|
+
key TEXT PRIMARY KEY,
|
|
32
|
+
user_id TEXT NOT NULL,
|
|
33
|
+
created_at TEXT NOT NULL
|
|
34
|
+
);
|
|
35
|
+
|
|
36
|
+
CREATE TABLE IF NOT EXISTS shared_memories (
|
|
37
|
+
id TEXT PRIMARY KEY,
|
|
38
|
+
team_id TEXT NOT NULL REFERENCES teams(id),
|
|
39
|
+
type TEXT NOT NULL,
|
|
40
|
+
text TEXT NOT NULL,
|
|
41
|
+
scope TEXT NOT NULL,
|
|
42
|
+
path_scope TEXT,
|
|
43
|
+
repo TEXT,
|
|
44
|
+
status TEXT NOT NULL,
|
|
45
|
+
confidence REAL NOT NULL DEFAULT 0,
|
|
46
|
+
source TEXT NOT NULL,
|
|
47
|
+
evidence TEXT NOT NULL DEFAULT '[]',
|
|
48
|
+
supersedes TEXT,
|
|
49
|
+
created_at TEXT NOT NULL,
|
|
50
|
+
updated_at TEXT NOT NULL,
|
|
51
|
+
pushed_by TEXT NOT NULL,
|
|
52
|
+
sync_version INTEGER NOT NULL DEFAULT 0,
|
|
53
|
+
origin_id TEXT NOT NULL
|
|
54
|
+
);
|
|
55
|
+
|
|
56
|
+
CREATE INDEX IF NOT EXISTS idx_shared_team ON shared_memories(team_id);
|
|
57
|
+
CREATE INDEX IF NOT EXISTS idx_shared_version ON shared_memories(team_id, sync_version);
|
|
58
|
+
`);
|
|
59
|
+
var stmts = {
|
|
60
|
+
getApiKey: sqlite.prepare("SELECT * FROM api_keys WHERE key = ?"),
|
|
61
|
+
createTeam: sqlite.prepare(
|
|
62
|
+
"INSERT INTO teams (id, name, created_by, created_at) VALUES (?, ?, ?, ?)"
|
|
63
|
+
),
|
|
64
|
+
getTeam: sqlite.prepare("SELECT * FROM teams WHERE id = ?"),
|
|
65
|
+
addMember: sqlite.prepare(
|
|
66
|
+
"INSERT OR IGNORE INTO team_members (id, team_id, user_id, role, joined_at) VALUES (?, ?, ?, ?, ?)"
|
|
67
|
+
),
|
|
68
|
+
getMembers: sqlite.prepare("SELECT * FROM team_members WHERE team_id = ?"),
|
|
69
|
+
isMember: sqlite.prepare(
|
|
70
|
+
"SELECT * FROM team_members WHERE team_id = ? AND user_id = ?"
|
|
71
|
+
),
|
|
72
|
+
getMaxVersion: sqlite.prepare(
|
|
73
|
+
"SELECT COALESCE(MAX(sync_version), 0) as max_version FROM shared_memories WHERE team_id = ?"
|
|
74
|
+
),
|
|
75
|
+
pushMemory: sqlite.prepare(`
|
|
76
|
+
INSERT OR REPLACE INTO shared_memories
|
|
77
|
+
(id, team_id, type, text, scope, path_scope, repo, status, confidence, source, evidence, supersedes, created_at, updated_at, pushed_by, sync_version, origin_id)
|
|
78
|
+
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
|
|
79
|
+
`),
|
|
80
|
+
pullMemories: sqlite.prepare(
|
|
81
|
+
"SELECT * FROM shared_memories WHERE team_id = ? AND sync_version > ? ORDER BY sync_version ASC"
|
|
82
|
+
),
|
|
83
|
+
createApiKey: sqlite.prepare(
|
|
84
|
+
"INSERT INTO api_keys (key, user_id, created_at) VALUES (?, ?, ?)"
|
|
85
|
+
)
|
|
86
|
+
};
|
|
87
|
+
function authenticate(req) {
|
|
88
|
+
const auth = req.headers.authorization;
|
|
89
|
+
if (!auth?.startsWith("Bearer ")) return null;
|
|
90
|
+
const key = auth.slice(7);
|
|
91
|
+
const row = stmts.getApiKey.get(key);
|
|
92
|
+
if (!row) return null;
|
|
93
|
+
return { user_id: row.user_id };
|
|
94
|
+
}
|
|
95
|
+
function parseBody(req) {
|
|
96
|
+
return new Promise((resolve, reject) => {
|
|
97
|
+
const chunks = [];
|
|
98
|
+
req.on("data", (c) => chunks.push(c));
|
|
99
|
+
req.on("end", () => {
|
|
100
|
+
try {
|
|
101
|
+
resolve(JSON.parse(Buffer.concat(chunks).toString()));
|
|
102
|
+
} catch {
|
|
103
|
+
resolve({});
|
|
104
|
+
}
|
|
105
|
+
});
|
|
106
|
+
req.on("error", reject);
|
|
107
|
+
});
|
|
108
|
+
}
|
|
109
|
+
function send(res, status, data) {
|
|
110
|
+
res.setHeader("Content-Type", "application/json");
|
|
111
|
+
res.statusCode = status;
|
|
112
|
+
res.end(JSON.stringify(data));
|
|
113
|
+
}
|
|
114
|
+
var server = createServer(async (req, res) => {
|
|
115
|
+
const url = new URL(req.url ?? "/", `http://localhost:${PORT}`);
|
|
116
|
+
const path = url.pathname;
|
|
117
|
+
const method = req.method ?? "GET";
|
|
118
|
+
try {
|
|
119
|
+
if (path === "/health" && method === "GET") {
|
|
120
|
+
return send(res, 200, { status: "ok", service: "recall-sync" });
|
|
121
|
+
}
|
|
122
|
+
if (path === "/api/bootstrap" && method === "POST") {
|
|
123
|
+
const body = await parseBody(req);
|
|
124
|
+
const key = `rk_${randomUUID().replace(/-/g, "")}`;
|
|
125
|
+
const userId = body.user_id ?? randomUUID();
|
|
126
|
+
stmts.createApiKey.run(key, userId, (/* @__PURE__ */ new Date()).toISOString());
|
|
127
|
+
return send(res, 200, { api_key: key, user_id: userId });
|
|
128
|
+
}
|
|
129
|
+
const auth = authenticate(req);
|
|
130
|
+
if (!auth) {
|
|
131
|
+
return send(res, 401, { error: "unauthorized" });
|
|
132
|
+
}
|
|
133
|
+
if (path === "/api/team" && method === "POST") {
|
|
134
|
+
const body = await parseBody(req);
|
|
135
|
+
const teamId = randomUUID();
|
|
136
|
+
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
137
|
+
stmts.createTeam.run(teamId, body.name ?? "My Team", auth.user_id, now);
|
|
138
|
+
stmts.addMember.run(randomUUID(), teamId, auth.user_id, "owner", now);
|
|
139
|
+
return send(res, 200, { team_id: teamId });
|
|
140
|
+
}
|
|
141
|
+
const teamMatch = path.match(/^\/api\/team\/([^/]+)$/);
|
|
142
|
+
if (teamMatch && method === "GET") {
|
|
143
|
+
const team = stmts.getTeam.get(teamMatch[1]);
|
|
144
|
+
if (!team) return send(res, 404, { error: "team not found" });
|
|
145
|
+
const members = stmts.getMembers.all(teamMatch[1]);
|
|
146
|
+
return send(res, 200, { team, members });
|
|
147
|
+
}
|
|
148
|
+
const joinMatch = path.match(/^\/api\/team\/([^/]+)\/join$/);
|
|
149
|
+
if (joinMatch && method === "POST") {
|
|
150
|
+
const teamId = joinMatch[1];
|
|
151
|
+
const team = stmts.getTeam.get(teamId);
|
|
152
|
+
if (!team) return send(res, 404, { error: "team not found" });
|
|
153
|
+
stmts.addMember.run(
|
|
154
|
+
randomUUID(),
|
|
155
|
+
teamId,
|
|
156
|
+
auth.user_id,
|
|
157
|
+
"member",
|
|
158
|
+
(/* @__PURE__ */ new Date()).toISOString()
|
|
159
|
+
);
|
|
160
|
+
return send(res, 200, { joined: teamId });
|
|
161
|
+
}
|
|
162
|
+
if (path === "/api/push" && method === "POST") {
|
|
163
|
+
const body = await parseBody(req);
|
|
164
|
+
const teamId = body.team_id;
|
|
165
|
+
if (!teamId) return send(res, 400, { error: "team_id required" });
|
|
166
|
+
const member = stmts.isMember.get(teamId, auth.user_id);
|
|
167
|
+
if (!member) return send(res, 403, { error: "not a team member" });
|
|
168
|
+
const memories = body.memories ?? [];
|
|
169
|
+
const maxRow = stmts.getMaxVersion.get(teamId);
|
|
170
|
+
let version = (maxRow?.max_version ?? 0) + 1;
|
|
171
|
+
const pushMany = sqlite.transaction(() => {
|
|
172
|
+
for (const mem of memories) {
|
|
173
|
+
const id = mem.id ?? randomUUID();
|
|
174
|
+
stmts.pushMemory.run(
|
|
175
|
+
id,
|
|
176
|
+
teamId,
|
|
177
|
+
mem.type,
|
|
178
|
+
mem.text,
|
|
179
|
+
mem.scope,
|
|
180
|
+
mem.path_scope ?? null,
|
|
181
|
+
mem.repo ?? null,
|
|
182
|
+
mem.status,
|
|
183
|
+
mem.confidence,
|
|
184
|
+
mem.source,
|
|
185
|
+
JSON.stringify(mem.evidence ?? []),
|
|
186
|
+
mem.supersedes ?? null,
|
|
187
|
+
mem.created_at,
|
|
188
|
+
mem.updated_at,
|
|
189
|
+
auth.user_id,
|
|
190
|
+
version,
|
|
191
|
+
mem.origin_id ?? mem.id ?? id
|
|
192
|
+
);
|
|
193
|
+
version++;
|
|
194
|
+
}
|
|
195
|
+
});
|
|
196
|
+
pushMany();
|
|
197
|
+
return send(res, 200, { pushed: memories.length, version: version - 1 });
|
|
198
|
+
}
|
|
199
|
+
if (path === "/api/pull" && method === "POST") {
|
|
200
|
+
const body = await parseBody(req);
|
|
201
|
+
const teamId = body.team_id;
|
|
202
|
+
if (!teamId) return send(res, 400, { error: "team_id required" });
|
|
203
|
+
const member = stmts.isMember.get(teamId, auth.user_id);
|
|
204
|
+
if (!member) return send(res, 403, { error: "not a team member" });
|
|
205
|
+
const sinceVersion = body.since_version ?? 0;
|
|
206
|
+
const rows = stmts.pullMemories.all(teamId, sinceVersion);
|
|
207
|
+
const memories = rows.map((r) => ({
|
|
208
|
+
...r,
|
|
209
|
+
evidence: typeof r.evidence === "string" ? JSON.parse(r.evidence) : r.evidence
|
|
210
|
+
}));
|
|
211
|
+
const maxRow = stmts.getMaxVersion.get(teamId);
|
|
212
|
+
return send(res, 200, {
|
|
213
|
+
memories,
|
|
214
|
+
version: maxRow?.max_version ?? 0
|
|
215
|
+
});
|
|
216
|
+
}
|
|
217
|
+
send(res, 404, { error: "not found" });
|
|
218
|
+
} catch (err) {
|
|
219
|
+
send(res, 500, { error: err.message });
|
|
220
|
+
}
|
|
221
|
+
});
|
|
222
|
+
server.listen(PORT, () => {
|
|
223
|
+
console.log(`Recall sync server on http://localhost:${PORT}`);
|
|
224
|
+
});
|
|
225
|
+
//# sourceMappingURL=sync-server.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/sync/server.ts"],"sourcesContent":["/**\n * Cloud sync server — standalone HTTP service for team memory sharing.\n * Run separately: `node dist/sync-server.js`\n *\n * Endpoints:\n * POST /api/push — push local memories to team\n * POST /api/pull — pull team memories since version\n * POST /api/team — create team\n * GET /api/team/:id — get team info\n * POST /api/team/:id/join — join team\n * GET /health\n *\n * Auth: Bearer token in Authorization header (API key).\n * Storage: separate SQLite DB for the sync server.\n */\n\nimport { createServer } from \"node:http\";\nimport Database from \"better-sqlite3\";\nimport { randomUUID } from \"node:crypto\";\nimport { join } from \"node:path\";\nimport { mkdirSync } from \"node:fs\";\n\nconst PORT = parseInt(process.env.RECALL_SYNC_PORT ?? \"7891\", 10);\nconst DATA_DIR =\n process.env.RECALL_SYNC_DATA_DIR ??\n join(process.env.HOME ?? \".\", \".recall\", \"sync-server\");\n\nmkdirSync(DATA_DIR, { recursive: true });\nconst sqlite = new Database(join(DATA_DIR, \"sync.db\"));\nsqlite.pragma(\"journal_mode = WAL\");\nsqlite.pragma(\"foreign_keys = ON\");\n\n// --- Schema ---\n\nsqlite.exec(`\n CREATE TABLE IF NOT EXISTS teams (\n id TEXT PRIMARY KEY,\n name TEXT NOT NULL,\n created_by TEXT NOT NULL,\n created_at TEXT NOT NULL\n );\n\n CREATE TABLE IF NOT EXISTS team_members (\n id TEXT PRIMARY KEY,\n team_id TEXT NOT NULL REFERENCES teams(id),\n user_id TEXT NOT NULL,\n role TEXT NOT NULL DEFAULT 'member',\n joined_at TEXT NOT NULL,\n UNIQUE(team_id, user_id)\n );\n\n CREATE TABLE IF NOT EXISTS api_keys (\n key TEXT PRIMARY KEY,\n user_id TEXT NOT NULL,\n created_at TEXT NOT NULL\n );\n\n CREATE TABLE IF NOT EXISTS shared_memories (\n id TEXT PRIMARY KEY,\n team_id TEXT NOT NULL REFERENCES teams(id),\n type TEXT NOT NULL,\n text TEXT NOT NULL,\n scope TEXT NOT NULL,\n path_scope TEXT,\n repo TEXT,\n status TEXT NOT NULL,\n confidence REAL NOT NULL DEFAULT 0,\n source TEXT NOT NULL,\n evidence TEXT NOT NULL DEFAULT '[]',\n supersedes TEXT,\n created_at TEXT NOT NULL,\n updated_at TEXT NOT NULL,\n pushed_by TEXT NOT NULL,\n sync_version INTEGER NOT NULL DEFAULT 0,\n origin_id TEXT NOT NULL\n );\n\n CREATE INDEX IF NOT EXISTS idx_shared_team ON shared_memories(team_id);\n CREATE INDEX IF NOT EXISTS idx_shared_version ON shared_memories(team_id, sync_version);\n`);\n\n// --- Prepared statements ---\n\nconst stmts = {\n getApiKey: sqlite.prepare(\"SELECT * FROM api_keys WHERE key = ?\"),\n createTeam: sqlite.prepare(\n \"INSERT INTO teams (id, name, created_by, created_at) VALUES (?, ?, ?, ?)\",\n ),\n getTeam: sqlite.prepare(\"SELECT * FROM teams WHERE id = ?\"),\n addMember: sqlite.prepare(\n \"INSERT OR IGNORE INTO team_members (id, team_id, user_id, role, joined_at) VALUES (?, ?, ?, ?, ?)\",\n ),\n getMembers: sqlite.prepare(\"SELECT * FROM team_members WHERE team_id = ?\"),\n isMember: sqlite.prepare(\n \"SELECT * FROM team_members WHERE team_id = ? AND user_id = ?\",\n ),\n getMaxVersion: sqlite.prepare(\n \"SELECT COALESCE(MAX(sync_version), 0) as max_version FROM shared_memories WHERE team_id = ?\",\n ),\n pushMemory: sqlite.prepare(`\n INSERT OR REPLACE INTO shared_memories\n (id, team_id, type, text, scope, path_scope, repo, status, confidence, source, evidence, supersedes, created_at, updated_at, pushed_by, sync_version, origin_id)\n VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)\n `),\n pullMemories: sqlite.prepare(\n \"SELECT * FROM shared_memories WHERE team_id = ? AND sync_version > ? ORDER BY sync_version ASC\",\n ),\n createApiKey: sqlite.prepare(\n \"INSERT INTO api_keys (key, user_id, created_at) VALUES (?, ?, ?)\",\n ),\n};\n\n// --- Auth helper ---\n\nfunction authenticate(\n req: import(\"node:http\").IncomingMessage,\n): { user_id: string } | null {\n const auth = req.headers.authorization;\n if (!auth?.startsWith(\"Bearer \")) return null;\n const key = auth.slice(7);\n const row = stmts.getApiKey.get(key) as any;\n if (!row) return null;\n return { user_id: row.user_id };\n}\n\n// --- Body parser ---\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 send(\n res: import(\"node:http\").ServerResponse,\n status: number,\n data: any,\n) {\n res.setHeader(\"Content-Type\", \"application/json\");\n res.statusCode = status;\n res.end(JSON.stringify(data));\n}\n\n// --- Server ---\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 try {\n // Health (no auth)\n if (path === \"/health\" && method === \"GET\") {\n return send(res, 200, { status: \"ok\", service: \"recall-sync\" });\n }\n\n // Bootstrap: create API key (no auth, first-run only)\n if (path === \"/api/bootstrap\" && method === \"POST\") {\n const body = await parseBody(req);\n const key = `rk_${randomUUID().replace(/-/g, \"\")}`;\n const userId = body.user_id ?? randomUUID();\n stmts.createApiKey.run(key, userId, new Date().toISOString());\n return send(res, 200, { api_key: key, user_id: userId });\n }\n\n // All other routes require auth\n const auth = authenticate(req);\n if (!auth) {\n return send(res, 401, { error: \"unauthorized\" });\n }\n\n // Create team\n if (path === \"/api/team\" && method === \"POST\") {\n const body = await parseBody(req);\n const teamId = randomUUID();\n const now = new Date().toISOString();\n stmts.createTeam.run(teamId, body.name ?? \"My Team\", auth.user_id, now);\n stmts.addMember.run(randomUUID(), teamId, auth.user_id, \"owner\", now);\n return send(res, 200, { team_id: teamId });\n }\n\n // Get team\n const teamMatch = path.match(/^\\/api\\/team\\/([^/]+)$/);\n if (teamMatch && method === \"GET\") {\n const team = stmts.getTeam.get(teamMatch[1]) as any;\n if (!team) return send(res, 404, { error: \"team not found\" });\n const members = stmts.getMembers.all(teamMatch[1]);\n return send(res, 200, { team, members });\n }\n\n // Join team\n const joinMatch = path.match(/^\\/api\\/team\\/([^/]+)\\/join$/);\n if (joinMatch && method === \"POST\") {\n const teamId = joinMatch[1];\n const team = stmts.getTeam.get(teamId);\n if (!team) return send(res, 404, { error: \"team not found\" });\n stmts.addMember.run(\n randomUUID(),\n teamId,\n auth.user_id,\n \"member\",\n new Date().toISOString(),\n );\n return send(res, 200, { joined: teamId });\n }\n\n // Push memories\n if (path === \"/api/push\" && method === \"POST\") {\n const body = await parseBody(req);\n const teamId = body.team_id;\n if (!teamId) return send(res, 400, { error: \"team_id required\" });\n\n const member = stmts.isMember.get(teamId, auth.user_id);\n if (!member) return send(res, 403, { error: \"not a team member\" });\n\n const memories: any[] = body.memories ?? [];\n const maxRow = stmts.getMaxVersion.get(teamId) as any;\n let version = (maxRow?.max_version ?? 0) + 1;\n\n const pushMany = sqlite.transaction(() => {\n for (const mem of memories) {\n const id = mem.id ?? randomUUID();\n stmts.pushMemory.run(\n id,\n teamId,\n mem.type,\n mem.text,\n mem.scope,\n mem.path_scope ?? null,\n mem.repo ?? null,\n mem.status,\n mem.confidence,\n mem.source,\n JSON.stringify(mem.evidence ?? []),\n mem.supersedes ?? null,\n mem.created_at,\n mem.updated_at,\n auth.user_id,\n version,\n mem.origin_id ?? mem.id ?? id,\n );\n version++;\n }\n });\n pushMany();\n\n return send(res, 200, { pushed: memories.length, version: version - 1 });\n }\n\n // Pull memories\n if (path === \"/api/pull\" && method === \"POST\") {\n const body = await parseBody(req);\n const teamId = body.team_id;\n if (!teamId) return send(res, 400, { error: \"team_id required\" });\n\n const member = stmts.isMember.get(teamId, auth.user_id);\n if (!member) return send(res, 403, { error: \"not a team member\" });\n\n const sinceVersion = body.since_version ?? 0;\n const rows = stmts.pullMemories.all(teamId, sinceVersion) as any[];\n\n const memories = rows.map((r) => ({\n ...r,\n evidence: typeof r.evidence === \"string\" ? JSON.parse(r.evidence) : r.evidence,\n }));\n\n const maxRow = stmts.getMaxVersion.get(teamId) as any;\n return send(res, 200, {\n memories,\n version: maxRow?.max_version ?? 0,\n });\n }\n\n send(res, 404, { error: \"not found\" });\n } catch (err: any) {\n send(res, 500, { error: err.message });\n }\n});\n\nserver.listen(PORT, () => {\n console.log(`Recall sync server on http://localhost:${PORT}`);\n});\n"],"mappings":"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","names":[]}
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import {
|
|
2
|
+
DEFAULT_ENQUEUE_CONFIG,
|
|
3
|
+
DEFAULT_LEASE_SECONDS,
|
|
4
|
+
DEFAULT_PRIORITIES,
|
|
5
|
+
TaskClaimConflictError,
|
|
6
|
+
abandonOverAttemptTasks,
|
|
7
|
+
applyBacklogCaps,
|
|
8
|
+
claimTask,
|
|
9
|
+
deleteTask,
|
|
10
|
+
enqueueMaintenanceTasks,
|
|
11
|
+
enqueueVerifyCapture,
|
|
12
|
+
expireStalePendingTasks,
|
|
13
|
+
getTask,
|
|
14
|
+
getTaskStats,
|
|
15
|
+
hasActiveTaskForTarget,
|
|
16
|
+
insertTaskIdempotent,
|
|
17
|
+
listTasks,
|
|
18
|
+
peekTasks,
|
|
19
|
+
produceMergeDuplicateTasks,
|
|
20
|
+
produceRefineCandidateTasks,
|
|
21
|
+
produceSummarizeHistoryTasks,
|
|
22
|
+
produceSummarizeSessionTasks,
|
|
23
|
+
produceSynthesizeRepoTasks,
|
|
24
|
+
releaseTask,
|
|
25
|
+
snippetHasMeaningfulContent,
|
|
26
|
+
submitTask,
|
|
27
|
+
sweepExpiredLeases,
|
|
28
|
+
targetKey
|
|
29
|
+
} from "./chunk-IILLSHLM.js";
|
|
30
|
+
import "./chunk-A5UIRZU6.js";
|
|
31
|
+
import "./chunk-4CV4JOE5.js";
|
|
32
|
+
export {
|
|
33
|
+
DEFAULT_ENQUEUE_CONFIG,
|
|
34
|
+
DEFAULT_LEASE_SECONDS,
|
|
35
|
+
DEFAULT_PRIORITIES,
|
|
36
|
+
TaskClaimConflictError,
|
|
37
|
+
abandonOverAttemptTasks,
|
|
38
|
+
applyBacklogCaps,
|
|
39
|
+
claimTask,
|
|
40
|
+
deleteTask,
|
|
41
|
+
enqueueMaintenanceTasks,
|
|
42
|
+
enqueueVerifyCapture,
|
|
43
|
+
expireStalePendingTasks,
|
|
44
|
+
getTask,
|
|
45
|
+
getTaskStats,
|
|
46
|
+
hasActiveTaskForTarget,
|
|
47
|
+
insertTaskIdempotent,
|
|
48
|
+
listTasks,
|
|
49
|
+
peekTasks,
|
|
50
|
+
produceMergeDuplicateTasks,
|
|
51
|
+
produceRefineCandidateTasks,
|
|
52
|
+
produceSummarizeHistoryTasks,
|
|
53
|
+
produceSummarizeSessionTasks,
|
|
54
|
+
produceSynthesizeRepoTasks,
|
|
55
|
+
releaseTask,
|
|
56
|
+
snippetHasMeaningfulContent,
|
|
57
|
+
submitTask,
|
|
58
|
+
sweepExpiredLeases,
|
|
59
|
+
targetKey
|
|
60
|
+
};
|
|
61
|
+
//# sourceMappingURL=tasks-UOLSPXJQ.js.map
|