@hivelore/mcp 0.43.2 → 0.46.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/README.md +1 -1
- package/dist/index.js +72 -13
- package/dist/index.js.map +1 -1
- package/dist/server.d.ts +4 -1
- package/dist/server.js +74 -14
- package/dist/server.js.map +1 -1
- package/package.json +16 -3
package/dist/server.d.ts
CHANGED
|
@@ -365,6 +365,7 @@ interface AntiPatternsCheckInput {
|
|
|
365
365
|
limit: number;
|
|
366
366
|
semantic: boolean;
|
|
367
367
|
min_semantic_score?: number;
|
|
368
|
+
track?: boolean;
|
|
368
369
|
}
|
|
369
370
|
interface AntiPatternsWarning {
|
|
370
371
|
id: string;
|
|
@@ -694,6 +695,7 @@ declare const ScaffoldTestInputSchema: {
|
|
|
694
695
|
memory_id: z.ZodString;
|
|
695
696
|
framework: z.ZodOptional<z.ZodEnum<["vitest", "jest", "pytest", "gotest"]>>;
|
|
696
697
|
out_path: z.ZodOptional<z.ZodString>;
|
|
698
|
+
red_ref: z.ZodOptional<z.ZodString>;
|
|
697
699
|
write: z.ZodDefault<z.ZodBoolean>;
|
|
698
700
|
};
|
|
699
701
|
type ScaffoldTestInput = {
|
|
@@ -834,5 +836,6 @@ declare function printHaiveMcpVersion(): void;
|
|
|
834
836
|
declare function runHaiveMcpStdio(options: {
|
|
835
837
|
root?: string;
|
|
836
838
|
}): Promise<void>;
|
|
839
|
+
declare function writeMcpRuntimeMarker(context: HaiveContext): Promise<void>;
|
|
837
840
|
|
|
838
|
-
export { type AnchorFrameworkGroup, type AntiPatternsCheckInput, type AntiPatternsCheckOutput, type AstMatch, type AstScanResult, type BriefingOutput, type CodeMapInput, type CodeMapToolOutput, type CodeSearchInput, type CodeSearchOutput, ENFORCEMENT_PROFILE_TOOLS, EXPERIMENTAL_PROFILE_TOOLS, type GetBriefingInput, type GetRecapInput, type GetRecapOutput, MAINTENANCE_PROFILE_TOOLS, type MemConflictCandidatesInput, type MemDistillInput, type MemDistillOutput, type MemRelevantToInput, type MemRelevantToOutput, type MemResolveProjectInput, type MemSuggestTopicInput, type MemTimelineInput, type MemTriedOutput, type PreCommitCheckInput, type PreCommitCheckOutput, type ProposeSensorOutput, SERVER_NAME, SERVER_VERSION, type ScaffoldTestOutput, TOOL_PROFILES, type ToolProfile, antiPatternsCheck, astEngineAvailable, astLangForPath, codeMapTool, codeSearch, createHaiveServer, detectTestFrameworkForPaths, detectTestFrameworksForAnchors, getAllowedToolsForProfile, getBriefing, getRecap, memConflictCandidates, memDistill, memRelevantTo, memResolveProject, memSuggestTopic, memTimeline, memTried, parseMcpCliArgs, preCommitCheck, printHaiveMcpVersion, proposeSensor, readPresumedCorrectTargets, runAstPattern, runAstSensorOnContent, runHaiveMcpStdio, scaffoldTest };
|
|
841
|
+
export { type AnchorFrameworkGroup, type AntiPatternsCheckInput, type AntiPatternsCheckOutput, type AstMatch, type AstScanResult, type BriefingOutput, type CodeMapInput, type CodeMapToolOutput, type CodeSearchInput, type CodeSearchOutput, ENFORCEMENT_PROFILE_TOOLS, EXPERIMENTAL_PROFILE_TOOLS, type GetBriefingInput, type GetRecapInput, type GetRecapOutput, MAINTENANCE_PROFILE_TOOLS, type MemConflictCandidatesInput, type MemDistillInput, type MemDistillOutput, type MemRelevantToInput, type MemRelevantToOutput, type MemResolveProjectInput, type MemSuggestTopicInput, type MemTimelineInput, type MemTriedOutput, type PreCommitCheckInput, type PreCommitCheckOutput, type ProposeSensorOutput, SERVER_NAME, SERVER_VERSION, type ScaffoldTestOutput, TOOL_PROFILES, type ToolProfile, antiPatternsCheck, astEngineAvailable, astLangForPath, codeMapTool, codeSearch, createHaiveServer, detectTestFrameworkForPaths, detectTestFrameworksForAnchors, getAllowedToolsForProfile, getBriefing, getRecap, memConflictCandidates, memDistill, memRelevantTo, memResolveProject, memSuggestTopic, memTimeline, memTried, parseMcpCliArgs, preCommitCheck, printHaiveMcpVersion, proposeSensor, readPresumedCorrectTargets, runAstPattern, runAstSensorOnContent, runHaiveMcpStdio, scaffoldTest, writeMcpRuntimeMarker };
|
package/dist/server.js
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
// src/server.ts
|
|
2
2
|
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
3
3
|
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
|
|
4
|
+
import { mkdir as mkdir8, writeFile as writeFile15 } from "fs/promises";
|
|
5
|
+
import path15 from "path";
|
|
4
6
|
|
|
5
7
|
// src/context.ts
|
|
6
8
|
import { findProjectRoot, resolveHaivePaths } from "@hivelore/core";
|
|
@@ -1791,15 +1793,24 @@ async function memTried(input, ctx) {
|
|
|
1791
1793
|
import { existsSync as existsSync17, statSync } from "fs";
|
|
1792
1794
|
import { mkdir as mkdir4, readFile as readFile4, writeFile as writeFile10 } from "fs/promises";
|
|
1793
1795
|
import path8 from "path";
|
|
1796
|
+
import { execFile } from "child_process";
|
|
1797
|
+
import { promisify } from "util";
|
|
1794
1798
|
import { z as z17 } from "zod";
|
|
1795
1799
|
import {
|
|
1796
1800
|
buildProposeCommand,
|
|
1801
|
+
incidentHintsFromDiff,
|
|
1797
1802
|
loadMemoriesFromDir as loadMemoriesFromDir14,
|
|
1798
1803
|
normalizeFramework,
|
|
1799
1804
|
parseLessonFields,
|
|
1800
1805
|
pickTestFramework,
|
|
1801
1806
|
scaffoldPostIncidentTest
|
|
1802
1807
|
} from "@hivelore/core";
|
|
1808
|
+
var execFileAsync = promisify(execFile);
|
|
1809
|
+
async function gitDiffText(root, redRef, paths) {
|
|
1810
|
+
const args = ["diff", redRef, "HEAD", "--", ...paths];
|
|
1811
|
+
const { stdout } = await execFileAsync("git", args, { cwd: root, maxBuffer: 64 * 1024 * 1024 });
|
|
1812
|
+
return stdout;
|
|
1813
|
+
}
|
|
1803
1814
|
var PY_SIGNALS = ["pyproject.toml", "setup.py", "pytest.ini", "requirements.txt", "tox.ini"];
|
|
1804
1815
|
async function detectForAnchor(root, rel) {
|
|
1805
1816
|
let dir = path8.resolve(root, rel);
|
|
@@ -1854,6 +1865,9 @@ var ScaffoldTestInputSchema = {
|
|
|
1854
1865
|
memory_id: z17.string().min(1).describe("Id of the attempt/gotcha lesson to scaffold a post-incident test from."),
|
|
1855
1866
|
framework: z17.enum(["vitest", "jest", "pytest", "gotest"]).optional().describe("Test framework. Auto-detected from the package that owns the lesson's anchor paths when omitted."),
|
|
1856
1867
|
out_path: z17.string().optional().describe("Override the generated test file path (repo-relative)."),
|
|
1868
|
+
red_ref: z17.string().optional().describe(
|
|
1869
|
+
"Pre-fix incident commit/ref. When set, the scaffold names the symbols the fix (<red_ref>..HEAD) touched within the lesson's anchor scope and pre-fills the example around them, so the assertion is a targeted edit rather than a blank page. A bad ref falls back to the generic template."
|
|
1870
|
+
),
|
|
1857
1871
|
write: z17.boolean().default(true).describe("Write the file to disk (default). false = return the content for preview without writing.")
|
|
1858
1872
|
};
|
|
1859
1873
|
async function scaffoldTest(input, ctx) {
|
|
@@ -1867,13 +1881,23 @@ async function scaffoldTest(input, ctx) {
|
|
|
1867
1881
|
const groups = input.out_path ? allGroups.slice(0, 1) : allGroups;
|
|
1868
1882
|
const frameworkFor = (detected) => input.framework ? normalizeFramework(input.framework) ?? detected : detected;
|
|
1869
1883
|
const fields = parseLessonFields(found.memory.body);
|
|
1884
|
+
let incidentHints;
|
|
1885
|
+
if (input.red_ref) {
|
|
1886
|
+
try {
|
|
1887
|
+
const diff = await gitDiffText(ctx.paths.root, input.red_ref, anchorPaths);
|
|
1888
|
+
const hints = incidentHintsFromDiff(diff, { redRef: input.red_ref });
|
|
1889
|
+
if (hints.changedSymbols.length > 0 || hints.changedFiles.length > 0) incidentHints = hints;
|
|
1890
|
+
} catch {
|
|
1891
|
+
}
|
|
1892
|
+
}
|
|
1870
1893
|
const lesson = {
|
|
1871
1894
|
memoryId: input.memory_id,
|
|
1872
1895
|
title: fields.title || input.memory_id,
|
|
1873
1896
|
whyFailed: fields.whyFailed,
|
|
1874
1897
|
instead: fields.instead,
|
|
1875
1898
|
incident: found.memory.frontmatter.sensor?.incident,
|
|
1876
|
-
paths: anchorPaths
|
|
1899
|
+
paths: anchorPaths,
|
|
1900
|
+
incidentHints
|
|
1877
1901
|
};
|
|
1878
1902
|
let scaffolds = groups.map(
|
|
1879
1903
|
(g) => scaffoldPostIncidentTest(lesson, { framework: frameworkFor(g.framework), outPath: input.out_path, baseDir: g.baseDir })
|
|
@@ -3197,7 +3221,7 @@ function oneLine(value) {
|
|
|
3197
3221
|
return value.replace(/\s+/g, " ").replace(/"/g, '\\"').trim().slice(0, 120);
|
|
3198
3222
|
}
|
|
3199
3223
|
function serverVersion() {
|
|
3200
|
-
return true ? "0.
|
|
3224
|
+
return true ? "0.46.0" : "dev";
|
|
3201
3225
|
}
|
|
3202
3226
|
|
|
3203
3227
|
// src/tools/code-map.ts
|
|
@@ -3483,7 +3507,8 @@ var AntiPatternsCheckInputSchema = {
|
|
|
3483
3507
|
),
|
|
3484
3508
|
min_semantic_score: z26.number().min(0).max(1).default(0.45).describe(
|
|
3485
3509
|
"Minimum cosine score for semantic-only anti-pattern hits. Anchor/literal matches still surface. Default 0.45 keeps broad, weakly-related memories out of review noise."
|
|
3486
|
-
)
|
|
3510
|
+
),
|
|
3511
|
+
track: z26.boolean().default(true).describe("Record real prevention outcomes. Set false for eval/selftest probes so synthetic cases never inflate ROI.")
|
|
3487
3512
|
};
|
|
3488
3513
|
function tokenizeDiffForLiteral(diff) {
|
|
3489
3514
|
const lines = diff.split("\n");
|
|
@@ -3511,6 +3536,7 @@ function isHaiveOwnedPath(p) {
|
|
|
3511
3536
|
if (/^\.github\/workflows\/haive-.*\.ya?ml$/.test(p)) return true;
|
|
3512
3537
|
return false;
|
|
3513
3538
|
}
|
|
3539
|
+
var MAX_FUZZY_SCAN_LINES = 2e4;
|
|
3514
3540
|
var TEST_PATH_RE = /(?:^|\/)(?:tests?|__tests__|__mocks__|e2e|fixtures)\/|\.(?:test|spec)\.[cm]?[jt]sx?$/i;
|
|
3515
3541
|
function isTestPath(p) {
|
|
3516
3542
|
return TEST_PATH_RE.test(p);
|
|
@@ -3521,7 +3547,7 @@ function stripTestHunks(diff) {
|
|
|
3521
3547
|
let block = [];
|
|
3522
3548
|
let keep = true;
|
|
3523
3549
|
const flush = () => {
|
|
3524
|
-
if (keep) out.push(
|
|
3550
|
+
if (keep) for (const l of block) out.push(l);
|
|
3525
3551
|
block = [];
|
|
3526
3552
|
keep = true;
|
|
3527
3553
|
};
|
|
@@ -3542,7 +3568,7 @@ function stripAiDirHunks(diff) {
|
|
|
3542
3568
|
let block = [];
|
|
3543
3569
|
let keep = true;
|
|
3544
3570
|
const flush = () => {
|
|
3545
|
-
if (keep) out.push(
|
|
3571
|
+
if (keep) for (const l of block) out.push(l);
|
|
3546
3572
|
block = [];
|
|
3547
3573
|
keep = true;
|
|
3548
3574
|
};
|
|
@@ -3613,7 +3639,10 @@ async function antiPatternsCheck(input, ctx) {
|
|
|
3613
3639
|
}
|
|
3614
3640
|
}
|
|
3615
3641
|
const scanDiff = input.diff ? stripTestHunks(stripAiDirHunks(input.diff)) : input.diff;
|
|
3616
|
-
|
|
3642
|
+
const scanAddedLineCount = scanDiff ? addedLinesFromDiff(scanDiff).split("\n").length : 0;
|
|
3643
|
+
const fuzzyScanTooLarge = scanAddedLineCount > MAX_FUZZY_SCAN_LINES;
|
|
3644
|
+
const notice = fuzzyScanTooLarge ? `Diff is very large (${scanAddedLineCount.toLocaleString()} added lines) \u2014 literal/semantic corroboration skipped for performance; anchored lessons and deterministic sensors were still evaluated in full. If this staged node_modules or a build artifact, unstage it.` : void 0;
|
|
3645
|
+
if (scanDiff && !fuzzyScanTooLarge) {
|
|
3617
3646
|
const tokens = tokenizeDiffForLiteral(scanDiff);
|
|
3618
3647
|
const added = addedLinesFromDiff(scanDiff);
|
|
3619
3648
|
const addedText = added.trim().length > 0 ? added : scanDiff;
|
|
@@ -3648,7 +3677,7 @@ async function antiPatternsCheck(input, ctx) {
|
|
|
3648
3677
|
}
|
|
3649
3678
|
}
|
|
3650
3679
|
}
|
|
3651
|
-
if (input.semantic && scanDiff) {
|
|
3680
|
+
if (input.semantic && scanDiff && !fuzzyScanTooLarge) {
|
|
3652
3681
|
try {
|
|
3653
3682
|
const mod = await import("@hivelore/embeddings");
|
|
3654
3683
|
const added = addedLinesFromDiff(scanDiff);
|
|
@@ -3676,10 +3705,13 @@ async function antiPatternsCheck(input, ctx) {
|
|
|
3676
3705
|
}).slice(0, input.limit);
|
|
3677
3706
|
const isHardBlockCatch = (w) => w.reasons.includes("sensor");
|
|
3678
3707
|
const strongCatches = warnings.filter(isHardBlockCatch);
|
|
3679
|
-
|
|
3708
|
+
if (input.track !== false) {
|
|
3709
|
+
await recordPreventionHits(ctx.paths, strongCatches.map((w) => w.id), "anti-pattern");
|
|
3710
|
+
}
|
|
3680
3711
|
return {
|
|
3681
3712
|
scanned: negative.length,
|
|
3682
|
-
warnings
|
|
3713
|
+
warnings,
|
|
3714
|
+
...notice ? { notice } : {}
|
|
3683
3715
|
};
|
|
3684
3716
|
}
|
|
3685
3717
|
|
|
@@ -3907,6 +3939,7 @@ async function preCommitCheck(input, ctx) {
|
|
|
3907
3939
|
relevant_memories: relevant_memories.length,
|
|
3908
3940
|
stale_anchors: staleHits.length
|
|
3909
3941
|
},
|
|
3942
|
+
...apResult.notice ? { notice: apResult.notice } : {},
|
|
3910
3943
|
warnings: classifiedWarnings,
|
|
3911
3944
|
relevant_memories,
|
|
3912
3945
|
stale_anchors: staleHits.map((r) => {
|
|
@@ -4458,13 +4491,14 @@ Main code areas detected: ${areas}
|
|
|
4458
4491
|
import { z as z35 } from "zod";
|
|
4459
4492
|
var PostTaskArgsSchema = {
|
|
4460
4493
|
task_summary: z35.string().optional().describe("One sentence describing what you just did"),
|
|
4461
|
-
files_touched: z35.
|
|
4494
|
+
files_touched: z35.string().optional().describe("Files you created or modified during the task, as CSV or a JSON array string")
|
|
4462
4495
|
};
|
|
4463
4496
|
function postTaskPrompt(args, ctx) {
|
|
4464
4497
|
const taskLine = args.task_summary ? `
|
|
4465
4498
|
Task just completed: **${args.task_summary}**` : "";
|
|
4466
|
-
const
|
|
4467
|
-
|
|
4499
|
+
const filesTouched = parsePromptFilesTouched(args.files_touched);
|
|
4500
|
+
const filesLine = filesTouched.length > 0 ? `
|
|
4501
|
+
Files touched: ${filesTouched.map((f) => `\`${f}\``).join(", ")}` : "";
|
|
4468
4502
|
const text = `You have just finished a task. Before closing this session, take 60 seconds to capture what you learned.
|
|
4469
4503
|
${taskLine}${filesLine}
|
|
4470
4504
|
|
|
@@ -4553,6 +4587,20 @@ When done, respond with a brief summary: "Saved N memories: [list of IDs]. Sessi
|
|
|
4553
4587
|
]
|
|
4554
4588
|
};
|
|
4555
4589
|
}
|
|
4590
|
+
function parsePromptFilesTouched(input) {
|
|
4591
|
+
const raw = input?.trim();
|
|
4592
|
+
if (!raw) return [];
|
|
4593
|
+
if (raw.startsWith("[")) {
|
|
4594
|
+
try {
|
|
4595
|
+
const parsed = JSON.parse(raw);
|
|
4596
|
+
if (Array.isArray(parsed)) {
|
|
4597
|
+
return parsed.filter((value) => typeof value === "string").map((value) => value.trim()).filter(Boolean);
|
|
4598
|
+
}
|
|
4599
|
+
} catch {
|
|
4600
|
+
}
|
|
4601
|
+
}
|
|
4602
|
+
return raw.split(",").map((value) => value.trim()).filter(Boolean);
|
|
4603
|
+
}
|
|
4556
4604
|
|
|
4557
4605
|
// src/prompts/import-docs.ts
|
|
4558
4606
|
import { z as z36 } from "zod";
|
|
@@ -4626,7 +4674,7 @@ When done, respond with: "Imported N memories: [list of IDs]" or "Nothing action
|
|
|
4626
4674
|
// src/server.ts
|
|
4627
4675
|
import { hasRecentBriefingMarker, loadConfigSync } from "@hivelore/core";
|
|
4628
4676
|
var SERVER_NAME = "hivelore";
|
|
4629
|
-
var SERVER_VERSION = "0.
|
|
4677
|
+
var SERVER_VERSION = "0.46.0";
|
|
4630
4678
|
function jsonResult(data) {
|
|
4631
4679
|
return {
|
|
4632
4680
|
content: [
|
|
@@ -5565,11 +5613,22 @@ function printHaiveMcpVersion() {
|
|
|
5565
5613
|
}
|
|
5566
5614
|
async function runHaiveMcpStdio(options) {
|
|
5567
5615
|
const { server, context } = createHaiveServer({ root: options.root, env: process.env });
|
|
5616
|
+
await writeMcpRuntimeMarker(context).catch(() => {
|
|
5617
|
+
});
|
|
5568
5618
|
console.error(
|
|
5569
5619
|
`[haive-mcp] starting server v${SERVER_VERSION} (project root: ${context.paths.root})`
|
|
5570
5620
|
);
|
|
5571
5621
|
await server.connect(new StdioServerTransport());
|
|
5572
5622
|
}
|
|
5623
|
+
async function writeMcpRuntimeMarker(context) {
|
|
5624
|
+
await mkdir8(context.paths.runtimeDir, { recursive: true });
|
|
5625
|
+
await writeFile15(path15.join(context.paths.runtimeDir, "mcp-server.json"), JSON.stringify({
|
|
5626
|
+
version: SERVER_VERSION,
|
|
5627
|
+
pid: process.pid,
|
|
5628
|
+
started_at: (/* @__PURE__ */ new Date()).toISOString(),
|
|
5629
|
+
command: "hivelore mcp --stdio"
|
|
5630
|
+
}, null, 2), "utf8");
|
|
5631
|
+
}
|
|
5573
5632
|
export {
|
|
5574
5633
|
ENFORCEMENT_PROFILE_TOOLS,
|
|
5575
5634
|
EXPERIMENTAL_PROFILE_TOOLS,
|
|
@@ -5603,6 +5662,7 @@ export {
|
|
|
5603
5662
|
runAstPattern,
|
|
5604
5663
|
runAstSensorOnContent,
|
|
5605
5664
|
runHaiveMcpStdio,
|
|
5606
|
-
scaffoldTest
|
|
5665
|
+
scaffoldTest,
|
|
5666
|
+
writeMcpRuntimeMarker
|
|
5607
5667
|
};
|
|
5608
5668
|
//# sourceMappingURL=server.js.map
|