@danielsimonjr/memory-mcp 0.48.0 → 9.8.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 (209) hide show
  1. package/LICENSE +22 -0
  2. package/README.md +2000 -194
  3. package/dist/__tests__/file-path.test.js +7 -11
  4. package/dist/__tests__/knowledge-graph.test.js +3 -8
  5. package/dist/core/EntityManager.d.ts +266 -0
  6. package/dist/core/EntityManager.d.ts.map +1 -0
  7. package/dist/core/EntityManager.js +85 -133
  8. package/dist/core/GraphEventEmitter.d.ts +202 -0
  9. package/dist/core/GraphEventEmitter.d.ts.map +1 -0
  10. package/dist/core/GraphEventEmitter.js +346 -0
  11. package/dist/core/GraphStorage.d.ts +395 -0
  12. package/dist/core/GraphStorage.d.ts.map +1 -0
  13. package/dist/core/GraphStorage.js +643 -31
  14. package/dist/core/GraphTraversal.d.ts +141 -0
  15. package/dist/core/GraphTraversal.d.ts.map +1 -0
  16. package/dist/core/GraphTraversal.js +573 -0
  17. package/dist/core/HierarchyManager.d.ts +111 -0
  18. package/dist/core/HierarchyManager.d.ts.map +1 -0
  19. package/dist/{features → core}/HierarchyManager.js +14 -9
  20. package/dist/core/ManagerContext.d.ts +72 -0
  21. package/dist/core/ManagerContext.d.ts.map +1 -0
  22. package/dist/core/ManagerContext.js +118 -0
  23. package/dist/core/ObservationManager.d.ts +85 -0
  24. package/dist/core/ObservationManager.d.ts.map +1 -0
  25. package/dist/core/ObservationManager.js +51 -57
  26. package/dist/core/RelationManager.d.ts +131 -0
  27. package/dist/core/RelationManager.d.ts.map +1 -0
  28. package/dist/core/RelationManager.js +31 -7
  29. package/dist/core/SQLiteStorage.d.ts +354 -0
  30. package/dist/core/SQLiteStorage.d.ts.map +1 -0
  31. package/dist/core/SQLiteStorage.js +917 -0
  32. package/dist/core/StorageFactory.d.ts +45 -0
  33. package/dist/core/StorageFactory.d.ts.map +1 -0
  34. package/dist/core/StorageFactory.js +64 -0
  35. package/dist/core/TransactionManager.d.ts +464 -0
  36. package/dist/core/TransactionManager.d.ts.map +1 -0
  37. package/dist/core/TransactionManager.js +490 -13
  38. package/dist/core/index.d.ts +17 -0
  39. package/dist/core/index.d.ts.map +1 -0
  40. package/dist/core/index.js +12 -2
  41. package/dist/features/AnalyticsManager.d.ts +44 -0
  42. package/dist/features/AnalyticsManager.d.ts.map +1 -0
  43. package/dist/features/AnalyticsManager.js +3 -2
  44. package/dist/features/ArchiveManager.d.ts +133 -0
  45. package/dist/features/ArchiveManager.d.ts.map +1 -0
  46. package/dist/features/ArchiveManager.js +221 -14
  47. package/dist/features/CompressionManager.d.ts +117 -0
  48. package/dist/features/CompressionManager.d.ts.map +1 -0
  49. package/dist/features/CompressionManager.js +189 -20
  50. package/dist/features/IOManager.d.ts +225 -0
  51. package/dist/features/IOManager.d.ts.map +1 -0
  52. package/dist/features/IOManager.js +1041 -0
  53. package/dist/features/StreamingExporter.d.ts +123 -0
  54. package/dist/features/StreamingExporter.d.ts.map +1 -0
  55. package/dist/features/StreamingExporter.js +203 -0
  56. package/dist/features/TagManager.d.ts +147 -0
  57. package/dist/features/TagManager.d.ts.map +1 -0
  58. package/dist/features/index.d.ts +12 -0
  59. package/dist/features/index.d.ts.map +1 -0
  60. package/dist/features/index.js +5 -6
  61. package/dist/index.d.ts +9 -0
  62. package/dist/index.d.ts.map +1 -0
  63. package/dist/index.js +10 -10
  64. package/dist/memory.jsonl +1 -26
  65. package/dist/search/BasicSearch.d.ts +51 -0
  66. package/dist/search/BasicSearch.d.ts.map +1 -0
  67. package/dist/search/BasicSearch.js +9 -3
  68. package/dist/search/BooleanSearch.d.ts +98 -0
  69. package/dist/search/BooleanSearch.d.ts.map +1 -0
  70. package/dist/search/BooleanSearch.js +156 -9
  71. package/dist/search/EmbeddingService.d.ts +178 -0
  72. package/dist/search/EmbeddingService.d.ts.map +1 -0
  73. package/dist/search/EmbeddingService.js +358 -0
  74. package/dist/search/FuzzySearch.d.ts +118 -0
  75. package/dist/search/FuzzySearch.d.ts.map +1 -0
  76. package/dist/search/FuzzySearch.js +241 -25
  77. package/dist/search/QueryCostEstimator.d.ts +111 -0
  78. package/dist/search/QueryCostEstimator.d.ts.map +1 -0
  79. package/dist/search/QueryCostEstimator.js +355 -0
  80. package/dist/search/RankedSearch.d.ts +71 -0
  81. package/dist/search/RankedSearch.d.ts.map +1 -0
  82. package/dist/search/RankedSearch.js +54 -6
  83. package/dist/search/SavedSearchManager.d.ts +79 -0
  84. package/dist/search/SavedSearchManager.d.ts.map +1 -0
  85. package/dist/search/SearchFilterChain.d.ts +120 -0
  86. package/dist/search/SearchFilterChain.d.ts.map +1 -0
  87. package/dist/search/SearchFilterChain.js +2 -4
  88. package/dist/search/SearchManager.d.ts +326 -0
  89. package/dist/search/SearchManager.d.ts.map +1 -0
  90. package/dist/search/SearchManager.js +148 -0
  91. package/dist/search/SearchSuggestions.d.ts +27 -0
  92. package/dist/search/SearchSuggestions.d.ts.map +1 -0
  93. package/dist/search/SearchSuggestions.js +1 -1
  94. package/dist/search/SemanticSearch.d.ts +149 -0
  95. package/dist/search/SemanticSearch.d.ts.map +1 -0
  96. package/dist/search/SemanticSearch.js +323 -0
  97. package/dist/search/TFIDFEventSync.d.ts +85 -0
  98. package/dist/search/TFIDFEventSync.d.ts.map +1 -0
  99. package/dist/search/TFIDFEventSync.js +133 -0
  100. package/dist/search/TFIDFIndexManager.d.ts +151 -0
  101. package/dist/search/TFIDFIndexManager.d.ts.map +1 -0
  102. package/dist/search/TFIDFIndexManager.js +232 -17
  103. package/dist/search/VectorStore.d.ts +235 -0
  104. package/dist/search/VectorStore.d.ts.map +1 -0
  105. package/dist/search/VectorStore.js +311 -0
  106. package/dist/search/index.d.ts +21 -0
  107. package/dist/search/index.d.ts.map +1 -0
  108. package/dist/search/index.js +12 -0
  109. package/dist/server/MCPServer.d.ts +21 -0
  110. package/dist/server/MCPServer.d.ts.map +1 -0
  111. package/dist/server/MCPServer.js +4 -4
  112. package/dist/server/responseCompressor.d.ts +94 -0
  113. package/dist/server/responseCompressor.d.ts.map +1 -0
  114. package/dist/server/responseCompressor.js +127 -0
  115. package/dist/server/toolDefinitions.d.ts +27 -0
  116. package/dist/server/toolDefinitions.d.ts.map +1 -0
  117. package/dist/server/toolDefinitions.js +188 -17
  118. package/dist/server/toolHandlers.d.ts +41 -0
  119. package/dist/server/toolHandlers.d.ts.map +1 -0
  120. package/dist/server/toolHandlers.js +467 -75
  121. package/dist/types/index.d.ts +13 -0
  122. package/dist/types/index.d.ts.map +1 -0
  123. package/dist/types/index.js +1 -1
  124. package/dist/types/types.d.ts +1654 -0
  125. package/dist/types/types.d.ts.map +1 -0
  126. package/dist/types/types.js +9 -0
  127. package/dist/utils/compressedCache.d.ts +192 -0
  128. package/dist/utils/compressedCache.d.ts.map +1 -0
  129. package/dist/utils/compressedCache.js +309 -0
  130. package/dist/utils/compressionUtil.d.ts +214 -0
  131. package/dist/utils/compressionUtil.d.ts.map +1 -0
  132. package/dist/utils/compressionUtil.js +247 -0
  133. package/dist/utils/constants.d.ts +245 -0
  134. package/dist/utils/constants.d.ts.map +1 -0
  135. package/dist/utils/constants.js +124 -0
  136. package/dist/utils/entityUtils.d.ts +321 -0
  137. package/dist/utils/entityUtils.d.ts.map +1 -0
  138. package/dist/utils/entityUtils.js +434 -4
  139. package/dist/utils/errors.d.ts +95 -0
  140. package/dist/utils/errors.d.ts.map +1 -0
  141. package/dist/utils/errors.js +24 -0
  142. package/dist/utils/formatters.d.ts +145 -0
  143. package/dist/utils/formatters.d.ts.map +1 -0
  144. package/dist/utils/{paginationUtils.js → formatters.js} +54 -3
  145. package/dist/utils/index.d.ts +23 -0
  146. package/dist/utils/index.d.ts.map +1 -0
  147. package/dist/utils/index.js +69 -31
  148. package/dist/utils/indexes.d.ts +270 -0
  149. package/dist/utils/indexes.d.ts.map +1 -0
  150. package/dist/utils/indexes.js +526 -0
  151. package/dist/utils/logger.d.ts +24 -0
  152. package/dist/utils/logger.d.ts.map +1 -0
  153. package/dist/utils/operationUtils.d.ts +124 -0
  154. package/dist/utils/operationUtils.d.ts.map +1 -0
  155. package/dist/utils/operationUtils.js +175 -0
  156. package/dist/utils/parallelUtils.d.ts +72 -0
  157. package/dist/utils/parallelUtils.d.ts.map +1 -0
  158. package/dist/utils/parallelUtils.js +169 -0
  159. package/dist/utils/schemas.d.ts +374 -0
  160. package/dist/utils/schemas.d.ts.map +1 -0
  161. package/dist/utils/schemas.js +302 -2
  162. package/dist/utils/searchAlgorithms.d.ts +99 -0
  163. package/dist/utils/searchAlgorithms.d.ts.map +1 -0
  164. package/dist/utils/searchAlgorithms.js +167 -0
  165. package/dist/utils/searchCache.d.ts +108 -0
  166. package/dist/utils/searchCache.d.ts.map +1 -0
  167. package/dist/utils/taskScheduler.d.ts +290 -0
  168. package/dist/utils/taskScheduler.d.ts.map +1 -0
  169. package/dist/utils/taskScheduler.js +466 -0
  170. package/dist/workers/index.d.ts +12 -0
  171. package/dist/workers/index.d.ts.map +1 -0
  172. package/dist/workers/index.js +9 -0
  173. package/dist/workers/levenshteinWorker.d.ts +60 -0
  174. package/dist/workers/levenshteinWorker.d.ts.map +1 -0
  175. package/dist/workers/levenshteinWorker.js +98 -0
  176. package/package.json +17 -4
  177. package/dist/__tests__/edge-cases/edge-cases.test.js +0 -406
  178. package/dist/__tests__/integration/workflows.test.js +0 -449
  179. package/dist/__tests__/performance/benchmarks.test.js +0 -413
  180. package/dist/__tests__/unit/core/EntityManager.test.js +0 -334
  181. package/dist/__tests__/unit/core/GraphStorage.test.js +0 -205
  182. package/dist/__tests__/unit/core/RelationManager.test.js +0 -274
  183. package/dist/__tests__/unit/features/CompressionManager.test.js +0 -350
  184. package/dist/__tests__/unit/search/BasicSearch.test.js +0 -311
  185. package/dist/__tests__/unit/search/BooleanSearch.test.js +0 -432
  186. package/dist/__tests__/unit/search/FuzzySearch.test.js +0 -448
  187. package/dist/__tests__/unit/search/RankedSearch.test.js +0 -379
  188. package/dist/__tests__/unit/utils/levenshtein.test.js +0 -77
  189. package/dist/core/KnowledgeGraphManager.js +0 -423
  190. package/dist/features/BackupManager.js +0 -311
  191. package/dist/features/ExportManager.js +0 -305
  192. package/dist/features/ImportExportManager.js +0 -50
  193. package/dist/features/ImportManager.js +0 -328
  194. package/dist/memory-saved-searches.jsonl +0 -0
  195. package/dist/memory-tag-aliases.jsonl +0 -0
  196. package/dist/types/analytics.types.js +0 -6
  197. package/dist/types/entity.types.js +0 -7
  198. package/dist/types/import-export.types.js +0 -7
  199. package/dist/types/search.types.js +0 -7
  200. package/dist/types/tag.types.js +0 -6
  201. package/dist/utils/dateUtils.js +0 -89
  202. package/dist/utils/filterUtils.js +0 -155
  203. package/dist/utils/levenshtein.js +0 -62
  204. package/dist/utils/pathUtils.js +0 -115
  205. package/dist/utils/responseFormatter.js +0 -55
  206. package/dist/utils/tagUtils.js +0 -107
  207. package/dist/utils/tfidf.js +0 -90
  208. package/dist/utils/validationHelper.js +0 -99
  209. package/dist/utils/validationUtils.js +0 -109
