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