@199-bio/engram 0.3.2 → 0.4.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.
@@ -1 +1 @@
1
- {"version":3,"file":"extractor.d.ts","sourceRoot":"","sources":["../../src/graph/extractor.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,MAAM,WAAW,eAAe;IAC9B,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,QAAQ,GAAG,OAAO,GAAG,SAAS,GAAG,OAAO,GAAG,cAAc,CAAC;IAChE,UAAU,EAAE,MAAM,CAAC;IACnB,IAAI,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,GAAG,EAAE,MAAM,CAAA;KAAE,CAAC;CACtC;AAwFD,qBAAa,eAAe;IAC1B;;OAEG;IACH,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,eAAe,EAAE;IA8D3C;;OAEG;IACH,oBAAoB,CAAC,IAAI,EAAE,MAAM,GAAG,eAAe,EAAE;IAuFrD;;OAEG;IACH,OAAO,CAAC,WAAW;IAInB;;OAEG;IACH,cAAc,CAAC,IAAI,EAAE,MAAM,GAAG,eAAe,EAAE;IAe/C;;OAEG;IACH,OAAO,CAAC,uBAAuB;IAyC/B;;OAEG;IACH,OAAO,CAAC,sBAAsB;IAuC9B;;OAEG;IACH,OAAO,CAAC,oBAAoB;IAiC5B;;OAEG;IACH,oBAAoB,CAAC,IAAI,EAAE,MAAM,GAAG,KAAK,CAAC;QACxC,OAAO,EAAE,MAAM,CAAC;QAChB,QAAQ,EAAE,MAAM,CAAC;QACjB,MAAM,EAAE,MAAM,CAAC;QACf,UAAU,EAAE,MAAM,CAAC;KACpB,CAAC;CA4BH;AAGD,eAAO,MAAM,eAAe,iBAAwB,CAAC"}
1
+ {"version":3,"file":"extractor.d.ts","sourceRoot":"","sources":["../../src/graph/extractor.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,MAAM,WAAW,eAAe;IAC9B,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,QAAQ,GAAG,OAAO,GAAG,SAAS,GAAG,OAAO,GAAG,cAAc,CAAC;IAChE,UAAU,EAAE,MAAM,CAAC;IACnB,IAAI,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,GAAG,EAAE,MAAM,CAAA;KAAE,CAAC;CACtC;AAwID,qBAAa,eAAe;IAC1B;;OAEG;IACH,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,eAAe,EAAE;IA8D3C;;OAEG;IACH,oBAAoB,CAAC,IAAI,EAAE,MAAM,GAAG,eAAe,EAAE;IAuFrD;;OAEG;IACH,OAAO,CAAC,WAAW;IAInB;;OAEG;IACH,cAAc,CAAC,IAAI,EAAE,MAAM,GAAG,eAAe,EAAE;IAe/C;;OAEG;IACH,OAAO,CAAC,uBAAuB;IAyC/B;;OAEG;IACH,OAAO,CAAC,sBAAsB;IAuC9B;;OAEG;IACH,OAAO,CAAC,oBAAoB;IAiC5B;;OAEG;IACH,oBAAoB,CAAC,IAAI,EAAE,MAAM,GAAG,KAAK,CAAC;QACxC,OAAO,EAAE,MAAM,CAAC;QAChB,QAAQ,EAAE,MAAM,CAAC;QACjB,MAAM,EAAE,MAAM,CAAC;QACf,UAAU,EAAE,MAAM,CAAC;KACpB,CAAC;CA4BH;AAGD,eAAO,MAAM,eAAe,iBAAwB,CAAC"}
package/dist/index.js CHANGED
@@ -42,7 +42,7 @@ async function initialize() {
42
42
  // ============ MCP Server ============
43
43
  const server = new Server({
44
44
  name: "engram",
45
- version: "0.3.2",
45
+ version: "0.4.0",
46
46
  }, {
47
47
  capabilities: {
48
48
  tools: {},
@@ -136,68 +136,6 @@ const TOOLS = [
136
136
  openWorldHint: false,
137
137
  },
138
138
  },
139
- {
140
- name: "query_entity",
141
- description: "Get all stored information about a specific person, place, or organization. Use after recall to get deeper details about an entity mentioned in search results.",
142
- inputSchema: {
143
- type: "object",
144
- properties: {
145
- entity: {
146
- type: "string",
147
- description: "Entity name to query",
148
- },
149
- },
150
- required: ["entity"],
151
- },
152
- annotations: {
153
- title: "Query Entity",
154
- readOnlyHint: true,
155
- destructiveHint: false,
156
- idempotentHint: true,
157
- openWorldHint: false,
158
- },
159
- },
160
- {
161
- name: "list_entities",
162
- description: "List all known entities (people, places, organizations, etc.). Use to browse the knowledge graph or find entity names for query_entity.",
163
- inputSchema: {
164
- type: "object",
165
- properties: {
166
- type: {
167
- type: "string",
168
- enum: ["person", "place", "concept", "event", "organization"],
169
- description: "Filter by entity type (optional)",
170
- },
171
- limit: {
172
- type: "number",
173
- description: "Maximum number of entities to return",
174
- default: 50,
175
- },
176
- },
177
- },
178
- annotations: {
179
- title: "List Entities",
180
- readOnlyHint: true,
181
- destructiveHint: false,
182
- idempotentHint: true,
183
- openWorldHint: false,
184
- },
185
- },
186
- {
187
- name: "stats",
188
- description: "Get memory statistics (counts of memories, entities, relations, observations)",
189
- inputSchema: {
190
- type: "object",
191
- properties: {},
192
- },
193
- annotations: {
194
- title: "Get Statistics",
195
- readOnlyHint: true,
196
- destructiveHint: false,
197
- idempotentHint: true,
198
- openWorldHint: false,
199
- },
200
- },
201
139
  {
202
140
  name: "engram_web",
203
141
  description: "Launch the Engram web interface for browsing, searching, and editing memories visually. Returns a URL to open in your browser.",
@@ -307,81 +245,6 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
307
245
  ],
308
246
  };
309
247
  }
310
- case "query_entity": {
311
- const { entity: entityName } = args;
312
- const details = graph.getEntityDetails(entityName);
313
- if (!details) {
314
- return {
315
- content: [
316
- {
317
- type: "text",
318
- text: JSON.stringify({ success: false, error: "Entity not found" }),
319
- },
320
- ],
321
- };
322
- }
323
- return {
324
- content: [
325
- {
326
- type: "text",
327
- text: JSON.stringify({
328
- entity: {
329
- id: details.id,
330
- name: details.name,
331
- type: details.type,
332
- created_at: details.created_at.toISOString(),
333
- },
334
- observations: details.observations.map((o) => ({
335
- content: o.content.substring(0, 200) + (o.content.length > 200 ? "..." : ""),
336
- confidence: o.confidence,
337
- valid_from: o.valid_from.toISOString(),
338
- })),
339
- relations_from: details.relationsFrom.map((r) => ({
340
- type: r.type,
341
- to: r.targetEntity.name,
342
- })),
343
- relations_to: details.relationsTo.map((r) => ({
344
- type: r.type,
345
- from: r.sourceEntity.name,
346
- })),
347
- }, null, 2),
348
- },
349
- ],
350
- };
351
- }
352
- case "list_entities": {
353
- const { type, limit = 50 } = args;
354
- const entities = graph.listEntities(type, limit);
355
- return {
356
- content: [
357
- {
358
- type: "text",
359
- text: JSON.stringify({
360
- entities: entities.map((e) => ({
361
- id: e.id,
362
- name: e.name,
363
- type: e.type,
364
- })),
365
- count: entities.length,
366
- }, null, 2),
367
- },
368
- ],
369
- };
370
- }
371
- case "stats": {
372
- const stats = db.getStats();
373
- return {
374
- content: [
375
- {
376
- type: "text",
377
- text: JSON.stringify({
378
- ...stats,
379
- database_path: DB_FILE,
380
- }, null, 2),
381
- },
382
- ],
383
- };
384
- }
385
248
  case "engram_web": {
386
249
  const { port = 3847 } = args;
387
250
  // Create or reuse web server
@@ -1 +1 @@
1
- {"version":3,"file":"database.d.ts","sourceRoot":"","sources":["../../src/storage/database.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"database.d.ts","sourceRoot":"","sources":["../../src/storage/database.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../../src/web/server.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAMH,OAAO,EAAE,cAAc,EAAE,MAAM,wBAAwB,CAAC;AACxD,OAAO,EAAE,cAAc,EAAE,MAAM,6BAA6B,CAAC;AAC7D,OAAO,EAAE,YAAY,EAAE,MAAM,wBAAwB,CAAC;AAiBtD,UAAU,gBAAgB;IACxB,EAAE,EAAE,cAAc,CAAC;IACnB,KAAK,EAAE,cAAc,CAAC;IACtB,MAAM,EAAE,YAAY,CAAC;IACrB,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED,qBAAa,eAAe;IAC1B,OAAO,CAAC,MAAM,CAA4B;IAC1C,OAAO,CAAC,EAAE,CAAiB;IAC3B,OAAO,CAAC,KAAK,CAAiB;IAC9B,OAAO,CAAC,MAAM,CAAe;IAC7B,OAAO,CAAC,IAAI,CAAS;gBAET,OAAO,EAAE,gBAAgB;IAO/B,KAAK,IAAI,OAAO,CAAC,MAAM,CAAC;IAkB9B,IAAI,IAAI,IAAI;YAOE,aAAa;YA+Bb,SAAS;YAgIT,WAAW;IAgCzB,OAAO,CAAC,SAAS;CAclB"}
1
+ {"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../../src/web/server.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAMH,OAAO,EAAE,cAAc,EAAE,MAAM,wBAAwB,CAAC;AACxD,OAAO,EAAE,cAAc,EAAE,MAAM,6BAA6B,CAAC;AAC7D,OAAO,EAAE,YAAY,EAAE,MAAM,wBAAwB,CAAC;AAiBtD,UAAU,gBAAgB;IACxB,EAAE,EAAE,cAAc,CAAC;IACnB,KAAK,EAAE,cAAc,CAAC;IACtB,MAAM,EAAE,YAAY,CAAC;IACrB,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED,qBAAa,eAAe;IAC1B,OAAO,CAAC,MAAM,CAA4B;IAC1C,OAAO,CAAC,EAAE,CAAiB;IAC3B,OAAO,CAAC,KAAK,CAAiB;IAC9B,OAAO,CAAC,MAAM,CAAe;IAC7B,OAAO,CAAC,IAAI,CAAS;gBAET,OAAO,EAAE,gBAAgB;IAO/B,KAAK,IAAI,OAAO,CAAC,MAAM,CAAC;IAkB9B,IAAI,IAAI,IAAI;YAOE,aAAa;YA+Bb,SAAS;YAyKT,WAAW;IAgCzB,OAAO,CAAC,SAAS;CAclB"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@199-bio/engram",
3
- "version": "0.3.2",
3
+ "version": "0.4.0",
4
4
  "description": "Give Claude a perfect memory. Local-first MCP server with hybrid search.",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
@@ -10,25 +10,73 @@ export interface ExtractedEntity {
10
10
  span: { start: number; end: number };
11
11
  }
12
12
 
13
- // Common words that look like names but aren't
13
+ // Common words that look like names but aren't (including verbs, adjectives, common nouns)
14
14
  const STOPWORDS = new Set([
15
+ // Articles, conjunctions, prepositions
15
16
  "the", "a", "an", "and", "or", "but", "in", "on", "at", "to", "for",
16
17
  "of", "with", "by", "from", "as", "is", "was", "are", "were", "been",
17
18
  "be", "have", "has", "had", "do", "does", "did", "will", "would",
18
19
  "could", "should", "may", "might", "must", "shall", "can", "need",
20
+ // Pronouns
19
21
  "this", "that", "these", "those", "i", "you", "he", "she", "it",
20
22
  "we", "they", "what", "which", "who", "whom", "whose", "where",
21
23
  "when", "why", "how", "all", "each", "every", "both", "few", "more",
22
24
  "most", "other", "some", "such", "no", "not", "only", "same", "so",
23
25
  "than", "too", "very", "just", "also", "now", "here", "there", "then",
26
+ // Conjunctions
24
27
  "if", "because", "while", "although", "though", "after", "before",
25
28
  "since", "until", "unless", "however", "therefore", "thus", "hence",
29
+ // Days and months
26
30
  "monday", "tuesday", "wednesday", "thursday", "friday", "saturday", "sunday",
27
31
  "january", "february", "march", "april", "may", "june", "july",
28
32
  "august", "september", "october", "november", "december",
33
+ // Time words
29
34
  "today", "tomorrow", "yesterday", "morning", "afternoon", "evening", "night",
35
+ // Common verbs (often capitalized at sentence start)
30
36
  "said", "says", "told", "asked", "replied", "answered", "mentioned",
31
37
  "think", "know", "believe", "feel", "want", "need", "like", "love",
38
+ "crashed", "gets", "getting", "got", "planning", "planned", "plans",
39
+ "working", "worked", "works", "going", "went", "gone", "coming", "came",
40
+ "looking", "looked", "looks", "trying", "tried", "tries", "using", "used",
41
+ "making", "made", "makes", "taking", "took", "takes", "giving", "gave",
42
+ "seeing", "saw", "seen", "being", "having", "doing", "saying", "getting",
43
+ "finding", "found", "keeping", "kept", "letting", "let", "putting", "put",
44
+ "running", "ran", "calling", "called", "moving", "moved", "living", "lived",
45
+ "starting", "started", "seems", "seemed", "showing", "showed", "hearing",
46
+ "playing", "played", "standing", "stood", "understanding", "understood",
47
+ "turning", "turned", "following", "followed", "watching", "watched",
48
+ "adding", "added", "changing", "changed", "writing", "wrote", "reading",
49
+ "learning", "learned", "growing", "grew", "opening", "opened", "walking",
50
+ "winning", "won", "offering", "offered", "remembering", "remembered",
51
+ "considering", "considered", "appearing", "appeared", "buying", "bought",
52
+ "waiting", "waited", "serving", "served", "dying", "died", "sending", "sent",
53
+ "building", "built", "staying", "stayed", "falling", "fell", "cutting", "cut",
54
+ "reaching", "reached", "killing", "killed", "raising", "raised", "passing",
55
+ "selling", "sold", "deciding", "decided", "returning", "returned",
56
+ // Common adjectives (often capitalized at sentence start)
57
+ "good", "bad", "great", "small", "large", "big", "little", "old", "young",
58
+ "new", "first", "last", "long", "short", "high", "low", "right", "wrong",
59
+ "next", "early", "late", "hard", "easy", "clear", "full", "empty", "ready",
60
+ "sure", "open", "closed", "free", "busy", "hot", "cold", "warm", "cool",
61
+ "fast", "slow", "strong", "weak", "deep", "wide", "near", "far", "dark",
62
+ "light", "heavy", "simple", "complex", "real", "true", "false", "best",
63
+ "worst", "happy", "sad", "angry", "afraid", "sorry", "glad", "nice",
64
+ "fine", "okay", "different", "similar", "same", "special", "important",
65
+ "interesting", "beautiful", "wonderful", "terrible", "amazing", "awesome",
66
+ // Common nouns (sentence starters)
67
+ "people", "time", "year", "years", "way", "day", "days", "man", "woman",
68
+ "child", "children", "world", "life", "hand", "part", "place", "case",
69
+ "week", "weeks", "company", "system", "program", "question", "work",
70
+ "government", "number", "point", "home", "water", "room", "mother",
71
+ "area", "money", "story", "fact", "month", "months", "lot", "right",
72
+ "study", "book", "books", "eye", "eyes", "job", "word", "words",
73
+ "business", "issue", "issues", "side", "kind", "head", "house", "service",
74
+ "friend", "friends", "power", "hour", "hours", "game", "line", "end",
75
+ "member", "members", "law", "car", "city", "community", "name", "names",
76
+ "team", "minute", "minutes", "idea", "ideas", "body", "information",
77
+ "back", "parent", "parents", "face", "others", "level", "office", "door",
78
+ "health", "person", "art", "war", "history", "party", "result", "change",
79
+ "reason", "research", "girl", "guy", "moment", "air", "teacher", "force",
32
80
  ]);
33
81
 
34
82
  // Common titles that precede names
package/src/index.ts CHANGED
@@ -60,7 +60,7 @@ async function initialize(): Promise<void> {
60
60
  const server = new Server(
61
61
  {
62
62
  name: "engram",
63
- version: "0.3.2",
63
+ version: "0.4.0",
64
64
  },
65
65
  {
66
66
  capabilities: {
@@ -159,68 +159,6 @@ const TOOLS = [
159
159
  openWorldHint: false,
160
160
  },
161
161
  },
162
- {
163
- name: "query_entity",
164
- description: "Get all stored information about a specific person, place, or organization. Use after recall to get deeper details about an entity mentioned in search results.",
165
- inputSchema: {
166
- type: "object" as const,
167
- properties: {
168
- entity: {
169
- type: "string",
170
- description: "Entity name to query",
171
- },
172
- },
173
- required: ["entity"],
174
- },
175
- annotations: {
176
- title: "Query Entity",
177
- readOnlyHint: true,
178
- destructiveHint: false,
179
- idempotentHint: true,
180
- openWorldHint: false,
181
- },
182
- },
183
- {
184
- name: "list_entities",
185
- description: "List all known entities (people, places, organizations, etc.). Use to browse the knowledge graph or find entity names for query_entity.",
186
- inputSchema: {
187
- type: "object" as const,
188
- properties: {
189
- type: {
190
- type: "string",
191
- enum: ["person", "place", "concept", "event", "organization"],
192
- description: "Filter by entity type (optional)",
193
- },
194
- limit: {
195
- type: "number",
196
- description: "Maximum number of entities to return",
197
- default: 50,
198
- },
199
- },
200
- },
201
- annotations: {
202
- title: "List Entities",
203
- readOnlyHint: true,
204
- destructiveHint: false,
205
- idempotentHint: true,
206
- openWorldHint: false,
207
- },
208
- },
209
- {
210
- name: "stats",
211
- description: "Get memory statistics (counts of memories, entities, relations, observations)",
212
- inputSchema: {
213
- type: "object" as const,
214
- properties: {},
215
- },
216
- annotations: {
217
- title: "Get Statistics",
218
- readOnlyHint: true,
219
- destructiveHint: false,
220
- idempotentHint: true,
221
- openWorldHint: false,
222
- },
223
- },
224
162
  {
225
163
  name: "engram_web",
226
164
  description: "Launch the Engram web interface for browsing, searching, and editing memories visually. Returns a URL to open in your browser.",
@@ -355,93 +293,6 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
355
293
  };
356
294
  }
357
295
 
358
- case "query_entity": {
359
- const { entity: entityName } = args as { entity: string };
360
-
361
- const details = graph.getEntityDetails(entityName);
362
-
363
- if (!details) {
364
- return {
365
- content: [
366
- {
367
- type: "text" as const,
368
- text: JSON.stringify({ success: false, error: "Entity not found" }),
369
- },
370
- ],
371
- };
372
- }
373
-
374
- return {
375
- content: [
376
- {
377
- type: "text" as const,
378
- text: JSON.stringify({
379
- entity: {
380
- id: details.id,
381
- name: details.name,
382
- type: details.type,
383
- created_at: details.created_at.toISOString(),
384
- },
385
- observations: details.observations.map((o) => ({
386
- content: o.content.substring(0, 200) + (o.content.length > 200 ? "..." : ""),
387
- confidence: o.confidence,
388
- valid_from: o.valid_from.toISOString(),
389
- })),
390
- relations_from: details.relationsFrom.map((r) => ({
391
- type: r.type,
392
- to: r.targetEntity.name,
393
- })),
394
- relations_to: details.relationsTo.map((r) => ({
395
- type: r.type,
396
- from: r.sourceEntity.name,
397
- })),
398
- }, null, 2),
399
- },
400
- ],
401
- };
402
- }
403
-
404
- case "list_entities": {
405
- const { type, limit = 50 } = args as {
406
- type?: "person" | "place" | "concept" | "event" | "organization";
407
- limit?: number;
408
- };
409
-
410
- const entities = graph.listEntities(type, limit);
411
-
412
- return {
413
- content: [
414
- {
415
- type: "text" as const,
416
- text: JSON.stringify({
417
- entities: entities.map((e) => ({
418
- id: e.id,
419
- name: e.name,
420
- type: e.type,
421
- })),
422
- count: entities.length,
423
- }, null, 2),
424
- },
425
- ],
426
- };
427
- }
428
-
429
- case "stats": {
430
- const stats = db.getStats();
431
-
432
- return {
433
- content: [
434
- {
435
- type: "text" as const,
436
- text: JSON.stringify({
437
- ...stats,
438
- database_path: DB_FILE,
439
- }, null, 2),
440
- },
441
- ],
442
- };
443
- }
444
-
445
296
  case "engram_web": {
446
297
  const { port = 3847 } = args as { port?: number };
447
298
 
@@ -358,6 +358,41 @@ export class EngramDatabase {
358
358
  return shared / total * 0.7;
359
359
  }
360
360
 
361
+ /**
362
+ * Merge two entities: transfers all observations and relations from source to target, then deletes source
363
+ */
364
+ mergeEntities(targetId: string, sourceId: string): { observationsMoved: number; relationsMoved: number } {
365
+ // Move observations from source to target
366
+ const obsResult = this.db.prepare(
367
+ "UPDATE observations SET entity_id = ? WHERE entity_id = ?"
368
+ ).run(targetId, sourceId);
369
+
370
+ // Move relations where source is from_entity
371
+ const relFromResult = this.db.prepare(
372
+ "UPDATE relations SET from_entity = ? WHERE from_entity = ?"
373
+ ).run(targetId, sourceId);
374
+
375
+ // Move relations where source is to_entity
376
+ const relToResult = this.db.prepare(
377
+ "UPDATE relations SET to_entity = ? WHERE to_entity = ?"
378
+ ).run(targetId, sourceId);
379
+
380
+ // Delete duplicate relations (same from, to, type)
381
+ this.db.prepare(`
382
+ DELETE FROM relations WHERE id NOT IN (
383
+ SELECT MIN(id) FROM relations GROUP BY from_entity, to_entity, type
384
+ )
385
+ `).run();
386
+
387
+ // Delete the source entity
388
+ this.deleteEntity(sourceId);
389
+
390
+ return {
391
+ observationsMoved: obsResult.changes,
392
+ relationsMoved: relFromResult.changes + relToResult.changes,
393
+ };
394
+ }
395
+
361
396
  /**
362
397
  * Find all potential duplicate entities
363
398
  */
package/src/web/server.ts CHANGED
@@ -226,6 +226,47 @@ export class EngramWebServer {
226
226
  return;
227
227
  }
228
228
 
229
+ // GET /api/tidy - analyze duplicates
230
+ if (pathname === "/api/tidy" && method === "GET") {
231
+ const duplicates = this.db.findDuplicateEntities();
232
+ res.end(JSON.stringify({
233
+ duplicate_groups: duplicates.map((d) => ({
234
+ keep: { id: d.entity.id, name: d.entity.name, type: d.entity.type },
235
+ merge: d.potentialDuplicates.map((p) => ({
236
+ id: p.id,
237
+ name: p.name,
238
+ type: p.type,
239
+ })),
240
+ })),
241
+ total_duplicates: duplicates.reduce((sum, d) => sum + d.potentialDuplicates.length, 0),
242
+ }));
243
+ return;
244
+ }
245
+
246
+ // POST /api/tidy - merge duplicates
247
+ if (pathname === "/api/tidy" && method === "POST") {
248
+ const duplicates = this.db.findDuplicateEntities();
249
+ let totalMerged = 0;
250
+ let observationsMoved = 0;
251
+ let relationsMoved = 0;
252
+
253
+ for (const group of duplicates) {
254
+ for (const dupe of group.potentialDuplicates) {
255
+ const result = this.db.mergeEntities(group.entity.id, dupe.id);
256
+ totalMerged++;
257
+ observationsMoved += result.observationsMoved;
258
+ relationsMoved += result.relationsMoved;
259
+ }
260
+ }
261
+
262
+ res.end(JSON.stringify({
263
+ entities_merged: totalMerged,
264
+ observations_moved: observationsMoved,
265
+ relations_moved: relationsMoved,
266
+ }));
267
+ return;
268
+ }
269
+
229
270
  // 404 for unknown API routes
230
271
  res.writeHead(404);
231
272
  res.end(JSON.stringify({ error: "Not found" }));