@@ -1,328 +0,0 @@
1
- /**
2
- * Import Manager
3
- *
4
- * Imports knowledge graphs from various formats (JSON, CSV, GraphML) with merge strategies.
5
- *
6
- * @module features/ImportManager
7
- */
8
- /**
9
- * Manages knowledge graph imports from multiple formats.
10
- */
11
- export class ImportManager {
12
- storage;
13
- constructor(storage) {
14
- this.storage = storage;
15
- }
16
- /**
17
- * Import graph from formatted data.
18
- *
19
- * @param format - Import format
20
- * @param data - Import data string
21
- * @param mergeStrategy - How to handle conflicts
22
- * @param dryRun - If true, preview changes without applying
23
- * @returns Import result with statistics
24
- */
25
- async importGraph(format, data, mergeStrategy = 'skip', dryRun = false) {
26
- let importedGraph;
27
- try {
28
- switch (format) {
29
- case 'json':
30
- importedGraph = this.parseJsonImport(data);
31
- break;
32
- case 'csv':
33
- importedGraph = this.parseCsvImport(data);
34
- break;
35
- case 'graphml':
36
- importedGraph = this.parseGraphMLImport(data);
37
- break;
38
- default:
39
- throw new Error(`Unsupported import format: ${format}`);
40
- }
41
- }
42
- catch (error) {
43
- return {
44
- entitiesAdded: 0,
45
- entitiesSkipped: 0,
46
- entitiesUpdated: 0,
47
- relationsAdded: 0,
48
- relationsSkipped: 0,
49
- errors: [`Failed to parse ${format} data: ${error instanceof Error ? error.message : String(error)}`],
50
- };
51
- }
52
- return await this.mergeImportedGraph(importedGraph, mergeStrategy, dryRun);
53
- }
54
- /**
55
- * Parse JSON format.
56
- */
57
- parseJsonImport(data) {
58
- const parsed = JSON.parse(data);
59
- if (!parsed.entities || !Array.isArray(parsed.entities)) {
60
- throw new Error('Invalid JSON: missing or invalid entities array');
61
- }
62
- if (!parsed.relations || !Array.isArray(parsed.relations)) {
63
- throw new Error('Invalid JSON: missing or invalid relations array');
64
- }
65
- return {
66
- entities: parsed.entities,
67
- relations: parsed.relations,
68
- };
69
- }
70
- /**
71
- * Parse CSV format.
72
- *
73
- * Expects: # ENTITIES section with header, then # RELATIONS section with header
74
- */
75
- parseCsvImport(data) {
76
- const lines = data
77
- .split('\n')
78
- .map(line => line.trim())
79
- .filter(line => line);
80
- const entities = [];
81
- const relations = [];
82
- let section = null;
83
- let headerParsed = false;
84
- const parseCsvLine = (line) => {
85
- const fields = [];
86
- let current = '';
87
- let inQuotes = false;
88
- for (let i = 0; i < line.length; i++) {
89
- const char = line[i];
90
- if (char === '"') {
91
- if (inQuotes && line[i + 1] === '"') {
92
- current += '"';
93
- i++;
94
- }
95
- else {
96
- inQuotes = !inQuotes;
97
- }
98
- }
99
- else if (char === ',' && !inQuotes) {
100
- fields.push(current);
101
- current = '';
102
- }
103
- else {
104
- current += char;
105
- }
106
- }
107
- fields.push(current);
108
- return fields;
109
- };
110
- for (const line of lines) {
111
- if (line.startsWith('# ENTITIES')) {
112
- section = 'entities';
113
- headerParsed = false;
114
- continue;
115
- }
116
- else if (line.startsWith('# RELATIONS')) {
117
- section = 'relations';
118
- headerParsed = false;
119
- continue;
120
- }
121
- if (line.startsWith('#'))
122
- continue;
123
- if (section === 'entities') {
124
- if (!headerParsed) {
125
- headerParsed = true;
126
- continue;
127
- }
128
- const fields = parseCsvLine(line);
129
- if (fields.length >= 2) {
130
- const entity = {
131
- name: fields[0],
132
- entityType: fields[1],
133
- observations: fields[2]
134
- ? fields[2]
135
- .split(';')
136
- .map(s => s.trim())
137
- .filter(s => s)
138
- : [],
139
- createdAt: fields[3] || undefined,
140
- lastModified: fields[4] || undefined,
141
- tags: fields[5]
142
- ? fields[5]
143
- .split(';')
144
- .map(s => s.trim().toLowerCase())
145
- .filter(s => s)
146
- : undefined,
147
- importance: fields[6] ? parseFloat(fields[6]) : undefined,
148
- };
149
- entities.push(entity);
150
- }
151
- }
152
- else if (section === 'relations') {
153
- if (!headerParsed) {
154
- headerParsed = true;
155
- continue;
156
- }
157
- const fields = parseCsvLine(line);
158
- if (fields.length >= 3) {
159
- const relation = {
160
- from: fields[0],
161
- to: fields[1],
162
- relationType: fields[2],
163
- createdAt: fields[3] || undefined,
164
- lastModified: fields[4] || undefined,
165
- };
166
- relations.push(relation);
167
- }
168
- }
169
- }
170
- return { entities, relations };
171
- }
172
- /**
173
- * Parse GraphML format.
174
- *
175
- * Note: Simplified regex-based parser for basic GraphML structure.
176
- */
177
- parseGraphMLImport(data) {
178
- const entities = [];
179
- const relations = [];
180
- // Extract nodes
181
- const nodeRegex = /<node\s+id="([^"]+)"[^>]*>([\s\S]*?)<\/node>/g;
182
- let nodeMatch;
183
- while ((nodeMatch = nodeRegex.exec(data)) !== null) {
184
- const nodeId = nodeMatch[1];
185
- const nodeContent = nodeMatch[2];
186
- const getDataValue = (key) => {
187
- const dataRegex = new RegExp(`<data\\s+key="${key}">([^<]*)<\/data>`);
188
- const match = dataRegex.exec(nodeContent);
189
- return match ? match[1] : undefined;
190
- };
191
- const entity = {
192
- name: nodeId,
193
- entityType: getDataValue('d0') || getDataValue('entityType') || 'unknown',
194
- observations: (getDataValue('d1') || getDataValue('observations') || '')
195
- .split(';')
196
- .map(s => s.trim())
197
- .filter(s => s),
198
- createdAt: getDataValue('d2') || getDataValue('createdAt'),
199
- lastModified: getDataValue('d3') || getDataValue('lastModified'),
200
- tags: (getDataValue('d4') || getDataValue('tags') || '')
201
- .split(';')
202
- .map(s => s.trim().toLowerCase())
203
- .filter(s => s),
204
- importance: getDataValue('d5') || getDataValue('importance') ? parseFloat(getDataValue('d5') || getDataValue('importance') || '0') : undefined,
205
- };
206
- entities.push(entity);
207
- }
208
- // Extract edges
209
- const edgeRegex = /<edge\s+[^>]*source="([^"]+)"\s+target="([^"]+)"[^>]*>([\s\S]*?)<\/edge>/g;
210
- let edgeMatch;
211
- while ((edgeMatch = edgeRegex.exec(data)) !== null) {
212
- const source = edgeMatch[1];
213
- const target = edgeMatch[2];
214
- const edgeContent = edgeMatch[3];
215
- const getDataValue = (key) => {
216
- const dataRegex = new RegExp(`<data\\s+key="${key}">([^<]*)<\/data>`);
217
- const match = dataRegex.exec(edgeContent);
218
- return match ? match[1] : undefined;
219
- };
220
- const relation = {
221
- from: source,
222
- to: target,
223
- relationType: getDataValue('e0') || getDataValue('relationType') || 'related_to',
224
- createdAt: getDataValue('e1') || getDataValue('createdAt'),
225
- lastModified: getDataValue('e2') || getDataValue('lastModified'),
226
- };
227
- relations.push(relation);
228
- }
229
- return { entities, relations };
230
- }
231
- /**
232
- * Merge imported graph with existing graph.
233
- */
234
- async mergeImportedGraph(importedGraph, mergeStrategy, dryRun) {
235
- const existingGraph = await this.storage.loadGraph();
236
- const result = {
237
- entitiesAdded: 0,
238
- entitiesSkipped: 0,
239
- entitiesUpdated: 0,
240
- relationsAdded: 0,
241
- relationsSkipped: 0,
242
- errors: [],
243
- };
244
- const existingEntitiesMap = new Map();
245
- for (const entity of existingGraph.entities) {
246
- existingEntitiesMap.set(entity.name, entity);
247
- }
248
- const existingRelationsSet = new Set();
249
- for (const relation of existingGraph.relations) {
250
- existingRelationsSet.add(`${relation.from}|${relation.to}|${relation.relationType}`);
251
- }
252
- // Process entities
253
- for (const importedEntity of importedGraph.entities) {
254
- const existing = existingEntitiesMap.get(importedEntity.name);
255
- if (!existing) {
256
- result.entitiesAdded++;
257
- if (!dryRun) {
258
- existingGraph.entities.push(importedEntity);
259
- existingEntitiesMap.set(importedEntity.name, importedEntity);
260
- }
261
- }
262
- else {
263
- switch (mergeStrategy) {
264
- case 'replace':
265
- result.entitiesUpdated++;
266
- if (!dryRun) {
267
- Object.assign(existing, importedEntity);
268
- }
269
- break;
270
- case 'skip':
271
- result.entitiesSkipped++;
272
- break;
273
- case 'merge':
274
- result.entitiesUpdated++;
275
- if (!dryRun) {
276
- existing.observations = [
277
- ...new Set([...existing.observations, ...importedEntity.observations]),
278
- ];
279
- if (importedEntity.tags) {
280
- existing.tags = existing.tags || [];
281
- existing.tags = [...new Set([...existing.tags, ...importedEntity.tags])];
282
- }
283
- if (importedEntity.importance !== undefined) {
284
- existing.importance = importedEntity.importance;
285
- }
286
- existing.lastModified = new Date().toISOString();
287
- }
288
- break;
289
- case 'fail':
290
- result.errors.push(`Entity "${importedEntity.name}" already exists`);
291
- break;
292
- }
293
- }
294
- }
295
- // Process relations
296
- for (const importedRelation of importedGraph.relations) {
297
- const relationKey = `${importedRelation.from}|${importedRelation.to}|${importedRelation.relationType}`;
298
- if (!existingEntitiesMap.has(importedRelation.from)) {
299
- result.errors.push(`Relation source entity "${importedRelation.from}" does not exist`);
300
- continue;
301
- }
302
- if (!existingEntitiesMap.has(importedRelation.to)) {
303
- result.errors.push(`Relation target entity "${importedRelation.to}" does not exist`);
304
- continue;
305
- }
306
- if (!existingRelationsSet.has(relationKey)) {
307
- result.relationsAdded++;
308
- if (!dryRun) {
309
- existingGraph.relations.push(importedRelation);
310
- existingRelationsSet.add(relationKey);
311
- }
312
- }
313
- else {
314
- if (mergeStrategy === 'fail') {
315
- result.errors.push(`Relation "${relationKey}" already exists`);
316
- }
317
- else {
318
- result.relationsSkipped++;
319
- }
320
- }
321
- }
322
- // Save if not dry run and no blocking errors
323
- if (!dryRun && (mergeStrategy !== 'fail' || result.errors.length === 0)) {
324
- await this.storage.saveGraph(existingGraph);
325
- }
326
- return result;
327
- }
328
- }
File without changes
File without changes
@@ -1,6 +0,0 @@
1
- /**
2
- * Analytics Types
3
- *
4
- * Type definitions for graph statistics, validation reports, and analytics data.
5
- */
6
- export {};
@@ -1,7 +0,0 @@
1
- /**
2
- * Entity Types
3
- *
4
- * Core type definitions for entities, relations, and the knowledge graph structure.
5
- * These types form the foundation of the memory MCP server's data model.
6
- */
7
- export {};
@@ -1,7 +0,0 @@
1
- /**
2
- * Import/Export Types
3
- *
4
- * Type definitions for import and export operations, including
5
- * result summaries, compression results, and export filters.
6
- */
7
- export {};
@@ -1,7 +0,0 @@
1
- /**
2
- * Search Types
3
- *
4
- * Type definitions for search operations, including search results,
5
- * saved searches, and boolean query AST structures.
6
- */
7
- export {};
@@ -1,6 +0,0 @@
1
- /**
2
- * Tag Types
3
- *
4
- * Type definitions for tag management, including tag aliases for synonyms.
5
- */
6
- export {};
@@ -1,89 +0,0 @@
1
- /**
2
- * Date Utilities
3
- *
4
- * Helper functions for date parsing, validation, and range filtering.
5
- * All dates use ISO 8601 format (YYYY-MM-DDTHH:mm:ss.sssZ).
6
- *
7
- * @module utils/dateUtils
8
- */
9
- /**
10
- * Check if a date falls within a specified range.
11
- *
12
- * @param date - ISO 8601 date string to check
13
- * @param start - Optional start date (inclusive)
14
- * @param end - Optional end date (inclusive)
15
- * @returns True if date is within range
16
- *
17
- * @example
18
- * ```typescript
19
- * isWithinDateRange('2024-06-15T00:00:00Z', '2024-01-01T00:00:00Z', '2024-12-31T23:59:59Z'); // true
20
- * isWithinDateRange('2024-06-15T00:00:00Z', '2024-07-01T00:00:00Z'); // false
21
- * ```
22
- */
23
- export function isWithinDateRange(date, start, end) {
24
- const dateObj = new Date(date);
25
- if (isNaN(dateObj.getTime())) {
26
- return false;
27
- }
28
- if (start) {
29
- const startObj = new Date(start);
30
- if (isNaN(startObj.getTime())) {
31
- return false;
32
- }
33
- if (dateObj < startObj) {
34
- return false;
35
- }
36
- }
37
- if (end) {
38
- const endObj = new Date(end);
39
- if (isNaN(endObj.getTime())) {
40
- return false;
41
- }
42
- if (dateObj > endObj) {
43
- return false;
44
- }
45
- }
46
- return true;
47
- }
48
- /**
49
- * Parse and validate date range strings.
50
- *
51
- * @param startDate - Optional ISO 8601 start date
52
- * @param endDate - Optional ISO 8601 end date
53
- * @returns Parsed Date objects or null
54
- */
55
- export function parseDateRange(startDate, endDate) {
56
- let start = null;
57
- let end = null;
58
- if (startDate) {
59
- start = new Date(startDate);
60
- if (isNaN(start.getTime())) {
61
- start = null;
62
- }
63
- }
64
- if (endDate) {
65
- end = new Date(endDate);
66
- if (isNaN(end.getTime())) {
67
- end = null;
68
- }
69
- }
70
- return { start, end };
71
- }
72
- /**
73
- * Validate if a string is a valid ISO 8601 date.
74
- *
75
- * @param date - Date string to validate
76
- * @returns True if valid ISO 8601 date
77
- */
78
- export function isValidISODate(date) {
79
- const dateObj = new Date(date);
80
- return !isNaN(dateObj.getTime()) && dateObj.toISOString() === date;
81
- }
82
- /**
83
- * Get current timestamp in ISO 8601 format.
84
- *
85
- * @returns Current timestamp string
86
- */
87
- export function getCurrentTimestamp() {
88
- return new Date().toISOString();
89
- }
@@ -1,155 +0,0 @@
1
- /**
2
- * Entity Filtering Utilities
3
- *
4
- * Centralizes common filtering logic for importance, date ranges, and other
5
- * entity properties to eliminate duplicate patterns across search implementations.
6
- */
7
- /**
8
- * Checks if an entity's importance is within the specified range.
9
- * Entities without importance are treated as not matching if any filter is set.
10
- *
11
- * @param importance - The entity's importance value (may be undefined)
12
- * @param minImportance - Minimum importance filter (inclusive)
13
- * @param maxImportance - Maximum importance filter (inclusive)
14
- * @returns true if importance is within range or no filters are set
15
- *
16
- * @example
17
- * ```typescript
18
- * // Check if entity passes importance filter
19
- * if (isWithinImportanceRange(entity.importance, 5, 10)) {
20
- * // Entity has importance between 5 and 10
21
- * }
22
- * ```
23
- */
24
- export function isWithinImportanceRange(importance, minImportance, maxImportance) {
25
- // If no filters set, always pass
26
- if (minImportance === undefined && maxImportance === undefined) {
27
- return true;
28
- }
29
- // Check minimum importance
30
- if (minImportance !== undefined) {
31
- if (importance === undefined || importance < minImportance) {
32
- return false;
33
- }
34
- }
35
- // Check maximum importance
36
- if (maxImportance !== undefined) {
37
- if (importance === undefined || importance > maxImportance) {
38
- return false;
39
- }
40
- }
41
- return true;
42
- }
43
- /**
44
- * Filters entities by importance range.
45
- * Returns all entities if no importance filters are specified.
46
- *
47
- * @param entities - Array of entities to filter
48
- * @param minImportance - Minimum importance filter (inclusive)
49
- * @param maxImportance - Maximum importance filter (inclusive)
50
- * @returns Filtered entities within the importance range
51
- */
52
- export function filterByImportance(entities, minImportance, maxImportance) {
53
- if (minImportance === undefined && maxImportance === undefined) {
54
- return entities;
55
- }
56
- return entities.filter(e => isWithinImportanceRange(e.importance, minImportance, maxImportance));
57
- }
58
- /**
59
- * Checks if a date value is within the specified range.
60
- * Handles undefined values appropriately.
61
- *
62
- * @param dateValue - ISO 8601 date string to check (may be undefined)
63
- * @param startDate - Start of date range (inclusive)
64
- * @param endDate - End of date range (inclusive)
65
- * @returns true if date is within range or no filters are set
66
- */
67
- export function isWithinDateRange(dateValue, startDate, endDate) {
68
- // If no filters set, always pass
69
- if (!startDate && !endDate) {
70
- return true;
71
- }
72
- // If date value is undefined but we have filters, fail
73
- if (!dateValue) {
74
- return false;
75
- }
76
- const date = new Date(dateValue);
77
- if (startDate && date < new Date(startDate)) {
78
- return false;
79
- }
80
- if (endDate && date > new Date(endDate)) {
81
- return false;
82
- }
83
- return true;
84
- }
85
- /**
86
- * Filters entities by creation date range.
87
- *
88
- * @param entities - Array of entities to filter
89
- * @param startDate - Start of date range (inclusive)
90
- * @param endDate - End of date range (inclusive)
91
- * @returns Filtered entities created within the date range
92
- */
93
- export function filterByCreatedDate(entities, startDate, endDate) {
94
- if (!startDate && !endDate) {
95
- return entities;
96
- }
97
- return entities.filter(e => isWithinDateRange(e.createdAt, startDate, endDate));
98
- }
99
- /**
100
- * Filters entities by last modified date range.
101
- *
102
- * @param entities - Array of entities to filter
103
- * @param startDate - Start of date range (inclusive)
104
- * @param endDate - End of date range (inclusive)
105
- * @returns Filtered entities modified within the date range
106
- */
107
- export function filterByModifiedDate(entities, startDate, endDate) {
108
- if (!startDate && !endDate) {
109
- return entities;
110
- }
111
- return entities.filter(e => isWithinDateRange(e.lastModified, startDate, endDate));
112
- }
113
- /**
114
- * Filters entities by entity type.
115
- *
116
- * @param entities - Array of entities to filter
117
- * @param entityType - Entity type to filter by (case-sensitive)
118
- * @returns Filtered entities of the specified type
119
- */
120
- export function filterByEntityType(entities, entityType) {
121
- if (!entityType) {
122
- return entities;
123
- }
124
- return entities.filter(e => e.entityType === entityType);
125
- }
126
- /**
127
- * Checks if an entity passes all the specified filters.
128
- * Short-circuits on first failing filter for performance.
129
- *
130
- * Note: Tag filtering should be handled separately using tagUtils.hasMatchingTag
131
- * as it requires special normalization logic.
132
- *
133
- * @param entity - Entity to check
134
- * @param filters - Filters to apply
135
- * @returns true if entity passes all filters
136
- */
137
- export function entityPassesFilters(entity, filters) {
138
- // Importance filter
139
- if (!isWithinImportanceRange(entity.importance, filters.minImportance, filters.maxImportance)) {
140
- return false;
141
- }
142
- // Entity type filter
143
- if (filters.entityType && entity.entityType !== filters.entityType) {
144
- return false;
145
- }
146
- // Created date filter
147
- if (!isWithinDateRange(entity.createdAt, filters.createdAfter, filters.createdBefore)) {
148
- return false;
149
- }
150
- // Modified date filter
151
- if (!isWithinDateRange(entity.lastModified, filters.modifiedAfter, filters.modifiedBefore)) {
152
- return false;
153
- }
154
- return true;
155
- }
@@ -1,62 +0,0 @@
1
- /**
2
- * Levenshtein Distance Algorithm
3
- *
4
- * Calculates the minimum number of single-character edits (insertions,
5
- * deletions, or substitutions) needed to change one string into another.
6
- *
7
- * Used for fuzzy string matching to find similar entities despite typos.
8
- *
9
- * @module utils/levenshtein
10
- */
11
- /**
12
- * Calculate Levenshtein distance between two strings.
13
- *
14
- * Returns the minimum number of single-character edits needed to change
15
- * one word into another.
16
- *
17
- * **Algorithm**: Dynamic programming with O(m*n) time and space complexity,
18
- * where m and n are the lengths of the two strings.
19
- *
20
- * @param str1 - First string to compare
21
- * @param str2 - Second string to compare
22
- * @returns Minimum number of edits required (0 = identical strings)
23
- *
24
- * @example
25
- * ```typescript
26
- * levenshteinDistance("kitten", "sitting"); // Returns 3
27
- * levenshteinDistance("hello", "hello"); // Returns 0
28
- * levenshteinDistance("abc", ""); // Returns 3
29
- * ```
30
- */
31
- export function levenshteinDistance(str1, str2) {
32
- const m = str1.length;
33
- const n = str2.length;
34
- // Create 2D array for dynamic programming
35
- const dp = Array(m + 1)
36
- .fill(null)
37
- .map(() => Array(n + 1).fill(0));
38
- // Initialize base cases: distance from empty string
39
- for (let i = 0; i <= m; i++) {
40
- dp[i][0] = i;
41
- }
42
- for (let j = 0; j <= n; j++) {
43
- dp[0][j] = j;
44
- }
45
- // Fill dp table
46
- for (let i = 1; i <= m; i++) {
47
- for (let j = 1; j <= n; j++) {
48
- if (str1[i - 1] === str2[j - 1]) {
49
- // Characters match, no edit needed
50
- dp[i][j] = dp[i - 1][j - 1];
51
- }
52
- else {
53
- // Take minimum of three operations
54
- dp[i][j] = Math.min(dp[i - 1][j] + 1, // deletion
55
- dp[i][j - 1] + 1, // insertion
56
- dp[i - 1][j - 1] + 1 // substitution
57
- );
58
- }
59
- }
60
- }
61
- return dp[m][n];
62
- }