claude-launchpad 0.10.1-dev.3 → 0.10.1-dev.5

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.
@@ -281,6 +281,7 @@ function buildExplanation(parts, memory) {
281
281
 
282
282
  // src/commands/memory/tools/store.ts
283
283
  import { z } from "zod";
284
+ import { createHash } from "crypto";
284
285
 
285
286
  // src/commands/memory/utils/content-validation.ts
286
287
  var SOFT_LENGTH_LIMIT = 1500;
@@ -420,6 +421,8 @@ function checkContradiction(newContent, existingContent) {
420
421
  }
421
422
 
422
423
  // src/commands/memory/tools/store.ts
424
+ var recentStores = /* @__PURE__ */ new Map();
425
+ var DEDUP_WINDOW_MS = 1e4;
423
426
  var inputSchema = {
424
427
  type: z.enum(MEMORY_TYPES).describe("Memory type: working, episodic, semantic, procedural, or pattern"),
425
428
  content: z.string().min(1).max(1e4).describe("The memory content to store"),
@@ -451,15 +454,18 @@ function registerStore(server, deps) {
451
454
  }
452
455
  const context = args.context ?? JSON.stringify(getGitContext());
453
456
  const project = args.project ?? deps.project ?? void 0;
454
- const recent = deps.memoryRepo.getRecent(5, project);
455
- const isDupe = recent.some(
456
- (m) => m.content === args.content && Date.now() - new Date(m.createdAt).getTime() < 1e4
457
- );
458
- if (isDupe) {
457
+ const contentHash = createHash("sha256").update(args.content).digest("hex");
458
+ const now = Date.now();
459
+ const lastStored = recentStores.get(contentHash);
460
+ if (lastStored && now - lastStored < DEDUP_WINDOW_MS) {
459
461
  return {
460
462
  content: [{ type: "text", text: "Duplicate: identical memory was just stored. Skipped." }]
461
463
  };
462
464
  }
465
+ recentStores.set(contentHash, now);
466
+ for (const [key, ts] of recentStores) {
467
+ if (now - ts > DEDUP_WINDOW_MS) recentStores.delete(key);
468
+ }
463
469
  const contradictions = [];
464
470
  try {
465
471
  const existing = await deps.retrievalService.search({
@@ -882,7 +888,7 @@ async function startServer(deps) {
882
888
  const server = new McpServer(
883
889
  { name: "agentic-memory", version: "0.1.0" },
884
890
  {
885
- instructions: "Use memory_search before memory_store to check for duplicates. Use memory_update to modify existing memories instead of creating duplicates - it preserves access history. Store memories at the semantic level - capture WHY, not just WHAT happened. Only store knowledge worth remembering across sessions. Memory context is automatically injected at session start via hook - no need to call memory_recent manually."
891
+ instructions: "Use memory_search before memory_store to check for duplicates. Use memory_update to modify existing memories instead of creating duplicates - it preserves access history. Store memories at the semantic level - capture WHY, not just WHAT happened. Only store knowledge worth remembering across sessions. NEVER store credentials, API keys, tokens, passwords, or secrets - memories may be synced to external storage. Memory context is automatically injected at session start via hook - no need to call memory_recent manually."
886
892
  }
887
893
  );
888
894
  const project = detectProject(process.cwd());
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/commands/memory/server.ts","../../../src/commands/memory/services/retrieval-service.ts","../../../src/commands/memory/tools/store.ts","../../../src/commands/memory/utils/content-validation.ts","../../../src/commands/memory/utils/contradiction.ts","../../../src/commands/memory/tools/search.ts","../../../src/commands/memory/tools/forget.ts","../../../src/commands/memory/utils/errors.ts","../../../src/commands/memory/tools/relate.ts","../../../src/commands/memory/tools/stats.ts","../../../src/commands/memory/tools/recent.ts","../../../src/commands/memory/tools/update.ts","../../../src/commands/memory/tools/register.ts"],"sourcesContent":["import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';\nimport { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';\nimport { createDatabase, closeDatabase } from './storage/database.js';\nimport { migrate } from './storage/migrator.js';\nimport { MemoryRepo } from './storage/memory-repo.js';\nimport { RelationRepo } from './storage/relation-repo.js';\nimport { SearchRepo } from './storage/search-repo.js';\nimport { RetrievalService } from './services/retrieval-service.js';\nimport { loadConfig, resolveDataDir } from './config.js';\nimport type { Config } from './config.js';\nimport { registerTools } from './tools/register.js';\nimport { detectProject } from './utils/project.js';\n\nexport interface ServerDeps {\n readonly config: Config;\n}\n\nexport async function startServer(deps?: Partial<ServerDeps>): Promise<void> {\n const config = deps?.config ?? loadConfig();\n const dataDir = resolveDataDir(config.dataDir);\n\n const db = createDatabase({ dataDir });\n migrate(db);\n\n const memoryRepo = new MemoryRepo(db);\n const relationRepo = new RelationRepo(db);\n const searchRepo = new SearchRepo(db);\n\n const retrievalService = new RetrievalService({\n memoryRepo,\n relationRepo,\n searchRepo,\n });\n\n const server = new McpServer(\n { name: 'agentic-memory', version: '0.1.0' },\n {\n instructions:\n 'Use memory_search before memory_store to check for duplicates. '\n + 'Use memory_update to modify existing memories instead of creating duplicates - it preserves access history. '\n + 'Store memories at the semantic level - capture WHY, not just WHAT happened. '\n + 'Only store knowledge worth remembering across sessions. '\n + 'Memory context is automatically injected at session start via hook - no need to call memory_recent manually.',\n },\n );\n\n const project = detectProject(process.cwd());\n\n registerTools(server, { memoryRepo, relationRepo, retrievalService, dataDir, project });\n\n const transport = new StdioServerTransport();\n await server.connect(transport);\n\n const shutdown = async () => {\n await server.close();\n closeDatabase(db);\n process.exit(0);\n };\n process.on('SIGINT', () => void shutdown());\n process.on('SIGTERM', () => void shutdown());\n}\n\n// Auto-start when invoked directly as MCP server entry point\nstartServer().catch((err) => {\n process.stderr.write(`[agentic-memory] ${err}\\n`);\n process.exit(1);\n});\n","import type { Memory, MemoryType, SearchResult, SearchInput, RelationType } from '../types.js';\nimport type { MemoryRepo } from '../storage/memory-repo.js';\nimport type { RelationRepo } from '../storage/relation-repo.js';\nimport type { SearchRepo } from '../storage/search-repo.js';\nimport { SCORING_WEIGHTS } from '../config.js';\nimport { type GitContext, getGitContext, computeContextScore } from '../utils/git-context.js';\n\nconst STALENESS_THRESHOLDS = {\n working: 1,\n episodic: 7,\n pattern: 14,\n semantic: 30,\n procedural: 90,\n} as const;\n\nexport interface RetrievalDeps {\n readonly memoryRepo: MemoryRepo;\n readonly relationRepo: RelationRepo;\n readonly searchRepo: SearchRepo;\n readonly gitContext?: GitContext;\n}\n\nexport class RetrievalService {\n readonly #deps: RetrievalDeps;\n readonly #gitContext: GitContext;\n\n constructor(deps: RetrievalDeps) {\n this.#deps = deps;\n this.#gitContext = deps.gitContext ?? getGitContext();\n }\n\n /**\n * FTS5 keyword search with multi-signal scoring, context awareness,\n * and relation-based graph expansion.\n */\n async search(input: SearchInput): Promise<readonly SearchResult[]> {\n // Direct ID lookup\n if (input.id) {\n const memory = this.#deps.memoryRepo.getById(input.id);\n if (!memory) return [];\n this.#deps.memoryRepo.incrementAccess(input.id);\n return [{\n memory,\n score: 1.0,\n explanation: 'Direct lookup by ID',\n }];\n }\n\n // Phase 1: FTS5 keyword search\n const ftsResults = this.#deps.searchRepo.searchFts({\n query: input.query,\n limit: input.limit * 3,\n type: input.type,\n minImportance: input.min_importance,\n project: input.project,\n });\n\n const textScores = ftsOnlyScores(ftsResults);\n if (textScores.size === 0) return [];\n\n // Phase 2: Load memories and compute composite scores\n const candidates: { memory: Memory; composite: number; parts: ScoreParts }[] = [];\n\n for (const [memoryId, textScore] of textScores) {\n const memory = this.#deps.memoryRepo.getById(memoryId);\n if (!memory) continue;\n if (input.type && memory.type !== input.type) continue;\n if (memory.importance < input.min_importance) continue;\n if (input.tags?.length) {\n const memTags = new Set(memory.tags);\n if (!input.tags.every(t => memTags.has(t))) continue;\n }\n\n const parts = computeScoreParts(memory, textScore, this.#gitContext, input.query);\n const composite = computeComposite(parts);\n candidates.push({ memory, composite, parts });\n }\n\n // Phase 3: Sort by composite score\n candidates.sort((a, b) => b.composite - a.composite);\n let topN = candidates.slice(0, input.limit);\n\n // Phase 4: Relation expansion — surface connected memories\n const seenIds = new Set(topN.map(c => c.memory.id));\n const expanded = this.#expandWithRelations(topN, input.limit, seenIds, input.min_importance);\n if (expanded.length > 0) {\n topN = [...topN, ...expanded].sort((a, b) => b.composite - a.composite).slice(0, input.limit);\n }\n\n // Phase 5: Build results with explanations, increment access\n return topN.map(({ memory, composite, parts }) => {\n this.#deps.memoryRepo.incrementAccess(memory.id);\n return {\n memory,\n score: composite,\n explanation: parts.relationSource\n ? `Related (${parts.relationSource.type}) to: ${parts.relationSource.title ?? parts.relationSource.id}`\n : buildExplanation(parts, memory),\n };\n });\n }\n\n /**\n * Smart session loading: returns context-matched, recent, and related memories\n * for session start context injection.\n */\n loadSessionContext(input: {\n readonly limit: number;\n readonly project?: string;\n readonly type?: MemoryType;\n }): readonly SessionContextResult[] {\n const contextBudget = Math.floor(input.limit * 0.4);\n const recentBudget = Math.floor(input.limit * 0.4);\n const relatedBudget = input.limit - contextBudget - recentBudget;\n const seenIds = new Set<string>();\n\n const contextMatched = this.#loadContextMatched(contextBudget, input.project, input.type, seenIds);\n const recent = this.#loadRecent(recentBudget, input.project, input.type, seenIds);\n\n const sourceIds = [...contextMatched, ...recent].map(r => r.result.memory.id);\n const related = this.#loadRelatedExpansion(sourceIds, relatedBudget, seenIds);\n\n const all = [...contextMatched, ...recent, ...related];\n for (const entry of all) {\n this.#deps.memoryRepo.incrementInjection(entry.result.memory.id);\n }\n return all;\n }\n\n #loadContextMatched(\n budget: number, project?: string, type?: MemoryType, seenIds?: Set<string>,\n ): SessionContextResult[] {\n if (budget <= 0) return [];\n const candidates = this.#deps.memoryRepo.getRecent(budget * 5, project, type);\n const scored: { memory: Memory; ctxScore: number; composite: number }[] = [];\n\n for (const m of candidates) {\n const ctxScore = computeContextScore(m.context, this.#gitContext, '');\n if (ctxScore <= 0.1) continue;\n const composite = ctxScore * 0.5 + m.importance * 0.3 + computeRecencyScore(m.updatedAt) * 0.2;\n scored.push({ memory: m, ctxScore, composite });\n }\n\n scored.sort((a, b) => b.composite - a.composite);\n const results: SessionContextResult[] = [];\n for (const s of scored.slice(0, budget)) {\n seenIds?.add(s.memory.id);\n results.push({ section: 'context', result: { memory: s.memory, score: s.composite, explanation: 'Context match' } });\n }\n return results;\n }\n\n #loadRecent(\n budget: number, project?: string, type?: MemoryType, seenIds?: Set<string>,\n ): SessionContextResult[] {\n if (budget <= 0) return [];\n const candidates = this.#deps.memoryRepo.getRecent(budget * 2, project, type);\n const results: SessionContextResult[] = [];\n\n for (const m of candidates) {\n if (seenIds?.has(m.id)) continue;\n const score = m.importance * 0.4 + computeRecencyScore(m.updatedAt) * 0.6;\n seenIds?.add(m.id);\n results.push({ section: 'recent', result: { memory: m, score, explanation: 'Recent' } });\n if (results.length >= budget) break;\n }\n return results;\n }\n\n #loadRelatedExpansion(\n sourceIds: readonly string[], budget: number, seenIds: Set<string>,\n ): SessionContextResult[] {\n if (budget <= 0) return [];\n const results: SessionContextResult[] = [];\n\n for (const srcId of sourceIds) {\n const relations = this.#deps.relationRepo.getByMemory(srcId);\n for (const rel of relations) {\n const otherId = rel.sourceId === srcId ? rel.targetId : rel.sourceId;\n if (otherId === srcId || seenIds.has(otherId)) continue;\n\n const other = this.#deps.memoryRepo.getById(otherId);\n if (!other) continue;\n\n const src = this.#deps.memoryRepo.getById(srcId);\n const weight = RELATION_TYPE_WEIGHTS[rel.relationType] ?? 0.5;\n seenIds.add(otherId);\n results.push({\n section: 'related',\n result: {\n memory: other,\n score: other.importance * weight,\n explanation: `Related (${rel.relationType}) to: ${src?.title ?? srcId}`,\n },\n });\n if (results.length >= budget) return results;\n }\n }\n return results;\n }\n\n #expandWithRelations(\n topResults: readonly { memory: Memory; composite: number; parts: ScoreParts }[],\n limit: number,\n seenIds: Set<string>,\n minImportance: number,\n ): { memory: Memory; composite: number; parts: ScoreParts }[] {\n if (topResults.length >= limit) return [];\n\n const expanded: { memory: Memory; composite: number; parts: ScoreParts }[] = [];\n const remaining = limit - topResults.length;\n const sourcesToExpand = topResults.slice(0, 5);\n\n for (const parent of sourcesToExpand) {\n const relations = this.#deps.relationRepo.getByMemory(parent.memory.id);\n for (const rel of relations) {\n const otherId = rel.sourceId === parent.memory.id ? rel.targetId : rel.sourceId;\n if (otherId === parent.memory.id || seenIds.has(otherId)) continue;\n\n const other = this.#deps.memoryRepo.getById(otherId);\n if (!other || other.importance < minImportance) continue;\n\n const weight = RELATION_TYPE_WEIGHTS[rel.relationType] ?? 0.5;\n const composite = parent.composite * 0.7 * weight;\n const parts: ScoreParts = {\n textScore: 0,\n importanceScore: other.importance,\n recencyScore: computeRecencyScore(other.updatedAt),\n accessScore: computeAccessScore(other.accessCount, other.lastAccessed),\n contextScore: 0,\n relationSource: { id: parent.memory.id, title: parent.memory.title, type: rel.relationType },\n };\n\n seenIds.add(otherId);\n expanded.push({ memory: other, composite, parts });\n if (expanded.length >= remaining) return expanded;\n }\n }\n\n return expanded;\n }\n}\n\n// ── Relation Expansion ──────────────────────────────────────\n\nconst RELATION_TYPE_WEIGHTS: Record<RelationType, number> = {\n depends_on: 1.0,\n extends: 0.9,\n implements: 0.9,\n relates_to: 0.7,\n derived_from: 0.6,\n contradicts: 0.3,\n};\n\n// ── FTS5-Only Fallback ───────────────────────────────────────\n\nfunction ftsOnlyScores(ftsResults: readonly { memoryId: string; rank: number }[]): Map<string, number> {\n const scores = new Map<string, number>();\n for (const r of ftsResults) {\n const score = Math.min(1, -r.rank / 20);\n scores.set(r.memoryId, score);\n }\n return scores;\n}\n\n// ── Scoring ───────────────────────────────────────────────────\n\ninterface ScoreParts {\n readonly textScore: number;\n readonly importanceScore: number;\n readonly recencyScore: number;\n readonly accessScore: number;\n readonly contextScore: number;\n readonly relationSource?: { readonly id: string; readonly title: string | null; readonly type: RelationType };\n}\n\nfunction computeScoreParts(\n memory: Memory,\n textScore: number,\n gitContext: GitContext,\n query: string,\n): ScoreParts {\n return {\n textScore,\n importanceScore: memory.importance,\n recencyScore: computeRecencyScore(memory.updatedAt),\n accessScore: computeAccessScore(memory.accessCount, memory.lastAccessed),\n contextScore: computeContextScore(memory.context, gitContext, query),\n };\n}\n\nfunction computeComposite(parts: ScoreParts): number {\n return (\n parts.textScore * SCORING_WEIGHTS.text +\n parts.importanceScore * SCORING_WEIGHTS.importance +\n parts.recencyScore * SCORING_WEIGHTS.recency +\n parts.accessScore * SCORING_WEIGHTS.access +\n parts.contextScore * SCORING_WEIGHTS.context\n );\n}\n\n/**\n * Recency score: 1.0 for today, decays exponentially.\n * Uses a 30-day half-life.\n */\nfunction computeRecencyScore(updatedAt: string): number {\n const ageMs = Date.now() - new Date(updatedAt).getTime();\n const ageDays = ageMs / (1000 * 60 * 60 * 24);\n if (ageDays < 0) return 1.0;\n return Math.exp(-ageDays * Math.LN2 / 30);\n}\n\n/**\n * Access score: logarithmic count x recency of last access.\n */\nfunction computeAccessScore(accessCount: number, lastAccessed: string | null): number {\n if (accessCount <= 0) return 0;\n const countScore = Math.min(1.0, Math.log10(accessCount + 1) / Math.log10(31));\n if (!lastAccessed) return countScore * 0.5;\n const ageDays = (Date.now() - new Date(lastAccessed).getTime()) / 86_400_000;\n const recency = Math.exp(-ageDays * Math.LN2 / 30);\n return countScore * (0.5 + 0.5 * recency);\n}\n\n// ── Explanation ───────────────────────────────────────────────\n\nfunction buildExplanation(parts: ScoreParts, memory: Memory): string {\n const factors: string[] = [];\n\n if (parts.textScore > 0.7) {\n factors.push(`High text match (${(parts.textScore * 100).toFixed(0)}%)`);\n } else if (parts.textScore > 0.3) {\n factors.push(`Moderate text match (${(parts.textScore * 100).toFixed(0)}%)`);\n }\n\n if (memory.importance > 0.7) {\n factors.push('High importance');\n }\n\n if (parts.recencyScore > 0.8) {\n factors.push('Very recent');\n } else if (parts.recencyScore > 0.5) {\n factors.push('Recent');\n }\n\n if (memory.accessCount > 10) {\n factors.push(`Frequently accessed (${memory.accessCount}x)`);\n } else if (memory.accessCount > 3) {\n factors.push(`Accessed ${memory.accessCount}x`);\n }\n\n if (parts.contextScore > 0.3) {\n factors.push('Context match');\n }\n\n const ageDays = Math.floor((Date.now() - new Date(memory.createdAt).getTime()) / 86_400_000);\n const stalenessThreshold = STALENESS_THRESHOLDS[memory.type];\n if (stalenessThreshold !== undefined && ageDays > stalenessThreshold) {\n factors.push(`${ageDays}d old - verify before acting`);\n }\n\n return factors.length > 0 ? factors.join(' + ') : 'Matched query';\n}\n\n// ── Types ────────────────────────────────────────────────────\n\nexport interface SessionContextResult {\n readonly section: 'context' | 'recent' | 'related';\n readonly result: SearchResult;\n}\n\n// Exported for testing\nexport { computeRecencyScore, computeAccessScore, computeComposite, computeScoreParts, ftsOnlyScores };\nexport type { ScoreParts };\n","import { z } from 'zod';\nimport type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';\nimport type { ToolDeps } from './register.js';\nimport { MEMORY_TYPES, MEMORY_SOURCES } from '../types.js';\nimport { getGitContext } from '../utils/git-context.js';\nimport { validateMemoryContent } from '../utils/content-validation.js';\nimport { checkContradiction } from '../utils/contradiction.js';\n\nconst inputSchema = {\n type: z.enum(MEMORY_TYPES).describe('Memory type: working, episodic, semantic, procedural, or pattern'),\n content: z.string().min(1).max(10000).describe('The memory content to store'),\n title: z.string().max(200).optional().describe('Short title for the memory'),\n tags: z.array(z.string()).max(20).default([]).describe('Tags for categorization. Suggested: #bug, #decision, #gotcha, #howto, #pattern'),\n importance: z.number().min(0).max(1).default(0.5).describe('0-0.3 ephemeral, 0.3-0.6 reference, 0.6-0.8 important, 0.8-1.0 critical'),\n context: z.string().optional().describe('JSON: {\"files\": [...], \"branch\": \"...\", \"intent\": \"...\"}. Auto-detected from git if omitted.'),\n source: z.enum(MEMORY_SOURCES).default('manual').describe('How this memory was created'),\n project: z.string().max(200).optional().describe('Project scope (auto-detected from CWD if omitted)'),\n};\n\nexport function registerStore(server: McpServer, deps: ToolDeps): void {\n server.registerTool(\n 'memory_store',\n {\n description:\n 'Store a new memory. Use memory_search first to check for duplicates. '\n + 'Prefer updating existing semantic/procedural memories over creating new ones. '\n + 'Types: episodic (events), semantic (facts), procedural (how-to), pattern (recurring), working (temporary). '\n + 'Importance: 0-0.3 ephemeral, 0.3-0.6 reference, 0.6-0.8 important, 0.8-1.0 critical. '\n + 'Suggested tags: #bug, #decision, #gotcha, #howto, #pattern, #architecture. '\n + 'Context is auto-detected from git (branch, recent files) if omitted.',\n inputSchema,\n annotations: { idempotentHint: false },\n },\n async (args) => {\n const validation = validateMemoryContent(args.content);\n if (!validation.valid) {\n return {\n content: [{\n type: 'text' as const,\n text: `Rejected: ${validation.reason}`,\n }],\n isError: true,\n };\n }\n\n const context = args.context ?? JSON.stringify(getGitContext());\n const project = args.project ?? deps.project ?? undefined;\n\n // Dedup: reject if identical content was stored in the last 10 seconds\n const recent = deps.memoryRepo.getRecent(5, project);\n const isDupe = recent.some((m) =>\n m.content === args.content && (Date.now() - new Date(m.createdAt).getTime()) < 10_000\n );\n if (isDupe) {\n return {\n content: [{ type: 'text' as const, text: 'Duplicate: identical memory was just stored. Skipped.' }],\n };\n }\n\n // Contradiction detection\n const contradictions: { id: string; title: string | null }[] = [];\n try {\n const existing = await deps.retrievalService.search({\n query: args.content.slice(0, 200),\n limit: 3,\n min_importance: 0,\n project,\n });\n for (const result of existing) {\n if (result.score > 0.6 && checkContradiction(args.content, result.memory.content)) {\n contradictions.push({ id: result.memory.id, title: result.memory.title });\n }\n }\n } catch {\n // Contradiction check is best-effort\n }\n\n const memory = deps.memoryRepo.create(\n {\n type: args.type,\n content: args.content,\n title: args.title,\n tags: args.tags,\n importance: args.importance,\n context,\n source: args.source,\n project,\n },\n null,\n );\n\n // Create contradiction relations\n for (const c of contradictions) {\n try {\n deps.relationRepo.create(memory.id, c.id, 'contradicts');\n } catch {\n // Relation creation is best-effort\n }\n }\n\n const parts: string[] = [\n `Stored memory ${memory.id} (type: ${memory.type}, importance: ${memory.importance})`,\n ];\n\n for (const warning of validation.warnings) {\n parts.push(`Warning: ${warning}`);\n }\n\n for (const c of contradictions) {\n parts.push(`Warning: potential contradiction with memory ${c.id}${c.title ? ` (\"${c.title}\")` : ''}. Linked with 'contradicts' relation.`);\n }\n\n return {\n content: [{\n type: 'text' as const,\n text: parts.join('\\n'),\n }],\n };\n },\n );\n}\n","// ── Content Validation for memory_store ─────────────────────\n\nexport interface ValidationResult {\n readonly valid: boolean;\n readonly reason?: string;\n readonly warnings: readonly string[];\n}\n\nconst SOFT_LENGTH_LIMIT = 1500;\nconst HARD_LENGTH_LIMIT = 5000;\nconst CODE_RATIO_THRESHOLD = 0.5;\n\n/**\n * Validate memory content before storage.\n * Returns hard rejections (don't store) and soft warnings (store but warn).\n */\nexport function validateMemoryContent(content: string): ValidationResult {\n const warnings: string[] = [];\n\n // Hard reject: git log output\n if (isGitLog(content)) {\n return { valid: false, reason: 'Content looks like raw git log output. Use git log directly — don\\'t store it as memory.', warnings: [] };\n }\n\n // Hard reject: code-heavy content\n if (isCodeHeavy(content)) {\n return { valid: false, reason: 'Content is >50% code blocks. Code belongs in files, not memory. Store the insight or decision instead.', warnings: [] };\n }\n\n // Hard reject: too long\n if (content.length > HARD_LENGTH_LIMIT) {\n return { valid: false, reason: `Content is ${content.length} chars (limit: ${HARD_LENGTH_LIMIT}). Break it into smaller, atomic memories.`, warnings: [] };\n }\n\n // Soft warn: lengthy\n if (content.length > SOFT_LENGTH_LIMIT) {\n warnings.push(`Content is ${content.length} chars. Shorter memories (<${SOFT_LENGTH_LIMIT} chars) are easier to retrieve and less likely to decay.`);\n }\n\n return { valid: true, warnings };\n}\n\n/**\n * Content is >50% fenced code blocks.\n */\nexport function isCodeHeavy(content: string): boolean {\n const fencedBlockPattern = /```[\\s\\S]*?```/g;\n let codeChars = 0;\n let match: RegExpExecArray | null;\n\n while ((match = fencedBlockPattern.exec(content)) !== null) {\n codeChars += match[0].length;\n }\n\n return content.length > 0 && codeChars / content.length > CODE_RATIO_THRESHOLD;\n}\n\n/**\n * Content looks like raw git log output.\n * Matches patterns like \"commit abc123\\nAuthor: ...\\nDate: ...\"\n */\nexport function isGitLog(content: string): boolean {\n const lines = content.split('\\n');\n let gitLogLines = 0;\n\n for (const line of lines) {\n const trimmed = line.trim();\n if (/^commit\\s+[0-9a-f]{7,40}$/i.test(trimmed)) gitLogLines++;\n else if (/^Author:\\s+.+/i.test(trimmed)) gitLogLines++;\n else if (/^Date:\\s+.+/i.test(trimmed)) gitLogLines++;\n else if (/^[0-9a-f]{7,12}\\s+\\S+/i.test(trimmed) && trimmed.length < 200) gitLogLines++;\n }\n\n // At least 3 git-log-like lines and they make up >30% of non-empty lines\n const nonEmptyLines = lines.filter(l => l.trim().length > 0).length;\n return gitLogLines >= 3 && nonEmptyLines > 0 && gitLogLines / nonEmptyLines > 0.3;\n}\n","// ── Contradiction Detection (keyword-overlap heuristic) ─────\n\nconst NEGATION_PATTERNS = [\n /\\bnot\\b/i,\n /\\bno longer\\b/i,\n /\\binstead of\\b/i,\n /\\breplaced\\b/i,\n /\\bremoved\\b/i,\n /\\bdon'?t\\b/i,\n /\\bwon'?t\\b/i,\n /\\bshouldn'?t\\b/i,\n /\\bdeprecated\\b/i,\n /\\bdisabled\\b/i,\n /\\bstopped\\b/i,\n /\\bavoid\\b/i,\n /\\bnever\\b/i,\n /\\bwithout\\b/i,\n];\n\nconst KEYWORD_OVERLAP_THRESHOLD = 0.4;\nconst MIN_KEYWORD_LENGTH = 3;\nconst STOP_WORDS = new Set([\n 'the', 'and', 'for', 'are', 'but', 'not', 'you', 'all', 'can', 'had',\n 'her', 'was', 'one', 'our', 'out', 'has', 'have', 'been', 'from', 'that',\n 'this', 'with', 'they', 'will', 'each', 'make', 'like', 'than', 'them',\n 'then', 'what', 'when', 'into', 'more', 'some', 'such', 'also', 'use',\n 'used', 'using', 'should', 'would', 'could', 'about', 'which', 'their',\n 'there', 'these', 'those', 'does', 'done', 'just', 'very',\n]);\n\n/**\n * Extract meaningful keywords from text.\n */\nfunction extractKeywords(text: string): ReadonlySet<string> {\n const words = text.toLowerCase().match(/[a-z][a-z0-9_-]+/g) ?? [];\n return new Set(\n words.filter(w => w.length >= MIN_KEYWORD_LENGTH && !STOP_WORDS.has(w)),\n );\n}\n\n/**\n * Check if new content potentially contradicts existing content.\n *\n * Heuristic: high keyword overlap + negation markers = likely contradiction.\n * Not perfect, but catches the common case of \"we used X\" vs \"we no longer use X\".\n */\nexport function checkContradiction(newContent: string, existingContent: string): boolean {\n const newKeywords = extractKeywords(newContent);\n const existingKeywords = extractKeywords(existingContent);\n\n if (newKeywords.size === 0 || existingKeywords.size === 0) return false;\n\n // Compute Jaccard-like overlap: |intersection| / |smaller set|\n let overlap = 0;\n for (const kw of newKeywords) {\n if (existingKeywords.has(kw)) overlap++;\n }\n\n const smallerSize = Math.min(newKeywords.size, existingKeywords.size);\n const overlapRatio = overlap / smallerSize;\n\n if (overlapRatio < KEYWORD_OVERLAP_THRESHOLD) return false;\n\n // High overlap — check for negation markers in the NEW content only.\n return NEGATION_PATTERNS.some(pattern => pattern.test(newContent));\n}\n","import { z } from 'zod';\nimport type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';\nimport type { ToolDeps } from './register.js';\nimport { MEMORY_TYPES } from '../types.js';\n\nconst inputSchema = {\n query: z.string().min(1).max(500).describe('Search query (natural language or keywords)'),\n id: z.string().optional().describe('Direct lookup by memory ID (bypasses search)'),\n type: z.enum(MEMORY_TYPES).optional().describe('Filter by memory type'),\n tags: z.array(z.string()).max(10).optional().describe('Filter to memories containing ALL of these tags'),\n limit: z.number().int().min(1).max(50).default(10).describe('Maximum results to return'),\n min_importance: z.number().min(0).max(1).default(0).describe('Minimum importance threshold'),\n};\n\nexport function registerSearch(server: McpServer, deps: ToolDeps): void {\n server.registerTool(\n 'memory_search',\n {\n description:\n 'Search memories by keyword match, context relevance, and relation graph. '\n + 'Returns up to `limit` results ranked by composite score (text match, importance, recency, access frequency, git context). '\n + 'Related memories are automatically surfaced via 1-hop graph expansion. '\n + 'Pass `id` for direct lookup. Use `type` and `tags` to filter.',\n inputSchema,\n annotations: { readOnlyHint: true, idempotentHint: true },\n },\n async (args) => {\n const results = await deps.retrievalService.search({\n query: args.query,\n id: args.id,\n type: args.type,\n tags: args.tags,\n limit: args.limit,\n min_importance: args.min_importance,\n project: deps.project ?? undefined,\n });\n\n if (results.length === 0) {\n return {\n content: [{ type: 'text' as const, text: 'No memories found matching your query.' }],\n };\n }\n\n const formatted = results.map((r, i) => ({\n rank: i + 1,\n id: r.memory.id,\n type: r.memory.type,\n title: r.memory.title,\n content: r.memory.content.slice(0, 500),\n score: Math.round(r.score * 100) / 100,\n explanation: r.explanation,\n importance: r.memory.importance,\n tags: r.memory.tags,\n accessCount: r.memory.accessCount,\n createdAt: r.memory.createdAt,\n }));\n\n return {\n content: [{\n type: 'text' as const,\n text: JSON.stringify(formatted, null, 2),\n }],\n };\n },\n );\n}\n","import { z } from 'zod';\nimport type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';\nimport type { ToolDeps } from './register.js';\nimport { memoryNotFound, formatMcpError } from '../utils/errors.js';\n\nconst inputSchema = {\n id: z.string().describe('ID of the memory to forget'),\n hard_delete: z.boolean().default(false).describe('true = permanent delete, false = set importance to 0 (soft delete)'),\n};\n\nexport function registerForget(server: McpServer, deps: ToolDeps): void {\n server.registerTool(\n 'memory_forget',\n {\n description:\n 'Forget a memory. By default, soft-deletes (sets importance to 0, allowing natural decay). '\n + 'Pass hard_delete=true to permanently remove. Use memory_search to find the ID first.',\n inputSchema,\n annotations: { destructiveHint: true, idempotentHint: true },\n },\n async (args) => {\n const memory = deps.memoryRepo.getById(args.id);\n if (!memory) {\n return formatMcpError(memoryNotFound(args.id));\n }\n\n if (deps.project && memory.project !== null && memory.project !== deps.project) {\n return formatMcpError({\n what: `Memory ${args.id} belongs to project \"${memory.project}\".`,\n why: `Current project is \"${deps.project}\". Cross-project deletion is not allowed.`,\n fix: 'Switch to the correct project or use a global context.',\n });\n }\n\n if (args.hard_delete) {\n deps.memoryRepo.hardDelete(args.id);\n return {\n content: [{\n type: 'text' as const,\n text: `Permanently deleted memory ${args.id} (\"${memory.title ?? memory.content.slice(0, 50)}\")`,\n }],\n };\n }\n\n deps.memoryRepo.softDelete(args.id);\n return {\n content: [{\n type: 'text' as const,\n text: `Soft-deleted memory ${args.id} (importance set to 0, will decay naturally)`,\n }],\n };\n },\n );\n}\n","// ── Structured Error Formatting ──────────────────────────────\n// Every error answers: What happened? Why? What to do?\n\nexport interface StructuredError {\n readonly what: string;\n readonly why: string;\n readonly fix: string;\n}\n\nexport function formatError(err: StructuredError): string {\n return `${err.what}\\nWhy: ${err.why}\\nFix: ${err.fix}`;\n}\n\nexport function formatMcpError(err: StructuredError): { isError: true; content: [{ type: 'text'; text: string }] } {\n return {\n isError: true,\n content: [{ type: 'text' as const, text: formatError(err) }],\n };\n}\n\n// ── Common Error Templates ───────────────────────────────────\n\nexport function memoryNotFound(id: string): StructuredError {\n return {\n what: `Memory \"${id}\" not found.`,\n why: 'The ID may be incorrect, or the memory was deleted or pruned.',\n fix: 'Use memory_search to find valid IDs.',\n };\n}\n\nexport function databaseLocked(): StructuredError {\n return {\n what: 'Database is temporarily locked.',\n why: 'Another process is writing to the database (SQLITE_BUSY).',\n fix: 'Retry in a moment. If persistent, run: claude-launchpad doctor --fix',\n };\n}\n\nexport function databaseCorrupt(): StructuredError {\n return {\n what: 'Database integrity check failed.',\n why: 'The database file may be corrupted (disk error, incomplete write).',\n fix: 'Run: claude-launchpad doctor --fix (creates backup, reinitializes DB)',\n };\n}\n\nexport function diskFull(): StructuredError {\n return {\n what: 'Disk write failed — not enough space.',\n why: 'The disk partition containing ~/.agentic-memory is full.',\n fix: 'Free disk space, then run: claude-launchpad doctor --fix',\n };\n}\n\nexport function invalidInput(field: string, reason: string): StructuredError {\n return {\n what: `Invalid input: ${field}`,\n why: reason,\n fix: 'Check the parameter value and try again.',\n };\n}\n\n// ── SQLite Retry Logic ───────────────────────────────────────\n\nconst RETRY_DELAYS = [100, 200, 400] as const;\n\nexport function withRetry<T>(fn: () => T, label: string): T {\n for (let attempt = 0; attempt < RETRY_DELAYS.length; attempt++) {\n try {\n return fn();\n } catch (err) {\n if (isSqliteBusy(err) && attempt < RETRY_DELAYS.length - 1) {\n const delay = RETRY_DELAYS[attempt]!;\n process.stderr.write(`[memory] ${label}: SQLITE_BUSY, retrying in ${delay}ms\\n`);\n sleepSync(delay);\n continue;\n }\n throw err;\n }\n }\n // Unreachable, but TypeScript needs it\n throw new Error(`${label}: exhausted retries`);\n}\n\nfunction isSqliteBusy(err: unknown): boolean {\n if (err instanceof Error) {\n return err.message.includes('SQLITE_BUSY') || err.message.includes('database is locked');\n }\n return false;\n}\n\nfunction sleepSync(ms: number): void {\n Atomics.wait(new Int32Array(new SharedArrayBuffer(4)), 0, 0, ms);\n}\n","import { z } from 'zod';\nimport type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';\nimport type { ToolDeps } from './register.js';\nimport { RELATION_TYPES } from '../types.js';\nimport { memoryNotFound, formatMcpError } from '../utils/errors.js';\n\nconst inputSchema = {\n source_id: z.string().describe('ID of the source memory'),\n target_id: z.string().describe('ID of the target memory'),\n relation_type: z.enum(RELATION_TYPES).describe(\n 'Type of relation: relates_to, depends_on, contradicts, extends, implements, derived_from'\n ),\n};\n\nexport function registerRelate(server: McpServer, deps: ToolDeps): void {\n server.registerTool(\n 'memory_relate',\n {\n description:\n 'Create a typed relation between two memories. '\n + 'Relations affect retrieval ranking (connected memories decay slower). '\n + 'Types: relates_to, depends_on, contradicts, extends, implements, derived_from.',\n inputSchema,\n annotations: { idempotentHint: true },\n },\n async (args) => {\n if (args.source_id === args.target_id) {\n return formatMcpError({\n what: 'Cannot create self-relation.',\n why: 'source_id and target_id are the same memory.',\n fix: 'Provide two different memory IDs.',\n });\n }\n\n const source = deps.memoryRepo.getById(args.source_id);\n if (!source) {\n return formatMcpError(memoryNotFound(args.source_id));\n }\n\n const target = deps.memoryRepo.getById(args.target_id);\n if (!target) {\n return formatMcpError(memoryNotFound(args.target_id));\n }\n\n if (deps.project) {\n for (const mem of [source, target]) {\n if (mem.project !== null && mem.project !== deps.project) {\n return formatMcpError({\n what: `Memory ${mem.id} belongs to project \"${mem.project}\".`,\n why: `Current project is \"${deps.project}\". Cross-project relations are not allowed.`,\n fix: 'Both memories must belong to the same project.',\n });\n }\n }\n }\n\n const created = deps.relationRepo.create(args.source_id, args.target_id, args.relation_type);\n\n if (!created) {\n return {\n content: [{\n type: 'text' as const,\n text: `Relation already exists: ${args.source_id} --[${args.relation_type}]--> ${args.target_id}`,\n }],\n };\n }\n\n return {\n content: [{\n type: 'text' as const,\n text: `Created relation: \"${source.title ?? source.content.slice(0, 40)}\" --[${args.relation_type}]--> \"${target.title ?? target.content.slice(0, 40)}\"`,\n }],\n };\n },\n );\n}\n","import type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';\nimport type { ToolDeps } from './register.js';\nimport { MEMORY_TYPES } from '../types.js';\nimport type { MemoryStats } from '../types.js';\nimport { statSync } from 'node:fs';\nimport { join } from 'node:path';\n\nexport function registerStats(server: McpServer, deps: ToolDeps): void {\n server.registerTool(\n 'memory_stats',\n {\n description:\n 'Show memory dashboard: total count, breakdown by type, storage size, '\n + 'and most-injected memories. No arguments needed.',\n annotations: { readOnlyHint: true, idempotentHint: true },\n },\n async () => {\n const countByType = deps.memoryRepo.countByType();\n const total = deps.memoryRepo.count();\n const topInjected = deps.memoryRepo.topInjected(5);\n const totalRelations = deps.relationRepo.count();\n\n let dbSizeBytes = 0;\n try {\n const dbPath = join(deps.dataDir, 'memory.db');\n dbSizeBytes = statSync(dbPath).size;\n } catch {\n // :memory: or file not found\n }\n\n const { oldest, newest } = deps.memoryRepo.dateRange();\n\n const stats: MemoryStats = {\n totalMemories: total,\n byType: Object.fromEntries(\n MEMORY_TYPES.map(t => [t, countByType[t] ?? 0])\n ) as Record<string, number>,\n totalRelations,\n dbSizeBytes,\n oldestMemory: oldest,\n newestMemory: newest,\n topInjected,\n };\n\n return {\n content: [{\n type: 'text' as const,\n text: JSON.stringify(stats, null, 2),\n }],\n };\n },\n );\n}\n","import { z } from 'zod';\nimport type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';\nimport type { ToolDeps } from './register.js';\nimport { MEMORY_TYPES } from '../types.js';\n\nconst inputSchema = {\n limit: z.number().int().min(1).max(50).default(10).describe('Maximum memories to return'),\n type: z.enum(MEMORY_TYPES).optional().describe('Filter by memory type'),\n};\n\nexport function registerRecent(server: McpServer, deps: ToolDeps): void {\n server.registerTool(\n 'memory_recent',\n {\n description:\n 'Load session context: returns context-matched, recent, and related memories. '\n + 'Call this at the start of every session to load context from previous work. '\n + 'Results are grouped into sections: contextMatched (matching current branch/files), '\n + 'recent (most recent), and related (connected via relations).',\n inputSchema,\n annotations: { readOnlyHint: true, idempotentHint: true },\n },\n async (args) => {\n const results = deps.retrievalService.loadSessionContext({\n limit: args.limit,\n project: deps.project ?? undefined,\n type: args.type,\n });\n\n if (results.length === 0) {\n return {\n content: [{ type: 'text' as const, text: 'No memories found for this project.' }],\n };\n }\n\n const formatEntry = (entry: typeof results[number], rank: number) => ({\n rank,\n section: entry.section,\n id: entry.result.memory.id,\n type: entry.result.memory.type,\n title: entry.result.memory.title,\n content: entry.result.memory.content.slice(0, 500),\n importance: entry.result.memory.importance,\n tags: entry.result.memory.tags,\n score: Math.round(entry.result.score * 100) / 100,\n explanation: entry.result.explanation,\n createdAt: entry.result.memory.createdAt,\n });\n\n const contextMatched = results.filter(r => r.section === 'context').map((r, i) => formatEntry(r, i + 1));\n const recent = results.filter(r => r.section === 'recent').map((r, i) => formatEntry(r, i + 1));\n const related = results.filter(r => r.section === 'related').map((r, i) => formatEntry(r, i + 1));\n\n return {\n content: [{\n type: 'text' as const,\n text: JSON.stringify({ contextMatched, recent, related }, null, 2),\n }],\n };\n },\n );\n}\n","import { z } from 'zod';\nimport type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';\nimport type { ToolDeps } from './register.js';\n\nconst inputSchema = {\n id: z.string().describe('Memory ID to update (use memory_search to find it)'),\n title: z.string().max(200).optional().describe('Updated title'),\n content: z.string().min(1).max(10000).optional().describe('Updated content'),\n tags: z.array(z.string()).max(20).optional().describe('Updated tags'),\n importance: z.number().min(0).max(1).optional().describe('Updated importance (0-1)'),\n context: z.string().optional().describe('Updated context JSON'),\n};\n\nexport function registerUpdate(server: McpServer, deps: ToolDeps): void {\n server.registerTool(\n 'memory_update',\n {\n description:\n 'Update an existing memory in-place. Preserves access count, injection count, and creation date. '\n + 'Use memory_search to find the ID first. At least one field must be provided.',\n inputSchema,\n annotations: { readOnlyHint: false, destructiveHint: false, idempotentHint: true },\n },\n async (args) => {\n const hasUpdate = args.title !== undefined || args.content !== undefined\n || args.tags !== undefined || args.importance !== undefined\n || args.context !== undefined;\n\n if (!hasUpdate) {\n return {\n content: [{ type: 'text' as const, text: 'No fields to update. Provide at least one of: title, content, tags, importance, context.' }],\n isError: true,\n };\n }\n\n const existing = deps.memoryRepo.getById(args.id);\n if (!existing) {\n return {\n content: [{ type: 'text' as const, text: `Memory ${args.id} not found.` }],\n isError: true,\n };\n }\n\n const updated = deps.memoryRepo.updateContent(args.id, {\n title: args.title,\n content: args.content,\n tags: args.tags,\n importance: args.importance,\n context: args.context,\n });\n\n if (!updated) {\n return {\n content: [{ type: 'text' as const, text: `Failed to update memory ${args.id}.` }],\n isError: true,\n };\n }\n\n const fields = [\n args.title !== undefined && 'title',\n args.content !== undefined && 'content',\n args.tags !== undefined && 'tags',\n args.importance !== undefined && 'importance',\n args.context !== undefined && 'context',\n ].filter(Boolean).join(', ');\n\n return {\n content: [{ type: 'text' as const, text: `Updated memory ${args.id} (fields: ${fields})` }],\n };\n },\n );\n}\n","import type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';\nimport type { MemoryRepo } from '../storage/memory-repo.js';\nimport type { RelationRepo } from '../storage/relation-repo.js';\nimport type { RetrievalService } from '../services/retrieval-service.js';\nimport { registerStore } from './store.js';\nimport { registerSearch } from './search.js';\nimport { registerForget } from './forget.js';\nimport { registerRelate } from './relate.js';\nimport { registerStats } from './stats.js';\nimport { registerRecent } from './recent.js';\nimport { registerUpdate } from './update.js';\n\nexport interface ToolDeps {\n readonly memoryRepo: MemoryRepo;\n readonly relationRepo: RelationRepo;\n readonly retrievalService: RetrievalService;\n readonly dataDir: string;\n readonly project: string | null;\n}\n\nexport function registerTools(server: McpServer, deps: ToolDeps): void {\n registerStore(server, deps);\n registerSearch(server, deps);\n registerRecent(server, deps);\n registerForget(server, deps);\n registerRelate(server, deps);\n registerStats(server, deps);\n registerUpdate(server, deps);\n}\n"],"mappings":"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","names":["z","inputSchema","z","z","inputSchema","z","z","inputSchema","z","z","inputSchema","z","z","inputSchema"]}
1
+ {"version":3,"sources":["../../../src/commands/memory/server.ts","../../../src/commands/memory/services/retrieval-service.ts","../../../src/commands/memory/tools/store.ts","../../../src/commands/memory/utils/content-validation.ts","../../../src/commands/memory/utils/contradiction.ts","../../../src/commands/memory/tools/search.ts","../../../src/commands/memory/tools/forget.ts","../../../src/commands/memory/utils/errors.ts","../../../src/commands/memory/tools/relate.ts","../../../src/commands/memory/tools/stats.ts","../../../src/commands/memory/tools/recent.ts","../../../src/commands/memory/tools/update.ts","../../../src/commands/memory/tools/register.ts"],"sourcesContent":["import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';\nimport { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';\nimport { createDatabase, closeDatabase } from './storage/database.js';\nimport { migrate } from './storage/migrator.js';\nimport { MemoryRepo } from './storage/memory-repo.js';\nimport { RelationRepo } from './storage/relation-repo.js';\nimport { SearchRepo } from './storage/search-repo.js';\nimport { RetrievalService } from './services/retrieval-service.js';\nimport { loadConfig, resolveDataDir } from './config.js';\nimport type { Config } from './config.js';\nimport { registerTools } from './tools/register.js';\nimport { detectProject } from './utils/project.js';\n\nexport interface ServerDeps {\n readonly config: Config;\n}\n\nexport async function startServer(deps?: Partial<ServerDeps>): Promise<void> {\n const config = deps?.config ?? loadConfig();\n const dataDir = resolveDataDir(config.dataDir);\n\n const db = createDatabase({ dataDir });\n migrate(db);\n\n const memoryRepo = new MemoryRepo(db);\n const relationRepo = new RelationRepo(db);\n const searchRepo = new SearchRepo(db);\n\n const retrievalService = new RetrievalService({\n memoryRepo,\n relationRepo,\n searchRepo,\n });\n\n const server = new McpServer(\n { name: 'agentic-memory', version: '0.1.0' },\n {\n instructions:\n 'Use memory_search before memory_store to check for duplicates. '\n + 'Use memory_update to modify existing memories instead of creating duplicates - it preserves access history. '\n + 'Store memories at the semantic level - capture WHY, not just WHAT happened. '\n + 'Only store knowledge worth remembering across sessions. '\n + 'NEVER store credentials, API keys, tokens, passwords, or secrets - memories may be synced to external storage. '\n + 'Memory context is automatically injected at session start via hook - no need to call memory_recent manually.',\n },\n );\n\n const project = detectProject(process.cwd());\n\n registerTools(server, { memoryRepo, relationRepo, retrievalService, dataDir, project });\n\n const transport = new StdioServerTransport();\n await server.connect(transport);\n\n const shutdown = async () => {\n await server.close();\n closeDatabase(db);\n process.exit(0);\n };\n process.on('SIGINT', () => void shutdown());\n process.on('SIGTERM', () => void shutdown());\n}\n\n// Auto-start when invoked directly as MCP server entry point\nstartServer().catch((err) => {\n process.stderr.write(`[agentic-memory] ${err}\\n`);\n process.exit(1);\n});\n","import type { Memory, MemoryType, SearchResult, SearchInput, RelationType } from '../types.js';\nimport type { MemoryRepo } from '../storage/memory-repo.js';\nimport type { RelationRepo } from '../storage/relation-repo.js';\nimport type { SearchRepo } from '../storage/search-repo.js';\nimport { SCORING_WEIGHTS } from '../config.js';\nimport { type GitContext, getGitContext, computeContextScore } from '../utils/git-context.js';\n\nconst STALENESS_THRESHOLDS = {\n working: 1,\n episodic: 7,\n pattern: 14,\n semantic: 30,\n procedural: 90,\n} as const;\n\nexport interface RetrievalDeps {\n readonly memoryRepo: MemoryRepo;\n readonly relationRepo: RelationRepo;\n readonly searchRepo: SearchRepo;\n readonly gitContext?: GitContext;\n}\n\nexport class RetrievalService {\n readonly #deps: RetrievalDeps;\n readonly #gitContext: GitContext;\n\n constructor(deps: RetrievalDeps) {\n this.#deps = deps;\n this.#gitContext = deps.gitContext ?? getGitContext();\n }\n\n /**\n * FTS5 keyword search with multi-signal scoring, context awareness,\n * and relation-based graph expansion.\n */\n async search(input: SearchInput): Promise<readonly SearchResult[]> {\n // Direct ID lookup\n if (input.id) {\n const memory = this.#deps.memoryRepo.getById(input.id);\n if (!memory) return [];\n this.#deps.memoryRepo.incrementAccess(input.id);\n return [{\n memory,\n score: 1.0,\n explanation: 'Direct lookup by ID',\n }];\n }\n\n // Phase 1: FTS5 keyword search\n const ftsResults = this.#deps.searchRepo.searchFts({\n query: input.query,\n limit: input.limit * 3,\n type: input.type,\n minImportance: input.min_importance,\n project: input.project,\n });\n\n const textScores = ftsOnlyScores(ftsResults);\n if (textScores.size === 0) return [];\n\n // Phase 2: Load memories and compute composite scores\n const candidates: { memory: Memory; composite: number; parts: ScoreParts }[] = [];\n\n for (const [memoryId, textScore] of textScores) {\n const memory = this.#deps.memoryRepo.getById(memoryId);\n if (!memory) continue;\n if (input.type && memory.type !== input.type) continue;\n if (memory.importance < input.min_importance) continue;\n if (input.tags?.length) {\n const memTags = new Set(memory.tags);\n if (!input.tags.every(t => memTags.has(t))) continue;\n }\n\n const parts = computeScoreParts(memory, textScore, this.#gitContext, input.query);\n const composite = computeComposite(parts);\n candidates.push({ memory, composite, parts });\n }\n\n // Phase 3: Sort by composite score\n candidates.sort((a, b) => b.composite - a.composite);\n let topN = candidates.slice(0, input.limit);\n\n // Phase 4: Relation expansion — surface connected memories\n const seenIds = new Set(topN.map(c => c.memory.id));\n const expanded = this.#expandWithRelations(topN, input.limit, seenIds, input.min_importance);\n if (expanded.length > 0) {\n topN = [...topN, ...expanded].sort((a, b) => b.composite - a.composite).slice(0, input.limit);\n }\n\n // Phase 5: Build results with explanations, increment access\n return topN.map(({ memory, composite, parts }) => {\n this.#deps.memoryRepo.incrementAccess(memory.id);\n return {\n memory,\n score: composite,\n explanation: parts.relationSource\n ? `Related (${parts.relationSource.type}) to: ${parts.relationSource.title ?? parts.relationSource.id}`\n : buildExplanation(parts, memory),\n };\n });\n }\n\n /**\n * Smart session loading: returns context-matched, recent, and related memories\n * for session start context injection.\n */\n loadSessionContext(input: {\n readonly limit: number;\n readonly project?: string;\n readonly type?: MemoryType;\n }): readonly SessionContextResult[] {\n const contextBudget = Math.floor(input.limit * 0.4);\n const recentBudget = Math.floor(input.limit * 0.4);\n const relatedBudget = input.limit - contextBudget - recentBudget;\n const seenIds = new Set<string>();\n\n const contextMatched = this.#loadContextMatched(contextBudget, input.project, input.type, seenIds);\n const recent = this.#loadRecent(recentBudget, input.project, input.type, seenIds);\n\n const sourceIds = [...contextMatched, ...recent].map(r => r.result.memory.id);\n const related = this.#loadRelatedExpansion(sourceIds, relatedBudget, seenIds);\n\n const all = [...contextMatched, ...recent, ...related];\n for (const entry of all) {\n this.#deps.memoryRepo.incrementInjection(entry.result.memory.id);\n }\n return all;\n }\n\n #loadContextMatched(\n budget: number, project?: string, type?: MemoryType, seenIds?: Set<string>,\n ): SessionContextResult[] {\n if (budget <= 0) return [];\n const candidates = this.#deps.memoryRepo.getRecent(budget * 5, project, type);\n const scored: { memory: Memory; ctxScore: number; composite: number }[] = [];\n\n for (const m of candidates) {\n const ctxScore = computeContextScore(m.context, this.#gitContext, '');\n if (ctxScore <= 0.1) continue;\n const composite = ctxScore * 0.5 + m.importance * 0.3 + computeRecencyScore(m.updatedAt) * 0.2;\n scored.push({ memory: m, ctxScore, composite });\n }\n\n scored.sort((a, b) => b.composite - a.composite);\n const results: SessionContextResult[] = [];\n for (const s of scored.slice(0, budget)) {\n seenIds?.add(s.memory.id);\n results.push({ section: 'context', result: { memory: s.memory, score: s.composite, explanation: 'Context match' } });\n }\n return results;\n }\n\n #loadRecent(\n budget: number, project?: string, type?: MemoryType, seenIds?: Set<string>,\n ): SessionContextResult[] {\n if (budget <= 0) return [];\n const candidates = this.#deps.memoryRepo.getRecent(budget * 2, project, type);\n const results: SessionContextResult[] = [];\n\n for (const m of candidates) {\n if (seenIds?.has(m.id)) continue;\n const score = m.importance * 0.4 + computeRecencyScore(m.updatedAt) * 0.6;\n seenIds?.add(m.id);\n results.push({ section: 'recent', result: { memory: m, score, explanation: 'Recent' } });\n if (results.length >= budget) break;\n }\n return results;\n }\n\n #loadRelatedExpansion(\n sourceIds: readonly string[], budget: number, seenIds: Set<string>,\n ): SessionContextResult[] {\n if (budget <= 0) return [];\n const results: SessionContextResult[] = [];\n\n for (const srcId of sourceIds) {\n const relations = this.#deps.relationRepo.getByMemory(srcId);\n for (const rel of relations) {\n const otherId = rel.sourceId === srcId ? rel.targetId : rel.sourceId;\n if (otherId === srcId || seenIds.has(otherId)) continue;\n\n const other = this.#deps.memoryRepo.getById(otherId);\n if (!other) continue;\n\n const src = this.#deps.memoryRepo.getById(srcId);\n const weight = RELATION_TYPE_WEIGHTS[rel.relationType] ?? 0.5;\n seenIds.add(otherId);\n results.push({\n section: 'related',\n result: {\n memory: other,\n score: other.importance * weight,\n explanation: `Related (${rel.relationType}) to: ${src?.title ?? srcId}`,\n },\n });\n if (results.length >= budget) return results;\n }\n }\n return results;\n }\n\n #expandWithRelations(\n topResults: readonly { memory: Memory; composite: number; parts: ScoreParts }[],\n limit: number,\n seenIds: Set<string>,\n minImportance: number,\n ): { memory: Memory; composite: number; parts: ScoreParts }[] {\n if (topResults.length >= limit) return [];\n\n const expanded: { memory: Memory; composite: number; parts: ScoreParts }[] = [];\n const remaining = limit - topResults.length;\n const sourcesToExpand = topResults.slice(0, 5);\n\n for (const parent of sourcesToExpand) {\n const relations = this.#deps.relationRepo.getByMemory(parent.memory.id);\n for (const rel of relations) {\n const otherId = rel.sourceId === parent.memory.id ? rel.targetId : rel.sourceId;\n if (otherId === parent.memory.id || seenIds.has(otherId)) continue;\n\n const other = this.#deps.memoryRepo.getById(otherId);\n if (!other || other.importance < minImportance) continue;\n\n const weight = RELATION_TYPE_WEIGHTS[rel.relationType] ?? 0.5;\n const composite = parent.composite * 0.7 * weight;\n const parts: ScoreParts = {\n textScore: 0,\n importanceScore: other.importance,\n recencyScore: computeRecencyScore(other.updatedAt),\n accessScore: computeAccessScore(other.accessCount, other.lastAccessed),\n contextScore: 0,\n relationSource: { id: parent.memory.id, title: parent.memory.title, type: rel.relationType },\n };\n\n seenIds.add(otherId);\n expanded.push({ memory: other, composite, parts });\n if (expanded.length >= remaining) return expanded;\n }\n }\n\n return expanded;\n }\n}\n\n// ── Relation Expansion ──────────────────────────────────────\n\nconst RELATION_TYPE_WEIGHTS: Record<RelationType, number> = {\n depends_on: 1.0,\n extends: 0.9,\n implements: 0.9,\n relates_to: 0.7,\n derived_from: 0.6,\n contradicts: 0.3,\n};\n\n// ── FTS5-Only Fallback ───────────────────────────────────────\n\nfunction ftsOnlyScores(ftsResults: readonly { memoryId: string; rank: number }[]): Map<string, number> {\n const scores = new Map<string, number>();\n for (const r of ftsResults) {\n const score = Math.min(1, -r.rank / 20);\n scores.set(r.memoryId, score);\n }\n return scores;\n}\n\n// ── Scoring ───────────────────────────────────────────────────\n\ninterface ScoreParts {\n readonly textScore: number;\n readonly importanceScore: number;\n readonly recencyScore: number;\n readonly accessScore: number;\n readonly contextScore: number;\n readonly relationSource?: { readonly id: string; readonly title: string | null; readonly type: RelationType };\n}\n\nfunction computeScoreParts(\n memory: Memory,\n textScore: number,\n gitContext: GitContext,\n query: string,\n): ScoreParts {\n return {\n textScore,\n importanceScore: memory.importance,\n recencyScore: computeRecencyScore(memory.updatedAt),\n accessScore: computeAccessScore(memory.accessCount, memory.lastAccessed),\n contextScore: computeContextScore(memory.context, gitContext, query),\n };\n}\n\nfunction computeComposite(parts: ScoreParts): number {\n return (\n parts.textScore * SCORING_WEIGHTS.text +\n parts.importanceScore * SCORING_WEIGHTS.importance +\n parts.recencyScore * SCORING_WEIGHTS.recency +\n parts.accessScore * SCORING_WEIGHTS.access +\n parts.contextScore * SCORING_WEIGHTS.context\n );\n}\n\n/**\n * Recency score: 1.0 for today, decays exponentially.\n * Uses a 30-day half-life.\n */\nfunction computeRecencyScore(updatedAt: string): number {\n const ageMs = Date.now() - new Date(updatedAt).getTime();\n const ageDays = ageMs / (1000 * 60 * 60 * 24);\n if (ageDays < 0) return 1.0;\n return Math.exp(-ageDays * Math.LN2 / 30);\n}\n\n/**\n * Access score: logarithmic count x recency of last access.\n */\nfunction computeAccessScore(accessCount: number, lastAccessed: string | null): number {\n if (accessCount <= 0) return 0;\n const countScore = Math.min(1.0, Math.log10(accessCount + 1) / Math.log10(31));\n if (!lastAccessed) return countScore * 0.5;\n const ageDays = (Date.now() - new Date(lastAccessed).getTime()) / 86_400_000;\n const recency = Math.exp(-ageDays * Math.LN2 / 30);\n return countScore * (0.5 + 0.5 * recency);\n}\n\n// ── Explanation ───────────────────────────────────────────────\n\nfunction buildExplanation(parts: ScoreParts, memory: Memory): string {\n const factors: string[] = [];\n\n if (parts.textScore > 0.7) {\n factors.push(`High text match (${(parts.textScore * 100).toFixed(0)}%)`);\n } else if (parts.textScore > 0.3) {\n factors.push(`Moderate text match (${(parts.textScore * 100).toFixed(0)}%)`);\n }\n\n if (memory.importance > 0.7) {\n factors.push('High importance');\n }\n\n if (parts.recencyScore > 0.8) {\n factors.push('Very recent');\n } else if (parts.recencyScore > 0.5) {\n factors.push('Recent');\n }\n\n if (memory.accessCount > 10) {\n factors.push(`Frequently accessed (${memory.accessCount}x)`);\n } else if (memory.accessCount > 3) {\n factors.push(`Accessed ${memory.accessCount}x`);\n }\n\n if (parts.contextScore > 0.3) {\n factors.push('Context match');\n }\n\n const ageDays = Math.floor((Date.now() - new Date(memory.createdAt).getTime()) / 86_400_000);\n const stalenessThreshold = STALENESS_THRESHOLDS[memory.type];\n if (stalenessThreshold !== undefined && ageDays > stalenessThreshold) {\n factors.push(`${ageDays}d old - verify before acting`);\n }\n\n return factors.length > 0 ? factors.join(' + ') : 'Matched query';\n}\n\n// ── Types ────────────────────────────────────────────────────\n\nexport interface SessionContextResult {\n readonly section: 'context' | 'recent' | 'related';\n readonly result: SearchResult;\n}\n\n// Exported for testing\nexport { computeRecencyScore, computeAccessScore, computeComposite, computeScoreParts, ftsOnlyScores };\nexport type { ScoreParts };\n","import { z } from 'zod';\nimport { createHash } from 'node:crypto';\nimport type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';\nimport type { ToolDeps } from './register.js';\nimport { MEMORY_TYPES, MEMORY_SOURCES } from '../types.js';\nimport { getGitContext } from '../utils/git-context.js';\nimport { validateMemoryContent } from '../utils/content-validation.js';\nimport { checkContradiction } from '../utils/contradiction.js';\n\n// In-memory dedup: content hash → timestamp. Catches parallel calls within same request.\nconst recentStores = new Map<string, number>();\nconst DEDUP_WINDOW_MS = 10_000;\n\nconst inputSchema = {\n type: z.enum(MEMORY_TYPES).describe('Memory type: working, episodic, semantic, procedural, or pattern'),\n content: z.string().min(1).max(10000).describe('The memory content to store'),\n title: z.string().max(200).optional().describe('Short title for the memory'),\n tags: z.array(z.string()).max(20).default([]).describe('Tags for categorization. Suggested: #bug, #decision, #gotcha, #howto, #pattern'),\n importance: z.number().min(0).max(1).default(0.5).describe('0-0.3 ephemeral, 0.3-0.6 reference, 0.6-0.8 important, 0.8-1.0 critical'),\n context: z.string().optional().describe('JSON: {\"files\": [...], \"branch\": \"...\", \"intent\": \"...\"}. Auto-detected from git if omitted.'),\n source: z.enum(MEMORY_SOURCES).default('manual').describe('How this memory was created'),\n project: z.string().max(200).optional().describe('Project scope (auto-detected from CWD if omitted)'),\n};\n\nexport function registerStore(server: McpServer, deps: ToolDeps): void {\n server.registerTool(\n 'memory_store',\n {\n description:\n 'Store a new memory. Use memory_search first to check for duplicates. '\n + 'Prefer updating existing semantic/procedural memories over creating new ones. '\n + 'Types: episodic (events), semantic (facts), procedural (how-to), pattern (recurring), working (temporary). '\n + 'Importance: 0-0.3 ephemeral, 0.3-0.6 reference, 0.6-0.8 important, 0.8-1.0 critical. '\n + 'Suggested tags: #bug, #decision, #gotcha, #howto, #pattern, #architecture. '\n + 'Context is auto-detected from git (branch, recent files) if omitted.',\n inputSchema,\n annotations: { idempotentHint: false },\n },\n async (args) => {\n const validation = validateMemoryContent(args.content);\n if (!validation.valid) {\n return {\n content: [{\n type: 'text' as const,\n text: `Rejected: ${validation.reason}`,\n }],\n isError: true,\n };\n }\n\n const context = args.context ?? JSON.stringify(getGitContext());\n const project = args.project ?? deps.project ?? undefined;\n\n // Dedup: in-memory guard catches parallel calls within same request\n const contentHash = createHash('sha256').update(args.content).digest('hex');\n const now = Date.now();\n const lastStored = recentStores.get(contentHash);\n if (lastStored && (now - lastStored) < DEDUP_WINDOW_MS) {\n return {\n content: [{ type: 'text' as const, text: 'Duplicate: identical memory was just stored. Skipped.' }],\n };\n }\n recentStores.set(contentHash, now);\n // Prune old entries\n for (const [key, ts] of recentStores) {\n if (now - ts > DEDUP_WINDOW_MS) recentStores.delete(key);\n }\n\n // Contradiction detection\n const contradictions: { id: string; title: string | null }[] = [];\n try {\n const existing = await deps.retrievalService.search({\n query: args.content.slice(0, 200),\n limit: 3,\n min_importance: 0,\n project,\n });\n for (const result of existing) {\n if (result.score > 0.6 && checkContradiction(args.content, result.memory.content)) {\n contradictions.push({ id: result.memory.id, title: result.memory.title });\n }\n }\n } catch {\n // Contradiction check is best-effort\n }\n\n const memory = deps.memoryRepo.create(\n {\n type: args.type,\n content: args.content,\n title: args.title,\n tags: args.tags,\n importance: args.importance,\n context,\n source: args.source,\n project,\n },\n null,\n );\n\n // Create contradiction relations\n for (const c of contradictions) {\n try {\n deps.relationRepo.create(memory.id, c.id, 'contradicts');\n } catch {\n // Relation creation is best-effort\n }\n }\n\n const parts: string[] = [\n `Stored memory ${memory.id} (type: ${memory.type}, importance: ${memory.importance})`,\n ];\n\n for (const warning of validation.warnings) {\n parts.push(`Warning: ${warning}`);\n }\n\n for (const c of contradictions) {\n parts.push(`Warning: potential contradiction with memory ${c.id}${c.title ? ` (\"${c.title}\")` : ''}. Linked with 'contradicts' relation.`);\n }\n\n return {\n content: [{\n type: 'text' as const,\n text: parts.join('\\n'),\n }],\n };\n },\n );\n}\n","// ── Content Validation for memory_store ─────────────────────\n\nexport interface ValidationResult {\n readonly valid: boolean;\n readonly reason?: string;\n readonly warnings: readonly string[];\n}\n\nconst SOFT_LENGTH_LIMIT = 1500;\nconst HARD_LENGTH_LIMIT = 5000;\nconst CODE_RATIO_THRESHOLD = 0.5;\n\n/**\n * Validate memory content before storage.\n * Returns hard rejections (don't store) and soft warnings (store but warn).\n */\nexport function validateMemoryContent(content: string): ValidationResult {\n const warnings: string[] = [];\n\n // Hard reject: git log output\n if (isGitLog(content)) {\n return { valid: false, reason: 'Content looks like raw git log output. Use git log directly — don\\'t store it as memory.', warnings: [] };\n }\n\n // Hard reject: code-heavy content\n if (isCodeHeavy(content)) {\n return { valid: false, reason: 'Content is >50% code blocks. Code belongs in files, not memory. Store the insight or decision instead.', warnings: [] };\n }\n\n // Hard reject: too long\n if (content.length > HARD_LENGTH_LIMIT) {\n return { valid: false, reason: `Content is ${content.length} chars (limit: ${HARD_LENGTH_LIMIT}). Break it into smaller, atomic memories.`, warnings: [] };\n }\n\n // Soft warn: lengthy\n if (content.length > SOFT_LENGTH_LIMIT) {\n warnings.push(`Content is ${content.length} chars. Shorter memories (<${SOFT_LENGTH_LIMIT} chars) are easier to retrieve and less likely to decay.`);\n }\n\n return { valid: true, warnings };\n}\n\n/**\n * Content is >50% fenced code blocks.\n */\nexport function isCodeHeavy(content: string): boolean {\n const fencedBlockPattern = /```[\\s\\S]*?```/g;\n let codeChars = 0;\n let match: RegExpExecArray | null;\n\n while ((match = fencedBlockPattern.exec(content)) !== null) {\n codeChars += match[0].length;\n }\n\n return content.length > 0 && codeChars / content.length > CODE_RATIO_THRESHOLD;\n}\n\n/**\n * Content looks like raw git log output.\n * Matches patterns like \"commit abc123\\nAuthor: ...\\nDate: ...\"\n */\nexport function isGitLog(content: string): boolean {\n const lines = content.split('\\n');\n let gitLogLines = 0;\n\n for (const line of lines) {\n const trimmed = line.trim();\n if (/^commit\\s+[0-9a-f]{7,40}$/i.test(trimmed)) gitLogLines++;\n else if (/^Author:\\s+.+/i.test(trimmed)) gitLogLines++;\n else if (/^Date:\\s+.+/i.test(trimmed)) gitLogLines++;\n else if (/^[0-9a-f]{7,12}\\s+\\S+/i.test(trimmed) && trimmed.length < 200) gitLogLines++;\n }\n\n // At least 3 git-log-like lines and they make up >30% of non-empty lines\n const nonEmptyLines = lines.filter(l => l.trim().length > 0).length;\n return gitLogLines >= 3 && nonEmptyLines > 0 && gitLogLines / nonEmptyLines > 0.3;\n}\n","// ── Contradiction Detection (keyword-overlap heuristic) ─────\n\nconst NEGATION_PATTERNS = [\n /\\bnot\\b/i,\n /\\bno longer\\b/i,\n /\\binstead of\\b/i,\n /\\breplaced\\b/i,\n /\\bremoved\\b/i,\n /\\bdon'?t\\b/i,\n /\\bwon'?t\\b/i,\n /\\bshouldn'?t\\b/i,\n /\\bdeprecated\\b/i,\n /\\bdisabled\\b/i,\n /\\bstopped\\b/i,\n /\\bavoid\\b/i,\n /\\bnever\\b/i,\n /\\bwithout\\b/i,\n];\n\nconst KEYWORD_OVERLAP_THRESHOLD = 0.4;\nconst MIN_KEYWORD_LENGTH = 3;\nconst STOP_WORDS = new Set([\n 'the', 'and', 'for', 'are', 'but', 'not', 'you', 'all', 'can', 'had',\n 'her', 'was', 'one', 'our', 'out', 'has', 'have', 'been', 'from', 'that',\n 'this', 'with', 'they', 'will', 'each', 'make', 'like', 'than', 'them',\n 'then', 'what', 'when', 'into', 'more', 'some', 'such', 'also', 'use',\n 'used', 'using', 'should', 'would', 'could', 'about', 'which', 'their',\n 'there', 'these', 'those', 'does', 'done', 'just', 'very',\n]);\n\n/**\n * Extract meaningful keywords from text.\n */\nfunction extractKeywords(text: string): ReadonlySet<string> {\n const words = text.toLowerCase().match(/[a-z][a-z0-9_-]+/g) ?? [];\n return new Set(\n words.filter(w => w.length >= MIN_KEYWORD_LENGTH && !STOP_WORDS.has(w)),\n );\n}\n\n/**\n * Check if new content potentially contradicts existing content.\n *\n * Heuristic: high keyword overlap + negation markers = likely contradiction.\n * Not perfect, but catches the common case of \"we used X\" vs \"we no longer use X\".\n */\nexport function checkContradiction(newContent: string, existingContent: string): boolean {\n const newKeywords = extractKeywords(newContent);\n const existingKeywords = extractKeywords(existingContent);\n\n if (newKeywords.size === 0 || existingKeywords.size === 0) return false;\n\n // Compute Jaccard-like overlap: |intersection| / |smaller set|\n let overlap = 0;\n for (const kw of newKeywords) {\n if (existingKeywords.has(kw)) overlap++;\n }\n\n const smallerSize = Math.min(newKeywords.size, existingKeywords.size);\n const overlapRatio = overlap / smallerSize;\n\n if (overlapRatio < KEYWORD_OVERLAP_THRESHOLD) return false;\n\n // High overlap — check for negation markers in the NEW content only.\n return NEGATION_PATTERNS.some(pattern => pattern.test(newContent));\n}\n","import { z } from 'zod';\nimport type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';\nimport type { ToolDeps } from './register.js';\nimport { MEMORY_TYPES } from '../types.js';\n\nconst inputSchema = {\n query: z.string().min(1).max(500).describe('Search query (natural language or keywords)'),\n id: z.string().optional().describe('Direct lookup by memory ID (bypasses search)'),\n type: z.enum(MEMORY_TYPES).optional().describe('Filter by memory type'),\n tags: z.array(z.string()).max(10).optional().describe('Filter to memories containing ALL of these tags'),\n limit: z.number().int().min(1).max(50).default(10).describe('Maximum results to return'),\n min_importance: z.number().min(0).max(1).default(0).describe('Minimum importance threshold'),\n};\n\nexport function registerSearch(server: McpServer, deps: ToolDeps): void {\n server.registerTool(\n 'memory_search',\n {\n description:\n 'Search memories by keyword match, context relevance, and relation graph. '\n + 'Returns up to `limit` results ranked by composite score (text match, importance, recency, access frequency, git context). '\n + 'Related memories are automatically surfaced via 1-hop graph expansion. '\n + 'Pass `id` for direct lookup. Use `type` and `tags` to filter.',\n inputSchema,\n annotations: { readOnlyHint: true, idempotentHint: true },\n },\n async (args) => {\n const results = await deps.retrievalService.search({\n query: args.query,\n id: args.id,\n type: args.type,\n tags: args.tags,\n limit: args.limit,\n min_importance: args.min_importance,\n project: deps.project ?? undefined,\n });\n\n if (results.length === 0) {\n return {\n content: [{ type: 'text' as const, text: 'No memories found matching your query.' }],\n };\n }\n\n const formatted = results.map((r, i) => ({\n rank: i + 1,\n id: r.memory.id,\n type: r.memory.type,\n title: r.memory.title,\n content: r.memory.content.slice(0, 500),\n score: Math.round(r.score * 100) / 100,\n explanation: r.explanation,\n importance: r.memory.importance,\n tags: r.memory.tags,\n accessCount: r.memory.accessCount,\n createdAt: r.memory.createdAt,\n }));\n\n return {\n content: [{\n type: 'text' as const,\n text: JSON.stringify(formatted, null, 2),\n }],\n };\n },\n );\n}\n","import { z } from 'zod';\nimport type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';\nimport type { ToolDeps } from './register.js';\nimport { memoryNotFound, formatMcpError } from '../utils/errors.js';\n\nconst inputSchema = {\n id: z.string().describe('ID of the memory to forget'),\n hard_delete: z.boolean().default(false).describe('true = permanent delete, false = set importance to 0 (soft delete)'),\n};\n\nexport function registerForget(server: McpServer, deps: ToolDeps): void {\n server.registerTool(\n 'memory_forget',\n {\n description:\n 'Forget a memory. By default, soft-deletes (sets importance to 0, allowing natural decay). '\n + 'Pass hard_delete=true to permanently remove. Use memory_search to find the ID first.',\n inputSchema,\n annotations: { destructiveHint: true, idempotentHint: true },\n },\n async (args) => {\n const memory = deps.memoryRepo.getById(args.id);\n if (!memory) {\n return formatMcpError(memoryNotFound(args.id));\n }\n\n if (deps.project && memory.project !== null && memory.project !== deps.project) {\n return formatMcpError({\n what: `Memory ${args.id} belongs to project \"${memory.project}\".`,\n why: `Current project is \"${deps.project}\". Cross-project deletion is not allowed.`,\n fix: 'Switch to the correct project or use a global context.',\n });\n }\n\n if (args.hard_delete) {\n deps.memoryRepo.hardDelete(args.id);\n return {\n content: [{\n type: 'text' as const,\n text: `Permanently deleted memory ${args.id} (\"${memory.title ?? memory.content.slice(0, 50)}\")`,\n }],\n };\n }\n\n deps.memoryRepo.softDelete(args.id);\n return {\n content: [{\n type: 'text' as const,\n text: `Soft-deleted memory ${args.id} (importance set to 0, will decay naturally)`,\n }],\n };\n },\n );\n}\n","// ── Structured Error Formatting ──────────────────────────────\n// Every error answers: What happened? Why? What to do?\n\nexport interface StructuredError {\n readonly what: string;\n readonly why: string;\n readonly fix: string;\n}\n\nexport function formatError(err: StructuredError): string {\n return `${err.what}\\nWhy: ${err.why}\\nFix: ${err.fix}`;\n}\n\nexport function formatMcpError(err: StructuredError): { isError: true; content: [{ type: 'text'; text: string }] } {\n return {\n isError: true,\n content: [{ type: 'text' as const, text: formatError(err) }],\n };\n}\n\n// ── Common Error Templates ───────────────────────────────────\n\nexport function memoryNotFound(id: string): StructuredError {\n return {\n what: `Memory \"${id}\" not found.`,\n why: 'The ID may be incorrect, or the memory was deleted or pruned.',\n fix: 'Use memory_search to find valid IDs.',\n };\n}\n\nexport function databaseLocked(): StructuredError {\n return {\n what: 'Database is temporarily locked.',\n why: 'Another process is writing to the database (SQLITE_BUSY).',\n fix: 'Retry in a moment. If persistent, run: claude-launchpad doctor --fix',\n };\n}\n\nexport function databaseCorrupt(): StructuredError {\n return {\n what: 'Database integrity check failed.',\n why: 'The database file may be corrupted (disk error, incomplete write).',\n fix: 'Run: claude-launchpad doctor --fix (creates backup, reinitializes DB)',\n };\n}\n\nexport function diskFull(): StructuredError {\n return {\n what: 'Disk write failed — not enough space.',\n why: 'The disk partition containing ~/.agentic-memory is full.',\n fix: 'Free disk space, then run: claude-launchpad doctor --fix',\n };\n}\n\nexport function invalidInput(field: string, reason: string): StructuredError {\n return {\n what: `Invalid input: ${field}`,\n why: reason,\n fix: 'Check the parameter value and try again.',\n };\n}\n\n// ── SQLite Retry Logic ───────────────────────────────────────\n\nconst RETRY_DELAYS = [100, 200, 400] as const;\n\nexport function withRetry<T>(fn: () => T, label: string): T {\n for (let attempt = 0; attempt < RETRY_DELAYS.length; attempt++) {\n try {\n return fn();\n } catch (err) {\n if (isSqliteBusy(err) && attempt < RETRY_DELAYS.length - 1) {\n const delay = RETRY_DELAYS[attempt]!;\n process.stderr.write(`[memory] ${label}: SQLITE_BUSY, retrying in ${delay}ms\\n`);\n sleepSync(delay);\n continue;\n }\n throw err;\n }\n }\n // Unreachable, but TypeScript needs it\n throw new Error(`${label}: exhausted retries`);\n}\n\nfunction isSqliteBusy(err: unknown): boolean {\n if (err instanceof Error) {\n return err.message.includes('SQLITE_BUSY') || err.message.includes('database is locked');\n }\n return false;\n}\n\nfunction sleepSync(ms: number): void {\n Atomics.wait(new Int32Array(new SharedArrayBuffer(4)), 0, 0, ms);\n}\n","import { z } from 'zod';\nimport type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';\nimport type { ToolDeps } from './register.js';\nimport { RELATION_TYPES } from '../types.js';\nimport { memoryNotFound, formatMcpError } from '../utils/errors.js';\n\nconst inputSchema = {\n source_id: z.string().describe('ID of the source memory'),\n target_id: z.string().describe('ID of the target memory'),\n relation_type: z.enum(RELATION_TYPES).describe(\n 'Type of relation: relates_to, depends_on, contradicts, extends, implements, derived_from'\n ),\n};\n\nexport function registerRelate(server: McpServer, deps: ToolDeps): void {\n server.registerTool(\n 'memory_relate',\n {\n description:\n 'Create a typed relation between two memories. '\n + 'Relations affect retrieval ranking (connected memories decay slower). '\n + 'Types: relates_to, depends_on, contradicts, extends, implements, derived_from.',\n inputSchema,\n annotations: { idempotentHint: true },\n },\n async (args) => {\n if (args.source_id === args.target_id) {\n return formatMcpError({\n what: 'Cannot create self-relation.',\n why: 'source_id and target_id are the same memory.',\n fix: 'Provide two different memory IDs.',\n });\n }\n\n const source = deps.memoryRepo.getById(args.source_id);\n if (!source) {\n return formatMcpError(memoryNotFound(args.source_id));\n }\n\n const target = deps.memoryRepo.getById(args.target_id);\n if (!target) {\n return formatMcpError(memoryNotFound(args.target_id));\n }\n\n if (deps.project) {\n for (const mem of [source, target]) {\n if (mem.project !== null && mem.project !== deps.project) {\n return formatMcpError({\n what: `Memory ${mem.id} belongs to project \"${mem.project}\".`,\n why: `Current project is \"${deps.project}\". Cross-project relations are not allowed.`,\n fix: 'Both memories must belong to the same project.',\n });\n }\n }\n }\n\n const created = deps.relationRepo.create(args.source_id, args.target_id, args.relation_type);\n\n if (!created) {\n return {\n content: [{\n type: 'text' as const,\n text: `Relation already exists: ${args.source_id} --[${args.relation_type}]--> ${args.target_id}`,\n }],\n };\n }\n\n return {\n content: [{\n type: 'text' as const,\n text: `Created relation: \"${source.title ?? source.content.slice(0, 40)}\" --[${args.relation_type}]--> \"${target.title ?? target.content.slice(0, 40)}\"`,\n }],\n };\n },\n );\n}\n","import type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';\nimport type { ToolDeps } from './register.js';\nimport { MEMORY_TYPES } from '../types.js';\nimport type { MemoryStats } from '../types.js';\nimport { statSync } from 'node:fs';\nimport { join } from 'node:path';\n\nexport function registerStats(server: McpServer, deps: ToolDeps): void {\n server.registerTool(\n 'memory_stats',\n {\n description:\n 'Show memory dashboard: total count, breakdown by type, storage size, '\n + 'and most-injected memories. No arguments needed.',\n annotations: { readOnlyHint: true, idempotentHint: true },\n },\n async () => {\n const countByType = deps.memoryRepo.countByType();\n const total = deps.memoryRepo.count();\n const topInjected = deps.memoryRepo.topInjected(5);\n const totalRelations = deps.relationRepo.count();\n\n let dbSizeBytes = 0;\n try {\n const dbPath = join(deps.dataDir, 'memory.db');\n dbSizeBytes = statSync(dbPath).size;\n } catch {\n // :memory: or file not found\n }\n\n const { oldest, newest } = deps.memoryRepo.dateRange();\n\n const stats: MemoryStats = {\n totalMemories: total,\n byType: Object.fromEntries(\n MEMORY_TYPES.map(t => [t, countByType[t] ?? 0])\n ) as Record<string, number>,\n totalRelations,\n dbSizeBytes,\n oldestMemory: oldest,\n newestMemory: newest,\n topInjected,\n };\n\n return {\n content: [{\n type: 'text' as const,\n text: JSON.stringify(stats, null, 2),\n }],\n };\n },\n );\n}\n","import { z } from 'zod';\nimport type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';\nimport type { ToolDeps } from './register.js';\nimport { MEMORY_TYPES } from '../types.js';\n\nconst inputSchema = {\n limit: z.number().int().min(1).max(50).default(10).describe('Maximum memories to return'),\n type: z.enum(MEMORY_TYPES).optional().describe('Filter by memory type'),\n};\n\nexport function registerRecent(server: McpServer, deps: ToolDeps): void {\n server.registerTool(\n 'memory_recent',\n {\n description:\n 'Load session context: returns context-matched, recent, and related memories. '\n + 'Call this at the start of every session to load context from previous work. '\n + 'Results are grouped into sections: contextMatched (matching current branch/files), '\n + 'recent (most recent), and related (connected via relations).',\n inputSchema,\n annotations: { readOnlyHint: true, idempotentHint: true },\n },\n async (args) => {\n const results = deps.retrievalService.loadSessionContext({\n limit: args.limit,\n project: deps.project ?? undefined,\n type: args.type,\n });\n\n if (results.length === 0) {\n return {\n content: [{ type: 'text' as const, text: 'No memories found for this project.' }],\n };\n }\n\n const formatEntry = (entry: typeof results[number], rank: number) => ({\n rank,\n section: entry.section,\n id: entry.result.memory.id,\n type: entry.result.memory.type,\n title: entry.result.memory.title,\n content: entry.result.memory.content.slice(0, 500),\n importance: entry.result.memory.importance,\n tags: entry.result.memory.tags,\n score: Math.round(entry.result.score * 100) / 100,\n explanation: entry.result.explanation,\n createdAt: entry.result.memory.createdAt,\n });\n\n const contextMatched = results.filter(r => r.section === 'context').map((r, i) => formatEntry(r, i + 1));\n const recent = results.filter(r => r.section === 'recent').map((r, i) => formatEntry(r, i + 1));\n const related = results.filter(r => r.section === 'related').map((r, i) => formatEntry(r, i + 1));\n\n return {\n content: [{\n type: 'text' as const,\n text: JSON.stringify({ contextMatched, recent, related }, null, 2),\n }],\n };\n },\n );\n}\n","import { z } from 'zod';\nimport type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';\nimport type { ToolDeps } from './register.js';\n\nconst inputSchema = {\n id: z.string().describe('Memory ID to update (use memory_search to find it)'),\n title: z.string().max(200).optional().describe('Updated title'),\n content: z.string().min(1).max(10000).optional().describe('Updated content'),\n tags: z.array(z.string()).max(20).optional().describe('Updated tags'),\n importance: z.number().min(0).max(1).optional().describe('Updated importance (0-1)'),\n context: z.string().optional().describe('Updated context JSON'),\n};\n\nexport function registerUpdate(server: McpServer, deps: ToolDeps): void {\n server.registerTool(\n 'memory_update',\n {\n description:\n 'Update an existing memory in-place. Preserves access count, injection count, and creation date. '\n + 'Use memory_search to find the ID first. At least one field must be provided.',\n inputSchema,\n annotations: { readOnlyHint: false, destructiveHint: false, idempotentHint: true },\n },\n async (args) => {\n const hasUpdate = args.title !== undefined || args.content !== undefined\n || args.tags !== undefined || args.importance !== undefined\n || args.context !== undefined;\n\n if (!hasUpdate) {\n return {\n content: [{ type: 'text' as const, text: 'No fields to update. Provide at least one of: title, content, tags, importance, context.' }],\n isError: true,\n };\n }\n\n const existing = deps.memoryRepo.getById(args.id);\n if (!existing) {\n return {\n content: [{ type: 'text' as const, text: `Memory ${args.id} not found.` }],\n isError: true,\n };\n }\n\n const updated = deps.memoryRepo.updateContent(args.id, {\n title: args.title,\n content: args.content,\n tags: args.tags,\n importance: args.importance,\n context: args.context,\n });\n\n if (!updated) {\n return {\n content: [{ type: 'text' as const, text: `Failed to update memory ${args.id}.` }],\n isError: true,\n };\n }\n\n const fields = [\n args.title !== undefined && 'title',\n args.content !== undefined && 'content',\n args.tags !== undefined && 'tags',\n args.importance !== undefined && 'importance',\n args.context !== undefined && 'context',\n ].filter(Boolean).join(', ');\n\n return {\n content: [{ type: 'text' as const, text: `Updated memory ${args.id} (fields: ${fields})` }],\n };\n },\n );\n}\n","import type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';\nimport type { MemoryRepo } from '../storage/memory-repo.js';\nimport type { RelationRepo } from '../storage/relation-repo.js';\nimport type { RetrievalService } from '../services/retrieval-service.js';\nimport { registerStore } from './store.js';\nimport { registerSearch } from './search.js';\nimport { registerForget } from './forget.js';\nimport { registerRelate } from './relate.js';\nimport { registerStats } from './stats.js';\nimport { registerRecent } from './recent.js';\nimport { registerUpdate } from './update.js';\n\nexport interface ToolDeps {\n readonly memoryRepo: MemoryRepo;\n readonly relationRepo: RelationRepo;\n readonly retrievalService: RetrievalService;\n readonly dataDir: string;\n readonly project: string | null;\n}\n\nexport function registerTools(server: McpServer, deps: ToolDeps): void {\n registerStore(server, deps);\n registerSearch(server, deps);\n registerRecent(server, deps);\n registerForget(server, deps);\n registerRelate(server, deps);\n registerStats(server, deps);\n registerUpdate(server, deps);\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,SAAS,iBAAiB;AAC1B,SAAS,4BAA4B;;;ACMrC,IAAM,uBAAuB;AAAA,EAC3B,SAAS;AAAA,EACT,UAAU;AAAA,EACV,SAAS;AAAA,EACT,UAAU;AAAA,EACV,YAAY;AACd;AASO,IAAM,mBAAN,MAAuB;AAAA,EACnB;AAAA,EACA;AAAA,EAET,YAAY,MAAqB;AAC/B,SAAK,QAAQ;AACb,SAAK,cAAc,KAAK,cAAc,cAAc;AAAA,EACtD;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,MAAM,OAAO,OAAsD;AAEjE,QAAI,MAAM,IAAI;AACZ,YAAM,SAAS,KAAK,MAAM,WAAW,QAAQ,MAAM,EAAE;AACrD,UAAI,CAAC,OAAQ,QAAO,CAAC;AACrB,WAAK,MAAM,WAAW,gBAAgB,MAAM,EAAE;AAC9C,aAAO,CAAC;AAAA,QACN;AAAA,QACA,OAAO;AAAA,QACP,aAAa;AAAA,MACf,CAAC;AAAA,IACH;AAGA,UAAM,aAAa,KAAK,MAAM,WAAW,UAAU;AAAA,MACjD,OAAO,MAAM;AAAA,MACb,OAAO,MAAM,QAAQ;AAAA,MACrB,MAAM,MAAM;AAAA,MACZ,eAAe,MAAM;AAAA,MACrB,SAAS,MAAM;AAAA,IACjB,CAAC;AAED,UAAM,aAAa,cAAc,UAAU;AAC3C,QAAI,WAAW,SAAS,EAAG,QAAO,CAAC;AAGnC,UAAM,aAAyE,CAAC;AAEhF,eAAW,CAAC,UAAU,SAAS,KAAK,YAAY;AAC9C,YAAM,SAAS,KAAK,MAAM,WAAW,QAAQ,QAAQ;AACrD,UAAI,CAAC,OAAQ;AACb,UAAI,MAAM,QAAQ,OAAO,SAAS,MAAM,KAAM;AAC9C,UAAI,OAAO,aAAa,MAAM,eAAgB;AAC9C,UAAI,MAAM,MAAM,QAAQ;AACtB,cAAM,UAAU,IAAI,IAAI,OAAO,IAAI;AACnC,YAAI,CAAC,MAAM,KAAK,MAAM,OAAK,QAAQ,IAAI,CAAC,CAAC,EAAG;AAAA,MAC9C;AAEA,YAAM,QAAQ,kBAAkB,QAAQ,WAAW,KAAK,aAAa,MAAM,KAAK;AAChF,YAAM,YAAY,iBAAiB,KAAK;AACxC,iBAAW,KAAK,EAAE,QAAQ,WAAW,MAAM,CAAC;AAAA,IAC9C;AAGA,eAAW,KAAK,CAAC,GAAG,MAAM,EAAE,YAAY,EAAE,SAAS;AACnD,QAAI,OAAO,WAAW,MAAM,GAAG,MAAM,KAAK;AAG1C,UAAM,UAAU,IAAI,IAAI,KAAK,IAAI,OAAK,EAAE,OAAO,EAAE,CAAC;AAClD,UAAM,WAAW,KAAK,qBAAqB,MAAM,MAAM,OAAO,SAAS,MAAM,cAAc;AAC3F,QAAI,SAAS,SAAS,GAAG;AACvB,aAAO,CAAC,GAAG,MAAM,GAAG,QAAQ,EAAE,KAAK,CAAC,GAAG,MAAM,EAAE,YAAY,EAAE,SAAS,EAAE,MAAM,GAAG,MAAM,KAAK;AAAA,IAC9F;AAGA,WAAO,KAAK,IAAI,CAAC,EAAE,QAAQ,WAAW,MAAM,MAAM;AAChD,WAAK,MAAM,WAAW,gBAAgB,OAAO,EAAE;AAC/C,aAAO;AAAA,QACL;AAAA,QACA,OAAO;AAAA,QACP,aAAa,MAAM,iBACf,YAAY,MAAM,eAAe,IAAI,SAAS,MAAM,eAAe,SAAS,MAAM,eAAe,EAAE,KACnG,iBAAiB,OAAO,MAAM;AAAA,MACpC;AAAA,IACF,CAAC;AAAA,EACH;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,mBAAmB,OAIiB;AAClC,UAAM,gBAAgB,KAAK,MAAM,MAAM,QAAQ,GAAG;AAClD,UAAM,eAAe,KAAK,MAAM,MAAM,QAAQ,GAAG;AACjD,UAAM,gBAAgB,MAAM,QAAQ,gBAAgB;AACpD,UAAM,UAAU,oBAAI,IAAY;AAEhC,UAAM,iBAAiB,KAAK,oBAAoB,eAAe,MAAM,SAAS,MAAM,MAAM,OAAO;AACjG,UAAM,SAAS,KAAK,YAAY,cAAc,MAAM,SAAS,MAAM,MAAM,OAAO;AAEhF,UAAM,YAAY,CAAC,GAAG,gBAAgB,GAAG,MAAM,EAAE,IAAI,OAAK,EAAE,OAAO,OAAO,EAAE;AAC5E,UAAM,UAAU,KAAK,sBAAsB,WAAW,eAAe,OAAO;AAE5E,UAAM,MAAM,CAAC,GAAG,gBAAgB,GAAG,QAAQ,GAAG,OAAO;AACrD,eAAW,SAAS,KAAK;AACvB,WAAK,MAAM,WAAW,mBAAmB,MAAM,OAAO,OAAO,EAAE;AAAA,IACjE;AACA,WAAO;AAAA,EACT;AAAA,EAEA,oBACE,QAAgB,SAAkB,MAAmB,SAC7B;AACxB,QAAI,UAAU,EAAG,QAAO,CAAC;AACzB,UAAM,aAAa,KAAK,MAAM,WAAW,UAAU,SAAS,GAAG,SAAS,IAAI;AAC5E,UAAM,SAAoE,CAAC;AAE3E,eAAW,KAAK,YAAY;AAC1B,YAAM,WAAW,oBAAoB,EAAE,SAAS,KAAK,aAAa,EAAE;AACpE,UAAI,YAAY,IAAK;AACrB,YAAM,YAAY,WAAW,MAAM,EAAE,aAAa,MAAM,oBAAoB,EAAE,SAAS,IAAI;AAC3F,aAAO,KAAK,EAAE,QAAQ,GAAG,UAAU,UAAU,CAAC;AAAA,IAChD;AAEA,WAAO,KAAK,CAAC,GAAG,MAAM,EAAE,YAAY,EAAE,SAAS;AAC/C,UAAM,UAAkC,CAAC;AACzC,eAAW,KAAK,OAAO,MAAM,GAAG,MAAM,GAAG;AACvC,eAAS,IAAI,EAAE,OAAO,EAAE;AACxB,cAAQ,KAAK,EAAE,SAAS,WAAW,QAAQ,EAAE,QAAQ,EAAE,QAAQ,OAAO,EAAE,WAAW,aAAa,gBAAgB,EAAE,CAAC;AAAA,IACrH;AACA,WAAO;AAAA,EACT;AAAA,EAEA,YACE,QAAgB,SAAkB,MAAmB,SAC7B;AACxB,QAAI,UAAU,EAAG,QAAO,CAAC;AACzB,UAAM,aAAa,KAAK,MAAM,WAAW,UAAU,SAAS,GAAG,SAAS,IAAI;AAC5E,UAAM,UAAkC,CAAC;AAEzC,eAAW,KAAK,YAAY;AAC1B,UAAI,SAAS,IAAI,EAAE,EAAE,EAAG;AACxB,YAAM,QAAQ,EAAE,aAAa,MAAM,oBAAoB,EAAE,SAAS,IAAI;AACtE,eAAS,IAAI,EAAE,EAAE;AACjB,cAAQ,KAAK,EAAE,SAAS,UAAU,QAAQ,EAAE,QAAQ,GAAG,OAAO,aAAa,SAAS,EAAE,CAAC;AACvF,UAAI,QAAQ,UAAU,OAAQ;AAAA,IAChC;AACA,WAAO;AAAA,EACT;AAAA,EAEA,sBACE,WAA8B,QAAgB,SACtB;AACxB,QAAI,UAAU,EAAG,QAAO,CAAC;AACzB,UAAM,UAAkC,CAAC;AAEzC,eAAW,SAAS,WAAW;AAC7B,YAAM,YAAY,KAAK,MAAM,aAAa,YAAY,KAAK;AAC3D,iBAAW,OAAO,WAAW;AAC3B,cAAM,UAAU,IAAI,aAAa,QAAQ,IAAI,WAAW,IAAI;AAC5D,YAAI,YAAY,SAAS,QAAQ,IAAI,OAAO,EAAG;AAE/C,cAAM,QAAQ,KAAK,MAAM,WAAW,QAAQ,OAAO;AACnD,YAAI,CAAC,MAAO;AAEZ,cAAM,MAAM,KAAK,MAAM,WAAW,QAAQ,KAAK;AAC/C,cAAM,SAAS,sBAAsB,IAAI,YAAY,KAAK;AAC1D,gBAAQ,IAAI,OAAO;AACnB,gBAAQ,KAAK;AAAA,UACX,SAAS;AAAA,UACT,QAAQ;AAAA,YACN,QAAQ;AAAA,YACR,OAAO,MAAM,aAAa;AAAA,YAC1B,aAAa,YAAY,IAAI,YAAY,SAAS,KAAK,SAAS,KAAK;AAAA,UACvE;AAAA,QACF,CAAC;AACD,YAAI,QAAQ,UAAU,OAAQ,QAAO;AAAA,MACvC;AAAA,IACF;AACA,WAAO;AAAA,EACT;AAAA,EAEA,qBACE,YACA,OACA,SACA,eAC4D;AAC5D,QAAI,WAAW,UAAU,MAAO,QAAO,CAAC;AAExC,UAAM,WAAuE,CAAC;AAC9E,UAAM,YAAY,QAAQ,WAAW;AACrC,UAAM,kBAAkB,WAAW,MAAM,GAAG,CAAC;AAE7C,eAAW,UAAU,iBAAiB;AACpC,YAAM,YAAY,KAAK,MAAM,aAAa,YAAY,OAAO,OAAO,EAAE;AACtE,iBAAW,OAAO,WAAW;AAC3B,cAAM,UAAU,IAAI,aAAa,OAAO,OAAO,KAAK,IAAI,WAAW,IAAI;AACvE,YAAI,YAAY,OAAO,OAAO,MAAM,QAAQ,IAAI,OAAO,EAAG;AAE1D,cAAM,QAAQ,KAAK,MAAM,WAAW,QAAQ,OAAO;AACnD,YAAI,CAAC,SAAS,MAAM,aAAa,cAAe;AAEhD,cAAM,SAAS,sBAAsB,IAAI,YAAY,KAAK;AAC1D,cAAM,YAAY,OAAO,YAAY,MAAM;AAC3C,cAAM,QAAoB;AAAA,UACxB,WAAW;AAAA,UACX,iBAAiB,MAAM;AAAA,UACvB,cAAc,oBAAoB,MAAM,SAAS;AAAA,UACjD,aAAa,mBAAmB,MAAM,aAAa,MAAM,YAAY;AAAA,UACrE,cAAc;AAAA,UACd,gBAAgB,EAAE,IAAI,OAAO,OAAO,IAAI,OAAO,OAAO,OAAO,OAAO,MAAM,IAAI,aAAa;AAAA,QAC7F;AAEA,gBAAQ,IAAI,OAAO;AACnB,iBAAS,KAAK,EAAE,QAAQ,OAAO,WAAW,MAAM,CAAC;AACjD,YAAI,SAAS,UAAU,UAAW,QAAO;AAAA,MAC3C;AAAA,IACF;AAEA,WAAO;AAAA,EACT;AACF;AAIA,IAAM,wBAAsD;AAAA,EAC1D,YAAY;AAAA,EACZ,SAAS;AAAA,EACT,YAAY;AAAA,EACZ,YAAY;AAAA,EACZ,cAAc;AAAA,EACd,aAAa;AACf;AAIA,SAAS,cAAc,YAAgF;AACrG,QAAM,SAAS,oBAAI,IAAoB;AACvC,aAAW,KAAK,YAAY;AAC1B,UAAM,QAAQ,KAAK,IAAI,GAAG,CAAC,EAAE,OAAO,EAAE;AACtC,WAAO,IAAI,EAAE,UAAU,KAAK;AAAA,EAC9B;AACA,SAAO;AACT;AAaA,SAAS,kBACP,QACA,WACA,YACA,OACY;AACZ,SAAO;AAAA,IACL;AAAA,IACA,iBAAiB,OAAO;AAAA,IACxB,cAAc,oBAAoB,OAAO,SAAS;AAAA,IAClD,aAAa,mBAAmB,OAAO,aAAa,OAAO,YAAY;AAAA,IACvE,cAAc,oBAAoB,OAAO,SAAS,YAAY,KAAK;AAAA,EACrE;AACF;AAEA,SAAS,iBAAiB,OAA2B;AACnD,SACE,MAAM,YAAY,gBAAgB,OAClC,MAAM,kBAAkB,gBAAgB,aACxC,MAAM,eAAe,gBAAgB,UACrC,MAAM,cAAc,gBAAgB,SACpC,MAAM,eAAe,gBAAgB;AAEzC;AAMA,SAAS,oBAAoB,WAA2B;AACtD,QAAM,QAAQ,KAAK,IAAI,IAAI,IAAI,KAAK,SAAS,EAAE,QAAQ;AACvD,QAAM,UAAU,SAAS,MAAO,KAAK,KAAK;AAC1C,MAAI,UAAU,EAAG,QAAO;AACxB,SAAO,KAAK,IAAI,CAAC,UAAU,KAAK,MAAM,EAAE;AAC1C;AAKA,SAAS,mBAAmB,aAAqB,cAAqC;AACpF,MAAI,eAAe,EAAG,QAAO;AAC7B,QAAM,aAAa,KAAK,IAAI,GAAK,KAAK,MAAM,cAAc,CAAC,IAAI,KAAK,MAAM,EAAE,CAAC;AAC7E,MAAI,CAAC,aAAc,QAAO,aAAa;AACvC,QAAM,WAAW,KAAK,IAAI,IAAI,IAAI,KAAK,YAAY,EAAE,QAAQ,KAAK;AAClE,QAAM,UAAU,KAAK,IAAI,CAAC,UAAU,KAAK,MAAM,EAAE;AACjD,SAAO,cAAc,MAAM,MAAM;AACnC;AAIA,SAAS,iBAAiB,OAAmB,QAAwB;AACnE,QAAM,UAAoB,CAAC;AAE3B,MAAI,MAAM,YAAY,KAAK;AACzB,YAAQ,KAAK,qBAAqB,MAAM,YAAY,KAAK,QAAQ,CAAC,CAAC,IAAI;AAAA,EACzE,WAAW,MAAM,YAAY,KAAK;AAChC,YAAQ,KAAK,yBAAyB,MAAM,YAAY,KAAK,QAAQ,CAAC,CAAC,IAAI;AAAA,EAC7E;AAEA,MAAI,OAAO,aAAa,KAAK;AAC3B,YAAQ,KAAK,iBAAiB;AAAA,EAChC;AAEA,MAAI,MAAM,eAAe,KAAK;AAC5B,YAAQ,KAAK,aAAa;AAAA,EAC5B,WAAW,MAAM,eAAe,KAAK;AACnC,YAAQ,KAAK,QAAQ;AAAA,EACvB;AAEA,MAAI,OAAO,cAAc,IAAI;AAC3B,YAAQ,KAAK,wBAAwB,OAAO,WAAW,IAAI;AAAA,EAC7D,WAAW,OAAO,cAAc,GAAG;AACjC,YAAQ,KAAK,YAAY,OAAO,WAAW,GAAG;AAAA,EAChD;AAEA,MAAI,MAAM,eAAe,KAAK;AAC5B,YAAQ,KAAK,eAAe;AAAA,EAC9B;AAEA,QAAM,UAAU,KAAK,OAAO,KAAK,IAAI,IAAI,IAAI,KAAK,OAAO,SAAS,EAAE,QAAQ,KAAK,KAAU;AAC3F,QAAM,qBAAqB,qBAAqB,OAAO,IAAI;AAC3D,MAAI,uBAAuB,UAAa,UAAU,oBAAoB;AACpE,YAAQ,KAAK,GAAG,OAAO,8BAA8B;AAAA,EACvD;AAEA,SAAO,QAAQ,SAAS,IAAI,QAAQ,KAAK,KAAK,IAAI;AACpD;;;AC1WA,SAAS,SAAS;AAClB,SAAS,kBAAkB;;;ACO3B,IAAM,oBAAoB;AAC1B,IAAM,oBAAoB;AAC1B,IAAM,uBAAuB;AAMtB,SAAS,sBAAsB,SAAmC;AACvE,QAAM,WAAqB,CAAC;AAG5B,MAAI,SAAS,OAAO,GAAG;AACrB,WAAO,EAAE,OAAO,OAAO,QAAQ,gGAA4F,UAAU,CAAC,EAAE;AAAA,EAC1I;AAGA,MAAI,YAAY,OAAO,GAAG;AACxB,WAAO,EAAE,OAAO,OAAO,QAAQ,0GAA0G,UAAU,CAAC,EAAE;AAAA,EACxJ;AAGA,MAAI,QAAQ,SAAS,mBAAmB;AACtC,WAAO,EAAE,OAAO,OAAO,QAAQ,cAAc,QAAQ,MAAM,kBAAkB,iBAAiB,8CAA8C,UAAU,CAAC,EAAE;AAAA,EAC3J;AAGA,MAAI,QAAQ,SAAS,mBAAmB;AACtC,aAAS,KAAK,cAAc,QAAQ,MAAM,8BAA8B,iBAAiB,0DAA0D;AAAA,EACrJ;AAEA,SAAO,EAAE,OAAO,MAAM,SAAS;AACjC;AAKO,SAAS,YAAY,SAA0B;AACpD,QAAM,qBAAqB;AAC3B,MAAI,YAAY;AAChB,MAAI;AAEJ,UAAQ,QAAQ,mBAAmB,KAAK,OAAO,OAAO,MAAM;AAC1D,iBAAa,MAAM,CAAC,EAAE;AAAA,EACxB;AAEA,SAAO,QAAQ,SAAS,KAAK,YAAY,QAAQ,SAAS;AAC5D;AAMO,SAAS,SAAS,SAA0B;AACjD,QAAM,QAAQ,QAAQ,MAAM,IAAI;AAChC,MAAI,cAAc;AAElB,aAAW,QAAQ,OAAO;AACxB,UAAM,UAAU,KAAK,KAAK;AAC1B,QAAI,6BAA6B,KAAK,OAAO,EAAG;AAAA,aACvC,iBAAiB,KAAK,OAAO,EAAG;AAAA,aAChC,eAAe,KAAK,OAAO,EAAG;AAAA,aAC9B,yBAAyB,KAAK,OAAO,KAAK,QAAQ,SAAS,IAAK;AAAA,EAC3E;AAGA,QAAM,gBAAgB,MAAM,OAAO,OAAK,EAAE,KAAK,EAAE,SAAS,CAAC,EAAE;AAC7D,SAAO,eAAe,KAAK,gBAAgB,KAAK,cAAc,gBAAgB;AAChF;;;AC1EA,IAAM,oBAAoB;AAAA,EACxB;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;AAEA,IAAM,4BAA4B;AAClC,IAAM,qBAAqB;AAC3B,IAAM,aAAa,oBAAI,IAAI;AAAA,EACzB;AAAA,EAAO;AAAA,EAAO;AAAA,EAAO;AAAA,EAAO;AAAA,EAAO;AAAA,EAAO;AAAA,EAAO;AAAA,EAAO;AAAA,EAAO;AAAA,EAC/D;AAAA,EAAO;AAAA,EAAO;AAAA,EAAO;AAAA,EAAO;AAAA,EAAO;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAQ;AAAA,EAAQ;AAAA,EAClE;AAAA,EAAQ;AAAA,EAAQ;AAAA,EAAQ;AAAA,EAAQ;AAAA,EAAQ;AAAA,EAAQ;AAAA,EAAQ;AAAA,EAAQ;AAAA,EAChE;AAAA,EAAQ;AAAA,EAAQ;AAAA,EAAQ;AAAA,EAAQ;AAAA,EAAQ;AAAA,EAAQ;AAAA,EAAQ;AAAA,EAAQ;AAAA,EAChE;AAAA,EAAQ;AAAA,EAAS;AAAA,EAAU;AAAA,EAAS;AAAA,EAAS;AAAA,EAAS;AAAA,EAAS;AAAA,EAC/D;AAAA,EAAS;AAAA,EAAS;AAAA,EAAS;AAAA,EAAQ;AAAA,EAAQ;AAAA,EAAQ;AACrD,CAAC;AAKD,SAAS,gBAAgB,MAAmC;AAC1D,QAAM,QAAQ,KAAK,YAAY,EAAE,MAAM,mBAAmB,KAAK,CAAC;AAChE,SAAO,IAAI;AAAA,IACT,MAAM,OAAO,OAAK,EAAE,UAAU,sBAAsB,CAAC,WAAW,IAAI,CAAC,CAAC;AAAA,EACxE;AACF;AAQO,SAAS,mBAAmB,YAAoB,iBAAkC;AACvF,QAAM,cAAc,gBAAgB,UAAU;AAC9C,QAAM,mBAAmB,gBAAgB,eAAe;AAExD,MAAI,YAAY,SAAS,KAAK,iBAAiB,SAAS,EAAG,QAAO;AAGlE,MAAI,UAAU;AACd,aAAW,MAAM,aAAa;AAC5B,QAAI,iBAAiB,IAAI,EAAE,EAAG;AAAA,EAChC;AAEA,QAAM,cAAc,KAAK,IAAI,YAAY,MAAM,iBAAiB,IAAI;AACpE,QAAM,eAAe,UAAU;AAE/B,MAAI,eAAe,0BAA2B,QAAO;AAGrD,SAAO,kBAAkB,KAAK,aAAW,QAAQ,KAAK,UAAU,CAAC;AACnE;;;AFvDA,IAAM,eAAe,oBAAI,IAAoB;AAC7C,IAAM,kBAAkB;AAExB,IAAM,cAAc;AAAA,EAClB,MAAM,EAAE,KAAK,YAAY,EAAE,SAAS,kEAAkE;AAAA,EACtG,SAAS,EAAE,OAAO,EAAE,IAAI,CAAC,EAAE,IAAI,GAAK,EAAE,SAAS,6BAA6B;AAAA,EAC5E,OAAO,EAAE,OAAO,EAAE,IAAI,GAAG,EAAE,SAAS,EAAE,SAAS,4BAA4B;AAAA,EAC3E,MAAM,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,IAAI,EAAE,EAAE,QAAQ,CAAC,CAAC,EAAE,SAAS,gFAAgF;AAAA,EACvI,YAAY,EAAE,OAAO,EAAE,IAAI,CAAC,EAAE,IAAI,CAAC,EAAE,QAAQ,GAAG,EAAE,SAAS,yEAAyE;AAAA,EACpI,SAAS,EAAE,OAAO,EAAE,SAAS,EAAE,SAAS,8FAA8F;AAAA,EACtI,QAAQ,EAAE,KAAK,cAAc,EAAE,QAAQ,QAAQ,EAAE,SAAS,6BAA6B;AAAA,EACvF,SAAS,EAAE,OAAO,EAAE,IAAI,GAAG,EAAE,SAAS,EAAE,SAAS,mDAAmD;AACtG;AAEO,SAAS,cAAc,QAAmB,MAAsB;AACrE,SAAO;AAAA,IACL;AAAA,IACA;AAAA,MACE,aACE;AAAA,MAMF;AAAA,MACA,aAAa,EAAE,gBAAgB,MAAM;AAAA,IACvC;AAAA,IACA,OAAO,SAAS;AACd,YAAM,aAAa,sBAAsB,KAAK,OAAO;AACrD,UAAI,CAAC,WAAW,OAAO;AACrB,eAAO;AAAA,UACL,SAAS,CAAC;AAAA,YACR,MAAM;AAAA,YACN,MAAM,aAAa,WAAW,MAAM;AAAA,UACtC,CAAC;AAAA,UACD,SAAS;AAAA,QACX;AAAA,MACF;AAEA,YAAM,UAAU,KAAK,WAAW,KAAK,UAAU,cAAc,CAAC;AAC9D,YAAM,UAAU,KAAK,WAAW,KAAK,WAAW;AAGhD,YAAM,cAAc,WAAW,QAAQ,EAAE,OAAO,KAAK,OAAO,EAAE,OAAO,KAAK;AAC1E,YAAM,MAAM,KAAK,IAAI;AACrB,YAAM,aAAa,aAAa,IAAI,WAAW;AAC/C,UAAI,cAAe,MAAM,aAAc,iBAAiB;AACtD,eAAO;AAAA,UACL,SAAS,CAAC,EAAE,MAAM,QAAiB,MAAM,wDAAwD,CAAC;AAAA,QACpG;AAAA,MACF;AACA,mBAAa,IAAI,aAAa,GAAG;AAEjC,iBAAW,CAAC,KAAK,EAAE,KAAK,cAAc;AACpC,YAAI,MAAM,KAAK,gBAAiB,cAAa,OAAO,GAAG;AAAA,MACzD;AAGA,YAAM,iBAAyD,CAAC;AAChE,UAAI;AACF,cAAM,WAAW,MAAM,KAAK,iBAAiB,OAAO;AAAA,UAClD,OAAO,KAAK,QAAQ,MAAM,GAAG,GAAG;AAAA,UAChC,OAAO;AAAA,UACP,gBAAgB;AAAA,UAChB;AAAA,QACF,CAAC;AACD,mBAAW,UAAU,UAAU;AAC7B,cAAI,OAAO,QAAQ,OAAO,mBAAmB,KAAK,SAAS,OAAO,OAAO,OAAO,GAAG;AACjF,2BAAe,KAAK,EAAE,IAAI,OAAO,OAAO,IAAI,OAAO,OAAO,OAAO,MAAM,CAAC;AAAA,UAC1E;AAAA,QACF;AAAA,MACF,QAAQ;AAAA,MAER;AAEA,YAAM,SAAS,KAAK,WAAW;AAAA,QAC7B;AAAA,UACE,MAAM,KAAK;AAAA,UACX,SAAS,KAAK;AAAA,UACd,OAAO,KAAK;AAAA,UACZ,MAAM,KAAK;AAAA,UACX,YAAY,KAAK;AAAA,UACjB;AAAA,UACA,QAAQ,KAAK;AAAA,UACb;AAAA,QACF;AAAA,QACA;AAAA,MACF;AAGA,iBAAW,KAAK,gBAAgB;AAC9B,YAAI;AACF,eAAK,aAAa,OAAO,OAAO,IAAI,EAAE,IAAI,aAAa;AAAA,QACzD,QAAQ;AAAA,QAER;AAAA,MACF;AAEA,YAAM,QAAkB;AAAA,QACtB,iBAAiB,OAAO,EAAE,WAAW,OAAO,IAAI,iBAAiB,OAAO,UAAU;AAAA,MACpF;AAEA,iBAAW,WAAW,WAAW,UAAU;AACzC,cAAM,KAAK,YAAY,OAAO,EAAE;AAAA,MAClC;AAEA,iBAAW,KAAK,gBAAgB;AAC9B,cAAM,KAAK,gDAAgD,EAAE,EAAE,GAAG,EAAE,QAAQ,MAAM,EAAE,KAAK,OAAO,EAAE,uCAAuC;AAAA,MAC3I;AAEA,aAAO;AAAA,QACL,SAAS,CAAC;AAAA,UACR,MAAM;AAAA,UACN,MAAM,MAAM,KAAK,IAAI;AAAA,QACvB,CAAC;AAAA,MACH;AAAA,IACF;AAAA,EACF;AACF;;;AGjIA,SAAS,KAAAA,UAAS;AAKlB,IAAMC,eAAc;AAAA,EAClB,OAAOC,GAAE,OAAO,EAAE,IAAI,CAAC,EAAE,IAAI,GAAG,EAAE,SAAS,6CAA6C;AAAA,EACxF,IAAIA,GAAE,OAAO,EAAE,SAAS,EAAE,SAAS,8CAA8C;AAAA,EACjF,MAAMA,GAAE,KAAK,YAAY,EAAE,SAAS,EAAE,SAAS,uBAAuB;AAAA,EACtE,MAAMA,GAAE,MAAMA,GAAE,OAAO,CAAC,EAAE,IAAI,EAAE,EAAE,SAAS,EAAE,SAAS,iDAAiD;AAAA,EACvG,OAAOA,GAAE,OAAO,EAAE,IAAI,EAAE,IAAI,CAAC,EAAE,IAAI,EAAE,EAAE,QAAQ,EAAE,EAAE,SAAS,2BAA2B;AAAA,EACvF,gBAAgBA,GAAE,OAAO,EAAE,IAAI,CAAC,EAAE,IAAI,CAAC,EAAE,QAAQ,CAAC,EAAE,SAAS,8BAA8B;AAC7F;AAEO,SAAS,eAAe,QAAmB,MAAsB;AACtE,SAAO;AAAA,IACL;AAAA,IACA;AAAA,MACE,aACE;AAAA,MAIF,aAAAD;AAAA,MACA,aAAa,EAAE,cAAc,MAAM,gBAAgB,KAAK;AAAA,IAC1D;AAAA,IACA,OAAO,SAAS;AACd,YAAM,UAAU,MAAM,KAAK,iBAAiB,OAAO;AAAA,QACjD,OAAO,KAAK;AAAA,QACZ,IAAI,KAAK;AAAA,QACT,MAAM,KAAK;AAAA,QACX,MAAM,KAAK;AAAA,QACX,OAAO,KAAK;AAAA,QACZ,gBAAgB,KAAK;AAAA,QACrB,SAAS,KAAK,WAAW;AAAA,MAC3B,CAAC;AAED,UAAI,QAAQ,WAAW,GAAG;AACxB,eAAO;AAAA,UACL,SAAS,CAAC,EAAE,MAAM,QAAiB,MAAM,yCAAyC,CAAC;AAAA,QACrF;AAAA,MACF;AAEA,YAAM,YAAY,QAAQ,IAAI,CAAC,GAAG,OAAO;AAAA,QACvC,MAAM,IAAI;AAAA,QACV,IAAI,EAAE,OAAO;AAAA,QACb,MAAM,EAAE,OAAO;AAAA,QACf,OAAO,EAAE,OAAO;AAAA,QAChB,SAAS,EAAE,OAAO,QAAQ,MAAM,GAAG,GAAG;AAAA,QACtC,OAAO,KAAK,MAAM,EAAE,QAAQ,GAAG,IAAI;AAAA,QACnC,aAAa,EAAE;AAAA,QACf,YAAY,EAAE,OAAO;AAAA,QACrB,MAAM,EAAE,OAAO;AAAA,QACf,aAAa,EAAE,OAAO;AAAA,QACtB,WAAW,EAAE,OAAO;AAAA,MACtB,EAAE;AAEF,aAAO;AAAA,QACL,SAAS,CAAC;AAAA,UACR,MAAM;AAAA,UACN,MAAM,KAAK,UAAU,WAAW,MAAM,CAAC;AAAA,QACzC,CAAC;AAAA,MACH;AAAA,IACF;AAAA,EACF;AACF;;;ACjEA,SAAS,KAAAE,UAAS;;;ACSX,SAAS,YAAY,KAA8B;AACxD,SAAO,GAAG,IAAI,IAAI;AAAA,OAAU,IAAI,GAAG;AAAA,OAAU,IAAI,GAAG;AACtD;AAEO,SAAS,eAAe,KAAoF;AACjH,SAAO;AAAA,IACL,SAAS;AAAA,IACT,SAAS,CAAC,EAAE,MAAM,QAAiB,MAAM,YAAY,GAAG,EAAE,CAAC;AAAA,EAC7D;AACF;AAIO,SAAS,eAAe,IAA6B;AAC1D,SAAO;AAAA,IACL,MAAM,WAAW,EAAE;AAAA,IACnB,KAAK;AAAA,IACL,KAAK;AAAA,EACP;AACF;;;ADvBA,IAAMC,eAAc;AAAA,EAClB,IAAIC,GAAE,OAAO,EAAE,SAAS,4BAA4B;AAAA,EACpD,aAAaA,GAAE,QAAQ,EAAE,QAAQ,KAAK,EAAE,SAAS,oEAAoE;AACvH;AAEO,SAAS,eAAe,QAAmB,MAAsB;AACtE,SAAO;AAAA,IACL;AAAA,IACA;AAAA,MACE,aACE;AAAA,MAEF,aAAAD;AAAA,MACA,aAAa,EAAE,iBAAiB,MAAM,gBAAgB,KAAK;AAAA,IAC7D;AAAA,IACA,OAAO,SAAS;AACd,YAAM,SAAS,KAAK,WAAW,QAAQ,KAAK,EAAE;AAC9C,UAAI,CAAC,QAAQ;AACX,eAAO,eAAe,eAAe,KAAK,EAAE,CAAC;AAAA,MAC/C;AAEA,UAAI,KAAK,WAAW,OAAO,YAAY,QAAQ,OAAO,YAAY,KAAK,SAAS;AAC9E,eAAO,eAAe;AAAA,UACpB,MAAM,UAAU,KAAK,EAAE,wBAAwB,OAAO,OAAO;AAAA,UAC7D,KAAK,uBAAuB,KAAK,OAAO;AAAA,UACxC,KAAK;AAAA,QACP,CAAC;AAAA,MACH;AAEA,UAAI,KAAK,aAAa;AACpB,aAAK,WAAW,WAAW,KAAK,EAAE;AAClC,eAAO;AAAA,UACL,SAAS,CAAC;AAAA,YACR,MAAM;AAAA,YACN,MAAM,8BAA8B,KAAK,EAAE,MAAM,OAAO,SAAS,OAAO,QAAQ,MAAM,GAAG,EAAE,CAAC;AAAA,UAC9F,CAAC;AAAA,QACH;AAAA,MACF;AAEA,WAAK,WAAW,WAAW,KAAK,EAAE;AAClC,aAAO;AAAA,QACL,SAAS,CAAC;AAAA,UACR,MAAM;AAAA,UACN,MAAM,uBAAuB,KAAK,EAAE;AAAA,QACtC,CAAC;AAAA,MACH;AAAA,IACF;AAAA,EACF;AACF;;;AErDA,SAAS,KAAAE,UAAS;AAMlB,IAAMC,eAAc;AAAA,EAClB,WAAWC,GAAE,OAAO,EAAE,SAAS,yBAAyB;AAAA,EACxD,WAAWA,GAAE,OAAO,EAAE,SAAS,yBAAyB;AAAA,EACxD,eAAeA,GAAE,KAAK,cAAc,EAAE;AAAA,IACpC;AAAA,EACF;AACF;AAEO,SAAS,eAAe,QAAmB,MAAsB;AACtE,SAAO;AAAA,IACL;AAAA,IACA;AAAA,MACE,aACE;AAAA,MAGF,aAAAD;AAAA,MACA,aAAa,EAAE,gBAAgB,KAAK;AAAA,IACtC;AAAA,IACA,OAAO,SAAS;AACd,UAAI,KAAK,cAAc,KAAK,WAAW;AACrC,eAAO,eAAe;AAAA,UACpB,MAAM;AAAA,UACN,KAAK;AAAA,UACL,KAAK;AAAA,QACP,CAAC;AAAA,MACH;AAEA,YAAM,SAAS,KAAK,WAAW,QAAQ,KAAK,SAAS;AACrD,UAAI,CAAC,QAAQ;AACX,eAAO,eAAe,eAAe,KAAK,SAAS,CAAC;AAAA,MACtD;AAEA,YAAM,SAAS,KAAK,WAAW,QAAQ,KAAK,SAAS;AACrD,UAAI,CAAC,QAAQ;AACX,eAAO,eAAe,eAAe,KAAK,SAAS,CAAC;AAAA,MACtD;AAEA,UAAI,KAAK,SAAS;AAChB,mBAAW,OAAO,CAAC,QAAQ,MAAM,GAAG;AAClC,cAAI,IAAI,YAAY,QAAQ,IAAI,YAAY,KAAK,SAAS;AACxD,mBAAO,eAAe;AAAA,cACpB,MAAM,UAAU,IAAI,EAAE,wBAAwB,IAAI,OAAO;AAAA,cACzD,KAAK,uBAAuB,KAAK,OAAO;AAAA,cACxC,KAAK;AAAA,YACP,CAAC;AAAA,UACH;AAAA,QACF;AAAA,MACF;AAEA,YAAM,UAAU,KAAK,aAAa,OAAO,KAAK,WAAW,KAAK,WAAW,KAAK,aAAa;AAE3F,UAAI,CAAC,SAAS;AACZ,eAAO;AAAA,UACL,SAAS,CAAC;AAAA,YACR,MAAM;AAAA,YACN,MAAM,4BAA4B,KAAK,SAAS,OAAO,KAAK,aAAa,QAAQ,KAAK,SAAS;AAAA,UACjG,CAAC;AAAA,QACH;AAAA,MACF;AAEA,aAAO;AAAA,QACL,SAAS,CAAC;AAAA,UACR,MAAM;AAAA,UACN,MAAM,sBAAsB,OAAO,SAAS,OAAO,QAAQ,MAAM,GAAG,EAAE,CAAC,QAAQ,KAAK,aAAa,SAAS,OAAO,SAAS,OAAO,QAAQ,MAAM,GAAG,EAAE,CAAC;AAAA,QACvJ,CAAC;AAAA,MACH;AAAA,IACF;AAAA,EACF;AACF;;;ACvEA,SAAS,gBAAgB;AACzB,SAAS,YAAY;AAEd,SAAS,cAAc,QAAmB,MAAsB;AACrE,SAAO;AAAA,IACL;AAAA,IACA;AAAA,MACE,aACE;AAAA,MAEF,aAAa,EAAE,cAAc,MAAM,gBAAgB,KAAK;AAAA,IAC1D;AAAA,IACA,YAAY;AACV,YAAM,cAAc,KAAK,WAAW,YAAY;AAChD,YAAM,QAAQ,KAAK,WAAW,MAAM;AACpC,YAAM,cAAc,KAAK,WAAW,YAAY,CAAC;AACjD,YAAM,iBAAiB,KAAK,aAAa,MAAM;AAE/C,UAAI,cAAc;AAClB,UAAI;AACF,cAAM,SAAS,KAAK,KAAK,SAAS,WAAW;AAC7C,sBAAc,SAAS,MAAM,EAAE;AAAA,MACjC,QAAQ;AAAA,MAER;AAEA,YAAM,EAAE,QAAQ,OAAO,IAAI,KAAK,WAAW,UAAU;AAErD,YAAM,QAAqB;AAAA,QACzB,eAAe;AAAA,QACf,QAAQ,OAAO;AAAA,UACb,aAAa,IAAI,OAAK,CAAC,GAAG,YAAY,CAAC,KAAK,CAAC,CAAC;AAAA,QAChD;AAAA,QACA;AAAA,QACA;AAAA,QACA,cAAc;AAAA,QACd,cAAc;AAAA,QACd;AAAA,MACF;AAEA,aAAO;AAAA,QACL,SAAS,CAAC;AAAA,UACR,MAAM;AAAA,UACN,MAAM,KAAK,UAAU,OAAO,MAAM,CAAC;AAAA,QACrC,CAAC;AAAA,MACH;AAAA,IACF;AAAA,EACF;AACF;;;ACpDA,SAAS,KAAAE,UAAS;AAKlB,IAAMC,eAAc;AAAA,EAClB,OAAOC,GAAE,OAAO,EAAE,IAAI,EAAE,IAAI,CAAC,EAAE,IAAI,EAAE,EAAE,QAAQ,EAAE,EAAE,SAAS,4BAA4B;AAAA,EACxF,MAAMA,GAAE,KAAK,YAAY,EAAE,SAAS,EAAE,SAAS,uBAAuB;AACxE;AAEO,SAAS,eAAe,QAAmB,MAAsB;AACtE,SAAO;AAAA,IACL;AAAA,IACA;AAAA,MACE,aACE;AAAA,MAIF,aAAAD;AAAA,MACA,aAAa,EAAE,cAAc,MAAM,gBAAgB,KAAK;AAAA,IAC1D;AAAA,IACA,OAAO,SAAS;AACd,YAAM,UAAU,KAAK,iBAAiB,mBAAmB;AAAA,QACvD,OAAO,KAAK;AAAA,QACZ,SAAS,KAAK,WAAW;AAAA,QACzB,MAAM,KAAK;AAAA,MACb,CAAC;AAED,UAAI,QAAQ,WAAW,GAAG;AACxB,eAAO;AAAA,UACL,SAAS,CAAC,EAAE,MAAM,QAAiB,MAAM,sCAAsC,CAAC;AAAA,QAClF;AAAA,MACF;AAEA,YAAM,cAAc,CAAC,OAA+B,UAAkB;AAAA,QACpE;AAAA,QACA,SAAS,MAAM;AAAA,QACf,IAAI,MAAM,OAAO,OAAO;AAAA,QACxB,MAAM,MAAM,OAAO,OAAO;AAAA,QAC1B,OAAO,MAAM,OAAO,OAAO;AAAA,QAC3B,SAAS,MAAM,OAAO,OAAO,QAAQ,MAAM,GAAG,GAAG;AAAA,QACjD,YAAY,MAAM,OAAO,OAAO;AAAA,QAChC,MAAM,MAAM,OAAO,OAAO;AAAA,QAC1B,OAAO,KAAK,MAAM,MAAM,OAAO,QAAQ,GAAG,IAAI;AAAA,QAC9C,aAAa,MAAM,OAAO;AAAA,QAC1B,WAAW,MAAM,OAAO,OAAO;AAAA,MACjC;AAEA,YAAM,iBAAiB,QAAQ,OAAO,OAAK,EAAE,YAAY,SAAS,EAAE,IAAI,CAAC,GAAG,MAAM,YAAY,GAAG,IAAI,CAAC,CAAC;AACvG,YAAM,SAAS,QAAQ,OAAO,OAAK,EAAE,YAAY,QAAQ,EAAE,IAAI,CAAC,GAAG,MAAM,YAAY,GAAG,IAAI,CAAC,CAAC;AAC9F,YAAM,UAAU,QAAQ,OAAO,OAAK,EAAE,YAAY,SAAS,EAAE,IAAI,CAAC,GAAG,MAAM,YAAY,GAAG,IAAI,CAAC,CAAC;AAEhG,aAAO;AAAA,QACL,SAAS,CAAC;AAAA,UACR,MAAM;AAAA,UACN,MAAM,KAAK,UAAU,EAAE,gBAAgB,QAAQ,QAAQ,GAAG,MAAM,CAAC;AAAA,QACnE,CAAC;AAAA,MACH;AAAA,IACF;AAAA,EACF;AACF;;;AC7DA,SAAS,KAAAE,UAAS;AAIlB,IAAMC,eAAc;AAAA,EAClB,IAAID,GAAE,OAAO,EAAE,SAAS,oDAAoD;AAAA,EAC5E,OAAOA,GAAE,OAAO,EAAE,IAAI,GAAG,EAAE,SAAS,EAAE,SAAS,eAAe;AAAA,EAC9D,SAASA,GAAE,OAAO,EAAE,IAAI,CAAC,EAAE,IAAI,GAAK,EAAE,SAAS,EAAE,SAAS,iBAAiB;AAAA,EAC3E,MAAMA,GAAE,MAAMA,GAAE,OAAO,CAAC,EAAE,IAAI,EAAE,EAAE,SAAS,EAAE,SAAS,cAAc;AAAA,EACpE,YAAYA,GAAE,OAAO,EAAE,IAAI,CAAC,EAAE,IAAI,CAAC,EAAE,SAAS,EAAE,SAAS,0BAA0B;AAAA,EACnF,SAASA,GAAE,OAAO,EAAE,SAAS,EAAE,SAAS,sBAAsB;AAChE;AAEO,SAAS,eAAe,QAAmB,MAAsB;AACtE,SAAO;AAAA,IACL;AAAA,IACA;AAAA,MACE,aACE;AAAA,MAEF,aAAAC;AAAA,MACA,aAAa,EAAE,cAAc,OAAO,iBAAiB,OAAO,gBAAgB,KAAK;AAAA,IACnF;AAAA,IACA,OAAO,SAAS;AACd,YAAM,YAAY,KAAK,UAAU,UAAa,KAAK,YAAY,UAC1D,KAAK,SAAS,UAAa,KAAK,eAAe,UAC/C,KAAK,YAAY;AAEtB,UAAI,CAAC,WAAW;AACd,eAAO;AAAA,UACL,SAAS,CAAC,EAAE,MAAM,QAAiB,MAAM,2FAA2F,CAAC;AAAA,UACrI,SAAS;AAAA,QACX;AAAA,MACF;AAEA,YAAM,WAAW,KAAK,WAAW,QAAQ,KAAK,EAAE;AAChD,UAAI,CAAC,UAAU;AACb,eAAO;AAAA,UACL,SAAS,CAAC,EAAE,MAAM,QAAiB,MAAM,UAAU,KAAK,EAAE,cAAc,CAAC;AAAA,UACzE,SAAS;AAAA,QACX;AAAA,MACF;AAEA,YAAM,UAAU,KAAK,WAAW,cAAc,KAAK,IAAI;AAAA,QACrD,OAAO,KAAK;AAAA,QACZ,SAAS,KAAK;AAAA,QACd,MAAM,KAAK;AAAA,QACX,YAAY,KAAK;AAAA,QACjB,SAAS,KAAK;AAAA,MAChB,CAAC;AAED,UAAI,CAAC,SAAS;AACZ,eAAO;AAAA,UACL,SAAS,CAAC,EAAE,MAAM,QAAiB,MAAM,2BAA2B,KAAK,EAAE,IAAI,CAAC;AAAA,UAChF,SAAS;AAAA,QACX;AAAA,MACF;AAEA,YAAM,SAAS;AAAA,QACb,KAAK,UAAU,UAAa;AAAA,QAC5B,KAAK,YAAY,UAAa;AAAA,QAC9B,KAAK,SAAS,UAAa;AAAA,QAC3B,KAAK,eAAe,UAAa;AAAA,QACjC,KAAK,YAAY,UAAa;AAAA,MAChC,EAAE,OAAO,OAAO,EAAE,KAAK,IAAI;AAE3B,aAAO;AAAA,QACL,SAAS,CAAC,EAAE,MAAM,QAAiB,MAAM,kBAAkB,KAAK,EAAE,aAAa,MAAM,IAAI,CAAC;AAAA,MAC5F;AAAA,IACF;AAAA,EACF;AACF;;;ACnDO,SAAS,cAAc,QAAmB,MAAsB;AACrE,gBAAc,QAAQ,IAAI;AAC1B,iBAAe,QAAQ,IAAI;AAC3B,iBAAe,QAAQ,IAAI;AAC3B,iBAAe,QAAQ,IAAI;AAC3B,iBAAe,QAAQ,IAAI;AAC3B,gBAAc,QAAQ,IAAI;AAC1B,iBAAe,QAAQ,IAAI;AAC7B;;;AZXA,eAAsB,YAAY,MAA2C;AAC3E,QAAM,SAAS,MAAM,UAAU,WAAW;AAC1C,QAAM,UAAU,eAAe,OAAO,OAAO;AAE7C,QAAM,KAAK,eAAe,EAAE,QAAQ,CAAC;AACrC,UAAQ,EAAE;AAEV,QAAM,aAAa,IAAI,WAAW,EAAE;AACpC,QAAM,eAAe,IAAI,aAAa,EAAE;AACxC,QAAM,aAAa,IAAI,WAAW,EAAE;AAEpC,QAAM,mBAAmB,IAAI,iBAAiB;AAAA,IAC5C;AAAA,IACA;AAAA,IACA;AAAA,EACF,CAAC;AAED,QAAM,SAAS,IAAI;AAAA,IACjB,EAAE,MAAM,kBAAkB,SAAS,QAAQ;AAAA,IAC3C;AAAA,MACE,cACE;AAAA,IAMJ;AAAA,EACF;AAEA,QAAM,UAAU,cAAc,QAAQ,IAAI,CAAC;AAE3C,gBAAc,QAAQ,EAAE,YAAY,cAAc,kBAAkB,SAAS,QAAQ,CAAC;AAEtF,QAAM,YAAY,IAAI,qBAAqB;AAC3C,QAAM,OAAO,QAAQ,SAAS;AAE9B,QAAM,WAAW,YAAY;AAC3B,UAAM,OAAO,MAAM;AACnB,kBAAc,EAAE;AAChB,YAAQ,KAAK,CAAC;AAAA,EAChB;AACA,UAAQ,GAAG,UAAU,MAAM,KAAK,SAAS,CAAC;AAC1C,UAAQ,GAAG,WAAW,MAAM,KAAK,SAAS,CAAC;AAC7C;AAGA,YAAY,EAAE,MAAM,CAAC,QAAQ;AAC3B,UAAQ,OAAO,MAAM,oBAAoB,GAAG;AAAA,CAAI;AAChD,UAAQ,KAAK,CAAC;AAChB,CAAC;","names":["z","inputSchema","z","z","inputSchema","z","z","inputSchema","z","z","inputSchema","z","z","inputSchema"]}
@@ -0,0 +1,109 @@
1
+ #!/usr/bin/env node
2
+ import {
3
+ assertGhAvailable,
4
+ filenameToProject,
5
+ listGistFiles,
6
+ loadSyncConfig,
7
+ mergeFromRemote,
8
+ parsePayload,
9
+ projectToFilename,
10
+ readGistFile
11
+ } from "./chunk-HVWGJSU5.js";
12
+ import "./chunk-J5NT4JGE.js";
13
+ import {
14
+ detectProject
15
+ } from "./chunk-NAW47BYA.js";
16
+ import {
17
+ initStorage
18
+ } from "./chunk-YEGOHLE7.js";
19
+ import "./chunk-JXFTVFPC.js";
20
+ import "./chunk-ZMSHFAZQ.js";
21
+ import "./chunk-Z6FBT44W.js";
22
+ import {
23
+ log
24
+ } from "./chunk-RJGXPH7P.js";
25
+
26
+ // src/commands/memory/subcommands/pull.ts
27
+ async function runPull(opts) {
28
+ assertGhAvailable();
29
+ const syncConfig = loadSyncConfig();
30
+ if (!syncConfig) {
31
+ log.error("No sync gist found. Run `memory push` first.");
32
+ return;
33
+ }
34
+ const { requireMemoryDeps } = await import("./require-deps-NKRCPVAO.js");
35
+ await requireMemoryDeps();
36
+ const ctx = initStorage();
37
+ try {
38
+ if (opts.all) {
39
+ pullAll(ctx, syncConfig.gistId);
40
+ } else {
41
+ pullProject(ctx, syncConfig.gistId);
42
+ }
43
+ } finally {
44
+ ctx.close();
45
+ }
46
+ }
47
+ function pullProject(ctx, gistId) {
48
+ const project = detectProject(process.cwd());
49
+ if (!project) {
50
+ log.error("Could not detect project. Run from a project directory or use --all.");
51
+ return;
52
+ }
53
+ const filename = projectToFilename(project);
54
+ const payload = parsePayload(readGistFile(gistId, filename));
55
+ if (!payload) {
56
+ log.error(`No memories found for project "${project}" in gist.`);
57
+ return;
58
+ }
59
+ const result = mergeFromRemote(ctx.memoryRepo, ctx.relationRepo, payload);
60
+ printResult(result, project);
61
+ }
62
+ function pullAll(ctx, gistId) {
63
+ const files = listGistFiles(gistId);
64
+ const projectFiles = files.filter((f) => filenameToProject(f) !== null);
65
+ if (projectFiles.length === 0) {
66
+ log.error("No memory files found in gist.");
67
+ return;
68
+ }
69
+ let totalInserted = 0;
70
+ let totalUpdated = 0;
71
+ let totalRelations = 0;
72
+ for (const filename of projectFiles) {
73
+ const payload = parsePayload(readGistFile(gistId, filename));
74
+ if (!payload) continue;
75
+ const result = mergeFromRemote(ctx.memoryRepo, ctx.relationRepo, payload);
76
+ totalInserted += result.inserted;
77
+ totalUpdated += result.updated;
78
+ totalRelations += result.relationsAdded;
79
+ }
80
+ log.blank();
81
+ if (totalInserted === 0 && totalUpdated === 0 && totalRelations === 0) {
82
+ log.step("Already in sync");
83
+ } else {
84
+ log.step("Pull complete");
85
+ if (totalInserted > 0) log.info(`Inserted: ${totalInserted}`);
86
+ if (totalUpdated > 0) log.info(`Updated: ${totalUpdated}`);
87
+ if (totalRelations > 0) log.info(`Relations: ${totalRelations} added`);
88
+ }
89
+ log.info(`Projects: ${projectFiles.length}`);
90
+ log.blank();
91
+ }
92
+ function printResult(result, project) {
93
+ log.blank();
94
+ if (result.inserted === 0 && result.updated === 0 && result.relationsAdded === 0) {
95
+ log.step("Already in sync");
96
+ log.info(`Project: ${project}`);
97
+ } else {
98
+ log.step("Pull complete");
99
+ log.info(`Project: ${project}`);
100
+ if (result.inserted > 0) log.info(`Inserted: ${result.inserted}`);
101
+ if (result.updated > 0) log.info(`Updated: ${result.updated}`);
102
+ if (result.relationsAdded > 0) log.info(`Relations: ${result.relationsAdded} added`);
103
+ }
104
+ log.blank();
105
+ }
106
+ export {
107
+ runPull
108
+ };
109
+ //# sourceMappingURL=pull-6WBOOER2.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/commands/memory/subcommands/pull.ts"],"sourcesContent":["import { log } from '../../../lib/output.js';\nimport { initStorage } from './init-storage.js';\nimport {\n assertGhAvailable,\n loadSyncConfig,\n readGistFile,\n listGistFiles,\n filenameToProject,\n projectToFilename,\n parsePayload,\n} from '../utils/gist-transport.js';\nimport { mergeFromRemote } from '../utils/sync-merge.js';\nimport type { SyncPayload, MergeResult } from '../types.js';\nimport { detectProject } from '../utils/project.js';\n\ninterface PullOpts {\n readonly all?: boolean;\n}\n\nexport async function runPull(opts: PullOpts): Promise<void> {\n assertGhAvailable();\n\n const syncConfig = loadSyncConfig();\n if (!syncConfig) {\n log.error('No sync gist found. Run `memory push` first.');\n return;\n }\n\n const { requireMemoryDeps } = await import('../utils/require-deps.js');\n await requireMemoryDeps();\n const ctx = initStorage();\n\n try {\n if (opts.all) {\n pullAll(ctx, syncConfig.gistId);\n } else {\n pullProject(ctx, syncConfig.gistId);\n }\n } finally {\n ctx.close();\n }\n}\n\nfunction pullProject(ctx: ReturnType<typeof initStorage>, gistId: string): void {\n const project = detectProject(process.cwd());\n if (!project) {\n log.error('Could not detect project. Run from a project directory or use --all.');\n return;\n }\n\n const filename = projectToFilename(project);\n const payload = parsePayload(readGistFile(gistId, filename));\n if (!payload) {\n log.error(`No memories found for project \"${project}\" in gist.`);\n return;\n }\n\n const result = mergeFromRemote(ctx.memoryRepo, ctx.relationRepo, payload);\n printResult(result, project);\n}\n\nfunction pullAll(ctx: ReturnType<typeof initStorage>, gistId: string): void {\n const files = listGistFiles(gistId);\n const projectFiles = files.filter((f) => filenameToProject(f) !== null);\n\n if (projectFiles.length === 0) {\n log.error('No memory files found in gist.');\n return;\n }\n\n let totalInserted = 0;\n let totalUpdated = 0;\n let totalRelations = 0;\n\n for (const filename of projectFiles) {\n const payload = parsePayload(readGistFile(gistId, filename));\n if (!payload) continue;\n const result = mergeFromRemote(ctx.memoryRepo, ctx.relationRepo, payload);\n totalInserted += result.inserted;\n totalUpdated += result.updated;\n totalRelations += result.relationsAdded;\n }\n\n log.blank();\n if (totalInserted === 0 && totalUpdated === 0 && totalRelations === 0) {\n log.step('Already in sync');\n } else {\n log.step('Pull complete');\n if (totalInserted > 0) log.info(`Inserted: ${totalInserted}`);\n if (totalUpdated > 0) log.info(`Updated: ${totalUpdated}`);\n if (totalRelations > 0) log.info(`Relations: ${totalRelations} added`);\n }\n log.info(`Projects: ${projectFiles.length}`);\n log.blank();\n}\n\nfunction printResult(result: MergeResult, project: string): void {\n log.blank();\n if (result.inserted === 0 && result.updated === 0 && result.relationsAdded === 0) {\n log.step('Already in sync');\n log.info(`Project: ${project}`);\n } else {\n log.step('Pull complete');\n log.info(`Project: ${project}`);\n if (result.inserted > 0) log.info(`Inserted: ${result.inserted}`);\n if (result.updated > 0) log.info(`Updated: ${result.updated}`);\n if (result.relationsAdded > 0) log.info(`Relations: ${result.relationsAdded} added`);\n }\n log.blank();\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;AAmBA,eAAsB,QAAQ,MAA+B;AAC3D,oBAAkB;AAElB,QAAM,aAAa,eAAe;AAClC,MAAI,CAAC,YAAY;AACf,QAAI,MAAM,8CAA8C;AACxD;AAAA,EACF;AAEA,QAAM,EAAE,kBAAkB,IAAI,MAAM,OAAO,4BAA0B;AACrE,QAAM,kBAAkB;AACxB,QAAM,MAAM,YAAY;AAExB,MAAI;AACF,QAAI,KAAK,KAAK;AACZ,cAAQ,KAAK,WAAW,MAAM;AAAA,IAChC,OAAO;AACL,kBAAY,KAAK,WAAW,MAAM;AAAA,IACpC;AAAA,EACF,UAAE;AACA,QAAI,MAAM;AAAA,EACZ;AACF;AAEA,SAAS,YAAY,KAAqC,QAAsB;AAC9E,QAAM,UAAU,cAAc,QAAQ,IAAI,CAAC;AAC3C,MAAI,CAAC,SAAS;AACZ,QAAI,MAAM,sEAAsE;AAChF;AAAA,EACF;AAEA,QAAM,WAAW,kBAAkB,OAAO;AAC1C,QAAM,UAAU,aAAa,aAAa,QAAQ,QAAQ,CAAC;AAC3D,MAAI,CAAC,SAAS;AACZ,QAAI,MAAM,kCAAkC,OAAO,YAAY;AAC/D;AAAA,EACF;AAEA,QAAM,SAAS,gBAAgB,IAAI,YAAY,IAAI,cAAc,OAAO;AACxE,cAAY,QAAQ,OAAO;AAC7B;AAEA,SAAS,QAAQ,KAAqC,QAAsB;AAC1E,QAAM,QAAQ,cAAc,MAAM;AAClC,QAAM,eAAe,MAAM,OAAO,CAAC,MAAM,kBAAkB,CAAC,MAAM,IAAI;AAEtE,MAAI,aAAa,WAAW,GAAG;AAC7B,QAAI,MAAM,gCAAgC;AAC1C;AAAA,EACF;AAEA,MAAI,gBAAgB;AACpB,MAAI,eAAe;AACnB,MAAI,iBAAiB;AAErB,aAAW,YAAY,cAAc;AACnC,UAAM,UAAU,aAAa,aAAa,QAAQ,QAAQ,CAAC;AAC3D,QAAI,CAAC,QAAS;AACd,UAAM,SAAS,gBAAgB,IAAI,YAAY,IAAI,cAAc,OAAO;AACxE,qBAAiB,OAAO;AACxB,oBAAgB,OAAO;AACvB,sBAAkB,OAAO;AAAA,EAC3B;AAEA,MAAI,MAAM;AACV,MAAI,kBAAkB,KAAK,iBAAiB,KAAK,mBAAmB,GAAG;AACrE,QAAI,KAAK,iBAAiB;AAAA,EAC5B,OAAO;AACL,QAAI,KAAK,eAAe;AACxB,QAAI,gBAAgB,EAAG,KAAI,KAAK,cAAc,aAAa,EAAE;AAC7D,QAAI,eAAe,EAAG,KAAI,KAAK,cAAc,YAAY,EAAE;AAC3D,QAAI,iBAAiB,EAAG,KAAI,KAAK,cAAc,cAAc,QAAQ;AAAA,EACvE;AACA,MAAI,KAAK,cAAc,aAAa,MAAM,EAAE;AAC5C,MAAI,MAAM;AACZ;AAEA,SAAS,YAAY,QAAqB,SAAuB;AAC/D,MAAI,MAAM;AACV,MAAI,OAAO,aAAa,KAAK,OAAO,YAAY,KAAK,OAAO,mBAAmB,GAAG;AAChF,QAAI,KAAK,iBAAiB;AAC1B,QAAI,KAAK,YAAY,OAAO,EAAE;AAAA,EAChC,OAAO;AACL,QAAI,KAAK,eAAe;AACxB,QAAI,KAAK,cAAc,OAAO,EAAE;AAChC,QAAI,OAAO,WAAW,EAAG,KAAI,KAAK,cAAc,OAAO,QAAQ,EAAE;AACjE,QAAI,OAAO,UAAU,EAAG,KAAI,KAAK,cAAc,OAAO,OAAO,EAAE;AAC/D,QAAI,OAAO,iBAAiB,EAAG,KAAI,KAAK,cAAc,OAAO,cAAc,QAAQ;AAAA,EACrF;AACA,MAAI,MAAM;AACZ;","names":[]}