@velvetmonkey/flywheel-memory 2.3.2 → 2.4.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.
Files changed (2) hide show
  1. package/dist/index.js +124 -50
  2. package/package.json +2 -2
package/dist/index.js CHANGED
@@ -10389,10 +10389,10 @@ async function initToolRouting() {
10389
10389
  function hasToolRouting() {
10390
10390
  return routingIndex !== null && routingIndex.length > 0;
10391
10391
  }
10392
- function getToolRoutingMode(toolTierMode2) {
10392
+ function getToolRoutingMode(isFullToolset) {
10393
10393
  const env = process.env.FLYWHEEL_TOOL_ROUTING?.trim().toLowerCase();
10394
10394
  if (env === "pattern" || env === "hybrid" || env === "semantic") return env;
10395
- return toolTierMode2 === "tiered" ? "hybrid" : "pattern";
10395
+ return isFullToolset ? "hybrid" : "pattern";
10396
10396
  }
10397
10397
  async function getSemanticActivations(query) {
10398
10398
  return rankAndCollapse(query, routingIndex, hasToolRouting(), manifestModel ?? "");
@@ -11738,6 +11738,7 @@ var ALL_CATEGORIES = [
11738
11738
  var PRESETS = {
11739
11739
  // Presets
11740
11740
  full: [...ALL_CATEGORIES],
11741
+ auto: [...ALL_CATEGORIES],
11741
11742
  agent: ["search", "read", "write", "tasks", "memory"],
11742
11743
  // Composable bundles (one per category)
11743
11744
  graph: ["graph"],
@@ -11816,16 +11817,19 @@ function resolveToolConfig(envValue) {
11816
11817
  return {
11817
11818
  categories: new Set(PRESETS[DEFAULT_PRESET]),
11818
11819
  preset: DEFAULT_PRESET,
11819
- isFullToolset: true
11820
+ isFullToolset: true,
11821
+ enableProgressiveDisclosure: false
11820
11822
  };
11821
11823
  }
11822
11824
  const lowerValue = raw.toLowerCase();
11823
11825
  if (PRESETS[lowerValue]) {
11824
11826
  const cats = new Set(PRESETS[lowerValue]);
11827
+ const isFullToolset = cats.size === ALL_CATEGORIES.length && ALL_CATEGORIES.every((c) => cats.has(c));
11825
11828
  return {
11826
11829
  categories: cats,
11827
11830
  preset: lowerValue,
11828
- isFullToolset: cats.size === ALL_CATEGORIES.length && ALL_CATEGORIES.every((c) => cats.has(c))
11831
+ isFullToolset,
11832
+ enableProgressiveDisclosure: lowerValue === "auto"
11829
11833
  };
11830
11834
  }
11831
11835
  if (DEPRECATED_ALIASES[lowerValue]) {
@@ -11835,7 +11839,8 @@ function resolveToolConfig(envValue) {
11835
11839
  return {
11836
11840
  categories: cats,
11837
11841
  preset: resolved,
11838
- isFullToolset: cats.size === ALL_CATEGORIES.length && ALL_CATEGORIES.every((c) => cats.has(c))
11842
+ isFullToolset: cats.size === ALL_CATEGORIES.length && ALL_CATEGORIES.every((c) => cats.has(c)),
11843
+ enableProgressiveDisclosure: resolved === "auto"
11839
11844
  };
11840
11845
  }
11841
11846
  }
@@ -11843,14 +11848,16 @@ function resolveToolConfig(envValue) {
11843
11848
  return {
11844
11849
  categories,
11845
11850
  preset: null,
11846
- isFullToolset: categories.size === ALL_CATEGORIES.length && ALL_CATEGORIES.every((c) => categories.has(c))
11851
+ isFullToolset: categories.size === ALL_CATEGORIES.length && ALL_CATEGORIES.every((c) => categories.has(c)),
11852
+ enableProgressiveDisclosure: false
11847
11853
  };
11848
11854
  }
11849
11855
  var TOOL_CATEGORY = {
11850
- // search (3 tools)
11856
+ // search
11851
11857
  search: "search",
11852
11858
  init_semantic: "search",
11853
11859
  find_similar: "search",
11860
+ discover_tools: "search",
11854
11861
  // read (3 tools) -- note reading
11855
11862
  get_note_structure: "read",
11856
11863
  get_section_content: "read",
@@ -11938,10 +11945,11 @@ var TOOL_CATEGORY = {
11938
11945
  tool_selection_feedback: "diagnostics"
11939
11946
  };
11940
11947
  var TOOL_TIER = {
11941
- // Tier 1 — always visible (= agent preset, 18 tools)
11948
+ // Tier 1 — always visible (= agent preset, see TIER_1_TOOL_COUNT)
11942
11949
  search: 1,
11943
11950
  init_semantic: 1,
11944
11951
  find_similar: 1,
11952
+ discover_tools: 1,
11945
11953
  get_note_structure: 1,
11946
11954
  get_section_content: 1,
11947
11955
  find_sections: 1,
@@ -11957,7 +11965,7 @@ var TOOL_TIER = {
11957
11965
  vault_add_task: 1,
11958
11966
  memory: 1,
11959
11967
  brief: 1,
11960
- // Tier 2 — context-triggered categories + core diagnostics (33 tools)
11968
+ // Tier 2 — context-triggered categories + core diagnostics (see TIER_2_TOOL_COUNT)
11961
11969
  graph_analysis: 2,
11962
11970
  semantic_analysis: 2,
11963
11971
  get_backlinks: 2,
@@ -11991,7 +11999,7 @@ var TOOL_TIER = {
11991
11999
  flywheel_config: 2,
11992
12000
  server_log: 2,
11993
12001
  flywheel_doctor: 2,
11994
- // Tier 3 — explicit or advanced operations (26 tools)
12002
+ // Tier 3 — explicit or advanced operations (see TIER_3_TOOL_COUNT)
11995
12003
  vault_schema: 3,
11996
12004
  schema_conventions: 3,
11997
12005
  schema_validate: 3,
@@ -12031,6 +12039,10 @@ function assertToolTierCoverage() {
12031
12039
  }
12032
12040
  }
12033
12041
  assertToolTierCoverage();
12042
+ var TOTAL_TOOL_COUNT = Object.keys(TOOL_CATEGORY).length;
12043
+ var TIER_1_TOOL_COUNT = Object.values(TOOL_TIER).filter((t) => t === 1).length;
12044
+ var TIER_2_TOOL_COUNT = Object.values(TOOL_TIER).filter((t) => t === 2).length;
12045
+ var TIER_3_TOOL_COUNT = Object.values(TOOL_TIER).filter((t) => t === 3).length;
12034
12046
  function generateInstructions(categories, registry, activeTierCategories) {
12035
12047
  const parts = [];
12036
12048
  const tieringActive = activeTierCategories !== void 0;
@@ -12140,8 +12152,6 @@ Use "get_connection_strength" to measure link strength between two entities.
12140
12152
  Use "get_link_path" to trace the shortest path between any two entities or notes.
12141
12153
  Use "get_strong_connections" to find the strongest or most-connected relationships for an entity.`);
12142
12154
  } else if (tieringActive && categories.has("graph")) {
12143
- parts.push(`
12144
- **More tools available:** Ask about graph connections, backlinks, hubs, clusters, or paths to unlock graph analysis tools.`);
12145
12155
  }
12146
12156
  if (isCategoryVisible("note-ops")) {
12147
12157
  parts.push(`
@@ -12167,8 +12177,6 @@ Use "schema_conventions" to infer frontmatter conventions from folder usage patt
12167
12177
  Use "schema_validate" to validate frontmatter against explicit rules or find notes missing expected fields by folder.
12168
12178
  Use "note_intelligence" for per-note analysis (completeness, quality, suggestions).`);
12169
12179
  } else if (tieringActive && categories.has("schema")) {
12170
- parts.push(`
12171
- **Advanced tools:** Ask to unlock schema tools for conventions, validation, migrations, and bulk metadata analysis.`);
12172
12180
  }
12173
12181
  if (isCategoryVisible("wikilinks")) {
12174
12182
  parts.push(`
@@ -12184,8 +12192,6 @@ Link quality and discovery \u2014 not for finding content (use search for that).
12184
12192
  - "Was that link correct?" \u2192 wikilink_feedback (accept/reject, improves future suggestions)
12185
12193
  - "What aliases am I missing?" \u2192 suggest_entity_aliases (acronyms, short forms, alternate names)`);
12186
12194
  } else if (tieringActive && categories.has("wikilinks")) {
12187
- parts.push(`
12188
- **More tools available:** Ask about wikilinks, suggestions, stubs, or unlinked mentions to unlock wikilink tools.`);
12189
12195
  }
12190
12196
  if (isCategoryVisible("corrections")) {
12191
12197
  parts.push(`
@@ -12198,8 +12204,6 @@ When the user says something is wrong \u2014 a bad link, wrong entity, wrong cat
12198
12204
  "vault_resolve_correction" marks a correction as applied or dismissed.
12199
12205
  Use "absorb_as_alias" when two names should resolve to the same entity without merging note bodies.`);
12200
12206
  } else if (tieringActive && categories.has("corrections")) {
12201
- parts.push(`
12202
- **More tools available:** Ask about errors, wrong links, or fixes to unlock correction tools.`);
12203
12207
  }
12204
12208
  if (isCategoryVisible("temporal")) {
12205
12209
  parts.push(`
@@ -12215,8 +12219,6 @@ Temporal tools analyze *patterns and changes* over time \u2014 use them for "wha
12215
12219
 
12216
12220
  temporal_summary composes the other three \u2014 use it for weekly/monthly reviews.`);
12217
12221
  } else if (tieringActive && categories.has("temporal")) {
12218
- parts.push(`
12219
- **More tools available:** Ask about time, history, evolution, or stale notes to unlock temporal tools.`);
12220
12222
  }
12221
12223
  if (isCategoryVisible("diagnostics")) {
12222
12224
  parts.push(`
@@ -12231,9 +12233,10 @@ temporal_summary composes the other three \u2014 use it for weekly/monthly revie
12231
12233
 
12232
12234
  Use "flywheel_config" to inspect runtime configuration and set "tool_tier_override" to "auto", "full", or "minimal" for this vault.`);
12233
12235
  } else if (tieringActive && categories.has("diagnostics")) {
12236
+ }
12237
+ if (tieringActive) {
12234
12238
  parts.push(`
12235
- **More tools available:** Ask about vault health, indexing, status, or configuration to unlock diagnostic tools.
12236
- **Advanced tools:** Ask to unlock note operations or deep diagnostics for note mutations, benchmarks, history, graph exports, and learning reports.`);
12239
+ **More tools available:** Call \`discover_tools({ query: "your need" })\` to find and activate specialized tools for graph analysis, wikilinks, diagnostics, schema, temporal analysis, note operations, and more. Returns tool names, descriptions, and input schemas.`);
12237
12240
  }
12238
12241
  return parts.join("\n");
12239
12242
  }
@@ -12243,7 +12246,7 @@ import * as path38 from "path";
12243
12246
  import { dirname as dirname5, join as join19 } from "path";
12244
12247
  import { statSync as statSync6, readFileSync as readFileSync5 } from "fs";
12245
12248
  import { fileURLToPath } from "url";
12246
- import { z as z40 } from "zod";
12249
+ import { z as z41 } from "zod";
12247
12250
  import { CallToolRequestSchema, ErrorCode, McpError } from "@modelcontextprotocol/sdk/types.js";
12248
12251
  import { getSessionId } from "@velvetmonkey/vault-core";
12249
12252
 
@@ -26550,6 +26553,61 @@ function registerCalibrationExportTools(server2, getIndex, getStateDb4, getConfi
26550
26553
  );
26551
26554
  }
26552
26555
 
26556
+ // src/tools/read/discovery.ts
26557
+ import { z as z40 } from "zod";
26558
+ import { normalizeObjectSchema } from "@modelcontextprotocol/sdk/server/zod-compat.js";
26559
+ import { toJsonSchemaCompat } from "@modelcontextprotocol/sdk/server/zod-json-schema-compat.js";
26560
+ function toJsonSchema(inputSchema) {
26561
+ const obj = normalizeObjectSchema(inputSchema);
26562
+ if (!obj) return { type: "object" };
26563
+ return toJsonSchemaCompat(obj, { strictUnions: true, pipeStrategy: "input" });
26564
+ }
26565
+ function registerDiscoveryTools(server2, controller) {
26566
+ server2.tool(
26567
+ "discover_tools",
26568
+ 'Find and activate specialized tools. Call with what you need \u2014 e.g. "vault health", "graph connections", "schema migration". Returns matching tool names, descriptions, and input schemas. Does not execute discovered tools \u2014 call them separately after discovery.',
26569
+ {
26570
+ query: z40.string().describe(
26571
+ 'Natural language description of what you need \u2014 e.g. "vault health", "backlinks and graph", "schema migration"'
26572
+ )
26573
+ },
26574
+ async ({ query }) => {
26575
+ const signals = unionSignalsByCategory(getPatternSignals(query));
26576
+ const matchedCategories = [];
26577
+ const newlyActivatedCategories = [];
26578
+ for (const { category, tier } of signals) {
26579
+ const wasActive = controller.activeCategories.has(category);
26580
+ matchedCategories.push(category);
26581
+ controller.activateCategory(category, tier);
26582
+ if (!wasActive && controller.activeCategories.has(category)) {
26583
+ newlyActivatedCategories.push(category);
26584
+ }
26585
+ }
26586
+ const tools = [];
26587
+ for (const [name, handle] of controller.getRegisteredTools()) {
26588
+ const cat = TOOL_CATEGORY[name];
26589
+ if (handle.enabled && cat && matchedCategories.includes(cat)) {
26590
+ tools.push({
26591
+ name,
26592
+ description: handle.description ?? "",
26593
+ category: cat,
26594
+ inputSchema: toJsonSchema(handle.inputSchema)
26595
+ });
26596
+ }
26597
+ }
26598
+ const result = {
26599
+ matched_categories: matchedCategories,
26600
+ newly_activated_categories: newlyActivatedCategories,
26601
+ tools,
26602
+ hint: tools.length === 0 ? `No tools matched "${query}". Available categories: ${ALL_CATEGORIES.join(", ")}` : `${tools.length} tools available across ${matchedCategories.join(", ")}`
26603
+ };
26604
+ return {
26605
+ content: [{ type: "text", text: JSON.stringify(result, null, 2) }]
26606
+ };
26607
+ }
26608
+ );
26609
+ }
26610
+
26553
26611
  // src/resources/vault.ts
26554
26612
  function registerVaultResources(server2, getIndex) {
26555
26613
  server2.registerResource(
@@ -26698,7 +26756,15 @@ function getPatternSignals(raw) {
26698
26756
  if (!raw) return [];
26699
26757
  return ACTIVATION_PATTERNS.filter(({ patterns }) => patterns.some((pattern) => pattern.test(raw))).map(({ category, tier }) => ({ category, tier }));
26700
26758
  }
26701
- async function getActivationSignals(toolName, params, searchMethod, toolTierMode2 = "off") {
26759
+ function unionSignalsByCategory(signals) {
26760
+ const best = /* @__PURE__ */ new Map();
26761
+ for (const { category, tier } of signals) {
26762
+ const existing = best.get(category);
26763
+ if (!existing || tier > existing) best.set(category, tier);
26764
+ }
26765
+ return Array.from(best.entries()).map(([category, tier]) => ({ category, tier }));
26766
+ }
26767
+ async function getActivationSignals(toolName, params, searchMethod, isFullToolset = false) {
26702
26768
  if (toolName !== "search" && toolName !== "brief") return [];
26703
26769
  if (!params || typeof params !== "object") return [];
26704
26770
  const raw = [
@@ -26706,7 +26772,7 @@ async function getActivationSignals(toolName, params, searchMethod, toolTierMode
26706
26772
  typeof params.focus === "string" ? params.focus : ""
26707
26773
  ].filter(Boolean).join(" ");
26708
26774
  if (!raw) return [];
26709
- const routingMode = getToolRoutingMode(toolTierMode2);
26775
+ const routingMode = getToolRoutingMode(isFullToolset);
26710
26776
  const patternSignals = routingMode !== "semantic" ? getPatternSignals(raw) : [];
26711
26777
  let semanticSignals = [];
26712
26778
  if (routingMode !== "pattern" && searchMethod === "hybrid" && hasToolRouting()) {
@@ -26715,14 +26781,7 @@ async function getActivationSignals(toolName, params, searchMethod, toolTierMode
26715
26781
  if (routingMode === "semantic" && searchMethod !== "hybrid") {
26716
26782
  return getPatternSignals(raw);
26717
26783
  }
26718
- const categoryBest = /* @__PURE__ */ new Map();
26719
- for (const { category, tier } of [...patternSignals, ...semanticSignals]) {
26720
- const existing = categoryBest.get(category);
26721
- if (!existing || tier > existing) {
26722
- categoryBest.set(category, tier);
26723
- }
26724
- }
26725
- return Array.from(categoryBest.entries()).map(([category, tier]) => ({ category, tier }));
26784
+ return unionSignalsByCategory([...patternSignals, ...semanticSignals]);
26726
26785
  }
26727
26786
  function extractSearchMethod(result) {
26728
26787
  if (!result || typeof result !== "object") return void 0;
@@ -26737,7 +26796,7 @@ function extractSearchMethod(result) {
26737
26796
  }
26738
26797
  return void 0;
26739
26798
  }
26740
- function applyToolGating(targetServer, categories, getDb4, registry, getVaultPath, vaultCallbacks, tierMode = "off", onTierStateChange) {
26799
+ function applyToolGating(targetServer, categories, getDb4, registry, getVaultPath, vaultCallbacks, tierMode = "off", onTierStateChange, isFullToolset = false) {
26741
26800
  let _registered = 0;
26742
26801
  let _skipped = 0;
26743
26802
  let tierOverride = "auto";
@@ -26759,12 +26818,12 @@ function applyToolGating(targetServer, categories, getDb4, registry, getVaultPat
26759
26818
  return true;
26760
26819
  }
26761
26820
  function enableCategory(category, tier) {
26762
- if (!categories.has(category)) return;
26821
+ if (!categories.has(category)) return [];
26763
26822
  const previousTier = activatedCategoryTiers.get(category) ?? 0;
26764
26823
  if (tier > previousTier) {
26765
26824
  activatedCategoryTiers.set(category, tier);
26766
26825
  }
26767
- refreshToolVisibility();
26826
+ return refreshToolVisibility();
26768
26827
  }
26769
26828
  function shouldEnableTool(toolName) {
26770
26829
  const tier = TOOL_TIER[toolName];
@@ -26779,26 +26838,29 @@ function applyToolGating(targetServer, categories, getDb4, registry, getVaultPat
26779
26838
  return activatedTier >= tier;
26780
26839
  }
26781
26840
  function refreshToolVisibility() {
26782
- let changed = false;
26841
+ const newlyEnabled = [];
26783
26842
  for (const [name, handle] of toolHandles) {
26784
26843
  const enabled = shouldEnableTool(name);
26785
26844
  if (enabled !== handle.enabled) {
26786
26845
  handle.enabled = enabled;
26787
- changed = true;
26846
+ if (enabled) newlyEnabled.push(name);
26788
26847
  }
26789
26848
  }
26790
- if (changed) {
26849
+ if (newlyEnabled.length > 0) {
26791
26850
  targetServer.sendToolListChanged();
26792
26851
  }
26793
26852
  if (controllerRef) {
26794
26853
  onTierStateChange?.(controllerRef);
26795
26854
  }
26855
+ return newlyEnabled;
26796
26856
  }
26797
26857
  async function maybeActivateFromContext(toolName, params, searchMethod) {
26798
- if (tierMode !== "tiered" || tierOverride === "full") return;
26799
- for (const { category, tier } of await getActivationSignals(toolName, params, searchMethod, tierMode)) {
26800
- enableCategory(category, tier);
26858
+ if (tierMode !== "tiered" || tierOverride === "full") return [];
26859
+ const newlyEnabled = [];
26860
+ for (const { category, tier } of await getActivationSignals(toolName, params, searchMethod, isFullToolset)) {
26861
+ newlyEnabled.push(...enableCategory(category, tier));
26801
26862
  }
26863
+ return newlyEnabled;
26802
26864
  }
26803
26865
  function ensureToolEnabledForDirectCall(toolName) {
26804
26866
  if (tierMode !== "tiered") return;
@@ -26844,7 +26906,14 @@ function applyToolGating(targetServer, categories, getDb4, registry, getVaultPat
26844
26906
  try {
26845
26907
  result = await handler(...args);
26846
26908
  const searchMethod = extractSearchMethod(result);
26847
- await maybeActivateFromContext(toolName, params, searchMethod);
26909
+ const newlyActivated = await maybeActivateFromContext(toolName, params, searchMethod);
26910
+ if (newlyActivated.length > 0 && result?.content && Array.isArray(result.content)) {
26911
+ result.content.push({
26912
+ type: "text",
26913
+ text: `
26914
+ [Progressive disclosure: ${newlyActivated.length} new tools activated: ${newlyActivated.join(", ")}. Call tools/list to refresh.]`
26915
+ });
26916
+ }
26848
26917
  return result;
26849
26918
  } catch (err) {
26850
26919
  success = false;
@@ -27010,7 +27079,7 @@ function applyToolGating(targetServer, categories, getDb4, registry, getVaultPat
27010
27079
  const schemaIdx = handlerIdx - 1;
27011
27080
  const schema = args[schemaIdx];
27012
27081
  if (schema && typeof schema === "object" && !Array.isArray(schema)) {
27013
- schema.vault = z40.string().optional().describe(
27082
+ schema.vault = z41.string().optional().describe(
27014
27083
  `Vault name for multi-vault mode. Available: ${registry.getVaultNames().join(", ")}. Default: ${registry.primaryName}`
27015
27084
  );
27016
27085
  }
@@ -27127,7 +27196,7 @@ function applyToolGating(targetServer, categories, getDb4, registry, getVaultPat
27127
27196
  controllerRef = controller;
27128
27197
  return controller;
27129
27198
  }
27130
- function registerAllTools(targetServer, ctx) {
27199
+ function registerAllTools(targetServer, ctx, controller) {
27131
27200
  const { getVaultPath: gvp, getVaultIndex: gvi, getStateDb: gsd, getFlywheelConfig: gcf } = ctx;
27132
27201
  registerHealthTools(targetServer, gvi, gvp, gcf, gsd, ctx.getWatcherStatus, () => trPkg.version, ctx.getPipelineActivity);
27133
27202
  registerSystemTools(
@@ -27220,6 +27289,9 @@ function registerAllTools(targetServer, ctx) {
27220
27289
  registerCalibrationExportTools(targetServer, gvi, gsd, gcf);
27221
27290
  registerMemoryTools(targetServer, gsd);
27222
27291
  registerBriefTools(targetServer, gsd);
27292
+ if (controller && controller.mode === "tiered") {
27293
+ registerDiscoveryTools(targetServer, controller);
27294
+ }
27223
27295
  registerVaultResources(targetServer, () => gvi() ?? null);
27224
27296
  }
27225
27297
 
@@ -27252,7 +27324,7 @@ function getWatcherStatus() {
27252
27324
  }
27253
27325
  var toolConfig = resolveToolConfig();
27254
27326
  var enabledCategories = toolConfig.categories;
27255
- var toolTierMode = toolConfig.isFullToolset ? "tiered" : "off";
27327
+ var toolTierMode = toolConfig.enableProgressiveDisclosure ? "tiered" : "off";
27256
27328
  var runtimeToolTierOverride = INITIAL_TIER_OVERRIDE;
27257
27329
  var runtimeActiveCategoryTiers = /* @__PURE__ */ new Map();
27258
27330
  var primaryToolTierController = null;
@@ -27303,9 +27375,10 @@ function createConfiguredServer() {
27303
27375
  ctx.getVaultPath,
27304
27376
  buildVaultCallbacks(),
27305
27377
  toolTierMode,
27306
- handleTierStateChange
27378
+ handleTierStateChange,
27379
+ toolConfig.isFullToolset
27307
27380
  );
27308
- registerAllTools(s, ctx);
27381
+ registerAllTools(s, ctx, toolTierController);
27309
27382
  toolTierController.setOverride(runtimeToolTierOverride);
27310
27383
  for (const [category, tier] of runtimeActiveCategoryTiers) {
27311
27384
  toolTierController.activateCategory(category, tier);
@@ -27356,9 +27429,10 @@ var _gatingResult = applyToolGating(
27356
27429
  _registryCtx.getVaultPath,
27357
27430
  buildVaultCallbacks(),
27358
27431
  toolTierMode,
27359
- handleTierStateChange
27432
+ handleTierStateChange,
27433
+ toolConfig.isFullToolset
27360
27434
  );
27361
- registerAllTools(server, _registryCtx);
27435
+ registerAllTools(server, _registryCtx, _gatingResult);
27362
27436
  _gatingResult.setOverride(runtimeToolTierOverride);
27363
27437
  _gatingResult.finalizeRegistration();
27364
27438
  primaryToolTierController = _gatingResult;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@velvetmonkey/flywheel-memory",
3
- "version": "2.3.2",
3
+ "version": "2.4.0",
4
4
  "description": "MCP tools that search, write, and auto-link your Obsidian vault — and learn from your edits.",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
@@ -55,7 +55,7 @@
55
55
  "dependencies": {
56
56
  "@huggingface/transformers": "^3.8.1",
57
57
  "@modelcontextprotocol/sdk": "^1.25.1",
58
- "@velvetmonkey/vault-core": "^2.3.2",
58
+ "@velvetmonkey/vault-core": "^2.4.0",
59
59
  "better-sqlite3": "^12.0.0",
60
60
  "chokidar": "^4.0.0",
61
61
  "gray-matter": "^4.0.3",