@pcircle/memesh 4.2.10 → 4.3.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 (106) hide show
  1. package/.claude-plugin/marketplace.json +1 -1
  2. package/.claude-plugin/plugin.json +1 -1
  3. package/README.de.md +14 -13
  4. package/README.es.md +14 -13
  5. package/README.fr.md +14 -13
  6. package/README.ja.md +14 -13
  7. package/README.ko.md +14 -13
  8. package/README.md +15 -14
  9. package/README.pt.md +14 -13
  10. package/README.th.md +15 -14
  11. package/README.vi.md +14 -13
  12. package/README.zh-CN.md +12 -11
  13. package/README.zh-TW.md +12 -11
  14. package/dashboard/dist/index.html +8 -8
  15. package/dist/cli/view.d.ts.map +1 -1
  16. package/dist/cli/view.js +6 -0
  17. package/dist/cli/view.js.map +1 -1
  18. package/dist/core/config.d.ts +14 -0
  19. package/dist/core/config.d.ts.map +1 -1
  20. package/dist/core/config.js +25 -5
  21. package/dist/core/config.js.map +1 -1
  22. package/dist/core/doctor.d.ts +3 -0
  23. package/dist/core/doctor.d.ts.map +1 -1
  24. package/dist/core/doctor.js +84 -5
  25. package/dist/core/doctor.js.map +1 -1
  26. package/dist/core/dreamer.d.ts.map +1 -1
  27. package/dist/core/dreamer.js +26 -15
  28. package/dist/core/dreamer.js.map +1 -1
  29. package/dist/core/embedder.d.ts +6 -1
  30. package/dist/core/embedder.d.ts.map +1 -1
  31. package/dist/core/embedder.js +33 -9
  32. package/dist/core/embedder.js.map +1 -1
  33. package/dist/core/llm-validator.d.ts.map +1 -1
  34. package/dist/core/llm-validator.js +6 -0
  35. package/dist/core/llm-validator.js.map +1 -1
  36. package/dist/core/memory-tool.d.ts +37 -0
  37. package/dist/core/memory-tool.d.ts.map +1 -0
  38. package/dist/core/memory-tool.js +371 -0
  39. package/dist/core/memory-tool.js.map +1 -0
  40. package/dist/core/operations.d.ts +11 -5
  41. package/dist/core/operations.d.ts.map +1 -1
  42. package/dist/core/operations.js +91 -34
  43. package/dist/core/operations.js.map +1 -1
  44. package/dist/core/prompt-safety.d.ts.map +1 -1
  45. package/dist/core/prompt-safety.js.map +1 -1
  46. package/dist/core/schema-export.d.ts.map +1 -1
  47. package/dist/core/schema-export.js +19 -34
  48. package/dist/core/schema-export.js.map +1 -1
  49. package/dist/core/types.d.ts +5 -12
  50. package/dist/core/types.d.ts.map +1 -1
  51. package/dist/core/types.js +4 -1
  52. package/dist/core/types.js.map +1 -1
  53. package/dist/core/verifier.d.ts +3 -0
  54. package/dist/core/verifier.d.ts.map +1 -1
  55. package/dist/core/verifier.js +27 -11
  56. package/dist/core/verifier.js.map +1 -1
  57. package/dist/db.d.ts +11 -0
  58. package/dist/db.d.ts.map +1 -1
  59. package/dist/db.js +174 -35
  60. package/dist/db.js.map +1 -1
  61. package/dist/index.d.ts +2 -0
  62. package/dist/index.d.ts.map +1 -1
  63. package/dist/index.js +1 -0
  64. package/dist/index.js.map +1 -1
  65. package/dist/knowledge-graph.d.ts +1 -2
  66. package/dist/knowledge-graph.d.ts.map +1 -1
  67. package/dist/knowledge-graph.js +94 -44
  68. package/dist/knowledge-graph.js.map +1 -1
  69. package/dist/skills-manifest.json +14 -15
  70. package/dist/storage/conflicts.d.ts +1 -4
  71. package/dist/storage/conflicts.d.ts.map +1 -1
  72. package/dist/storage/conflicts.js +2 -5
  73. package/dist/storage/conflicts.js.map +1 -1
  74. package/dist/storage/fts-index.d.ts +11 -0
  75. package/dist/storage/fts-index.d.ts.map +1 -1
  76. package/dist/storage/fts-index.js +58 -2
  77. package/dist/storage/fts-index.js.map +1 -1
  78. package/dist/transports/cli/cli.d.ts.map +1 -1
  79. package/dist/transports/cli/cli.js +96 -50
  80. package/dist/transports/cli/cli.js.map +1 -1
  81. package/dist/transports/http/retired-routes.d.ts +2 -0
  82. package/dist/transports/http/retired-routes.d.ts.map +1 -0
  83. package/dist/transports/http/retired-routes.js +4 -0
  84. package/dist/transports/http/retired-routes.js.map +1 -0
  85. package/dist/transports/http/server.d.ts.map +1 -1
  86. package/dist/transports/http/server.js +6 -3
  87. package/dist/transports/http/server.js.map +1 -1
  88. package/dist/transports/mcp/handlers.d.ts +4 -25
  89. package/dist/transports/mcp/handlers.d.ts.map +1 -1
  90. package/dist/transports/mcp/handlers.js +8 -28
  91. package/dist/transports/mcp/handlers.js.map +1 -1
  92. package/dist/transports/schemas.d.ts +0 -5
  93. package/dist/transports/schemas.d.ts.map +1 -1
  94. package/dist/transports/schemas.js +0 -5
  95. package/dist/transports/schemas.js.map +1 -1
  96. package/package.json +35 -6
  97. package/scripts/hooks/_generated/fts-index.js +58 -2
  98. package/scripts/hooks/_shared.js +238 -4
  99. package/scripts/hooks/pre-compact.js +14 -3
  100. package/scripts/hooks/pre-edit-recall.js +76 -9
  101. package/skills/memesh/SKILL.md +11 -4
  102. package/skills/memesh-review/SKILL.md +7 -5
  103. package/dist/core/consolidator.d.ts +0 -3
  104. package/dist/core/consolidator.d.ts.map +0 -1
  105. package/dist/core/consolidator.js +0 -108
  106. package/dist/core/consolidator.js.map +0 -1
