@vheins/local-memory-mcp 0.19.1 → 0.19.3

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.
@@ -8,8 +8,8 @@
8
8
  <link rel="preconnect" href="https://fonts.googleapis.com">
9
9
  <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
10
10
  <link href="https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700;800&family=JetBrains+Mono:wght@400;500&display=swap" rel="stylesheet">
11
- <script type="module" crossorigin src="/assets/index-BEmIBViV.js"></script>
12
- <link rel="stylesheet" crossorigin href="/assets/index-DGiNkigj.css">
11
+ <script type="module" crossorigin src="/assets/index-BQArG0_h.js"></script>
12
+ <link rel="stylesheet" crossorigin href="/assets/index-B1-RxLD9.css">
13
13
  </head>
14
14
  <body>
15
15
  <div id="app"></div>
@@ -15,7 +15,7 @@ import {
15
15
  handleTaskClaim,
16
16
  listResources,
17
17
  logger
18
- } from "../chunk-AKFMCVQ4.js";
18
+ } from "../chunk-R45NRES5.js";
19
19
 
20
20
  // src/dashboard/server.ts
21
21
  import express from "express";
@@ -1470,11 +1470,13 @@ app.use((req, res, next) => {
1470
1470
  `);
1471
1471
  }
1472
1472
  });
1473
- app.use((err, req, res, _next) => {
1474
- if (err.status === 404) return res.status(404).end();
1475
- logger.error("Unhandled error", { error: err.message });
1476
- res.status(500).end();
1477
- });
1473
+ app.use(
1474
+ (err, req, res, _next) => {
1475
+ if (err.status === 404) return res.status(404).end();
1476
+ logger.error("Unhandled error", { error: err.message });
1477
+ res.status(500).end();
1478
+ }
1479
+ );
1478
1480
  if (process.env.DASHBOARD_ENABLE_MCP === "true") {
1479
1481
  mcpClient.start().catch((e) => logger.error("MCP Client failed", { error: e.message }));
1480
1482
  }
@@ -7,6 +7,7 @@ import {
7
7
  DeleteEntitySchema,
8
8
  DeleteObservationSchema,
9
9
  DeleteRelationSchema,
10
+ KGBackfillSchema,
10
11
  MemoryAcknowledgeSchema,
11
12
  MemoryDeleteSchema,
12
13
  MemoryDetailSchema,
@@ -60,7 +61,7 @@ import {
60
61
  parseRepoInput,
61
62
  rankCompletionValues,
62
63
  toContextSlug
63
- } from "../chunk-AKFMCVQ4.js";
64
+ } from "../chunk-R45NRES5.js";
64
65
 
65
66
  // src/mcp/server.ts
66
67
  import { serveStdio } from "@modelcontextprotocol/server/stdio";
@@ -73,8 +74,8 @@ import path from "path";
73
74
  import { fileURLToPath } from "url";
74
75
  var __dirname = path.dirname(fileURLToPath(import.meta.url));
75
76
  var pkgVersion = "0.1.0";
76
- if ("0.19.1") {
77
- pkgVersion = "0.19.1";
77
+ if ("0.19.3") {
78
+ pkgVersion = "0.19.3";
78
79
  } else {
79
80
  let searchDir = __dirname;
80
81
  for (let i = 0; i < 5; i++) {
@@ -3405,6 +3406,100 @@ async function handleDeleteObservation(params, db2, _vectors) {
3405
3406
  );
3406
3407
  }
3407
3408
 
3409
+ // src/mcp/tools/kg-backfill.ts
3410
+ import { randomUUID as randomUUID6 } from "crypto";
3411
+ async function handleKGBackfill(args, db2) {
3412
+ const { repo, owner, source } = KGBackfillSchema.parse(args);
3413
+ const stats = {
3414
+ reposScanned: 0,
3415
+ itemsProcessed: 0,
3416
+ entitiesCreated: 0,
3417
+ observationsCreated: 0,
3418
+ errors: 0
3419
+ };
3420
+ const scanRepos = repo ? [repo] : db2.system.listRepoNavigation().map((r) => r.repo);
3421
+ stats.reposScanned = scanRepos.length;
3422
+ const insertEntity = db2.db.prepare(
3423
+ `INSERT OR IGNORE INTO entities (name, type, description, repo, owner, created_at, updated_at)
3424
+ VALUES (?, ?, ?, ?, ?, ?, ?)`
3425
+ );
3426
+ const insertObservation = db2.db.prepare(
3427
+ `INSERT INTO observations (id, entity_name, observation, repo, owner, created_at)
3428
+ VALUES (?, ?, ?, ?, ?, ?)`
3429
+ );
3430
+ const now = (/* @__PURE__ */ new Date()).toISOString();
3431
+ const transaction = db2.db.transaction(() => {
3432
+ for (const r of scanRepos) {
3433
+ const currentOwner = owner || "unknown";
3434
+ if (source === "memories" || source === "both") {
3435
+ const rows = db2.db.prepare("SELECT title, content FROM memories WHERE repo = ?").all(r);
3436
+ for (let i = 0; i < rows.length; i++) {
3437
+ const row = rows[i];
3438
+ const content = `${row.content || ""} ${row.title || ""}`;
3439
+ let entities;
3440
+ try {
3441
+ entities = extractEntities(content);
3442
+ } catch {
3443
+ stats.errors++;
3444
+ continue;
3445
+ }
3446
+ for (const ent of entities) {
3447
+ insertEntity.run(ent.name, ent.type, null, r, currentOwner, now, now);
3448
+ stats.entitiesCreated++;
3449
+ insertObservation.run(
3450
+ randomUUID6(),
3451
+ ent.name,
3452
+ `Mentioned in memory: ${row.title || "untitled"}`,
3453
+ r,
3454
+ currentOwner,
3455
+ now
3456
+ );
3457
+ stats.observationsCreated++;
3458
+ }
3459
+ stats.itemsProcessed++;
3460
+ if ((i + 1) % 100 === 0) {
3461
+ logger.info(`[kg-backfill] Processed ${i + 1}/${rows.length} memories in repo "${r}"`);
3462
+ }
3463
+ }
3464
+ }
3465
+ if (source === "standards" || source === "both") {
3466
+ const rows = db2.db.prepare("SELECT title, content FROM coding_standards WHERE repo = ?").all(r);
3467
+ for (let i = 0; i < rows.length; i++) {
3468
+ const row = rows[i];
3469
+ const content = `${row.content || ""} ${row.title || ""}`;
3470
+ let entities;
3471
+ try {
3472
+ entities = extractEntities(content);
3473
+ } catch {
3474
+ stats.errors++;
3475
+ continue;
3476
+ }
3477
+ for (const ent of entities) {
3478
+ insertEntity.run(ent.name, ent.type, null, r, currentOwner, now, now);
3479
+ stats.entitiesCreated++;
3480
+ insertObservation.run(
3481
+ randomUUID6(),
3482
+ ent.name,
3483
+ `Mentioned in standard: ${row.title || "untitled"}`,
3484
+ r,
3485
+ currentOwner,
3486
+ now
3487
+ );
3488
+ stats.observationsCreated++;
3489
+ }
3490
+ stats.itemsProcessed++;
3491
+ }
3492
+ }
3493
+ }
3494
+ });
3495
+ transaction();
3496
+ const summary = `${stats.reposScanned} repos, ${stats.itemsProcessed} items, ${stats.entitiesCreated} entities, ${stats.observationsCreated} observations.`;
3497
+ logger.info(`[kg-backfill] Complete: ${summary}`);
3498
+ return createMcpResponse(stats, summary, {
3499
+ contentSummary: `Backfill complete: ${summary}`
3500
+ });
3501
+ }
3502
+
3408
3503
  // src/mcp/tools/index.ts
3409
3504
  var WRITE_TOOLS = /* @__PURE__ */ new Set([
3410
3505
  "memory-store",
@@ -3435,7 +3530,8 @@ var WRITE_TOOLS = /* @__PURE__ */ new Set([
3435
3530
  "delete_entity",
3436
3531
  "create_relation",
3437
3532
  "delete_relation",
3438
- "delete_observation"
3533
+ "delete_observation",
3534
+ "kg-backfill"
3439
3535
  ]);
3440
3536
  function validateRootBoundPath(value, field, session) {
3441
3537
  if (typeof value !== "string" || !path2.isAbsolute(value)) {
@@ -3619,7 +3715,8 @@ function buildExecutors(session, options) {
3619
3715
  delete_entity: (args, db2, _vectors, _extra) => handleDeleteEntity(args, db2, _vectors),
3620
3716
  create_relation: (args, db2, _vectors, _extra) => handleCreateRelation(args, db2, _vectors),
3621
3717
  delete_relation: (args, db2, _vectors, _extra) => handleDeleteRelation(args, db2, _vectors),
3622
- delete_observation: (args, db2, _vectors, _extra) => handleDeleteObservation(args, db2, _vectors)
3718
+ delete_observation: (args, db2, _vectors, _extra) => handleDeleteObservation(args, db2, _vectors),
3719
+ "kg-backfill": (args, db2, _vectors, _extra) => handleKGBackfill(args, db2)
3623
3720
  };
3624
3721
  }
3625
3722
  function registerAllTools(server, store, vectors2, session, options) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vheins/local-memory-mcp",
3
- "version": "0.19.1",
3
+ "version": "0.19.3",
4
4
  "description": "MCP Local Memory Service for coding copilot agents",
5
5
  "mcpName": "io.github.vheins/local-memory-mcp",
6
6
  "type": "module",