@vheins/local-memory-mcp 0.19.16 → 0.19.18
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.
|
@@ -3896,7 +3896,7 @@ var MEMORY_TOOL_DEFINITIONS = [
|
|
|
3896
3896
|
{
|
|
3897
3897
|
name: "memory-acknowledge",
|
|
3898
3898
|
title: "Memory Acknowledge",
|
|
3899
|
-
description:
|
|
3899
|
+
description: 'Acknowledge the use of a memory or report its irrelevance/contradiction. Mandatory after using memory to generate code. Example: { code: "MEM-123", status: "used" } or { code: "MEM-123", status: "irrelevant" }.',
|
|
3900
3900
|
annotations: {
|
|
3901
3901
|
readOnlyHint: false,
|
|
3902
3902
|
idempotentHint: false,
|
|
@@ -6737,7 +6737,9 @@ var MemoryAcknowledgeSchema = z3.object({
|
|
|
6737
6737
|
code: z3.string().max(20).optional(),
|
|
6738
6738
|
owner: z3.string().min(1),
|
|
6739
6739
|
repo: z3.string().min(1).transform(normalizeRepo),
|
|
6740
|
-
status: z3.enum(["used", "irrelevant", "contradictory"])
|
|
6740
|
+
status: z3.enum(["used", "irrelevant", "contradictory"]).describe(
|
|
6741
|
+
`Usage status. Use "used" after generating code from a memory, "irrelevant" if the memory didn't help, or "contradictory" if it conflicts with current understanding.`
|
|
6742
|
+
),
|
|
6741
6743
|
application_context: z3.string().min(10).optional(),
|
|
6742
6744
|
structured: z3.boolean().default(false)
|
|
6743
6745
|
}).refine((data) => data.memory_id !== void 0 || data.code !== void 0, {
|
package/dist/dashboard/server.js
CHANGED
package/dist/mcp/server.js
CHANGED
|
@@ -62,7 +62,7 @@ import {
|
|
|
62
62
|
parseRepoInput,
|
|
63
63
|
rankCompletionValues,
|
|
64
64
|
toContextSlug
|
|
65
|
-
} from "../chunk-
|
|
65
|
+
} from "../chunk-7O3T3GQF.js";
|
|
66
66
|
|
|
67
67
|
// src/mcp/server.ts
|
|
68
68
|
import { serveStdio } from "@modelcontextprotocol/server/stdio";
|
|
@@ -75,8 +75,8 @@ import path from "path";
|
|
|
75
75
|
import { fileURLToPath } from "url";
|
|
76
76
|
var __dirname = path.dirname(fileURLToPath(import.meta.url));
|
|
77
77
|
var pkgVersion = "0.1.0";
|
|
78
|
-
if ("0.19.
|
|
79
|
-
pkgVersion = "0.19.
|
|
78
|
+
if ("0.19.18") {
|
|
79
|
+
pkgVersion = "0.19.18";
|
|
80
80
|
} else {
|
|
81
81
|
let searchDir = __dirname;
|
|
82
82
|
for (let i = 0; i < 5; i++) {
|
|
@@ -123,6 +123,7 @@ import { z } from "zod";
|
|
|
123
123
|
import { randomUUID as randomUUID2 } from "crypto";
|
|
124
124
|
|
|
125
125
|
// src/mcp/utils/code-generator.ts
|
|
126
|
+
import { randomBytes } from "crypto";
|
|
126
127
|
var ENTITY_CONFIG = {
|
|
127
128
|
task: { prefix: "TASK", table: "tasks", column: "task_code" },
|
|
128
129
|
memory: { prefix: "MEM", table: "memories", column: "code" },
|
|
@@ -152,6 +153,38 @@ function generateNextCode(owner, repo, entityType, storage, batchCodes) {
|
|
|
152
153
|
}
|
|
153
154
|
return `${config.prefix}-${String(nextSeq).padStart(3, "0")}`;
|
|
154
155
|
}
|
|
156
|
+
function resolveEntityCode(preferredCode, owner, repo, entityType, storage, options) {
|
|
157
|
+
const { batchCodes } = options ?? {};
|
|
158
|
+
if (!preferredCode) {
|
|
159
|
+
const code = generateNextCode(owner, repo, entityType, storage, batchCodes);
|
|
160
|
+
if (batchCodes) batchCodes.add(code);
|
|
161
|
+
return code;
|
|
162
|
+
}
|
|
163
|
+
const isTaken = (code) => {
|
|
164
|
+
if (batchCodes?.has(code)) return true;
|
|
165
|
+
switch (entityType) {
|
|
166
|
+
case "task":
|
|
167
|
+
return storage.tasks.isTaskCodeDuplicate(owner, repo, code);
|
|
168
|
+
case "memory":
|
|
169
|
+
return storage.memories.getByCode(code, owner, repo) !== null;
|
|
170
|
+
case "standard":
|
|
171
|
+
return storage.standards.getByCode(code, owner, repo) !== null;
|
|
172
|
+
}
|
|
173
|
+
};
|
|
174
|
+
if (!isTaken(preferredCode)) {
|
|
175
|
+
if (batchCodes) batchCodes.add(preferredCode);
|
|
176
|
+
return preferredCode;
|
|
177
|
+
}
|
|
178
|
+
for (let attempt = 0; attempt < 20; attempt++) {
|
|
179
|
+
const suffix = randomBytes(2).toString("hex");
|
|
180
|
+
const candidate = `${preferredCode}-${suffix}`;
|
|
181
|
+
if (!isTaken(candidate)) {
|
|
182
|
+
if (batchCodes) batchCodes.add(candidate);
|
|
183
|
+
return candidate;
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
return generateNextCode(owner, repo, entityType, storage, batchCodes);
|
|
187
|
+
}
|
|
155
188
|
|
|
156
189
|
// src/mcp/tools/kg-archivist.ts
|
|
157
190
|
import { randomUUID } from "crypto";
|
|
@@ -478,7 +511,7 @@ async function storeSingleMemory(params, db2, vectors2) {
|
|
|
478
511
|
}
|
|
479
512
|
const entry = {
|
|
480
513
|
id: randomUUID2(),
|
|
481
|
-
code: params.code
|
|
514
|
+
code: resolveEntityCode(params.code, params.scope.owner ?? "", params.scope.repo, "memory", db2),
|
|
482
515
|
type: params.type,
|
|
483
516
|
title: params.title,
|
|
484
517
|
content: params.content,
|
|
@@ -578,8 +611,9 @@ async function handleMemoryStore(params, db2, vectors2) {
|
|
|
578
611
|
if (mem.scope.language && !tags.includes(mem.scope.language.toLowerCase())) {
|
|
579
612
|
tags.push(mem.scope.language.toLowerCase());
|
|
580
613
|
}
|
|
581
|
-
const code = mem.code ||
|
|
582
|
-
|
|
614
|
+
const code = resolveEntityCode(mem.code || null, mem.scope.owner ?? "", mem.scope.repo, "memory", db2, {
|
|
615
|
+
batchCodes
|
|
616
|
+
});
|
|
583
617
|
entries.push({
|
|
584
618
|
id: randomUUID2(),
|
|
585
619
|
code,
|
|
@@ -2371,14 +2405,6 @@ async function handleTaskCreate(args, storage) {
|
|
|
2371
2405
|
const now2 = (/* @__PURE__ */ new Date()).toISOString();
|
|
2372
2406
|
const codesInRequest = /* @__PURE__ */ new Set();
|
|
2373
2407
|
const batchCodes = /* @__PURE__ */ new Set();
|
|
2374
|
-
for (const taskData of bulkTasks) {
|
|
2375
|
-
if (!taskData.task_code) {
|
|
2376
|
-
taskData.task_code = generateNextCode(owner ?? "", repo, "task", storage, batchCodes);
|
|
2377
|
-
}
|
|
2378
|
-
batchCodes.add(taskData.task_code);
|
|
2379
|
-
}
|
|
2380
|
-
const allCodes = bulkTasks.map((t) => t.task_code);
|
|
2381
|
-
const existingCodes = storage.tasks.getExistingTaskCodes(owner, repo, allCodes);
|
|
2382
2408
|
const initialStats = storage.taskStats.getTaskStats(owner, repo);
|
|
2383
2409
|
let pendingInRequestCount = 0;
|
|
2384
2410
|
const localCodeMap = /* @__PURE__ */ new Map();
|
|
@@ -2386,15 +2412,10 @@ async function handleTaskCreate(args, storage) {
|
|
|
2386
2412
|
localCodeMap.set(taskData.task_code, randomUUID4());
|
|
2387
2413
|
}
|
|
2388
2414
|
for (const taskData of bulkTasks) {
|
|
2389
|
-
const code = taskData.task_code;
|
|
2415
|
+
const code = resolveEntityCode(taskData.task_code ?? null, owner ?? "", repo, "task", storage, { batchCodes });
|
|
2390
2416
|
if (codesInRequest.has(code)) {
|
|
2391
2417
|
throw new Error(`Duplicate task_code in request: '${code}'`);
|
|
2392
2418
|
}
|
|
2393
|
-
if (existingCodes.has(code)) {
|
|
2394
|
-
throw new Error(
|
|
2395
|
-
`Duplicate task_code: '${code}' already exists in repository '${repo}'. Omit task_code to auto-generate, or use task-list/task-search to find available codes.`
|
|
2396
|
-
);
|
|
2397
|
-
}
|
|
2398
2419
|
codesInRequest.add(code);
|
|
2399
2420
|
let normalizedStatus = taskData.status || "backlog";
|
|
2400
2421
|
if (normalizedStatus !== "backlog" && normalizedStatus !== "pending") {
|
|
@@ -2472,12 +2493,7 @@ async function handleTaskCreate(args, storage) {
|
|
|
2472
2493
|
throw new Error("Missing required fields for single task creation (phase, title, description)");
|
|
2473
2494
|
}
|
|
2474
2495
|
let effectiveStatus = requestedStatus || "backlog";
|
|
2475
|
-
const resolvedCode = task_code
|
|
2476
|
-
if (storage.tasks.isTaskCodeDuplicate(owner, repo, resolvedCode)) {
|
|
2477
|
-
throw new Error(
|
|
2478
|
-
`Duplicate task_code: '${resolvedCode}' already exists in repository '${repo}'. Omit task_code to auto-generate, or use task-list/task-search to find available codes.`
|
|
2479
|
-
);
|
|
2480
|
-
}
|
|
2496
|
+
const resolvedCode = resolveEntityCode(task_code, owner ?? "", repo, "task", storage);
|
|
2481
2497
|
if (requestedStatus !== "backlog" && requestedStatus !== "pending" && requestedStatus !== void 0) {
|
|
2482
2498
|
throw new Error("New tasks must be created with status 'backlog' or 'pending'.");
|
|
2483
2499
|
}
|