@velvetmonkey/flywheel-memory 2.0.24 → 2.0.26

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 +46 -74
  2. package/package.json +2 -2
package/dist/index.js CHANGED
@@ -168,24 +168,6 @@ function findSection(content, sectionName) {
168
168
  contentStartLine
169
169
  };
170
170
  }
171
- function isInsideCodeBlock(lines, currentIndex) {
172
- let fenceCount = 0;
173
- for (let i = 0; i < currentIndex; i++) {
174
- if (lines[i].trim().startsWith("```")) {
175
- fenceCount++;
176
- }
177
- }
178
- return fenceCount % 2 === 1;
179
- }
180
- function isStructuredLine(line) {
181
- const trimmed = line.trimStart();
182
- return trimmed.startsWith("|") || // Table row
183
- trimmed.startsWith(">") || // Blockquote
184
- trimmed.startsWith("```") || // Code fence
185
- /^-{3,}$/.test(trimmed) || // Horizontal rule (dashes)
186
- /^\*{3,}$/.test(trimmed) || // Horizontal rule (asterisks)
187
- /^_{3,}$/.test(trimmed);
188
- }
189
171
  function isPreformattedList(content) {
190
172
  const trimmed = content.trim();
191
173
  if (!trimmed) return false;
@@ -223,9 +205,6 @@ function formatContent(content, format) {
223
205
  return lines.map((line, i) => {
224
206
  if (i === 0) return `- ${line}`;
225
207
  if (line === "") return "";
226
- if (isInsideCodeBlock(lines, i) || isStructuredLine(line)) {
227
- return line;
228
- }
229
208
  return ` ${line}`;
230
209
  }).join("\n");
231
210
  }
@@ -237,9 +216,6 @@ function formatContent(content, format) {
237
216
  return lines.map((line, i) => {
238
217
  if (i === 0) return `- [ ] ${line}`;
239
218
  if (line === "") return "";
240
- if (isInsideCodeBlock(lines, i) || isStructuredLine(line)) {
241
- return line;
242
- }
243
219
  return ` ${line}`;
244
220
  }).join("\n");
245
221
  }
@@ -251,9 +227,6 @@ function formatContent(content, format) {
251
227
  return lines.map((line, i) => {
252
228
  if (i === 0) return `1. ${line}`;
253
229
  if (line === "") return "";
254
- if (isInsideCodeBlock(lines, i) || isStructuredLine(line)) {
255
- return line;
256
- }
257
230
  return ` ${line}`;
258
231
  }).join("\n");
259
232
  }
@@ -270,9 +243,6 @@ function formatContent(content, format) {
270
243
  return lines.map((line, i) => {
271
244
  if (i === 0) return `${prefix}${line}`;
272
245
  if (line === "") return "";
273
- if (isInsideCodeBlock(lines, i) || isStructuredLine(line)) {
274
- return line;
275
- }
276
246
  return `${indent}${line}`;
277
247
  }).join("\n");
278
248
  }
@@ -348,10 +318,8 @@ function insertInSection(content, section, newContent, position, options) {
348
318
  const indent = detectSectionBaseIndentation(lines, section.contentStartLine, section.endLine);
349
319
  if (indent) {
350
320
  const contentLines = formattedContent.split("\n");
351
- const indentedContent = contentLines.map((line, i) => {
352
- if (line === "" || isInsideCodeBlock(contentLines, i) || isStructuredLine(line)) {
353
- return line;
354
- }
321
+ const indentedContent = contentLines.map((line) => {
322
+ if (line === "") return line;
355
323
  return indent + line;
356
324
  }).join("\n");
357
325
  lines.splice(section.contentStartLine, 0, indentedContent);
@@ -373,10 +341,8 @@ function insertInSection(content, section, newContent, position, options) {
373
341
  if (options?.preserveListNesting) {
374
342
  const indent = detectSectionBaseIndentation(lines, section.contentStartLine, section.endLine);
375
343
  const contentLines = formattedContent.split("\n");
376
- const indentedContent = contentLines.map((line, i) => {
377
- if (line === "" || isInsideCodeBlock(contentLines, i) || isStructuredLine(line)) {
378
- return line;
379
- }
344
+ const indentedContent = contentLines.map((line) => {
345
+ if (line === "") return line;
380
346
  return indent + line;
381
347
  }).join("\n");
382
348
  lines[lastContentLineIdx] = indentedContent;
@@ -398,10 +364,8 @@ function insertInSection(content, section, newContent, position, options) {
398
364
  if (options?.preserveListNesting) {
399
365
  const indent = detectSectionBaseIndentation(lines, section.contentStartLine, section.endLine);
400
366
  const contentLines = formattedContent.split("\n");
401
- const indentedContent = contentLines.map((line, i) => {
402
- if (line === "" || isInsideCodeBlock(contentLines, i) || isStructuredLine(line)) {
403
- return line;
404
- }
367
+ const indentedContent = contentLines.map((line) => {
368
+ if (line === "") return line;
405
369
  return indent + line;
406
370
  }).join("\n");
407
371
  lines.splice(insertLine, 0, indentedContent);
@@ -14900,14 +14864,18 @@ async function main() {
14900
14864
  initializeLogger2(vaultPath).catch((err) => {
14901
14865
  console.error(`[Memory] Write logger initialization failed: ${err}`);
14902
14866
  });
14903
- if (isIndexStale(vaultPath)) {
14904
- buildFTS5Index(vaultPath).then(() => {
14905
- console.error("[Memory] FTS5 search index ready");
14906
- }).catch((err) => {
14907
- console.error("[Memory] FTS5 build failed:", err);
14908
- });
14867
+ if (process.env.FLYWHEEL_SKIP_FTS5 !== "true") {
14868
+ if (isIndexStale(vaultPath)) {
14869
+ buildFTS5Index(vaultPath).then(() => {
14870
+ console.error("[Memory] FTS5 search index ready");
14871
+ }).catch((err) => {
14872
+ console.error("[Memory] FTS5 build failed:", err);
14873
+ });
14874
+ } else {
14875
+ console.error("[Memory] FTS5 search index already fresh, skipping rebuild");
14876
+ }
14909
14877
  } else {
14910
- console.error("[Memory] FTS5 search index already fresh, skipping rebuild");
14878
+ console.error("[Memory] FTS5 indexing skipped (FLYWHEEL_SKIP_FTS5=true)");
14911
14879
  }
14912
14880
  let cachedIndex = null;
14913
14881
  if (stateDb) {
@@ -15045,32 +15013,36 @@ async function runPostIndexWork(index) {
15045
15013
  if (flywheelConfig.vault_name) {
15046
15014
  console.error(`[Memory] Vault: ${flywheelConfig.vault_name}`);
15047
15015
  }
15048
- if (hasEmbeddingsIndex()) {
15049
- console.error("[Memory] Embeddings already built, skipping full scan");
15050
- } else {
15051
- setEmbeddingsBuilding(true);
15052
- buildEmbeddingsIndex(vaultPath, (p) => {
15053
- if (p.current % 100 === 0 || p.current === p.total) {
15054
- console.error(`[Semantic] ${p.current}/${p.total}`);
15055
- }
15056
- }).then(async () => {
15057
- if (stateDb) {
15058
- const entities = getAllEntitiesFromDb2(stateDb);
15059
- if (entities.length > 0) {
15060
- const entityMap = new Map(entities.map((e) => [e.name, {
15061
- name: e.name,
15062
- path: e.path,
15063
- category: e.category,
15064
- aliases: e.aliases
15065
- }]));
15066
- await buildEntityEmbeddingsIndex(vaultPath, entityMap);
15016
+ if (process.env.FLYWHEEL_SKIP_EMBEDDINGS !== "true") {
15017
+ if (hasEmbeddingsIndex()) {
15018
+ console.error("[Memory] Embeddings already built, skipping full scan");
15019
+ } else {
15020
+ setEmbeddingsBuilding(true);
15021
+ buildEmbeddingsIndex(vaultPath, (p) => {
15022
+ if (p.current % 100 === 0 || p.current === p.total) {
15023
+ console.error(`[Semantic] ${p.current}/${p.total}`);
15024
+ }
15025
+ }).then(async () => {
15026
+ if (stateDb) {
15027
+ const entities = getAllEntitiesFromDb2(stateDb);
15028
+ if (entities.length > 0) {
15029
+ const entityMap = new Map(entities.map((e) => [e.name, {
15030
+ name: e.name,
15031
+ path: e.path,
15032
+ category: e.category,
15033
+ aliases: e.aliases
15034
+ }]));
15035
+ await buildEntityEmbeddingsIndex(vaultPath, entityMap);
15036
+ }
15067
15037
  }
15068
- }
15069
- loadEntityEmbeddingsToMemory();
15070
- console.error("[Memory] Embeddings refreshed");
15071
- }).catch((err) => {
15072
- console.error("[Memory] Embeddings refresh failed:", err);
15073
- });
15038
+ loadEntityEmbeddingsToMemory();
15039
+ console.error("[Memory] Embeddings refreshed");
15040
+ }).catch((err) => {
15041
+ console.error("[Memory] Embeddings refresh failed:", err);
15042
+ });
15043
+ }
15044
+ } else {
15045
+ console.error("[Memory] Embeddings skipped (FLYWHEEL_SKIP_EMBEDDINGS=true)");
15074
15046
  }
15075
15047
  if (process.env.FLYWHEEL_WATCH !== "false") {
15076
15048
  const config = parseWatcherConfig();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@velvetmonkey/flywheel-memory",
3
- "version": "2.0.24",
3
+ "version": "2.0.26",
4
4
  "description": "MCP server that gives Claude full read/write access to your Obsidian vault. 42 tools for search, backlinks, graph queries, mutations, and hybrid semantic search.",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
@@ -50,7 +50,7 @@
50
50
  },
51
51
  "dependencies": {
52
52
  "@modelcontextprotocol/sdk": "^1.25.1",
53
- "@velvetmonkey/vault-core": "^2.0.24",
53
+ "@velvetmonkey/vault-core": "^2.0.26",
54
54
  "better-sqlite3": "^11.0.0",
55
55
  "chokidar": "^4.0.0",
56
56
  "gray-matter": "^4.0.3",