@vheins/local-memory-mcp 0.19.12 → 0.19.14
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.
|
@@ -6690,7 +6690,7 @@ var MemoryStoreSchema = z3.object({
|
|
|
6690
6690
|
memories: z3.array(SingleMemorySchema).min(1).optional()
|
|
6691
6691
|
});
|
|
6692
6692
|
var MemoryUpdateSchema = z3.object({
|
|
6693
|
-
id: z3.string().
|
|
6693
|
+
id: z3.string().optional(),
|
|
6694
6694
|
code: z3.string().max(20).optional(),
|
|
6695
6695
|
owner: z3.string().min(1),
|
|
6696
6696
|
repo: z3.string().min(1).transform(normalizeRepo),
|
|
@@ -6730,7 +6730,7 @@ var MemorySearchSchema = z3.object({
|
|
|
6730
6730
|
structured: z3.boolean().default(false)
|
|
6731
6731
|
});
|
|
6732
6732
|
var MemoryAcknowledgeSchema = z3.object({
|
|
6733
|
-
memory_id: z3.string().
|
|
6733
|
+
memory_id: z3.string().optional(),
|
|
6734
6734
|
code: z3.string().max(20).optional(),
|
|
6735
6735
|
owner: z3.string().min(1),
|
|
6736
6736
|
repo: z3.string().min(1).transform(normalizeRepo),
|
|
@@ -6750,8 +6750,8 @@ var MemoryRecapSchema = z3.object({
|
|
|
6750
6750
|
var MemoryDeleteSchema = z3.object({
|
|
6751
6751
|
owner: z3.string().min(1),
|
|
6752
6752
|
repo: z3.string().min(1).transform(normalizeRepo),
|
|
6753
|
-
id: z3.string().
|
|
6754
|
-
ids: z3.array(z3.string()
|
|
6753
|
+
id: z3.string().optional(),
|
|
6754
|
+
ids: z3.array(z3.string()).min(1).optional(),
|
|
6755
6755
|
code: z3.string().max(20).optional(),
|
|
6756
6756
|
codes: z3.array(z3.string().max(20)).min(1).optional(),
|
|
6757
6757
|
structured: z3.boolean().default(false)
|
|
@@ -6762,7 +6762,7 @@ var MemoryDeleteSchema = z3.object({
|
|
|
6762
6762
|
}
|
|
6763
6763
|
);
|
|
6764
6764
|
var MemoryDetailSchema = z3.object({
|
|
6765
|
-
id: z3.string().
|
|
6765
|
+
id: z3.string().optional(),
|
|
6766
6766
|
code: z3.string().max(20).optional(),
|
|
6767
6767
|
owner: z3.string().min(1),
|
|
6768
6768
|
repo: z3.string().min(1).transform(normalizeRepo),
|
|
@@ -6899,8 +6899,8 @@ var TaskCreateInteractiveSchema = SingleTaskCreateSchema.partial().extend({
|
|
|
6899
6899
|
var TaskUpdateSchema = z4.object({
|
|
6900
6900
|
owner: z4.string().min(1),
|
|
6901
6901
|
repo: z4.string().min(1).transform(normalizeRepo),
|
|
6902
|
-
id: z4.string().
|
|
6903
|
-
ids: z4.array(z4.string()
|
|
6902
|
+
id: z4.string().optional(),
|
|
6903
|
+
ids: z4.array(z4.string()).min(1).optional(),
|
|
6904
6904
|
task_code: z4.string().optional(),
|
|
6905
6905
|
task_codes: z4.array(z4.string().min(1)).min(1).optional(),
|
|
6906
6906
|
phase: z4.string().optional(),
|
|
@@ -6926,7 +6926,7 @@ var TaskUpdateSchema = z4.object({
|
|
|
6926
6926
|
}).refine(
|
|
6927
6927
|
(data) => data.id !== void 0 || data.ids !== void 0 || data.task_code !== void 0 || data.task_codes !== void 0,
|
|
6928
6928
|
{
|
|
6929
|
-
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.
|
|
6929
|
+
message: "Either 'id' (UUID), 'ids' (array of UUIDs or codes), 'task_code' (string code like PERF-1), or 'task_codes' (array of string codes) must be provided."
|
|
6930
6930
|
}
|
|
6931
6931
|
).refine((data) => Object.keys(data).length > 2, {
|
|
6932
6932
|
message: "At least one field besides repo and id/ids must be provided for update"
|
|
@@ -6955,21 +6955,21 @@ var TaskSearchSchema = z4.object({
|
|
|
6955
6955
|
var TaskDeleteSchema = z4.object({
|
|
6956
6956
|
owner: z4.string().min(1),
|
|
6957
6957
|
repo: z4.string().min(1).transform(normalizeRepo),
|
|
6958
|
-
id: z4.string().
|
|
6959
|
-
ids: z4.array(z4.string()
|
|
6958
|
+
id: z4.string().optional(),
|
|
6959
|
+
ids: z4.array(z4.string()).min(1).optional(),
|
|
6960
6960
|
task_code: z4.string().optional(),
|
|
6961
6961
|
task_codes: z4.array(z4.string().min(1)).min(1).optional(),
|
|
6962
6962
|
structured: z4.boolean().default(false)
|
|
6963
6963
|
}).refine(
|
|
6964
6964
|
(data) => data.id !== void 0 || data.ids !== void 0 || data.task_code !== void 0 || data.task_codes !== void 0,
|
|
6965
6965
|
{
|
|
6966
|
-
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.
|
|
6966
|
+
message: "Either 'id' (UUID), 'ids' (array of UUIDs or codes), 'task_code' (string code like PERF-1), or 'task_codes' (array of string codes) must be provided."
|
|
6967
6967
|
}
|
|
6968
6968
|
);
|
|
6969
6969
|
var TaskGetSchema = z4.object({
|
|
6970
6970
|
owner: z4.string().min(1),
|
|
6971
6971
|
repo: z4.string().min(1).transform(normalizeRepo),
|
|
6972
|
-
id: z4.string().
|
|
6972
|
+
id: z4.string().optional(),
|
|
6973
6973
|
task_code: z4.string().optional(),
|
|
6974
6974
|
task_codes: z4.array(z4.string().min(1)).min(1).optional(),
|
|
6975
6975
|
structured: z4.boolean().default(false)
|
|
@@ -6984,7 +6984,7 @@ var HandoffCreateSchema = z5.object({
|
|
|
6984
6984
|
repo: z5.string().min(1, "repo is required \u2014 provide it explicitly or configure MCP workspace roots").transform(normalizeRepo),
|
|
6985
6985
|
from_agent: z5.string().min(1),
|
|
6986
6986
|
to_agent: z5.string().min(1).optional(),
|
|
6987
|
-
task_id: z5.string().
|
|
6987
|
+
task_id: z5.string().optional(),
|
|
6988
6988
|
task_code: z5.string().optional(),
|
|
6989
6989
|
summary: z5.string().min(1),
|
|
6990
6990
|
context: z5.record(z5.string(), z5.unknown()).optional(),
|
|
@@ -7016,7 +7016,7 @@ var HandoffListSchema = z5.object({
|
|
|
7016
7016
|
var TaskClaimSchema = z5.object({
|
|
7017
7017
|
owner: z5.string().min(1, "owner is required \u2014 provide it explicitly or configure MCP workspace roots"),
|
|
7018
7018
|
repo: z5.string().min(1, "repo is required \u2014 provide it explicitly or configure MCP workspace roots").transform(normalizeRepo),
|
|
7019
|
-
task_id: z5.string().
|
|
7019
|
+
task_id: z5.string().optional(),
|
|
7020
7020
|
task_code: z5.string().optional(),
|
|
7021
7021
|
agent: z5.string().min(1),
|
|
7022
7022
|
role: z5.string().optional(),
|
|
@@ -7039,7 +7039,7 @@ var ClaimListSchema = z5.object({
|
|
|
7039
7039
|
var ClaimReleaseSchema = z5.object({
|
|
7040
7040
|
owner: z5.string().min(1, "owner is required \u2014 provide it explicitly or configure MCP workspace roots"),
|
|
7041
7041
|
repo: z5.string().min(1, "repo is required \u2014 provide it explicitly or configure MCP workspace roots").transform(normalizeRepo),
|
|
7042
|
-
task_id: z5.string().
|
|
7042
|
+
task_id: z5.string().optional(),
|
|
7043
7043
|
task_code: z5.string().optional(),
|
|
7044
7044
|
agent: z5.string().min(1).optional(),
|
|
7045
7045
|
structured: z5.boolean().default(false)
|
|
@@ -7078,7 +7078,7 @@ var StandardStoreSchema = z6.object({
|
|
|
7078
7078
|
message: "repo is required for repo-specific standards"
|
|
7079
7079
|
});
|
|
7080
7080
|
var StandardUpdateSchema = z6.object({
|
|
7081
|
-
id: z6.string().
|
|
7081
|
+
id: z6.string().optional(),
|
|
7082
7082
|
code: z6.string().max(20).optional(),
|
|
7083
7083
|
name: z6.string().min(3).max(255).optional(),
|
|
7084
7084
|
content: z6.string().min(10).optional(),
|
|
@@ -7120,8 +7120,8 @@ var StandardSearchSchema = z6.object({
|
|
|
7120
7120
|
var StandardDeleteSchema = z6.object({
|
|
7121
7121
|
owner: z6.string().min(1),
|
|
7122
7122
|
repo: z6.string().min(1).transform(normalizeRepo),
|
|
7123
|
-
id: z6.string().
|
|
7124
|
-
ids: z6.array(z6.string()
|
|
7123
|
+
id: z6.string().optional(),
|
|
7124
|
+
ids: z6.array(z6.string()).min(1).optional(),
|
|
7125
7125
|
code: z6.string().max(20).optional(),
|
|
7126
7126
|
codes: z6.array(z6.string().max(20)).min(1).optional(),
|
|
7127
7127
|
structured: z6.boolean().default(false)
|
|
@@ -7132,7 +7132,7 @@ var StandardDeleteSchema = z6.object({
|
|
|
7132
7132
|
}
|
|
7133
7133
|
);
|
|
7134
7134
|
var StandardDetailSchema = z6.object({
|
|
7135
|
-
id: z6.string().
|
|
7135
|
+
id: z6.string().optional(),
|
|
7136
7136
|
code: z6.string().max(20).optional(),
|
|
7137
7137
|
owner: z6.string().min(1),
|
|
7138
7138
|
repo: z6.string().min(1).transform(normalizeRepo),
|
|
@@ -7215,6 +7215,9 @@ var KGBackfillSchema = z8.object({
|
|
|
7215
7215
|
source: z8.enum(["memories", "standards", "both"]).optional().default("both")
|
|
7216
7216
|
});
|
|
7217
7217
|
|
|
7218
|
+
// src/mcp/utils/uuid.ts
|
|
7219
|
+
var UUID_REGEX = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
|
|
7220
|
+
|
|
7218
7221
|
// src/mcp/tools/handoff.manage.ts
|
|
7219
7222
|
function buildHandoffListSummary(repo, count, status, fromAgent, toAgent) {
|
|
7220
7223
|
const parts = [`Found ${count} handoff${count === 1 ? "" : "s"} in repo "${repo}".`];
|
|
@@ -7243,6 +7246,13 @@ async function handleHandoffCreate(args, storage) {
|
|
|
7243
7246
|
const validated = HandoffCreateSchema.parse(args);
|
|
7244
7247
|
const { owner, repo, from_agent, to_agent, task_id, task_code, summary, context, expires_at, structured } = validated;
|
|
7245
7248
|
let resolvedTaskId = task_id ?? null;
|
|
7249
|
+
if (resolvedTaskId && !UUID_REGEX.test(resolvedTaskId)) {
|
|
7250
|
+
const task = storage.tasks.getTaskByCode(owner, repo, resolvedTaskId);
|
|
7251
|
+
if (!task) {
|
|
7252
|
+
throw new Error(`Task not found: ${resolvedTaskId} in repo ${repo}`);
|
|
7253
|
+
}
|
|
7254
|
+
resolvedTaskId = task.id;
|
|
7255
|
+
}
|
|
7246
7256
|
if (!resolvedTaskId && task_code) {
|
|
7247
7257
|
const task = storage.tasks.getTaskByCode(owner, repo, task_code);
|
|
7248
7258
|
if (!task) {
|
|
@@ -7361,6 +7371,13 @@ async function handleTaskClaim(args, storage) {
|
|
|
7361
7371
|
const validated = TaskClaimSchema.parse(args);
|
|
7362
7372
|
const { owner, repo, task_id, task_code, agent, role, metadata, structured } = validated;
|
|
7363
7373
|
let taskId = task_id;
|
|
7374
|
+
if (taskId && !UUID_REGEX.test(taskId)) {
|
|
7375
|
+
const task2 = storage.tasks.getTaskByCode(owner, repo, taskId);
|
|
7376
|
+
if (!task2) {
|
|
7377
|
+
throw new Error(`Task not found: ${taskId} in repo ${repo}`);
|
|
7378
|
+
}
|
|
7379
|
+
taskId = task2.id;
|
|
7380
|
+
}
|
|
7364
7381
|
let resolvedTaskCode;
|
|
7365
7382
|
let task;
|
|
7366
7383
|
if (taskId) {
|
|
@@ -7466,6 +7483,13 @@ async function handleClaimRelease(args, storage) {
|
|
|
7466
7483
|
const validated = ClaimReleaseSchema.parse(args);
|
|
7467
7484
|
const { owner, repo, task_id, task_code, agent, structured } = validated;
|
|
7468
7485
|
let resolvedTaskId = task_id;
|
|
7486
|
+
if (resolvedTaskId && !UUID_REGEX.test(resolvedTaskId)) {
|
|
7487
|
+
const task = storage.tasks.getTaskByCode(owner, repo, resolvedTaskId);
|
|
7488
|
+
if (!task) {
|
|
7489
|
+
throw new Error(`Task not found: ${resolvedTaskId} in repo ${repo}`);
|
|
7490
|
+
}
|
|
7491
|
+
resolvedTaskId = task.id;
|
|
7492
|
+
}
|
|
7469
7493
|
let resolvedTaskCode = task_code ?? null;
|
|
7470
7494
|
if (resolvedTaskId) {
|
|
7471
7495
|
const task = storage.tasks.getTaskById(resolvedTaskId);
|
|
@@ -7576,6 +7600,7 @@ export {
|
|
|
7576
7600
|
DeleteRelationSchema,
|
|
7577
7601
|
DeleteObservationSchema,
|
|
7578
7602
|
KGBackfillSchema,
|
|
7603
|
+
UUID_REGEX,
|
|
7579
7604
|
handleHandoffCreate,
|
|
7580
7605
|
handleHandoffList,
|
|
7581
7606
|
handleHandoffUpdate,
|
package/dist/dashboard/server.js
CHANGED
package/dist/mcp/server.js
CHANGED
|
@@ -34,6 +34,7 @@ import {
|
|
|
34
34
|
TaskSearchSchema,
|
|
35
35
|
TaskStatusSchema,
|
|
36
36
|
TaskUpdateSchema,
|
|
37
|
+
UUID_REGEX,
|
|
37
38
|
addLogSink,
|
|
38
39
|
buildStandardVectorText,
|
|
39
40
|
completePromptArgument,
|
|
@@ -61,7 +62,7 @@ import {
|
|
|
61
62
|
parseRepoInput,
|
|
62
63
|
rankCompletionValues,
|
|
63
64
|
toContextSlug
|
|
64
|
-
} from "../chunk-
|
|
65
|
+
} from "../chunk-3ZCTWRSA.js";
|
|
65
66
|
|
|
66
67
|
// src/mcp/server.ts
|
|
67
68
|
import { serveStdio } from "@modelcontextprotocol/server/stdio";
|
|
@@ -74,8 +75,8 @@ import path from "path";
|
|
|
74
75
|
import { fileURLToPath } from "url";
|
|
75
76
|
var __dirname = path.dirname(fileURLToPath(import.meta.url));
|
|
76
77
|
var pkgVersion = "0.1.0";
|
|
77
|
-
if ("0.19.
|
|
78
|
-
pkgVersion = "0.19.
|
|
78
|
+
if ("0.19.14") {
|
|
79
|
+
pkgVersion = "0.19.14";
|
|
79
80
|
} else {
|
|
80
81
|
let searchDir = __dirname;
|
|
81
82
|
for (let i = 0; i < 5; i++) {
|
|
@@ -422,7 +423,6 @@ async function saveExtractions(content, title, owner, repo, db2) {
|
|
|
422
423
|
}
|
|
423
424
|
|
|
424
425
|
// src/mcp/tools/memory.store.ts
|
|
425
|
-
var UUID_REGEX = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
|
|
426
426
|
function hasMetadataLikeTitle(title) {
|
|
427
427
|
const normalized = title.trim();
|
|
428
428
|
return /^\[[^\]]{0,200}(agent:|role:|model:|\d{4}-\d{2}-\d{2}|source_)[^\]]*\]/i.test(normalized);
|
|
@@ -657,14 +657,13 @@ async function handleMemoryStore(params, db2, vectors2) {
|
|
|
657
657
|
}
|
|
658
658
|
|
|
659
659
|
// src/mcp/tools/memory.update.ts
|
|
660
|
-
var UUID_REGEX2 = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
|
|
661
660
|
function hasMetadataLikeTitle2(title) {
|
|
662
661
|
const normalized = title.trim();
|
|
663
662
|
return /^\[[^\]]{0,200}(agent:|role:|model:|\d{4}-\d{2}-\d{2}|source_)[^\]]*\]/i.test(normalized);
|
|
664
663
|
}
|
|
665
664
|
function resolveMemorySupersedes2(value, db2, owner, repo) {
|
|
666
665
|
if (!value) return null;
|
|
667
|
-
if (
|
|
666
|
+
if (UUID_REGEX.test(value)) return value;
|
|
668
667
|
const memory = db2.memories.getByCode(value, owner, repo);
|
|
669
668
|
if (!memory) throw new Error(`supersedes: memory with code '${value}' not found`);
|
|
670
669
|
return memory.id;
|
|
@@ -672,6 +671,11 @@ function resolveMemorySupersedes2(value, db2, owner, repo) {
|
|
|
672
671
|
async function handleMemoryUpdate(params, db2, vectors2) {
|
|
673
672
|
const validated = MemoryUpdateSchema.parse(params);
|
|
674
673
|
let resolvedId = validated.id;
|
|
674
|
+
if (resolvedId && !UUID_REGEX.test(resolvedId)) {
|
|
675
|
+
const byCode = db2.memories.getByCode(resolvedId, validated.owner, validated.repo);
|
|
676
|
+
if (!byCode) throw new Error(`Memory not found: ${resolvedId}`);
|
|
677
|
+
resolvedId = byCode.id;
|
|
678
|
+
}
|
|
675
679
|
if (!resolvedId && validated.code) {
|
|
676
680
|
const byCode = db2.memories.getByCode(validated.code, validated.owner, validated.repo);
|
|
677
681
|
if (!byCode) throw new Error(`Memory not found: ${validated.code}`);
|
|
@@ -1037,6 +1041,11 @@ function applyTimeFilter(memories, tunnel) {
|
|
|
1037
1041
|
async function handleMemoryAcknowledge(params, db2) {
|
|
1038
1042
|
const validated = MemoryAcknowledgeSchema.parse(params);
|
|
1039
1043
|
let memoryId = validated.memory_id;
|
|
1044
|
+
if (memoryId && !UUID_REGEX.test(memoryId)) {
|
|
1045
|
+
const byCode = db2.memories.getByCode(memoryId, validated.owner, validated.repo);
|
|
1046
|
+
if (!byCode) throw new Error(`Memory not found: ${memoryId}`);
|
|
1047
|
+
memoryId = byCode.id;
|
|
1048
|
+
}
|
|
1040
1049
|
if (!memoryId && validated.code) {
|
|
1041
1050
|
const byCode = db2.memories.getByCode(validated.code, validated.owner, validated.repo);
|
|
1042
1051
|
if (!byCode) throw new Error(`Memory not found: ${validated.code}`);
|
|
@@ -1541,8 +1550,26 @@ async function handleMemoryDelete(params, db2, vectors2, onProgress) {
|
|
|
1541
1550
|
const validated = MemoryDeleteSchema.parse(params);
|
|
1542
1551
|
const { id, ids, code, codes, owner, repo, structured } = validated;
|
|
1543
1552
|
const resolvedIds = [];
|
|
1544
|
-
if (ids)
|
|
1545
|
-
|
|
1553
|
+
if (ids) {
|
|
1554
|
+
for (const item of ids) {
|
|
1555
|
+
if (UUID_REGEX.test(item)) {
|
|
1556
|
+
resolvedIds.push(item);
|
|
1557
|
+
} else {
|
|
1558
|
+
const entry = db2.memories.getByCode(item, owner, repo);
|
|
1559
|
+
if (!entry) throw new Error(`Memory not found: ${item}`);
|
|
1560
|
+
resolvedIds.push(entry.id);
|
|
1561
|
+
}
|
|
1562
|
+
}
|
|
1563
|
+
}
|
|
1564
|
+
if (id) {
|
|
1565
|
+
if (!UUID_REGEX.test(id)) {
|
|
1566
|
+
const entry = db2.memories.getByCode(id, owner, repo);
|
|
1567
|
+
if (!entry) throw new Error(`Memory not found: ${id}`);
|
|
1568
|
+
resolvedIds.push(entry.id);
|
|
1569
|
+
} else {
|
|
1570
|
+
resolvedIds.push(id);
|
|
1571
|
+
}
|
|
1572
|
+
}
|
|
1546
1573
|
if (code) {
|
|
1547
1574
|
const entry = db2.memories.getByCode(code, owner, repo);
|
|
1548
1575
|
if (!entry) throw new Error(`Memory not found: ${code}`);
|
|
@@ -1573,7 +1600,7 @@ async function handleMemoryDelete(params, db2, vectors2, onProgress) {
|
|
|
1573
1600
|
lastRepo = existing.scope.repo;
|
|
1574
1601
|
deletedCodes.push(existing.code || existing.id);
|
|
1575
1602
|
validIdsToDelete.push(targetId);
|
|
1576
|
-
} else
|
|
1603
|
+
} else {
|
|
1577
1604
|
throw new Error(`Memory not found: ${targetId}`);
|
|
1578
1605
|
}
|
|
1579
1606
|
}
|
|
@@ -1615,7 +1642,7 @@ async function handleMemoryDetail(args, storage) {
|
|
|
1615
1642
|
const { id, code, owner, repo } = validated;
|
|
1616
1643
|
let memory;
|
|
1617
1644
|
if (id) {
|
|
1618
|
-
memory = storage.memories.getById(id);
|
|
1645
|
+
memory = UUID_REGEX.test(id) ? storage.memories.getById(id) : storage.memories.getByCode(id, owner, repo);
|
|
1619
1646
|
} else if (code) {
|
|
1620
1647
|
memory = storage.memories.getByCode(code, owner, repo);
|
|
1621
1648
|
}
|
|
@@ -1645,10 +1672,9 @@ async function handleMemoryDetail(args, storage) {
|
|
|
1645
1672
|
|
|
1646
1673
|
// src/mcp/tools/standard.store.ts
|
|
1647
1674
|
import { randomUUID as randomUUID3 } from "crypto";
|
|
1648
|
-
var UUID_REGEX3 = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
|
|
1649
1675
|
function resolveStandardParentId(value, db2, owner, repo) {
|
|
1650
1676
|
if (!value) return null;
|
|
1651
|
-
if (
|
|
1677
|
+
if (UUID_REGEX.test(value)) return value;
|
|
1652
1678
|
const standard = db2.standards.getByCode(value, owner, repo);
|
|
1653
1679
|
if (!standard) throw new Error(`parent_id: standard with code '${value}' not found`);
|
|
1654
1680
|
return standard.id;
|
|
@@ -2055,10 +2081,9 @@ async function handleStandardSearch(params, db2, vectors2) {
|
|
|
2055
2081
|
}
|
|
2056
2082
|
|
|
2057
2083
|
// src/mcp/tools/standard.update.ts
|
|
2058
|
-
var UUID_REGEX4 = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
|
|
2059
2084
|
function resolveStandardParentId2(value, db2, owner, repo) {
|
|
2060
2085
|
if (!value) return null;
|
|
2061
|
-
if (
|
|
2086
|
+
if (UUID_REGEX.test(value)) return value;
|
|
2062
2087
|
const standard = db2.standards.getByCode(value, owner, repo);
|
|
2063
2088
|
if (!standard) throw new Error(`parent_id: standard with code '${value}' not found`);
|
|
2064
2089
|
return standard.id;
|
|
@@ -2066,6 +2091,11 @@ function resolveStandardParentId2(value, db2, owner, repo) {
|
|
|
2066
2091
|
async function handleStandardUpdate(params, db2, vectors2) {
|
|
2067
2092
|
const validated = StandardUpdateSchema.parse(params);
|
|
2068
2093
|
let resolvedId = validated.id;
|
|
2094
|
+
if (resolvedId && !UUID_REGEX.test(resolvedId)) {
|
|
2095
|
+
const byCode = db2.standards.getByCode(resolvedId, validated.owner, validated.repo);
|
|
2096
|
+
if (!byCode) throw new Error(`Coding standard not found: ${resolvedId}`);
|
|
2097
|
+
resolvedId = byCode.id;
|
|
2098
|
+
}
|
|
2069
2099
|
if (!resolvedId && validated.code) {
|
|
2070
2100
|
const byCode = db2.standards.getByCode(validated.code, validated.owner, validated.repo);
|
|
2071
2101
|
if (!byCode) throw new Error(`Coding standard not found: ${validated.code}`);
|
|
@@ -2123,9 +2153,15 @@ async function handleStandardUpdate(params, db2, vectors2) {
|
|
|
2123
2153
|
// src/mcp/tools/standard.detail.ts
|
|
2124
2154
|
async function handleStandardDetail(args, storage) {
|
|
2125
2155
|
const validated = StandardDetailSchema.parse(args);
|
|
2126
|
-
const
|
|
2156
|
+
const { id, code, owner, repo } = validated;
|
|
2157
|
+
let standard;
|
|
2158
|
+
if (id) {
|
|
2159
|
+
standard = UUID_REGEX.test(id) ? storage.standards.getById(id) : storage.standards.getByCode(id, owner, repo);
|
|
2160
|
+
} else if (code) {
|
|
2161
|
+
standard = storage.standards.getByCode(code, owner, repo);
|
|
2162
|
+
}
|
|
2127
2163
|
if (!standard) {
|
|
2128
|
-
const identifier =
|
|
2164
|
+
const identifier = id ?? code;
|
|
2129
2165
|
throw new Error(`Coding standard not found: ${identifier}`);
|
|
2130
2166
|
}
|
|
2131
2167
|
storage.standards.incrementHitCounts([standard.id]);
|
|
@@ -2159,8 +2195,26 @@ async function handleStandardDelete(params, db2, vectors2) {
|
|
|
2159
2195
|
const validated = StandardDeleteSchema.parse(params);
|
|
2160
2196
|
const { id, ids, code, codes, owner, repo, structured } = validated;
|
|
2161
2197
|
const resolvedIds = [];
|
|
2162
|
-
if (ids)
|
|
2163
|
-
|
|
2198
|
+
if (ids) {
|
|
2199
|
+
for (const item of ids) {
|
|
2200
|
+
if (UUID_REGEX.test(item)) {
|
|
2201
|
+
resolvedIds.push(item);
|
|
2202
|
+
} else {
|
|
2203
|
+
const entry = db2.standards.getByCode(item, owner, repo);
|
|
2204
|
+
if (!entry) throw new Error(`Coding standard not found: ${item}`);
|
|
2205
|
+
resolvedIds.push(entry.id);
|
|
2206
|
+
}
|
|
2207
|
+
}
|
|
2208
|
+
}
|
|
2209
|
+
if (id) {
|
|
2210
|
+
if (!UUID_REGEX.test(id)) {
|
|
2211
|
+
const entry = db2.standards.getByCode(id, owner, repo);
|
|
2212
|
+
if (!entry) throw new Error(`Coding standard not found: ${id}`);
|
|
2213
|
+
resolvedIds.push(entry.id);
|
|
2214
|
+
} else {
|
|
2215
|
+
resolvedIds.push(id);
|
|
2216
|
+
}
|
|
2217
|
+
}
|
|
2164
2218
|
if (code) {
|
|
2165
2219
|
const entry = db2.standards.getByCode(code, owner, repo);
|
|
2166
2220
|
if (!entry) throw new Error(`Coding standard not found: ${code}`);
|
|
@@ -2188,7 +2242,7 @@ async function handleStandardDelete(params, db2, vectors2) {
|
|
|
2188
2242
|
db2.standards.delete(targetId);
|
|
2189
2243
|
await vectors2.remove(targetId, "standard");
|
|
2190
2244
|
deletedCount++;
|
|
2191
|
-
} else
|
|
2245
|
+
} else {
|
|
2192
2246
|
throw new Error(`Coding standard not found: ${targetId}`);
|
|
2193
2247
|
}
|
|
2194
2248
|
}
|
|
@@ -2214,10 +2268,9 @@ async function handleStandardDelete(params, db2, vectors2) {
|
|
|
2214
2268
|
import { randomUUID as randomUUID4 } from "crypto";
|
|
2215
2269
|
|
|
2216
2270
|
// src/mcp/tools/task.helpers.ts
|
|
2217
|
-
var UUID_REGEX5 = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
|
|
2218
2271
|
function resolveParentId(value, owner, repo, storage, localCodeMap) {
|
|
2219
2272
|
if (!value) return null;
|
|
2220
|
-
if (
|
|
2273
|
+
if (UUID_REGEX.test(value)) return value;
|
|
2221
2274
|
if (localCodeMap?.has(value)) return localCodeMap.get(value);
|
|
2222
2275
|
const parent = storage.tasks.getTaskByCode(owner, repo, value);
|
|
2223
2276
|
if (!parent) throw new Error(`parent_id: task with code '${value}' not found in repo '${repo}'`);
|
|
@@ -2225,7 +2278,7 @@ function resolveParentId(value, owner, repo, storage, localCodeMap) {
|
|
|
2225
2278
|
}
|
|
2226
2279
|
function resolveDependsOn(value, owner, repo, storage, localCodeMap) {
|
|
2227
2280
|
if (!value) return null;
|
|
2228
|
-
if (
|
|
2281
|
+
if (UUID_REGEX.test(value)) return value;
|
|
2229
2282
|
if (localCodeMap?.has(value)) return localCodeMap.get(value);
|
|
2230
2283
|
const task = storage.tasks.getTaskByCode(owner, repo, value);
|
|
2231
2284
|
if (!task) throw new Error(`depends_on: task with code '${value}' not found in repo '${repo}'`);
|
|
@@ -2583,12 +2636,29 @@ async function handleTaskUpdate(args, storage, vectors2) {
|
|
|
2583
2636
|
const updateData = TaskUpdateSchema.parse(args);
|
|
2584
2637
|
const { owner, repo, id, ids, comment, force, ...updates } = updateData;
|
|
2585
2638
|
let resolvedId = id;
|
|
2639
|
+
if (resolvedId && !UUID_REGEX.test(resolvedId)) {
|
|
2640
|
+
const found = storage.tasks.getTaskByCode(owner, repo, resolvedId);
|
|
2641
|
+
if (!found) throw new Error(`Task not found: ${resolvedId}`);
|
|
2642
|
+
resolvedId = found.id;
|
|
2643
|
+
}
|
|
2586
2644
|
if (!resolvedId && !ids && updates.task_code) {
|
|
2587
2645
|
const found = storage.tasks.getTaskByCode(owner, repo, updates.task_code);
|
|
2588
2646
|
if (!found) throw new Error(`Task not found: ${updates.task_code}`);
|
|
2589
2647
|
resolvedId = found.id;
|
|
2590
2648
|
}
|
|
2591
|
-
const
|
|
2649
|
+
const resolvedIdsArray = [];
|
|
2650
|
+
if (ids) {
|
|
2651
|
+
for (const item of ids) {
|
|
2652
|
+
if (UUID_REGEX.test(item)) {
|
|
2653
|
+
resolvedIdsArray.push(item);
|
|
2654
|
+
} else {
|
|
2655
|
+
const task = storage.tasks.getTaskByCode(owner, repo, item);
|
|
2656
|
+
if (!task) throw new Error(`Task not found: ${item}`);
|
|
2657
|
+
resolvedIdsArray.push(task.id);
|
|
2658
|
+
}
|
|
2659
|
+
}
|
|
2660
|
+
}
|
|
2661
|
+
const targetIds = resolvedIdsArray.length > 0 ? resolvedIdsArray : resolvedId ? [resolvedId] : [];
|
|
2592
2662
|
if (targetIds.length === 0) {
|
|
2593
2663
|
throw new Error("Either 'id' or 'ids' must be provided for update");
|
|
2594
2664
|
}
|
|
@@ -2731,8 +2801,26 @@ async function handleTaskDelete(args, storage) {
|
|
|
2731
2801
|
const validated = TaskDeleteSchema.parse(args);
|
|
2732
2802
|
const { owner, repo, id, ids, task_code } = validated;
|
|
2733
2803
|
const resolvedIds = [];
|
|
2734
|
-
if (ids)
|
|
2735
|
-
|
|
2804
|
+
if (ids) {
|
|
2805
|
+
for (const item of ids) {
|
|
2806
|
+
if (UUID_REGEX.test(item)) {
|
|
2807
|
+
resolvedIds.push(item);
|
|
2808
|
+
} else {
|
|
2809
|
+
const task = storage.tasks.getTaskByCode(owner, repo, item);
|
|
2810
|
+
if (!task) throw new Error(`Task not found: ${item}`);
|
|
2811
|
+
resolvedIds.push(task.id);
|
|
2812
|
+
}
|
|
2813
|
+
}
|
|
2814
|
+
}
|
|
2815
|
+
if (id) {
|
|
2816
|
+
if (!UUID_REGEX.test(id)) {
|
|
2817
|
+
const task = storage.tasks.getTaskByCode(owner, repo, id);
|
|
2818
|
+
if (!task) throw new Error(`Task not found: ${id}`);
|
|
2819
|
+
resolvedIds.push(task.id);
|
|
2820
|
+
} else {
|
|
2821
|
+
resolvedIds.push(id);
|
|
2822
|
+
}
|
|
2823
|
+
}
|
|
2736
2824
|
if (task_code) {
|
|
2737
2825
|
const task = storage.tasks.getTaskByCode(owner, repo, task_code);
|
|
2738
2826
|
if (!task) throw new Error(`Task not found: ${task_code}`);
|
|
@@ -2768,7 +2856,7 @@ async function handleTaskGet(args, storage) {
|
|
|
2768
2856
|
const { owner, repo, id, task_code, structured: isStructuredRequest } = validated;
|
|
2769
2857
|
let task;
|
|
2770
2858
|
if (id) {
|
|
2771
|
-
task = storage.tasks.getTaskById(id);
|
|
2859
|
+
task = UUID_REGEX.test(id) ? storage.tasks.getTaskById(id) : storage.tasks.getTaskByCode(owner, repo, id);
|
|
2772
2860
|
} else if (task_code) {
|
|
2773
2861
|
task = storage.tasks.getTaskByCode(owner, repo, task_code);
|
|
2774
2862
|
} else {
|
|
@@ -3063,6 +3151,10 @@ async function handleDecisionLog(args, db2, vectors2) {
|
|
|
3063
3151
|
tags,
|
|
3064
3152
|
structured: validated.structured
|
|
3065
3153
|
};
|
|
3154
|
+
const conflict = await db2.memoryVectors.checkConflicts(formattedContent, owner, repo, "decision", vectors2, 0.55);
|
|
3155
|
+
if (conflict) {
|
|
3156
|
+
memoryStoreParams.supersedes = conflict.id;
|
|
3157
|
+
}
|
|
3066
3158
|
return handleMemoryStore(memoryStoreParams, db2, vectors2);
|
|
3067
3159
|
}
|
|
3068
3160
|
|
|
@@ -54,9 +54,41 @@ S2 | continue to task or respond | S1✅ | ready | —
|
|
|
54
54
|
- Durable only (arch, patterns, decisions, fixes)
|
|
55
55
|
- memory-acknowledge after code gen from memory
|
|
56
56
|
- Global scope = cross-repo only; prefer repo-specific
|
|
57
|
-
- decision-log = shortcut for storing decision-type memories (auto-sets type=decision, importance=4)
|
|
57
|
+
- decision-log = shortcut for storing decision-type memories (auto-sets type=decision, importance=4, agent=current, model=current, scope=current)
|
|
58
58
|
- session-summarize = archive session as task_archive memory (type=task_archive, importance=3)
|
|
59
59
|
|
|
60
|
+
### memory-store required fields
|
|
61
|
+
|
|
62
|
+
Every `memory-store` call MUST include these fields:
|
|
63
|
+
|
|
64
|
+
| Field | Type | Description |
|
|
65
|
+
| :----------- | :------------------------------------------------------------------ | :------------------------------------------------------------------ |
|
|
66
|
+
| `type` | enum: `code_fact`, `decision`, `mistake`, `pattern`, `task_archive` | Memory category |
|
|
67
|
+
| `title` | string (3-255 chars) | Concise title, no metadata |
|
|
68
|
+
| `content` | string (min 10 chars) | Body of the memory |
|
|
69
|
+
| `importance` | number (1-5) | 1=low, 5=critical |
|
|
70
|
+
| `agent` | string | Identity of the calling agent (e.g., `explore`, `sentinel`, `main`) |
|
|
71
|
+
| `model` | string | Model identifier (e.g., `opencode-go/deepseek-v4-flash`) |
|
|
72
|
+
| `scope` | object `{ owner, repo }` | `owner`=GitHub org/username, `repo`=repo name |
|
|
73
|
+
|
|
74
|
+
Example:
|
|
75
|
+
|
|
76
|
+
```json
|
|
77
|
+
{
|
|
78
|
+
"type": "code_fact",
|
|
79
|
+
"title": "Auth uses JWT",
|
|
80
|
+
"content": "Authentication system uses JWT tokens with 1h expiry.",
|
|
81
|
+
"importance": 3,
|
|
82
|
+
"agent": "explore",
|
|
83
|
+
"model": "opencode-go/deepseek-v4-flash",
|
|
84
|
+
"scope": { "owner": "vheins", "repo": "sentinel-agent" }
|
|
85
|
+
}
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
### memory-update optional fields
|
|
89
|
+
|
|
90
|
+
`memory-update` accepts the same fields as `memory-store` but all are optional (only provide the fields to change). Either `id` (UUID) or `code` (string) is required to identify the target memory.
|
|
91
|
+
|
|
60
92
|
**Tasks**: task-list → task-claim(auto → in_progress) → task-update(completed)
|
|
61
93
|
|
|
62
94
|
- Register via task-create before execution
|