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