@vheins/local-memory-mcp 0.19.5 → 0.19.6
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.
|
@@ -1070,7 +1070,15 @@ var BaseEntity = class {
|
|
|
1070
1070
|
status: r.status || "active",
|
|
1071
1071
|
is_global: r.is_global === 1,
|
|
1072
1072
|
tags: this.safeJSONParse(r.tags, []),
|
|
1073
|
-
metadata:
|
|
1073
|
+
metadata: (() => {
|
|
1074
|
+
const meta = this.safeJSONParse(r.metadata, {});
|
|
1075
|
+
delete meta.structuredData;
|
|
1076
|
+
return meta;
|
|
1077
|
+
})(),
|
|
1078
|
+
structuredData: (() => {
|
|
1079
|
+
const meta = this.safeJSONParse(r.metadata, {});
|
|
1080
|
+
return meta.structuredData ?? void 0;
|
|
1081
|
+
})()
|
|
1074
1082
|
};
|
|
1075
1083
|
}
|
|
1076
1084
|
rowToTask(row) {
|
|
@@ -1162,6 +1170,7 @@ var VALID_COLUMNS = /* @__PURE__ */ new Set([
|
|
|
1162
1170
|
]);
|
|
1163
1171
|
var MemoryEntity = class extends BaseEntity {
|
|
1164
1172
|
insert(entry) {
|
|
1173
|
+
const mergedMeta = this.mergeStructuredData(entry.metadata, entry.structuredData);
|
|
1165
1174
|
this.run(
|
|
1166
1175
|
`INSERT INTO memories (
|
|
1167
1176
|
id, code, repo, owner, type, title, content, importance, folder, language,
|
|
@@ -1186,7 +1195,7 @@ var MemoryEntity = class extends BaseEntity {
|
|
|
1186
1195
|
entry.status || "active",
|
|
1187
1196
|
entry.is_global ? 1 : 0,
|
|
1188
1197
|
entry.tags ? JSON.stringify(entry.tags) : null,
|
|
1189
|
-
|
|
1198
|
+
mergedMeta ? JSON.stringify(mergedMeta) : null,
|
|
1190
1199
|
entry.agent || "unknown",
|
|
1191
1200
|
entry.role || "unknown",
|
|
1192
1201
|
entry.model || "unknown",
|
|
@@ -1194,6 +1203,9 @@ var MemoryEntity = class extends BaseEntity {
|
|
|
1194
1203
|
]
|
|
1195
1204
|
);
|
|
1196
1205
|
}
|
|
1206
|
+
mergeStructuredData(metadata, structuredData) {
|
|
1207
|
+
return { ...metadata, structuredData: structuredData ?? {} };
|
|
1208
|
+
}
|
|
1197
1209
|
update(id, updates) {
|
|
1198
1210
|
const fields = [];
|
|
1199
1211
|
const values = [];
|
|
@@ -1219,6 +1231,12 @@ var MemoryEntity = class extends BaseEntity {
|
|
|
1219
1231
|
fields.push("language = ?");
|
|
1220
1232
|
values.push(scope.language);
|
|
1221
1233
|
}
|
|
1234
|
+
} else if (k === "structuredData") {
|
|
1235
|
+
const existingRow = this.get("SELECT metadata FROM memories WHERE id = ?", [id]);
|
|
1236
|
+
const existingMeta = existingRow ? this.safeJSONParse(existingRow.metadata, {}) : {};
|
|
1237
|
+
const merged = { ...existingMeta, structuredData: val };
|
|
1238
|
+
fields.push("metadata = ?");
|
|
1239
|
+
values.push(JSON.stringify(merged));
|
|
1222
1240
|
} else if (k === "tags" || k === "metadata") {
|
|
1223
1241
|
fields.push(`${k} = ?`);
|
|
1224
1242
|
values.push(JSON.stringify(val));
|
|
@@ -1322,6 +1340,7 @@ var MemoryEntity = class extends BaseEntity {
|
|
|
1322
1340
|
return this.transaction(() => {
|
|
1323
1341
|
let count = 0;
|
|
1324
1342
|
for (const entry of entries) {
|
|
1343
|
+
const mergedMeta = this.mergeStructuredData(entry.metadata, entry.structuredData);
|
|
1325
1344
|
this.run(
|
|
1326
1345
|
`INSERT INTO memories (
|
|
1327
1346
|
id, repo, owner, type, title, content, importance, folder, language,
|
|
@@ -1345,7 +1364,7 @@ var MemoryEntity = class extends BaseEntity {
|
|
|
1345
1364
|
entry.status || "active",
|
|
1346
1365
|
entry.is_global ? 1 : 0,
|
|
1347
1366
|
entry.tags ? JSON.stringify(entry.tags) : null,
|
|
1348
|
-
|
|
1367
|
+
mergedMeta ? JSON.stringify(mergedMeta) : null,
|
|
1349
1368
|
entry.agent || "unknown",
|
|
1350
1369
|
entry.role || "unknown",
|
|
1351
1370
|
entry.model || "unknown",
|
|
@@ -6457,6 +6476,28 @@ var SingleStandardSchema = z2.object({
|
|
|
6457
6476
|
model: z2.string().optional()
|
|
6458
6477
|
});
|
|
6459
6478
|
var TaskStatusValues = TaskStatusSchema.options;
|
|
6479
|
+
function isPlainObject(v) {
|
|
6480
|
+
return typeof v === "object" && v !== null && !Array.isArray(v) && Object.getPrototypeOf(v) === Object.prototype;
|
|
6481
|
+
}
|
|
6482
|
+
function isJsonSerializable(val) {
|
|
6483
|
+
try {
|
|
6484
|
+
JSON.stringify(val);
|
|
6485
|
+
return true;
|
|
6486
|
+
} catch {
|
|
6487
|
+
return false;
|
|
6488
|
+
}
|
|
6489
|
+
}
|
|
6490
|
+
var StructuredDataValue = z2.lazy(
|
|
6491
|
+
() => z2.union([
|
|
6492
|
+
z2.string(),
|
|
6493
|
+
z2.number().refine((v) => Number.isFinite(v), "Number must be finite"),
|
|
6494
|
+
z2.boolean(),
|
|
6495
|
+
z2.null(),
|
|
6496
|
+
z2.array(StructuredDataValue),
|
|
6497
|
+
z2.record(z2.string(), StructuredDataValue).refine(isPlainObject, "Plain object required")
|
|
6498
|
+
])
|
|
6499
|
+
);
|
|
6500
|
+
var StructuredDataSchema = z2.unknown().refine(isJsonSerializable, { message: "Value must be JSON-serializable" }).pipe(z2.record(z2.string(), StructuredDataValue));
|
|
6460
6501
|
|
|
6461
6502
|
// src/mcp/tools/schemas/memory.ts
|
|
6462
6503
|
import { z as z3 } from "zod";
|
|
@@ -6538,8 +6579,8 @@ var MemoryAcknowledgeSchema = z3.object({
|
|
|
6538
6579
|
message: "Either memory_id or code must be provided"
|
|
6539
6580
|
});
|
|
6540
6581
|
var MemoryRecapSchema = z3.object({
|
|
6541
|
-
owner: z3.string().min(1),
|
|
6542
|
-
repo: z3.string().min(1).transform(normalizeRepo),
|
|
6582
|
+
owner: z3.string().min(1, "owner is required \u2014 provide it explicitly or configure MCP workspace roots"),
|
|
6583
|
+
repo: z3.string().min(1, "repo is required \u2014 provide it explicitly or configure MCP workspace roots").transform(normalizeRepo),
|
|
6543
6584
|
limit: z3.number().min(1).max(50).default(20),
|
|
6544
6585
|
offset: z3.number().min(0).default(0),
|
|
6545
6586
|
structured: z3.boolean().default(false)
|
|
@@ -6729,8 +6770,8 @@ var TaskUpdateSchema = z4.object({
|
|
|
6729
6770
|
message: "At least one field besides repo and id/ids must be provided for update"
|
|
6730
6771
|
});
|
|
6731
6772
|
var TaskListSchema = z4.object({
|
|
6732
|
-
owner: z4.string().min(1),
|
|
6733
|
-
repo: z4.string().min(1).transform(normalizeRepo),
|
|
6773
|
+
owner: z4.string().min(1, "owner is required \u2014 provide it explicitly or configure MCP workspace roots"),
|
|
6774
|
+
repo: z4.string().min(1, "repo is required \u2014 provide it explicitly or configure MCP workspace roots").transform(normalizeRepo),
|
|
6734
6775
|
status: TaskStatusListSchema.default("backlog,pending,in_progress,blocked"),
|
|
6735
6776
|
phase: z4.string().optional(),
|
|
6736
6777
|
query: z4.string().optional(),
|
|
@@ -6759,7 +6800,9 @@ var TaskDeleteSchema = z4.object({
|
|
|
6759
6800
|
structured: z4.boolean().default(false)
|
|
6760
6801
|
}).refine(
|
|
6761
6802
|
(data) => data.id !== void 0 || data.ids !== void 0 || data.task_code !== void 0 || data.task_codes !== void 0,
|
|
6762
|
-
{
|
|
6803
|
+
{
|
|
6804
|
+
message: "Either 'id' (UUID), 'ids' (array of UUIDs), 'task_code' (string code like PERF-1), or 'task_codes' (array of string codes) must be provided. Note: 'ids' expects UUID format, not task codes \u2014 use 'task_code'/'task_codes' for string identifiers."
|
|
6805
|
+
}
|
|
6763
6806
|
);
|
|
6764
6807
|
var TaskGetSchema = z4.object({
|
|
6765
6808
|
owner: z4.string().min(1),
|
|
@@ -6775,8 +6818,8 @@ var TaskGetSchema = z4.object({
|
|
|
6775
6818
|
// src/mcp/tools/schemas/handoff.ts
|
|
6776
6819
|
import { z as z5 } from "zod";
|
|
6777
6820
|
var HandoffCreateSchema = z5.object({
|
|
6778
|
-
owner: z5.string().min(1
|
|
6779
|
-
repo: z5.string().min(1).transform(normalizeRepo),
|
|
6821
|
+
owner: z5.string().min(1, "owner is required \u2014 provide it explicitly or configure MCP workspace roots"),
|
|
6822
|
+
repo: z5.string().min(1, "repo is required \u2014 provide it explicitly or configure MCP workspace roots").transform(normalizeRepo),
|
|
6780
6823
|
from_agent: z5.string().min(1),
|
|
6781
6824
|
to_agent: z5.string().min(1).optional(),
|
|
6782
6825
|
task_id: z5.string().uuid().optional(),
|
|
@@ -6799,8 +6842,8 @@ var HandoffUpdateSchema = z5.object({
|
|
|
6799
6842
|
structured: z5.boolean().default(false)
|
|
6800
6843
|
});
|
|
6801
6844
|
var HandoffListSchema = z5.object({
|
|
6802
|
-
owner: z5.string().min(1
|
|
6803
|
-
repo: z5.string().min(1).transform(normalizeRepo),
|
|
6845
|
+
owner: z5.string().min(1, "owner is required \u2014 provide it explicitly or configure MCP workspace roots"),
|
|
6846
|
+
repo: z5.string().min(1, "repo is required \u2014 provide it explicitly or configure MCP workspace roots").transform(normalizeRepo),
|
|
6804
6847
|
status: HandoffStatusSchema.optional(),
|
|
6805
6848
|
from_agent: z5.string().min(1).optional(),
|
|
6806
6849
|
to_agent: z5.string().min(1).optional(),
|
|
@@ -6809,8 +6852,8 @@ var HandoffListSchema = z5.object({
|
|
|
6809
6852
|
structured: z5.boolean().default(false)
|
|
6810
6853
|
});
|
|
6811
6854
|
var TaskClaimSchema = z5.object({
|
|
6812
|
-
owner: z5.string().min(1
|
|
6813
|
-
repo: z5.string().min(1).transform(normalizeRepo),
|
|
6855
|
+
owner: z5.string().min(1, "owner is required \u2014 provide it explicitly or configure MCP workspace roots"),
|
|
6856
|
+
repo: z5.string().min(1, "repo is required \u2014 provide it explicitly or configure MCP workspace roots").transform(normalizeRepo),
|
|
6814
6857
|
task_id: z5.string().uuid().optional(),
|
|
6815
6858
|
task_code: z5.string().optional(),
|
|
6816
6859
|
agent: z5.string().min(1),
|
|
@@ -6823,8 +6866,8 @@ var TaskClaimSchema = z5.object({
|
|
|
6823
6866
|
message: "Provide either task_id or task_code, not both"
|
|
6824
6867
|
});
|
|
6825
6868
|
var ClaimListSchema = z5.object({
|
|
6826
|
-
owner: z5.string().
|
|
6827
|
-
repo: z5.string().
|
|
6869
|
+
owner: z5.string().optional().default(""),
|
|
6870
|
+
repo: z5.string().transform(normalizeRepo).optional().default(""),
|
|
6828
6871
|
agent: z5.string().min(1).optional(),
|
|
6829
6872
|
active_only: z5.boolean().default(true),
|
|
6830
6873
|
limit: z5.number().min(1).max(100).default(20),
|
|
@@ -6832,8 +6875,8 @@ var ClaimListSchema = z5.object({
|
|
|
6832
6875
|
structured: z5.boolean().default(false)
|
|
6833
6876
|
});
|
|
6834
6877
|
var ClaimReleaseSchema = z5.object({
|
|
6835
|
-
owner: z5.string().min(1
|
|
6836
|
-
repo: z5.string().min(1).transform(normalizeRepo),
|
|
6878
|
+
owner: z5.string().min(1, "owner is required \u2014 provide it explicitly or configure MCP workspace roots"),
|
|
6879
|
+
repo: z5.string().min(1, "repo is required \u2014 provide it explicitly or configure MCP workspace roots").transform(normalizeRepo),
|
|
6837
6880
|
task_id: z5.string().uuid().optional(),
|
|
6838
6881
|
task_code: z5.string().optional(),
|
|
6839
6882
|
agent: z5.string().min(1).optional(),
|
|
@@ -7070,7 +7113,13 @@ async function handleHandoffCreate(args, storage) {
|
|
|
7070
7113
|
});
|
|
7071
7114
|
}
|
|
7072
7115
|
async function handleHandoffList(args, storage) {
|
|
7073
|
-
const
|
|
7116
|
+
const parsed = HandoffListSchema.safeParse(args);
|
|
7117
|
+
if (!parsed.success) {
|
|
7118
|
+
const missing = parsed.error.issues.filter((i) => i.path.some((p) => p === "owner" || p === "repo")).map((i) => i.message).filter(Boolean);
|
|
7119
|
+
const msg = missing.length > 0 ? `Missing required fields: ${missing.join("; ")}. Pass owner/repo explicitly or configure MCP workspace roots so they can be auto-inferred.` : `Validation error: ${parsed.error.message}`;
|
|
7120
|
+
return { content: [{ type: "text", text: msg }], isError: true };
|
|
7121
|
+
}
|
|
7122
|
+
const validated = parsed.data;
|
|
7074
7123
|
const { owner, repo, status, from_agent, to_agent, limit, offset, structured } = validated;
|
|
7075
7124
|
const handoffs = storage.handoffs.listHandoffs({
|
|
7076
7125
|
owner,
|
package/dist/dashboard/server.js
CHANGED
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-IT2PAPJ6.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.6") {
|
|
78
|
+
pkgVersion = "0.19.6";
|
|
79
79
|
} else {
|
|
80
80
|
let searchDir = __dirname;
|
|
81
81
|
for (let i = 0; i < 5; i++) {
|
|
@@ -1118,7 +1118,13 @@ function extractAcceptedElicitationContent(result) {
|
|
|
1118
1118
|
|
|
1119
1119
|
// src/mcp/tools/memory.recap.ts
|
|
1120
1120
|
async function handleMemoryRecap(params, db2) {
|
|
1121
|
-
const
|
|
1121
|
+
const parsed = MemoryRecapSchema.safeParse(params);
|
|
1122
|
+
if (!parsed.success) {
|
|
1123
|
+
const missing = parsed.error.issues.filter((i) => i.path.some((p) => p === "owner" || p === "repo")).map((i) => i.message).filter(Boolean);
|
|
1124
|
+
const msg = missing.length > 0 ? `Missing required fields: ${missing.join("; ")}. Pass owner/repo explicitly or configure MCP workspace roots so they can be auto-inferred.` : `Validation error: ${parsed.error.message}`;
|
|
1125
|
+
return { content: [{ type: "text", text: msg }], isError: true };
|
|
1126
|
+
}
|
|
1127
|
+
const validated = parsed.data;
|
|
1122
1128
|
logger.info("[Tool] memory.recap", { repo: validated.repo, limit: validated.limit, offset: validated.offset });
|
|
1123
1129
|
const stats = db2.memories.getStats(validated.owner, validated.repo);
|
|
1124
1130
|
const total = db2.memories.getTotalCount(validated.owner, validated.repo, false, ["task_archive"]);
|
|
@@ -1241,7 +1247,13 @@ function capitalize3(str) {
|
|
|
1241
1247
|
return str.charAt(0).toUpperCase() + str.slice(1);
|
|
1242
1248
|
}
|
|
1243
1249
|
async function handleTaskList(args, storage) {
|
|
1244
|
-
const
|
|
1250
|
+
const parsed = TaskListSchema.safeParse(args);
|
|
1251
|
+
if (!parsed.success) {
|
|
1252
|
+
const missing = parsed.error.issues.filter((i) => i.path.some((p) => p === "owner" || p === "repo")).map((i) => i.message).filter(Boolean);
|
|
1253
|
+
const msg = missing.length > 0 ? `Missing required fields: ${missing.join("; ")}. Pass owner/repo explicitly or configure MCP workspace roots so they can be auto-inferred.` : `Validation error: ${parsed.error.message}`;
|
|
1254
|
+
return { content: [{ type: "text", text: msg }], isError: true };
|
|
1255
|
+
}
|
|
1256
|
+
const validated = parsed.data;
|
|
1245
1257
|
const { owner, repo, status, phase, query, limit, offset, structured: isStructuredRequest = false } = validated;
|
|
1246
1258
|
let statuses = [];
|
|
1247
1259
|
if (status !== "all") {
|