@vheins/local-memory-mcp 0.18.1 → 0.18.2
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.
|
@@ -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.2") {
|
|
85
|
+
pkgVersion = "0.18.2";
|
|
86
86
|
} else {
|
|
87
87
|
let searchDir = __dirname2;
|
|
88
88
|
for (let i = 0; i < 5; i++) {
|
|
@@ -666,6 +666,20 @@ var MigrationManager = class {
|
|
|
666
666
|
CREATE INDEX IF NOT EXISTS idx_memories_is_global ON memories(is_global);
|
|
667
667
|
CREATE INDEX IF NOT EXISTS idx_coding_standards_hit_count ON coding_standards(hit_count);
|
|
668
668
|
`);
|
|
669
|
+
try {
|
|
670
|
+
this.exec(`CREATE UNIQUE INDEX IF NOT EXISTS idx_tasks_code_owner_repo ON tasks(owner, repo, task_code);`);
|
|
671
|
+
} catch {
|
|
672
|
+
const dupRows = this.all(
|
|
673
|
+
"SELECT task_code, COUNT(*) as cnt FROM tasks GROUP BY owner, repo, task_code HAVING cnt > 1"
|
|
674
|
+
);
|
|
675
|
+
if (dupRows.length > 0) {
|
|
676
|
+
const codes = dupRows.map((r) => `'${r.task_code}'`).join(", ");
|
|
677
|
+
throw new Error(
|
|
678
|
+
`Cannot create UNIQUE INDEX on (owner, repo, task_code): ${dupRows.length} duplicate task_code(s) found: ${codes}. Remove duplicates manually and re-run migration.`
|
|
679
|
+
);
|
|
680
|
+
}
|
|
681
|
+
throw new Error("Could not create UNIQUE INDEX on tasks(owner, repo, task_code)");
|
|
682
|
+
}
|
|
669
683
|
try {
|
|
670
684
|
this.run("UPDATE tasks SET task_code = substr(id, 1, 8) WHERE task_code IS NULL");
|
|
671
685
|
} catch {
|
|
@@ -1696,6 +1710,9 @@ var MemoryArchiveEntity = class extends BaseEntity {
|
|
|
1696
1710
|
};
|
|
1697
1711
|
|
|
1698
1712
|
// src/mcp/entities/task.ts
|
|
1713
|
+
function isSqliteError(err) {
|
|
1714
|
+
return err instanceof Error && typeof err.code === "string";
|
|
1715
|
+
}
|
|
1699
1716
|
var TaskEntity = class extends BaseEntity {
|
|
1700
1717
|
coordinationSelect(alias = "t") {
|
|
1701
1718
|
return `
|
|
@@ -1711,40 +1728,52 @@ var TaskEntity = class extends BaseEntity {
|
|
|
1711
1728
|
`;
|
|
1712
1729
|
}
|
|
1713
1730
|
insertTask(task) {
|
|
1714
|
-
|
|
1715
|
-
|
|
1716
|
-
|
|
1717
|
-
|
|
1718
|
-
|
|
1719
|
-
|
|
1720
|
-
|
|
1721
|
-
|
|
1722
|
-
|
|
1723
|
-
|
|
1724
|
-
|
|
1725
|
-
|
|
1726
|
-
|
|
1727
|
-
|
|
1728
|
-
|
|
1729
|
-
|
|
1730
|
-
|
|
1731
|
-
|
|
1732
|
-
|
|
1733
|
-
|
|
1734
|
-
|
|
1735
|
-
|
|
1736
|
-
|
|
1737
|
-
|
|
1738
|
-
|
|
1739
|
-
|
|
1740
|
-
|
|
1741
|
-
|
|
1742
|
-
|
|
1743
|
-
|
|
1744
|
-
|
|
1745
|
-
|
|
1746
|
-
|
|
1747
|
-
|
|
1731
|
+
try {
|
|
1732
|
+
this.run(
|
|
1733
|
+
`INSERT INTO tasks (
|
|
1734
|
+
id, repo, owner, task_code, phase, title, description, status, priority,
|
|
1735
|
+
agent, role, doc_path, created_at, updated_at, finished_at, canceled_at, tags, suggested_skills, metadata, parent_id, depends_on, est_tokens, in_progress_at,
|
|
1736
|
+
commit_id, changed_files
|
|
1737
|
+
) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`,
|
|
1738
|
+
[
|
|
1739
|
+
task.id,
|
|
1740
|
+
task.repo,
|
|
1741
|
+
task.owner || "",
|
|
1742
|
+
task.task_code,
|
|
1743
|
+
task.phase || null,
|
|
1744
|
+
task.title,
|
|
1745
|
+
task.description || null,
|
|
1746
|
+
task.status || "backlog",
|
|
1747
|
+
task.priority || 3,
|
|
1748
|
+
task.agent || "unknown",
|
|
1749
|
+
task.role || "unknown",
|
|
1750
|
+
task.doc_path || null,
|
|
1751
|
+
task.created_at,
|
|
1752
|
+
task.updated_at,
|
|
1753
|
+
task.finished_at || null,
|
|
1754
|
+
task.canceled_at || null,
|
|
1755
|
+
task.tags ? JSON.stringify(task.tags) : null,
|
|
1756
|
+
task.suggested_skills ? JSON.stringify(task.suggested_skills) : null,
|
|
1757
|
+
task.metadata ? JSON.stringify(task.metadata) : null,
|
|
1758
|
+
task.parent_id || null,
|
|
1759
|
+
task.depends_on || null,
|
|
1760
|
+
task.est_tokens || 0,
|
|
1761
|
+
task.in_progress_at || null,
|
|
1762
|
+
task.commit_id || null,
|
|
1763
|
+
task.changed_files ? JSON.stringify(task.changed_files) : null
|
|
1764
|
+
]
|
|
1765
|
+
);
|
|
1766
|
+
} catch (err) {
|
|
1767
|
+
this.handleDuplicateTaskCode(err, task.task_code, task.repo);
|
|
1768
|
+
}
|
|
1769
|
+
}
|
|
1770
|
+
handleDuplicateTaskCode(err, taskCode, repo) {
|
|
1771
|
+
if (isSqliteError(err) && err.code === "SQLITE_CONSTRAINT_UNIQUE") {
|
|
1772
|
+
throw new Error(
|
|
1773
|
+
`Duplicate task_code: '${taskCode}' already exists in repository '${repo}'. The task_code must be unique within the repository.`
|
|
1774
|
+
);
|
|
1775
|
+
}
|
|
1776
|
+
throw err;
|
|
1748
1777
|
}
|
|
1749
1778
|
updateTask(id, updates) {
|
|
1750
1779
|
const fields = [];
|
|
@@ -1843,14 +1872,19 @@ var TaskEntity = class extends BaseEntity {
|
|
|
1843
1872
|
});
|
|
1844
1873
|
}
|
|
1845
1874
|
getTaskByCode(owner, repo, taskCode) {
|
|
1875
|
+
const params = [repo, taskCode];
|
|
1876
|
+
const ownerClause = owner ? "t.owner = ? AND " : "";
|
|
1877
|
+
if (owner) {
|
|
1878
|
+
params.unshift(owner);
|
|
1879
|
+
}
|
|
1846
1880
|
const row = this.get(
|
|
1847
1881
|
`SELECT t.*, d.task_code as depends_on_code, p.task_code as parent_code,
|
|
1848
1882
|
${this.coordinationSelect("t")}
|
|
1849
1883
|
FROM tasks t
|
|
1850
1884
|
LEFT JOIN tasks d ON t.depends_on = d.id
|
|
1851
1885
|
LEFT JOIN tasks p ON t.parent_id = p.id
|
|
1852
|
-
WHERE t.
|
|
1853
|
-
|
|
1886
|
+
WHERE ${ownerClause}t.repo = ? AND t.task_code = ?`,
|
|
1887
|
+
params
|
|
1854
1888
|
);
|
|
1855
1889
|
return row ? {
|
|
1856
1890
|
...this.rowToTask(row),
|
|
@@ -1996,8 +2030,12 @@ var TaskEntity = class extends BaseEntity {
|
|
|
1996
2030
|
return row?.count ?? 0;
|
|
1997
2031
|
}
|
|
1998
2032
|
isTaskCodeDuplicate(owner, repo, task_code, excludeId) {
|
|
1999
|
-
let query = "SELECT COUNT(*) as count FROM tasks WHERE
|
|
2000
|
-
const params = [
|
|
2033
|
+
let query = "SELECT COUNT(*) as count FROM tasks WHERE repo = ? AND task_code = ?";
|
|
2034
|
+
const params = [repo, task_code];
|
|
2035
|
+
if (owner) {
|
|
2036
|
+
query = "SELECT COUNT(*) as count FROM tasks WHERE owner = ? AND repo = ? AND task_code = ?";
|
|
2037
|
+
params.unshift(owner);
|
|
2038
|
+
}
|
|
2001
2039
|
if (excludeId) {
|
|
2002
2040
|
query += " AND id != ?";
|
|
2003
2041
|
params.push(excludeId);
|
|
@@ -2020,9 +2058,14 @@ var TaskEntity = class extends BaseEntity {
|
|
|
2020
2058
|
getExistingTaskCodes(owner, repo, codes) {
|
|
2021
2059
|
if (codes.length === 0) return /* @__PURE__ */ new Set();
|
|
2022
2060
|
const placeholders = codes.map(() => "?").join(",");
|
|
2061
|
+
const params = [repo, ...codes];
|
|
2062
|
+
const ownerClause = owner ? "owner = ? AND " : "";
|
|
2063
|
+
if (owner) {
|
|
2064
|
+
params.unshift(owner);
|
|
2065
|
+
}
|
|
2023
2066
|
const rows = this.all(
|
|
2024
|
-
`SELECT task_code FROM tasks WHERE
|
|
2025
|
-
|
|
2067
|
+
`SELECT task_code FROM tasks WHERE ${ownerClause}repo = ? AND task_code IN (${placeholders})`,
|
|
2068
|
+
params
|
|
2026
2069
|
);
|
|
2027
2070
|
return new Set(rows.map((r) => r.task_code));
|
|
2028
2071
|
}
|
|
@@ -4899,7 +4942,7 @@ var TOOL_DEFINITIONS = [
|
|
|
4899
4942
|
{
|
|
4900
4943
|
name: "task-list",
|
|
4901
4944
|
title: "Task List",
|
|
4902
|
-
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 in_progress and pending tasks. Use 'query' to filter by code, title, or description. Use 'status' (comma-separated) for specific filters. AGENTS: call this once at start, pick ONE task, then call task-detail.",
|
|
4945
|
+
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 in_progress and pending tasks. Use 'query' to filter by code, title, or description. Use 'status' (comma-separated) for specific filters, or 'all' for all statuses. AGENTS: call this once at start, pick ONE task, then call task-detail.",
|
|
4903
4946
|
annotations: {
|
|
4904
4947
|
readOnlyHint: true,
|
|
4905
4948
|
idempotentHint: true,
|
|
@@ -4916,7 +4959,7 @@ var TOOL_DEFINITIONS = [
|
|
|
4916
4959
|
status: {
|
|
4917
4960
|
type: "string",
|
|
4918
4961
|
default: "in_progress,pending",
|
|
4919
|
-
description: "Comma-separated status filter (backlog, pending, in_progress, completed, canceled, blocked). Defaults to 'in_progress,
|
|
4962
|
+
description: "Comma-separated status filter (backlog, pending, in_progress, completed, canceled, blocked) or 'all' for all statuses. Defaults to 'backlog,pending,in_progress,blocked'."
|
|
4920
4963
|
},
|
|
4921
4964
|
phase: {
|
|
4922
4965
|
type: "string",
|
|
@@ -6462,6 +6505,7 @@ export {
|
|
|
6462
6505
|
MemoryDeleteSchema,
|
|
6463
6506
|
MemorySummarizeSchema,
|
|
6464
6507
|
MemorySynthesizeSchema,
|
|
6508
|
+
TaskStatusSchema,
|
|
6465
6509
|
TaskCreateSchema,
|
|
6466
6510
|
TaskCreateInteractiveSchema,
|
|
6467
6511
|
TaskUpdateSchema,
|
package/dist/dashboard/server.js
CHANGED
package/dist/mcp/server.js
CHANGED
|
@@ -26,6 +26,7 @@ import {
|
|
|
26
26
|
TaskGetSchema,
|
|
27
27
|
TaskListSchema,
|
|
28
28
|
TaskSearchSchema,
|
|
29
|
+
TaskStatusSchema,
|
|
29
30
|
TaskUpdateSchema,
|
|
30
31
|
addLogSink,
|
|
31
32
|
buildStandardVectorText,
|
|
@@ -62,7 +63,7 @@ import {
|
|
|
62
63
|
toContextSlug,
|
|
63
64
|
updateSessionFromInitialize,
|
|
64
65
|
updateSessionRoots
|
|
65
|
-
} from "../chunk-
|
|
66
|
+
} from "../chunk-AVM7ZGOJ.js";
|
|
66
67
|
|
|
67
68
|
// src/mcp/server.ts
|
|
68
69
|
import readline from "readline";
|
|
@@ -2502,7 +2503,14 @@ async function handleTaskSearch(args, storage) {
|
|
|
2502
2503
|
tasks = storage.tasks.getTasksByRepo(owner, repo, status, void 0, void 0, query);
|
|
2503
2504
|
}
|
|
2504
2505
|
} else {
|
|
2505
|
-
tasks = storage.tasks.
|
|
2506
|
+
tasks = storage.tasks.getTasksByMultipleStatuses(
|
|
2507
|
+
owner,
|
|
2508
|
+
repo,
|
|
2509
|
+
[...TaskStatusSchema.options],
|
|
2510
|
+
void 0,
|
|
2511
|
+
void 0,
|
|
2512
|
+
query
|
|
2513
|
+
);
|
|
2506
2514
|
}
|
|
2507
2515
|
if (phase) {
|
|
2508
2516
|
const phaseLower = phase.toLowerCase();
|