@londer/cortex 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (125) hide show
  1. package/CHANGELOG.md +62 -0
  2. package/LICENSE +21 -0
  3. package/README.md +183 -0
  4. package/dist/cli.d.ts +3 -0
  5. package/dist/cli.d.ts.map +1 -0
  6. package/dist/cli.js +278 -0
  7. package/dist/cli.js.map +1 -0
  8. package/dist/config-store.d.ts +15 -0
  9. package/dist/config-store.d.ts.map +1 -0
  10. package/dist/config-store.js +86 -0
  11. package/dist/config-store.js.map +1 -0
  12. package/dist/config.d.ts +28 -0
  13. package/dist/config.d.ts.map +1 -0
  14. package/dist/config.js +39 -0
  15. package/dist/config.js.map +1 -0
  16. package/dist/consolidation/cluster-finder.d.ts +5 -0
  17. package/dist/consolidation/cluster-finder.d.ts.map +1 -0
  18. package/dist/consolidation/cluster-finder.js +43 -0
  19. package/dist/consolidation/cluster-finder.js.map +1 -0
  20. package/dist/consolidation/consolidator.d.ts +29 -0
  21. package/dist/consolidation/consolidator.d.ts.map +1 -0
  22. package/dist/consolidation/consolidator.js +296 -0
  23. package/dist/consolidation/consolidator.js.map +1 -0
  24. package/dist/embedding/embedder.d.ts +9 -0
  25. package/dist/embedding/embedder.d.ts.map +1 -0
  26. package/dist/embedding/embedder.js +89 -0
  27. package/dist/embedding/embedder.js.map +1 -0
  28. package/dist/extraction/auto-extractor.d.ts +7 -0
  29. package/dist/extraction/auto-extractor.d.ts.map +1 -0
  30. package/dist/extraction/auto-extractor.js +174 -0
  31. package/dist/extraction/auto-extractor.js.map +1 -0
  32. package/dist/extraction/conversation-buffer.d.ts +15 -0
  33. package/dist/extraction/conversation-buffer.d.ts.map +1 -0
  34. package/dist/extraction/conversation-buffer.js +60 -0
  35. package/dist/extraction/conversation-buffer.js.map +1 -0
  36. package/dist/extraction/extractor.d.ts +23 -0
  37. package/dist/extraction/extractor.d.ts.map +1 -0
  38. package/dist/extraction/extractor.js +108 -0
  39. package/dist/extraction/extractor.js.map +1 -0
  40. package/dist/extraction/tier1-regex.d.ts +7 -0
  41. package/dist/extraction/tier1-regex.d.ts.map +1 -0
  42. package/dist/extraction/tier1-regex.js +119 -0
  43. package/dist/extraction/tier1-regex.js.map +1 -0
  44. package/dist/extraction/tier2-nlp.d.ts +13 -0
  45. package/dist/extraction/tier2-nlp.d.ts.map +1 -0
  46. package/dist/extraction/tier2-nlp.js +195 -0
  47. package/dist/extraction/tier2-nlp.js.map +1 -0
  48. package/dist/extraction/tier3-llm.d.ts +8 -0
  49. package/dist/extraction/tier3-llm.d.ts.map +1 -0
  50. package/dist/extraction/tier3-llm.js +57 -0
  51. package/dist/extraction/tier3-llm.js.map +1 -0
  52. package/dist/index.d.ts +2 -0
  53. package/dist/index.d.ts.map +1 -0
  54. package/dist/index.js +398 -0
  55. package/dist/index.js.map +1 -0
  56. package/dist/llm/anthropic-client.d.ts +18 -0
  57. package/dist/llm/anthropic-client.d.ts.map +1 -0
  58. package/dist/llm/anthropic-client.js +116 -0
  59. package/dist/llm/anthropic-client.js.map +1 -0
  60. package/dist/orchestration/ranker.d.ts +18 -0
  61. package/dist/orchestration/ranker.d.ts.map +1 -0
  62. package/dist/orchestration/ranker.js +124 -0
  63. package/dist/orchestration/ranker.js.map +1 -0
  64. package/dist/orchestration/scope.d.ts +15 -0
  65. package/dist/orchestration/scope.d.ts.map +1 -0
  66. package/dist/orchestration/scope.js +28 -0
  67. package/dist/orchestration/scope.js.map +1 -0
  68. package/dist/storage/neo4j.d.ts +19 -0
  69. package/dist/storage/neo4j.d.ts.map +1 -0
  70. package/dist/storage/neo4j.js +246 -0
  71. package/dist/storage/neo4j.js.map +1 -0
  72. package/dist/storage/qdrant.d.ts +21 -0
  73. package/dist/storage/qdrant.d.ts.map +1 -0
  74. package/dist/storage/qdrant.js +125 -0
  75. package/dist/storage/qdrant.js.map +1 -0
  76. package/dist/storage/sqlite.d.ts +23 -0
  77. package/dist/storage/sqlite.d.ts.map +1 -0
  78. package/dist/storage/sqlite.js +162 -0
  79. package/dist/storage/sqlite.js.map +1 -0
  80. package/dist/templates/claude-instructions.d.ts +11 -0
  81. package/dist/templates/claude-instructions.d.ts.map +1 -0
  82. package/dist/templates/claude-instructions.js +110 -0
  83. package/dist/templates/claude-instructions.js.map +1 -0
  84. package/dist/tools/config.d.ts +21 -0
  85. package/dist/tools/config.d.ts.map +1 -0
  86. package/dist/tools/config.js +96 -0
  87. package/dist/tools/config.js.map +1 -0
  88. package/dist/tools/consolidate.d.ts +4 -0
  89. package/dist/tools/consolidate.d.ts.map +1 -0
  90. package/dist/tools/consolidate.js +16 -0
  91. package/dist/tools/consolidate.js.map +1 -0
  92. package/dist/tools/context.d.ts +8 -0
  93. package/dist/tools/context.d.ts.map +1 -0
  94. package/dist/tools/context.js +84 -0
  95. package/dist/tools/context.js.map +1 -0
  96. package/dist/tools/forget.d.ts +7 -0
  97. package/dist/tools/forget.d.ts.map +1 -0
  98. package/dist/tools/forget.js +49 -0
  99. package/dist/tools/forget.js.map +1 -0
  100. package/dist/tools/graph-query.d.ts +5 -0
  101. package/dist/tools/graph-query.d.ts.map +1 -0
  102. package/dist/tools/graph-query.js +35 -0
  103. package/dist/tools/graph-query.js.map +1 -0
  104. package/dist/tools/ingest.d.ts +8 -0
  105. package/dist/tools/ingest.d.ts.map +1 -0
  106. package/dist/tools/ingest.js +101 -0
  107. package/dist/tools/ingest.js.map +1 -0
  108. package/dist/tools/relate.d.ts +4 -0
  109. package/dist/tools/relate.d.ts.map +1 -0
  110. package/dist/tools/relate.js +10 -0
  111. package/dist/tools/relate.js.map +1 -0
  112. package/dist/tools/search.d.ts +6 -0
  113. package/dist/tools/search.d.ts.map +1 -0
  114. package/dist/tools/search.js +43 -0
  115. package/dist/tools/search.js.map +1 -0
  116. package/dist/tools/store.d.ts +8 -0
  117. package/dist/tools/store.d.ts.map +1 -0
  118. package/dist/tools/store.js +64 -0
  119. package/dist/tools/store.js.map +1 -0
  120. package/dist/types/index.d.ts +289 -0
  121. package/dist/types/index.d.ts.map +1 -0
  122. package/dist/types/index.js +3 -0
  123. package/dist/types/index.js.map +1 -0
  124. package/docker-compose.yml +27 -0
  125. package/package.json +71 -0