@@ -0,0 +1,371 @@
1
+ import { getDatabase } from '../db.js';
2
+ import { KnowledgeGraph } from '../knowledge-graph.js';
3
+ import { removeFromFts, insertFtsRow } from '../storage/fts-index.js';
4
+ export const MEMORY_ROOT = '/memories';
5
+ const NAMESPACES = ['personal', 'team', 'global'];
6
+ const FILE_SUFFIX = '.md';
7
+ const MAX_FILE_BYTES = 256 * 1024;
8
+ const MAX_VIEW_CHARS = 16_000;
9
+ const ok = (content) => ({ content, isError: false });
10
+ const err = (content) => ({ content, isError: true });
11
+ function encodeName(name) {
12
+ return name.replace(/%/g, '%25').replace(/\//g, '%2F').replace(/\\/g, '%5C');
13
+ }
14
+ function decodeName(segment) {
15
+ return segment
16
+ .replace(/%2F/gi, '/')
17
+ .replace(/%5C/gi, '\\')
18
+ .replace(/%25/g, '%');
19
+ }
20
+ function parsePath(raw) {
21
+ if (typeof raw !== 'string' || raw.length === 0) {
22
+ return err('Error: `path` must be a non-empty string.');
23
+ }
24
+ if (raw.includes('\0')) {
25
+ return err('Error: `path` may not contain a NUL byte.');
26
+ }
27
+ if (raw !== MEMORY_ROOT && !raw.startsWith(`${MEMORY_ROOT}/`)) {
28
+ return err(`Error: paths must be under ${MEMORY_ROOT}. The path ${raw} is outside it.`);
29
+ }
30
+ const rest = raw.slice(MEMORY_ROOT.length).replace(/^\//, '');
31
+ if (rest === '')
32
+ return { kind: 'root' };
33
+ const segments = rest.split('/');
34
+ for (const segment of segments) {
35
+ if (segment === '' || segment === '.' || segment === '..') {
36
+ return err(`Error: the path ${raw} contains a traversal or empty segment and was refused.`);
37
+ }
38
+ if (/%2e%2e/i.test(segment) || segment.includes('\\')) {
39
+ return err(`Error: the path ${raw} contains a traversal sequence and was refused.`);
40
+ }
41
+ }
42
+ if (segments.length > 2) {
43
+ return err(`Error: ${MEMORY_ROOT} is two levels deep — ${MEMORY_ROOT}/<namespace>/<memory>${FILE_SUFFIX}. ` +
44
+ `The path ${raw} is deeper than that.`);
45
+ }
46
+ const namespace = segments[0];
47
+ if (!NAMESPACES.includes(namespace)) {
48
+ return err(`Error: "${namespace}" is not a memory namespace. Use one of: ${NAMESPACES.join(', ')}.`);
49
+ }
50
+ if (segments.length === 1) {
51
+ return { kind: 'namespace', namespace: namespace };
52
+ }
53
+ const file = segments[1];
54
+ if (!file.endsWith(FILE_SUFFIX)) {
55
+ return err(`Error: memory files end in ${FILE_SUFFIX}. The path ${raw} does not.`);
56
+ }
57
+ const name = decodeName(file.slice(0, -FILE_SUFFIX.length));
58
+ if (name === '') {
59
+ return err(`Error: the path ${raw} names an empty memory.`);
60
+ }
61
+ return { kind: 'entity', namespace: namespace, name };
62
+ }
63
+ const isResult = (v) => 'content' in v;
64
+ function entityPath(namespace, name) {
65
+ return `${MEMORY_ROOT}/${namespace}/${encodeName(name)}${FILE_SUFFIX}`;
66
+ }
67
+ function renderBody(entity) {
68
+ return entity.observations.join('\n');
69
+ }
70
+ function lineOwners(observations) {
71
+ const owners = [];
72
+ observations.forEach((observation, index) => {
73
+ const span = observation.split('\n').length;
74
+ for (let i = 0; i < span; i++)
75
+ owners.push(index);
76
+ });
77
+ return owners;
78
+ }
79
+ function withLineNumbers(body, from = 1) {
80
+ if (body === '')
81
+ return '';
82
+ return body
83
+ .split('\n')
84
+ .map((line, i) => `${String(from + i).padStart(6, ' ')}\t${line}`)
85
+ .join('\n');
86
+ }
87
+ function humanSize(bytes) {
88
+ if (bytes < 1024)
89
+ return `${bytes}`;
90
+ return `${(bytes / 1024).toFixed(1)}K`;
91
+ }
92
+ function graph() {
93
+ return new KnowledgeGraph(getDatabase());
94
+ }
95
+ function listNamespace(namespace) {
96
+ return getDatabase()
97
+ .prepare(`SELECT e.name AS name,
98
+ e.type AS type,
99
+ COALESCE(SUM(LENGTH(o.content)) + MAX(COUNT(o.id) - 1, 0), 0) AS bytes
100
+ FROM entities e
101
+ LEFT JOIN observations o ON o.entity_id = e.id
102
+ WHERE e.status = 'active' AND e.namespace = ?
103
+ GROUP BY e.id
104
+ ORDER BY e.id DESC`)
105
+ .all(namespace);
106
+ }
107
+ function countNamespace(namespace) {
108
+ return getDatabase()
109
+ .prepare("SELECT COUNT(*) AS n FROM entities WHERE status = 'active' AND namespace = ?")
110
+ .get(namespace).n;
111
+ }
112
+ function tagsOf(name) {
113
+ return getDatabase()
114
+ .prepare('SELECT tag FROM tags WHERE entity_id = (SELECT id FROM entities WHERE name = ?)')
115
+ .all(name).map((t) => t.tag);
116
+ }
117
+ function findEntity(kg, namespace, name) {
118
+ const entity = kg.getEntity(name);
119
+ if (!entity || entity.namespace !== namespace)
120
+ return null;
121
+ return entity;
122
+ }
123
+ function rewriteObservations(kg, entity, observations) {
124
+ getDatabase().transaction(() => {
125
+ kg.clearEntityData(entity.name);
126
+ kg.createEntity(entity.name, entity.type, {
127
+ observations,
128
+ tags: entity.tags,
129
+ namespace: entity.namespace,
130
+ });
131
+ })();
132
+ }
133
+ function tooLarge(body, path) {
134
+ const bytes = Buffer.byteLength(body, 'utf8');
135
+ if (bytes <= MAX_FILE_BYTES)
136
+ return null;
137
+ return err(`Error: ${path} would be ${humanSize(bytes)}, over the ${humanSize(MAX_FILE_BYTES)} ` +
138
+ `limit for one memory. Split it across several memories.`);
139
+ }
140
+ function viewRoot() {
141
+ const lines = [`${MEMORY_ROOT}`];
142
+ for (const namespace of NAMESPACES) {
143
+ lines.push(`${MEMORY_ROOT}/${namespace}\t${countNamespace(namespace)} memories`);
144
+ }
145
+ return ok(`Here're the files and directories up to 2 levels deep in ${MEMORY_ROOT}, ` +
146
+ `excluding hidden items and node_modules:\n${lines.join('\n')}`);
147
+ }
148
+ function viewNamespace(namespace) {
149
+ const lines = listNamespace(namespace).map((row) => {
150
+ const tags = tagsOf(row.name);
151
+ const suffix = tags.length > 0 ? ` tags: ${tags.join(', ')}` : '';
152
+ return `${humanSize(row.bytes)}\t${entityPath(namespace, row.name)}\t(${row.type})${suffix}`;
153
+ });
154
+ return ok(`Here're the files and directories up to 2 levels deep in ${MEMORY_ROOT}/${namespace}, ` +
155
+ `excluding hidden items and node_modules:\n` +
156
+ [`${MEMORY_ROOT}/${namespace}`, ...lines].join('\n'));
157
+ }
158
+ function viewEntity(namespace, name, range, path) {
159
+ const entity = findEntity(graph(), namespace, name);
160
+ if (!entity) {
161
+ return err(`The path ${path} does not exist. Please provide a valid path.`);
162
+ }
163
+ const body = renderBody(entity);
164
+ const lines = body === '' ? [] : body.split('\n');
165
+ if (range === undefined) {
166
+ if (body.length > MAX_VIEW_CHARS) {
167
+ const kept = [];
168
+ let used = 0;
169
+ for (const line of lines) {
170
+ if (used + line.length + 1 > MAX_VIEW_CHARS)
171
+ break;
172
+ kept.push(line);
173
+ used += line.length + 1;
174
+ }
175
+ return ok(`Here's the content of ${path} with line numbers:\n${withLineNumbers(kept.join('\n'))}\n` +
176
+ `\n[truncated at ${kept.length} of ${lines.length} lines — ` +
177
+ `use view_range to read from line ${kept.length + 1}]`);
178
+ }
179
+ return ok(`Here's the content of ${path} with line numbers:\n${withLineNumbers(body)}`);
180
+ }
181
+ if (!Array.isArray(range) || range.length !== 2 || !range.every((n) => Number.isInteger(n))) {
182
+ return err('Error: `view_range` must be a two-element array of integers, [start, end].');
183
+ }
184
+ const [start, rawEnd] = range;
185
+ const end = rawEnd === -1 ? lines.length : rawEnd;
186
+ if (start < 1 || start > Math.max(lines.length, 1) || end < start) {
187
+ return err(`Error: Invalid \`view_range\`: [${start}, ${rawEnd}]. ` +
188
+ `It should be within the range of lines of the file: [1, ${lines.length}]`);
189
+ }
190
+ const slice = lines.slice(start - 1, end).join('\n');
191
+ return ok(`Here's the content of ${path} with line numbers:\n${withLineNumbers(slice, start)}`);
192
+ }
193
+ function createEntityFile(namespace, name, fileText, path) {
194
+ if (typeof fileText !== 'string') {
195
+ return err('Error: `file_text` must be a string.');
196
+ }
197
+ const kg = graph();
198
+ const existing = findEntity(kg, namespace, name);
199
+ const oversize = tooLarge(fileText, path);
200
+ if (oversize)
201
+ return oversize;
202
+ const observations = fileText === '' ? [] : fileText.split('\n');
203
+ if (existing) {
204
+ rewriteObservations(kg, existing, observations);
205
+ return ok(`File created successfully at: ${path}`);
206
+ }
207
+ kg.createEntity(name, 'note', { observations, namespace });
208
+ return ok(`File created successfully at: ${path}`);
209
+ }
210
+ function strReplace(namespace, name, oldStr, newStr, path) {
211
+ if (typeof oldStr !== 'string' || oldStr === '') {
212
+ return err('Error: `old_str` must be a non-empty string.');
213
+ }
214
+ if (newStr !== undefined && typeof newStr !== 'string') {
215
+ return err('Error: `new_str` must be a string when present.');
216
+ }
217
+ const kg = graph();
218
+ const entity = findEntity(kg, namespace, name);
219
+ if (!entity) {
220
+ return err(`Error: The path ${path} does not exist. Please provide a valid path.`);
221
+ }
222
+ const body = renderBody(entity);
223
+ const first = body.indexOf(oldStr);
224
+ if (first === -1) {
225
+ return err(`No replacement was performed, old_str \`${oldStr}\` did not appear verbatim in ${path}.`);
226
+ }
227
+ if (body.indexOf(oldStr, first + 1) !== -1) {
228
+ const lines = [];
229
+ let at = first;
230
+ while (at !== -1) {
231
+ lines.push(body.slice(0, at).split('\n').length);
232
+ at = body.indexOf(oldStr, at + 1);
233
+ }
234
+ return err(`No replacement was performed. Multiple occurrences of old_str \`${oldStr}\` ` +
235
+ `in lines: ${lines.join(', ')}. Please ensure it is unique`);
236
+ }
237
+ const replaced = body.slice(0, first) + (newStr ?? '') + body.slice(first + oldStr.length);
238
+ const oversize = tooLarge(replaced, path);
239
+ if (oversize)
240
+ return oversize;
241
+ const observations = replaced === '' ? [] : replaced.split('\n');
242
+ rewriteObservations(kg, entity, observations);
243
+ const at = replaced.slice(0, first).split('\n').length;
244
+ const from = Math.max(1, at - 2);
245
+ const snippet = replaced.split('\n').slice(from - 1, at + 2).join('\n');
246
+ return ok(`The memory file has been edited. Here's a snippet of ${path} with line numbers:\n` +
247
+ withLineNumbers(snippet, from));
248
+ }
249
+ function insertLine(namespace, name, atLine, text, path) {
250
+ if (!Number.isInteger(atLine)) {
251
+ return err('Error: `insert_line` must be an integer.');
252
+ }
253
+ if (typeof text !== 'string') {
254
+ return err('Error: `insert_text` must be a string.');
255
+ }
256
+ const kg = graph();
257
+ const entity = findEntity(kg, namespace, name);
258
+ if (!entity)
259
+ return err(`Error: The path ${path} does not exist`);
260
+ const owners = lineOwners(entity.observations);
261
+ const line = atLine;
262
+ if (line < 0 || line > owners.length) {
263
+ return err(`Error: Invalid \`insert_line\` parameter: ${line}. ` +
264
+ `It should be within the range of lines of the file: [0, ${owners.length}]`);
265
+ }
266
+ const insertAfter = line === 0 ? -1 : owners[line - 1];
267
+ const observations = [...entity.observations];
268
+ observations.splice(insertAfter + 1, 0, text.replace(/\n$/, ''));
269
+ const oversize = tooLarge(observations.join('\n'), path);
270
+ if (oversize)
271
+ return oversize;
272
+ rewriteObservations(kg, entity, observations);
273
+ return ok(`The file ${path} has been edited.`);
274
+ }
275
+ function deletePath(parsed, path) {
276
+ if (parsed.kind === 'root') {
277
+ return err(`Error: ${MEMORY_ROOT} itself cannot be deleted.`);
278
+ }
279
+ if (parsed.kind === 'namespace') {
280
+ return err(`Error: ${path} is a namespace and cannot be deleted. Delete individual memories instead.`);
281
+ }
282
+ const kg = graph();
283
+ const entity = findEntity(kg, parsed.namespace, parsed.name);
284
+ if (!entity)
285
+ return err(`Error: The path ${path} does not exist`);
286
+ kg.archiveEntity(entity.name);
287
+ return ok(`Successfully deleted ${path}`);
288
+ }
289
+ function renamePath(oldRaw, newRaw) {
290
+ const from = parsePath(oldRaw);
291
+ if (isResult(from))
292
+ return from;
293
+ const to = parsePath(newRaw);
294
+ if (isResult(to))
295
+ return to;
296
+ if (from.kind !== 'entity' || to.kind !== 'entity') {
297
+ return err(`Error: rename moves one memory to another memory path. ` +
298
+ `${MEMORY_ROOT} and its namespaces cannot be renamed.`);
299
+ }
300
+ const kg = graph();
301
+ const source = findEntity(kg, from.namespace, from.name);
302
+ if (!source)
303
+ return err(`Error: The path ${String(oldRaw)} does not exist`);
304
+ if (findEntity(kg, to.namespace, to.name)) {
305
+ return err(`Error: The destination ${String(newRaw)} already exists`);
306
+ }
307
+ if (kg.getEntity(to.name)) {
308
+ return err(`Error: The destination ${String(newRaw)} already exists in another namespace. ` +
309
+ `Memory names are unique across namespaces.`);
310
+ }
311
+ const db = getDatabase();
312
+ const entityId = source.id;
313
+ const obsText = source.observations.join(' ');
314
+ db.transaction(() => {
315
+ removeFromFts(db, entityId, source.name, obsText);
316
+ db.prepare('UPDATE entities SET name = ?, namespace = ? WHERE id = ?')
317
+ .run(to.name, to.namespace, entityId);
318
+ insertFtsRow(db, entityId, to.name, obsText);
319
+ })();
320
+ return ok(`Successfully renamed ${String(oldRaw)} to ${String(newRaw)}`);
321
+ }
322
+ export function handleMemoryCommand(input) {
323
+ if (typeof input !== 'object' || input === null) {
324
+ return err('Error: the memory tool input must be an object.');
325
+ }
326
+ const cmd = input;
327
+ switch (cmd.command) {
328
+ case 'rename':
329
+ return renamePath(cmd.old_path, cmd.new_path);
330
+ case 'view':
331
+ case 'create':
332
+ case 'str_replace':
333
+ case 'insert':
334
+ case 'delete':
335
+ break;
336
+ case undefined:
337
+ return err('Error: the memory tool input has no `command`.');
338
+ default:
339
+ return err(`Error: unknown command ${String(cmd.command)}`);
340
+ }
341
+ const parsed = parsePath(cmd.path);
342
+ if (isResult(parsed))
343
+ return parsed;
344
+ const path = cmd.path;
345
+ if (cmd.command === 'delete')
346
+ return deletePath(parsed, path);
347
+ if (cmd.command === 'view') {
348
+ if (parsed.kind === 'root')
349
+ return viewRoot();
350
+ if (parsed.kind === 'namespace')
351
+ return viewNamespace(parsed.namespace);
352
+ return viewEntity(parsed.namespace, parsed.name, cmd.view_range, path);
353
+ }
354
+ if (parsed.kind !== 'entity') {
355
+ return err(`Error: ${path} is a directory. ${cmd.command} needs a memory file, ` +
356
+ `${MEMORY_ROOT}/<namespace>/<memory>${FILE_SUFFIX}.`);
357
+ }
358
+ switch (cmd.command) {
359
+ case 'create':
360
+ return createEntityFile(parsed.namespace, parsed.name, cmd.file_text, path);
361
+ case 'str_replace':
362
+ return strReplace(parsed.namespace, parsed.name, cmd.old_str, cmd.new_str, path);
363
+ case 'insert':
364
+ return insertLine(parsed.namespace, parsed.name, cmd.insert_line, cmd.insert_text, path);
365
+ }
366
+ }
367
+ export const MEMORY_TOOL_DEFINITION = {
368
+ type: 'memory_20250818',
369
+ name: 'memory',
370
+ };
371
+ //# sourceMappingURL=memory-tool.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"memory-tool.js","sourceRoot":"","sources":["../../src/core/memory-tool.ts"],"names":[],"mappings":"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"}
@@ -1,3 +1,4 @@
1
+ import type { EmbedOutcome } from './embedder.js';
1
2
  import type { RememberInput, RememberResult, RecallInput, ForgetInput, ForgetResult, LearnInput, LearnResult, Entity } from './types.js';
2
3
  export declare function remember(args: RememberInput): RememberResult;
3
4
  export declare function recall(args: RecallInput): Entity[];
@@ -6,7 +7,6 @@ export declare function recallWithConflicts(args: RecallInput): Promise<{
6
7
  entities: Entity[];
7
8
  conflicts: string[];
8
9
  }>;
9
- export { consolidate } from './consolidator.js';
10
10
  export { exportMemories, importMemories } from './serializer.js';
11
11
  export declare function learn(args: LearnInput): LearnResult;
12
12
  export declare function forget(args: ForgetInput): ForgetResult;
@@ -15,11 +15,17 @@ export declare function setPinned(name: string, pinned: boolean): {
15
15
  pinned: boolean;
16
16
  found: boolean;
17
17
  };
18
- export declare function reindex(opts?: {
19
- namespace?: string;
20
- }): Promise<{
18
+ export interface ReindexResult {
21
19
  processed: number;
22
20
  embedded: number;
23
21
  skipped: number;
24
- }>;
22
+ outcomes: Record<EmbedOutcome | 'entity_missing' | 'nothing_to_embed', number>;
23
+ failed: number;
24
+ missingVectors: number;
25
+ missingVectorsDatabaseWide: number;
26
+ pendingReindexCleared: boolean;
27
+ }
28
+ export declare function reindex(opts?: {
29
+ namespace?: string;
30
+ }): Promise<ReindexResult>;
25
31
  //# sourceMappingURL=operations.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"operations.d.ts","sourceRoot":"","sources":["../../src/core/operations.ts"],"names":[],"mappings":"AAmBA,OAAO,KAAK,EACV,aAAa,EACb,cAAc,EACd,WAAW,EACX,WAAW,EACX,YAAY,EACZ,UAAU,EACV,WAAW,EACX,MAAM,EACP,MAAM,YAAY,CAAC;AAiCpB,wBAAgB,QAAQ,CAAC,IAAI,EAAE,aAAa,GAAG,cAAc,CAgF5D;AAQD,wBAAgB,MAAM,CAAC,IAAI,EAAE,WAAW,GAAG,MAAM,EAAE,CAmBlD;AA4DD,wBAAsB,cAAc,CAAC,IAAI,EAAE,WAAW,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,CAuBzE;AASD,wBAAsB,mBAAmB,CAAC,IAAI,EAAE,WAAW;;;GAK1D;AAGD,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAGhD,OAAO,EAAE,cAAc,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AAYjE,wBAAgB,KAAK,CAAC,IAAI,EAAE,UAAU,GAAG,WAAW,CAmBnD;AAMD,wBAAgB,MAAM,CAAC,IAAI,EAAE,WAAW,GAAG,YAAY,CAuBtD;AAYD,wBAAgB,SAAS,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,GAAG;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,OAAO,CAAC;IAAC,KAAK,EAAE,OAAO,CAAA;CAAE,CAe1G;AAOD,wBAAsB,OAAO,CAAC,IAAI,CAAC,EAAE;IAAE,SAAS,CAAC,EAAE,MAAM,CAAA;CAAE,GAAG,OAAO,CAAC;IACpE,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,MAAM,CAAC;CACjB,CAAC,CAuDD"}
1
+ {"version":3,"file":"operations.d.ts","sourceRoot":"","sources":["../../src/core/operations.ts"],"names":[],"mappings":"AAkBA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AAGlD,OAAO,KAAK,EACV,aAAa,EACb,cAAc,EACd,WAAW,EACX,WAAW,EACX,YAAY,EACZ,UAAU,EACV,WAAW,EACX,MAAM,EACP,MAAM,YAAY,CAAC;AAgDpB,wBAAgB,QAAQ,CAAC,IAAI,EAAE,aAAa,GAAG,cAAc,CAgF5D;AAUD,wBAAgB,MAAM,CAAC,IAAI,EAAE,WAAW,GAAG,MAAM,EAAE,CAGlD;AAsHD,wBAAsB,cAAc,CAAC,IAAI,EAAE,WAAW,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,CAezE;AASD,wBAAsB,mBAAmB,CAAC,IAAI,EAAE,WAAW;;;GAK1D;AAGD,OAAO,EAAE,cAAc,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AAYjE,wBAAgB,KAAK,CAAC,IAAI,EAAE,UAAU,GAAG,WAAW,CAmBnD;AAMD,wBAAgB,MAAM,CAAC,IAAI,EAAE,WAAW,GAAG,YAAY,CAuBtD;AAYD,wBAAgB,SAAS,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,GAAG;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,OAAO,CAAC;IAAC,KAAK,EAAE,OAAO,CAAA;CAAE,CAe1G;AAED,MAAM,WAAW,aAAa;IAC5B,SAAS,EAAE,MAAM,CAAC;IAElB,QAAQ,EAAE,MAAM,CAAC;IAEjB,OAAO,EAAE,MAAM,CAAC;IAEhB,QAAQ,EAAE,MAAM,CAAC,YAAY,GAAG,gBAAgB,GAAG,kBAAkB,EAAE,MAAM,CAAC,CAAC;IAgB/E,MAAM,EAAE,MAAM,CAAC;IAYf,cAAc,EAAE,MAAM,CAAC;IAOvB,0BAA0B,EAAE,MAAM,CAAC;IAEnC,qBAAqB,EAAE,OAAO,CAAC;CAChC;AAwCD,wBAAsB,OAAO,CAAC,IAAI,CAAC,EAAE;IAAE,SAAS,CAAC,EAAE,MAAM,CAAA;CAAE,GAAG,OAAO,CAAC,aAAa,CAAC,CAwInF"}
@@ -1,9 +1,10 @@
1
1
  import { getDatabase, clearPendingReindexFlag } from '../db.js';
2
+ import { hasSearchableTerms } from '../storage/fts-index.js';
2
3
  import { KnowledgeGraph } from '../knowledge-graph.js';
3
4
  import { rankEntities } from './scoring.js';
4
5
  import { getProjectName } from './paths.js';
5
6
  import { createExplicitLesson } from './lesson-engine.js';
6
- import { embedAndStore, isEmbeddingAvailable, embedText, scheduleEmbedAndStore, vectorSearch } from './embedder.js';
7
+ import { embedAndStore, isEmbeddingAvailable, embedText, scheduleEmbedAndStore, vectorSearch, vectorSimilarity, MAX_VECTOR_DISTANCE } from './embedder.js';
7
8
  import { autoTagAndApply } from './auto-tagger.js';
8
9
  import { detectCapabilities } from './config.js';
9
10
  function buildLocalMetadata(existingMetadata, overrides) {
@@ -21,6 +22,9 @@ function buildLocalMetadata(existingMetadata, overrides) {
21
22
  function recallTagFilter(args) {
22
23
  return args.cross_project ? undefined : args.tag;
23
24
  }
25
+ function buildRelevanceMap(entities) {
26
+ return new Map(entities.map((entity, index) => [entity.name, 1 - index / (entities.length + 1)]));
27
+ }
24
28
  export function remember(args) {
25
29
  const db = getDatabase();
26
30
  const kg = new KnowledgeGraph(db);
@@ -84,19 +88,22 @@ export function remember(args) {
84
88
  };
85
89
  }
86
90
  export function recall(args) {
87
- const db = getDatabase();
88
- const kg = new KnowledgeGraph(db);
91
+ const { entities, relevanceMap } = searchAndScore(args);
92
+ return rankEntities(entities, relevanceMap).slice(0, args.limit ?? 20);
93
+ }
94
+ function searchAndScore(args) {
95
+ const kg = new KnowledgeGraph(getDatabase());
89
96
  const entities = kg.search(args.query, {
90
97
  tag: recallTagFilter(args),
91
98
  limit: args.limit,
92
99
  includeArchived: args.include_archived,
93
100
  namespace: args.namespace,
94
101
  });
95
- const relevanceMap = new Map();
96
- for (const e of entities) {
97
- relevanceMap.set(e.name, args.query ? 1.0 : 0.5);
98
- }
99
- return rankEntities(entities, relevanceMap).slice(0, args.limit ?? 20);
102
+ return {
103
+ kg,
104
+ entities,
105
+ relevanceMap: args.query ? buildRelevanceMap(entities) : new Map(),
106
+ };
100
107
  }
101
108
  async function supplementWithVectors(query, args, kg, merged, relevanceMap) {
102
109
  if (!isEmbeddingAvailable())
@@ -108,7 +115,10 @@ async function supplementWithVectors(query, args, kg, merged, relevanceMap) {
108
115
  const vectorHits = vectorSearch(queryEmb, args.limit ?? 20);
109
116
  if (vectorHits.length === 0)
110
117
  return;
111
- const hitIds = vectorHits.map(h => h.id);
118
+ const alreadyMerged = new Set(merged.map(e => e.id));
119
+ const hitIds = vectorHits.map(h => h.id).filter(id => !alreadyMerged.has(id));
120
+ if (hitIds.length === 0)
121
+ return;
112
122
  const hitEntities = kg.getEntitiesByIds(hitIds, {
113
123
  includeArchived: args.include_archived === true,
114
124
  namespace: args.namespace,
@@ -119,28 +129,17 @@ async function supplementWithVectors(query, args, kg, merged, relevanceMap) {
119
129
  if (existingNames.has(entity.name))
120
130
  continue;
121
131
  merged.push(entity);
122
- const dist = vectorHits.find(h => h.id === entity.id)?.distance ?? 1;
123
- relevanceMap.set(entity.name, Math.max(0, 1 - dist));
132
+ const dist = vectorHits.find(h => h.id === entity.id)?.distance ?? MAX_VECTOR_DISTANCE;
133
+ relevanceMap.set(entity.name, vectorSimilarity(dist));
124
134
  }
125
135
  }
126
136
  catch {
127
137
  }
128
138
  }
129
139
  export async function recallEnhanced(args) {
130
- const db = getDatabase();
131
- const kg = new KnowledgeGraph(db);
132
- const entities = kg.search(args.query, {
133
- tag: recallTagFilter(args),
134
- limit: args.limit,
135
- includeArchived: args.include_archived,
136
- namespace: args.namespace,
137
- });
138
- const relevanceMap = new Map();
139
- for (const e of entities) {
140
- relevanceMap.set(e.name, args.query ? 1.0 : 0.5);
141
- }
140
+ const { kg, entities, relevanceMap } = searchAndScore(args);
142
141
  const mergedEntities = [...entities];
143
- if (args.query) {
142
+ if (args.query && hasSearchableTerms(args.query)) {
144
143
  await supplementWithVectors(args.query, args, kg, mergedEntities, relevanceMap);
145
144
  }
146
145
  return rankEntities(mergedEntities, relevanceMap).slice(0, args.limit ?? 20);
@@ -151,7 +150,6 @@ export async function recallWithConflicts(args) {
151
150
  const conflicts = kg.findConflicts(entities.map((e) => e.name));
152
151
  return { entities, conflicts };
153
152
  }
154
- export { consolidate } from './consolidator.js';
155
153
  export { exportMemories, importMemories } from './serializer.js';
156
154
  export function learn(args) {
157
155
  const projectName = getProjectName();
@@ -200,6 +198,16 @@ export function setPinned(name, pinned) {
200
198
  });
201
199
  return { name, pinned, found: true };
202
200
  }
201
+ function countMissingVectors(db, namespace) {
202
+ const row = db.prepare(`
203
+ SELECT COUNT(*) AS n FROM entities e
204
+ WHERE e.status = 'active'
205
+ ${namespace ? 'AND e.namespace = ?' : ''}
206
+ AND EXISTS (SELECT 1 FROM observations o WHERE o.entity_id = e.id AND TRIM(o.content) <> '')
207
+ AND NOT EXISTS (SELECT 1 FROM entities_vec v WHERE v.rowid = e.id)
208
+ `).get(...(namespace ? [namespace] : []));
209
+ return row.n;
210
+ }
203
211
  export async function reindex(opts) {
204
212
  if (!isEmbeddingAvailable()) {
205
213
  throw new Error('No embedding provider available. Configure OpenAI API key, Ollama, or install @huggingface/transformers.');
@@ -209,32 +217,81 @@ export async function reindex(opts) {
209
217
  const namespaceFilter = opts?.namespace ? 'AND namespace = ?' : '';
210
218
  const params = opts?.namespace ? [opts.namespace] : [];
211
219
  const entities = db.prepare(`SELECT id, name FROM entities WHERE status = 'active' ${namespaceFilter} ORDER BY id`).all(...params);
220
+ const outcomes = {
221
+ stored: 0,
222
+ removed: 0,
223
+ no_embedding: 0,
224
+ dimension_mismatch: 0,
225
+ write_failed: 0,
226
+ database_closed: 0,
227
+ entity_missing: 0,
228
+ nothing_to_embed: 0,
229
+ };
212
230
  let processed = 0;
213
- let embedded = 0;
214
- let skipped = 0;
215
231
  process.stderr.write(`MeMesh: Reindexing ${entities.length} entities...\n`);
216
232
  for (const entity of entities) {
217
233
  processed++;
218
234
  const fullEntity = kg.getEntity(entity.name);
219
235
  if (!fullEntity) {
220
- skipped++;
236
+ outcomes.entity_missing++;
221
237
  continue;
222
238
  }
223
239
  const text = fullEntity.observations.join(' ');
240
+ if (text.trim() === '') {
241
+ outcomes.nothing_to_embed++;
242
+ continue;
243
+ }
224
244
  try {
225
- await embedAndStore(entity.id, text);
226
- embedded++;
245
+ outcomes[await embedAndStore(entity.id, text)]++;
227
246
  if (processed % 10 === 0) {
228
- process.stderr.write(`MeMesh: Processed ${processed}/${entities.length} (${embedded} embedded, ${skipped} skipped)\n`);
247
+ process.stderr.write(`MeMesh: Processed ${processed}/${entities.length} ` +
248
+ `(${outcomes.stored} embedded, ${processed - outcomes.stored} skipped)\n`);
229
249
  }
230
250
  }
231
251
  catch (err) {
232
- skipped++;
252
+ outcomes.write_failed++;
233
253
  process.stderr.write(`MeMesh: Failed to embed entity ${entity.name}: ${err}\n`);
234
254
  }
235
255
  }
256
+ const embedded = outcomes.stored;
257
+ const skipped = processed - embedded;
258
+ const failed = outcomes.no_embedding +
259
+ outcomes.dimension_mismatch +
260
+ outcomes.write_failed +
261
+ outcomes.database_closed;
262
+ const missingVectors = countMissingVectors(db, opts?.namespace);
263
+ const missingVectorsDatabaseWide = opts?.namespace
264
+ ? countMissingVectors(db)
265
+ : missingVectors;
236
266
  process.stderr.write(`MeMesh: Reindex complete. ${embedded}/${processed} entities embedded.\n`);
237
- clearPendingReindexFlag();
238
- return { processed, embedded, skipped };
267
+ if (outcomes.dimension_mismatch > 0) {
268
+ process.stderr.write(`MeMesh: ${outcomes.dimension_mismatch} entities were skipped because the provider's ` +
269
+ `embedding dimension does not match this database's vector index. Rebuild it with ` +
270
+ `'memesh reindex --vectors'.\n`);
271
+ }
272
+ const pendingReindexCleared = missingVectorsDatabaseWide === 0 && failed === 0;
273
+ if (pendingReindexCleared) {
274
+ clearPendingReindexFlag();
275
+ }
276
+ else if (missingVectorsDatabaseWide > 0) {
277
+ process.stderr.write(`MeMesh: ${missingVectorsDatabaseWide} active memories still have no vector` +
278
+ `${opts?.namespace ? ' (across all namespaces)' : ''}, so the ` +
279
+ `reindex-needed flag was left set.\n`);
280
+ }
281
+ else {
282
+ process.stderr.write(`MeMesh: every memory has a vector, but ${failed} could not be regenerated, ` +
283
+ `so those still hold their previous embedding and the reindex-needed flag ` +
284
+ `was left set.\n`);
285
+ }
286
+ return {
287
+ processed,
288
+ embedded,
289
+ skipped,
290
+ outcomes,
291
+ failed,
292
+ missingVectors,
293
+ missingVectorsDatabaseWide,
294
+ pendingReindexCleared,
295
+ };
239
296
  }
240
297
  //# sourceMappingURL=operations.js.map