@vheins/local-memory-mcp 0.19.3 → 0.19.5
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.
- package/dist/{chunk-R45NRES5.js → chunk-ZSGQQS5F.js} +58 -17
- package/dist/dashboard/public/assets/{index-BQArG0_h.js → index-Bl3hkhYk.js} +2 -2
- package/dist/dashboard/public/assets/{index-B1-RxLD9.css → index-iYrQr1US.css} +1 -1
- package/dist/dashboard/public/index.html +2 -2
- package/dist/dashboard/server.js +1 -1
- package/dist/mcp/server.js +87 -78
- package/package.json +1 -1
package/dist/mcp/server.js
CHANGED
|
@@ -61,7 +61,7 @@ import {
|
|
|
61
61
|
parseRepoInput,
|
|
62
62
|
rankCompletionValues,
|
|
63
63
|
toContextSlug
|
|
64
|
-
} from "../chunk-
|
|
64
|
+
} from "../chunk-ZSGQQS5F.js";
|
|
65
65
|
|
|
66
66
|
// src/mcp/server.ts
|
|
67
67
|
import { serveStdio } from "@modelcontextprotocol/server/stdio";
|
|
@@ -74,8 +74,8 @@ import path from "path";
|
|
|
74
74
|
import { fileURLToPath } from "url";
|
|
75
75
|
var __dirname = path.dirname(fileURLToPath(import.meta.url));
|
|
76
76
|
var pkgVersion = "0.1.0";
|
|
77
|
-
if ("0.19.
|
|
78
|
-
pkgVersion = "0.19.
|
|
77
|
+
if ("0.19.5") {
|
|
78
|
+
pkgVersion = "0.19.5";
|
|
79
79
|
} else {
|
|
80
80
|
let searchDir = __dirname;
|
|
81
81
|
for (let i = 0; i < 5; i++) {
|
|
@@ -154,7 +154,6 @@ function generateNextCode(owner, repo, entityType, storage, batchCodes) {
|
|
|
154
154
|
|
|
155
155
|
// src/mcp/tools/kg-archivist.ts
|
|
156
156
|
import { randomUUID } from "crypto";
|
|
157
|
-
import nlp from "compromise";
|
|
158
157
|
var MAX_CONTENT_LENGTH = 5e3;
|
|
159
158
|
var PRONOUNS = /* @__PURE__ */ new Set([
|
|
160
159
|
"i",
|
|
@@ -354,8 +353,9 @@ function isExcludedNoun(candidate) {
|
|
|
354
353
|
if (/^\d+$/.test(candidate)) return true;
|
|
355
354
|
return false;
|
|
356
355
|
}
|
|
357
|
-
function extractEntities(content) {
|
|
356
|
+
async function extractEntities(content) {
|
|
358
357
|
if (!content || content.trim().length === 0) return [];
|
|
358
|
+
const { default: nlp } = await import("compromise");
|
|
359
359
|
const text = content.length > MAX_CONTENT_LENGTH ? content.slice(0, MAX_CONTENT_LENGTH) : content;
|
|
360
360
|
const doc = nlp(text);
|
|
361
361
|
const seen = /* @__PURE__ */ new Set();
|
|
@@ -386,11 +386,11 @@ function extractEntities(content) {
|
|
|
386
386
|
}
|
|
387
387
|
return entities;
|
|
388
388
|
}
|
|
389
|
-
function saveExtractions(content, title, owner, repo, db2) {
|
|
389
|
+
async function saveExtractions(content, title, owner, repo, db2) {
|
|
390
390
|
if (!content || content.trim().length === 0) return;
|
|
391
391
|
let entities;
|
|
392
392
|
try {
|
|
393
|
-
entities = extractEntities(content);
|
|
393
|
+
entities = await extractEntities(content);
|
|
394
394
|
} catch (err) {
|
|
395
395
|
logger.warn("[KG-Archivist] Entity extraction failed, skipping", {
|
|
396
396
|
error: String(err)
|
|
@@ -507,7 +507,7 @@ async function storeSingleMemory(params, db2, vectors2) {
|
|
|
507
507
|
logger.warn("Failed to generate vector embedding", { error: String(error) });
|
|
508
508
|
}
|
|
509
509
|
try {
|
|
510
|
-
saveExtractions(entry.content, entry.title, entry.scope.owner, entry.scope.repo, db2);
|
|
510
|
+
await saveExtractions(entry.content, entry.title, entry.scope.owner, entry.scope.repo, db2);
|
|
511
511
|
} catch (error) {
|
|
512
512
|
logger.warn("[KG-Archivist] NLP extraction failed, memory stored without KG enrichment", {
|
|
513
513
|
error: String(error)
|
|
@@ -614,7 +614,7 @@ async function handleMemoryStore(params, db2, vectors2) {
|
|
|
614
614
|
logger.warn("Failed to generate vector embedding", { error: String(error) });
|
|
615
615
|
}
|
|
616
616
|
try {
|
|
617
|
-
saveExtractions(entry.content, entry.title, entry.scope.owner, entry.scope.repo, db2);
|
|
617
|
+
await saveExtractions(entry.content, entry.title, entry.scope.owner, entry.scope.repo, db2);
|
|
618
618
|
} catch (error) {
|
|
619
619
|
logger.warn("[KG-Archivist] NLP extraction failed, memory stored without KG enrichment", {
|
|
620
620
|
error: String(error)
|
|
@@ -3419,6 +3419,55 @@ async function handleKGBackfill(args, db2) {
|
|
|
3419
3419
|
};
|
|
3420
3420
|
const scanRepos = repo ? [repo] : db2.system.listRepoNavigation().map((r) => r.repo);
|
|
3421
3421
|
stats.reposScanned = scanRepos.length;
|
|
3422
|
+
const pendingOps = [];
|
|
3423
|
+
for (const r of scanRepos) {
|
|
3424
|
+
const currentOwner = owner || "unknown";
|
|
3425
|
+
if (source === "memories" || source === "both") {
|
|
3426
|
+
const rows = db2.db.prepare("SELECT title, content FROM memories WHERE repo = ?").all(r);
|
|
3427
|
+
for (let i = 0; i < rows.length; i++) {
|
|
3428
|
+
const row = rows[i];
|
|
3429
|
+
const text = `${row.content || ""} ${row.title || ""}`;
|
|
3430
|
+
try {
|
|
3431
|
+
const entities = await extractEntities(text);
|
|
3432
|
+
if (entities.length > 0) {
|
|
3433
|
+
pendingOps.push({
|
|
3434
|
+
entities,
|
|
3435
|
+
repo: r,
|
|
3436
|
+
owner: currentOwner,
|
|
3437
|
+
observationText: `Mentioned in memory: ${row.title || "untitled"}`
|
|
3438
|
+
});
|
|
3439
|
+
}
|
|
3440
|
+
} catch {
|
|
3441
|
+
stats.errors++;
|
|
3442
|
+
}
|
|
3443
|
+
stats.itemsProcessed++;
|
|
3444
|
+
if ((i + 1) % 100 === 0) {
|
|
3445
|
+
logger.info(`[kg-backfill] Processed ${i + 1}/${rows.length} memories in repo "${r}"`);
|
|
3446
|
+
}
|
|
3447
|
+
}
|
|
3448
|
+
}
|
|
3449
|
+
if (source === "standards" || source === "both") {
|
|
3450
|
+
const rows = db2.db.prepare("SELECT title, content FROM coding_standards WHERE repo = ?").all(r);
|
|
3451
|
+
for (let i = 0; i < rows.length; i++) {
|
|
3452
|
+
const row = rows[i];
|
|
3453
|
+
const text = `${row.content || ""} ${row.title || ""}`;
|
|
3454
|
+
try {
|
|
3455
|
+
const entities = await extractEntities(text);
|
|
3456
|
+
if (entities.length > 0) {
|
|
3457
|
+
pendingOps.push({
|
|
3458
|
+
entities,
|
|
3459
|
+
repo: r,
|
|
3460
|
+
owner: currentOwner,
|
|
3461
|
+
observationText: `Mentioned in standard: ${row.title || "untitled"}`
|
|
3462
|
+
});
|
|
3463
|
+
}
|
|
3464
|
+
} catch {
|
|
3465
|
+
stats.errors++;
|
|
3466
|
+
}
|
|
3467
|
+
stats.itemsProcessed++;
|
|
3468
|
+
}
|
|
3469
|
+
}
|
|
3470
|
+
}
|
|
3422
3471
|
const insertEntity = db2.db.prepare(
|
|
3423
3472
|
`INSERT OR IGNORE INTO entities (name, type, description, repo, owner, created_at, updated_at)
|
|
3424
3473
|
VALUES (?, ?, ?, ?, ?, ?, ?)`
|
|
@@ -3429,66 +3478,12 @@ async function handleKGBackfill(args, db2) {
|
|
|
3429
3478
|
);
|
|
3430
3479
|
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
3431
3480
|
const transaction = db2.db.transaction(() => {
|
|
3432
|
-
for (const
|
|
3433
|
-
const
|
|
3434
|
-
|
|
3435
|
-
|
|
3436
|
-
|
|
3437
|
-
|
|
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
|
-
}
|
|
3481
|
+
for (const op of pendingOps) {
|
|
3482
|
+
for (const ent of op.entities) {
|
|
3483
|
+
insertEntity.run(ent.name, ent.type, null, op.repo, op.owner, now, now);
|
|
3484
|
+
stats.entitiesCreated++;
|
|
3485
|
+
insertObservation.run(randomUUID6(), ent.name, op.observationText, op.repo, op.owner, now);
|
|
3486
|
+
stats.observationsCreated++;
|
|
3492
3487
|
}
|
|
3493
3488
|
}
|
|
3494
3489
|
});
|
|
@@ -3835,8 +3830,8 @@ function registerAllResources(server, store, _vectors, session) {
|
|
|
3835
3830
|
mimeType: "application/json"
|
|
3836
3831
|
},
|
|
3837
3832
|
async (uri, _extra) => {
|
|
3838
|
-
const
|
|
3839
|
-
const payload = JSON.stringify(
|
|
3833
|
+
const repos = db2.system.listRepoNavigation();
|
|
3834
|
+
const payload = JSON.stringify(repos, null, 2);
|
|
3840
3835
|
return {
|
|
3841
3836
|
contents: [
|
|
3842
3837
|
{
|
|
@@ -3869,15 +3864,29 @@ function registerAllResources(server, store, _vectors, session) {
|
|
|
3869
3864
|
};
|
|
3870
3865
|
}
|
|
3871
3866
|
);
|
|
3872
|
-
|
|
3873
|
-
|
|
3867
|
+
function reposLazy() {
|
|
3868
|
+
let cached = null;
|
|
3869
|
+
return () => {
|
|
3870
|
+
if (cached === null) cached = getRepos();
|
|
3871
|
+
return cached;
|
|
3872
|
+
};
|
|
3873
|
+
}
|
|
3874
|
+
function tagsLazy() {
|
|
3875
|
+
let cached = null;
|
|
3876
|
+
return () => {
|
|
3877
|
+
if (cached === null) cached = getTags();
|
|
3878
|
+
return cached;
|
|
3879
|
+
};
|
|
3880
|
+
}
|
|
3881
|
+
const reposFn = reposLazy();
|
|
3882
|
+
const tagsFn = tagsLazy();
|
|
3874
3883
|
server.registerResource(
|
|
3875
3884
|
"repository-memories",
|
|
3876
3885
|
new ResourceTemplate("repository://{name}/memories{?search,type,tag,limit,offset}", {
|
|
3877
3886
|
list: void 0,
|
|
3878
3887
|
complete: {
|
|
3879
|
-
name: async (value) => rankCompletionValues(
|
|
3880
|
-
tag: async (value) => rankCompletionValues(
|
|
3888
|
+
name: async (value) => rankCompletionValues(reposFn(), value),
|
|
3889
|
+
tag: async (value) => rankCompletionValues(tagsFn(), value)
|
|
3881
3890
|
}
|
|
3882
3891
|
}),
|
|
3883
3892
|
{
|
|
@@ -3941,7 +3950,7 @@ function registerAllResources(server, store, _vectors, session) {
|
|
|
3941
3950
|
new ResourceTemplate("repository://{name}/tasks{?status,priority,limit,offset}", {
|
|
3942
3951
|
list: void 0,
|
|
3943
3952
|
complete: {
|
|
3944
|
-
name: async (value) => rankCompletionValues(
|
|
3953
|
+
name: async (value) => rankCompletionValues(reposFn(), value)
|
|
3945
3954
|
}
|
|
3946
3955
|
}),
|
|
3947
3956
|
{
|
|
@@ -4010,7 +4019,7 @@ function registerAllResources(server, store, _vectors, session) {
|
|
|
4010
4019
|
new ResourceTemplate("repository://{name}/summary", {
|
|
4011
4020
|
list: void 0,
|
|
4012
4021
|
complete: {
|
|
4013
|
-
name: async (value) => rankCompletionValues(
|
|
4022
|
+
name: async (value) => rankCompletionValues(reposFn(), value)
|
|
4014
4023
|
}
|
|
4015
4024
|
}),
|
|
4016
4025
|
{
|
|
@@ -4038,7 +4047,7 @@ function registerAllResources(server, store, _vectors, session) {
|
|
|
4038
4047
|
new ResourceTemplate("repository://{name}/actions{?limit,offset}", {
|
|
4039
4048
|
list: void 0,
|
|
4040
4049
|
complete: {
|
|
4041
|
-
name: async (value) => rankCompletionValues(
|
|
4050
|
+
name: async (value) => rankCompletionValues(reposFn(), value)
|
|
4042
4051
|
}
|
|
4043
4052
|
}),
|
|
4044
4053
|
{
|