@velvetmonkey/flywheel-memory 2.0.155 → 2.0.156

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 +212 -49
  2. package/package.json +2 -2
package/dist/index.js CHANGED
@@ -6516,6 +6516,7 @@ import {
6516
6516
  loadFlywheelConfigFromDb,
6517
6517
  saveFlywheelConfigToDb
6518
6518
  } from "@velvetmonkey/vault-core";
6519
+ var DEFAULT_ENTITY_EXCLUDE_FOLDERS = ["node_modules", "templates", "attachments", "tmp"];
6519
6520
  var DEFAULT_CONFIG = {
6520
6521
  exclude: [],
6521
6522
  exclude_entity_folders: [],
@@ -7238,6 +7239,7 @@ function addNoteToIndex(index, note) {
7238
7239
  async function upsertNote(index, vaultPath2, notePath) {
7239
7240
  try {
7240
7241
  const existed = index.notes.has(notePath);
7242
+ const oldNote = existed ? index.notes.get(notePath) : void 0;
7241
7243
  let releasedKeys = [];
7242
7244
  if (existed) {
7243
7245
  releasedKeys = removeNoteFromIndex(index, notePath);
@@ -7255,10 +7257,12 @@ async function upsertNote(index, vaultPath2, notePath) {
7255
7257
  if (releasedKeys.length > 0) {
7256
7258
  reconcileReleasedKeys(index, releasedKeys);
7257
7259
  }
7260
+ const entityFieldChanged = !oldNote || (oldNote.title !== note.title || JSON.stringify(oldNote.aliases) !== JSON.stringify(note.aliases) || oldNote.frontmatter.type !== note.frontmatter.type);
7258
7261
  return {
7259
7262
  success: true,
7260
7263
  action: existed ? "updated" : "added",
7261
- path: notePath
7264
+ path: notePath,
7265
+ entityFieldChanged
7262
7266
  };
7263
7267
  } catch (error) {
7264
7268
  return {
@@ -7300,7 +7304,8 @@ async function processBatch(index, vaultPath2, batch, options = {}) {
7300
7304
  successful: 0,
7301
7305
  failed: 0,
7302
7306
  results: [],
7303
- durationMs: 0
7307
+ durationMs: 0,
7308
+ hasEntityRelevantChanges: false
7304
7309
  };
7305
7310
  }
7306
7311
  console.error(`[flywheel] Processing ${total} file events`);
@@ -7355,7 +7360,8 @@ async function processBatch(index, vaultPath2, batch, options = {}) {
7355
7360
  successful,
7356
7361
  failed,
7357
7362
  results,
7358
- durationMs
7363
+ durationMs,
7364
+ hasEntityRelevantChanges: results.some((r) => r.entityFieldChanged)
7359
7365
  };
7360
7366
  }
7361
7367
 
@@ -8427,6 +8433,7 @@ var PipelineRunner = class {
8427
8433
  entitiesAfter = [];
8428
8434
  entitiesBefore = [];
8429
8435
  hubBefore = /* @__PURE__ */ new Map();
8436
+ hasEntityRelevantChanges = false;
8430
8437
  forwardLinkResults = [];
8431
8438
  linkDiffs = [];
8432
8439
  survivedLinks = [];
@@ -8498,6 +8505,7 @@ var PipelineRunner = class {
8498
8505
  if (!vaultIndex2) {
8499
8506
  const rebuilt = await p.buildVaultIndex(p.vp);
8500
8507
  p.updateVaultIndex(rebuilt);
8508
+ this.hasEntityRelevantChanges = true;
8501
8509
  serverLog("watcher", `Index rebuilt (full): ${rebuilt.notes.size} notes, ${rebuilt.entities.size} entities`);
8502
8510
  } else {
8503
8511
  const absoluteBatch = {
@@ -8505,6 +8513,7 @@ var PipelineRunner = class {
8505
8513
  events: p.events.map((e) => ({ ...e, path: path15.join(p.vp, e.path) }))
8506
8514
  };
8507
8515
  const batchResult = await processBatch(vaultIndex2, p.vp, absoluteBatch);
8516
+ this.hasEntityRelevantChanges = batchResult.hasEntityRelevantChanges;
8508
8517
  serverLog("watcher", `Incremental: ${batchResult.successful}/${batchResult.total} files in ${batchResult.durationMs}ms`);
8509
8518
  }
8510
8519
  p.updateIndexState("ready");
@@ -8551,7 +8560,7 @@ var PipelineRunner = class {
8551
8560
  for (const r of rows) this.hubBefore.set(r.name, r.hub_score);
8552
8561
  }
8553
8562
  const entityScanAgeMs = p.ctx.lastEntityScanAt > 0 ? Date.now() - p.ctx.lastEntityScanAt : Infinity;
8554
- if (entityScanAgeMs < 5 * 60 * 1e3) {
8563
+ if (entityScanAgeMs < 5 * 60 * 1e3 && !this.hasEntityRelevantChanges) {
8555
8564
  tracker.start("entity_scan", {});
8556
8565
  tracker.skip("entity_scan", `cache valid (${Math.round(entityScanAgeMs / 1e3)}s old)`);
8557
8566
  this.entitiesBefore = p.sd ? getAllEntitiesFromDb(p.sd) : [];
@@ -9329,7 +9338,7 @@ async function flushLogs() {
9329
9338
 
9330
9339
  // src/index.ts
9331
9340
  init_embeddings();
9332
- import { openStateDb, scanVaultEntities as scanVaultEntities4, getAllEntitiesFromDb as getAllEntitiesFromDb5, loadContentHashes, saveContentHashBatch, renameContentHash, checkDbIntegrity as checkDbIntegrity2, safeBackupAsync as safeBackupAsync2, preserveCorruptedDb, deleteStateDbFiles, attemptSalvage } from "@velvetmonkey/vault-core";
9341
+ import { openStateDb, scanVaultEntities as scanVaultEntities4, getAllEntitiesFromDb as getAllEntitiesFromDb6, loadContentHashes, saveContentHashBatch, renameContentHash, checkDbIntegrity as checkDbIntegrity2, safeBackupAsync as safeBackupAsync2, preserveCorruptedDb, deleteStateDbFiles, attemptSalvage } from "@velvetmonkey/vault-core";
9333
9342
 
9334
9343
  // src/core/write/memory.ts
9335
9344
  init_wikilinkFeedback();
@@ -10723,6 +10732,20 @@ import { z } from "zod";
10723
10732
  // src/core/read/constants.ts
10724
10733
  var MAX_LIMIT = 200;
10725
10734
 
10735
+ // src/core/read/indexGuard.ts
10736
+ function requireIndex() {
10737
+ const state2 = getIndexState();
10738
+ if (state2 === "building") {
10739
+ const { parsed, total } = getIndexProgress();
10740
+ const progress = total > 0 ? ` (${parsed}/${total} files)` : "";
10741
+ throw new Error(`Index building${progress}... try again shortly`);
10742
+ }
10743
+ if (state2 === "error") {
10744
+ const error = getIndexError();
10745
+ throw new Error(`Index failed to build: ${error?.message || "unknown error"}`);
10746
+ }
10747
+ }
10748
+
10726
10749
  // src/tools/read/query.ts
10727
10750
  init_embeddings();
10728
10751
  import {
@@ -11747,6 +11770,7 @@ function registerQueryTools(server2, getIndex, getVaultPath, getStateDb3) {
11747
11770
  consumer: z.enum(["llm", "human"]).default("llm").describe('Output format: "llm" applies sandwich ordering and strips scoring fields for context efficiency. "human" preserves score order and all scoring metadata for UI display.')
11748
11771
  },
11749
11772
  async ({ query, where, has_tag, has_any_tag, has_all_tags, include_children, folder, title_contains, modified_after, modified_before, sort_by, order, prefix, limit: requestedLimit, detail_count: requestedDetailCount, context_note, consumer }) => {
11773
+ requireIndex();
11750
11774
  const limit = Math.min(requestedLimit ?? 10, MAX_LIMIT);
11751
11775
  const detailN = requestedDetailCount ?? 5;
11752
11776
  const index = getIndex();
@@ -12466,20 +12490,6 @@ function detectCycles(index, maxLength = 10, limit = 20) {
12466
12490
  return cycles;
12467
12491
  }
12468
12492
 
12469
- // src/core/read/indexGuard.ts
12470
- function requireIndex() {
12471
- const state2 = getIndexState();
12472
- if (state2 === "building") {
12473
- const { parsed, total } = getIndexProgress();
12474
- const progress = total > 0 ? ` (${parsed}/${total} files)` : "";
12475
- throw new Error(`Index building${progress}... try again shortly`);
12476
- }
12477
- if (state2 === "error") {
12478
- const error = getIndexError();
12479
- throw new Error(`Index failed to build: ${error?.message || "unknown error"}`);
12480
- }
12481
- }
12482
-
12483
12493
  // src/tools/read/graph.ts
12484
12494
  async function getContext(vaultPath2, sourcePath, line, contextLines = 1) {
12485
12495
  try {
@@ -14656,7 +14666,7 @@ function registerHealthTools(server2, getIndex, getVaultPath, getConfig2 = () =>
14656
14666
  import * as fs15 from "fs";
14657
14667
  import * as path18 from "path";
14658
14668
  import { z as z6 } from "zod";
14659
- import { scanVaultEntities as scanVaultEntities2, getEntityIndexFromDb as getEntityIndexFromDb2 } from "@velvetmonkey/vault-core";
14669
+ import { scanVaultEntities as scanVaultEntities2, getEntityIndexFromDb as getEntityIndexFromDb2, getAllEntitiesFromDb as getAllEntitiesFromDb3 } from "@velvetmonkey/vault-core";
14660
14670
 
14661
14671
  // src/core/read/aliasSuggestions.ts
14662
14672
  import { STOPWORDS_EN as STOPWORDS_EN3 } from "@velvetmonkey/vault-core";
@@ -14726,6 +14736,10 @@ function suggestEntityAliases(stateDb2, folder) {
14726
14736
  // src/tools/read/system.ts
14727
14737
  init_edgeWeights();
14728
14738
  init_embeddings();
14739
+ init_wikilinks();
14740
+ init_wikilinkFeedback();
14741
+ init_recency();
14742
+ init_cooccurrence();
14729
14743
  function registerSystemTools(server2, getIndex, setIndex, getVaultPath, setConfig, getStateDb3) {
14730
14744
  const RefreshIndexOutputSchema = {
14731
14745
  success: z6.boolean().describe("Whether the refresh succeeded"),
@@ -14733,7 +14747,15 @@ function registerSystemTools(server2, getIndex, setIndex, getVaultPath, setConfi
14733
14747
  entities_count: z6.number().describe("Number of entities (titles + aliases)"),
14734
14748
  fts5_notes: z6.number().describe("Number of notes in FTS5 search index"),
14735
14749
  edges_recomputed: z6.number().optional().describe("Number of edges with recomputed weights"),
14750
+ hub_scores: z6.number().optional().describe("Number of hub scores exported"),
14751
+ graph_snapshot: z6.boolean().optional().describe("Whether graph topology snapshot was recorded"),
14752
+ suppression_list: z6.boolean().optional().describe("Whether wikilink suppression list was updated"),
14753
+ task_cache: z6.boolean().optional().describe("Whether task cache was refreshed"),
14736
14754
  embeddings_refreshed: z6.number().optional().describe("Number of note embeddings updated"),
14755
+ entity_embeddings_refreshed: z6.number().optional().describe("Number of entity embeddings updated"),
14756
+ recency_rebuilt: z6.boolean().optional().describe("Whether recency index was rebuilt"),
14757
+ cooccurrence_associations: z6.number().optional().describe("Number of co-occurrence associations rebuilt"),
14758
+ index_cached: z6.boolean().optional().describe("Whether vault index cache was saved"),
14737
14759
  duration_ms: z6.number().describe("Time taken to rebuild index")
14738
14760
  };
14739
14761
  server2.registerTool(
@@ -14747,90 +14769,224 @@ function registerSystemTools(server2, getIndex, setIndex, getVaultPath, setConfi
14747
14769
  async () => {
14748
14770
  const vaultPath2 = getVaultPath();
14749
14771
  const startTime = Date.now();
14772
+ const tracker = createStepTracker();
14750
14773
  setIndexState("building");
14751
14774
  setIndexError(null);
14752
14775
  try {
14776
+ tracker.start("vault_index", {});
14753
14777
  const newIndex = await buildVaultIndex(vaultPath2);
14754
14778
  setIndex(newIndex);
14755
14779
  setIndexState("ready");
14780
+ tracker.end({ notes: newIndex.notes.size, entities: newIndex.entities.size });
14756
14781
  const stateDb2 = getStateDb3?.();
14757
14782
  if (stateDb2) {
14783
+ tracker.start("entity_sync", {});
14758
14784
  try {
14759
14785
  const config = loadConfig(stateDb2);
14786
+ const excludeFolders = config.exclude_entity_folders?.length ? config.exclude_entity_folders : DEFAULT_ENTITY_EXCLUDE_FOLDERS;
14760
14787
  const entityIndex2 = await scanVaultEntities2(vaultPath2, {
14761
- excludeFolders: [
14762
- "daily-notes",
14763
- "daily",
14764
- "weekly",
14765
- "weekly-notes",
14766
- "monthly",
14767
- "monthly-notes",
14768
- "quarterly",
14769
- "yearly-notes",
14770
- "periodic",
14771
- "journal",
14772
- "inbox",
14773
- "templates",
14774
- "attachments",
14775
- "tmp",
14776
- "clippings",
14777
- "readwise",
14778
- "articles",
14779
- "bookmarks",
14780
- "web-clips"
14781
- ],
14788
+ excludeFolders,
14782
14789
  customCategories: config.custom_categories
14783
14790
  });
14784
14791
  stateDb2.replaceAllEntities(entityIndex2);
14792
+ tracker.end({ entities: entityIndex2._metadata.total_entities });
14785
14793
  console.error(`[Flywheel] Updated ${entityIndex2._metadata.total_entities} entities in StateDb`);
14786
14794
  } catch (e) {
14795
+ tracker.end({ error: String(e) });
14787
14796
  console.error("[Flywheel] Failed to update entities:", e);
14788
14797
  }
14789
14798
  }
14799
+ let flywheelConfig2;
14790
14800
  if (setConfig) {
14801
+ tracker.start("config_merge", {});
14791
14802
  const existing = loadConfig(stateDb2);
14792
14803
  const inferred = inferConfig(newIndex, vaultPath2);
14793
14804
  if (stateDb2) {
14794
14805
  saveConfig(stateDb2, inferred, existing);
14795
14806
  }
14796
- setConfig(loadConfig(stateDb2));
14807
+ flywheelConfig2 = loadConfig(stateDb2);
14808
+ setConfig(flywheelConfig2);
14809
+ tracker.end({});
14797
14810
  }
14798
14811
  let fts5Notes = 0;
14812
+ tracker.start("fts5_rebuild", {});
14799
14813
  try {
14800
14814
  const ftsState = await buildFTS5Index(vaultPath2);
14801
14815
  fts5Notes = ftsState.noteCount;
14816
+ tracker.end({ notes: fts5Notes });
14802
14817
  console.error(`[Flywheel] FTS5 index rebuilt: ${fts5Notes} notes`);
14803
14818
  } catch (err) {
14819
+ tracker.end({ error: String(err) });
14804
14820
  console.error("[Flywheel] FTS5 rebuild failed:", err);
14805
14821
  }
14806
14822
  let edgesRecomputed = 0;
14807
14823
  if (stateDb2) {
14824
+ tracker.start("edge_weights", {});
14808
14825
  try {
14809
14826
  const edgeResult = recomputeEdgeWeights(stateDb2);
14810
14827
  edgesRecomputed = edgeResult.edges_updated;
14828
+ tracker.end({ edges: edgeResult.edges_updated, duration_ms: edgeResult.duration_ms });
14811
14829
  console.error(`[Flywheel] Edge weights: ${edgeResult.edges_updated} edges in ${edgeResult.duration_ms}ms`);
14812
14830
  } catch (err) {
14831
+ tracker.end({ error: String(err) });
14813
14832
  console.error("[Flywheel] Edge weight recompute failed:", err);
14814
14833
  }
14815
14834
  }
14835
+ tracker.start("entity_index_init", {});
14836
+ try {
14837
+ await initializeEntityIndex(vaultPath2);
14838
+ tracker.end({});
14839
+ console.error("[Flywheel] Entity index initialized");
14840
+ } catch (err) {
14841
+ tracker.end({ error: String(err) });
14842
+ console.error("[Flywheel] Entity index init failed:", err);
14843
+ }
14844
+ let hubScoresExported = 0;
14845
+ tracker.start("hub_scores", {});
14846
+ try {
14847
+ hubScoresExported = await exportHubScores(newIndex, stateDb2);
14848
+ tracker.end({ exported: hubScoresExported });
14849
+ if (hubScoresExported > 0) {
14850
+ console.error(`[Flywheel] Hub scores: ${hubScoresExported} entities`);
14851
+ }
14852
+ } catch (err) {
14853
+ tracker.end({ error: String(err) });
14854
+ console.error("[Flywheel] Hub score export failed:", err);
14855
+ }
14856
+ let graphSnapshotRecorded = false;
14857
+ if (stateDb2) {
14858
+ tracker.start("graph_snapshot", {});
14859
+ try {
14860
+ const graphMetrics = computeGraphMetrics(newIndex);
14861
+ recordGraphSnapshot(stateDb2, graphMetrics);
14862
+ graphSnapshotRecorded = true;
14863
+ tracker.end({ recorded: true });
14864
+ } catch (err) {
14865
+ tracker.end({ error: String(err) });
14866
+ console.error("[Flywheel] Graph snapshot failed:", err);
14867
+ }
14868
+ }
14869
+ let suppressionUpdated = false;
14870
+ if (stateDb2) {
14871
+ tracker.start("suppression_list", {});
14872
+ try {
14873
+ updateSuppressionList(stateDb2);
14874
+ suppressionUpdated = true;
14875
+ tracker.end({ updated: true });
14876
+ } catch (err) {
14877
+ tracker.end({ error: String(err) });
14878
+ console.error("[Flywheel] Suppression list update failed:", err);
14879
+ }
14880
+ }
14881
+ let recencyRebuilt = false;
14882
+ if (stateDb2) {
14883
+ tracker.start("recency", {});
14884
+ try {
14885
+ const entities = getAllEntitiesFromDb3(stateDb2).map((e) => ({
14886
+ name: e.name,
14887
+ path: e.path,
14888
+ aliases: e.aliases
14889
+ }));
14890
+ const recencyIndex2 = await buildRecencyIndex(vaultPath2, entities);
14891
+ saveRecencyToStateDb(recencyIndex2, stateDb2);
14892
+ recencyRebuilt = true;
14893
+ tracker.end({ entities: recencyIndex2.lastMentioned.size });
14894
+ console.error(`[Flywheel] Recency: rebuilt ${recencyIndex2.lastMentioned.size} entities`);
14895
+ } catch (err) {
14896
+ tracker.end({ error: String(err) });
14897
+ console.error("[Flywheel] Recency rebuild failed:", err);
14898
+ }
14899
+ }
14900
+ let cooccurrenceAssociations;
14901
+ if (stateDb2) {
14902
+ tracker.start("cooccurrence", {});
14903
+ try {
14904
+ const entityNames = getAllEntitiesFromDb3(stateDb2).map((e) => e.name);
14905
+ const cooccurrenceIdx = await mineCooccurrences(vaultPath2, entityNames);
14906
+ setCooccurrenceIndex(cooccurrenceIdx);
14907
+ saveCooccurrenceToStateDb(stateDb2, cooccurrenceIdx);
14908
+ cooccurrenceAssociations = cooccurrenceIdx._metadata.total_associations;
14909
+ tracker.end({ associations: cooccurrenceAssociations });
14910
+ console.error(`[Flywheel] Co-occurrence: rebuilt ${cooccurrenceAssociations} associations`);
14911
+ } catch (err) {
14912
+ tracker.end({ error: String(err) });
14913
+ console.error("[Flywheel] Co-occurrence rebuild failed:", err);
14914
+ }
14915
+ }
14916
+ let taskCacheRefreshed = false;
14917
+ tracker.start("task_cache", {});
14918
+ try {
14919
+ if (!flywheelConfig2) {
14920
+ flywheelConfig2 = loadConfig(stateDb2);
14921
+ }
14922
+ await buildTaskCache(vaultPath2, newIndex, getExcludeTags(flywheelConfig2));
14923
+ taskCacheRefreshed = true;
14924
+ tracker.end({ rebuilt: true });
14925
+ console.error("[Flywheel] Task cache rebuilt");
14926
+ } catch (err) {
14927
+ tracker.end({ error: String(err) });
14928
+ console.error("[Flywheel] Task cache rebuild failed:", err);
14929
+ }
14816
14930
  let embeddingsRefreshed = 0;
14817
14931
  if (hasEmbeddingsIndex()) {
14932
+ tracker.start("embeddings_sync", {});
14818
14933
  try {
14819
14934
  const progress = await buildEmbeddingsIndex(vaultPath2);
14820
14935
  embeddingsRefreshed = progress.total - progress.skipped;
14936
+ tracker.end({ refreshed: embeddingsRefreshed });
14821
14937
  if (embeddingsRefreshed > 0) {
14822
14938
  console.error(`[Flywheel] Embeddings: ${embeddingsRefreshed} notes updated`);
14823
14939
  }
14824
14940
  } catch (err) {
14941
+ tracker.end({ error: String(err) });
14825
14942
  console.error("[Flywheel] Embedding sync failed:", err);
14826
14943
  }
14827
14944
  }
14945
+ let entityEmbeddingsRefreshed = 0;
14946
+ if (stateDb2 && hasEntityEmbeddingsIndex()) {
14947
+ tracker.start("entity_embeddings", {});
14948
+ try {
14949
+ const entities = getAllEntitiesFromDb3(stateDb2);
14950
+ if (entities.length > 0) {
14951
+ const entityMap = new Map(entities.map((e) => [e.name, {
14952
+ name: e.name,
14953
+ path: e.path,
14954
+ category: e.category,
14955
+ aliases: e.aliases
14956
+ }]));
14957
+ entityEmbeddingsRefreshed = await buildEntityEmbeddingsIndex(vaultPath2, entityMap);
14958
+ loadEntityEmbeddingsToMemory();
14959
+ tracker.end({ refreshed: entityEmbeddingsRefreshed });
14960
+ if (entityEmbeddingsRefreshed > 0) {
14961
+ console.error(`[Flywheel] Entity embeddings: ${entityEmbeddingsRefreshed} updated`);
14962
+ }
14963
+ } else {
14964
+ tracker.end({ refreshed: 0 });
14965
+ }
14966
+ } catch (err) {
14967
+ tracker.end({ error: String(err) });
14968
+ console.error("[Flywheel] Entity embedding sync failed:", err);
14969
+ }
14970
+ }
14971
+ let indexCached = false;
14972
+ if (stateDb2) {
14973
+ tracker.start("index_cache", {});
14974
+ try {
14975
+ saveVaultIndexToCache(stateDb2, newIndex);
14976
+ indexCached = true;
14977
+ tracker.end({ cached: true });
14978
+ } catch (err) {
14979
+ tracker.end({ error: String(err) });
14980
+ console.error("[Flywheel] Index cache save failed:", err);
14981
+ }
14982
+ }
14828
14983
  const duration = Date.now() - startTime;
14829
14984
  if (stateDb2) {
14830
14985
  recordIndexEvent(stateDb2, {
14831
14986
  trigger: "manual_refresh",
14832
14987
  duration_ms: duration,
14833
- note_count: newIndex.notes.size
14988
+ note_count: newIndex.notes.size,
14989
+ steps: tracker.steps
14834
14990
  });
14835
14991
  }
14836
14992
  const output = {
@@ -14839,7 +14995,15 @@ function registerSystemTools(server2, getIndex, setIndex, getVaultPath, setConfi
14839
14995
  entities_count: newIndex.entities.size,
14840
14996
  fts5_notes: fts5Notes,
14841
14997
  edges_recomputed: edgesRecomputed,
14998
+ hub_scores: hubScoresExported || void 0,
14999
+ graph_snapshot: graphSnapshotRecorded || void 0,
15000
+ suppression_list: suppressionUpdated || void 0,
15001
+ task_cache: taskCacheRefreshed || void 0,
14842
15002
  embeddings_refreshed: embeddingsRefreshed || void 0,
15003
+ entity_embeddings_refreshed: entityEmbeddingsRefreshed || void 0,
15004
+ recency_rebuilt: recencyRebuilt || void 0,
15005
+ cooccurrence_associations: cooccurrenceAssociations,
15006
+ index_cached: indexCached || void 0,
14843
15007
  duration_ms: duration
14844
15008
  };
14845
15009
  return {
@@ -22728,7 +22892,7 @@ function registerSimilarityTools(server2, getIndex, getVaultPath, getStateDb3) {
22728
22892
  // src/tools/read/semantic.ts
22729
22893
  init_embeddings();
22730
22894
  import { z as z32 } from "zod";
22731
- import { getAllEntitiesFromDb as getAllEntitiesFromDb3 } from "@velvetmonkey/vault-core";
22895
+ import { getAllEntitiesFromDb as getAllEntitiesFromDb4 } from "@velvetmonkey/vault-core";
22732
22896
  function registerSemanticTools(server2, getVaultPath, getStateDb3) {
22733
22897
  server2.registerTool(
22734
22898
  "init_semantic",
@@ -22792,7 +22956,7 @@ function registerSemanticTools(server2, getVaultPath, getStateDb3) {
22792
22956
  const embedded = progress.total - progress.skipped;
22793
22957
  let entityEmbedded = 0;
22794
22958
  try {
22795
- const allEntities = getAllEntitiesFromDb3(stateDb2);
22959
+ const allEntities = getAllEntitiesFromDb4(stateDb2);
22796
22960
  const entityMap = /* @__PURE__ */ new Map();
22797
22961
  for (const e of allEntities) {
22798
22962
  entityMap.set(e.name, {
@@ -22844,7 +23008,7 @@ function registerSemanticTools(server2, getVaultPath, getStateDb3) {
22844
23008
  // src/tools/read/merges.ts
22845
23009
  init_levenshtein();
22846
23010
  import { z as z33 } from "zod";
22847
- import { getAllEntitiesFromDb as getAllEntitiesFromDb4, getDismissedMergePairs, recordMergeDismissal } from "@velvetmonkey/vault-core";
23011
+ import { getAllEntitiesFromDb as getAllEntitiesFromDb5, getDismissedMergePairs, recordMergeDismissal } from "@velvetmonkey/vault-core";
22848
23012
  function normalizeName(name) {
22849
23013
  return name.toLowerCase().replace(/[.\-_]/g, "").replace(/js$/, "").replace(/ts$/, "");
22850
23014
  }
@@ -22862,7 +23026,7 @@ function registerMergeTools2(server2, getStateDb3) {
22862
23026
  content: [{ type: "text", text: JSON.stringify({ suggestions: [], error: "StateDb not available" }) }]
22863
23027
  };
22864
23028
  }
22865
- const entities = getAllEntitiesFromDb4(stateDb2);
23029
+ const entities = getAllEntitiesFromDb5(stateDb2);
22866
23030
  if (entities.length === 0) {
22867
23031
  return {
22868
23032
  content: [{ type: "text", text: JSON.stringify({ suggestions: [] }) }]
@@ -25122,7 +25286,6 @@ async function main() {
25122
25286
  })();
25123
25287
  }
25124
25288
  }
25125
- var DEFAULT_ENTITY_EXCLUDE_FOLDERS = ["node_modules", "templates", "attachments", "tmp"];
25126
25289
  async function updateEntitiesInStateDb(vp, sd) {
25127
25290
  const db4 = sd ?? stateDb;
25128
25291
  const vault = vp ?? vaultPath;
@@ -25293,7 +25456,7 @@ async function runPostIndexWork(ctx) {
25293
25456
  }
25294
25457
  });
25295
25458
  if (sd) {
25296
- const entities = getAllEntitiesFromDb5(sd);
25459
+ const entities = getAllEntitiesFromDb6(sd);
25297
25460
  if (entities.length > 0) {
25298
25461
  const entityMap = new Map(entities.map((e) => [e.name, {
25299
25462
  name: e.name,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@velvetmonkey/flywheel-memory",
3
- "version": "2.0.155",
3
+ "version": "2.0.156",
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",
@@ -54,7 +54,7 @@
54
54
  "dependencies": {
55
55
  "@huggingface/transformers": "^3.8.1",
56
56
  "@modelcontextprotocol/sdk": "^1.25.1",
57
- "@velvetmonkey/vault-core": "^2.0.155",
57
+ "@velvetmonkey/vault-core": "^2.0.156",
58
58
  "better-sqlite3": "^12.0.0",
59
59
  "chokidar": "^4.0.0",
60
60
  "gray-matter": "^4.0.3",