@hiveai/mcp 0.2.1 → 0.2.3
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/index.js +147 -47
- package/dist/index.js.map +1 -1
- package/dist/server.js +146 -46
- package/dist/server.js.map +1 -1
- package/package.json +3 -3
package/dist/server.js
CHANGED
|
@@ -80,7 +80,10 @@ var MemListInputSchema = {
|
|
|
80
80
|
scope: z3.enum(["personal", "team", "module"]).optional(),
|
|
81
81
|
type: z3.enum(["convention", "decision", "gotcha", "architecture", "glossary"]).optional(),
|
|
82
82
|
module: z3.string().optional(),
|
|
83
|
-
tag: z3.string().optional()
|
|
83
|
+
tag: z3.string().optional(),
|
|
84
|
+
status: z3.enum(["draft", "proposed", "validated", "deprecated", "stale", "rejected"]).optional().describe("Filter by a single status. Omit to return all statuses."),
|
|
85
|
+
exclude_rejected: z3.boolean().default(false).describe("When true, exclude memories with status=rejected from results."),
|
|
86
|
+
include_body: z3.boolean().default(false).describe("Include full body text. Default false to save tokens \u2014 use mem_get for a single memory's full content.")
|
|
84
87
|
};
|
|
85
88
|
async function memList(input, ctx) {
|
|
86
89
|
if (!existsSync3(ctx.paths.memoriesDir)) {
|
|
@@ -93,10 +96,13 @@ async function memList(input, ctx) {
|
|
|
93
96
|
if (input.type && fm.type !== input.type) return false;
|
|
94
97
|
if (input.module && fm.module !== input.module) return false;
|
|
95
98
|
if (input.tag && !fm.tags.includes(input.tag)) return false;
|
|
99
|
+
if (input.status && fm.status !== input.status) return false;
|
|
100
|
+
if (input.exclude_rejected && fm.status === "rejected") return false;
|
|
96
101
|
return true;
|
|
97
102
|
});
|
|
98
103
|
const memories = filtered.map(({ memory, filePath }) => {
|
|
99
104
|
const fm = memory.frontmatter;
|
|
105
|
+
const snippet = memory.body.replace(/\s+/g, " ").trim().slice(0, 120);
|
|
100
106
|
return {
|
|
101
107
|
id: fm.id,
|
|
102
108
|
scope: fm.scope,
|
|
@@ -104,7 +110,9 @@ async function memList(input, ctx) {
|
|
|
104
110
|
...fm.module ? { module: fm.module } : {},
|
|
105
111
|
status: fm.status,
|
|
106
112
|
tags: fm.tags,
|
|
107
|
-
|
|
113
|
+
snippet,
|
|
114
|
+
file_path: filePath,
|
|
115
|
+
...input.include_body ? { body: memory.body } : {}
|
|
108
116
|
};
|
|
109
117
|
});
|
|
110
118
|
return { memories };
|
|
@@ -188,6 +196,8 @@ var MemSearchInputSchema = {
|
|
|
188
196
|
scope: z5.enum(["personal", "team", "module"]).optional().describe("Restrict results to a single scope"),
|
|
189
197
|
type: z5.enum(["convention", "decision", "gotcha", "architecture", "glossary"]).optional().describe("Restrict results to a memory type"),
|
|
190
198
|
module: z5.string().optional().describe("Restrict results to a module"),
|
|
199
|
+
status: z5.enum(["draft", "proposed", "validated", "deprecated", "stale", "rejected"]).optional().describe("Filter by a single status. Omit to return all statuses."),
|
|
200
|
+
exclude_rejected: z5.boolean().default(false).describe("When true, exclude memories with status=rejected from results."),
|
|
191
201
|
limit: z5.number().int().positive().max(100).default(20).describe("Max results"),
|
|
192
202
|
semantic: z5.boolean().default(false).describe(
|
|
193
203
|
"Use semantic similarity from the embeddings index (requires `haive embeddings index`)."
|
|
@@ -229,6 +239,8 @@ function passesFilters(fm, input) {
|
|
|
229
239
|
if (input.scope && fm.scope !== input.scope) return false;
|
|
230
240
|
if (input.type && fm.type !== input.type) return false;
|
|
231
241
|
if (input.module && fm.module !== input.module) return false;
|
|
242
|
+
if (input.status && fm.status !== input.status) return false;
|
|
243
|
+
if (input.exclude_rejected && fm.status === "rejected") return false;
|
|
232
244
|
return true;
|
|
233
245
|
}
|
|
234
246
|
function buildLiteralResult(input, filtered, usage) {
|
|
@@ -330,6 +342,14 @@ async function memVerify(input, ctx) {
|
|
|
330
342
|
const isAnchored = memory.frontmatter.anchor.paths.length > 0 || memory.frontmatter.anchor.symbols.length > 0;
|
|
331
343
|
if (!isAnchored) {
|
|
332
344
|
anchorless++;
|
|
345
|
+
results.push({
|
|
346
|
+
id: memory.frontmatter.id,
|
|
347
|
+
file_path: filePath,
|
|
348
|
+
stale: false,
|
|
349
|
+
reason: null,
|
|
350
|
+
status_after: memory.frontmatter.status,
|
|
351
|
+
skipped: true
|
|
352
|
+
});
|
|
333
353
|
continue;
|
|
334
354
|
}
|
|
335
355
|
const result = await verifyAnchor(memory, { projectRoot: ctx.paths.root });
|
|
@@ -387,12 +407,14 @@ function applyVerification(mem, result) {
|
|
|
387
407
|
}
|
|
388
408
|
|
|
389
409
|
// src/tools/mem-reject.ts
|
|
410
|
+
import { writeFile as writeFile4 } from "fs/promises";
|
|
390
411
|
import { existsSync as existsSync7 } from "fs";
|
|
391
412
|
import {
|
|
392
413
|
loadMemoriesFromDir as loadMemoriesFromDir4,
|
|
393
414
|
loadUsageIndex as loadUsageIndex2,
|
|
394
415
|
recordRejection,
|
|
395
|
-
saveUsageIndex
|
|
416
|
+
saveUsageIndex,
|
|
417
|
+
serializeMemory as serializeMemory3
|
|
396
418
|
} from "@hiveai/core";
|
|
397
419
|
import { z as z7 } from "zod";
|
|
398
420
|
var MemRejectInputSchema = {
|
|
@@ -404,16 +426,23 @@ async function memReject(input, ctx) {
|
|
|
404
426
|
throw new Error(`No .ai/memories at ${ctx.paths.root}.`);
|
|
405
427
|
}
|
|
406
428
|
const memories = await loadMemoriesFromDir4(ctx.paths.memoriesDir);
|
|
407
|
-
const
|
|
408
|
-
if (!
|
|
409
|
-
|
|
410
|
-
|
|
429
|
+
const loaded = memories.find((m) => m.memory.frontmatter.id === input.id);
|
|
430
|
+
if (!loaded) throw new Error(`No memory with id "${input.id}".`);
|
|
431
|
+
await writeFile4(
|
|
432
|
+
loaded.filePath,
|
|
433
|
+
serializeMemory3({
|
|
434
|
+
frontmatter: { ...loaded.memory.frontmatter, status: "rejected" },
|
|
435
|
+
body: loaded.memory.body
|
|
436
|
+
}),
|
|
437
|
+
"utf8"
|
|
438
|
+
);
|
|
411
439
|
const idx = await loadUsageIndex2(ctx.paths);
|
|
412
440
|
recordRejection(idx, input.id, input.reason ?? null);
|
|
413
441
|
await saveUsageIndex(ctx.paths, idx);
|
|
414
442
|
const u = idx.by_id[input.id];
|
|
415
443
|
return {
|
|
416
444
|
id: input.id,
|
|
445
|
+
status: "rejected",
|
|
417
446
|
rejected_count: u?.rejected_count ?? 0,
|
|
418
447
|
last_rejected_at: u?.last_rejected_at ?? null,
|
|
419
448
|
rejection_reason: u?.rejection_reason ?? null
|
|
@@ -601,20 +630,80 @@ async function memDelete(input, ctx) {
|
|
|
601
630
|
return { id: input.id, deleted_file: found.filePath, usage_removed: usageRemoved };
|
|
602
631
|
}
|
|
603
632
|
|
|
604
|
-
// src/tools/mem-
|
|
633
|
+
// src/tools/mem-update.ts
|
|
634
|
+
import { writeFile as writeFile5 } from "fs/promises";
|
|
605
635
|
import { existsSync as existsSync11 } from "fs";
|
|
636
|
+
import { loadMemoriesFromDir as loadMemoriesFromDir8, serializeMemory as serializeMemory4 } from "@hiveai/core";
|
|
637
|
+
import { z as z11 } from "zod";
|
|
638
|
+
var MemUpdateInputSchema = {
|
|
639
|
+
id: z11.string().min(1).describe("Id of the memory to update"),
|
|
640
|
+
body: z11.string().optional().describe("New Markdown body \u2014 replaces the existing body"),
|
|
641
|
+
tags: z11.array(z11.string()).optional().describe("New tags array \u2014 fully replaces existing tags"),
|
|
642
|
+
paths: z11.array(z11.string()).optional().describe("New anchor paths \u2014 fully replaces existing anchor.paths"),
|
|
643
|
+
symbols: z11.array(z11.string()).optional().describe("New anchor symbols \u2014 fully replaces existing anchor.symbols"),
|
|
644
|
+
commit: z11.string().optional().describe("New anchor commit SHA"),
|
|
645
|
+
domain: z11.string().optional().describe("New domain label"),
|
|
646
|
+
author: z11.string().optional().describe("New author handle or email")
|
|
647
|
+
};
|
|
648
|
+
async function memUpdate(input, ctx) {
|
|
649
|
+
if (!existsSync11(ctx.paths.memoriesDir)) {
|
|
650
|
+
throw new Error(`No .ai/memories at ${ctx.paths.root}.`);
|
|
651
|
+
}
|
|
652
|
+
const memories = await loadMemoriesFromDir8(ctx.paths.memoriesDir);
|
|
653
|
+
const loaded = memories.find((m) => m.memory.frontmatter.id === input.id);
|
|
654
|
+
if (!loaded) throw new Error(`No memory with id "${input.id}".`);
|
|
655
|
+
const { frontmatter, body } = loaded.memory;
|
|
656
|
+
const updated_fields = [];
|
|
657
|
+
const newAnchor = { ...frontmatter.anchor };
|
|
658
|
+
if (input.paths !== void 0) {
|
|
659
|
+
newAnchor.paths = input.paths;
|
|
660
|
+
updated_fields.push("anchor.paths");
|
|
661
|
+
}
|
|
662
|
+
if (input.symbols !== void 0) {
|
|
663
|
+
newAnchor.symbols = input.symbols;
|
|
664
|
+
updated_fields.push("anchor.symbols");
|
|
665
|
+
}
|
|
666
|
+
if (input.commit !== void 0) {
|
|
667
|
+
newAnchor.commit = input.commit;
|
|
668
|
+
updated_fields.push("anchor.commit");
|
|
669
|
+
}
|
|
670
|
+
const newFrontmatter = {
|
|
671
|
+
...frontmatter,
|
|
672
|
+
anchor: newAnchor,
|
|
673
|
+
...input.tags !== void 0 ? { tags: input.tags } : {},
|
|
674
|
+
...input.domain !== void 0 ? { domain: input.domain } : {},
|
|
675
|
+
...input.author !== void 0 ? { author: input.author } : {}
|
|
676
|
+
};
|
|
677
|
+
if (input.tags !== void 0) updated_fields.push("tags");
|
|
678
|
+
if (input.domain !== void 0) updated_fields.push("domain");
|
|
679
|
+
if (input.author !== void 0) updated_fields.push("author");
|
|
680
|
+
const newBody = input.body !== void 0 ? input.body : body;
|
|
681
|
+
if (input.body !== void 0) updated_fields.push("body");
|
|
682
|
+
if (updated_fields.length === 0) {
|
|
683
|
+
throw new Error("No fields to update \u2014 provide at least one of: body, tags, paths, symbols, commit, domain, author.");
|
|
684
|
+
}
|
|
685
|
+
await writeFile5(
|
|
686
|
+
loaded.filePath,
|
|
687
|
+
serializeMemory4({ frontmatter: newFrontmatter, body: newBody }),
|
|
688
|
+
"utf8"
|
|
689
|
+
);
|
|
690
|
+
return { id: input.id, file_path: loaded.filePath, updated_fields };
|
|
691
|
+
}
|
|
692
|
+
|
|
693
|
+
// src/tools/mem-pending.ts
|
|
694
|
+
import { existsSync as existsSync12 } from "fs";
|
|
606
695
|
import {
|
|
607
696
|
getUsage as getUsage4,
|
|
608
|
-
loadMemoriesFromDir as
|
|
697
|
+
loadMemoriesFromDir as loadMemoriesFromDir9,
|
|
609
698
|
loadUsageIndex as loadUsageIndex6
|
|
610
699
|
} from "@hiveai/core";
|
|
611
|
-
import { z as
|
|
700
|
+
import { z as z12 } from "zod";
|
|
612
701
|
var MemPendingInputSchema = {
|
|
613
|
-
scope:
|
|
702
|
+
scope: z12.enum(["personal", "team", "module"]).optional()
|
|
614
703
|
};
|
|
615
704
|
async function memPending(input, ctx) {
|
|
616
|
-
if (!
|
|
617
|
-
const all = await
|
|
705
|
+
if (!existsSync12(ctx.paths.memoriesDir)) return { pending: [] };
|
|
706
|
+
const all = await loadMemoriesFromDir9(ctx.paths.memoriesDir);
|
|
618
707
|
const usage = await loadUsageIndex6(ctx.paths);
|
|
619
708
|
const now = Date.now();
|
|
620
709
|
const proposed = all.filter(({ memory }) => {
|
|
@@ -645,21 +734,21 @@ async function memPending(input, ctx) {
|
|
|
645
734
|
}
|
|
646
735
|
|
|
647
736
|
// src/tools/mem-approve.ts
|
|
648
|
-
import { writeFile as
|
|
649
|
-
import { existsSync as
|
|
737
|
+
import { writeFile as writeFile6 } from "fs/promises";
|
|
738
|
+
import { existsSync as existsSync13 } from "fs";
|
|
650
739
|
import {
|
|
651
|
-
loadMemoriesFromDir as
|
|
652
|
-
serializeMemory as
|
|
740
|
+
loadMemoriesFromDir as loadMemoriesFromDir10,
|
|
741
|
+
serializeMemory as serializeMemory5
|
|
653
742
|
} from "@hiveai/core";
|
|
654
|
-
import { z as
|
|
743
|
+
import { z as z13 } from "zod";
|
|
655
744
|
var MemApproveInputSchema = {
|
|
656
|
-
id:
|
|
745
|
+
id: z13.string().min(1).describe("Memory id to approve (sets status=validated immediately)")
|
|
657
746
|
};
|
|
658
747
|
async function memApprove(input, ctx) {
|
|
659
|
-
if (!
|
|
748
|
+
if (!existsSync13(ctx.paths.memoriesDir)) {
|
|
660
749
|
throw new Error(`No .ai/memories at ${ctx.paths.root}.`);
|
|
661
750
|
}
|
|
662
|
-
const all = await
|
|
751
|
+
const all = await loadMemoriesFromDir10(ctx.paths.memoriesDir);
|
|
663
752
|
const found = all.find((m) => m.memory.frontmatter.id === input.id);
|
|
664
753
|
if (!found) throw new Error(`No memory with id "${input.id}".`);
|
|
665
754
|
const previous = found.memory.frontmatter.status;
|
|
@@ -667,7 +756,7 @@ async function memApprove(input, ctx) {
|
|
|
667
756
|
frontmatter: { ...found.memory.frontmatter, status: "validated" },
|
|
668
757
|
body: found.memory.body
|
|
669
758
|
};
|
|
670
|
-
await
|
|
759
|
+
await writeFile6(found.filePath, serializeMemory5(next), "utf8");
|
|
671
760
|
return {
|
|
672
761
|
id: input.id,
|
|
673
762
|
previous_status: previous,
|
|
@@ -678,7 +767,7 @@ async function memApprove(input, ctx) {
|
|
|
678
767
|
|
|
679
768
|
// src/tools/get-briefing.ts
|
|
680
769
|
import { readFile as readFile3, readdir as readdir3 } from "fs/promises";
|
|
681
|
-
import { existsSync as
|
|
770
|
+
import { existsSync as existsSync14 } from "fs";
|
|
682
771
|
import path5 from "path";
|
|
683
772
|
import {
|
|
684
773
|
allocateBudget,
|
|
@@ -687,37 +776,41 @@ import {
|
|
|
687
776
|
getUsage as getUsage5,
|
|
688
777
|
inferModulesFromPaths as inferModulesFromPaths2,
|
|
689
778
|
literalMatchesAllTokens as literalMatchesAllTokens2,
|
|
690
|
-
loadMemoriesFromDir as
|
|
779
|
+
loadMemoriesFromDir as loadMemoriesFromDir11,
|
|
691
780
|
loadUsageIndex as loadUsageIndex7,
|
|
692
781
|
memoryMatchesAnchorPaths as memoryMatchesAnchorPaths2,
|
|
693
782
|
tokenizeQuery as tokenizeQuery2,
|
|
694
783
|
trackReads as trackReads3,
|
|
695
784
|
truncateToTokens
|
|
696
785
|
} from "@hiveai/core";
|
|
697
|
-
import { z as
|
|
786
|
+
import { z as z14 } from "zod";
|
|
698
787
|
var GetBriefingInputSchema = {
|
|
699
|
-
task:
|
|
788
|
+
task: z14.string().optional().describe(
|
|
700
789
|
"What you are about to do, in 1\u20132 sentences. Used to rank relevant memories semantically."
|
|
701
790
|
),
|
|
702
|
-
files:
|
|
703
|
-
max_tokens:
|
|
791
|
+
files: z14.array(z14.string()).default([]).describe("Project-relative file paths the agent is currently looking at or about to edit"),
|
|
792
|
+
max_tokens: z14.number().int().positive().default(8e3).describe(
|
|
704
793
|
"Approximate token budget for the entire briefing. Each section is allocated a share and truncated to fit."
|
|
705
794
|
),
|
|
706
|
-
max_memories:
|
|
707
|
-
include_project_context:
|
|
708
|
-
include_module_contexts:
|
|
709
|
-
semantic:
|
|
795
|
+
max_memories: z14.number().int().positive().default(8).describe("Cap on memories surfaced regardless of token budget"),
|
|
796
|
+
include_project_context: z14.boolean().default(true),
|
|
797
|
+
include_module_contexts: z14.boolean().default(true),
|
|
798
|
+
semantic: z14.boolean().default(true).describe(
|
|
710
799
|
"Use semantic ranking when a task is provided (requires `haive embeddings index`)."
|
|
711
800
|
),
|
|
712
|
-
track:
|
|
801
|
+
track: z14.boolean().default(true).describe("Increment read_count on returned memories")
|
|
713
802
|
};
|
|
714
803
|
async function getBriefing(input, ctx) {
|
|
715
804
|
const inferred = inferModulesFromPaths2(input.files);
|
|
716
805
|
const memories = [];
|
|
717
|
-
|
|
718
|
-
|
|
806
|
+
let searchMode = "literal";
|
|
807
|
+
if (existsSync14(ctx.paths.memoriesDir)) {
|
|
808
|
+
const allMemories = await loadMemoriesFromDir11(ctx.paths.memoriesDir);
|
|
719
809
|
const usage = await loadUsageIndex7(ctx.paths);
|
|
720
810
|
const semanticHits = input.task && input.semantic ? await trySemanticHits(ctx, input.task, allMemories.length * 2) : null;
|
|
811
|
+
if (input.task && input.semantic) {
|
|
812
|
+
searchMode = semanticHits ? "semantic" : "literal_fallback";
|
|
813
|
+
}
|
|
721
814
|
const seen = /* @__PURE__ */ new Map();
|
|
722
815
|
const addOrUpdate = (loaded, reason, score) => {
|
|
723
816
|
const fm = loaded.memory.frontmatter;
|
|
@@ -783,7 +876,7 @@ async function getBriefing(input, ctx) {
|
|
|
783
876
|
await trackReads3(ctx.paths, memories.map((m) => m.id));
|
|
784
877
|
}
|
|
785
878
|
}
|
|
786
|
-
const projectContext = input.include_project_context &&
|
|
879
|
+
const projectContext = input.include_project_context && existsSync14(ctx.paths.projectContext) ? await readFile3(ctx.paths.projectContext, "utf8") : "";
|
|
787
880
|
const moduleContents = input.include_module_contexts ? await loadModuleContexts2(ctx, inferred) : [];
|
|
788
881
|
const memoriesText = memories.map((m) => `### ${m.id} (${m.scope}/${m.type}, ${m.confidence})
|
|
789
882
|
${m.body.trim()}`).join("\n\n---\n\n");
|
|
@@ -825,6 +918,7 @@ ${m.content}`).join("\n\n---\n\n"),
|
|
|
825
918
|
const totalTokens = projectSlice.estimatedTokens + modulesSlice.estimatedTokens + memoriesSlice.estimatedTokens;
|
|
826
919
|
return {
|
|
827
920
|
...input.task ? { task: input.task } : {},
|
|
921
|
+
search_mode: searchMode,
|
|
828
922
|
inferred_modules: inferred,
|
|
829
923
|
project_context: projectContext ? { content: projectSlice.text, truncated: projectSlice.truncated } : null,
|
|
830
924
|
module_contexts: trimmedModules,
|
|
@@ -853,7 +947,7 @@ async function trySemanticHits(ctx, task, limit) {
|
|
|
853
947
|
}
|
|
854
948
|
async function loadModuleContexts2(ctx, modules) {
|
|
855
949
|
if (modules.length === 0) return [];
|
|
856
|
-
if (!
|
|
950
|
+
if (!existsSync14(ctx.paths.modulesContextDir)) return [];
|
|
857
951
|
const available = new Set(
|
|
858
952
|
(await readdir3(ctx.paths.modulesContextDir, { withFileTypes: true })).filter((d) => d.isDirectory()).map((d) => d.name)
|
|
859
953
|
);
|
|
@@ -861,7 +955,7 @@ async function loadModuleContexts2(ctx, modules) {
|
|
|
861
955
|
for (const m of modules) {
|
|
862
956
|
if (!available.has(m)) continue;
|
|
863
957
|
const file = path5.join(ctx.paths.modulesContextDir, m, "context.md");
|
|
864
|
-
if (
|
|
958
|
+
if (existsSync14(file)) {
|
|
865
959
|
out.push({ name: m, content: await readFile3(file, "utf8") });
|
|
866
960
|
}
|
|
867
961
|
}
|
|
@@ -870,11 +964,11 @@ async function loadModuleContexts2(ctx, modules) {
|
|
|
870
964
|
|
|
871
965
|
// src/tools/code-map.ts
|
|
872
966
|
import { loadCodeMap, queryCodeMap } from "@hiveai/core";
|
|
873
|
-
import { z as
|
|
967
|
+
import { z as z15 } from "zod";
|
|
874
968
|
var CodeMapInputSchema = {
|
|
875
|
-
file:
|
|
876
|
-
symbol:
|
|
877
|
-
max_files:
|
|
969
|
+
file: z15.string().optional().describe("Filter to files whose path contains this substring"),
|
|
970
|
+
symbol: z15.string().optional().describe("Filter to files exporting a symbol whose name contains this substring"),
|
|
971
|
+
max_files: z15.number().int().positive().default(40).describe("Cap on returned files")
|
|
878
972
|
};
|
|
879
973
|
async function codeMapTool(input, ctx) {
|
|
880
974
|
const map = await loadCodeMap(ctx.paths);
|
|
@@ -900,12 +994,12 @@ async function codeMapTool(input, ctx) {
|
|
|
900
994
|
}
|
|
901
995
|
|
|
902
996
|
// src/prompts/bootstrap-project.ts
|
|
903
|
-
import { z as
|
|
997
|
+
import { z as z16 } from "zod";
|
|
904
998
|
var BootstrapProjectArgsSchema = {
|
|
905
|
-
module:
|
|
999
|
+
module: z16.string().optional().describe(
|
|
906
1000
|
"Optional module name to scope the analysis to (writes to .ai/modules/<module>/context.md)"
|
|
907
1001
|
),
|
|
908
|
-
focus:
|
|
1002
|
+
focus: z16.string().optional().describe("Optional area to emphasize (e.g. 'data layer', 'API surface')")
|
|
909
1003
|
};
|
|
910
1004
|
var ROOT_TEMPLATE = `# Project context
|
|
911
1005
|
|
|
@@ -988,7 +1082,7 @@ ${template}\`\`\`
|
|
|
988
1082
|
|
|
989
1083
|
// src/server.ts
|
|
990
1084
|
var SERVER_NAME = "haive";
|
|
991
|
-
var SERVER_VERSION = "0.2.
|
|
1085
|
+
var SERVER_VERSION = "0.2.3";
|
|
992
1086
|
function jsonResult(data) {
|
|
993
1087
|
return {
|
|
994
1088
|
content: [
|
|
@@ -1077,6 +1171,12 @@ function createHaiveServer(options = {}) {
|
|
|
1077
1171
|
MemDeleteInputSchema,
|
|
1078
1172
|
async (input) => jsonResult(await memDelete(input, context))
|
|
1079
1173
|
);
|
|
1174
|
+
server.tool(
|
|
1175
|
+
"mem_update",
|
|
1176
|
+
"Update the body, tags, or anchor of an existing memory without changing its id or losing usage history.",
|
|
1177
|
+
MemUpdateInputSchema,
|
|
1178
|
+
async (input) => jsonResult(await memUpdate(input, context))
|
|
1179
|
+
);
|
|
1080
1180
|
server.tool(
|
|
1081
1181
|
"mem_pending",
|
|
1082
1182
|
"List 'proposed' memories awaiting review, sorted by reads (most-read first).",
|