@velvetmonkey/flywheel-memory 2.0.52 → 2.0.54
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 +82 -56
- package/package.json +2 -2
package/dist/index.js
CHANGED
|
@@ -4192,6 +4192,75 @@ function getExtendedDashboardData(stateDb2) {
|
|
|
4192
4192
|
};
|
|
4193
4193
|
}
|
|
4194
4194
|
|
|
4195
|
+
// src/core/write/corrections.ts
|
|
4196
|
+
function recordCorrection(stateDb2, type, description, source = "user", entity, notePath) {
|
|
4197
|
+
const result = stateDb2.db.prepare(`
|
|
4198
|
+
INSERT INTO corrections (entity, note_path, correction_type, description, source)
|
|
4199
|
+
VALUES (?, ?, ?, ?, ?)
|
|
4200
|
+
`).run(entity ?? null, notePath ?? null, type, description, source);
|
|
4201
|
+
return stateDb2.db.prepare(
|
|
4202
|
+
"SELECT * FROM corrections WHERE id = ?"
|
|
4203
|
+
).get(result.lastInsertRowid);
|
|
4204
|
+
}
|
|
4205
|
+
function listCorrections(stateDb2, status, entity, limit = 50) {
|
|
4206
|
+
const conditions = [];
|
|
4207
|
+
const params = [];
|
|
4208
|
+
if (status) {
|
|
4209
|
+
conditions.push("status = ?");
|
|
4210
|
+
params.push(status);
|
|
4211
|
+
}
|
|
4212
|
+
if (entity) {
|
|
4213
|
+
conditions.push("entity = ? COLLATE NOCASE");
|
|
4214
|
+
params.push(entity);
|
|
4215
|
+
}
|
|
4216
|
+
const where = conditions.length > 0 ? `WHERE ${conditions.join(" AND ")}` : "";
|
|
4217
|
+
params.push(limit);
|
|
4218
|
+
return stateDb2.db.prepare(
|
|
4219
|
+
`SELECT * FROM corrections ${where} ORDER BY created_at DESC LIMIT ?`
|
|
4220
|
+
).all(...params);
|
|
4221
|
+
}
|
|
4222
|
+
function resolveCorrection(stateDb2, id, newStatus) {
|
|
4223
|
+
const result = stateDb2.db.prepare(`
|
|
4224
|
+
UPDATE corrections
|
|
4225
|
+
SET status = ?, resolved_at = datetime('now')
|
|
4226
|
+
WHERE id = ?
|
|
4227
|
+
`).run(newStatus, id);
|
|
4228
|
+
return result.changes > 0;
|
|
4229
|
+
}
|
|
4230
|
+
function getCorrectedEntityNotePairs(stateDb2) {
|
|
4231
|
+
const rows = stateDb2.db.prepare(`
|
|
4232
|
+
SELECT entity, note_path FROM corrections
|
|
4233
|
+
WHERE correction_type = 'wrong_link'
|
|
4234
|
+
AND entity IS NOT NULL AND note_path IS NOT NULL
|
|
4235
|
+
AND status IN ('pending', 'applied')
|
|
4236
|
+
`).all();
|
|
4237
|
+
const map = /* @__PURE__ */ new Map();
|
|
4238
|
+
for (const row of rows) {
|
|
4239
|
+
const key = row.entity.toLowerCase();
|
|
4240
|
+
if (!map.has(key)) map.set(key, /* @__PURE__ */ new Set());
|
|
4241
|
+
map.get(key).add(row.note_path);
|
|
4242
|
+
}
|
|
4243
|
+
return map;
|
|
4244
|
+
}
|
|
4245
|
+
function processPendingCorrections(stateDb2) {
|
|
4246
|
+
const pending = listCorrections(stateDb2, "pending");
|
|
4247
|
+
let processed = 0;
|
|
4248
|
+
for (const correction of pending) {
|
|
4249
|
+
if (!correction.entity) {
|
|
4250
|
+
resolveCorrection(stateDb2, correction.id, "dismissed");
|
|
4251
|
+
continue;
|
|
4252
|
+
}
|
|
4253
|
+
if (correction.correction_type === "wrong_link") {
|
|
4254
|
+
recordFeedback(stateDb2, correction.entity, "correction:wrong_link", correction.note_path || "", false, 1);
|
|
4255
|
+
} else if (correction.correction_type === "wrong_category") {
|
|
4256
|
+
recordFeedback(stateDb2, correction.entity, "correction:wrong_category", "", false, 0.5);
|
|
4257
|
+
}
|
|
4258
|
+
resolveCorrection(stateDb2, correction.id, "applied");
|
|
4259
|
+
processed++;
|
|
4260
|
+
}
|
|
4261
|
+
return processed;
|
|
4262
|
+
}
|
|
4263
|
+
|
|
4195
4264
|
// src/core/write/git.ts
|
|
4196
4265
|
import { simpleGit, CheckRepoActions } from "simple-git";
|
|
4197
4266
|
import path8 from "path";
|
|
@@ -5986,6 +6055,14 @@ function processWikilinks(content, notePath, existingContent) {
|
|
|
5986
6055
|
return !isSuppressed(moduleStateDb5, name, folder);
|
|
5987
6056
|
});
|
|
5988
6057
|
}
|
|
6058
|
+
if (moduleStateDb5 && notePath) {
|
|
6059
|
+
const correctedPairs = getCorrectedEntityNotePairs(moduleStateDb5);
|
|
6060
|
+
entities = entities.filter((e) => {
|
|
6061
|
+
const name = getEntityName2(e).toLowerCase();
|
|
6062
|
+
const paths = correctedPairs.get(name);
|
|
6063
|
+
return !paths || !paths.has(notePath);
|
|
6064
|
+
});
|
|
6065
|
+
}
|
|
5989
6066
|
const sortedEntities = sortEntitiesByPriority(entities, notePath);
|
|
5990
6067
|
const resolved = resolveAliasWikilinks(content, sortedEntities, {
|
|
5991
6068
|
caseInsensitive: true
|
|
@@ -6470,6 +6547,7 @@ async function suggestRelatedLinks(content, options = {}) {
|
|
|
6470
6547
|
const noteFolder = notePath ? notePath.split("/")[0] : void 0;
|
|
6471
6548
|
const feedbackBoosts = moduleStateDb5 ? getAllFeedbackBoosts(moduleStateDb5, noteFolder) : /* @__PURE__ */ new Map();
|
|
6472
6549
|
const suppressionPenalties = moduleStateDb5 ? getAllSuppressionPenalties(moduleStateDb5) : /* @__PURE__ */ new Map();
|
|
6550
|
+
const correctedPairs = moduleStateDb5 ? getCorrectedEntityNotePairs(moduleStateDb5) : /* @__PURE__ */ new Map();
|
|
6473
6551
|
const edgeWeightMap = moduleStateDb5 ? getEntityEdgeWeightMap(moduleStateDb5) : /* @__PURE__ */ new Map();
|
|
6474
6552
|
const scoredEntities = [];
|
|
6475
6553
|
const directlyMatchedEntities = /* @__PURE__ */ new Set();
|
|
@@ -6486,6 +6564,10 @@ async function suggestRelatedLinks(content, options = {}) {
|
|
|
6486
6564
|
if (linkedEntities.has(entityName.toLowerCase())) {
|
|
6487
6565
|
continue;
|
|
6488
6566
|
}
|
|
6567
|
+
if (notePath && correctedPairs.has(entityName.toLowerCase())) {
|
|
6568
|
+
const paths = correctedPairs.get(entityName.toLowerCase());
|
|
6569
|
+
if (paths.has(notePath)) continue;
|
|
6570
|
+
}
|
|
6489
6571
|
const contentScore = disabled.has("exact_match") && disabled.has("stem_match") ? 0 : scoreEntity(entity, contentTokens, contentStems, config, cooccurrenceIndex);
|
|
6490
6572
|
let score = contentScore;
|
|
6491
6573
|
if (contentScore > 0) {
|
|
@@ -16352,62 +16434,6 @@ function registerWikilinkFeedbackTools(server2, getStateDb) {
|
|
|
16352
16434
|
|
|
16353
16435
|
// src/tools/write/corrections.ts
|
|
16354
16436
|
import { z as z22 } from "zod";
|
|
16355
|
-
|
|
16356
|
-
// src/core/write/corrections.ts
|
|
16357
|
-
function recordCorrection(stateDb2, type, description, source = "user", entity, notePath) {
|
|
16358
|
-
const result = stateDb2.db.prepare(`
|
|
16359
|
-
INSERT INTO corrections (entity, note_path, correction_type, description, source)
|
|
16360
|
-
VALUES (?, ?, ?, ?, ?)
|
|
16361
|
-
`).run(entity ?? null, notePath ?? null, type, description, source);
|
|
16362
|
-
return stateDb2.db.prepare(
|
|
16363
|
-
"SELECT * FROM corrections WHERE id = ?"
|
|
16364
|
-
).get(result.lastInsertRowid);
|
|
16365
|
-
}
|
|
16366
|
-
function listCorrections(stateDb2, status, entity, limit = 50) {
|
|
16367
|
-
const conditions = [];
|
|
16368
|
-
const params = [];
|
|
16369
|
-
if (status) {
|
|
16370
|
-
conditions.push("status = ?");
|
|
16371
|
-
params.push(status);
|
|
16372
|
-
}
|
|
16373
|
-
if (entity) {
|
|
16374
|
-
conditions.push("entity = ? COLLATE NOCASE");
|
|
16375
|
-
params.push(entity);
|
|
16376
|
-
}
|
|
16377
|
-
const where = conditions.length > 0 ? `WHERE ${conditions.join(" AND ")}` : "";
|
|
16378
|
-
params.push(limit);
|
|
16379
|
-
return stateDb2.db.prepare(
|
|
16380
|
-
`SELECT * FROM corrections ${where} ORDER BY created_at DESC LIMIT ?`
|
|
16381
|
-
).all(...params);
|
|
16382
|
-
}
|
|
16383
|
-
function resolveCorrection(stateDb2, id, newStatus) {
|
|
16384
|
-
const result = stateDb2.db.prepare(`
|
|
16385
|
-
UPDATE corrections
|
|
16386
|
-
SET status = ?, resolved_at = datetime('now')
|
|
16387
|
-
WHERE id = ?
|
|
16388
|
-
`).run(newStatus, id);
|
|
16389
|
-
return result.changes > 0;
|
|
16390
|
-
}
|
|
16391
|
-
function processPendingCorrections(stateDb2) {
|
|
16392
|
-
const pending = listCorrections(stateDb2, "pending");
|
|
16393
|
-
let processed = 0;
|
|
16394
|
-
for (const correction of pending) {
|
|
16395
|
-
if (!correction.entity) {
|
|
16396
|
-
resolveCorrection(stateDb2, correction.id, "dismissed");
|
|
16397
|
-
continue;
|
|
16398
|
-
}
|
|
16399
|
-
if (correction.correction_type === "wrong_link") {
|
|
16400
|
-
recordFeedback(stateDb2, correction.entity, "correction:wrong_link", correction.note_path || "", false, 1);
|
|
16401
|
-
} else if (correction.correction_type === "wrong_category") {
|
|
16402
|
-
recordFeedback(stateDb2, correction.entity, "correction:wrong_category", "", false, 0.5);
|
|
16403
|
-
}
|
|
16404
|
-
resolveCorrection(stateDb2, correction.id, "applied");
|
|
16405
|
-
processed++;
|
|
16406
|
-
}
|
|
16407
|
-
return processed;
|
|
16408
|
-
}
|
|
16409
|
-
|
|
16410
|
-
// src/tools/write/corrections.ts
|
|
16411
16437
|
function registerCorrectionTools(server2, getStateDb) {
|
|
16412
16438
|
server2.tool(
|
|
16413
16439
|
"vault_record_correction",
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@velvetmonkey/flywheel-memory",
|
|
3
|
-
"version": "2.0.
|
|
3
|
+
"version": "2.0.54",
|
|
4
4
|
"description": "MCP server that gives Claude full read/write access to your Obsidian vault. Select from 42 tools for search, backlinks, graph queries, mutations, and hybrid semantic search.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -52,7 +52,7 @@
|
|
|
52
52
|
},
|
|
53
53
|
"dependencies": {
|
|
54
54
|
"@modelcontextprotocol/sdk": "^1.25.1",
|
|
55
|
-
"@velvetmonkey/vault-core": "^2.0.
|
|
55
|
+
"@velvetmonkey/vault-core": "^2.0.54",
|
|
56
56
|
"better-sqlite3": "^11.0.0",
|
|
57
57
|
"chokidar": "^4.0.0",
|
|
58
58
|
"gray-matter": "^4.0.3",
|