@hiveai/mcp 0.9.3 → 0.9.6
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 +288 -17
- package/dist/index.js.map +1 -1
- package/dist/server.d.ts +85 -2
- package/dist/server.js +294 -17
- package/dist/server.js.map +1 -1
- package/package.json +3 -3
package/dist/server.d.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
|
|
2
|
-
import
|
|
2
|
+
import * as _hiveai_core from '@hiveai/core';
|
|
3
|
+
import { HaivePaths, ConfidenceLevel, resolveProjectInfo, readRuntimeJournalTail } from '@hiveai/core';
|
|
3
4
|
import { z } from 'zod';
|
|
4
5
|
|
|
5
6
|
interface HaiveContext {
|
|
@@ -565,6 +566,88 @@ interface PatternDetectOutput {
|
|
|
565
566
|
}
|
|
566
567
|
declare function patternDetect(input: PatternDetectInput, ctx: HaiveContext): Promise<PatternDetectOutput>;
|
|
567
568
|
|
|
569
|
+
/** Input is intentionally minimal — callers may pass cwd for multi-root clients. */
|
|
570
|
+
declare const MemResolveProjectInputSchema: {
|
|
571
|
+
cwd: z.ZodOptional<z.ZodString>;
|
|
572
|
+
};
|
|
573
|
+
type MemResolveProjectInput = {
|
|
574
|
+
[K in keyof typeof MemResolveProjectInputSchema]: z.infer<(typeof MemResolveProjectInputSchema)[K]>;
|
|
575
|
+
};
|
|
576
|
+
declare function memResolveProject(input: MemResolveProjectInput, _ctx: HaiveContext): Promise<{
|
|
577
|
+
info: ReturnType<typeof resolveProjectInfo>;
|
|
578
|
+
ok: true;
|
|
579
|
+
}>;
|
|
580
|
+
|
|
581
|
+
declare const MemSuggestTopicInputSchema: {
|
|
582
|
+
type: z.ZodEnum<["convention", "decision", "gotcha", "architecture", "glossary", "attempt", "session_recap"]>;
|
|
583
|
+
title: z.ZodString;
|
|
584
|
+
};
|
|
585
|
+
type MemSuggestTopicInput = {
|
|
586
|
+
[K in keyof typeof MemSuggestTopicInputSchema]: z.infer<(typeof MemSuggestTopicInputSchema)[K]>;
|
|
587
|
+
};
|
|
588
|
+
declare function memSuggestTopic(input: MemSuggestTopicInput, _ctx: HaiveContext): Promise<{
|
|
589
|
+
topic_key: string;
|
|
590
|
+
family: string;
|
|
591
|
+
type: string;
|
|
592
|
+
}>;
|
|
593
|
+
|
|
594
|
+
declare const MemTimelineInputSchema: {
|
|
595
|
+
memory_id: z.ZodOptional<z.ZodString>;
|
|
596
|
+
topic: z.ZodOptional<z.ZodString>;
|
|
597
|
+
limit: z.ZodDefault<z.ZodNumber>;
|
|
598
|
+
};
|
|
599
|
+
type MemTimelineInput = {
|
|
600
|
+
[K in keyof typeof MemTimelineInputSchema]: z.infer<(typeof MemTimelineInputSchema)[K]>;
|
|
601
|
+
};
|
|
602
|
+
declare function memTimeline(input: MemTimelineInput, ctx: HaiveContext): Promise<{
|
|
603
|
+
entries: _hiveai_core.TimelineEntry[];
|
|
604
|
+
total: number;
|
|
605
|
+
notice: string | undefined;
|
|
606
|
+
}>;
|
|
607
|
+
|
|
608
|
+
declare const MemConflictCandidatesInputSchema: {
|
|
609
|
+
since_days: z.ZodDefault<z.ZodNumber>;
|
|
610
|
+
types: z.ZodDefault<z.ZodArray<z.ZodEnum<["decision", "architecture", "convention", "gotcha"]>, "many">>;
|
|
611
|
+
min_jaccard: z.ZodDefault<z.ZodNumber>;
|
|
612
|
+
max_pairs: z.ZodDefault<z.ZodNumber>;
|
|
613
|
+
max_scan: z.ZodDefault<z.ZodNumber>;
|
|
614
|
+
max_topic_pairs: z.ZodDefault<z.ZodNumber>;
|
|
615
|
+
};
|
|
616
|
+
type MemConflictCandidatesInput = {
|
|
617
|
+
[K in keyof typeof MemConflictCandidatesInputSchema]: z.infer<(typeof MemConflictCandidatesInputSchema)[K]>;
|
|
618
|
+
};
|
|
619
|
+
declare function memConflictCandidates(input: MemConflictCandidatesInput, ctx: HaiveContext): Promise<{
|
|
620
|
+
pairs: _hiveai_core.ConflictCandidatePair[];
|
|
621
|
+
topic_status_pairs: _hiveai_core.TopicStatusPair[];
|
|
622
|
+
scanned: number;
|
|
623
|
+
truncated: boolean;
|
|
624
|
+
notice: string | undefined;
|
|
625
|
+
}>;
|
|
626
|
+
|
|
627
|
+
declare const RuntimeJournalAppendInputSchema: {
|
|
628
|
+
message: z.ZodString;
|
|
629
|
+
kind: z.ZodDefault<z.ZodEnum<["note", "session_end", "mcp"]>>;
|
|
630
|
+
tool: z.ZodOptional<z.ZodString>;
|
|
631
|
+
};
|
|
632
|
+
type RuntimeJournalAppendInput = {
|
|
633
|
+
[K in keyof typeof RuntimeJournalAppendInputSchema]: z.infer<(typeof RuntimeJournalAppendInputSchema)[K]>;
|
|
634
|
+
};
|
|
635
|
+
declare function runtimeJournalAppend(input: RuntimeJournalAppendInput, ctx: HaiveContext): Promise<{
|
|
636
|
+
ok: true;
|
|
637
|
+
path_hint: string;
|
|
638
|
+
}>;
|
|
639
|
+
|
|
640
|
+
declare const RuntimeJournalTailInputSchema: {
|
|
641
|
+
limit: z.ZodDefault<z.ZodNumber>;
|
|
642
|
+
};
|
|
643
|
+
type RuntimeJournalTailInput = {
|
|
644
|
+
[K in keyof typeof RuntimeJournalTailInputSchema]: z.infer<(typeof RuntimeJournalTailInputSchema)[K]>;
|
|
645
|
+
};
|
|
646
|
+
declare function runtimeJournalTail(input: RuntimeJournalTailInput, ctx: HaiveContext): Promise<{
|
|
647
|
+
entries: Awaited<ReturnType<typeof readRuntimeJournalTail>>;
|
|
648
|
+
empty?: boolean;
|
|
649
|
+
}>;
|
|
650
|
+
|
|
568
651
|
declare const SERVER_NAME = "haive";
|
|
569
652
|
declare const SERVER_VERSION: string;
|
|
570
653
|
declare function createHaiveServer(options?: CreateContextOptions): {
|
|
@@ -587,4 +670,4 @@ declare function runHaiveMcpStdio(options: {
|
|
|
587
670
|
root?: string;
|
|
588
671
|
}): Promise<void>;
|
|
589
672
|
|
|
590
|
-
export { type AntiPatternsCheckInput, type AntiPatternsCheckOutput, type BriefingOutput, type CodeMapInput, type CodeMapToolOutput, type CodeSearchInput, type CodeSearchOutput, type GetBriefingInput, type GetRecapInput, type GetRecapOutput, type MemConflictsInput, type MemConflictsOutput, type MemDistillInput, type MemDistillOutput, type MemRelevantToInput, type MemRelevantToOutput, type PatternDetectInput, type PatternDetectOutput, type PreCommitCheckInput, type PreCommitCheckOutput, SERVER_NAME, SERVER_VERSION, type WhyThisDecisionInput, type WhyThisDecisionOutput, type WhyThisFileInput, type WhyThisFileOutput, antiPatternsCheck, codeMapTool, codeSearch, createHaiveServer, getBriefing, getRecap, memConflicts, memDistill, memRelevantTo, parseMcpCliArgs, patternDetect, preCommitCheck, printHaiveMcpVersion, runHaiveMcpStdio, whyThisDecision, whyThisFile };
|
|
673
|
+
export { type AntiPatternsCheckInput, type AntiPatternsCheckOutput, type BriefingOutput, type CodeMapInput, type CodeMapToolOutput, type CodeSearchInput, type CodeSearchOutput, type GetBriefingInput, type GetRecapInput, type GetRecapOutput, type MemConflictCandidatesInput, type MemConflictsInput, type MemConflictsOutput, type MemDistillInput, type MemDistillOutput, type MemRelevantToInput, type MemRelevantToOutput, type MemResolveProjectInput, type MemSuggestTopicInput, type MemTimelineInput, type PatternDetectInput, type PatternDetectOutput, type PreCommitCheckInput, type PreCommitCheckOutput, type RuntimeJournalAppendInput, type RuntimeJournalTailInput, SERVER_NAME, SERVER_VERSION, type WhyThisDecisionInput, type WhyThisDecisionOutput, type WhyThisFileInput, type WhyThisFileOutput, antiPatternsCheck, codeMapTool, codeSearch, createHaiveServer, getBriefing, getRecap, memConflictCandidates, memConflicts, memDistill, memRelevantTo, memResolveProject, memSuggestTopic, memTimeline, parseMcpCliArgs, patternDetect, preCommitCheck, printHaiveMcpVersion, runHaiveMcpStdio, runtimeJournalAppend, runtimeJournalTail, whyThisDecision, whyThisFile };
|
package/dist/server.js
CHANGED
|
@@ -319,6 +319,7 @@ import {
|
|
|
319
319
|
loadMemoriesFromDir as loadMemoriesFromDir3,
|
|
320
320
|
loadUsageIndex,
|
|
321
321
|
pickSnippetNeedle,
|
|
322
|
+
rankMemoriesLexical,
|
|
322
323
|
tokenizeQuery,
|
|
323
324
|
trackReads
|
|
324
325
|
} from "@hiveai/core";
|
|
@@ -335,6 +336,9 @@ var MemSearchInputSchema = {
|
|
|
335
336
|
semantic: z5.boolean().default(false).describe(
|
|
336
337
|
"Use semantic similarity from the embeddings index (requires `haive embeddings index`)."
|
|
337
338
|
),
|
|
339
|
+
lexical_rank: z5.boolean().default(false).describe(
|
|
340
|
+
"When true (and semantic is false), rank the filtered corpus with Okapi-BM25-style lexical scoring instead of literal AND/OR. Helps phrase-like queries without embeddings."
|
|
341
|
+
),
|
|
338
342
|
min_score: z5.number().min(0).max(1).default(0).describe("Minimum cosine similarity (semantic mode only)"),
|
|
339
343
|
track: z5.boolean().default(true).describe("Increment read_count on returned memories (used for passive validation)")
|
|
340
344
|
};
|
|
@@ -360,6 +364,27 @@ async function memSearch(input, ctx) {
|
|
|
360
364
|
notice: "Semantic search unavailable (embeddings index missing or @hiveai/embeddings not installed). Falling back to literal search."
|
|
361
365
|
};
|
|
362
366
|
}
|
|
367
|
+
} else if (input.lexical_rank && input.query.trim()) {
|
|
368
|
+
const { ranked, scores } = rankMemoriesLexical(
|
|
369
|
+
filtered,
|
|
370
|
+
input.query,
|
|
371
|
+
input.limit
|
|
372
|
+
);
|
|
373
|
+
if (ranked.length > 0) {
|
|
374
|
+
const snippetNeedle = pickSnippetNeedle(input.query);
|
|
375
|
+
result = {
|
|
376
|
+
matches: ranked.map(
|
|
377
|
+
(loaded, i) => lexicalHit(loaded, snippetNeedle, usage, scores[i])
|
|
378
|
+
),
|
|
379
|
+
total: ranked.length,
|
|
380
|
+
mode: "lexical_ranked"
|
|
381
|
+
};
|
|
382
|
+
} else {
|
|
383
|
+
result = {
|
|
384
|
+
...buildLiteralResult(input, filtered, usage),
|
|
385
|
+
notice: "Lexical ranking found no BM25-positive hits \u2014 showing literal matches instead."
|
|
386
|
+
};
|
|
387
|
+
}
|
|
363
388
|
} else {
|
|
364
389
|
result = buildLiteralResult(input, filtered, usage);
|
|
365
390
|
}
|
|
@@ -457,6 +482,9 @@ function toHit(loaded, needle, usage) {
|
|
|
457
482
|
file_path: loaded.filePath
|
|
458
483
|
};
|
|
459
484
|
}
|
|
485
|
+
function lexicalHit(loaded, needle, usage, lexicalScore) {
|
|
486
|
+
return { ...toHit(loaded, needle, usage), score: lexicalScore };
|
|
487
|
+
}
|
|
460
488
|
|
|
461
489
|
// src/tools/mem-verify.ts
|
|
462
490
|
import { writeFile as writeFile3 } from "fs/promises";
|
|
@@ -1097,7 +1125,11 @@ import {
|
|
|
1097
1125
|
import { z as z16 } from "zod";
|
|
1098
1126
|
|
|
1099
1127
|
// src/session-tracker.ts
|
|
1100
|
-
import {
|
|
1128
|
+
import {
|
|
1129
|
+
appendUsageEvent,
|
|
1130
|
+
appendRuntimeJournalEntry,
|
|
1131
|
+
loadConfig as loadConfig2
|
|
1132
|
+
} from "@hiveai/core";
|
|
1101
1133
|
import { mkdir as mkdir5, writeFile as writeFile9, rm } from "fs/promises";
|
|
1102
1134
|
import { existsSync as existsSync16 } from "fs";
|
|
1103
1135
|
import path7 from "path";
|
|
@@ -1170,6 +1202,14 @@ var SessionTracker = class {
|
|
|
1170
1202
|
recapId = result.id;
|
|
1171
1203
|
} catch {
|
|
1172
1204
|
}
|
|
1205
|
+
void appendRuntimeJournalEntry(this.ctx.paths, {
|
|
1206
|
+
kind: "session_end",
|
|
1207
|
+
message: recapId ? `auto session close | ${toolSummary} | recap:${recapId}` : `auto session close | ${toolSummary}`,
|
|
1208
|
+
meta: {
|
|
1209
|
+
recap_id: recapId ?? null,
|
|
1210
|
+
total_tool_calls: totalCalls
|
|
1211
|
+
}
|
|
1212
|
+
});
|
|
1173
1213
|
const ranPostTask = this.events.some(
|
|
1174
1214
|
(e) => e.tool === "mem_session_end" && !e.summary?.startsWith("Auto-captured")
|
|
1175
1215
|
);
|
|
@@ -3038,13 +3078,139 @@ function gitFileDiff(root, file, sinceDays) {
|
|
|
3038
3078
|
}
|
|
3039
3079
|
}
|
|
3040
3080
|
|
|
3041
|
-
// src/
|
|
3081
|
+
// src/tools/mem-conflict-candidates.ts
|
|
3082
|
+
import { existsSync as existsSync27 } from "fs";
|
|
3083
|
+
import {
|
|
3084
|
+
findLexicalConflictPairs,
|
|
3085
|
+
findTopicStatusConflictPairs,
|
|
3086
|
+
loadMemoriesFromDir as loadMemoriesFromDir21
|
|
3087
|
+
} from "@hiveai/core";
|
|
3042
3088
|
import { z as z30 } from "zod";
|
|
3089
|
+
var MemConflictCandidatesInputSchema = {
|
|
3090
|
+
since_days: z30.number().int().positive().max(3650).default(365).describe("Only memories created since N days ago"),
|
|
3091
|
+
types: z30.array(z30.enum(["decision", "architecture", "convention", "gotcha"])).default(["decision", "architecture"]).describe("Memory types scanned for pairwise lexical overlap"),
|
|
3092
|
+
min_jaccard: z30.number().min(0).max(1).default(0.45).describe("Minimum Jaccard token similarity to surface as a candidate pair"),
|
|
3093
|
+
max_pairs: z30.number().int().positive().max(100).default(20).describe("Cap pairs returned"),
|
|
3094
|
+
max_scan: z30.number().int().positive().max(2e3).default(500).describe("Maximum memories sampled for O(n\xB2) scan \u2014 excess dropped after chronological sort."),
|
|
3095
|
+
max_topic_pairs: z30.number().int().positive().max(100).default(20).describe(
|
|
3096
|
+
"Cap for extra signal: memories sharing the same topic with validated vs rejected status."
|
|
3097
|
+
)
|
|
3098
|
+
};
|
|
3099
|
+
async function memConflictCandidates(input, ctx) {
|
|
3100
|
+
if (!existsSync27(ctx.paths.memoriesDir)) {
|
|
3101
|
+
return {
|
|
3102
|
+
pairs: [],
|
|
3103
|
+
topic_status_pairs: [],
|
|
3104
|
+
scanned: 0,
|
|
3105
|
+
truncated: false,
|
|
3106
|
+
notice: "No .ai/memories directory."
|
|
3107
|
+
};
|
|
3108
|
+
}
|
|
3109
|
+
const all = await loadMemoriesFromDir21(ctx.paths.memoriesDir);
|
|
3110
|
+
const { pairs, scanned, truncated } = findLexicalConflictPairs(all, {
|
|
3111
|
+
sinceDays: input.since_days,
|
|
3112
|
+
types: input.types,
|
|
3113
|
+
minJaccard: input.min_jaccard,
|
|
3114
|
+
maxPairs: input.max_pairs,
|
|
3115
|
+
maxScan: input.max_scan
|
|
3116
|
+
});
|
|
3117
|
+
const topicStatusPairs = findTopicStatusConflictPairs(all, input.max_topic_pairs);
|
|
3118
|
+
const notice = pairs.length === 0 && topicStatusPairs.length === 0 ? "No lexical or topic-status candidates \u2014 widen since_days/types or lower min_jaccard." : void 0;
|
|
3119
|
+
return { pairs, topic_status_pairs: topicStatusPairs, scanned, truncated, notice };
|
|
3120
|
+
}
|
|
3121
|
+
|
|
3122
|
+
// src/tools/mem-resolve-project.ts
|
|
3123
|
+
import { resolveProjectInfo } from "@hiveai/core";
|
|
3124
|
+
import { z as z31 } from "zod";
|
|
3125
|
+
var MemResolveProjectInputSchema = {
|
|
3126
|
+
cwd: z31.string().optional().describe("Directory used for root discovery when HAIVE_PROJECT_ROOT is unset.")
|
|
3127
|
+
};
|
|
3128
|
+
async function memResolveProject(input, _ctx) {
|
|
3129
|
+
void _ctx;
|
|
3130
|
+
return {
|
|
3131
|
+
ok: true,
|
|
3132
|
+
info: resolveProjectInfo({
|
|
3133
|
+
cwd: input.cwd
|
|
3134
|
+
})
|
|
3135
|
+
};
|
|
3136
|
+
}
|
|
3137
|
+
|
|
3138
|
+
// src/tools/mem-suggest-topic.ts
|
|
3139
|
+
import { MemoryTypeSchema, suggestTopicKey } from "@hiveai/core";
|
|
3140
|
+
import { z as z32 } from "zod";
|
|
3141
|
+
var MemSuggestTopicInputSchema = {
|
|
3142
|
+
type: MemoryTypeSchema.describe("Memory kind \u2014 drives the suggested topic family."),
|
|
3143
|
+
title: z32.string().min(1).describe("Short title or phrase (headers, headings) \u2014 turned into slug")
|
|
3144
|
+
};
|
|
3145
|
+
async function memSuggestTopic(input, _ctx) {
|
|
3146
|
+
void _ctx;
|
|
3147
|
+
const suggestion = suggestTopicKey(input.type, input.title);
|
|
3148
|
+
return { topic_key: suggestion.topic_key, family: suggestion.family, type: input.type };
|
|
3149
|
+
}
|
|
3150
|
+
|
|
3151
|
+
// src/tools/mem-timeline.ts
|
|
3152
|
+
import { existsSync as existsSync28 } from "fs";
|
|
3153
|
+
import { collectTimelineEntries, loadMemoriesFromDir as loadMemoriesFromDir22 } from "@hiveai/core";
|
|
3154
|
+
import { z as z33 } from "zod";
|
|
3155
|
+
var MemTimelineInputSchema = {
|
|
3156
|
+
memory_id: z33.string().optional().describe("Seed id \u2014 expands via related_ids, topic, anchors"),
|
|
3157
|
+
topic: z33.string().optional().describe("Frontmatter.topic value \u2014 chronological list when memory_id omitted"),
|
|
3158
|
+
limit: z33.number().int().positive().max(100).default(30).describe("Max timeline entries returned")
|
|
3159
|
+
};
|
|
3160
|
+
async function memTimeline(input, ctx) {
|
|
3161
|
+
if (!existsSync28(ctx.paths.memoriesDir)) {
|
|
3162
|
+
return { entries: [], total: 0, notice: "No .ai/memories directory." };
|
|
3163
|
+
}
|
|
3164
|
+
const all = await loadMemoriesFromDir22(ctx.paths.memoriesDir);
|
|
3165
|
+
const { entries, notice } = collectTimelineEntries(all, {
|
|
3166
|
+
memoryId: input.memory_id,
|
|
3167
|
+
topic: input.topic,
|
|
3168
|
+
limit: input.limit
|
|
3169
|
+
});
|
|
3170
|
+
return { entries, total: entries.length, notice };
|
|
3171
|
+
}
|
|
3172
|
+
|
|
3173
|
+
// src/tools/runtime-journal-append.ts
|
|
3174
|
+
import { appendRuntimeJournalEntry as appendRuntimeJournalEntry2 } from "@hiveai/core";
|
|
3175
|
+
import { z as z34 } from "zod";
|
|
3176
|
+
var RuntimeJournalAppendInputSchema = {
|
|
3177
|
+
message: z34.string().min(1).describe("Short line to append to the runtime session journal"),
|
|
3178
|
+
kind: z34.enum(["note", "session_end", "mcp"]).default("note"),
|
|
3179
|
+
tool: z34.string().optional().describe("When kind=mcp, which tool name (optional)")
|
|
3180
|
+
};
|
|
3181
|
+
async function runtimeJournalAppend(input, ctx) {
|
|
3182
|
+
await appendRuntimeJournalEntry2(ctx.paths, {
|
|
3183
|
+
kind: input.kind,
|
|
3184
|
+
message: input.message,
|
|
3185
|
+
...input.tool ? { tool: input.tool } : {}
|
|
3186
|
+
});
|
|
3187
|
+
return {
|
|
3188
|
+
ok: true,
|
|
3189
|
+
path_hint: `${ctx.paths.runtimeDir}/session-journal.ndjson`
|
|
3190
|
+
};
|
|
3191
|
+
}
|
|
3192
|
+
|
|
3193
|
+
// src/tools/runtime-journal-tail.ts
|
|
3194
|
+
import { readRuntimeJournalTail } from "@hiveai/core";
|
|
3195
|
+
import { z as z35 } from "zod";
|
|
3196
|
+
var RuntimeJournalTailInputSchema = {
|
|
3197
|
+
limit: z35.number().int().positive().max(500).default(30).describe("Last N journal entries to return")
|
|
3198
|
+
};
|
|
3199
|
+
async function runtimeJournalTail(input, ctx) {
|
|
3200
|
+
const entries = await readRuntimeJournalTail(ctx.paths, input.limit);
|
|
3201
|
+
if (entries.length === 0) {
|
|
3202
|
+
return { entries: [], empty: true };
|
|
3203
|
+
}
|
|
3204
|
+
return { entries };
|
|
3205
|
+
}
|
|
3206
|
+
|
|
3207
|
+
// src/prompts/bootstrap-project.ts
|
|
3208
|
+
import { z as z36 } from "zod";
|
|
3043
3209
|
var BootstrapProjectArgsSchema = {
|
|
3044
|
-
module:
|
|
3210
|
+
module: z36.string().optional().describe(
|
|
3045
3211
|
"Optional module name to scope the analysis to (writes to .ai/modules/<module>/context.md)"
|
|
3046
3212
|
),
|
|
3047
|
-
focus:
|
|
3213
|
+
focus: z36.string().optional().describe("Optional area to emphasize (e.g. 'data layer', 'API surface')")
|
|
3048
3214
|
};
|
|
3049
3215
|
var ROOT_TEMPLATE = `# Project context
|
|
3050
3216
|
|
|
@@ -3126,10 +3292,10 @@ ${template}\`\`\`
|
|
|
3126
3292
|
}
|
|
3127
3293
|
|
|
3128
3294
|
// src/prompts/post-task.ts
|
|
3129
|
-
import { z as
|
|
3295
|
+
import { z as z37 } from "zod";
|
|
3130
3296
|
var PostTaskArgsSchema = {
|
|
3131
|
-
task_summary:
|
|
3132
|
-
files_touched:
|
|
3297
|
+
task_summary: z37.string().optional().describe("One sentence describing what you just did"),
|
|
3298
|
+
files_touched: z37.array(z37.string()).optional().describe("Files you created or modified during the task")
|
|
3133
3299
|
};
|
|
3134
3300
|
function postTaskPrompt(args, ctx) {
|
|
3135
3301
|
const taskLine = args.task_summary ? `
|
|
@@ -3213,12 +3379,12 @@ When done, respond with a brief summary: "Saved N memories: [list of IDs]. Sessi
|
|
|
3213
3379
|
}
|
|
3214
3380
|
|
|
3215
3381
|
// src/prompts/import-docs.ts
|
|
3216
|
-
import { z as
|
|
3382
|
+
import { z as z38 } from "zod";
|
|
3217
3383
|
var ImportDocsArgsSchema = {
|
|
3218
|
-
content:
|
|
3219
|
-
source:
|
|
3220
|
-
scope:
|
|
3221
|
-
dry_run:
|
|
3384
|
+
content: z38.string().describe("The documentation content to analyze and import as memories (Markdown, README, ADR, etc.)"),
|
|
3385
|
+
source: z38.string().optional().describe("Origin of the content (file path, URL, or document title) \u2014 used to anchor memories"),
|
|
3386
|
+
scope: z38.enum(["personal", "team"]).default("team").describe("Scope to assign to created memories"),
|
|
3387
|
+
dry_run: z38.boolean().default(false).describe("If true, describe what would be saved without actually calling mem_save")
|
|
3222
3388
|
};
|
|
3223
3389
|
function importDocsPrompt(args, ctx) {
|
|
3224
3390
|
const sourceLine = args.source ? `
|
|
@@ -3283,7 +3449,7 @@ When done, respond with: "Imported N memories: [list of IDs]" or "Nothing action
|
|
|
3283
3449
|
|
|
3284
3450
|
// src/server.ts
|
|
3285
3451
|
var SERVER_NAME = "haive";
|
|
3286
|
-
var SERVER_VERSION = "0.9.
|
|
3452
|
+
var SERVER_VERSION = "0.9.6";
|
|
3287
3453
|
function jsonResult(data) {
|
|
3288
3454
|
return {
|
|
3289
3455
|
content: [
|
|
@@ -3334,6 +3500,23 @@ function createHaiveServer(options = {}) {
|
|
|
3334
3500
|
return jsonResult(await memSave(input, context));
|
|
3335
3501
|
}
|
|
3336
3502
|
);
|
|
3503
|
+
server.tool(
|
|
3504
|
+
"mem_suggest_topic",
|
|
3505
|
+
[
|
|
3506
|
+
"Propose a stable `topic` key (topic-upsert) from type + short title.",
|
|
3507
|
+
"",
|
|
3508
|
+
"USE BEFORE mem_save when you want deterministic updates to the same memory over time;",
|
|
3509
|
+
"families mimic Engram-style grouping (architecture/*, bug/*, decision/*, \u2026).",
|
|
3510
|
+
"",
|
|
3511
|
+
"PARAMETERS:",
|
|
3512
|
+
" type \u2014 convention | decision | gotcha | architecture | glossary | attempt | session_recap",
|
|
3513
|
+
" title \u2014 phrase to slugify under the suggested family prefix",
|
|
3514
|
+
"",
|
|
3515
|
+
"RETURNS: { topic_key, family, type }"
|
|
3516
|
+
].join("\n"),
|
|
3517
|
+
MemSuggestTopicInputSchema,
|
|
3518
|
+
async (input) => jsonResult(await memSuggestTopic(input, context))
|
|
3519
|
+
);
|
|
3337
3520
|
server.tool(
|
|
3338
3521
|
"mem_tried",
|
|
3339
3522
|
[
|
|
@@ -3425,8 +3608,12 @@ function createHaiveServer(options = {}) {
|
|
|
3425
3608
|
server.tool(
|
|
3426
3609
|
"get_briefing",
|
|
3427
3610
|
[
|
|
3428
|
-
"\u2B50
|
|
3429
|
-
"
|
|
3611
|
+
"\u2B50 DEFAULT-FIRST for coding agents on any repo where `haive init` ran: call this BEFORE",
|
|
3612
|
+
"changing source or project config for the current goal (unless the developer explicitly opts out).",
|
|
3613
|
+
"One-shot onboarding: everything relevant in a single call under a token budget.",
|
|
3614
|
+
"",
|
|
3615
|
+
"PROGRESSIVE DISCLOSURE \u2014 after this, drill down only if needed:",
|
|
3616
|
+
" mem_relevant_to / mem_search (compact lists) \u2192 mem_get (full body + anchors).",
|
|
3430
3617
|
"",
|
|
3431
3618
|
"RETURNS (in order of priority):",
|
|
3432
3619
|
" 0. action_required \u2014 \u26A0\uFE0F HANDLE THIS FIRST if non-empty (see protocol below)",
|
|
@@ -3461,7 +3648,7 @@ function createHaiveServer(options = {}) {
|
|
|
3461
3648
|
" low \u2014 proposed, few reads (take with caution)",
|
|
3462
3649
|
" unverified \u2014 draft (unverified: true flag set)",
|
|
3463
3650
|
"",
|
|
3464
|
-
"Replaces 4\u20135 separate tool calls.
|
|
3651
|
+
"Replaces 4\u20135 separate tool calls. Prefer this first; use mem_search / mem_get only for follow-up."
|
|
3465
3652
|
].join("\n"),
|
|
3466
3653
|
GetBriefingInputSchema,
|
|
3467
3654
|
async (input) => {
|
|
@@ -3480,6 +3667,8 @@ function createHaiveServer(options = {}) {
|
|
|
3480
3667
|
"SEARCH MODES:",
|
|
3481
3668
|
" Literal (default): AND search across id, tags, and body \u2014 all tokens must match.",
|
|
3482
3669
|
" Falls back to OR automatically if no AND results (partial match).",
|
|
3670
|
+
" Lexical rank (lexical_rank: true, semantic: false): Okapi-BM25-style scoring on the",
|
|
3671
|
+
" filtered corpus \u2014 good for phrase-like queries without embeddings.",
|
|
3483
3672
|
" Semantic (semantic: true): embedding-based similarity \u2014 finds related memories",
|
|
3484
3673
|
" even with different wording. Requires haive embeddings index to be built.",
|
|
3485
3674
|
"",
|
|
@@ -3488,6 +3677,7 @@ function createHaiveServer(options = {}) {
|
|
|
3488
3677
|
" scope \u2014 filter by personal | team | module",
|
|
3489
3678
|
" type \u2014 filter by convention | decision | gotcha | architecture | glossary",
|
|
3490
3679
|
" semantic \u2014 true for embedding-based search (requires @hiveai/embeddings)",
|
|
3680
|
+
" lexical_rank \u2014 BM25-style ranking (ignored when semantic is true)",
|
|
3491
3681
|
" limit \u2014 max results (default 10)",
|
|
3492
3682
|
"",
|
|
3493
3683
|
"RETURNS: array of { id, type, scope, status, confidence, body, match_quality }"
|
|
@@ -3498,6 +3688,22 @@ function createHaiveServer(options = {}) {
|
|
|
3498
3688
|
return jsonResult(await memSearch(input, context));
|
|
3499
3689
|
}
|
|
3500
3690
|
);
|
|
3691
|
+
server.tool(
|
|
3692
|
+
"mem_timeline",
|
|
3693
|
+
[
|
|
3694
|
+
"Chronological view of related memories: by shared frontmatter.topic OR expanded from a seed id",
|
|
3695
|
+
"(related_ids, same topic, overlapping anchor paths \u2014 one extra hop on related_ids).",
|
|
3696
|
+
"",
|
|
3697
|
+
"PARAMETERS:",
|
|
3698
|
+
" memory_id \u2014 optional seed memory id",
|
|
3699
|
+
" topic \u2014 optional topic key (required if memory_id omitted)",
|
|
3700
|
+
" limit \u2014 max entries (default 30)",
|
|
3701
|
+
"",
|
|
3702
|
+
"RETURNS: { entries: [{ id, type, scope, created_at, one_line, topic? }], total, notice? }"
|
|
3703
|
+
].join("\n"),
|
|
3704
|
+
MemTimelineInputSchema,
|
|
3705
|
+
async (input) => jsonResult(await memTimeline(input, context))
|
|
3706
|
+
);
|
|
3501
3707
|
server.tool(
|
|
3502
3708
|
"mem_for_files",
|
|
3503
3709
|
[
|
|
@@ -3527,7 +3733,7 @@ function createHaiveServer(options = {}) {
|
|
|
3527
3733
|
[
|
|
3528
3734
|
"Fetch a single memory by its full id with all details.",
|
|
3529
3735
|
"",
|
|
3530
|
-
"USE WHEN get_briefing returned a
|
|
3736
|
+
"USE WHEN get_briefing / mem_relevant_to / mem_search returned a compact hit and you need",
|
|
3531
3737
|
"the full body, or when you know the exact id of a memory.",
|
|
3532
3738
|
"",
|
|
3533
3739
|
"PARAMETERS:",
|
|
@@ -3615,6 +3821,22 @@ function createHaiveServer(options = {}) {
|
|
|
3615
3821
|
CodeMapInputSchema,
|
|
3616
3822
|
async (input) => jsonResult(await codeMapTool(input, context))
|
|
3617
3823
|
);
|
|
3824
|
+
server.tool(
|
|
3825
|
+
"mem_resolve_project",
|
|
3826
|
+
[
|
|
3827
|
+
"Diagnostics: resolve which project root hAIve is using (never throws).",
|
|
3828
|
+
"",
|
|
3829
|
+
"USE IN multi-root workspaces or when the agent CWD may not be the repo root \u2014",
|
|
3830
|
+
"mirrors HAIVE_PROJECT_ROOT, findProjectRoot markers, and presence of .ai/memories.",
|
|
3831
|
+
"",
|
|
3832
|
+
"PARAMETERS:",
|
|
3833
|
+
" cwd \u2014 optional directory used for discovery when HAIVE_PROJECT_ROOT is unset",
|
|
3834
|
+
"",
|
|
3835
|
+
"RETURNS: { ok: true, info: { cwd, resolved_root, haive_project_root_env, \u2026 } }"
|
|
3836
|
+
].join("\n"),
|
|
3837
|
+
MemResolveProjectInputSchema,
|
|
3838
|
+
async (input) => jsonResult(await memResolveProject(input, context))
|
|
3839
|
+
);
|
|
3618
3840
|
server.tool(
|
|
3619
3841
|
"mem_update",
|
|
3620
3842
|
[
|
|
@@ -3748,6 +3970,8 @@ function createHaiveServer(options = {}) {
|
|
|
3748
3970
|
"One-shot ranked memories for a task \u2014 use instead of get_briefing when",
|
|
3749
3971
|
"project context is already loaded and you only want the relevant memory layer.",
|
|
3750
3972
|
"",
|
|
3973
|
+
"Second step in progressive disclosure (after get_briefing): narrow here, then mem_get for full text.",
|
|
3974
|
+
"",
|
|
3751
3975
|
"Reuses the same ranking pipeline (anchor / module / literal / semantic) but",
|
|
3752
3976
|
"skips project_context, modules, action_required, etc.",
|
|
3753
3977
|
"",
|
|
@@ -3905,6 +4129,53 @@ function createHaiveServer(options = {}) {
|
|
|
3905
4129
|
return jsonResult(await memConflicts(input, context));
|
|
3906
4130
|
}
|
|
3907
4131
|
);
|
|
4132
|
+
server.tool(
|
|
4133
|
+
"mem_conflict_candidates",
|
|
4134
|
+
[
|
|
4135
|
+
"Bulk scan for conflict CANDIDATES (not proof):",
|
|
4136
|
+
"",
|
|
4137
|
+
" 1. Lexical similarity (Jaccard) on decision/architecture-like pairs",
|
|
4138
|
+
" 2. Same frontmatter.topic with validated vs rejected \u2014 quick human-review signal",
|
|
4139
|
+
"",
|
|
4140
|
+
"Advisory only \u2014 follow with mem_conflicts_with on specific ids.",
|
|
4141
|
+
"",
|
|
4142
|
+
"PARAMETERS:",
|
|
4143
|
+
" since_days, types, min_jaccard, max_pairs, max_scan, max_topic_pairs",
|
|
4144
|
+
"",
|
|
4145
|
+
"RETURNS: { pairs, topic_status_pairs, scanned, truncated, notice? }"
|
|
4146
|
+
].join("\n"),
|
|
4147
|
+
MemConflictCandidatesInputSchema,
|
|
4148
|
+
async (input) => {
|
|
4149
|
+
tracker.record("mem_conflict_candidates", `${input.since_days}d`);
|
|
4150
|
+
return jsonResult(await memConflictCandidates(input, context));
|
|
4151
|
+
}
|
|
4152
|
+
);
|
|
4153
|
+
server.tool(
|
|
4154
|
+
"runtime_journal_append",
|
|
4155
|
+
[
|
|
4156
|
+
"Append one line to `.ai/.runtime/session-journal.ndjson` \u2014 machine-local session continuity.",
|
|
4157
|
+
"",
|
|
4158
|
+
"Does NOT replace team memories; complements mem_session_end recaps for local traces.",
|
|
4159
|
+
"",
|
|
4160
|
+
"PARAMETERS: message, kind (note|session_end|mcp), optional tool",
|
|
4161
|
+
"",
|
|
4162
|
+
"RETURNS: { ok, path_hint }"
|
|
4163
|
+
].join("\n"),
|
|
4164
|
+
RuntimeJournalAppendInputSchema,
|
|
4165
|
+
async (input) => jsonResult(await runtimeJournalAppend(input, context))
|
|
4166
|
+
);
|
|
4167
|
+
server.tool(
|
|
4168
|
+
"runtime_journal_tail",
|
|
4169
|
+
[
|
|
4170
|
+
"Read the last N entries from the runtime session journal (parsed JSON lines).",
|
|
4171
|
+
"",
|
|
4172
|
+
"PARAMETERS: limit (default 30, max 500)",
|
|
4173
|
+
"",
|
|
4174
|
+
"RETURNS: { entries: [...], empty?: true }"
|
|
4175
|
+
].join("\n"),
|
|
4176
|
+
RuntimeJournalTailInputSchema,
|
|
4177
|
+
async (input) => jsonResult(await runtimeJournalTail(input, context))
|
|
4178
|
+
);
|
|
3908
4179
|
server.tool(
|
|
3909
4180
|
"pre_commit_check",
|
|
3910
4181
|
[
|
|
@@ -4051,14 +4322,20 @@ export {
|
|
|
4051
4322
|
createHaiveServer,
|
|
4052
4323
|
getBriefing,
|
|
4053
4324
|
getRecap,
|
|
4325
|
+
memConflictCandidates,
|
|
4054
4326
|
memConflicts,
|
|
4055
4327
|
memDistill,
|
|
4056
4328
|
memRelevantTo,
|
|
4329
|
+
memResolveProject,
|
|
4330
|
+
memSuggestTopic,
|
|
4331
|
+
memTimeline,
|
|
4057
4332
|
parseMcpCliArgs,
|
|
4058
4333
|
patternDetect,
|
|
4059
4334
|
preCommitCheck,
|
|
4060
4335
|
printHaiveMcpVersion,
|
|
4061
4336
|
runHaiveMcpStdio,
|
|
4337
|
+
runtimeJournalAppend,
|
|
4338
|
+
runtimeJournalTail,
|
|
4062
4339
|
whyThisDecision,
|
|
4063
4340
|
whyThisFile
|
|
4064
4341
|
};
|