@vheins/local-memory-mcp 0.18.8 → 0.18.10
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-PXTBSGN4.js → chunk-YACQ3MHF.js} +106 -129
- package/dist/dashboard/server.js +16 -6
- package/dist/mcp/server.js +30 -37
- package/package.json +1 -1
|
@@ -81,8 +81,8 @@ function loadServerInstructions() {
|
|
|
81
81
|
// src/mcp/capabilities.ts
|
|
82
82
|
var __dirname2 = path2.dirname(fileURLToPath2(import.meta.url));
|
|
83
83
|
var pkgVersion = "0.1.0";
|
|
84
|
-
if ("0.18.
|
|
85
|
-
pkgVersion = "0.18.
|
|
84
|
+
if ("0.18.10") {
|
|
85
|
+
pkgVersion = "0.18.10";
|
|
86
86
|
} else {
|
|
87
87
|
let searchDir = __dirname2;
|
|
88
88
|
for (let i = 0; i < 5; i++) {
|
|
@@ -367,7 +367,6 @@ var MigrationManager = class {
|
|
|
367
367
|
);
|
|
368
368
|
|
|
369
369
|
CREATE INDEX IF NOT EXISTS idx_tasks_repo ON tasks(repo);
|
|
370
|
-
CREATE INDEX IF NOT EXISTS idx_tasks_code ON tasks(task_code);
|
|
371
370
|
CREATE INDEX IF NOT EXISTS idx_tasks_status ON tasks(status);
|
|
372
371
|
CREATE INDEX IF NOT EXISTS idx_tasks_phase ON tasks(phase);
|
|
373
372
|
CREATE INDEX IF NOT EXISTS idx_tasks_priority ON tasks(priority);
|
|
@@ -666,44 +665,32 @@ var MigrationManager = class {
|
|
|
666
665
|
CREATE INDEX IF NOT EXISTS idx_memories_is_global ON memories(is_global);
|
|
667
666
|
CREATE INDEX IF NOT EXISTS idx_coding_standards_hit_count ON coding_standards(hit_count);
|
|
668
667
|
`);
|
|
669
|
-
|
|
670
|
-
|
|
671
|
-
|
|
672
|
-
|
|
673
|
-
|
|
674
|
-
|
|
675
|
-
|
|
676
|
-
|
|
677
|
-
|
|
678
|
-
|
|
679
|
-
|
|
680
|
-
|
|
681
|
-
|
|
682
|
-
|
|
683
|
-
|
|
684
|
-
|
|
685
|
-
|
|
686
|
-
|
|
687
|
-
|
|
688
|
-
|
|
689
|
-
)`,
|
|
690
|
-
dup.owner,
|
|
691
|
-
dup.repo,
|
|
692
|
-
dup.task_code,
|
|
693
|
-
dup.owner,
|
|
694
|
-
dup.repo,
|
|
695
|
-
dup.task_code
|
|
696
|
-
);
|
|
697
|
-
for (const row of idsToDelete) {
|
|
698
|
-
this.run("DELETE FROM task_comments WHERE task_id = ?", row.id);
|
|
699
|
-
this.run("DELETE FROM tasks WHERE id = ?", row.id);
|
|
700
|
-
}
|
|
701
|
-
console.log(` Deduplicated ${dup.task_code}: kept 1, removed ${idsToDelete.length}`);
|
|
668
|
+
const dupRows = this.all(`
|
|
669
|
+
SELECT owner, repo, task_code, COUNT(*) as cnt
|
|
670
|
+
FROM tasks
|
|
671
|
+
GROUP BY owner, repo, task_code
|
|
672
|
+
HAVING cnt > 1
|
|
673
|
+
`);
|
|
674
|
+
if (dupRows.length > 0) {
|
|
675
|
+
console.log(`Found ${dupRows.length} duplicate task_code(s). Deduplicating by suffix...`);
|
|
676
|
+
for (const dup of dupRows) {
|
|
677
|
+
const rows = this.all(
|
|
678
|
+
`SELECT id, task_code, created_at FROM tasks
|
|
679
|
+
WHERE owner = ? AND repo = ? AND task_code = ?
|
|
680
|
+
ORDER BY created_at ASC, id ASC`,
|
|
681
|
+
dup.owner,
|
|
682
|
+
dup.repo,
|
|
683
|
+
dup.task_code
|
|
684
|
+
);
|
|
685
|
+
for (let i = 1; i < rows.length; i++) {
|
|
686
|
+
const newCode = `${dup.task_code}-${i + 1}`;
|
|
687
|
+
this.run("UPDATE tasks SET task_code = ? WHERE id = ?", newCode, rows[i].id);
|
|
702
688
|
}
|
|
689
|
+
console.log(` Deduplicated ${dup.task_code}: kept 1 (${rows[0].id}), renamed ${rows.length - 1} rows`);
|
|
703
690
|
}
|
|
704
|
-
this.exec(`CREATE UNIQUE INDEX IF NOT EXISTS idx_tasks_code_owner_repo ON tasks(owner, repo, task_code);`);
|
|
705
|
-
console.log("UNIQUE INDEX on (owner, repo, task_code) created after deduplication.");
|
|
706
691
|
}
|
|
692
|
+
this.exec(`CREATE UNIQUE INDEX IF NOT EXISTS idx_tasks_code_owner_repo ON tasks(owner, repo, task_code);`);
|
|
693
|
+
this.exec("DROP INDEX IF EXISTS idx_tasks_code;");
|
|
707
694
|
try {
|
|
708
695
|
this.run("UPDATE tasks SET task_code = substr(id, 1, 8) WHERE task_code IS NULL");
|
|
709
696
|
} catch {
|
|
@@ -1332,8 +1319,14 @@ var MemoryEntity = class extends BaseEntity {
|
|
|
1332
1319
|
const row = this.get("SELECT * FROM memories WHERE id = ?", [id]);
|
|
1333
1320
|
return row ? this.rowToMemoryEntry(row) : null;
|
|
1334
1321
|
}
|
|
1335
|
-
getByCode(code) {
|
|
1336
|
-
|
|
1322
|
+
getByCode(code, owner, repo) {
|
|
1323
|
+
let sql = "SELECT * FROM memories WHERE code = ?";
|
|
1324
|
+
const params = [code];
|
|
1325
|
+
if (owner && repo) {
|
|
1326
|
+
sql += " AND owner = ? AND repo = ?";
|
|
1327
|
+
params.push(owner, repo);
|
|
1328
|
+
}
|
|
1329
|
+
const row = this.get(sql, params);
|
|
1337
1330
|
return row ? this.rowToMemoryEntry(row) : null;
|
|
1338
1331
|
}
|
|
1339
1332
|
getByIdWithStats(id) {
|
|
@@ -2099,10 +2092,27 @@ var TaskEntity = class extends BaseEntity {
|
|
|
2099
2092
|
);
|
|
2100
2093
|
return new Set(rows.map((r) => r.task_code));
|
|
2101
2094
|
}
|
|
2095
|
+
/**
|
|
2096
|
+
* Bulk inserts tasks into the database within a single transaction.
|
|
2097
|
+
* Pre-deduplicates against existing task_codes before the transaction.
|
|
2098
|
+
* Rows whose task_code already exists in the DB are silently skipped (skip-and-continue).
|
|
2099
|
+
* The per-row INSERT has no try/catch since all rows are pre-validated.
|
|
2100
|
+
*
|
|
2101
|
+
* @param tasks - Array of tasks to insert
|
|
2102
|
+
* @returns Number of tasks actually inserted (excluding skipped duplicates)
|
|
2103
|
+
*/
|
|
2102
2104
|
bulkInsertTasks(tasks) {
|
|
2105
|
+
if (tasks.length === 0) return 0;
|
|
2106
|
+
const owner = tasks[0].owner || "";
|
|
2107
|
+
const repo = tasks[0].repo;
|
|
2108
|
+
const codes = tasks.map((t) => t.task_code);
|
|
2109
|
+
const existingCodes = this.getExistingTaskCodes(owner, repo, codes);
|
|
2103
2110
|
return this.transaction(() => {
|
|
2104
2111
|
let count = 0;
|
|
2105
2112
|
for (const task of tasks) {
|
|
2113
|
+
if (existingCodes.has(task.task_code)) {
|
|
2114
|
+
continue;
|
|
2115
|
+
}
|
|
2106
2116
|
this.run(
|
|
2107
2117
|
`INSERT INTO tasks (
|
|
2108
2118
|
id, repo, owner, task_code, phase, title, description, status, priority,
|
|
@@ -2753,8 +2763,14 @@ var StandardEntity = class extends BaseEntity {
|
|
|
2753
2763
|
const row = this.get("SELECT * FROM coding_standards WHERE id = ?", [id]);
|
|
2754
2764
|
return row ? this.rowToEntry(row) : null;
|
|
2755
2765
|
}
|
|
2756
|
-
getByCode(code) {
|
|
2757
|
-
|
|
2766
|
+
getByCode(code, owner, repo) {
|
|
2767
|
+
let sql = "SELECT * FROM coding_standards WHERE code = ?";
|
|
2768
|
+
const params = [code];
|
|
2769
|
+
if (owner && repo) {
|
|
2770
|
+
sql += " AND owner = ? AND repo = ?";
|
|
2771
|
+
params.push(owner, repo);
|
|
2772
|
+
}
|
|
2773
|
+
const row = this.get(sql, params);
|
|
2758
2774
|
return row ? this.rowToEntry(row) : null;
|
|
2759
2775
|
}
|
|
2760
2776
|
search(options) {
|
|
@@ -3642,6 +3658,8 @@ var MemoryStoreSchema = z.object({
|
|
|
3642
3658
|
var MemoryUpdateSchema = z.object({
|
|
3643
3659
|
id: z.string().uuid().optional(),
|
|
3644
3660
|
code: z.string().max(20).optional(),
|
|
3661
|
+
owner: z.string().min(1),
|
|
3662
|
+
repo: z.string().min(1).transform(normalizeRepo),
|
|
3645
3663
|
type: MemoryTypeSchema.optional(),
|
|
3646
3664
|
title: z.string().min(3).max(255).optional(),
|
|
3647
3665
|
content: z.string().min(10).optional(),
|
|
@@ -3680,6 +3698,8 @@ var MemorySearchSchema = z.object({
|
|
|
3680
3698
|
var MemoryAcknowledgeSchema = z.object({
|
|
3681
3699
|
memory_id: z.string().uuid().optional(),
|
|
3682
3700
|
code: z.string().max(20).optional(),
|
|
3701
|
+
owner: z.string().min(1),
|
|
3702
|
+
repo: z.string().min(1).transform(normalizeRepo),
|
|
3683
3703
|
status: z.enum(["used", "irrelevant", "contradictory"]),
|
|
3684
3704
|
application_context: z.string().min(10).optional(),
|
|
3685
3705
|
structured: z.boolean().default(false)
|
|
@@ -3694,8 +3714,8 @@ var MemoryRecapSchema = z.object({
|
|
|
3694
3714
|
structured: z.boolean().default(false)
|
|
3695
3715
|
});
|
|
3696
3716
|
var MemoryDeleteSchema = z.object({
|
|
3697
|
-
owner: z.string().
|
|
3698
|
-
repo: z.string().min(1).transform(normalizeRepo)
|
|
3717
|
+
owner: z.string().min(1),
|
|
3718
|
+
repo: z.string().min(1).transform(normalizeRepo),
|
|
3699
3719
|
id: z.string().uuid().optional(),
|
|
3700
3720
|
ids: z.array(z.string().uuid()).min(1).optional(),
|
|
3701
3721
|
code: z.string().max(20).optional(),
|
|
@@ -3854,10 +3874,20 @@ var TaskUpdateSchema = z.object({
|
|
|
3854
3874
|
}).refine((data) => Object.keys(data).length > 2, {
|
|
3855
3875
|
message: "At least one field besides repo and id/ids must be provided for update"
|
|
3856
3876
|
});
|
|
3877
|
+
var TaskStatusValues = TaskStatusSchema.options;
|
|
3878
|
+
var TaskStatusListSchema = z.string().refine(
|
|
3879
|
+
(val) => {
|
|
3880
|
+
if (val === "all") return true;
|
|
3881
|
+
const parts = val.split(",").map((s) => s.trim()).filter(Boolean);
|
|
3882
|
+
if (parts.length === 0) return false;
|
|
3883
|
+
return parts.every((p) => TaskStatusValues.includes(p));
|
|
3884
|
+
},
|
|
3885
|
+
{ message: "status must be 'all' or a comma-separated list of valid TaskStatus values" }
|
|
3886
|
+
);
|
|
3857
3887
|
var TaskListSchema = z.object({
|
|
3858
3888
|
owner: z.string().min(1),
|
|
3859
3889
|
repo: z.string().min(1).transform(normalizeRepo),
|
|
3860
|
-
status:
|
|
3890
|
+
status: TaskStatusListSchema.default("backlog,pending,in_progress,blocked"),
|
|
3861
3891
|
phase: z.string().optional(),
|
|
3862
3892
|
query: z.string().optional(),
|
|
3863
3893
|
limit: z.number().min(1).max(100).default(15),
|
|
@@ -3888,6 +3918,8 @@ var TaskDeleteSchema = z.object({
|
|
|
3888
3918
|
var MemoryDetailSchema = z.object({
|
|
3889
3919
|
id: z.string().uuid().optional(),
|
|
3890
3920
|
code: z.string().max(20).optional(),
|
|
3921
|
+
owner: z.string().min(1),
|
|
3922
|
+
repo: z.string().min(1).transform(normalizeRepo),
|
|
3891
3923
|
structured: z.boolean().default(false)
|
|
3892
3924
|
}).refine((data) => data.id !== void 0 || data.code !== void 0, {
|
|
3893
3925
|
message: "Either id or code must be provided"
|
|
@@ -3895,13 +3927,15 @@ var MemoryDetailSchema = z.object({
|
|
|
3895
3927
|
var StandardDetailSchema = z.object({
|
|
3896
3928
|
id: z.string().uuid().optional(),
|
|
3897
3929
|
code: z.string().max(20).optional(),
|
|
3930
|
+
owner: z.string().min(1),
|
|
3931
|
+
repo: z.string().min(1).transform(normalizeRepo),
|
|
3898
3932
|
structured: z.boolean().default(false)
|
|
3899
3933
|
}).refine((data) => data.id !== void 0 || data.code !== void 0, {
|
|
3900
3934
|
message: "Either id or code must be provided"
|
|
3901
3935
|
});
|
|
3902
3936
|
var StandardDeleteSchema = z.object({
|
|
3903
|
-
owner: z.string().
|
|
3904
|
-
repo: z.string().min(1).transform(normalizeRepo)
|
|
3937
|
+
owner: z.string().min(1),
|
|
3938
|
+
repo: z.string().min(1).transform(normalizeRepo),
|
|
3905
3939
|
id: z.string().uuid().optional(),
|
|
3906
3940
|
ids: z.array(z.string().uuid()).min(1).optional(),
|
|
3907
3941
|
code: z.string().max(20).optional(),
|
|
@@ -4028,8 +4062,8 @@ var StandardUpdateSchema = z.object({
|
|
|
4028
4062
|
version: z.string().optional(),
|
|
4029
4063
|
language: z.string().optional(),
|
|
4030
4064
|
stack: z.array(z.string().min(1)).min(1).optional(),
|
|
4031
|
-
owner: z.string().
|
|
4032
|
-
repo: z.string().transform(normalizeRepo)
|
|
4065
|
+
owner: z.string().min(1),
|
|
4066
|
+
repo: z.string().transform(normalizeRepo),
|
|
4033
4067
|
is_global: z.boolean().optional(),
|
|
4034
4068
|
tags: z.array(z.string().min(1)).min(1).optional(),
|
|
4035
4069
|
metadata: z.record(z.string(), z.any()).refine((value) => Object.keys(value).length > 0, { message: "metadata must contain at least one key" }).optional(),
|
|
@@ -4076,7 +4110,7 @@ var TOOL_DEFINITIONS = [
|
|
|
4076
4110
|
properties: {
|
|
4077
4111
|
owner: {
|
|
4078
4112
|
type: "string",
|
|
4079
|
-
description: "
|
|
4113
|
+
description: "Organization/namespace (e.g., GitHub org or username)"
|
|
4080
4114
|
},
|
|
4081
4115
|
repo: { type: "string", description: "Repository/project name. Optional when a single MCP root is active." },
|
|
4082
4116
|
objective: { type: "string", minLength: 5, description: "Question or synthesis objective." },
|
|
@@ -4124,10 +4158,7 @@ var TOOL_DEFINITIONS = [
|
|
|
4124
4158
|
inputSchema: {
|
|
4125
4159
|
type: "object",
|
|
4126
4160
|
properties: {
|
|
4127
|
-
owner: {
|
|
4128
|
-
type: "string",
|
|
4129
|
-
description: "GitHub repository owner (username or organization). For repo 'vheins/my-repo', owner='vheins'. CRITICAL: this is the GitHub owner, NOT the agent name. Do NOT use the calling agent's name."
|
|
4130
|
-
},
|
|
4161
|
+
owner: { type: "string", description: "Organization/namespace (e.g., GitHub org or username)" },
|
|
4131
4162
|
repo: {
|
|
4132
4163
|
type: "string",
|
|
4133
4164
|
description: "Repository name. Optional when it can be inferred from MCP roots or elicited from the user."
|
|
@@ -4200,10 +4231,7 @@ var TOOL_DEFINITIONS = [
|
|
|
4200
4231
|
inputSchema: {
|
|
4201
4232
|
type: "object",
|
|
4202
4233
|
properties: {
|
|
4203
|
-
owner: {
|
|
4204
|
-
type: "string",
|
|
4205
|
-
description: "GitHub repository owner (username or organization). For repo 'vheins/my-repo', owner='vheins'. CRITICAL: this is the GitHub owner, NOT the agent name. Do NOT use the calling agent's name."
|
|
4206
|
-
},
|
|
4234
|
+
owner: { type: "string", description: "Organization/namespace (e.g., GitHub org or username)" },
|
|
4207
4235
|
repo: { type: "string", description: "Repository name" },
|
|
4208
4236
|
id: { type: "string", format: "uuid", description: "Task ID (optional if task_code is provided)" },
|
|
4209
4237
|
task_code: { type: "string", description: "Task code (e.g. TASK-001) (optional if id is provided)" },
|
|
@@ -4266,10 +4294,7 @@ var TOOL_DEFINITIONS = [
|
|
|
4266
4294
|
scope: {
|
|
4267
4295
|
type: "object",
|
|
4268
4296
|
properties: {
|
|
4269
|
-
owner: {
|
|
4270
|
-
type: "string",
|
|
4271
|
-
description: "GitHub repository owner (username or organization). For repo 'vheins/my-repo', owner='vheins'. CRITICAL: this is the GitHub owner, NOT the agent name. Do NOT use the calling agent's name."
|
|
4272
|
-
},
|
|
4297
|
+
owner: { type: "string", description: "Organization/namespace (e.g., GitHub org or username)" },
|
|
4273
4298
|
repo: { type: "string", description: "Repository/project name" },
|
|
4274
4299
|
branch: { type: "string", description: "Git branch this memory relates to" },
|
|
4275
4300
|
folder: { type: "string", description: "Subdirectory within the repo" },
|
|
@@ -4318,10 +4343,7 @@ var TOOL_DEFINITIONS = [
|
|
|
4318
4343
|
scope: {
|
|
4319
4344
|
type: "object",
|
|
4320
4345
|
properties: {
|
|
4321
|
-
owner: {
|
|
4322
|
-
type: "string",
|
|
4323
|
-
description: "GitHub repository owner (username or organization). For repo 'vheins/my-repo', owner='vheins'. CRITICAL: this is the GitHub owner, NOT the agent name. Do NOT use the calling agent's name."
|
|
4324
|
-
},
|
|
4346
|
+
owner: { type: "string", description: "Organization/namespace (e.g., GitHub org or username)" },
|
|
4325
4347
|
repo: { type: "string", description: "Repository/project name" },
|
|
4326
4348
|
branch: { type: "string", description: "Git branch this memory relates to" },
|
|
4327
4349
|
folder: { type: "string", description: "Subdirectory within the repo" },
|
|
@@ -4462,10 +4484,7 @@ var TOOL_DEFINITIONS = [
|
|
|
4462
4484
|
description: "Search keyword to match against memory titles and content"
|
|
4463
4485
|
},
|
|
4464
4486
|
prompt: { type: "string", description: "Natural language prompt for semantic search" },
|
|
4465
|
-
owner: {
|
|
4466
|
-
type: "string",
|
|
4467
|
-
description: "GitHub repository owner (username or organization). For repo 'vheins/my-repo', owner='vheins'. CRITICAL: this is the GitHub owner, NOT the agent name. Do NOT use the calling agent's name."
|
|
4468
|
-
},
|
|
4487
|
+
owner: { type: "string", description: "Organization/namespace (e.g., GitHub org or username)" },
|
|
4469
4488
|
repo: { type: "string", description: "Repository/project name" },
|
|
4470
4489
|
current_tags: {
|
|
4471
4490
|
type: "array",
|
|
@@ -4493,10 +4512,7 @@ var TOOL_DEFINITIONS = [
|
|
|
4493
4512
|
scope: {
|
|
4494
4513
|
type: "object",
|
|
4495
4514
|
properties: {
|
|
4496
|
-
owner: {
|
|
4497
|
-
type: "string",
|
|
4498
|
-
description: "GitHub repository owner (username or organization). For repo 'vheins/my-repo', owner='vheins'. CRITICAL: this is the GitHub owner, NOT the agent name. Do NOT use the calling agent's name."
|
|
4499
|
-
},
|
|
4515
|
+
owner: { type: "string", description: "Organization/namespace (e.g., GitHub org or username)" },
|
|
4500
4516
|
repo: { type: "string", description: "Repository/project name" },
|
|
4501
4517
|
branch: { type: "string", description: "Git branch filter" },
|
|
4502
4518
|
folder: { type: "string", description: "Subdirectory filter" },
|
|
@@ -4552,10 +4568,7 @@ var TOOL_DEFINITIONS = [
|
|
|
4552
4568
|
inputSchema: {
|
|
4553
4569
|
type: "object",
|
|
4554
4570
|
properties: {
|
|
4555
|
-
owner: {
|
|
4556
|
-
type: "string",
|
|
4557
|
-
description: "GitHub repository owner (username or organization). For repo 'vheins/my-repo', owner='vheins'. CRITICAL: this is the GitHub owner, NOT the agent name. Do NOT use the calling agent's name."
|
|
4558
|
-
},
|
|
4571
|
+
owner: { type: "string", description: "Organization/namespace (e.g., GitHub org or username)" },
|
|
4559
4572
|
repo: { type: "string", description: "Repository/project name" },
|
|
4560
4573
|
signals: {
|
|
4561
4574
|
type: "array",
|
|
@@ -4684,10 +4697,7 @@ var TOOL_DEFINITIONS = [
|
|
|
4684
4697
|
inputSchema: {
|
|
4685
4698
|
type: "object",
|
|
4686
4699
|
properties: {
|
|
4687
|
-
owner: {
|
|
4688
|
-
type: "string",
|
|
4689
|
-
description: "GitHub repository owner (username or organization). For repo 'vheins/my-repo', owner='vheins'. CRITICAL: this is the GitHub owner, NOT the agent name. Do NOT use the calling agent's name."
|
|
4690
|
-
},
|
|
4700
|
+
owner: { type: "string", description: "Organization/namespace (e.g., GitHub org or username)" },
|
|
4691
4701
|
repo: { type: "string", description: "Repository/project name (required)" },
|
|
4692
4702
|
limit: {
|
|
4693
4703
|
type: "number",
|
|
@@ -4761,10 +4771,7 @@ var TOOL_DEFINITIONS = [
|
|
|
4761
4771
|
inputSchema: {
|
|
4762
4772
|
type: "object",
|
|
4763
4773
|
properties: {
|
|
4764
|
-
owner: {
|
|
4765
|
-
type: "string",
|
|
4766
|
-
description: "GitHub repository owner (username or organization). For repo 'vheins/my-repo', owner='vheins'. CRITICAL: this is the GitHub owner, NOT the agent name. Do NOT use the calling agent's name."
|
|
4767
|
-
},
|
|
4774
|
+
owner: { type: "string", description: "Organization/namespace (e.g., GitHub org or username)" },
|
|
4768
4775
|
repo: { type: "string", description: "Repository/project name" },
|
|
4769
4776
|
task_code: { type: "string", description: "Unique task code (e.g. TASK-001) (Required for single task)" },
|
|
4770
4777
|
phase: { type: "string", description: "Project phase (Required for single task)" },
|
|
@@ -4877,10 +4884,7 @@ var TOOL_DEFINITIONS = [
|
|
|
4877
4884
|
inputSchema: {
|
|
4878
4885
|
type: "object",
|
|
4879
4886
|
properties: {
|
|
4880
|
-
owner: {
|
|
4881
|
-
type: "string",
|
|
4882
|
-
description: "GitHub repository owner (username or organization). For repo 'vheins/my-repo', owner='vheins'. CRITICAL: this is the GitHub owner, NOT the agent name. Do NOT use the calling agent's name."
|
|
4883
|
-
},
|
|
4887
|
+
owner: { type: "string", description: "Organization/namespace (e.g., GitHub org or username)" },
|
|
4884
4888
|
repo: { type: "string", description: "Repository name" },
|
|
4885
4889
|
id: { type: "string", format: "uuid", description: "Task ID (for single update)" },
|
|
4886
4890
|
ids: { type: "array", items: { type: "string", format: "uuid" }, description: "Task IDs (for bulk update)" },
|
|
@@ -4973,10 +4977,7 @@ var TOOL_DEFINITIONS = [
|
|
|
4973
4977
|
inputSchema: {
|
|
4974
4978
|
type: "object",
|
|
4975
4979
|
properties: {
|
|
4976
|
-
owner: {
|
|
4977
|
-
type: "string",
|
|
4978
|
-
description: "GitHub repository owner (username or organization). For repo 'vheins/my-repo', owner='vheins'. CRITICAL: this is the GitHub owner, NOT the agent name. Do NOT use the calling agent's name."
|
|
4979
|
-
},
|
|
4980
|
+
owner: { type: "string", description: "Organization/namespace (e.g., GitHub org or username)" },
|
|
4980
4981
|
repo: { type: "string", description: "Repository name" },
|
|
4981
4982
|
id: {
|
|
4982
4983
|
type: "string",
|
|
@@ -5005,7 +5006,7 @@ var TOOL_DEFINITIONS = [
|
|
|
5005
5006
|
{
|
|
5006
5007
|
name: "task-list",
|
|
5007
5008
|
title: "Task List",
|
|
5008
|
-
description: "PRIMARY navigation and search tool for tasks. Returns a compact tabular list of tasks (id, task_code, title, status, priority, updated_at, comments_count). Defaults to
|
|
5009
|
+
description: "PRIMARY navigation and search tool for tasks. Returns a compact tabular list of tasks (id, task_code, title, status, priority, updated_at, comments_count). Defaults to backlog, pending, in_progress, and blocked tasks. Use 'status' (comma-separated) to override or 'all' for all statuses. AGENTS: call this once at start, pick ONE task, then call task-detail.",
|
|
5009
5010
|
annotations: {
|
|
5010
5011
|
readOnlyHint: true,
|
|
5011
5012
|
idempotentHint: true,
|
|
@@ -5014,17 +5015,14 @@ var TOOL_DEFINITIONS = [
|
|
|
5014
5015
|
inputSchema: {
|
|
5015
5016
|
type: "object",
|
|
5016
5017
|
properties: {
|
|
5017
|
-
owner: {
|
|
5018
|
-
type: "string",
|
|
5019
|
-
description: "GitHub repository owner (username or organization). For repo 'vheins/my-repo', owner='vheins'. CRITICAL: this is the GitHub owner, NOT the agent name. Do NOT use the calling agent's name."
|
|
5020
|
-
},
|
|
5018
|
+
owner: { type: "string", description: "Organization/namespace (e.g., GitHub org or username)" },
|
|
5021
5019
|
repo: {
|
|
5022
5020
|
type: "string",
|
|
5023
5021
|
description: "Repository/project name (required)"
|
|
5024
5022
|
},
|
|
5025
5023
|
status: {
|
|
5026
5024
|
type: "string",
|
|
5027
|
-
default: "in_progress,
|
|
5025
|
+
default: "backlog,pending,in_progress,blocked",
|
|
5028
5026
|
description: "Comma-separated status filter (backlog, pending, in_progress, completed, canceled, blocked) or 'all' for all statuses. Defaults to 'backlog,pending,in_progress,blocked'."
|
|
5029
5027
|
},
|
|
5030
5028
|
phase: {
|
|
@@ -5094,10 +5092,7 @@ var TOOL_DEFINITIONS = [
|
|
|
5094
5092
|
inputSchema: {
|
|
5095
5093
|
type: "object",
|
|
5096
5094
|
properties: {
|
|
5097
|
-
owner: {
|
|
5098
|
-
type: "string",
|
|
5099
|
-
description: "GitHub repository owner (username or organization). For repo 'vheins/my-repo', owner='vheins'. CRITICAL: this is the GitHub owner, NOT the agent name. Do NOT use the calling agent's name."
|
|
5100
|
-
},
|
|
5095
|
+
owner: { type: "string", description: "Organization/namespace (e.g., GitHub org or username)" },
|
|
5101
5096
|
repo: { type: "string", description: "Repository/project name" },
|
|
5102
5097
|
query: {
|
|
5103
5098
|
type: "string",
|
|
@@ -5155,10 +5150,7 @@ var TOOL_DEFINITIONS = [
|
|
|
5155
5150
|
inputSchema: {
|
|
5156
5151
|
type: "object",
|
|
5157
5152
|
properties: {
|
|
5158
|
-
owner: {
|
|
5159
|
-
type: "string",
|
|
5160
|
-
description: "GitHub repository owner (username or organization). For repo 'vheins/my-repo', owner='vheins'. CRITICAL: this is the GitHub owner, NOT the agent name. Do NOT use the calling agent's name."
|
|
5161
|
-
},
|
|
5153
|
+
owner: { type: "string", description: "Organization/namespace (e.g., GitHub org or username)" },
|
|
5162
5154
|
repo: { type: "string", description: "Repository/project name" },
|
|
5163
5155
|
from_agent: { type: "string", description: "Agent creating the handoff" },
|
|
5164
5156
|
to_agent: { type: "string", description: "Optional target agent" },
|
|
@@ -5233,10 +5225,7 @@ var TOOL_DEFINITIONS = [
|
|
|
5233
5225
|
inputSchema: {
|
|
5234
5226
|
type: "object",
|
|
5235
5227
|
properties: {
|
|
5236
|
-
owner: {
|
|
5237
|
-
type: "string",
|
|
5238
|
-
description: "GitHub repository owner (username or organization). For repo 'vheins/my-repo', owner='vheins'. CRITICAL: this is the GitHub owner, NOT the agent name. Do NOT use the calling agent's name."
|
|
5239
|
-
},
|
|
5228
|
+
owner: { type: "string", description: "Organization/namespace (e.g., GitHub org or username)" },
|
|
5240
5229
|
repo: { type: "string", description: "Repository/project name" },
|
|
5241
5230
|
status: { type: "string", enum: ["pending", "accepted", "rejected", "expired"] },
|
|
5242
5231
|
from_agent: { type: "string" },
|
|
@@ -5286,10 +5275,7 @@ var TOOL_DEFINITIONS = [
|
|
|
5286
5275
|
inputSchema: {
|
|
5287
5276
|
type: "object",
|
|
5288
5277
|
properties: {
|
|
5289
|
-
owner: {
|
|
5290
|
-
type: "string",
|
|
5291
|
-
description: "GitHub repository owner (username or organization). For repo 'vheins/my-repo', owner='vheins'. CRITICAL: this is the GitHub owner, NOT the agent name. Do NOT use the calling agent's name."
|
|
5292
|
-
},
|
|
5278
|
+
owner: { type: "string", description: "Organization/namespace (e.g., GitHub org or username)" },
|
|
5293
5279
|
repo: { type: "string", description: "Repository/project name" },
|
|
5294
5280
|
task_id: {
|
|
5295
5281
|
type: "string",
|
|
@@ -5333,10 +5319,7 @@ var TOOL_DEFINITIONS = [
|
|
|
5333
5319
|
inputSchema: {
|
|
5334
5320
|
type: "object",
|
|
5335
5321
|
properties: {
|
|
5336
|
-
owner: {
|
|
5337
|
-
type: "string",
|
|
5338
|
-
description: "GitHub repository owner (username or organization). For repo 'vheins/my-repo', owner='vheins'. CRITICAL: this is the GitHub owner, NOT the agent name. Do NOT use the calling agent's name."
|
|
5339
|
-
},
|
|
5322
|
+
owner: { type: "string", description: "Organization/namespace (e.g., GitHub org or username)" },
|
|
5340
5323
|
repo: { type: "string", description: "Repository/project name" },
|
|
5341
5324
|
agent: { type: "string", description: "Optional agent filter" },
|
|
5342
5325
|
active_only: { type: "boolean", description: "When true, return only unreleased claims" },
|
|
@@ -5385,10 +5368,7 @@ var TOOL_DEFINITIONS = [
|
|
|
5385
5368
|
inputSchema: {
|
|
5386
5369
|
type: "object",
|
|
5387
5370
|
properties: {
|
|
5388
|
-
owner: {
|
|
5389
|
-
type: "string",
|
|
5390
|
-
description: "GitHub repository owner (username or organization). For repo 'vheins/my-repo', owner='vheins'. CRITICAL: this is the GitHub owner, NOT the agent name. Do NOT use the calling agent's name."
|
|
5391
|
-
},
|
|
5371
|
+
owner: { type: "string", description: "Organization/namespace (e.g., GitHub org or username)" },
|
|
5392
5372
|
repo: { type: "string", description: "Repository name" },
|
|
5393
5373
|
task_id: {
|
|
5394
5374
|
type: "string",
|
|
@@ -5426,10 +5406,7 @@ var TOOL_DEFINITIONS = [
|
|
|
5426
5406
|
inputSchema: {
|
|
5427
5407
|
type: "object",
|
|
5428
5408
|
properties: {
|
|
5429
|
-
owner: {
|
|
5430
|
-
type: "string",
|
|
5431
|
-
description: "GitHub repository owner (username or organization). For repo 'vheins/my-repo', owner='vheins'. CRITICAL: this is the GitHub owner, NOT the agent name. Do NOT use the calling agent's name."
|
|
5432
|
-
},
|
|
5409
|
+
owner: { type: "string", description: "Organization/namespace (e.g., GitHub org or username)" },
|
|
5433
5410
|
name: { type: "string", minLength: 3, maxLength: 255, description: "Human-readable standard name" },
|
|
5434
5411
|
content: {
|
|
5435
5412
|
type: "string",
|
|
@@ -6413,7 +6390,7 @@ async function handleTaskClaim(args, storage) {
|
|
|
6413
6390
|
const { owner, repo, task_id, task_code, agent, role, metadata, structured } = validated;
|
|
6414
6391
|
let taskId = task_id;
|
|
6415
6392
|
let resolvedTaskCode;
|
|
6416
|
-
let task
|
|
6393
|
+
let task;
|
|
6417
6394
|
if (taskId) {
|
|
6418
6395
|
task = storage.tasks.getTaskById(taskId);
|
|
6419
6396
|
if (!task || task.repo !== repo) {
|
package/dist/dashboard/server.js
CHANGED
|
@@ -16,7 +16,7 @@ import {
|
|
|
16
16
|
handleTaskClaim,
|
|
17
17
|
listResources,
|
|
18
18
|
logger
|
|
19
|
-
} from "../chunk-
|
|
19
|
+
} from "../chunk-YACQ3MHF.js";
|
|
20
20
|
|
|
21
21
|
// src/dashboard/server.ts
|
|
22
22
|
import express from "express";
|
|
@@ -726,9 +726,9 @@ var TasksController = class {
|
|
|
726
726
|
try {
|
|
727
727
|
await db.refresh();
|
|
728
728
|
const attributes = getAttributes(req);
|
|
729
|
-
const { repo, task_code, title } = attributes;
|
|
729
|
+
const { repo, task_code, title, owner } = attributes;
|
|
730
730
|
if (!repo || !task_code || !title) return res.status(400).json(jsonApiError("Required fields missing", 400));
|
|
731
|
-
if (db.tasks.isTaskCodeDuplicate("", repo, task_code))
|
|
731
|
+
if (db.tasks.isTaskCodeDuplicate(owner || "", repo, task_code))
|
|
732
732
|
return res.status(400).json(jsonApiError("Duplicate task_code", 400));
|
|
733
733
|
const id = randomUUID2();
|
|
734
734
|
await db.withWrite(() => {
|
|
@@ -1320,7 +1320,8 @@ try {
|
|
|
1320
1320
|
} catch {
|
|
1321
1321
|
}
|
|
1322
1322
|
var app = express();
|
|
1323
|
-
var PORT = process.env.PORT || 3456;
|
|
1323
|
+
var PORT = Number(process.env.PORT) || 3456;
|
|
1324
|
+
var HOST = process.env.DASHBOARD_HOST || "127.0.0.1";
|
|
1324
1325
|
app.use(express.json({ limit: process.env.DASHBOARD_JSON_LIMIT || "50mb" }));
|
|
1325
1326
|
app.use((req, res, next) => {
|
|
1326
1327
|
const start = Date.now();
|
|
@@ -1399,8 +1400,17 @@ if (process.env.DASHBOARD_ENABLE_MCP === "true") {
|
|
|
1399
1400
|
mcpClient.start().catch((e) => logger.error("MCP Client failed", { error: e.message }));
|
|
1400
1401
|
}
|
|
1401
1402
|
function startServer() {
|
|
1402
|
-
const server = app.listen(PORT, () => {
|
|
1403
|
-
|
|
1403
|
+
const server = app.listen(PORT, HOST, () => {
|
|
1404
|
+
const addr = server.address();
|
|
1405
|
+
const bindAddr = typeof addr === "string" ? addr : addr?.address ?? HOST;
|
|
1406
|
+
if (bindAddr !== "127.0.0.1" && bindAddr !== "::1") {
|
|
1407
|
+
logger.warn("Dashboard bound to non-loopback address \u2014 access is exposed on the network", {
|
|
1408
|
+
address: bindAddr,
|
|
1409
|
+
port: PORT,
|
|
1410
|
+
suggestion: "Set DASHBOARD_HOST=127.0.0.1 to restrict to localhost"
|
|
1411
|
+
});
|
|
1412
|
+
}
|
|
1413
|
+
console.log(`${(/* @__PURE__ */ new Date()).toISOString()} DASHBOARD_STARTING v${pkg2.version} on ${bindAddr}:${PORT}`);
|
|
1404
1414
|
});
|
|
1405
1415
|
server.on("error", (err) => {
|
|
1406
1416
|
if (err.code === "EADDRINUSE") {
|
package/dist/mcp/server.js
CHANGED
|
@@ -63,7 +63,7 @@ import {
|
|
|
63
63
|
toContextSlug,
|
|
64
64
|
updateSessionFromInitialize,
|
|
65
65
|
updateSessionRoots
|
|
66
|
-
} from "../chunk-
|
|
66
|
+
} from "../chunk-YACQ3MHF.js";
|
|
67
67
|
|
|
68
68
|
// src/mcp/server.ts
|
|
69
69
|
import readline from "readline";
|
|
@@ -230,10 +230,10 @@ function hasMetadataLikeTitle(title) {
|
|
|
230
230
|
const normalized = title.trim();
|
|
231
231
|
return /^\[[^\]]{0,200}(agent:|role:|model:|\d{4}-\d{2}-\d{2}|source_)[^\]]*\]/i.test(normalized);
|
|
232
232
|
}
|
|
233
|
-
function resolveMemorySupersedes(value, db2) {
|
|
233
|
+
function resolveMemorySupersedes(value, db2, owner, repo) {
|
|
234
234
|
if (!value) return null;
|
|
235
235
|
if (UUID_REGEX.test(value)) return value;
|
|
236
|
-
const memory = db2.memories.getByCode(value);
|
|
236
|
+
const memory = db2.memories.getByCode(value, owner, repo);
|
|
237
237
|
if (!memory) throw new Error(`supersedes: memory with code '${value}' not found`);
|
|
238
238
|
return memory.id;
|
|
239
239
|
}
|
|
@@ -246,7 +246,7 @@ async function storeSingleMemory(params, db2, vectors2) {
|
|
|
246
246
|
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
247
247
|
const createdAtTime = new Date(now).getTime();
|
|
248
248
|
const expires_at = params.ttlDays != null ? new Date(createdAtTime + params.ttlDays * 864e5).toISOString() : null;
|
|
249
|
-
const resolvedSupersedes = resolveMemorySupersedes(params.supersedes, db2);
|
|
249
|
+
const resolvedSupersedes = resolveMemorySupersedes(params.supersedes, db2, params.scope.owner, params.scope.repo);
|
|
250
250
|
if (!resolvedSupersedes && params.type !== "task_archive") {
|
|
251
251
|
const conflict = await db2.memoryVectors.checkConflicts(
|
|
252
252
|
params.content,
|
|
@@ -341,7 +341,7 @@ async function handleMemoryStore(params, db2, vectors2) {
|
|
|
341
341
|
}
|
|
342
342
|
const createdAtTime = new Date(now).getTime();
|
|
343
343
|
const expires_at = mem.ttlDays != null ? new Date(createdAtTime + mem.ttlDays * 864e5).toISOString() : null;
|
|
344
|
-
const resolvedSupersedes = resolveMemorySupersedes(mem.supersedes, db2);
|
|
344
|
+
const resolvedSupersedes = resolveMemorySupersedes(mem.supersedes, db2, mem.scope.owner, mem.scope.repo);
|
|
345
345
|
if (!resolvedSupersedes && mem.type !== "task_archive") {
|
|
346
346
|
const conflict = await db2.memoryVectors.checkConflicts(
|
|
347
347
|
mem.content,
|
|
@@ -451,10 +451,10 @@ function hasMetadataLikeTitle2(title) {
|
|
|
451
451
|
const normalized = title.trim();
|
|
452
452
|
return /^\[[^\]]{0,200}(agent:|role:|model:|\d{4}-\d{2}-\d{2}|source_)[^\]]*\]/i.test(normalized);
|
|
453
453
|
}
|
|
454
|
-
function resolveMemorySupersedes2(value, db2) {
|
|
454
|
+
function resolveMemorySupersedes2(value, db2, owner, repo) {
|
|
455
455
|
if (!value) return null;
|
|
456
456
|
if (UUID_REGEX2.test(value)) return value;
|
|
457
|
-
const memory = db2.memories.getByCode(value);
|
|
457
|
+
const memory = db2.memories.getByCode(value, owner, repo);
|
|
458
458
|
if (!memory) throw new Error(`supersedes: memory with code '${value}' not found`);
|
|
459
459
|
return memory.id;
|
|
460
460
|
}
|
|
@@ -462,7 +462,7 @@ async function handleMemoryUpdate(params, db2, vectors2) {
|
|
|
462
462
|
const validated = MemoryUpdateSchema.parse(params);
|
|
463
463
|
let resolvedId = validated.id;
|
|
464
464
|
if (!resolvedId && validated.code) {
|
|
465
|
-
const byCode = db2.memories.getByCode(validated.code);
|
|
465
|
+
const byCode = db2.memories.getByCode(validated.code, validated.owner, validated.repo);
|
|
466
466
|
if (!byCode) throw new Error(`Memory not found: ${validated.code}`);
|
|
467
467
|
resolvedId = byCode.id;
|
|
468
468
|
} else if (!resolvedId) {
|
|
@@ -491,7 +491,8 @@ async function handleMemoryUpdate(params, db2, vectors2) {
|
|
|
491
491
|
if (validated.agent !== void 0) updates.agent = validated.agent;
|
|
492
492
|
if (validated.role !== void 0) updates.role = validated.role;
|
|
493
493
|
if (validated.status !== void 0) updates.status = validated.status;
|
|
494
|
-
if (validated.supersedes !== void 0)
|
|
494
|
+
if (validated.supersedes !== void 0)
|
|
495
|
+
updates.supersedes = resolveMemorySupersedes2(validated.supersedes, db2, existing.scope.owner, existing.scope.repo);
|
|
495
496
|
if (validated.tags !== void 0) updates.tags = validated.tags;
|
|
496
497
|
if (validated.metadata !== void 0) updates.metadata = validated.metadata;
|
|
497
498
|
if (validated.is_global !== void 0) updates.is_global = validated.is_global;
|
|
@@ -941,16 +942,7 @@ Comments & History:
|
|
|
941
942
|
}
|
|
942
943
|
async function handleTaskList(args, storage) {
|
|
943
944
|
const validated = TaskListSchema.parse(args);
|
|
944
|
-
const {
|
|
945
|
-
owner,
|
|
946
|
-
repo,
|
|
947
|
-
status = "backlog,pending,in_progress,blocked",
|
|
948
|
-
phase,
|
|
949
|
-
query,
|
|
950
|
-
limit,
|
|
951
|
-
offset,
|
|
952
|
-
structured: isStructuredRequest = false
|
|
953
|
-
} = validated;
|
|
945
|
+
const { owner, repo, status, phase, query, limit, offset, structured: isStructuredRequest = false } = validated;
|
|
954
946
|
let statuses = [];
|
|
955
947
|
if (status !== "all") {
|
|
956
948
|
statuses = status.split(",").map((s) => s.trim()).filter(Boolean);
|
|
@@ -1685,18 +1677,18 @@ async function executeSamplingTool(toolName, rawInput, db2, vectors2, owner) {
|
|
|
1685
1677
|
// src/mcp/tools/memory.delete.ts
|
|
1686
1678
|
async function handleMemoryDelete(params, db2, vectors2, onProgress) {
|
|
1687
1679
|
const validated = MemoryDeleteSchema.parse(params);
|
|
1688
|
-
const { id, ids, code, codes, repo, structured } = validated;
|
|
1680
|
+
const { id, ids, code, codes, owner, repo, structured } = validated;
|
|
1689
1681
|
const resolvedIds = [];
|
|
1690
1682
|
if (ids) resolvedIds.push(...ids);
|
|
1691
1683
|
if (id) resolvedIds.push(id);
|
|
1692
1684
|
if (code) {
|
|
1693
|
-
const entry = db2.memories.getByCode(code);
|
|
1685
|
+
const entry = db2.memories.getByCode(code, owner, repo);
|
|
1694
1686
|
if (!entry) throw new Error(`Memory not found: ${code}`);
|
|
1695
1687
|
resolvedIds.push(entry.id);
|
|
1696
1688
|
}
|
|
1697
1689
|
if (codes) {
|
|
1698
1690
|
for (const c of codes) {
|
|
1699
|
-
const entry = db2.memories.getByCode(c);
|
|
1691
|
+
const entry = db2.memories.getByCode(c, owner, repo);
|
|
1700
1692
|
if (!entry) throw new Error(`Memory not found: ${c}`);
|
|
1701
1693
|
resolvedIds.push(entry.id);
|
|
1702
1694
|
}
|
|
@@ -1760,7 +1752,7 @@ async function handleMemoryAcknowledge(params, db2) {
|
|
|
1760
1752
|
const validated = MemoryAcknowledgeSchema.parse(params);
|
|
1761
1753
|
let memoryId = validated.memory_id;
|
|
1762
1754
|
if (!memoryId && validated.code) {
|
|
1763
|
-
const byCode = db2.memories.getByCode(validated.code);
|
|
1755
|
+
const byCode = db2.memories.getByCode(validated.code, validated.owner, validated.repo);
|
|
1764
1756
|
if (!byCode) throw new Error(`Memory not found: ${validated.code}`);
|
|
1765
1757
|
memoryId = byCode.id;
|
|
1766
1758
|
} else if (!memoryId) {
|
|
@@ -1798,12 +1790,12 @@ async function handleMemoryAcknowledge(params, db2) {
|
|
|
1798
1790
|
// src/mcp/tools/memory.detail.ts
|
|
1799
1791
|
async function handleMemoryDetail(args, storage) {
|
|
1800
1792
|
const validated = MemoryDetailSchema.parse(args);
|
|
1801
|
-
const { id, code } = validated;
|
|
1793
|
+
const { id, code, owner, repo } = validated;
|
|
1802
1794
|
let memory;
|
|
1803
1795
|
if (id) {
|
|
1804
1796
|
memory = storage.memories.getById(id);
|
|
1805
1797
|
} else if (code) {
|
|
1806
|
-
memory = storage.memories.getByCode(code);
|
|
1798
|
+
memory = storage.memories.getByCode(code, owner, repo);
|
|
1807
1799
|
}
|
|
1808
1800
|
if (!memory) {
|
|
1809
1801
|
throw new Error(`Memory not found: ${id || code}`);
|
|
@@ -1832,10 +1824,10 @@ async function handleMemoryDetail(args, storage) {
|
|
|
1832
1824
|
// src/mcp/tools/standard.store.ts
|
|
1833
1825
|
import { randomUUID as randomUUID3 } from "crypto";
|
|
1834
1826
|
var UUID_REGEX4 = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
|
|
1835
|
-
function resolveStandardParentId(value, db2) {
|
|
1827
|
+
function resolveStandardParentId(value, db2, owner, repo) {
|
|
1836
1828
|
if (!value) return null;
|
|
1837
1829
|
if (UUID_REGEX4.test(value)) return value;
|
|
1838
|
-
const standard = db2.standards.getByCode(value);
|
|
1830
|
+
const standard = db2.standards.getByCode(value, owner, repo);
|
|
1839
1831
|
if (!standard) throw new Error(`parent_id: standard with code '${value}' not found`);
|
|
1840
1832
|
return standard.id;
|
|
1841
1833
|
}
|
|
@@ -1877,7 +1869,7 @@ async function storeSingleStandard(params, db2, vectors2) {
|
|
|
1877
1869
|
code: generateNextCode(params.owner, params.repo || "__global__", "standard", db2),
|
|
1878
1870
|
title: params.name,
|
|
1879
1871
|
content: params.content,
|
|
1880
|
-
parent_id: resolveStandardParentId(params.parent_id, db2),
|
|
1872
|
+
parent_id: resolveStandardParentId(params.parent_id, db2, params.owner, params.repo),
|
|
1881
1873
|
context: toContextSlug(params.context || "general"),
|
|
1882
1874
|
version: params.version || "1.0.0",
|
|
1883
1875
|
language: params.language || null,
|
|
@@ -1960,7 +1952,7 @@ async function handleStandardStore(params, db2, vectors2) {
|
|
|
1960
1952
|
code,
|
|
1961
1953
|
title: std.name,
|
|
1962
1954
|
content: std.content,
|
|
1963
|
-
parent_id: resolveStandardParentId(std.parent_id, db2),
|
|
1955
|
+
parent_id: resolveStandardParentId(std.parent_id, db2, validated.owner, validated.repo),
|
|
1964
1956
|
context: toContextSlug(std.context || "general"),
|
|
1965
1957
|
version: std.version || "1.0.0",
|
|
1966
1958
|
language: std.language || null,
|
|
@@ -2242,10 +2234,10 @@ async function handleStandardSearch(params, db2, vectors2) {
|
|
|
2242
2234
|
|
|
2243
2235
|
// src/mcp/tools/standard.update.ts
|
|
2244
2236
|
var UUID_REGEX5 = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
|
|
2245
|
-
function resolveStandardParentId2(value, db2) {
|
|
2237
|
+
function resolveStandardParentId2(value, db2, owner, repo) {
|
|
2246
2238
|
if (!value) return null;
|
|
2247
2239
|
if (UUID_REGEX5.test(value)) return value;
|
|
2248
|
-
const standard = db2.standards.getByCode(value);
|
|
2240
|
+
const standard = db2.standards.getByCode(value, owner, repo);
|
|
2249
2241
|
if (!standard) throw new Error(`parent_id: standard with code '${value}' not found`);
|
|
2250
2242
|
return standard.id;
|
|
2251
2243
|
}
|
|
@@ -2253,7 +2245,7 @@ async function handleStandardUpdate(params, db2, vectors2) {
|
|
|
2253
2245
|
const validated = StandardUpdateSchema.parse(params);
|
|
2254
2246
|
let resolvedId = validated.id;
|
|
2255
2247
|
if (!resolvedId && validated.code) {
|
|
2256
|
-
const byCode = db2.standards.getByCode(validated.code);
|
|
2248
|
+
const byCode = db2.standards.getByCode(validated.code, validated.owner, validated.repo);
|
|
2257
2249
|
if (!byCode) throw new Error(`Coding standard not found: ${validated.code}`);
|
|
2258
2250
|
resolvedId = byCode.id;
|
|
2259
2251
|
} else if (!resolvedId) {
|
|
@@ -2266,7 +2258,8 @@ async function handleStandardUpdate(params, db2, vectors2) {
|
|
|
2266
2258
|
const updates = {};
|
|
2267
2259
|
if (validated.name !== void 0) updates.title = validated.name;
|
|
2268
2260
|
if (validated.content !== void 0) updates.content = validated.content;
|
|
2269
|
-
if (validated.parent_id !== void 0)
|
|
2261
|
+
if (validated.parent_id !== void 0)
|
|
2262
|
+
updates.parent_id = resolveStandardParentId2(validated.parent_id, db2, existing.owner, existing.repo ?? void 0);
|
|
2270
2263
|
if (validated.context !== void 0) updates.context = validated.context;
|
|
2271
2264
|
if (validated.version !== void 0) updates.version = validated.version;
|
|
2272
2265
|
if (validated.language !== void 0) updates.language = validated.language;
|
|
@@ -2308,7 +2301,7 @@ async function handleStandardUpdate(params, db2, vectors2) {
|
|
|
2308
2301
|
// src/mcp/tools/standard.detail.ts
|
|
2309
2302
|
async function handleStandardDetail(args, storage) {
|
|
2310
2303
|
const validated = StandardDetailSchema.parse(args);
|
|
2311
|
-
const standard = validated.id ? storage.standards.getById(validated.id) : storage.standards.getByCode(validated.code);
|
|
2304
|
+
const standard = validated.id ? storage.standards.getById(validated.id) : storage.standards.getByCode(validated.code, validated.owner, validated.repo);
|
|
2312
2305
|
if (!standard) {
|
|
2313
2306
|
const identifier = validated.id ?? validated.code;
|
|
2314
2307
|
throw new Error(`Coding standard not found: ${identifier}`);
|
|
@@ -2342,18 +2335,18 @@ async function handleStandardDetail(args, storage) {
|
|
|
2342
2335
|
// src/mcp/tools/standard.delete.ts
|
|
2343
2336
|
async function handleStandardDelete(params, db2, vectors2) {
|
|
2344
2337
|
const validated = StandardDeleteSchema.parse(params);
|
|
2345
|
-
const { id, ids, code, codes, repo, structured } = validated;
|
|
2338
|
+
const { id, ids, code, codes, owner, repo, structured } = validated;
|
|
2346
2339
|
const resolvedIds = [];
|
|
2347
2340
|
if (ids) resolvedIds.push(...ids);
|
|
2348
2341
|
if (id) resolvedIds.push(id);
|
|
2349
2342
|
if (code) {
|
|
2350
|
-
const entry = db2.standards.getByCode(code);
|
|
2343
|
+
const entry = db2.standards.getByCode(code, owner, repo);
|
|
2351
2344
|
if (!entry) throw new Error(`Coding standard not found: ${code}`);
|
|
2352
2345
|
resolvedIds.push(entry.id);
|
|
2353
2346
|
}
|
|
2354
2347
|
if (codes) {
|
|
2355
2348
|
for (const c of codes) {
|
|
2356
|
-
const entry = db2.standards.getByCode(c);
|
|
2349
|
+
const entry = db2.standards.getByCode(c, owner, repo);
|
|
2357
2350
|
if (!entry) throw new Error(`Coding standard not found: ${c}`);
|
|
2358
2351
|
resolvedIds.push(entry.id);
|
|
2359
2352
|
}
|