@@ -0,0 +1,162 @@
1
+ import Database from 'better-sqlite3';
2
+ import { mkdirSync } from 'node:fs';
3
+ import { dirname } from 'node:path';
4
+ import { loadConfig } from '../config.js';
5
+ export class SQLiteStore {
6
+ db;
7
+ constructor(dbPath) {
8
+ const path = dbPath ?? loadConfig().sqlitePath;
9
+ mkdirSync(dirname(path), { recursive: true });
10
+ this.db = new Database(path);
11
+ }
12
+ init() {
13
+ this.db.pragma('journal_mode = WAL');
14
+ this.db.pragma('foreign_keys = ON');
15
+ this.db.exec(`
16
+ CREATE TABLE IF NOT EXISTS memories (
17
+ id TEXT PRIMARY KEY,
18
+ content TEXT NOT NULL,
19
+ type TEXT NOT NULL,
20
+ project TEXT,
21
+ tags TEXT,
22
+ entities TEXT,
23
+ source TEXT,
24
+ created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
25
+ updated_at DATETIME DEFAULT CURRENT_TIMESTAMP,
26
+ is_deleted INTEGER DEFAULT 0
27
+ );
28
+
29
+ CREATE INDEX IF NOT EXISTS idx_memories_project ON memories(project);
30
+ CREATE INDEX IF NOT EXISTS idx_memories_type ON memories(type);
31
+ CREATE INDEX IF NOT EXISTS idx_memories_created ON memories(created_at);
32
+
33
+ CREATE TABLE IF NOT EXISTS sessions (
34
+ id TEXT PRIMARY KEY,
35
+ project TEXT,
36
+ started_at DATETIME DEFAULT CURRENT_TIMESTAMP,
37
+ last_active DATETIME,
38
+ tool_calls INTEGER DEFAULT 0
39
+ );
40
+ `);
41
+ // Phase 2: Add new columns (safe to run multiple times)
42
+ this.migratePhase2();
43
+ }
44
+ migratePhase2() {
45
+ // Add new columns if they don't exist
46
+ const columns = this.db.pragma('table_info(memories)');
47
+ const existingColumns = new Set(columns.map(c => c.name));
48
+ if (!existingColumns.has('source_type')) {
49
+ this.db.exec(`ALTER TABLE memories ADD COLUMN source_type TEXT DEFAULT 'manual'`);
50
+ }
51
+ if (!existingColumns.has('consolidated_from')) {
52
+ this.db.exec(`ALTER TABLE memories ADD COLUMN consolidated_from TEXT DEFAULT NULL`);
53
+ }
54
+ if (!existingColumns.has('extraction_confidence')) {
55
+ this.db.exec(`ALTER TABLE memories ADD COLUMN extraction_confidence REAL DEFAULT NULL`);
56
+ }
57
+ if (!existingColumns.has('extraction_tier')) {
58
+ this.db.exec(`ALTER TABLE memories ADD COLUMN extraction_tier INTEGER DEFAULT NULL`);
59
+ }
60
+ // Create consolidation_log table
61
+ this.db.exec(`
62
+ CREATE TABLE IF NOT EXISTS consolidation_log (
63
+ id TEXT PRIMARY KEY,
64
+ action TEXT NOT NULL,
65
+ reason TEXT,
66
+ source_ids TEXT NOT NULL,
67
+ result_id TEXT,
68
+ mode TEXT NOT NULL,
69
+ created_at DATETIME DEFAULT CURRENT_TIMESTAMP
70
+ );
71
+ `);
72
+ }
73
+ insertMemory(memory) {
74
+ const stmt = this.db.prepare(`
75
+ INSERT INTO memories (id, content, type, project, tags, entities, source, created_at, updated_at, is_deleted,
76
+ source_type, consolidated_from, extraction_confidence, extraction_tier)
77
+ VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
78
+ `);
79
+ stmt.run(memory.id, memory.content, memory.type, memory.project, JSON.stringify(memory.tags), JSON.stringify(memory.entities), memory.source, memory.created_at, memory.updated_at, memory.is_deleted, memory.source_type ?? 'manual', memory.consolidated_from ?? null, memory.extraction_confidence ?? null, memory.extraction_tier ?? null);
80
+ }
81
+ getMemory(id) {
82
+ const stmt = this.db.prepare('SELECT * FROM memories WHERE id = ? AND is_deleted = 0');
83
+ const row = stmt.get(id);
84
+ return row ? this.rowToMemory(row) : null;
85
+ }
86
+ getMemoriesByIds(ids) {
87
+ if (ids.length === 0)
88
+ return [];
89
+ const placeholders = ids.map(() => '?').join(',');
90
+ const stmt = this.db.prepare(`SELECT * FROM memories WHERE id IN (${placeholders}) AND is_deleted = 0`);
91
+ const rows = stmt.all(...ids);
92
+ return rows.map(row => this.rowToMemory(row));
93
+ }
94
+ getRecentMemories(project, limit) {
95
+ if (project) {
96
+ const stmt = this.db.prepare('SELECT * FROM memories WHERE project = ? AND is_deleted = 0 ORDER BY created_at DESC LIMIT ?');
97
+ return stmt.all(project, limit).map(row => this.rowToMemory(row));
98
+ }
99
+ const stmt = this.db.prepare('SELECT * FROM memories WHERE is_deleted = 0 ORDER BY created_at DESC LIMIT ?');
100
+ return stmt.all(limit).map(row => this.rowToMemory(row));
101
+ }
102
+ searchByProject(project, limit) {
103
+ const stmt = this.db.prepare('SELECT * FROM memories WHERE project = ? AND is_deleted = 0 ORDER BY created_at DESC LIMIT ?');
104
+ return stmt.all(project, limit).map(row => this.rowToMemory(row));
105
+ }
106
+ softDelete(id) {
107
+ const stmt = this.db.prepare('UPDATE memories SET is_deleted = 1, updated_at = CURRENT_TIMESTAMP WHERE id = ?');
108
+ stmt.run(id);
109
+ }
110
+ deleteByProject(project) {
111
+ const stmt = this.db.prepare('DELETE FROM memories WHERE project = ?');
112
+ stmt.run(project);
113
+ }
114
+ getStats() {
115
+ const memoriesCount = this.db.prepare('SELECT COUNT(*) as count FROM memories WHERE is_deleted = 0').get().count;
116
+ // Count unique entities across all memories
117
+ const rows = this.db.prepare('SELECT entities FROM memories WHERE is_deleted = 0 AND entities IS NOT NULL').all();
118
+ const entitySet = new Set();
119
+ for (const row of rows) {
120
+ try {
121
+ const entities = JSON.parse(row.entities);
122
+ for (const e of entities)
123
+ entitySet.add(e);
124
+ }
125
+ catch { /* skip invalid */ }
126
+ }
127
+ return {
128
+ totalMemories: memoriesCount,
129
+ totalEntities: entitySet.size,
130
+ totalRelationships: 0, // Neo4j tracks relationships; approximation is fine here
131
+ };
132
+ }
133
+ insertConsolidationLog(entry) {
134
+ const stmt = this.db.prepare(`
135
+ INSERT INTO consolidation_log (id, action, reason, source_ids, result_id, mode, created_at)
136
+ VALUES (?, ?, ?, ?, ?, ?, ?)
137
+ `);
138
+ stmt.run(entry.id, entry.action, entry.reason, JSON.stringify(entry.source_ids), entry.result_id, entry.mode, entry.created_at);
139
+ }
140
+ close() {
141
+ this.db.close();
142
+ }
143
+ rowToMemory(row) {
144
+ return {
145
+ id: row.id,
146
+ content: row.content,
147
+ type: row.type,
148
+ project: row.project ?? null,
149
+ tags: JSON.parse(row.tags ?? '[]'),
150
+ entities: JSON.parse(row.entities ?? '[]'),
151
+ source: row.source ?? null,
152
+ created_at: row.created_at,
153
+ updated_at: row.updated_at,
154
+ is_deleted: row.is_deleted,
155
+ source_type: row.source_type ?? null,
156
+ consolidated_from: row.consolidated_from ?? null,
157
+ extraction_confidence: row.extraction_confidence ?? null,
158
+ extraction_tier: row.extraction_tier ?? null,
159
+ };
160
+ }
161
+ }
162
+ //# sourceMappingURL=sqlite.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sqlite.js","sourceRoot":"","sources":["../../src/storage/sqlite.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,11 @@
1
+ /**
2
+ * Claude Code instruction templates for Cortex integration.
3
+ *
4
+ * PROJECT_INSTRUCTIONS — appended to a project's CLAUDE.md
5
+ * GLOBAL_INSTRUCTIONS — written to ~/.claude/CLAUDE.md
6
+ */
7
+ export declare const START_MARKER = "<!-- cortex-instructions-start -->";
8
+ export declare const END_MARKER = "<!-- cortex-instructions-end -->";
9
+ export declare const PROJECT_INSTRUCTIONS = "<!-- cortex-instructions-start -->\n## Memory System (Cortex MCP)\n\nYou have access to a persistent memory system called Cortex, connected via MCP. It stores knowledge across sessions and projects. **Use it proactively without being asked.**\n\n### Automatic behaviours\n\n**At the start of every non-trivial task:**\n1. Call `memory_context` with a description of what you're about to do and the current project name.\n2. Read the returned context. Let it inform your approach \u2014 don't ignore it.\n\n**During work, store memories when you encounter:**\n- An architectural or design decision (type: `decision`) \u2014 include the reasoning, not just the outcome.\n- A bug and its root cause (type: `insight`) \u2014 future you will thank past you.\n- A pattern or convention being used in the project (type: `pattern`).\n- A useful code snippet worth reusing (type: `snippet`).\n- A factual piece of project knowledge (type: `fact`).\n- A gotcha, caveat, or non-obvious behaviour (type: `note`).\n\n**When you discover relationships between components:**\n- Call `memory_relate` to connect entities in the knowledge graph.\n- Use meaningful relation types: `DEPENDS_ON`, `USES`, `PART_OF`, `RELATED_TO`, `IMPLEMENTS`, `CALLS`.\n\n### Available tools\n\n| Tool | When to use |\n|------|-------------|\n| `memory_store` | Store a specific piece of knowledge with type, tags, and entities. |\n| `memory_search` | Find memories by semantic similarity. Use when you need specific past knowledge. |\n| `memory_relate` | Connect two entities with a typed relationship. |\n| `memory_graph_query` | Explore what's connected to an entity in the knowledge graph. |\n| `memory_context` | Get the best available context for a task. Call this at the start of work. |\n| `memory_forget` | Remove outdated or incorrect memories. Requires `confirm: true`. |\n| `memory_ingest` | Process a large block of text (meeting notes, docs) into memories. |\n| `memory_consolidate` | Merge redundant memories. Use `dry_run: true` to preview first. |\n| `memory_config` | Check config, storage health, stats. Set API key at runtime. |\n\n### Extraction tiers\n\nCortex extracts entities using a tiered system that adapts to available resources:\n\n- **Tier 1 (Regex):** Always available. Detects snake_case, camelCase, PascalCase identifiers and basic verb patterns.\n- **Tier 2 (NLP):** Always available. Linguistic analysis with embedding similarity for smarter entity and relationship detection.\n- **Tier 3 (LLM):** Requires Anthropic API key. Full semantic understanding of natural language entity names and complex relationships.\n\nThe active tier is selected automatically. Check it with `memory_config({ action: 'get' })`. To unlock Tier 3, set an API key: `memory_config({ action: 'set', key: 'anthropic_api_key', value: 'sk-ant-...' })`.\n\n### What NOT to store\n\n- Code patterns, conventions, architecture, file paths, or project structure \u2014 these can be derived by reading the current project state.\n- Git history, recent changes, or who-changed-what \u2014 `git log` / `git blame` are authoritative.\n- Debugging solutions or fix recipes \u2014 the fix is in the code; the commit message has the context.\n- Anything already documented in CLAUDE.md files.\n- Ephemeral task details: in-progress work, temporary state, current conversation context.\n\n### Memory search before assumptions\n\nIf you're unsure about a project's conventions, past decisions, or how something works \u2014 search Cortex first (`memory_search`), then check the codebase, then ask the user. In that order.\n\n### Always include\n\n- The `project` parameter \u2014 infer it from the current working directory or ask if unclear.\n- Relevant `entities` as snake_case identifiers when storing memories.\n- Meaningful `tags` for discoverability.\n<!-- cortex-instructions-end -->";
10
+ export declare const GLOBAL_INSTRUCTIONS = "<!-- cortex-instructions-start -->\n## Memory System (Cortex)\n\nYou have access to a persistent memory system called Cortex, connected via MCP. It stores knowledge across sessions and projects. **Use it proactively without being asked.**\n\n### Automatic behaviours\n\n**At the start of every non-trivial task:**\n1. Call `memory_context` with a description of what you're about to do and the current project name.\n2. Read the returned context. Let it inform your approach \u2014 don't ignore it.\n\n**During work, store memories when you encounter:**\n- An architectural or design decision (type: `decision`) \u2014 include the reasoning, not just the outcome.\n- A bug and its root cause (type: `insight`) \u2014 future you will thank past you.\n- A pattern or convention being used in the project (type: `pattern`).\n- A useful code snippet worth reusing (type: `snippet`).\n- A factual piece of project knowledge (type: `fact`).\n- A gotcha, caveat, or non-obvious behaviour (type: `note`).\n\n**When you discover relationships between components:**\n- Call `memory_relate` to connect entities in the knowledge graph.\n- Use meaningful relation types: `DEPENDS_ON`, `USES`, `PART_OF`, `RELATED_TO`, `IMPLEMENTS`, `CALLS`.\n\n### What NOT to store\n- Trivial information (file listed, routine shell commands).\n- Information already in the codebase (don't duplicate what's in README, package.json, etc.).\n- Temporary debugging steps that won't matter tomorrow.\n\n### Always include\n- The `project` parameter \u2014 infer it from the current working directory or ask if unclear.\n- Relevant `entities` as snake_case identifiers.\n- Meaningful `tags` for discoverability.\n\n### Memory search before assumptions\nIf you're unsure about a project's conventions, past decisions, or how something works \u2014 search Cortex first (`memory_search`), then check the codebase, then ask the user. In that order.\n<!-- cortex-instructions-end -->";
11
+ //# sourceMappingURL=claude-instructions.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"claude-instructions.d.ts","sourceRoot":"","sources":["../../src/templates/claude-instructions.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,eAAO,MAAM,YAAY,uCAAuC,CAAC;AACjE,eAAO,MAAM,UAAU,qCAAqC,CAAC;AAE7D,eAAO,MAAM,oBAAoB,+wHAgEnB,CAAC;AAEf,eAAO,MAAM,mBAAmB,65DAmClB,CAAC"}
@@ -0,0 +1,110 @@
1
+ /**
2
+ * Claude Code instruction templates for Cortex integration.
3
+ *
4
+ * PROJECT_INSTRUCTIONS — appended to a project's CLAUDE.md
5
+ * GLOBAL_INSTRUCTIONS — written to ~/.claude/CLAUDE.md
6
+ */
7
+ export const START_MARKER = '<!-- cortex-instructions-start -->';
8
+ export const END_MARKER = '<!-- cortex-instructions-end -->';
9
+ export const PROJECT_INSTRUCTIONS = `${START_MARKER}
10
+ ## Memory System (Cortex MCP)
11
+
12
+ You have access to a persistent memory system called Cortex, connected via MCP. It stores knowledge across sessions and projects. **Use it proactively without being asked.**
13
+
14
+ ### Automatic behaviours
15
+
16
+ **At the start of every non-trivial task:**
17
+ 1. Call \`memory_context\` with a description of what you're about to do and the current project name.
18
+ 2. Read the returned context. Let it inform your approach — don't ignore it.
19
+
20
+ **During work, store memories when you encounter:**
21
+ - An architectural or design decision (type: \`decision\`) — include the reasoning, not just the outcome.
22
+ - A bug and its root cause (type: \`insight\`) — future you will thank past you.
23
+ - A pattern or convention being used in the project (type: \`pattern\`).
24
+ - A useful code snippet worth reusing (type: \`snippet\`).
25
+ - A factual piece of project knowledge (type: \`fact\`).
26
+ - A gotcha, caveat, or non-obvious behaviour (type: \`note\`).
27
+
28
+ **When you discover relationships between components:**
29
+ - Call \`memory_relate\` to connect entities in the knowledge graph.
30
+ - Use meaningful relation types: \`DEPENDS_ON\`, \`USES\`, \`PART_OF\`, \`RELATED_TO\`, \`IMPLEMENTS\`, \`CALLS\`.
31
+
32
+ ### Available tools
33
+
34
+ | Tool | When to use |
35
+ |------|-------------|
36
+ | \`memory_store\` | Store a specific piece of knowledge with type, tags, and entities. |
37
+ | \`memory_search\` | Find memories by semantic similarity. Use when you need specific past knowledge. |
38
+ | \`memory_relate\` | Connect two entities with a typed relationship. |
39
+ | \`memory_graph_query\` | Explore what's connected to an entity in the knowledge graph. |
40
+ | \`memory_context\` | Get the best available context for a task. Call this at the start of work. |
41
+ | \`memory_forget\` | Remove outdated or incorrect memories. Requires \`confirm: true\`. |
42
+ | \`memory_ingest\` | Process a large block of text (meeting notes, docs) into memories. |
43
+ | \`memory_consolidate\` | Merge redundant memories. Use \`dry_run: true\` to preview first. |
44
+ | \`memory_config\` | Check config, storage health, stats. Set API key at runtime. |
45
+
46
+ ### Extraction tiers
47
+
48
+ Cortex extracts entities using a tiered system that adapts to available resources:
49
+
50
+ - **Tier 1 (Regex):** Always available. Detects snake_case, camelCase, PascalCase identifiers and basic verb patterns.
51
+ - **Tier 2 (NLP):** Always available. Linguistic analysis with embedding similarity for smarter entity and relationship detection.
52
+ - **Tier 3 (LLM):** Requires Anthropic API key. Full semantic understanding of natural language entity names and complex relationships.
53
+
54
+ The active tier is selected automatically. Check it with \`memory_config({ action: 'get' })\`. To unlock Tier 3, set an API key: \`memory_config({ action: 'set', key: 'anthropic_api_key', value: 'sk-ant-...' })\`.
55
+
56
+ ### What NOT to store
57
+
58
+ - Code patterns, conventions, architecture, file paths, or project structure — these can be derived by reading the current project state.
59
+ - Git history, recent changes, or who-changed-what — \`git log\` / \`git blame\` are authoritative.
60
+ - Debugging solutions or fix recipes — the fix is in the code; the commit message has the context.
61
+ - Anything already documented in CLAUDE.md files.
62
+ - Ephemeral task details: in-progress work, temporary state, current conversation context.
63
+
64
+ ### Memory search before assumptions
65
+
66
+ If you're unsure about a project's conventions, past decisions, or how something works — search Cortex first (\`memory_search\`), then check the codebase, then ask the user. In that order.
67
+
68
+ ### Always include
69
+
70
+ - The \`project\` parameter — infer it from the current working directory or ask if unclear.
71
+ - Relevant \`entities\` as snake_case identifiers when storing memories.
72
+ - Meaningful \`tags\` for discoverability.
73
+ ${END_MARKER}`;
74
+ export const GLOBAL_INSTRUCTIONS = `${START_MARKER}
75
+ ## Memory System (Cortex)
76
+
77
+ You have access to a persistent memory system called Cortex, connected via MCP. It stores knowledge across sessions and projects. **Use it proactively without being asked.**
78
+
79
+ ### Automatic behaviours
80
+
81
+ **At the start of every non-trivial task:**
82
+ 1. Call \`memory_context\` with a description of what you're about to do and the current project name.
83
+ 2. Read the returned context. Let it inform your approach — don't ignore it.
84
+
85
+ **During work, store memories when you encounter:**
86
+ - An architectural or design decision (type: \`decision\`) — include the reasoning, not just the outcome.
87
+ - A bug and its root cause (type: \`insight\`) — future you will thank past you.
88
+ - A pattern or convention being used in the project (type: \`pattern\`).
89
+ - A useful code snippet worth reusing (type: \`snippet\`).
90
+ - A factual piece of project knowledge (type: \`fact\`).
91
+ - A gotcha, caveat, or non-obvious behaviour (type: \`note\`).
92
+
93
+ **When you discover relationships between components:**
94
+ - Call \`memory_relate\` to connect entities in the knowledge graph.
95
+ - Use meaningful relation types: \`DEPENDS_ON\`, \`USES\`, \`PART_OF\`, \`RELATED_TO\`, \`IMPLEMENTS\`, \`CALLS\`.
96
+
97
+ ### What NOT to store
98
+ - Trivial information (file listed, routine shell commands).
99
+ - Information already in the codebase (don't duplicate what's in README, package.json, etc.).
100
+ - Temporary debugging steps that won't matter tomorrow.
101
+
102
+ ### Always include
103
+ - The \`project\` parameter — infer it from the current working directory or ask if unclear.
104
+ - Relevant \`entities\` as snake_case identifiers.
105
+ - Meaningful \`tags\` for discoverability.
106
+
107
+ ### Memory search before assumptions
108
+ If you're unsure about a project's conventions, past decisions, or how something works — search Cortex first (\`memory_search\`), then check the codebase, then ask the user. In that order.
109
+ ${END_MARKER}`;
110
+ //# sourceMappingURL=claude-instructions.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"claude-instructions.js","sourceRoot":"","sources":["../../src/templates/claude-instructions.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,MAAM,CAAC,MAAM,YAAY,GAAG,oCAAoC,CAAC;AACjE,MAAM,CAAC,MAAM,UAAU,GAAG,kCAAkC,CAAC;AAE7D,MAAM,CAAC,MAAM,oBAAoB,GAAG,GAAG,YAAY;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAgEjD,UAAU,EAAE,CAAC;AAEf,MAAM,CAAC,MAAM,mBAAmB,GAAG,GAAG,YAAY;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAmChD,UAAU,EAAE,CAAC"}
@@ -0,0 +1,21 @@
1
+ import type { MemoryConfigInput, MemoryConfigOutput } from '../types/index.js';
2
+ import type { RuntimeConfigStore } from '../config-store.js';
3
+ import type { AnthropicClient } from '../llm/anthropic-client.js';
4
+ import type { EntityExtractor } from '../extraction/extractor.js';
5
+ import type { SQLiteStore } from '../storage/sqlite.js';
6
+ import type { QdrantStore } from '../storage/qdrant.js';
7
+ import type { Neo4jStore } from '../storage/neo4j.js';
8
+ import type { Consolidator } from '../consolidation/consolidator.js';
9
+ import type { CortexConfig } from '../config.js';
10
+ export interface ConfigToolDeps {
11
+ configStore: RuntimeConfigStore;
12
+ llmClient: AnthropicClient;
13
+ extractor: EntityExtractor;
14
+ sqlite: SQLiteStore;
15
+ qdrant: QdrantStore;
16
+ neo4j: Neo4jStore;
17
+ consolidator: Consolidator | null;
18
+ baseConfig: CortexConfig;
19
+ }
20
+ export declare function handleMemoryConfig(args: MemoryConfigInput, deps: ConfigToolDeps): Promise<MemoryConfigOutput>;
21
+ //# sourceMappingURL=config.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../src/tools/config.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAE,kBAAkB,EAAkB,MAAM,mBAAmB,CAAC;AAC/F,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,oBAAoB,CAAC;AAC7D,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,4BAA4B,CAAC;AAClE,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,4BAA4B,CAAC;AAClE,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,sBAAsB,CAAC;AACxD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,sBAAsB,CAAC;AACxD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAC;AACtD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,kCAAkC,CAAC;AACrE,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAEjD,MAAM,WAAW,cAAc;IAC7B,WAAW,EAAE,kBAAkB,CAAC;IAChC,SAAS,EAAE,eAAe,CAAC;IAC3B,SAAS,EAAE,eAAe,CAAC;IAC3B,MAAM,EAAE,WAAW,CAAC;IACpB,MAAM,EAAE,WAAW,CAAC;IACpB,KAAK,EAAE,UAAU,CAAC;IAClB,YAAY,EAAE,YAAY,GAAG,IAAI,CAAC;IAClC,UAAU,EAAE,YAAY,CAAC;CAC1B;AAED,wBAAsB,kBAAkB,CACtC,IAAI,EAAE,iBAAiB,EACvB,IAAI,EAAE,cAAc,GACnB,OAAO,CAAC,kBAAkB,CAAC,CAgB7B"}
@@ -0,0 +1,96 @@
1
+ export async function handleMemoryConfig(args, deps) {
2
+ if (args.action === 'get') {
3
+ return getConfig(deps);
4
+ }
5
+ if (args.action === 'set') {
6
+ if (!args.key || args.value === undefined) {
7
+ return {
8
+ config: null,
9
+ error: 'Both key and value are required for set action',
10
+ };
11
+ }
12
+ return setConfig(args.key, args.value, deps);
13
+ }
14
+ return { config: null, error: `Unknown action: ${args.action}` };
15
+ }
16
+ async function getConfig(deps) {
17
+ const { llmClient, extractor, sqlite, qdrant, neo4j, baseConfig } = deps;
18
+ // Check storage connectivity
19
+ let qdrantStatus = 'disconnected';
20
+ let neo4jStatus = 'disconnected';
21
+ try {
22
+ if (await qdrant.healthCheck())
23
+ qdrantStatus = 'connected';
24
+ }
25
+ catch { /* disconnected */ }
26
+ try {
27
+ if (await neo4j.healthCheck())
28
+ neo4jStatus = 'connected';
29
+ }
30
+ catch { /* disconnected */ }
31
+ // Get stats
32
+ const stats = sqlite.getStats();
33
+ const usage = llmClient.getUsage();
34
+ return {
35
+ config: {
36
+ llm_available: llmClient.isAvailable(),
37
+ llm_model: llmClient.isAvailable() ? llmClient.getModel() : null,
38
+ extraction_tier: baseConfig.extractionTier,
39
+ active_extraction_tier: extractor.getActiveTier(),
40
+ auto_extract: baseConfig.autoExtract,
41
+ consolidation_enabled: baseConfig.consolidationEnabled,
42
+ consolidation_interval_ms: baseConfig.consolidationIntervalMs,
43
+ storage: {
44
+ qdrant: qdrantStatus,
45
+ neo4j: neo4jStatus,
46
+ sqlite: 'connected',
47
+ },
48
+ stats: {
49
+ total_memories: stats.totalMemories,
50
+ total_entities: stats.totalEntities,
51
+ total_relationships: stats.totalRelationships,
52
+ llm_tokens_used: { input: usage.inputTokens, output: usage.outputTokens },
53
+ },
54
+ },
55
+ };
56
+ }
57
+ async function setConfig(key, value, deps) {
58
+ const { configStore, llmClient, extractor, consolidator } = deps;
59
+ if (!configStore.isSettable(key)) {
60
+ return {
61
+ config: null,
62
+ error: `Key "${key}" is not settable at runtime`,
63
+ };
64
+ }
65
+ // Special handling for API key
66
+ if (key === 'anthropic_api_key') {
67
+ const valid = await llmClient.setApiKey(value);
68
+ if (!valid) {
69
+ return {
70
+ config: null,
71
+ error: 'Invalid API key — validation failed',
72
+ };
73
+ }
74
+ }
75
+ // Special handling for extraction tier
76
+ if (key === 'extraction_tier') {
77
+ const validTiers = ['auto', 'local-only', 'llm-preferred'];
78
+ if (!validTiers.includes(value)) {
79
+ return {
80
+ config: null,
81
+ error: `Invalid extraction tier. Must be one of: ${validTiers.join(', ')}`,
82
+ };
83
+ }
84
+ extractor.setExtractionTier(value);
85
+ }
86
+ const result = configStore.set(key, value);
87
+ return {
88
+ config: null,
89
+ updated: {
90
+ key,
91
+ previous: result.previous,
92
+ current: result.current,
93
+ },
94
+ };
95
+ }
96
+ //# sourceMappingURL=config.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.js","sourceRoot":"","sources":["../../src/tools/config.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,4 @@
1
+ import type { MemoryConsolidateInput, MemoryConsolidateOutput } from '../types/index.js';
2
+ import type { Consolidator } from '../consolidation/consolidator.js';
3
+ export declare function handleMemoryConsolidate(args: MemoryConsolidateInput, consolidator: Consolidator): Promise<MemoryConsolidateOutput>;
4
+ //# sourceMappingURL=consolidate.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"consolidate.d.ts","sourceRoot":"","sources":["../../src/tools/consolidate.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,sBAAsB,EAAE,uBAAuB,EAAE,MAAM,mBAAmB,CAAC;AACzF,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,kCAAkC,CAAC;AAErE,wBAAsB,uBAAuB,CAC3C,IAAI,EAAE,sBAAsB,EAC5B,YAAY,EAAE,YAAY,GACzB,OAAO,CAAC,uBAAuB,CAAC,CAgBlC"}
@@ -0,0 +1,16 @@
1
+ export async function handleMemoryConsolidate(args, consolidator) {
2
+ const maxClusters = args.max_clusters ?? 10;
3
+ const dryRun = args.dry_run ?? false;
4
+ const result = await consolidator.run(args.project, maxClusters, dryRun);
5
+ return {
6
+ merged: result.merged,
7
+ archived: result.archived,
8
+ contradictions: result.contradictions,
9
+ flagged: result.flagged,
10
+ unchanged: result.unchanged,
11
+ duration_ms: result.duration_ms,
12
+ mode: result.mode,
13
+ ...(dryRun && result.details ? { details: result.details } : {}),
14
+ };
15
+ }
16
+ //# sourceMappingURL=consolidate.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"consolidate.js","sourceRoot":"","sources":["../../src/tools/consolidate.ts"],"names":[],"mappings":"AAGA,MAAM,CAAC,KAAK,UAAU,uBAAuB,CAC3C,IAA4B,EAC5B,YAA0B;IAE1B,MAAM,WAAW,GAAG,IAAI,CAAC,YAAY,IAAI,EAAE,CAAC;IAC5C,MAAM,MAAM,GAAG,IAAI,CAAC,OAAO,IAAI,KAAK,CAAC;IAErC,MAAM,MAAM,GAAG,MAAM,YAAY,CAAC,GAAG,CAAC,IAAI,CAAC,OAAO,EAAE,WAAW,EAAE,MAAM,CAAC,CAAC;IAEzE,OAAO;QACL,MAAM,EAAE,MAAM,CAAC,MAAM;QACrB,QAAQ,EAAE,MAAM,CAAC,QAAQ;QACzB,cAAc,EAAE,MAAM,CAAC,cAAc;QACrC,OAAO,EAAE,MAAM,CAAC,OAAO;QACvB,SAAS,EAAE,MAAM,CAAC,SAAS;QAC3B,WAAW,EAAE,MAAM,CAAC,WAAW;QAC/B,IAAI,EAAE,MAAM,CAAC,IAAI;QACjB,GAAG,CAAC,MAAM,IAAI,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,MAAM,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;KACjE,CAAC;AACJ,CAAC"}
@@ -0,0 +1,8 @@
1
+ import type { MemoryContextInput, MemoryContextOutput } from '../types/index.js';
2
+ import type { Embedder } from '../embedding/embedder.js';
3
+ import type { SQLiteStore } from '../storage/sqlite.js';
4
+ import type { QdrantStore } from '../storage/qdrant.js';
5
+ import type { Neo4jStore } from '../storage/neo4j.js';
6
+ import type { EntityExtractor } from '../extraction/extractor.js';
7
+ export declare function handleMemoryContext(args: MemoryContextInput, embedder: Embedder, sqlite: SQLiteStore, qdrant: QdrantStore, neo4j: Neo4jStore, currentProject?: string, extractor?: EntityExtractor): Promise<MemoryContextOutput>;
8
+ //# sourceMappingURL=context.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"context.d.ts","sourceRoot":"","sources":["../../src/tools/context.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,kBAAkB,EAAE,mBAAmB,EAAE,MAAM,mBAAmB,CAAC;AACjF,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,0BAA0B,CAAC;AACzD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,sBAAsB,CAAC;AACxD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,sBAAsB,CAAC;AACxD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAC;AACtD,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,4BAA4B,CAAC;AAGlE,wBAAsB,mBAAmB,CACvC,IAAI,EAAE,kBAAkB,EACxB,QAAQ,EAAE,QAAQ,EAClB,MAAM,EAAE,WAAW,EACnB,MAAM,EAAE,WAAW,EACnB,KAAK,EAAE,UAAU,EACjB,cAAc,CAAC,EAAE,MAAM,EACvB,SAAS,CAAC,EAAE,eAAe,GAC1B,OAAO,CAAC,mBAAmB,CAAC,CA4E9B"}
@@ -0,0 +1,84 @@
1
+ import { mergeAndRank, formatContext } from '../orchestration/ranker.js';
2
+ export async function handleMemoryContext(args, embedder, sqlite, qdrant, neo4j, currentProject, extractor) {
3
+ const project = args.project ?? currentProject ?? null;
4
+ const maxTokens = args.max_tokens ?? 2000;
5
+ // 1. Semantic search (Tier 1)
6
+ const vector = await embedder.embed(args.description);
7
+ const semanticResults = await qdrant.search(vector, undefined, 20);
8
+ // Enrich semantic results with content from SQLite
9
+ const semanticIds = semanticResults.map(r => r.id);
10
+ const semanticMemories = sqlite.getMemoriesByIds(semanticIds);
11
+ const memMap = new Map(semanticMemories.map(m => [m.id, m]));
12
+ for (const r of semanticResults) {
13
+ const mem = memMap.get(r.id);
14
+ if (mem) {
15
+ r.content = mem.content;
16
+ }
17
+ }
18
+ // 2. Graph traversal (Tier 2) — use tiered extractor if available, else regex fallback
19
+ let entityNames;
20
+ if (extractor) {
21
+ const extraction = await extractor.extract(args.description, project ?? undefined);
22
+ entityNames = extraction.entities.map(e => e.name);
23
+ }
24
+ else {
25
+ entityNames = extractEntityNamesLegacy(args.description);
26
+ }
27
+ const graphMemories = [];
28
+ const seenGraphIds = new Set();
29
+ for (const entityName of entityNames) {
30
+ try {
31
+ const graphResult = await neo4j.traverse(entityName, 2);
32
+ const allEntities = new Set([entityName, ...graphResult.connections.map(c => c.entity)]);
33
+ for (const eName of allEntities) {
34
+ const memIds = await neo4j.findMemoriesByEntity(eName);
35
+ for (const memId of memIds) {
36
+ if (seenGraphIds.has(memId))
37
+ continue;
38
+ seenGraphIds.add(memId);
39
+ const mem = sqlite.getMemory(memId);
40
+ if (mem) {
41
+ graphMemories.push({ id: mem.id, content: mem.content, score: 0.7 });
42
+ }
43
+ }
44
+ }
45
+ }
46
+ catch {
47
+ // Entity doesn't exist in graph — that's fine
48
+ }
49
+ }
50
+ // 3. Recent memories (Tier 3)
51
+ const recentMemories = sqlite.getRecentMemories(project, 10);
52
+ // 4. Merge, rank, deduplicate
53
+ const { ranked } = mergeAndRank(semanticResults, graphMemories, recentMemories, project, undefined, maxTokens);
54
+ // 5. Format as context block
55
+ const context = formatContext(ranked);
56
+ // 6. Build sources list
57
+ const sources = ranked.map(r => ({
58
+ id: r.id,
59
+ type: r.sourceType,
60
+ score: r.score,
61
+ }));
62
+ return { context, sources };
63
+ }
64
+ /**
65
+ * Legacy entity name extraction (fallback when extractor not available).
66
+ */
67
+ function extractEntityNamesLegacy(description) {
68
+ const patterns = [
69
+ /[a-z][a-z0-9]*(?:_[a-z0-9]+)+/g,
70
+ /[a-z]+(?:[A-Z][a-z0-9]+)+/g,
71
+ /[A-Z][a-z0-9]+(?:[A-Z][a-z0-9]+)+/g,
72
+ ];
73
+ const entities = new Set();
74
+ for (const pattern of patterns) {
75
+ const matches = description.match(pattern);
76
+ if (matches) {
77
+ for (const m of matches) {
78
+ entities.add(m);
79
+ }
80
+ }
81
+ }
82
+ return Array.from(entities);
83
+ }
84
+ //# sourceMappingURL=context.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"context.js","sourceRoot":"","sources":["../../src/tools/context.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,7 @@
1
+ import type { MemoryForgetInput, MemoryForgetOutput } from '../types/index.js';
2
+ import type { Embedder } from '../embedding/embedder.js';
3
+ import type { SQLiteStore } from '../storage/sqlite.js';
4
+ import type { QdrantStore } from '../storage/qdrant.js';
5
+ import type { Neo4jStore } from '../storage/neo4j.js';
6
+ export declare function handleMemoryForget(args: MemoryForgetInput, embedder: Embedder, sqlite: SQLiteStore, qdrant: QdrantStore, neo4j: Neo4jStore): Promise<MemoryForgetOutput>;
7
+ //# sourceMappingURL=forget.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"forget.d.ts","sourceRoot":"","sources":["../../src/tools/forget.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAE,kBAAkB,EAAE,MAAM,mBAAmB,CAAC;AAC/E,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,0BAA0B,CAAC;AACzD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,sBAAsB,CAAC;AACxD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,sBAAsB,CAAC;AACxD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAC;AAEtD,wBAAsB,kBAAkB,CACtC,IAAI,EAAE,iBAAiB,EACvB,QAAQ,EAAE,QAAQ,EAClB,MAAM,EAAE,WAAW,EACnB,MAAM,EAAE,WAAW,EACnB,KAAK,EAAE,UAAU,GAChB,OAAO,CAAC,kBAAkB,CAAC,CAmD7B"}
@@ -0,0 +1,49 @@
1
+ export async function handleMemoryForget(args, embedder, sqlite, qdrant, neo4j) {
2
+ // Must provide either id or query
3
+ if (!args.id && !args.query) {
4
+ throw new Error('Either id or query must be provided');
5
+ }
6
+ let idsToDelete = [];
7
+ if (args.id) {
8
+ // Direct deletion by ID — always attempt cleanup across all stores,
9
+ // even if SQLite doesn't have the record (handles orphaned entries)
10
+ idsToDelete = [args.id];
11
+ }
12
+ else if (args.query) {
13
+ // Search for matching memories
14
+ const vector = await embedder.embed(args.query);
15
+ const results = await qdrant.search(vector, undefined, 5);
16
+ idsToDelete = results.map(r => r.id);
17
+ }
18
+ // Safety guard: require explicit confirmation before any deletion
19
+ if (!args.confirm) {
20
+ return {
21
+ forgotten: idsToDelete,
22
+ count: idsToDelete.length,
23
+ };
24
+ }
25
+ // Actually delete from all stores
26
+ for (const id of idsToDelete) {
27
+ // Soft delete in SQLite
28
+ sqlite.softDelete(id);
29
+ // Delete from Qdrant
30
+ try {
31
+ await qdrant.delete(id);
32
+ }
33
+ catch (error) {
34
+ console.error(`[cortex] Failed to delete ${id} from Qdrant: ${error}`);
35
+ }
36
+ // Unlink from Neo4j (don't delete orphaned entities)
37
+ try {
38
+ await neo4j.unlinkMemory(id);
39
+ }
40
+ catch (error) {
41
+ console.error(`[cortex] Failed to unlink ${id} from Neo4j: ${error}`);
42
+ }
43
+ }
44
+ return {
45
+ forgotten: idsToDelete,
46
+ count: idsToDelete.length,
47
+ };
48
+ }
49
+ //# sourceMappingURL=forget.js.map