@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.
- package/dist/index.js +46 -74
- 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
|
|
352
|
-
if (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
|
|
377
|
-
if (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
|
|
402
|
-
if (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 (
|
|
14904
|
-
|
|
14905
|
-
|
|
14906
|
-
|
|
14907
|
-
|
|
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
|
|
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 (
|
|
15049
|
-
|
|
15050
|
-
|
|
15051
|
-
|
|
15052
|
-
|
|
15053
|
-
|
|
15054
|
-
|
|
15055
|
-
|
|
15056
|
-
|
|
15057
|
-
|
|
15058
|
-
|
|
15059
|
-
|
|
15060
|
-
|
|
15061
|
-
|
|
15062
|
-
|
|
15063
|
-
|
|
15064
|
-
|
|
15065
|
-
|
|
15066
|
-
|
|
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
|
-
|
|
15070
|
-
|
|
15071
|
-
|
|
15072
|
-
|
|
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.
|
|
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.
|
|
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",
|