@hiveai/mcp 0.2.6 → 0.2.7
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 +102 -17
- package/dist/index.js.map +1 -1
- package/dist/server.js +102 -17
- package/dist/server.js.map +1 -1
- package/package.json +2 -2
package/dist/index.js
CHANGED
|
@@ -903,7 +903,7 @@ async function getBriefing(input, ctx) {
|
|
|
903
903
|
searchMode = semanticHits ? "semantic" : "literal_fallback";
|
|
904
904
|
}
|
|
905
905
|
const seen = /* @__PURE__ */ new Map();
|
|
906
|
-
const addOrUpdate = (loaded, reason, score) => {
|
|
906
|
+
const addOrUpdate = (loaded, reason, score, matchQuality) => {
|
|
907
907
|
const fm = loaded.memory.frontmatter;
|
|
908
908
|
const existing = seen.get(fm.id);
|
|
909
909
|
if (existing) {
|
|
@@ -911,6 +911,11 @@ async function getBriefing(input, ctx) {
|
|
|
911
911
|
if (score !== void 0 && (existing.semantic_score ?? 0) < score) {
|
|
912
912
|
existing.semantic_score = score;
|
|
913
913
|
}
|
|
914
|
+
if (matchQuality === "exact" && existing.match_quality !== "exact") {
|
|
915
|
+
existing.match_quality = "exact";
|
|
916
|
+
} else if (matchQuality === "semantic" && existing.match_quality === "partial") {
|
|
917
|
+
existing.match_quality = "semantic";
|
|
918
|
+
}
|
|
914
919
|
return;
|
|
915
920
|
}
|
|
916
921
|
const u = getUsage5(usage, fm.id);
|
|
@@ -924,6 +929,7 @@ async function getBriefing(input, ctx) {
|
|
|
924
929
|
confidence: deriveConfidence4(fm, u),
|
|
925
930
|
read_count: u.read_count,
|
|
926
931
|
reasons: [reason],
|
|
932
|
+
match_quality: matchQuality ?? "partial",
|
|
927
933
|
...score !== void 0 ? { semantic_score: score } : {},
|
|
928
934
|
body: loaded.memory.body,
|
|
929
935
|
file_path: loaded.filePath
|
|
@@ -931,32 +937,33 @@ async function getBriefing(input, ctx) {
|
|
|
931
937
|
};
|
|
932
938
|
if (input.files.length > 0) {
|
|
933
939
|
for (const loaded of allMemories) {
|
|
934
|
-
if (memoryMatchesAnchorPaths2(loaded.memory, input.files)) addOrUpdate(loaded, "anchor");
|
|
940
|
+
if (memoryMatchesAnchorPaths2(loaded.memory, input.files)) addOrUpdate(loaded, "anchor", void 0, "exact");
|
|
935
941
|
}
|
|
936
942
|
for (const loaded of allMemories) {
|
|
937
943
|
const fm = loaded.memory.frontmatter;
|
|
938
|
-
if (fm.module && inferred.includes(fm.module)) addOrUpdate(loaded, "module");
|
|
939
|
-
if (fm.domain && inferred.includes(fm.domain)) addOrUpdate(loaded, "domain");
|
|
940
|
-
if (fm.tags.some((t) => inferred.includes(t))) addOrUpdate(loaded, "module");
|
|
944
|
+
if (fm.module && inferred.includes(fm.module)) addOrUpdate(loaded, "module", void 0, "partial");
|
|
945
|
+
if (fm.domain && inferred.includes(fm.domain)) addOrUpdate(loaded, "domain", void 0, "partial");
|
|
946
|
+
if (fm.tags.some((t) => inferred.includes(t))) addOrUpdate(loaded, "module", void 0, "partial");
|
|
941
947
|
}
|
|
942
948
|
}
|
|
943
949
|
if (input.task) {
|
|
944
950
|
const tokens = tokenizeQuery2(input.task);
|
|
945
951
|
for (const loaded of allMemories) {
|
|
946
952
|
if (literalMatchesAllTokens2(loaded.memory, tokens)) {
|
|
947
|
-
addOrUpdate(loaded, "semantic");
|
|
953
|
+
addOrUpdate(loaded, "semantic", void 0, "exact");
|
|
948
954
|
}
|
|
949
955
|
}
|
|
950
956
|
if (semanticHits) {
|
|
951
957
|
const byId = new Map(allMemories.map((m) => [m.memory.frontmatter.id, m]));
|
|
952
958
|
for (const hit of semanticHits) {
|
|
953
959
|
const loaded = byId.get(hit.id);
|
|
954
|
-
if (loaded) addOrUpdate(loaded, "semantic", hit.score);
|
|
960
|
+
if (loaded) addOrUpdate(loaded, "semantic", hit.score, "semantic");
|
|
955
961
|
}
|
|
956
962
|
}
|
|
957
963
|
}
|
|
958
964
|
const ranked = [...seen.values()].sort((a, b) => {
|
|
959
|
-
const reasonScore = (m) => (m.
|
|
965
|
+
const reasonScore = (m) => (m.type === "attempt" ? 3 : 0) + // attempt = negative knowledge, surface first to prevent repeating mistakes
|
|
966
|
+
(m.reasons.includes("anchor") ? 4 : 0) + (m.reasons.includes("module") ? 2 : 0) + (m.reasons.includes("semantic") ? 2 : 0) + (m.reasons.includes("domain") ? 1 : 0);
|
|
960
967
|
const confidenceScore = (m) => m.confidence === "authoritative" ? 4 : m.confidence === "trusted" ? 3 : m.confidence === "low" ? 1 : m.confidence === "stale" ? -2 : 0;
|
|
961
968
|
const sa = reasonScore(a) + confidenceScore(a) + (a.semantic_score ?? 0);
|
|
962
969
|
const sb = reasonScore(b) + confidenceScore(b) + (b.semantic_score ?? 0);
|
|
@@ -1003,12 +1010,24 @@ ${m.content}`).join("\n\n---\n\n"),
|
|
|
1003
1010
|
}
|
|
1004
1011
|
}
|
|
1005
1012
|
const trimmedMemoriesText = memoriesSlice.text;
|
|
1006
|
-
const trimmedMemories =
|
|
1007
|
-
|
|
1008
|
-
|
|
1009
|
-
|
|
1010
|
-
|
|
1011
|
-
|
|
1013
|
+
const trimmedMemories = [];
|
|
1014
|
+
if (!memoriesSlice.truncated) {
|
|
1015
|
+
trimmedMemories.push(...memories);
|
|
1016
|
+
} else {
|
|
1017
|
+
let remaining = memoriesSlice.allocatedTokens;
|
|
1018
|
+
for (const m of memories) {
|
|
1019
|
+
const bodyTokens = estimateTokens(m.body);
|
|
1020
|
+
if (remaining <= 0) break;
|
|
1021
|
+
if (bodyTokens <= remaining) {
|
|
1022
|
+
trimmedMemories.push(m);
|
|
1023
|
+
remaining -= bodyTokens;
|
|
1024
|
+
} else if (remaining > 80) {
|
|
1025
|
+
const t = truncateToTokens(m.body, { maxTokens: remaining, mode: "head" });
|
|
1026
|
+
trimmedMemories.push({ ...m, body: t.text });
|
|
1027
|
+
remaining = 0;
|
|
1028
|
+
}
|
|
1029
|
+
}
|
|
1030
|
+
}
|
|
1012
1031
|
const totalTokens = projectSlice.estimatedTokens + modulesSlice.estimatedTokens + memoriesSlice.estimatedTokens;
|
|
1013
1032
|
return {
|
|
1014
1033
|
...input.task ? { task: input.task } : {},
|
|
@@ -1174,9 +1193,69 @@ ${template}\`\`\`
|
|
|
1174
1193
|
};
|
|
1175
1194
|
}
|
|
1176
1195
|
|
|
1196
|
+
// src/prompts/post-task.ts
|
|
1197
|
+
import { z as z18 } from "zod";
|
|
1198
|
+
var PostTaskArgsSchema = {
|
|
1199
|
+
task_summary: z18.string().optional().describe("One sentence describing what you just did"),
|
|
1200
|
+
files_touched: z18.array(z18.string()).optional().describe("Files you created or modified during the task")
|
|
1201
|
+
};
|
|
1202
|
+
function postTaskPrompt(args, ctx) {
|
|
1203
|
+
const taskLine = args.task_summary ? `
|
|
1204
|
+
Task just completed: **${args.task_summary}**` : "";
|
|
1205
|
+
const filesLine = args.files_touched && args.files_touched.length > 0 ? `
|
|
1206
|
+
Files touched: ${args.files_touched.map((f) => `\`${f}\``).join(", ")}` : "";
|
|
1207
|
+
const text = `You have just finished a task. Before closing this session, take 60 seconds to capture what you learned.
|
|
1208
|
+
${taskLine}${filesLine}
|
|
1209
|
+
|
|
1210
|
+
Project root: \`${ctx.paths.root}\`
|
|
1211
|
+
|
|
1212
|
+
## Checklist \u2014 answer each question honestly
|
|
1213
|
+
|
|
1214
|
+
Go through each item. If the answer is yes, call the corresponding tool immediately.
|
|
1215
|
+
|
|
1216
|
+
### 1. Did you try an approach that failed?
|
|
1217
|
+
\u2192 If yes, call **\`mem_tried\`** with:
|
|
1218
|
+
- \`what\`: the approach you tried (e.g. "importing gray-matter with ESM dynamic import")
|
|
1219
|
+
- \`why_failed\`: why it didn't work
|
|
1220
|
+
- \`instead\`: what worked instead
|
|
1221
|
+
- \`scope\`: "team" if others will hit the same issue, "personal" if specific to your setup
|
|
1222
|
+
- \`paths\`: the files where the issue manifested
|
|
1223
|
+
|
|
1224
|
+
### 2. Did you discover a convention that isn't documented?
|
|
1225
|
+
\u2192 If yes, call **\`mem_save\`** with \`type="convention"\` and \`scope="team"\`
|
|
1226
|
+
|
|
1227
|
+
### 3. Did you make an architectural decision?
|
|
1228
|
+
\u2192 If yes, call **\`mem_save\`** with \`type="decision"\` and document the WHY (constraints, tradeoffs), not just the what
|
|
1229
|
+
|
|
1230
|
+
### 4. Did you hit a non-obvious bug or surprising behavior?
|
|
1231
|
+
\u2192 If yes, call **\`mem_save\`** with \`type="gotcha"\` and anchor it to the relevant file paths
|
|
1232
|
+
|
|
1233
|
+
### 5. Did you find that an existing memory is outdated or wrong?
|
|
1234
|
+
\u2192 If yes, call **\`mem_update\`** with the correct information, or **\`mem_reject\`** if it's completely wrong
|
|
1235
|
+
|
|
1236
|
+
## Rules
|
|
1237
|
+
|
|
1238
|
+
- One memory per insight. Don't cram multiple lessons into one body.
|
|
1239
|
+
- Anchor memories to file paths when possible (the \`paths\` field) \u2014 this enables staleness detection.
|
|
1240
|
+
- Prefer \`scope="team"\` for anything a teammate or future agent would benefit from.
|
|
1241
|
+
- Skip sections where you genuinely have nothing to add. Don't fabricate memories.
|
|
1242
|
+
|
|
1243
|
+
When done, respond with a brief summary: "Saved N memories: [list of IDs]" or "Nothing new to save."
|
|
1244
|
+
`;
|
|
1245
|
+
return {
|
|
1246
|
+
description: "Post-task reflection: capture what you learned before closing the session",
|
|
1247
|
+
messages: [
|
|
1248
|
+
{
|
|
1249
|
+
role: "user",
|
|
1250
|
+
content: { type: "text", text }
|
|
1251
|
+
}
|
|
1252
|
+
]
|
|
1253
|
+
};
|
|
1254
|
+
}
|
|
1255
|
+
|
|
1177
1256
|
// src/server.ts
|
|
1178
1257
|
var SERVER_NAME = "haive";
|
|
1179
|
-
var SERVER_VERSION = "0.2.
|
|
1258
|
+
var SERVER_VERSION = "0.2.7";
|
|
1180
1259
|
function jsonResult(data) {
|
|
1181
1260
|
return {
|
|
1182
1261
|
content: [
|
|
@@ -1195,7 +1274,7 @@ function createHaiveServer(options = {}) {
|
|
|
1195
1274
|
);
|
|
1196
1275
|
server.tool(
|
|
1197
1276
|
"mem_save",
|
|
1198
|
-
"Save a new memory (
|
|
1277
|
+
"Save a new memory (convention, decision, gotcha, architecture, glossary). For failed approaches use mem_tried instead \u2014 it enforces a structured format that is more useful to future agents. Use scope=team to share with the whole team.",
|
|
1199
1278
|
MemSaveInputSchema,
|
|
1200
1279
|
async (input) => jsonResult(await memSave(input, context))
|
|
1201
1280
|
);
|
|
@@ -1285,7 +1364,7 @@ function createHaiveServer(options = {}) {
|
|
|
1285
1364
|
);
|
|
1286
1365
|
server.tool(
|
|
1287
1366
|
"mem_tried",
|
|
1288
|
-
"
|
|
1367
|
+
"Preferred way to record a failed approach. Enforces a structured what/why_failed/instead format that is immediately actionable for future agents. Auto-validated (no approval cycle). Use whenever you tried an approach and it failed \u2014 prevents the same mistake from happening in the next session.",
|
|
1289
1368
|
MemTriedInputSchema,
|
|
1290
1369
|
async (input) => jsonResult(await memTried(input, context))
|
|
1291
1370
|
);
|
|
@@ -1295,6 +1374,12 @@ function createHaiveServer(options = {}) {
|
|
|
1295
1374
|
BootstrapProjectArgsSchema,
|
|
1296
1375
|
(args) => bootstrapProjectPrompt(args, context)
|
|
1297
1376
|
);
|
|
1377
|
+
server.prompt(
|
|
1378
|
+
"post_task",
|
|
1379
|
+
"Post-task checklist: run this after completing a task to capture failed approaches, new conventions, decisions, and gotchas before closing the session.",
|
|
1380
|
+
PostTaskArgsSchema,
|
|
1381
|
+
(args) => postTaskPrompt(args, context)
|
|
1382
|
+
);
|
|
1298
1383
|
return { server, context };
|
|
1299
1384
|
}
|
|
1300
1385
|
|