@hivelore/mcp 0.30.0 → 0.31.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/server.d.ts CHANGED
@@ -659,6 +659,65 @@ declare function preCommitCheck(input: PreCommitCheckInput, ctx: HaiveContext):
659
659
  */
660
660
  declare function readPresumedCorrectTargets(root: string, relPaths: string[]): Promise<SensorTarget[]>;
661
661
 
662
+ declare const MemTriedInputSchema: {
663
+ what: z.ZodString;
664
+ why_failed: z.ZodString;
665
+ instead: z.ZodOptional<z.ZodString>;
666
+ scope: z.ZodDefault<z.ZodEnum<["personal", "team", "module"]>>;
667
+ module: z.ZodOptional<z.ZodString>;
668
+ tags: z.ZodDefault<z.ZodArray<z.ZodString, "many">>;
669
+ paths: z.ZodDefault<z.ZodArray<z.ZodString, "many">>;
670
+ author: z.ZodOptional<z.ZodString>;
671
+ sensor: z.ZodOptional<z.ZodObject<{
672
+ pattern: z.ZodString;
673
+ absent: z.ZodOptional<z.ZodString>;
674
+ severity: z.ZodDefault<z.ZodEnum<["warn", "block"]>>;
675
+ message: z.ZodOptional<z.ZodString>;
676
+ bad_example: z.ZodOptional<z.ZodString>;
677
+ }, "strip", z.ZodTypeAny, {
678
+ pattern: string;
679
+ severity: "warn" | "block";
680
+ message?: string | undefined;
681
+ absent?: string | undefined;
682
+ bad_example?: string | undefined;
683
+ }, {
684
+ pattern: string;
685
+ message?: string | undefined;
686
+ absent?: string | undefined;
687
+ severity?: "warn" | "block" | undefined;
688
+ bad_example?: string | undefined;
689
+ }>>;
690
+ };
691
+ type MemTriedInput = {
692
+ [K in keyof typeof MemTriedInputSchema]: z.infer<(typeof MemTriedInputSchema)[K]>;
693
+ };
694
+ interface MemTriedOutput {
695
+ id: string;
696
+ scope: string;
697
+ file_path: string;
698
+ /**
699
+ * A captured attempt closes its prevention loop (gate can block the repeat) only once a sensor is
700
+ * VALIDATED via propose_sensor. True until then — the lesson is briefed but not enforced.
701
+ */
702
+ loop_open: boolean;
703
+ /** Heuristic candidate to PRE-FILL a propose_sensor call (refine, then call it). Never a persisted sensor. */
704
+ proposed_sensor_seed?: {
705
+ pattern: string;
706
+ absent?: string;
707
+ message: string;
708
+ };
709
+ /** Next-step guidance: how to close the loop via propose_sensor. */
710
+ hint?: string;
711
+ /** When input.sensor was given: the inline propose_sensor verdict (accepted ⇒ loop closed). */
712
+ sensor_result?: {
713
+ accepted: boolean;
714
+ severity: "warn" | "block";
715
+ reason?: string;
716
+ guidance?: string;
717
+ };
718
+ }
719
+ declare function memTried(input: MemTriedInput, ctx: HaiveContext): Promise<MemTriedOutput>;
720
+
662
721
  declare const PatternDetectInputSchema: {
663
722
  since_days: z.ZodDefault<z.ZodNumber>;
664
723
  dry_run: z.ZodDefault<z.ZodBoolean>;
@@ -816,4 +875,4 @@ declare function runHaiveMcpStdio(options: {
816
875
  root?: string;
817
876
  }): Promise<void>;
818
877
 
819
- export { type AntiPatternsCheckInput, type AntiPatternsCheckOutput, 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 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, TOOL_PROFILES, type ToolProfile, type WhyThisDecisionInput, type WhyThisDecisionOutput, type WhyThisFileInput, type WhyThisFileOutput, antiPatternsCheck, codeMapTool, codeSearch, createHaiveServer, getAllowedToolsForProfile, getBriefing, getRecap, memConflictCandidates, memConflicts, memDistill, memRelevantTo, memResolveProject, memSuggestTopic, memTimeline, parseMcpCliArgs, patternDetect, preCommitCheck, printHaiveMcpVersion, readPresumedCorrectTargets, runHaiveMcpStdio, runtimeJournalAppend, runtimeJournalTail, whyThisDecision, whyThisFile };
878
+ export { type AntiPatternsCheckInput, type AntiPatternsCheckOutput, 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 MemConflictsInput, type MemConflictsOutput, type MemDistillInput, type MemDistillOutput, type MemRelevantToInput, type MemRelevantToOutput, type MemResolveProjectInput, type MemSuggestTopicInput, type MemTimelineInput, type MemTriedOutput, type PatternDetectInput, type PatternDetectOutput, type PreCommitCheckInput, type PreCommitCheckOutput, type RuntimeJournalAppendInput, type RuntimeJournalTailInput, SERVER_NAME, SERVER_VERSION, TOOL_PROFILES, type ToolProfile, type WhyThisDecisionInput, type WhyThisDecisionOutput, type WhyThisFileInput, type WhyThisFileOutput, antiPatternsCheck, codeMapTool, codeSearch, createHaiveServer, getAllowedToolsForProfile, getBriefing, getRecap, memConflictCandidates, memConflicts, memDistill, memRelevantTo, memResolveProject, memSuggestTopic, memTimeline, memTried, parseMcpCliArgs, patternDetect, preCommitCheck, printHaiveMcpVersion, readPresumedCorrectTargets, runHaiveMcpStdio, runtimeJournalAppend, runtimeJournalTail, whyThisDecision, whyThisFile };
package/dist/server.js CHANGED
@@ -1120,94 +1120,40 @@ async function memApprove(input, ctx) {
1120
1120
  }
1121
1121
 
1122
1122
  // src/tools/mem-tried.ts
1123
- import { mkdir as mkdir3, writeFile as writeFile8 } from "fs/promises";
1124
- import { existsSync as existsSync15 } from "fs";
1125
- import path5 from "path";
1123
+ import { mkdir as mkdir3, writeFile as writeFile9 } from "fs/promises";
1124
+ import { existsSync as existsSync16 } from "fs";
1125
+ import path6 from "path";
1126
1126
  import {
1127
1127
  buildFrontmatter as buildFrontmatter2,
1128
1128
  memoryFilePath as memoryFilePath2,
1129
- serializeMemory as serializeMemory7,
1129
+ serializeMemory as serializeMemory8,
1130
1130
  suggestSensorSeed as suggestSensorSeed2
1131
1131
  } from "@hivelore/core";
1132
- import { z as z15 } from "zod";
1133
- var MemTriedInputSchema = {
1134
- what: z15.string().min(1).describe("Brief description of the approach that was tried"),
1135
- why_failed: z15.string().min(1).describe("Why it failed or why it should NOT be used"),
1136
- instead: z15.string().optional().describe("What to use or do instead (recommended alternative)"),
1137
- scope: z15.enum(["personal", "team", "module"]).default("personal").describe("Visibility scope"),
1138
- module: z15.string().optional().describe("Module name (required when scope=module)"),
1139
- tags: z15.array(z15.string()).default([]).describe("Tags for filtering"),
1140
- paths: z15.array(z15.string()).default([]).describe("Anchor file paths this applies to"),
1141
- author: z15.string().optional().describe("Author handle or email")
1142
- };
1143
- async function memTried(input, ctx) {
1144
- if (!existsSync15(ctx.paths.haiveDir)) {
1145
- throw new Error(`No .ai/ directory at ${ctx.paths.root}. Run 'hivelore init' first.`);
1146
- }
1147
- const slug = input.what.toLowerCase().replace(/[^a-z0-9\s]/g, "").trim().split(/\s+/).slice(0, 5).join("-");
1148
- const baseFm = buildFrontmatter2({
1149
- type: "attempt",
1150
- slug,
1151
- scope: input.scope,
1152
- module: input.module,
1153
- tags: input.tags,
1154
- paths: input.paths,
1155
- author: input.author
1156
- });
1157
- const frontmatter = { ...baseFm, status: "validated" };
1158
- const lines = [`# ${input.what}`, ""];
1159
- lines.push(`**Why it failed / do NOT use:** ${input.why_failed}`);
1160
- if (input.instead) {
1161
- lines.push("", `**Instead, use:** ${input.instead}`);
1162
- }
1163
- const body = lines.join("\n") + "\n";
1164
- const file = memoryFilePath2(ctx.paths, frontmatter.scope, frontmatter.id, frontmatter.module);
1165
- await mkdir3(path5.dirname(file), { recursive: true });
1166
- if (existsSync15(file)) {
1167
- throw new Error(`Memory already exists at ${file}`);
1168
- }
1169
- await writeFile8(file, serializeMemory7({ frontmatter, body }), "utf8");
1170
- const seed = input.paths.length > 0 ? suggestSensorSeed2(body, input.paths) : null;
1171
- const hint = input.paths.length === 0 ? "No `paths` given, so this attempt is feedforward-only \u2014 it will be briefed but the gate cannot block the repeat. Re-run with `paths` set to the file(s) where the mistake lives, then call propose_sensor to close the loop." : seed ? "This attempt is NOT yet enforced. Call propose_sensor to turn it into a reliable block \u2014 a candidate is pre-filled in proposed_sensor_seed (refine it: pattern = the faulty usage, absent = the correct-usage marker). Hivelore validates the proposal (silent on current code, fires on the bad example) before trusting it to block." : "This attempt is NOT yet enforced and no candidate pattern could be derived from the wording. Call propose_sensor with a discriminating pattern (pattern = faulty usage, absent = correct-usage marker) to close the loop.";
1172
- return {
1173
- id: frontmatter.id,
1174
- scope: frontmatter.scope,
1175
- file_path: file,
1176
- loop_open: true,
1177
- ...seed ? {
1178
- proposed_sensor_seed: {
1179
- pattern: seed.pattern,
1180
- ...seed.absent ? { absent: seed.absent } : {},
1181
- message: seed.message
1182
- }
1183
- } : {},
1184
- hint
1185
- };
1186
- }
1132
+ import { z as z16 } from "zod";
1187
1133
 
1188
1134
  // src/tools/propose-sensor.ts
1189
1135
  import { execSync } from "child_process";
1190
- import { readFile as readFile3, writeFile as writeFile9 } from "fs/promises";
1191
- import { existsSync as existsSync16 } from "fs";
1192
- import path6 from "path";
1136
+ import { readFile as readFile3, writeFile as writeFile8 } from "fs/promises";
1137
+ import { existsSync as existsSync15 } from "fs";
1138
+ import path5 from "path";
1193
1139
  import {
1194
1140
  extractSensorExamples,
1195
1141
  judgeProposedSensor,
1196
1142
  loadMemoriesFromDir as loadMemoriesFromDir13,
1197
- serializeMemory as serializeMemory8
1143
+ serializeMemory as serializeMemory7
1198
1144
  } from "@hivelore/core";
1199
- import { z as z16 } from "zod";
1145
+ import { z as z15 } from "zod";
1200
1146
  var ProposeSensorInputSchema = {
1201
- memory_id: z16.string().min(1).describe("Id of the gotcha/attempt memory this sensor protects."),
1202
- pattern: z16.string().min(1).describe("Regex matching the FAULTY usage (the risky call/token), e.g. 'stripe\\.paymentIntents\\.create'."),
1203
- absent: z16.string().optional().describe(
1147
+ memory_id: z15.string().min(1).describe("Id of the gotcha/attempt memory this sensor protects."),
1148
+ pattern: z15.string().min(1).describe("Regex matching the FAULTY usage (the risky call/token), e.g. 'stripe\\.paymentIntents\\.create'."),
1149
+ absent: z15.string().optional().describe(
1204
1150
  "Regex for the CORRECT-usage marker (e.g. 'idempotencyKey'). When it appears in the window around a match, the catch is suppressed \u2014 this is what makes the sensor discriminate the faulty call from the correct one. STRONGLY recommended for 'X without Y' lessons."
1205
1151
  ),
1206
- bad_example: z16.string().optional().describe("A code snippet that SHOULD match \u2014 proves the sensor catches the mistake. If omitted, examples are read from the lesson body."),
1207
- severity: z16.enum(["warn", "block"]).default("block").describe("block = hard-fail the gate (accepted ONLY if it passes self-validation). warn = advisory."),
1208
- message: z16.string().optional().describe("LLM-facing fix message shown when it fires. Defaults to one derived from the lesson."),
1209
- flags: z16.string().optional().describe("Optional regex flags (e.g. 'i' for case-insensitive)."),
1210
- paths: z16.array(z16.string()).default([]).describe("Override scope paths. Defaults to the memory's anchor paths.")
1152
+ bad_example: z15.string().optional().describe("A code snippet that SHOULD match \u2014 proves the sensor catches the mistake. If omitted, examples are read from the lesson body."),
1153
+ severity: z15.enum(["warn", "block"]).default("block").describe("block = hard-fail the gate (accepted ONLY if it passes self-validation). warn = advisory."),
1154
+ message: z15.string().optional().describe("LLM-facing fix message shown when it fires. Defaults to one derived from the lesson."),
1155
+ flags: z15.string().optional().describe("Optional regex flags (e.g. 'i' for case-insensitive)."),
1156
+ paths: z15.array(z15.string()).default([]).describe("Override scope paths. Defaults to the memory's anchor paths.")
1211
1157
  };
1212
1158
  function deriveMessage(body, pattern, absent) {
1213
1159
  const instead = body.match(/\*\*Instead,\s*use:\*\*\s*([^\n]+)/i)?.[1]?.trim();
@@ -1232,8 +1178,8 @@ async function readPresumedCorrectTargets(root, relPaths) {
1232
1178
  continue;
1233
1179
  } catch {
1234
1180
  }
1235
- const abs = path6.resolve(root, rel);
1236
- if (!existsSync16(abs)) continue;
1181
+ const abs = path5.resolve(root, rel);
1182
+ if (!existsSync15(abs)) continue;
1237
1183
  try {
1238
1184
  targets.push({ path: rel, content: await readFile3(abs, "utf8") });
1239
1185
  } catch {
@@ -1242,7 +1188,7 @@ async function readPresumedCorrectTargets(root, relPaths) {
1242
1188
  return targets;
1243
1189
  }
1244
1190
  async function proposeSensor(input, ctx) {
1245
- if (!existsSync16(ctx.paths.memoriesDir)) {
1191
+ if (!existsSync15(ctx.paths.memoriesDir)) {
1246
1192
  throw new Error(`No .ai/memories at ${ctx.paths.root}. Run 'hivelore init' first.`);
1247
1193
  }
1248
1194
  try {
@@ -1302,7 +1248,7 @@ async function proposeSensor(input, ctx) {
1302
1248
  frontmatter: { ...found.memory.frontmatter, sensor },
1303
1249
  body: found.memory.body
1304
1250
  };
1305
- await writeFile9(found.filePath, serializeMemory8(next), "utf8");
1251
+ await writeFile8(found.filePath, serializeMemory7(next), "utf8");
1306
1252
  return {
1307
1253
  accepted: true,
1308
1254
  memory_id: input.memory_id,
@@ -1312,6 +1258,99 @@ async function proposeSensor(input, ctx) {
1312
1258
  };
1313
1259
  }
1314
1260
 
1261
+ // src/tools/mem-tried.ts
1262
+ var MemTriedInputSchema = {
1263
+ what: z16.string().min(1).describe("Brief description of the approach that was tried"),
1264
+ why_failed: z16.string().min(1).describe("Why it failed or why it should NOT be used"),
1265
+ instead: z16.string().optional().describe("What to use or do instead (recommended alternative)"),
1266
+ scope: z16.enum(["personal", "team", "module"]).default("personal").describe("Visibility scope"),
1267
+ module: z16.string().optional().describe("Module name (required when scope=module)"),
1268
+ tags: z16.array(z16.string()).default([]).describe("Tags for filtering"),
1269
+ paths: z16.array(z16.string()).default([]).describe("Anchor file paths this applies to"),
1270
+ author: z16.string().optional().describe("Author handle or email"),
1271
+ sensor: z16.object({
1272
+ pattern: z16.string().min(1).describe("Regex matching the FAULTY usage (added diff lines)"),
1273
+ absent: z16.string().optional().describe("Regex marking CORRECT usage nearby \u2014 excludes it from firing"),
1274
+ severity: z16.enum(["warn", "block"]).default("block").describe("block = deterministic gate refusal"),
1275
+ message: z16.string().optional().describe("Self-correction message shown when the sensor fires"),
1276
+ bad_example: z16.string().optional().describe("Code snippet the sensor MUST fire on (validation)")
1277
+ }).optional().describe(
1278
+ "ONE-SHOT loop close: validate and attach a sensor in the same call (equivalent to a follow-up propose_sensor). Validated against HEAD \u2014 silent on current code, fires on the bad example. If rejected, the attempt is still saved and the verdict tells you how to revise."
1279
+ )
1280
+ };
1281
+ async function memTried(input, ctx) {
1282
+ if (!existsSync16(ctx.paths.haiveDir)) {
1283
+ throw new Error(`No .ai/ directory at ${ctx.paths.root}. Run 'hivelore init' first.`);
1284
+ }
1285
+ const slug = input.what.toLowerCase().replace(/[^a-z0-9\s]/g, "").trim().split(/\s+/).slice(0, 5).join("-");
1286
+ const baseFm = buildFrontmatter2({
1287
+ type: "attempt",
1288
+ slug,
1289
+ scope: input.scope,
1290
+ module: input.module,
1291
+ tags: input.tags,
1292
+ paths: input.paths,
1293
+ author: input.author
1294
+ });
1295
+ const frontmatter = { ...baseFm, status: "validated" };
1296
+ const lines = [`# ${input.what}`, ""];
1297
+ lines.push(`**Why it failed / do NOT use:** ${input.why_failed}`);
1298
+ if (input.instead) {
1299
+ lines.push("", `**Instead, use:** ${input.instead}`);
1300
+ }
1301
+ const body = lines.join("\n") + "\n";
1302
+ const file = memoryFilePath2(ctx.paths, frontmatter.scope, frontmatter.id, frontmatter.module);
1303
+ await mkdir3(path6.dirname(file), { recursive: true });
1304
+ if (existsSync16(file)) {
1305
+ throw new Error(`Memory already exists at ${file}`);
1306
+ }
1307
+ await writeFile9(file, serializeMemory8({ frontmatter, body }), "utf8");
1308
+ if (input.sensor) {
1309
+ const verdict = await proposeSensor(
1310
+ {
1311
+ memory_id: frontmatter.id,
1312
+ pattern: input.sensor.pattern,
1313
+ absent: input.sensor.absent,
1314
+ severity: input.sensor.severity ?? "block",
1315
+ message: input.sensor.message,
1316
+ bad_example: input.sensor.bad_example,
1317
+ flags: void 0,
1318
+ paths: []
1319
+ },
1320
+ ctx
1321
+ );
1322
+ return {
1323
+ id: frontmatter.id,
1324
+ scope: frontmatter.scope,
1325
+ file_path: file,
1326
+ loop_open: !verdict.accepted,
1327
+ sensor_result: {
1328
+ accepted: verdict.accepted,
1329
+ severity: input.sensor.severity ?? "block",
1330
+ ...verdict.reason ? { reason: verdict.reason } : {},
1331
+ ...verdict.guidance ? { guidance: verdict.guidance } : {}
1332
+ },
1333
+ hint: verdict.accepted ? "Loop closed: the attempt is saved AND enforced \u2014 the gate now refuses a repeat deterministically." : `Attempt saved, but the sensor was rejected (${verdict.reason}). Revise per the guidance and re-propose with propose_sensor.`
1334
+ };
1335
+ }
1336
+ const seed = input.paths.length > 0 ? suggestSensorSeed2(body, input.paths) : null;
1337
+ const hint = input.paths.length === 0 ? "No `paths` given, so this attempt is feedforward-only \u2014 it will be briefed but the gate cannot block the repeat. Re-run with `paths` set to the file(s) where the mistake lives, then call propose_sensor to close the loop." : seed ? "This attempt is NOT yet enforced. Call propose_sensor (or re-run mem_tried with the one-shot `sensor` parameter) to turn it into a reliable block \u2014 a candidate is pre-filled in proposed_sensor_seed (refine it: pattern = the faulty usage, absent = the correct-usage marker). Hivelore validates the proposal (silent on current code, fires on the bad example) before trusting it to block." : "This attempt is NOT yet enforced and no candidate pattern could be derived from the wording. Call propose_sensor with a discriminating pattern (pattern = faulty usage, absent = correct-usage marker) to close the loop.";
1338
+ return {
1339
+ id: frontmatter.id,
1340
+ scope: frontmatter.scope,
1341
+ file_path: file,
1342
+ loop_open: true,
1343
+ ...seed ? {
1344
+ proposed_sensor_seed: {
1345
+ pattern: seed.pattern,
1346
+ ...seed.absent ? { absent: seed.absent } : {},
1347
+ message: seed.message
1348
+ }
1349
+ } : {},
1350
+ hint
1351
+ };
1352
+ }
1353
+
1315
1354
  // src/tools/ingest-findings.ts
1316
1355
  import { existsSync as existsSync17 } from "fs";
1317
1356
  import { mkdir as mkdir4, readFile as readFile4, writeFile as writeFile10 } from "fs/promises";
@@ -2313,11 +2352,20 @@ ${m.content}`).join("\n\n---\n\n"),
2313
2352
  if (isDecaying(u, createdAt)) decayWarnings.push(m.id);
2314
2353
  }
2315
2354
  const formattedMemories = input.format === "compact" ? trimmedMemories.map((m) => ({ ...m, body: compactSummary(m.body) })) : input.format === "actions" ? trimmedMemories.map((m) => ({ ...m, body: extractActionsBriefBody(m.body) })) : trimmedMemories;
2316
- const outputMemories = formattedMemories.map((m) => ({
2355
+ let outputMemories = formattedMemories.map((m) => ({
2317
2356
  ...m,
2318
2357
  priority: classifyMemoryPriority(m, byId.get(m.id), input.files, input.symbols),
2319
2358
  why: explainWhySurfaced(m, byId.get(m.id), input.files, inferred)
2320
2359
  }));
2360
+ if (input.format === "full") {
2361
+ const hasDirectHits = outputMemories.some((m) => m.priority === "must_read" || m.priority === "useful");
2362
+ if (hasDirectHits) {
2363
+ outputMemories = outputMemories.map(
2364
+ (m) => m.priority === "background" ? { ...m, body: `${compactSummary(m.body)}
2365
+ (background \u2014 full body: mem_get("${m.id}"))` } : m
2366
+ );
2367
+ }
2368
+ }
2321
2369
  const briefingQuality = classifyBriefingQuality(outputMemories, {
2322
2370
  isTemplateContext,
2323
2371
  autoContextGenerated,
@@ -2632,7 +2680,7 @@ function oneLine(value) {
2632
2680
  return value.replace(/\s+/g, " ").replace(/"/g, '\\"').trim().slice(0, 120);
2633
2681
  }
2634
2682
  function serverVersion() {
2635
- return true ? "0.30.0" : "dev";
2683
+ return true ? "0.31.0" : "dev";
2636
2684
  }
2637
2685
 
2638
2686
  // src/tools/code-map.ts
@@ -4703,7 +4751,7 @@ When done, respond with: "Imported N memories: [list of IDs]" or "Nothing action
4703
4751
  // src/server.ts
4704
4752
  import { hasRecentBriefingMarker, loadConfigSync } from "@hivelore/core";
4705
4753
  var SERVER_NAME = "hivelore";
4706
- var SERVER_VERSION = "0.30.0";
4754
+ var SERVER_VERSION = "0.31.0";
4707
4755
  function jsonResult(data) {
4708
4756
  return {
4709
4757
  content: [
@@ -5805,6 +5853,7 @@ export {
5805
5853
  memResolveProject,
5806
5854
  memSuggestTopic,
5807
5855
  memTimeline,
5856
+ memTried,
5808
5857
  parseMcpCliArgs,
5809
5858
  patternDetect,
5810
5859
  preCommitCheck,