@velvetmonkey/flywheel-memory 2.0.31 → 2.0.32
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 +45 -6
- package/package.json +2 -2
package/dist/index.js
CHANGED
|
@@ -3216,6 +3216,7 @@ import {
|
|
|
3216
3216
|
getEntityAliases,
|
|
3217
3217
|
applyWikilinks,
|
|
3218
3218
|
resolveAliasWikilinks,
|
|
3219
|
+
detectImplicitEntities,
|
|
3219
3220
|
getEntityIndexFromDb,
|
|
3220
3221
|
getStateDbMetadata,
|
|
3221
3222
|
getEntityByName,
|
|
@@ -5060,6 +5061,42 @@ function processWikilinks(content, notePath) {
|
|
|
5060
5061
|
firstOccurrenceOnly: true,
|
|
5061
5062
|
caseInsensitive: true
|
|
5062
5063
|
});
|
|
5064
|
+
const implicitMatches = detectImplicitEntities(result.content, {
|
|
5065
|
+
detectImplicit: true,
|
|
5066
|
+
implicitPatterns: ["proper-nouns", "single-caps", "quoted-terms", "camel-case", "acronyms"],
|
|
5067
|
+
minEntityLength: 3
|
|
5068
|
+
});
|
|
5069
|
+
const alreadyLinked = new Set(
|
|
5070
|
+
[...resolved.linkedEntities, ...result.linkedEntities].map((e) => e.toLowerCase())
|
|
5071
|
+
);
|
|
5072
|
+
for (const entity of sortedEntities) {
|
|
5073
|
+
const name = getEntityName2(entity);
|
|
5074
|
+
alreadyLinked.add(name.toLowerCase());
|
|
5075
|
+
const aliases = getEntityAliases(entity);
|
|
5076
|
+
for (const alias of aliases) {
|
|
5077
|
+
alreadyLinked.add(alias.toLowerCase());
|
|
5078
|
+
}
|
|
5079
|
+
}
|
|
5080
|
+
const currentNoteName = notePath ? notePath.replace(/\.md$/, "").split("/").pop()?.toLowerCase() : null;
|
|
5081
|
+
const newImplicits = implicitMatches.filter((m) => {
|
|
5082
|
+
const normalized = m.text.toLowerCase();
|
|
5083
|
+
if (alreadyLinked.has(normalized)) return false;
|
|
5084
|
+
if (currentNoteName && normalized === currentNoteName) return false;
|
|
5085
|
+
return true;
|
|
5086
|
+
});
|
|
5087
|
+
if (newImplicits.length > 0) {
|
|
5088
|
+
let processedContent = result.content;
|
|
5089
|
+
for (let i = newImplicits.length - 1; i >= 0; i--) {
|
|
5090
|
+
const m = newImplicits[i];
|
|
5091
|
+
processedContent = processedContent.slice(0, m.start) + `[[${m.text}]]` + processedContent.slice(m.end);
|
|
5092
|
+
}
|
|
5093
|
+
return {
|
|
5094
|
+
content: processedContent,
|
|
5095
|
+
linksAdded: resolved.linksAdded + result.linksAdded + newImplicits.length,
|
|
5096
|
+
linkedEntities: [...resolved.linkedEntities, ...result.linkedEntities],
|
|
5097
|
+
implicitEntities: newImplicits.map((m) => m.text)
|
|
5098
|
+
};
|
|
5099
|
+
}
|
|
5063
5100
|
return {
|
|
5064
5101
|
content: result.content,
|
|
5065
5102
|
linksAdded: resolved.linksAdded + result.linksAdded,
|
|
@@ -5076,9 +5113,11 @@ function maybeApplyWikilinks(content, skipWikilinks, notePath) {
|
|
|
5076
5113
|
if (moduleStateDb4 && notePath) {
|
|
5077
5114
|
trackWikilinkApplications(moduleStateDb4, notePath, result.linkedEntities);
|
|
5078
5115
|
}
|
|
5116
|
+
const implicitCount = result.implicitEntities?.length ?? 0;
|
|
5117
|
+
const implicitInfo = implicitCount > 0 ? ` + ${implicitCount} implicit: ${result.implicitEntities.join(", ")}` : "";
|
|
5079
5118
|
return {
|
|
5080
5119
|
content: result.content,
|
|
5081
|
-
wikilinkInfo: `Applied ${result.linksAdded} wikilink(s): ${result.linkedEntities.join(", ")}`
|
|
5120
|
+
wikilinkInfo: `Applied ${result.linksAdded} wikilink(s): ${result.linkedEntities.join(", ")}${implicitInfo}`
|
|
5082
5121
|
};
|
|
5083
5122
|
}
|
|
5084
5123
|
return { content: result.content };
|
|
@@ -7535,7 +7574,7 @@ function registerHealthTools(server2, getIndex, getVaultPath, getConfig = () =>
|
|
|
7535
7574
|
recommendations.push(`Index is ${Math.floor(indexAge / 60)} minutes old. Consider running refresh_index.`);
|
|
7536
7575
|
}
|
|
7537
7576
|
const noteCount = indexBuilt ? index.notes.size : 0;
|
|
7538
|
-
const
|
|
7577
|
+
const entityCount = indexBuilt ? index.entities.size : 0;
|
|
7539
7578
|
const tagCount = indexBuilt ? index.tags.size : 0;
|
|
7540
7579
|
let linkCount = 0;
|
|
7541
7580
|
if (indexBuilt) {
|
|
@@ -7615,7 +7654,7 @@ function registerHealthTools(server2, getIndex, getVaultPath, getConfig = () =>
|
|
|
7615
7654
|
index_age_seconds: indexAge,
|
|
7616
7655
|
index_stale: indexStale,
|
|
7617
7656
|
note_count: noteCount,
|
|
7618
|
-
entity_count:
|
|
7657
|
+
entity_count: entityCount,
|
|
7619
7658
|
tag_count: tagCount,
|
|
7620
7659
|
link_count: linkCount,
|
|
7621
7660
|
periodic_notes: periodicNotes && periodicNotes.length > 0 ? periodicNotes : void 0,
|
|
@@ -14544,7 +14583,7 @@ function computeMetrics(index, stateDb2) {
|
|
|
14544
14583
|
}
|
|
14545
14584
|
}
|
|
14546
14585
|
const tagCount = index.tags.size;
|
|
14547
|
-
const
|
|
14586
|
+
const entityCount = index.entities.size;
|
|
14548
14587
|
const avgLinksPerNote = noteCount > 0 ? linkCount / noteCount : 0;
|
|
14549
14588
|
const possibleLinks = noteCount * (noteCount - 1);
|
|
14550
14589
|
const linkDensity = possibleLinks > 0 ? linkCount / possibleLinks : 0;
|
|
@@ -14566,7 +14605,7 @@ function computeMetrics(index, stateDb2) {
|
|
|
14566
14605
|
link_count: linkCount,
|
|
14567
14606
|
orphan_count: orphanCount,
|
|
14568
14607
|
tag_count: tagCount,
|
|
14569
|
-
entity_count:
|
|
14608
|
+
entity_count: entityCount,
|
|
14570
14609
|
avg_links_per_note: Math.round(avgLinksPerNote * 100) / 100,
|
|
14571
14610
|
link_density: Math.round(linkDensity * 1e4) / 1e4,
|
|
14572
14611
|
connected_ratio: Math.round(connectedRatio * 1e3) / 1e3,
|
|
@@ -16138,7 +16177,7 @@ async function runPostIndexWork(index) {
|
|
|
16138
16177
|
const entityDiff = computeEntityDiff(entitiesBefore, entitiesAfter);
|
|
16139
16178
|
tracker.end({ entity_count: entitiesAfter.length, ...entityDiff });
|
|
16140
16179
|
serverLog("watcher", `Entity scan: ${entitiesAfter.length} entities`);
|
|
16141
|
-
tracker.start("hub_scores", { entity_count:
|
|
16180
|
+
tracker.start("hub_scores", { entity_count: entitiesAfter.length });
|
|
16142
16181
|
const hubUpdated = await exportHubScores(vaultIndex, stateDb);
|
|
16143
16182
|
tracker.end({ updated: hubUpdated ?? 0 });
|
|
16144
16183
|
serverLog("watcher", `Hub scores: ${hubUpdated ?? 0} updated`);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@velvetmonkey/flywheel-memory",
|
|
3
|
-
"version": "2.0.
|
|
3
|
+
"version": "2.0.32",
|
|
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.32",
|
|
54
54
|
"better-sqlite3": "^11.0.0",
|
|
55
55
|
"chokidar": "^4.0.0",
|
|
56
56
|
"gray-matter": "^4.0.3",
|