@hiveai/mcp 0.15.0 → 0.18.0
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 +131 -60
- package/dist/index.js.map +1 -1
- package/dist/server.js +131 -60
- package/dist/server.js.map +1 -1
- package/package.json +3 -3
package/dist/server.js
CHANGED
|
@@ -668,15 +668,19 @@ async function memReject(input, ctx) {
|
|
|
668
668
|
|
|
669
669
|
// src/tools/mem-feedback.ts
|
|
670
670
|
import {
|
|
671
|
+
applyFeedbackAdjustment,
|
|
671
672
|
computeImpact,
|
|
672
673
|
getUsage as getUsage2,
|
|
673
674
|
loadMemoriesFromDir as loadMemoriesFromDir6,
|
|
674
675
|
loadUsageIndex as loadUsageIndex3,
|
|
675
676
|
recordApplied,
|
|
676
677
|
recordRejection as recordRejection2,
|
|
677
|
-
|
|
678
|
+
recommendFeedbackAdjustment,
|
|
679
|
+
saveUsageIndex as saveUsageIndex2,
|
|
680
|
+
serializeMemory as serializeMemory4
|
|
678
681
|
} from "@hiveai/core";
|
|
679
682
|
import { existsSync as existsSync8 } from "fs";
|
|
683
|
+
import { writeFile as writeFile5 } from "fs/promises";
|
|
680
684
|
import { z as z8 } from "zod";
|
|
681
685
|
var MemFeedbackInputSchema = {
|
|
682
686
|
id: z8.string().min(1).describe("Full memory id the feedback is about"),
|
|
@@ -702,6 +706,12 @@ async function memFeedback(input, ctx) {
|
|
|
702
706
|
}
|
|
703
707
|
await saveUsageIndex2(ctx.paths, index);
|
|
704
708
|
const usage = getUsage2(index, input.id);
|
|
709
|
+
const adjustment = input.outcome === "rejected" ? recommendFeedbackAdjustment(target.memory.frontmatter, usage) : { action: "none", reason: "No automatic adjustment needed." };
|
|
710
|
+
const adjustedFrontmatter = applyFeedbackAdjustment(target.memory.frontmatter, adjustment);
|
|
711
|
+
if (adjustedFrontmatter !== target.memory.frontmatter) {
|
|
712
|
+
target.memory.frontmatter = adjustedFrontmatter;
|
|
713
|
+
await writeFile5(target.filePath, serializeMemory4(target.memory), "utf8");
|
|
714
|
+
}
|
|
705
715
|
const impact = computeImpact(target.memory.frontmatter, usage);
|
|
706
716
|
return {
|
|
707
717
|
ok: true,
|
|
@@ -712,7 +722,8 @@ async function memFeedback(input, ctx) {
|
|
|
712
722
|
applied_count: usage.applied_count,
|
|
713
723
|
rejected_count: usage.rejected_count
|
|
714
724
|
},
|
|
715
|
-
impact: { score: impact.score, tier: impact.tier, signals: impact.signals }
|
|
725
|
+
impact: { score: impact.score, tier: impact.tier, signals: impact.signals },
|
|
726
|
+
feedback_adjustment: adjustment
|
|
716
727
|
};
|
|
717
728
|
}
|
|
718
729
|
|
|
@@ -952,9 +963,9 @@ async function memDelete(input, ctx) {
|
|
|
952
963
|
}
|
|
953
964
|
|
|
954
965
|
// src/tools/mem-update.ts
|
|
955
|
-
import { writeFile as
|
|
966
|
+
import { writeFile as writeFile6 } from "fs/promises";
|
|
956
967
|
import { existsSync as existsSync12 } from "fs";
|
|
957
|
-
import { loadMemoriesFromDir as loadMemoriesFromDir10, serializeMemory as
|
|
968
|
+
import { loadMemoriesFromDir as loadMemoriesFromDir10, serializeMemory as serializeMemory5 } from "@hiveai/core";
|
|
958
969
|
import { z as z12 } from "zod";
|
|
959
970
|
var MemUpdateInputSchema = {
|
|
960
971
|
id: z12.string().min(1).describe("Id of the memory to update"),
|
|
@@ -1003,9 +1014,9 @@ async function memUpdate(input, ctx) {
|
|
|
1003
1014
|
if (updated_fields.length === 0) {
|
|
1004
1015
|
throw new Error("No fields to update \u2014 provide at least one of: body, tags, paths, symbols, commit, domain, author.");
|
|
1005
1016
|
}
|
|
1006
|
-
await
|
|
1017
|
+
await writeFile6(
|
|
1007
1018
|
loaded.filePath,
|
|
1008
|
-
|
|
1019
|
+
serializeMemory5({ frontmatter: newFrontmatter, body: newBody }),
|
|
1009
1020
|
"utf8"
|
|
1010
1021
|
);
|
|
1011
1022
|
return { id: input.id, file_path: loaded.filePath, updated_fields };
|
|
@@ -1055,11 +1066,11 @@ async function memPending(input, ctx) {
|
|
|
1055
1066
|
}
|
|
1056
1067
|
|
|
1057
1068
|
// src/tools/mem-approve.ts
|
|
1058
|
-
import { writeFile as
|
|
1069
|
+
import { writeFile as writeFile7 } from "fs/promises";
|
|
1059
1070
|
import { existsSync as existsSync14 } from "fs";
|
|
1060
1071
|
import {
|
|
1061
1072
|
loadMemoriesFromDir as loadMemoriesFromDir12,
|
|
1062
|
-
serializeMemory as
|
|
1073
|
+
serializeMemory as serializeMemory6
|
|
1063
1074
|
} from "@hiveai/core";
|
|
1064
1075
|
import { z as z14 } from "zod";
|
|
1065
1076
|
var MemApproveInputSchema = {
|
|
@@ -1077,7 +1088,7 @@ async function memApprove(input, ctx) {
|
|
|
1077
1088
|
frontmatter: { ...found.memory.frontmatter, status: "validated" },
|
|
1078
1089
|
body: found.memory.body
|
|
1079
1090
|
};
|
|
1080
|
-
await
|
|
1091
|
+
await writeFile7(found.filePath, serializeMemory6(next), "utf8");
|
|
1081
1092
|
return {
|
|
1082
1093
|
id: input.id,
|
|
1083
1094
|
previous_status: previous,
|
|
@@ -1087,13 +1098,13 @@ async function memApprove(input, ctx) {
|
|
|
1087
1098
|
}
|
|
1088
1099
|
|
|
1089
1100
|
// src/tools/mem-tried.ts
|
|
1090
|
-
import { mkdir as mkdir3, writeFile as
|
|
1101
|
+
import { mkdir as mkdir3, writeFile as writeFile8 } from "fs/promises";
|
|
1091
1102
|
import { existsSync as existsSync15 } from "fs";
|
|
1092
1103
|
import path5 from "path";
|
|
1093
1104
|
import {
|
|
1094
1105
|
buildFrontmatter as buildFrontmatter2,
|
|
1095
1106
|
memoryFilePath as memoryFilePath2,
|
|
1096
|
-
serializeMemory as
|
|
1107
|
+
serializeMemory as serializeMemory7,
|
|
1097
1108
|
suggestSensorFromMemory as suggestSensorFromMemory2
|
|
1098
1109
|
} from "@hiveai/core";
|
|
1099
1110
|
import { z as z15 } from "zod";
|
|
@@ -1137,13 +1148,13 @@ async function memTried(input, ctx) {
|
|
|
1137
1148
|
if (existsSync15(file)) {
|
|
1138
1149
|
throw new Error(`Memory already exists at ${file}`);
|
|
1139
1150
|
}
|
|
1140
|
-
await
|
|
1151
|
+
await writeFile8(file, serializeMemory7({ frontmatter, body }), "utf8");
|
|
1141
1152
|
return { id: frontmatter.id, scope: frontmatter.scope, file_path: file };
|
|
1142
1153
|
}
|
|
1143
1154
|
|
|
1144
1155
|
// src/tools/ingest-findings.ts
|
|
1145
1156
|
import { existsSync as existsSync16 } from "fs";
|
|
1146
|
-
import { mkdir as mkdir4, readFile as readFile3, writeFile as
|
|
1157
|
+
import { mkdir as mkdir4, readFile as readFile3, writeFile as writeFile9 } from "fs/promises";
|
|
1147
1158
|
import path6 from "path";
|
|
1148
1159
|
import {
|
|
1149
1160
|
draftsFromFindings,
|
|
@@ -1151,7 +1162,7 @@ import {
|
|
|
1151
1162
|
loadMemoriesFromDir as loadMemoriesFromDir13,
|
|
1152
1163
|
memoryFilePath as memoryFilePath3,
|
|
1153
1164
|
parseFindings,
|
|
1154
|
-
serializeMemory as
|
|
1165
|
+
serializeMemory as serializeMemory8
|
|
1155
1166
|
} from "@hiveai/core";
|
|
1156
1167
|
import { z as z16 } from "zod";
|
|
1157
1168
|
var IngestFindingsInputSchema = {
|
|
@@ -1228,19 +1239,19 @@ async function writeDraft(ctx, draft) {
|
|
|
1228
1239
|
draft.frontmatter.module
|
|
1229
1240
|
);
|
|
1230
1241
|
await mkdir4(path6.dirname(file), { recursive: true });
|
|
1231
|
-
await
|
|
1242
|
+
await writeFile9(file, serializeMemory8({ frontmatter: draft.frontmatter, body: draft.body }), "utf8");
|
|
1232
1243
|
return file;
|
|
1233
1244
|
}
|
|
1234
1245
|
|
|
1235
1246
|
// src/tools/mem-observe.ts
|
|
1236
|
-
import { mkdir as mkdir5, writeFile as
|
|
1247
|
+
import { mkdir as mkdir5, writeFile as writeFile10 } from "fs/promises";
|
|
1237
1248
|
import { existsSync as existsSync17 } from "fs";
|
|
1238
1249
|
import path7 from "path";
|
|
1239
1250
|
import {
|
|
1240
1251
|
buildFrontmatter as buildFrontmatter3,
|
|
1241
1252
|
isLikelyGuessable,
|
|
1242
1253
|
memoryFilePath as memoryFilePath4,
|
|
1243
|
-
serializeMemory as
|
|
1254
|
+
serializeMemory as serializeMemory9
|
|
1244
1255
|
} from "@hiveai/core";
|
|
1245
1256
|
import { z as z17 } from "zod";
|
|
1246
1257
|
var MemObserveInputSchema = {
|
|
@@ -1294,19 +1305,19 @@ async function memObserve(input, ctx) {
|
|
|
1294
1305
|
if (existsSync17(file)) {
|
|
1295
1306
|
throw new Error(`Memory already exists at ${file}`);
|
|
1296
1307
|
}
|
|
1297
|
-
await
|
|
1308
|
+
await writeFile10(file, serializeMemory9({ frontmatter, body }), "utf8");
|
|
1298
1309
|
return { id: frontmatter.id, scope: frontmatter.scope, file_path: file };
|
|
1299
1310
|
}
|
|
1300
1311
|
|
|
1301
1312
|
// src/tools/mem-session-end.ts
|
|
1302
|
-
import { writeFile as
|
|
1313
|
+
import { writeFile as writeFile12, mkdir as mkdir7 } from "fs/promises";
|
|
1303
1314
|
import { existsSync as existsSync19 } from "fs";
|
|
1304
1315
|
import path9 from "path";
|
|
1305
1316
|
import {
|
|
1306
1317
|
buildFrontmatter as buildFrontmatter4,
|
|
1307
1318
|
loadMemoriesFromDir as loadMemoriesFromDir14,
|
|
1308
1319
|
memoryFilePath as memoryFilePath5,
|
|
1309
|
-
serializeMemory as
|
|
1320
|
+
serializeMemory as serializeMemory10
|
|
1310
1321
|
} from "@hiveai/core";
|
|
1311
1322
|
import { z as z18 } from "zod";
|
|
1312
1323
|
|
|
@@ -1316,7 +1327,7 @@ import {
|
|
|
1316
1327
|
appendRuntimeJournalEntry,
|
|
1317
1328
|
loadConfig as loadConfig2
|
|
1318
1329
|
} from "@hiveai/core";
|
|
1319
|
-
import { mkdir as mkdir6, writeFile as
|
|
1330
|
+
import { mkdir as mkdir6, writeFile as writeFile11, rm } from "fs/promises";
|
|
1320
1331
|
import { existsSync as existsSync18 } from "fs";
|
|
1321
1332
|
import path8 from "path";
|
|
1322
1333
|
import { execSync } from "child_process";
|
|
@@ -1415,7 +1426,7 @@ var SessionTracker = class {
|
|
|
1415
1426
|
};
|
|
1416
1427
|
const cacheDir = path8.join(this.ctx.paths.haiveDir, ".cache");
|
|
1417
1428
|
await mkdir6(cacheDir, { recursive: true });
|
|
1418
|
-
await
|
|
1429
|
+
await writeFile11(
|
|
1419
1430
|
pendingDistillPath(this.ctx),
|
|
1420
1431
|
JSON.stringify(payload, null, 2) + "\n",
|
|
1421
1432
|
"utf8"
|
|
@@ -1521,9 +1532,9 @@ async function memSessionEnd(input, ctx) {
|
|
|
1521
1532
|
paths: normalizedFiles.length ? normalizedFiles : fm.anchor.paths
|
|
1522
1533
|
}
|
|
1523
1534
|
};
|
|
1524
|
-
await
|
|
1535
|
+
await writeFile12(
|
|
1525
1536
|
topicMatch.filePath,
|
|
1526
|
-
|
|
1537
|
+
serializeMemory10({ frontmatter: newFrontmatter, body }),
|
|
1527
1538
|
"utf8"
|
|
1528
1539
|
);
|
|
1529
1540
|
await clearPendingDistill(ctx);
|
|
@@ -1552,7 +1563,7 @@ async function memSessionEnd(input, ctx) {
|
|
|
1552
1563
|
frontmatter.module
|
|
1553
1564
|
);
|
|
1554
1565
|
await mkdir7(path9.dirname(file), { recursive: true });
|
|
1555
|
-
await
|
|
1566
|
+
await writeFile12(file, serializeMemory10({ frontmatter, body }), "utf8");
|
|
1556
1567
|
await clearPendingDistill(ctx);
|
|
1557
1568
|
return {
|
|
1558
1569
|
id: frontmatter.id,
|
|
@@ -1564,15 +1575,17 @@ async function memSessionEnd(input, ctx) {
|
|
|
1564
1575
|
}
|
|
1565
1576
|
|
|
1566
1577
|
// src/tools/get-briefing.ts
|
|
1567
|
-
import { readFile as readFile5, writeFile as
|
|
1578
|
+
import { readFile as readFile5, writeFile as writeFile13 } from "fs/promises";
|
|
1568
1579
|
import { existsSync as existsSync21 } from "fs";
|
|
1569
1580
|
import {
|
|
1570
1581
|
allocateBudget,
|
|
1582
|
+
briefingProofLine,
|
|
1571
1583
|
computeImpact as computeImpact2,
|
|
1572
1584
|
DEFAULT_AUTO_PROMOTE_RULE,
|
|
1573
1585
|
deriveConfidence as deriveConfidence4,
|
|
1574
1586
|
estimateTokens,
|
|
1575
1587
|
evaluateSkillActivation,
|
|
1588
|
+
compactAutoRecapBody,
|
|
1576
1589
|
extractActionsBriefBody,
|
|
1577
1590
|
getUsage as getUsage6,
|
|
1578
1591
|
inferModulesFromPaths as inferModulesFromPaths2,
|
|
@@ -1585,6 +1598,7 @@ import {
|
|
|
1585
1598
|
loadConfig as loadConfig3,
|
|
1586
1599
|
hashProjectContext,
|
|
1587
1600
|
loadMemoriesFromDir as loadMemoriesFromDir15,
|
|
1601
|
+
loadPreventionEvents,
|
|
1588
1602
|
loadUsageIndex as loadUsageIndex8,
|
|
1589
1603
|
memoryMatchesAnchorPaths as memoryMatchesAnchorPaths2,
|
|
1590
1604
|
projectContextRecentlyEmitted,
|
|
@@ -1592,7 +1606,7 @@ import {
|
|
|
1592
1606
|
recordProjectContextEmission,
|
|
1593
1607
|
queryCodeMap,
|
|
1594
1608
|
resolveBriefingBudget,
|
|
1595
|
-
serializeMemory as
|
|
1609
|
+
serializeMemory as serializeMemory11,
|
|
1596
1610
|
specificityScore,
|
|
1597
1611
|
GUESSABLE_THRESHOLD,
|
|
1598
1612
|
tokenizeQuery as tokenizeQuery2,
|
|
@@ -1606,7 +1620,12 @@ import { z as z19 } from "zod";
|
|
|
1606
1620
|
import { readdir as readdir3, readFile as readFile4 } from "fs/promises";
|
|
1607
1621
|
import { existsSync as existsSync20 } from "fs";
|
|
1608
1622
|
import path10 from "path";
|
|
1609
|
-
import {
|
|
1623
|
+
import {
|
|
1624
|
+
classifyMemoryPriority as coreClassifyPriority,
|
|
1625
|
+
isGlobPath,
|
|
1626
|
+
pathsOverlap,
|
|
1627
|
+
priorityRank as corePriorityRank
|
|
1628
|
+
} from "@hiveai/core";
|
|
1610
1629
|
function compactSummary(body) {
|
|
1611
1630
|
for (const line of body.split("\n")) {
|
|
1612
1631
|
const trimmed = line.replace(/^#+\s*/, "").trim();
|
|
@@ -1624,21 +1643,23 @@ function classifyMemoryPriority(memory, loaded, inputFiles, inputSymbols) {
|
|
|
1624
1643
|
(sym) => inputSymbols.some((wanted) => wanted.toLowerCase() === sym.toLowerCase())
|
|
1625
1644
|
)
|
|
1626
1645
|
);
|
|
1627
|
-
const
|
|
1628
|
-
|
|
1629
|
-
|
|
1630
|
-
|
|
1631
|
-
|
|
1632
|
-
|
|
1633
|
-
|
|
1634
|
-
|
|
1635
|
-
|
|
1636
|
-
|
|
1637
|
-
|
|
1638
|
-
|
|
1646
|
+
const semantic = memory.semantic_score ?? 0;
|
|
1647
|
+
return coreClassifyPriority({
|
|
1648
|
+
type: memory.type,
|
|
1649
|
+
tags: fm?.tags ?? memory.tags ?? [],
|
|
1650
|
+
requiresHumanApproval: Boolean(fm?.requires_human_approval),
|
|
1651
|
+
directAnchor,
|
|
1652
|
+
directSymbol,
|
|
1653
|
+
exactTaskMatch: memory.match_quality === "exact",
|
|
1654
|
+
strongSemantic: semantic >= 0.65,
|
|
1655
|
+
usefulSemantic: semantic >= 0.35,
|
|
1656
|
+
moduleOrDomainMatch: memory.reasons.includes("module") || memory.reasons.includes("domain"),
|
|
1657
|
+
tagTaskMatch: false
|
|
1658
|
+
// MCP ranking doesn't use a separate tag-token signal
|
|
1659
|
+
});
|
|
1639
1660
|
}
|
|
1640
1661
|
function priorityRank(priority) {
|
|
1641
|
-
return priority
|
|
1662
|
+
return corePriorityRank(priority);
|
|
1642
1663
|
}
|
|
1643
1664
|
function classifyBriefingQuality(memories, context) {
|
|
1644
1665
|
const mustRead = memories.filter((m) => m.priority === "must_read").length;
|
|
@@ -1807,7 +1828,9 @@ async function getBriefing(input, ctx) {
|
|
|
1807
1828
|
id: fm.id,
|
|
1808
1829
|
scope: fm.scope,
|
|
1809
1830
|
revision_count: fm.revision_count ?? 0,
|
|
1810
|
-
|
|
1831
|
+
// Auto-generated recaps are low-signal tool dumps — compact them so they inform without
|
|
1832
|
+
// dominating the briefing head. Human/post_task recaps pass through unchanged.
|
|
1833
|
+
body: compactAutoRecapBody(r.memory.body)
|
|
1811
1834
|
};
|
|
1812
1835
|
}
|
|
1813
1836
|
const allMemories = allLoaded.filter(({ memory }) => {
|
|
@@ -1959,7 +1982,7 @@ async function getBriefing(input, ctx) {
|
|
|
1959
1982
|
if (!isAutoPromoteEligible(loaded.memory.frontmatter, u, rule)) continue;
|
|
1960
1983
|
const newFm = { ...loaded.memory.frontmatter, status: "validated" };
|
|
1961
1984
|
try {
|
|
1962
|
-
await
|
|
1985
|
+
await writeFile13(loaded.filePath, serializeMemory11({ frontmatter: newFm, body: loaded.memory.body }), "utf8");
|
|
1963
1986
|
m.status = "validated";
|
|
1964
1987
|
m.confidence = "trusted";
|
|
1965
1988
|
} catch {
|
|
@@ -2230,6 +2253,10 @@ When done, call \`mem_session_end\` to acknowledge \u2014 this clears the pendin
|
|
|
2230
2253
|
"No team-specific policy matched these files/task \u2014 nothing here a capable model can't infer. The auto-generated project context was trimmed to keep this briefing near-zero-cost; proceed with normal Read/Grep."
|
|
2231
2254
|
);
|
|
2232
2255
|
}
|
|
2256
|
+
if (outputMemories.length > 0 && existsSync21(ctx.paths.haiveDir)) {
|
|
2257
|
+
const proof = briefingProofLine(await loadPreventionEvents(ctx.paths));
|
|
2258
|
+
if (proof) hints.push(proof);
|
|
2259
|
+
}
|
|
2233
2260
|
if (existsSync21(ctx.paths.haiveDir)) {
|
|
2234
2261
|
await writeBriefingMarker(ctx.paths, {
|
|
2235
2262
|
sessionId: process.env.HAIVE_SESSION_ID,
|
|
@@ -2639,6 +2666,7 @@ import { existsSync as existsSync25 } from "fs";
|
|
|
2639
2666
|
import {
|
|
2640
2667
|
addedLinesFromDiff,
|
|
2641
2668
|
appendPreventionEvent,
|
|
2669
|
+
BRIDGE_TARGET_PATH,
|
|
2642
2670
|
buildDocFrequency,
|
|
2643
2671
|
CODE_STOPWORDS,
|
|
2644
2672
|
deriveConfidence as deriveConfidence6,
|
|
@@ -2680,6 +2708,44 @@ function tokenizeDiffForLiteral(diff) {
|
|
|
2680
2708
|
const wordTokens = source.toLowerCase().split(/[^a-z0-9]+/).filter((t) => t.length >= 4 && !CODE_STOPWORDS.has(t));
|
|
2681
2709
|
return [.../* @__PURE__ */ new Set([...wsTokens, ...wordTokens])];
|
|
2682
2710
|
}
|
|
2711
|
+
var HAIVE_GENERATED_FILES = /* @__PURE__ */ new Set([
|
|
2712
|
+
...Object.values(BRIDGE_TARGET_PATH),
|
|
2713
|
+
// .clinerules, .windsurfrules, .continuerules, .rules, AGENTS.md, .github/copilot-instructions.md, .sourcegraph/cody-rules.md
|
|
2714
|
+
"CLAUDE.md",
|
|
2715
|
+
".cursorrules",
|
|
2716
|
+
".gitignore",
|
|
2717
|
+
".mcp.json",
|
|
2718
|
+
".cursor/mcp.json",
|
|
2719
|
+
".vscode/mcp.json"
|
|
2720
|
+
]);
|
|
2721
|
+
function isHaiveOwnedPath(p) {
|
|
2722
|
+
if (p.startsWith(".ai/")) return true;
|
|
2723
|
+
if (HAIVE_GENERATED_FILES.has(p)) return true;
|
|
2724
|
+
if (p.startsWith(".cursor/rules/")) return true;
|
|
2725
|
+
if (/^\.github\/workflows\/haive-.*\.ya?ml$/.test(p)) return true;
|
|
2726
|
+
return false;
|
|
2727
|
+
}
|
|
2728
|
+
function stripAiDirHunks(diff) {
|
|
2729
|
+
if (!diff.includes("diff --git")) return diff;
|
|
2730
|
+
const out = [];
|
|
2731
|
+
let block = [];
|
|
2732
|
+
let keep = true;
|
|
2733
|
+
const flush = () => {
|
|
2734
|
+
if (keep) out.push(...block);
|
|
2735
|
+
block = [];
|
|
2736
|
+
keep = true;
|
|
2737
|
+
};
|
|
2738
|
+
for (const line of diff.split("\n")) {
|
|
2739
|
+
if (line.startsWith("diff --git ")) {
|
|
2740
|
+
flush();
|
|
2741
|
+
const target = line.match(/ b\/(.+)$/)?.[1] ?? "";
|
|
2742
|
+
keep = !isHaiveOwnedPath(target);
|
|
2743
|
+
}
|
|
2744
|
+
block.push(line);
|
|
2745
|
+
}
|
|
2746
|
+
flush();
|
|
2747
|
+
return out.join("\n");
|
|
2748
|
+
}
|
|
2683
2749
|
async function antiPatternsCheck(input, ctx) {
|
|
2684
2750
|
if (!input.diff && input.paths.length === 0) {
|
|
2685
2751
|
return {
|
|
@@ -2735,10 +2801,11 @@ async function antiPatternsCheck(input, ctx) {
|
|
|
2735
2801
|
}
|
|
2736
2802
|
}
|
|
2737
2803
|
}
|
|
2738
|
-
|
|
2739
|
-
|
|
2740
|
-
const
|
|
2741
|
-
const
|
|
2804
|
+
const scanDiff = input.diff ? stripAiDirHunks(input.diff) : input.diff;
|
|
2805
|
+
if (scanDiff) {
|
|
2806
|
+
const tokens = tokenizeDiffForLiteral(scanDiff);
|
|
2807
|
+
const added = addedLinesFromDiff(scanDiff);
|
|
2808
|
+
const addedText = added.trim().length > 0 ? added : scanDiff;
|
|
2742
2809
|
if (tokens.length > 0) {
|
|
2743
2810
|
for (const { memory } of negative) {
|
|
2744
2811
|
if (literalMatchesAnyToken3(memory, tokens)) {
|
|
@@ -2751,11 +2818,13 @@ async function antiPatternsCheck(input, ctx) {
|
|
|
2751
2818
|
}
|
|
2752
2819
|
}
|
|
2753
2820
|
}
|
|
2754
|
-
if (
|
|
2755
|
-
const added = addedLinesFromDiff(
|
|
2756
|
-
const diffTargets = sensorTargetsFromDiff(
|
|
2821
|
+
if (scanDiff) {
|
|
2822
|
+
const added = addedLinesFromDiff(scanDiff);
|
|
2823
|
+
const diffTargets = sensorTargetsFromDiff(scanDiff);
|
|
2757
2824
|
const hasFileTargets = diffTargets.some((target) => target.path.length > 0);
|
|
2758
|
-
const
|
|
2825
|
+
const codePaths = input.paths.filter((p) => !isHaiveOwnedPath(p));
|
|
2826
|
+
const fallbackContent = added.trim().length > 0 ? added : scanDiff;
|
|
2827
|
+
const targets = diffTargets.length > 0 && hasFileTargets ? diffTargets : codePaths.length > 0 ? codePaths.map((p) => ({ path: p, content: fallbackContent })) : [{ path: "", content: fallbackContent }];
|
|
2759
2828
|
const hits = runSensors(negative.map(({ memory }) => memory), targets);
|
|
2760
2829
|
for (const hit of hits) {
|
|
2761
2830
|
const found = negative.find(({ memory }) => memory.frontmatter.id === hit.memory_id);
|
|
@@ -2768,10 +2837,10 @@ async function antiPatternsCheck(input, ctx) {
|
|
|
2768
2837
|
}
|
|
2769
2838
|
}
|
|
2770
2839
|
}
|
|
2771
|
-
if (input.semantic &&
|
|
2840
|
+
if (input.semantic && scanDiff) {
|
|
2772
2841
|
try {
|
|
2773
2842
|
const mod = await import("@hiveai/embeddings");
|
|
2774
|
-
const result = await mod.semanticSearch(ctx.paths,
|
|
2843
|
+
const result = await mod.semanticSearch(ctx.paths, scanDiff, { limit: input.limit * 2 });
|
|
2775
2844
|
if (result) {
|
|
2776
2845
|
const negativeIds = new Set(negative.map(({ memory }) => memory.frontmatter.id));
|
|
2777
2846
|
for (const hit of result.hits) {
|
|
@@ -2793,7 +2862,7 @@ async function antiPatternsCheck(input, ctx) {
|
|
|
2793
2862
|
return score(b) - score(a);
|
|
2794
2863
|
}).slice(0, input.limit);
|
|
2795
2864
|
const strongCatches = warnings.filter(
|
|
2796
|
-
(w) => w.reasons.includes("sensor") || w.
|
|
2865
|
+
(w) => w.reasons.includes("sensor") || w.reasons.includes("anchor") && w.reasons.includes("literal")
|
|
2797
2866
|
);
|
|
2798
2867
|
if (strongCatches.length > 0) {
|
|
2799
2868
|
const recordedIds = [];
|
|
@@ -3418,7 +3487,9 @@ function classifyWarning(warning, paths, anchoredBlocks = false) {
|
|
|
3418
3487
|
repair_command: repairCommand
|
|
3419
3488
|
};
|
|
3420
3489
|
}
|
|
3421
|
-
|
|
3490
|
+
const corroborated = warning.reasons.includes("anchor") || warning.distinctive_literal === true;
|
|
3491
|
+
const semanticReviewFloor = corroborated ? 0.45 : 0.6;
|
|
3492
|
+
if (hasSemantic && semanticScore >= semanticReviewFloor || highConfidence && warning.reasons.includes("anchor") && warning.reasons.includes("literal")) {
|
|
3422
3493
|
return {
|
|
3423
3494
|
...warning,
|
|
3424
3495
|
level: "review",
|
|
@@ -3551,7 +3622,7 @@ function repairTargetPathForWarning(warning, paths) {
|
|
|
3551
3622
|
}
|
|
3552
3623
|
|
|
3553
3624
|
// src/tools/pattern-detect.ts
|
|
3554
|
-
import { mkdir as mkdir8, writeFile as
|
|
3625
|
+
import { mkdir as mkdir8, writeFile as writeFile14 } from "fs/promises";
|
|
3555
3626
|
import { existsSync as existsSync29 } from "fs";
|
|
3556
3627
|
import path12 from "path";
|
|
3557
3628
|
import { execSync as execSync2 } from "child_process";
|
|
@@ -3559,7 +3630,7 @@ import {
|
|
|
3559
3630
|
buildFrontmatter as buildFrontmatter5,
|
|
3560
3631
|
memoryFilePath as memoryFilePath6,
|
|
3561
3632
|
readUsageEvents,
|
|
3562
|
-
serializeMemory as
|
|
3633
|
+
serializeMemory as serializeMemory12
|
|
3563
3634
|
} from "@hiveai/core";
|
|
3564
3635
|
import { z as z31 } from "zod";
|
|
3565
3636
|
var CONFIG_PATTERNS = [
|
|
@@ -3720,9 +3791,9 @@ async function patternDetect(input, ctx) {
|
|
|
3720
3791
|
);
|
|
3721
3792
|
if (existsSync29(file)) continue;
|
|
3722
3793
|
await mkdir8(path12.dirname(file), { recursive: true });
|
|
3723
|
-
await
|
|
3794
|
+
await writeFile14(
|
|
3724
3795
|
file,
|
|
3725
|
-
|
|
3796
|
+
serializeMemory12({ frontmatter: fm, body: match.proposed_body }),
|
|
3726
3797
|
"utf8"
|
|
3727
3798
|
);
|
|
3728
3799
|
savedIds.push(fm.id);
|
|
@@ -4148,7 +4219,7 @@ When done, respond with: "Imported N memories: [list of IDs]" or "Nothing action
|
|
|
4148
4219
|
// src/server.ts
|
|
4149
4220
|
import { hasRecentBriefingMarker, loadConfigSync } from "@hiveai/core";
|
|
4150
4221
|
var SERVER_NAME = "haive";
|
|
4151
|
-
var SERVER_VERSION = "0.
|
|
4222
|
+
var SERVER_VERSION = "0.18.0";
|
|
4152
4223
|
function jsonResult(data) {
|
|
4153
4224
|
return {
|
|
4154
4225
|
content: [
|