@hiveai/mcp 0.9.5 → 0.9.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/server.d.ts CHANGED
@@ -1,6 +1,6 @@
1
1
  import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
2
2
  import * as _hiveai_core from '@hiveai/core';
3
- import { HaivePaths, ConfidenceLevel, resolveProjectInfo } from '@hiveai/core';
3
+ import { HaivePaths, ConfidenceLevel, resolveProjectInfo, readRuntimeJournalTail } from '@hiveai/core';
4
4
  import { z } from 'zod';
5
5
 
6
6
  interface HaiveContext {
@@ -167,16 +167,26 @@ interface BriefingOutput {
167
167
  }
168
168
  declare function getBriefing(input: GetBriefingInput, ctx: HaiveContext): Promise<BriefingOutput>;
169
169
 
170
- declare const CodeMapInputSchema: {
170
+ declare const CodeMapInputZod: z.ZodObject<{
171
171
  file: z.ZodOptional<z.ZodString>;
172
172
  symbol: z.ZodOptional<z.ZodString>;
173
173
  paths: z.ZodDefault<z.ZodArray<z.ZodString, "many">>;
174
174
  max_files: z.ZodDefault<z.ZodNumber>;
175
175
  max_tokens: z.ZodOptional<z.ZodNumber>;
176
- };
177
- type CodeMapInput = {
178
- [K in keyof typeof CodeMapInputSchema]: z.infer<(typeof CodeMapInputSchema)[K]>;
179
- };
176
+ }, "strip", z.ZodTypeAny, {
177
+ paths: string[];
178
+ max_files: number;
179
+ symbol?: string | undefined;
180
+ max_tokens?: number | undefined;
181
+ file?: string | undefined;
182
+ }, {
183
+ symbol?: string | undefined;
184
+ paths?: string[] | undefined;
185
+ max_tokens?: number | undefined;
186
+ file?: string | undefined;
187
+ max_files?: number | undefined;
188
+ }>;
189
+ type CodeMapInput = z.infer<typeof CodeMapInputZod>;
180
190
  interface CodeMapToolOutput {
181
191
  available: boolean;
182
192
  generated_at?: string;
@@ -611,17 +621,43 @@ declare const MemConflictCandidatesInputSchema: {
611
621
  min_jaccard: z.ZodDefault<z.ZodNumber>;
612
622
  max_pairs: z.ZodDefault<z.ZodNumber>;
613
623
  max_scan: z.ZodDefault<z.ZodNumber>;
624
+ max_topic_pairs: z.ZodDefault<z.ZodNumber>;
614
625
  };
615
626
  type MemConflictCandidatesInput = {
616
627
  [K in keyof typeof MemConflictCandidatesInputSchema]: z.infer<(typeof MemConflictCandidatesInputSchema)[K]>;
617
628
  };
618
629
  declare function memConflictCandidates(input: MemConflictCandidatesInput, ctx: HaiveContext): Promise<{
619
630
  pairs: _hiveai_core.ConflictCandidatePair[];
631
+ topic_status_pairs: _hiveai_core.TopicStatusPair[];
620
632
  scanned: number;
621
633
  truncated: boolean;
622
634
  notice: string | undefined;
623
635
  }>;
624
636
 
637
+ declare const RuntimeJournalAppendInputSchema: {
638
+ message: z.ZodString;
639
+ kind: z.ZodDefault<z.ZodEnum<["note", "session_end", "mcp"]>>;
640
+ tool: z.ZodOptional<z.ZodString>;
641
+ };
642
+ type RuntimeJournalAppendInput = {
643
+ [K in keyof typeof RuntimeJournalAppendInputSchema]: z.infer<(typeof RuntimeJournalAppendInputSchema)[K]>;
644
+ };
645
+ declare function runtimeJournalAppend(input: RuntimeJournalAppendInput, ctx: HaiveContext): Promise<{
646
+ ok: true;
647
+ path_hint: string;
648
+ }>;
649
+
650
+ declare const RuntimeJournalTailInputSchema: {
651
+ limit: z.ZodDefault<z.ZodNumber>;
652
+ };
653
+ type RuntimeJournalTailInput = {
654
+ [K in keyof typeof RuntimeJournalTailInputSchema]: z.infer<(typeof RuntimeJournalTailInputSchema)[K]>;
655
+ };
656
+ declare function runtimeJournalTail(input: RuntimeJournalTailInput, ctx: HaiveContext): Promise<{
657
+ entries: Awaited<ReturnType<typeof readRuntimeJournalTail>>;
658
+ empty?: boolean;
659
+ }>;
660
+
625
661
  declare const SERVER_NAME = "haive";
626
662
  declare const SERVER_VERSION: string;
627
663
  declare function createHaiveServer(options?: CreateContextOptions): {
@@ -644,4 +680,4 @@ declare function runHaiveMcpStdio(options: {
644
680
  root?: string;
645
681
  }): Promise<void>;
646
682
 
647
- 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, 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, whyThisDecision, whyThisFile };
683
+ 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
@@ -1125,7 +1125,11 @@ import {
1125
1125
  import { z as z16 } from "zod";
1126
1126
 
1127
1127
  // src/session-tracker.ts
1128
- import { appendUsageEvent, loadConfig as loadConfig2 } from "@hiveai/core";
1128
+ import {
1129
+ appendUsageEvent,
1130
+ appendRuntimeJournalEntry,
1131
+ loadConfig as loadConfig2
1132
+ } from "@hiveai/core";
1129
1133
  import { mkdir as mkdir5, writeFile as writeFile9, rm } from "fs/promises";
1130
1134
  import { existsSync as existsSync16 } from "fs";
1131
1135
  import path7 from "path";
@@ -1198,6 +1202,14 @@ var SessionTracker = class {
1198
1202
  recapId = result.id;
1199
1203
  } catch {
1200
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
+ });
1201
1213
  const ranPostTask = this.events.some(
1202
1214
  (e) => e.tool === "mem_session_end" && !e.summary?.startsWith("Auto-captured")
1203
1215
  );
@@ -1898,6 +1910,7 @@ var CodeMapInputSchema = {
1898
1910
  "Approximate token budget for the response. When the matching set exceeds it, files are ranked by export density (exports per LOC) and the highest-signal ones are kept first. Omit to disable budgeting (legacy behavior)."
1899
1911
  )
1900
1912
  };
1913
+ var CodeMapInputZod = z18.object(CodeMapInputSchema);
1901
1914
  async function codeMapTool(input, ctx) {
1902
1915
  const map = await loadCodeMap2(ctx.paths);
1903
1916
  if (!map) {
@@ -3068,19 +3081,27 @@ function gitFileDiff(root, file, sinceDays) {
3068
3081
 
3069
3082
  // src/tools/mem-conflict-candidates.ts
3070
3083
  import { existsSync as existsSync27 } from "fs";
3071
- import { findLexicalConflictPairs, loadMemoriesFromDir as loadMemoriesFromDir21 } from "@hiveai/core";
3084
+ import {
3085
+ findLexicalConflictPairs,
3086
+ findTopicStatusConflictPairs,
3087
+ loadMemoriesFromDir as loadMemoriesFromDir21
3088
+ } from "@hiveai/core";
3072
3089
  import { z as z30 } from "zod";
3073
3090
  var MemConflictCandidatesInputSchema = {
3074
3091
  since_days: z30.number().int().positive().max(3650).default(365).describe("Only memories created since N days ago"),
3075
3092
  types: z30.array(z30.enum(["decision", "architecture", "convention", "gotcha"])).default(["decision", "architecture"]).describe("Memory types scanned for pairwise lexical overlap"),
3076
3093
  min_jaccard: z30.number().min(0).max(1).default(0.45).describe("Minimum Jaccard token similarity to surface as a candidate pair"),
3077
3094
  max_pairs: z30.number().int().positive().max(100).default(20).describe("Cap pairs returned"),
3078
- 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_scan: z30.number().int().positive().max(2e3).default(500).describe("Maximum memories sampled for O(n\xB2) scan \u2014 excess dropped after chronological sort."),
3096
+ max_topic_pairs: z30.number().int().positive().max(100).default(20).describe(
3097
+ "Cap for extra signal: memories sharing the same topic with validated vs rejected status."
3098
+ )
3079
3099
  };
3080
3100
  async function memConflictCandidates(input, ctx) {
3081
3101
  if (!existsSync27(ctx.paths.memoriesDir)) {
3082
3102
  return {
3083
3103
  pairs: [],
3104
+ topic_status_pairs: [],
3084
3105
  scanned: 0,
3085
3106
  truncated: false,
3086
3107
  notice: "No .ai/memories directory."
@@ -3094,8 +3115,9 @@ async function memConflictCandidates(input, ctx) {
3094
3115
  maxPairs: input.max_pairs,
3095
3116
  maxScan: input.max_scan
3096
3117
  });
3097
- const notice = pairs.length === 0 ? "No lexical candidate pairs \u2265 threshold \u2014 try lowering min_jaccard or widen since_days/types." : void 0;
3098
- return { pairs, scanned, truncated, notice };
3118
+ const topicStatusPairs = findTopicStatusConflictPairs(all, input.max_topic_pairs);
3119
+ 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;
3120
+ return { pairs, topic_status_pairs: topicStatusPairs, scanned, truncated, notice };
3099
3121
  }
3100
3122
 
3101
3123
  // src/tools/mem-resolve-project.ts
@@ -3149,13 +3171,47 @@ async function memTimeline(input, ctx) {
3149
3171
  return { entries, total: entries.length, notice };
3150
3172
  }
3151
3173
 
3152
- // src/prompts/bootstrap-project.ts
3174
+ // src/tools/runtime-journal-append.ts
3175
+ import { appendRuntimeJournalEntry as appendRuntimeJournalEntry2 } from "@hiveai/core";
3153
3176
  import { z as z34 } from "zod";
3177
+ var RuntimeJournalAppendInputSchema = {
3178
+ message: z34.string().min(1).describe("Short line to append to the runtime session journal"),
3179
+ kind: z34.enum(["note", "session_end", "mcp"]).default("note"),
3180
+ tool: z34.string().optional().describe("When kind=mcp, which tool name (optional)")
3181
+ };
3182
+ async function runtimeJournalAppend(input, ctx) {
3183
+ await appendRuntimeJournalEntry2(ctx.paths, {
3184
+ kind: input.kind,
3185
+ message: input.message,
3186
+ ...input.tool ? { tool: input.tool } : {}
3187
+ });
3188
+ return {
3189
+ ok: true,
3190
+ path_hint: `${ctx.paths.runtimeDir}/session-journal.ndjson`
3191
+ };
3192
+ }
3193
+
3194
+ // src/tools/runtime-journal-tail.ts
3195
+ import { readRuntimeJournalTail } from "@hiveai/core";
3196
+ import { z as z35 } from "zod";
3197
+ var RuntimeJournalTailInputSchema = {
3198
+ limit: z35.number().int().positive().max(500).default(30).describe("Last N journal entries to return")
3199
+ };
3200
+ async function runtimeJournalTail(input, ctx) {
3201
+ const entries = await readRuntimeJournalTail(ctx.paths, input.limit);
3202
+ if (entries.length === 0) {
3203
+ return { entries: [], empty: true };
3204
+ }
3205
+ return { entries };
3206
+ }
3207
+
3208
+ // src/prompts/bootstrap-project.ts
3209
+ import { z as z36 } from "zod";
3154
3210
  var BootstrapProjectArgsSchema = {
3155
- module: z34.string().optional().describe(
3211
+ module: z36.string().optional().describe(
3156
3212
  "Optional module name to scope the analysis to (writes to .ai/modules/<module>/context.md)"
3157
3213
  ),
3158
- focus: z34.string().optional().describe("Optional area to emphasize (e.g. 'data layer', 'API surface')")
3214
+ focus: z36.string().optional().describe("Optional area to emphasize (e.g. 'data layer', 'API surface')")
3159
3215
  };
3160
3216
  var ROOT_TEMPLATE = `# Project context
3161
3217
 
@@ -3237,10 +3293,10 @@ ${template}\`\`\`
3237
3293
  }
3238
3294
 
3239
3295
  // src/prompts/post-task.ts
3240
- import { z as z35 } from "zod";
3296
+ import { z as z37 } from "zod";
3241
3297
  var PostTaskArgsSchema = {
3242
- task_summary: z35.string().optional().describe("One sentence describing what you just did"),
3243
- files_touched: z35.array(z35.string()).optional().describe("Files you created or modified during the task")
3298
+ task_summary: z37.string().optional().describe("One sentence describing what you just did"),
3299
+ files_touched: z37.array(z37.string()).optional().describe("Files you created or modified during the task")
3244
3300
  };
3245
3301
  function postTaskPrompt(args, ctx) {
3246
3302
  const taskLine = args.task_summary ? `
@@ -3324,12 +3380,12 @@ When done, respond with a brief summary: "Saved N memories: [list of IDs]. Sessi
3324
3380
  }
3325
3381
 
3326
3382
  // src/prompts/import-docs.ts
3327
- import { z as z36 } from "zod";
3383
+ import { z as z38 } from "zod";
3328
3384
  var ImportDocsArgsSchema = {
3329
- content: z36.string().describe("The documentation content to analyze and import as memories (Markdown, README, ADR, etc.)"),
3330
- source: z36.string().optional().describe("Origin of the content (file path, URL, or document title) \u2014 used to anchor memories"),
3331
- scope: z36.enum(["personal", "team"]).default("team").describe("Scope to assign to created memories"),
3332
- dry_run: z36.boolean().default(false).describe("If true, describe what would be saved without actually calling mem_save")
3385
+ content: z38.string().describe("The documentation content to analyze and import as memories (Markdown, README, ADR, etc.)"),
3386
+ source: z38.string().optional().describe("Origin of the content (file path, URL, or document title) \u2014 used to anchor memories"),
3387
+ scope: z38.enum(["personal", "team"]).default("team").describe("Scope to assign to created memories"),
3388
+ dry_run: z38.boolean().default(false).describe("If true, describe what would be saved without actually calling mem_save")
3333
3389
  };
3334
3390
  function importDocsPrompt(args, ctx) {
3335
3391
  const sourceLine = args.source ? `
@@ -3394,7 +3450,7 @@ When done, respond with: "Imported N memories: [list of IDs]" or "Nothing action
3394
3450
 
3395
3451
  // src/server.ts
3396
3452
  var SERVER_NAME = "haive";
3397
- var SERVER_VERSION = "0.9.5";
3453
+ var SERVER_VERSION = "0.9.7";
3398
3454
  function jsonResult(data) {
3399
3455
  return {
3400
3456
  content: [
@@ -4077,14 +4133,17 @@ function createHaiveServer(options = {}) {
4077
4133
  server.tool(
4078
4134
  "mem_conflict_candidates",
4079
4135
  [
4080
- "Bulk lexical scan for decision/architecture-like pairs that look similar (Jaccard on tokens).",
4136
+ "Bulk scan for conflict CANDIDATES (not proof):",
4081
4137
  "",
4082
- "Advisory only \u2014 follow with mem_conflicts_with on specific ids for real contradiction checks.",
4138
+ " 1. Lexical similarity (Jaccard) on decision/architecture-like pairs",
4139
+ " 2. Same frontmatter.topic with validated vs rejected \u2014 quick human-review signal",
4140
+ "",
4141
+ "Advisory only \u2014 follow with mem_conflicts_with on specific ids.",
4083
4142
  "",
4084
4143
  "PARAMETERS:",
4085
- " since_days, types, min_jaccard, max_pairs, max_scan",
4144
+ " since_days, types, min_jaccard, max_pairs, max_scan, max_topic_pairs",
4086
4145
  "",
4087
- "RETURNS: { pairs: [{ id_a, id_b, jaccard }], scanned, truncated, notice? }"
4146
+ "RETURNS: { pairs, topic_status_pairs, scanned, truncated, notice? }"
4088
4147
  ].join("\n"),
4089
4148
  MemConflictCandidatesInputSchema,
4090
4149
  async (input) => {
@@ -4092,6 +4151,32 @@ function createHaiveServer(options = {}) {
4092
4151
  return jsonResult(await memConflictCandidates(input, context));
4093
4152
  }
4094
4153
  );
4154
+ server.tool(
4155
+ "runtime_journal_append",
4156
+ [
4157
+ "Append one line to `.ai/.runtime/session-journal.ndjson` \u2014 machine-local session continuity.",
4158
+ "",
4159
+ "Does NOT replace team memories; complements mem_session_end recaps for local traces.",
4160
+ "",
4161
+ "PARAMETERS: message, kind (note|session_end|mcp), optional tool",
4162
+ "",
4163
+ "RETURNS: { ok, path_hint }"
4164
+ ].join("\n"),
4165
+ RuntimeJournalAppendInputSchema,
4166
+ async (input) => jsonResult(await runtimeJournalAppend(input, context))
4167
+ );
4168
+ server.tool(
4169
+ "runtime_journal_tail",
4170
+ [
4171
+ "Read the last N entries from the runtime session journal (parsed JSON lines).",
4172
+ "",
4173
+ "PARAMETERS: limit (default 30, max 500)",
4174
+ "",
4175
+ "RETURNS: { entries: [...], empty?: true }"
4176
+ ].join("\n"),
4177
+ RuntimeJournalTailInputSchema,
4178
+ async (input) => jsonResult(await runtimeJournalTail(input, context))
4179
+ );
4095
4180
  server.tool(
4096
4181
  "pre_commit_check",
4097
4182
  [
@@ -4250,6 +4335,8 @@ export {
4250
4335
  preCommitCheck,
4251
4336
  printHaiveMcpVersion,
4252
4337
  runHaiveMcpStdio,
4338
+ runtimeJournalAppend,
4339
+ runtimeJournalTail,
4253
4340
  whyThisDecision,
4254
4341
  whyThisFile
4255
4342
  };