claude-launchpad 0.12.0 → 0.12.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cli.js +113 -54
- package/dist/cli.js.map +1 -1
- package/dist/commands/memory/server.js +1 -1
- package/dist/commands/memory/server.js.map +1 -1
- package/dist/{tui-YMBDAVTI.js → tui-IWUB7ZR4.js} +84 -18
- package/dist/tui-IWUB7ZR4.js.map +1 -0
- package/package.json +1 -1
- package/dist/tui-YMBDAVTI.js.map +0 -1
|
@@ -478,7 +478,7 @@ function registerStore(server, deps) {
|
|
|
478
478
|
server.registerTool(
|
|
479
479
|
"memory_store",
|
|
480
480
|
{
|
|
481
|
-
description:
|
|
481
|
+
description: 'Store a new memory. Use memory_search first to check for duplicates. Prefer updating existing semantic/procedural memories over creating new ones. Types: episodic (events), semantic (facts), procedural (how-to), pattern (recurring), working (temporary). Importance: 0-0.3 ephemeral, 0.3-0.6 reference, 0.6-0.8 important, 0.8-1.0 critical. Suggested tags: #bug, #decision, #gotcha, #howto, #pattern, #architecture. Context is auto-detected from git (branch, recent files) if omitted. NOTE: A built-in dedup guard prevents identical content from being stored twice within 10 seconds. If you see "Skipped" responses, the memory was likely already stored by a parallel call. This is expected behavior, not an error. The data is saved correctly.',
|
|
482
482
|
inputSchema,
|
|
483
483
|
annotations: { idempotentHint: false }
|
|
484
484
|
},
|
|
@@ -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 + '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 pendingStores = new Set<string>();\nconst DEDUP_WINDOW_MS = 10_000;\n\n// Tag normalization: lowercase, strip #, singularize common suffixes, apply aliases\nconst TAG_ALIASES: Record<string, string> = {\n bugs: 'bug', bugfix: 'bug', debugging: 'bug',\n decisions: 'decision', decided: 'decision',\n gotchas: 'gotcha', pitfall: 'gotcha', pitfalls: 'gotcha',\n howtos: 'howto', 'how-to': 'howto',\n patterns: 'pattern',\n todos: 'todo', fixme: 'todo',\n architectures: 'architecture', arch: 'architecture',\n};\n\nfunction normalizeTags(tags: readonly string[]): string[] {\n return [...new Set(tags.map((t) => {\n const stripped = t.replace(/^#/, '').toLowerCase().trim();\n return TAG_ALIASES[stripped] ?? stripped;\n }).filter(Boolean))];\n}\n\n// Auto-tag: detect common patterns in content\nconst AUTO_TAG_PATTERNS: readonly { readonly pattern: RegExp; readonly tag: string }[] = [\n { pattern: /\\b(bug|crash|error|fix(ed)?|broke)\\b/i, tag: 'bug' },\n { pattern: /\\b(decid|chose|decision|went with|picked)\\b/i, tag: 'decision' },\n { pattern: /\\b(gotcha|careful|watch out|trap|pitfall)\\b/i, tag: 'gotcha' },\n { pattern: /\\b(how to|steps to|run|install|deploy|command)\\b/i, tag: 'howto' },\n { pattern: /\\b(pattern|recurring|always|every time)\\b/i, tag: 'pattern' },\n];\n\nfunction autoTag(content: string, existingTags: readonly string[]): string[] {\n const existing = new Set(existingTags);\n const detected: string[] = [];\n for (const { pattern, tag } of AUTO_TAG_PATTERNS) {\n if (!existing.has(tag) && pattern.test(content)) {\n detected.push(tag);\n }\n }\n return detected;\n}\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(2000).describe('The memory content (max 2000 chars / ~500 tokens). Keep memories concise: capture the decision or insight, not the full context. Split large topics into separate memories.'),\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 // Uses a pending Set to catch calls that arrive in the same tick.\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: 'Skipped: identical memory already exists (stored moments ago).' }],\n };\n }\n if (pendingStores.has(contentHash)) {\n return {\n content: [{ type: 'text' as const, text: 'Skipped: identical memory is being stored by another call.' }],\n };\n }\n pendingStores.add(contentHash);\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 // Normalize tags + auto-tag from content\n const normalizedTags = normalizeTags(args.tags);\n const autoTags = autoTag(args.content, normalizedTags);\n const finalTags = [...new Set([...normalizedTags, ...autoTags])];\n\n const memory = deps.memoryRepo.create(\n {\n type: args.type,\n content: args.content,\n title: args.title,\n tags: finalTags,\n importance: args.importance,\n context,\n source: args.source,\n project,\n },\n null,\n );\n\n // Mark as stored (dedup window starts now)\n recentStores.set(contentHash, Date.now());\n pendingStores.delete(contentHash);\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 pendingStores = new Set<string>();\nconst DEDUP_WINDOW_MS = 10_000;\n\n// Tag normalization: lowercase, strip #, singularize common suffixes, apply aliases\nconst TAG_ALIASES: Record<string, string> = {\n bugs: 'bug', bugfix: 'bug', debugging: 'bug',\n decisions: 'decision', decided: 'decision',\n gotchas: 'gotcha', pitfall: 'gotcha', pitfalls: 'gotcha',\n howtos: 'howto', 'how-to': 'howto',\n patterns: 'pattern',\n todos: 'todo', fixme: 'todo',\n architectures: 'architecture', arch: 'architecture',\n};\n\nfunction normalizeTags(tags: readonly string[]): string[] {\n return [...new Set(tags.map((t) => {\n const stripped = t.replace(/^#/, '').toLowerCase().trim();\n return TAG_ALIASES[stripped] ?? stripped;\n }).filter(Boolean))];\n}\n\n// Auto-tag: detect common patterns in content\nconst AUTO_TAG_PATTERNS: readonly { readonly pattern: RegExp; readonly tag: string }[] = [\n { pattern: /\\b(bug|crash|error|fix(ed)?|broke)\\b/i, tag: 'bug' },\n { pattern: /\\b(decid|chose|decision|went with|picked)\\b/i, tag: 'decision' },\n { pattern: /\\b(gotcha|careful|watch out|trap|pitfall)\\b/i, tag: 'gotcha' },\n { pattern: /\\b(how to|steps to|run|install|deploy|command)\\b/i, tag: 'howto' },\n { pattern: /\\b(pattern|recurring|always|every time)\\b/i, tag: 'pattern' },\n];\n\nfunction autoTag(content: string, existingTags: readonly string[]): string[] {\n const existing = new Set(existingTags);\n const detected: string[] = [];\n for (const { pattern, tag } of AUTO_TAG_PATTERNS) {\n if (!existing.has(tag) && pattern.test(content)) {\n detected.push(tag);\n }\n }\n return detected;\n}\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(2000).describe('The memory content (max 2000 chars / ~500 tokens). Keep memories concise: capture the decision or insight, not the full context. Split large topics into separate memories.'),\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 + 'NOTE: A built-in dedup guard prevents identical content from being stored twice within 10 seconds. '\n + 'If you see \"Skipped\" responses, the memory was likely already stored by a parallel call. '\n + 'This is expected behavior, not an error. The data is saved correctly.',\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 // Uses a pending Set to catch calls that arrive in the same tick.\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: 'Skipped: identical memory already exists (stored moments ago).' }],\n };\n }\n if (pendingStores.has(contentHash)) {\n return {\n content: [{ type: 'text' as const, text: 'Skipped: identical memory is being stored by another call.' }],\n };\n }\n pendingStores.add(contentHash);\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 // Normalize tags + auto-tag from content\n const normalizedTags = normalizeTags(args.tags);\n const autoTags = autoTag(args.content, normalizedTags);\n const finalTags = [...new Set([...normalizedTags, ...autoTags])];\n\n const memory = deps.memoryRepo.create(\n {\n type: args.type,\n content: args.content,\n title: args.title,\n tags: finalTags,\n importance: args.importance,\n context,\n source: args.source,\n project,\n },\n null,\n );\n\n // Mark as stored (dedup window starts now)\n recentStores.set(contentHash, Date.now());\n pendingStores.delete(contentHash);\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"]}
|
|
@@ -94,6 +94,10 @@ var DashboardDataSource = class {
|
|
|
94
94
|
onChange();
|
|
95
95
|
});
|
|
96
96
|
}
|
|
97
|
+
/** Hard-delete a memory by ID. Returns true if deleted. */
|
|
98
|
+
deleteMemory(id) {
|
|
99
|
+
return this.#memoryRepo.hardDelete(id);
|
|
100
|
+
}
|
|
97
101
|
/** Stop watching the DB file. */
|
|
98
102
|
stopWatching() {
|
|
99
103
|
unwatchFile(this.#dbPath);
|
|
@@ -117,7 +121,7 @@ var DashboardDataSource = class {
|
|
|
117
121
|
};
|
|
118
122
|
|
|
119
123
|
// src/commands/memory/dashboard/app.tsx
|
|
120
|
-
import { Box as
|
|
124
|
+
import { Box as Box11, useApp } from "ink";
|
|
121
125
|
|
|
122
126
|
// src/commands/memory/dashboard/hooks/use-dashboard-state.ts
|
|
123
127
|
import { useState, useMemo, useEffect, useCallback } from "react";
|
|
@@ -217,6 +221,7 @@ function useDashboardState(dataSource) {
|
|
|
217
221
|
const [focusedPane, setFocusedPane] = useState("list");
|
|
218
222
|
const [showHelp, setShowHelp] = useState(false);
|
|
219
223
|
const [showProjectPicker, setShowProjectPicker] = useState(false);
|
|
224
|
+
const [showDeleteConfirm, setShowDeleteConfirm] = useState(false);
|
|
220
225
|
useEffect(() => {
|
|
221
226
|
dataSource.refresh();
|
|
222
227
|
setRevision((r) => r + 1);
|
|
@@ -294,6 +299,18 @@ function useDashboardState(dataSource) {
|
|
|
294
299
|
dataSource.refresh();
|
|
295
300
|
setRevision((r) => r + 1);
|
|
296
301
|
}, [dataSource]);
|
|
302
|
+
const promptDelete = useCallback(() => {
|
|
303
|
+
if (selectedMemory) setShowDeleteConfirm(true);
|
|
304
|
+
}, [selectedMemory]);
|
|
305
|
+
const confirmDelete = useCallback(() => {
|
|
306
|
+
if (!selectedMemory) return;
|
|
307
|
+
dataSource.deleteMemory(selectedMemory.id);
|
|
308
|
+
setShowDeleteConfirm(false);
|
|
309
|
+
setSelectedIndex((i) => Math.max(0, i - 1));
|
|
310
|
+
dataSource.refresh();
|
|
311
|
+
setRevision((r) => r + 1);
|
|
312
|
+
}, [dataSource, selectedMemory]);
|
|
313
|
+
const cancelDelete = useCallback(() => setShowDeleteConfirm(false), []);
|
|
297
314
|
return {
|
|
298
315
|
typeFilter,
|
|
299
316
|
lifespanFilter,
|
|
@@ -305,6 +322,7 @@ function useDashboardState(dataSource) {
|
|
|
305
322
|
focusedPane,
|
|
306
323
|
showHelp,
|
|
307
324
|
showProjectPicker,
|
|
325
|
+
showDeleteConfirm,
|
|
308
326
|
filteredMemories,
|
|
309
327
|
selectedMemory,
|
|
310
328
|
relations,
|
|
@@ -325,7 +343,10 @@ function useDashboardState(dataSource) {
|
|
|
325
343
|
filterByType,
|
|
326
344
|
openSearch,
|
|
327
345
|
closeSearch,
|
|
328
|
-
refresh
|
|
346
|
+
refresh,
|
|
347
|
+
promptDelete,
|
|
348
|
+
confirmDelete,
|
|
349
|
+
cancelDelete
|
|
329
350
|
};
|
|
330
351
|
}
|
|
331
352
|
function sortMemories(memories, mode) {
|
|
@@ -371,6 +392,7 @@ function useKeybindings(actions, opts) {
|
|
|
371
392
|
if (input === "]" || key.rightArrow) actions.cycleProjectNext();
|
|
372
393
|
if (input === "[" || key.leftArrow) actions.cycleProjectPrev();
|
|
373
394
|
if (key.tab) actions.focusNext();
|
|
395
|
+
if (input === "d") actions.deleteMemory();
|
|
374
396
|
if (input === "?") actions.showHelp();
|
|
375
397
|
if (input === "r") actions.refresh();
|
|
376
398
|
if (input === "q") actions.quit();
|
|
@@ -408,6 +430,7 @@ var HINTS = [
|
|
|
408
430
|
["1-5", "type"],
|
|
409
431
|
["l", "life"],
|
|
410
432
|
["s", "sort"],
|
|
433
|
+
["d", "delete"],
|
|
411
434
|
["Tab", "focus"],
|
|
412
435
|
["?", "help"],
|
|
413
436
|
["q", "quit"]
|
|
@@ -795,6 +818,7 @@ var BINDINGS = [
|
|
|
795
818
|
["s", "Cycle sort mode"],
|
|
796
819
|
["p", "Open project picker"],
|
|
797
820
|
["[ / ]", "Previous / next project"],
|
|
821
|
+
["d", "Delete selected memory"],
|
|
798
822
|
["Tab", "Focus next pane"],
|
|
799
823
|
["r", "Refresh"],
|
|
800
824
|
["?", "Show this help"],
|
|
@@ -865,8 +889,39 @@ function ProjectPicker({ projects, activeProject, onSelect, onClose }) {
|
|
|
865
889
|
] });
|
|
866
890
|
}
|
|
867
891
|
|
|
868
|
-
// src/commands/memory/dashboard/
|
|
892
|
+
// src/commands/memory/dashboard/components/delete-confirm.tsx
|
|
893
|
+
import { Box as Box10, Text as Text10, useInput as useInput4 } from "ink";
|
|
869
894
|
import { jsx as jsx10, jsxs as jsxs10 } from "react/jsx-runtime";
|
|
895
|
+
function DeleteConfirm({ memory, onConfirm, onCancel }) {
|
|
896
|
+
useInput4((input, key) => {
|
|
897
|
+
if (input === "y" || input === "Y") onConfirm();
|
|
898
|
+
if (input === "n" || input === "N" || key.escape) onCancel();
|
|
899
|
+
});
|
|
900
|
+
const title = memory.title ?? memory.content.slice(0, 40);
|
|
901
|
+
return /* @__PURE__ */ jsxs10(Box10, { flexDirection: "column", borderStyle: "double", borderColor: "red", paddingX: 2, paddingY: 1, children: [
|
|
902
|
+
/* @__PURE__ */ jsx10(Text10, { bold: true, color: "red", children: "Delete memory?" }),
|
|
903
|
+
/* @__PURE__ */ jsx10(Text10, { children: " " }),
|
|
904
|
+
/* @__PURE__ */ jsx10(Text10, { bold: true, children: title }),
|
|
905
|
+
/* @__PURE__ */ jsxs10(Text10, { dimColor: true, children: [
|
|
906
|
+
"[",
|
|
907
|
+
memory.type,
|
|
908
|
+
"] ",
|
|
909
|
+
memory.project ?? "(no project)"
|
|
910
|
+
] }),
|
|
911
|
+
/* @__PURE__ */ jsx10(Text10, { children: " " }),
|
|
912
|
+
/* @__PURE__ */ jsx10(Text10, { children: "This is a permanent hard delete. The memory cannot be recovered." }),
|
|
913
|
+
/* @__PURE__ */ jsx10(Text10, { children: " " }),
|
|
914
|
+
/* @__PURE__ */ jsxs10(Text10, { children: [
|
|
915
|
+
/* @__PURE__ */ jsx10(Text10, { color: "green", bold: true, children: "y" }),
|
|
916
|
+
" confirm ",
|
|
917
|
+
/* @__PURE__ */ jsx10(Text10, { color: "red", bold: true, children: "n/Esc" }),
|
|
918
|
+
" cancel"
|
|
919
|
+
] })
|
|
920
|
+
] });
|
|
921
|
+
}
|
|
922
|
+
|
|
923
|
+
// src/commands/memory/dashboard/app.tsx
|
|
924
|
+
import { jsx as jsx11, jsxs as jsxs11 } from "react/jsx-runtime";
|
|
870
925
|
function App({ dataSource }) {
|
|
871
926
|
const { exit } = useApp();
|
|
872
927
|
const { rows, layout } = useTerminalSize();
|
|
@@ -882,6 +937,7 @@ function App({ dataSource }) {
|
|
|
882
937
|
cycleProjectPrev: state.cycleProjectPrev,
|
|
883
938
|
cycleSort: state.cycleSort,
|
|
884
939
|
focusNext: state.focusNext,
|
|
940
|
+
deleteMemory: state.promptDelete,
|
|
885
941
|
openProjectPicker: () => state.setShowProjectPicker((v) => !v),
|
|
886
942
|
showHelp: () => state.setShowHelp((v) => !v),
|
|
887
943
|
refresh: state.refresh,
|
|
@@ -891,10 +947,10 @@ function App({ dataSource }) {
|
|
|
891
947
|
pickerOpen: state.showProjectPicker
|
|
892
948
|
});
|
|
893
949
|
if (state.showHelp) {
|
|
894
|
-
return /* @__PURE__ */
|
|
950
|
+
return /* @__PURE__ */ jsx11(HelpOverlay, { onClose: () => state.setShowHelp(false) });
|
|
895
951
|
}
|
|
896
952
|
if (state.showProjectPicker) {
|
|
897
|
-
return /* @__PURE__ */
|
|
953
|
+
return /* @__PURE__ */ jsx11(
|
|
898
954
|
ProjectPicker,
|
|
899
955
|
{
|
|
900
956
|
projects: [...state.projects],
|
|
@@ -907,11 +963,21 @@ function App({ dataSource }) {
|
|
|
907
963
|
}
|
|
908
964
|
);
|
|
909
965
|
}
|
|
966
|
+
if (state.showDeleteConfirm && state.selectedMemory) {
|
|
967
|
+
return /* @__PURE__ */ jsx11(
|
|
968
|
+
DeleteConfirm,
|
|
969
|
+
{
|
|
970
|
+
memory: state.selectedMemory,
|
|
971
|
+
onConfirm: state.confirmDelete,
|
|
972
|
+
onCancel: state.cancelDelete
|
|
973
|
+
}
|
|
974
|
+
);
|
|
975
|
+
}
|
|
910
976
|
const contentHeight = Math.max(4, rows - 6);
|
|
911
977
|
const isNarrow = layout === "narrow";
|
|
912
|
-
return /* @__PURE__ */
|
|
913
|
-
/* @__PURE__ */
|
|
914
|
-
/* @__PURE__ */
|
|
978
|
+
return /* @__PURE__ */ jsxs11(Box11, { flexDirection: "column", children: [
|
|
979
|
+
/* @__PURE__ */ jsx11(KeybindingBar, {}),
|
|
980
|
+
/* @__PURE__ */ jsx11(
|
|
915
981
|
Header,
|
|
916
982
|
{
|
|
917
983
|
project: state.currentProject,
|
|
@@ -921,7 +987,7 @@ function App({ dataSource }) {
|
|
|
921
987
|
searchQuery: state.searchQuery
|
|
922
988
|
}
|
|
923
989
|
),
|
|
924
|
-
state.searchActive && /* @__PURE__ */
|
|
990
|
+
state.searchActive && /* @__PURE__ */ jsx11(
|
|
925
991
|
SearchBar,
|
|
926
992
|
{
|
|
927
993
|
query: state.searchQuery,
|
|
@@ -929,8 +995,8 @@ function App({ dataSource }) {
|
|
|
929
995
|
onClose: () => state.setSearchQuery(state.searchQuery)
|
|
930
996
|
}
|
|
931
997
|
),
|
|
932
|
-
/* @__PURE__ */
|
|
933
|
-
/* @__PURE__ */
|
|
998
|
+
/* @__PURE__ */ jsxs11(Box11, { flexDirection: isNarrow ? "column" : "row", children: [
|
|
999
|
+
/* @__PURE__ */ jsx11(Box11, { width: isNarrow ? "100%" : "60%", children: /* @__PURE__ */ jsx11(
|
|
934
1000
|
MemoryList,
|
|
935
1001
|
{
|
|
936
1002
|
memories: state.filteredMemories,
|
|
@@ -939,8 +1005,8 @@ function App({ dataSource }) {
|
|
|
939
1005
|
height: contentHeight
|
|
940
1006
|
}
|
|
941
1007
|
) }),
|
|
942
|
-
/* @__PURE__ */
|
|
943
|
-
!isNarrow && /* @__PURE__ */
|
|
1008
|
+
/* @__PURE__ */ jsxs11(Box11, { flexDirection: "column", width: isNarrow ? "100%" : "40%", children: [
|
|
1009
|
+
!isNarrow && /* @__PURE__ */ jsx11(
|
|
944
1010
|
ProjectList,
|
|
945
1011
|
{
|
|
946
1012
|
memories: state.filteredMemories,
|
|
@@ -948,7 +1014,7 @@ function App({ dataSource }) {
|
|
|
948
1014
|
isFocused: state.focusedPane === "projects"
|
|
949
1015
|
}
|
|
950
1016
|
),
|
|
951
|
-
/* @__PURE__ */
|
|
1017
|
+
/* @__PURE__ */ jsx11(
|
|
952
1018
|
MemoryDetail,
|
|
953
1019
|
{
|
|
954
1020
|
memory: state.selectedMemory,
|
|
@@ -958,12 +1024,12 @@ function App({ dataSource }) {
|
|
|
958
1024
|
)
|
|
959
1025
|
] })
|
|
960
1026
|
] }),
|
|
961
|
-
/* @__PURE__ */
|
|
1027
|
+
/* @__PURE__ */ jsx11(StatsBar, { stats: state.stats, visible: state.filteredMemories })
|
|
962
1028
|
] });
|
|
963
1029
|
}
|
|
964
1030
|
|
|
965
1031
|
// src/commands/memory/dashboard/tui.tsx
|
|
966
|
-
import { jsx as
|
|
1032
|
+
import { jsx as jsx12 } from "react/jsx-runtime";
|
|
967
1033
|
async function startTui(options) {
|
|
968
1034
|
const config = loadConfig(
|
|
969
1035
|
options?.dbPath ? { dataDir: options.dbPath } : void 0
|
|
@@ -982,7 +1048,7 @@ async function startTui(options) {
|
|
|
982
1048
|
);
|
|
983
1049
|
let shuttingDown = false;
|
|
984
1050
|
const { waitUntilExit, unmount } = render(
|
|
985
|
-
/* @__PURE__ */
|
|
1051
|
+
/* @__PURE__ */ jsx12(App, { dataSource })
|
|
986
1052
|
);
|
|
987
1053
|
function shutdown() {
|
|
988
1054
|
if (shuttingDown) return;
|
|
@@ -1005,4 +1071,4 @@ async function startTui(options) {
|
|
|
1005
1071
|
export {
|
|
1006
1072
|
startTui
|
|
1007
1073
|
};
|
|
1008
|
-
//# sourceMappingURL=tui-
|
|
1074
|
+
//# sourceMappingURL=tui-IWUB7ZR4.js.map
|