@velvetmonkey/flywheel-memory 2.5.10 → 2.5.11
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/embedding-worker.js +76 -0
- package/dist/index.js +787 -767
- package/package.json +4 -4
package/dist/index.js
CHANGED
|
@@ -1,12 +1,6 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
var __defProp = Object.defineProperty;
|
|
3
3
|
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
4
|
-
var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require : typeof Proxy !== "undefined" ? new Proxy(x, {
|
|
5
|
-
get: (a, b) => (typeof require !== "undefined" ? require : a)[b]
|
|
6
|
-
}) : x)(function(x) {
|
|
7
|
-
if (typeof require !== "undefined") return require.apply(this, arguments);
|
|
8
|
-
throw Error('Dynamic require of "' + x + '" is not supported');
|
|
9
|
-
});
|
|
10
4
|
var __esm = (fn, res) => function __init() {
|
|
11
5
|
return fn && (res = (0, fn[__getOwnPropNames(fn)[0]])(fn = 0)), res;
|
|
12
6
|
};
|
|
@@ -283,6 +277,8 @@ var init_vault_scope = __esm({
|
|
|
283
277
|
import * as crypto from "crypto";
|
|
284
278
|
import * as fs3 from "fs";
|
|
285
279
|
import * as path2 from "path";
|
|
280
|
+
import { Worker } from "node:worker_threads";
|
|
281
|
+
import { fileURLToPath } from "node:url";
|
|
286
282
|
function getModelConfig() {
|
|
287
283
|
const envModel = process.env.EMBEDDING_MODEL?.trim();
|
|
288
284
|
if (!envModel) return MODEL_REGISTRY[DEFAULT_MODEL];
|
|
@@ -334,92 +330,115 @@ function clearEmbeddingsForRebuild() {
|
|
|
334
330
|
function setEmbeddingsDatabase(database) {
|
|
335
331
|
db = database;
|
|
336
332
|
}
|
|
337
|
-
function
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
const npxDir = path2.join(home, ".npm", "_npx");
|
|
348
|
-
if (fs3.existsSync(npxDir)) {
|
|
349
|
-
for (const hash of fs3.readdirSync(npxDir)) {
|
|
350
|
-
const candidate = path2.join(npxDir, hash, "node_modules", "@huggingface", "transformers", ".cache", ...modelId.split("/"));
|
|
351
|
-
if (fs3.existsSync(candidate)) candidates.push(candidate);
|
|
352
|
-
}
|
|
353
|
-
}
|
|
354
|
-
}
|
|
355
|
-
for (const cacheDir of candidates) {
|
|
356
|
-
if (fs3.existsSync(cacheDir)) {
|
|
357
|
-
fs3.rmSync(cacheDir, { recursive: true, force: true });
|
|
358
|
-
console.error(`[Semantic] Deleted corrupted model cache: ${cacheDir}`);
|
|
359
|
-
}
|
|
360
|
-
}
|
|
361
|
-
} catch (e) {
|
|
362
|
-
console.error(`[Semantic] Could not clear model cache: ${e instanceof Error ? e.message : e}`);
|
|
363
|
-
}
|
|
333
|
+
function resolveWorkerPath() {
|
|
334
|
+
const thisFile = typeof __filename !== "undefined" ? __filename : fileURLToPath(import.meta.url);
|
|
335
|
+
const thisDir = path2.dirname(thisFile);
|
|
336
|
+
const workerPath = path2.join(thisDir, "embedding-worker.js");
|
|
337
|
+
if (fs3.existsSync(workerPath)) return workerPath;
|
|
338
|
+
const devPath = path2.resolve(thisDir, "..", "..", "..", "dist", "embedding-worker.js");
|
|
339
|
+
if (fs3.existsSync(devPath)) return devPath;
|
|
340
|
+
throw new Error(
|
|
341
|
+
`Embedding worker not found at ${workerPath}. Run 'npm run build' to generate it.`
|
|
342
|
+
);
|
|
364
343
|
}
|
|
365
344
|
async function initEmbeddings() {
|
|
366
|
-
if (
|
|
367
|
-
if (
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
345
|
+
if (workerReady && worker) return;
|
|
346
|
+
if (workerInitPromise) return workerInitPromise;
|
|
347
|
+
workerInitPromise = new Promise((resolve3, reject) => {
|
|
348
|
+
try {
|
|
349
|
+
const workerPath = resolveWorkerPath();
|
|
350
|
+
console.error(`[Semantic] Spawning embedding worker: ${workerPath}`);
|
|
351
|
+
worker = new Worker(workerPath);
|
|
352
|
+
worker.on("message", (msg) => {
|
|
353
|
+
switch (msg.type) {
|
|
354
|
+
case "ready":
|
|
355
|
+
workerReady = true;
|
|
356
|
+
workerDims = msg.dims;
|
|
357
|
+
if (activeModelConfig.dims === 0) {
|
|
358
|
+
activeModelConfig.dims = msg.dims;
|
|
359
|
+
console.error(`[Semantic] Probed model ${activeModelConfig.id}: ${msg.dims} dims`);
|
|
360
|
+
}
|
|
361
|
+
console.error(`[Semantic] Worker ready (model: ${activeModelConfig.id}, dims: ${msg.dims})`);
|
|
362
|
+
resolve3();
|
|
363
|
+
break;
|
|
364
|
+
case "result": {
|
|
365
|
+
const pending = pendingEmbeds.get(msg.id);
|
|
366
|
+
if (pending) {
|
|
367
|
+
pendingEmbeds.delete(msg.id);
|
|
368
|
+
pending.resolve(new Float32Array(msg.embedding));
|
|
369
|
+
}
|
|
370
|
+
break;
|
|
371
|
+
}
|
|
372
|
+
case "error": {
|
|
373
|
+
if (msg.fatal) {
|
|
374
|
+
console.error(`[Semantic] Worker fatal error: ${msg.message}`);
|
|
375
|
+
console.error(`[Semantic] Semantic search disabled. Keyword search (BM25) remains available.`);
|
|
376
|
+
terminateWorker();
|
|
377
|
+
workerInitPromise = null;
|
|
378
|
+
reject(new Error(msg.message));
|
|
379
|
+
} else if (msg.id != null) {
|
|
380
|
+
const pending = pendingEmbeds.get(msg.id);
|
|
381
|
+
if (pending) {
|
|
382
|
+
pendingEmbeds.delete(msg.id);
|
|
383
|
+
pending.reject(new Error(msg.message));
|
|
384
|
+
}
|
|
385
|
+
}
|
|
386
|
+
break;
|
|
387
|
+
}
|
|
392
388
|
}
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
389
|
+
});
|
|
390
|
+
worker.on("error", (err) => {
|
|
391
|
+
console.error(`[Semantic] Worker error: ${err.message}`);
|
|
392
|
+
handleWorkerCrash();
|
|
393
|
+
if (!workerReady) {
|
|
394
|
+
workerInitPromise = null;
|
|
395
|
+
reject(err);
|
|
400
396
|
}
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
console.error(`[Semantic]
|
|
405
|
-
|
|
406
|
-
pipeline = null;
|
|
407
|
-
} else {
|
|
408
|
-
console.error(`[Semantic] Model load failed after ${MAX_RETRIES} attempts: ${err instanceof Error ? err.message : err}`);
|
|
409
|
-
console.error(`[Semantic] Semantic search disabled. Keyword search (BM25) remains available.`);
|
|
410
|
-
initPromise = null;
|
|
411
|
-
throw err;
|
|
397
|
+
});
|
|
398
|
+
worker.on("exit", (code) => {
|
|
399
|
+
if (code !== 0 && workerReady) {
|
|
400
|
+
console.error(`[Semantic] Worker exited with code ${code}`);
|
|
401
|
+
handleWorkerCrash();
|
|
412
402
|
}
|
|
413
|
-
}
|
|
403
|
+
});
|
|
404
|
+
worker.postMessage({ type: "init", modelId: activeModelConfig.id });
|
|
405
|
+
} catch (err) {
|
|
406
|
+
workerInitPromise = null;
|
|
407
|
+
reject(err);
|
|
414
408
|
}
|
|
415
|
-
})
|
|
416
|
-
return
|
|
409
|
+
});
|
|
410
|
+
return workerInitPromise;
|
|
411
|
+
}
|
|
412
|
+
function handleWorkerCrash() {
|
|
413
|
+
for (const [id, pending] of pendingEmbeds) {
|
|
414
|
+
pending.reject(new Error("Embedding worker crashed"));
|
|
415
|
+
pendingEmbeds.delete(id);
|
|
416
|
+
}
|
|
417
|
+
worker = null;
|
|
418
|
+
workerReady = false;
|
|
419
|
+
workerInitPromise = null;
|
|
420
|
+
}
|
|
421
|
+
function terminateWorker() {
|
|
422
|
+
if (worker) {
|
|
423
|
+
try {
|
|
424
|
+
worker.postMessage({ type: "shutdown" });
|
|
425
|
+
} catch {
|
|
426
|
+
}
|
|
427
|
+
worker = null;
|
|
428
|
+
}
|
|
429
|
+
workerReady = false;
|
|
430
|
+
workerInitPromise = null;
|
|
417
431
|
}
|
|
418
432
|
async function embedText(text) {
|
|
419
433
|
await initEmbeddings();
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
434
|
+
if (!worker) {
|
|
435
|
+
throw new Error("Embedding worker not available");
|
|
436
|
+
}
|
|
437
|
+
const id = ++embedRequestId;
|
|
438
|
+
return new Promise((resolve3, reject) => {
|
|
439
|
+
pendingEmbeds.set(id, { resolve: resolve3, reject });
|
|
440
|
+
worker.postMessage({ type: "embed", id, text });
|
|
441
|
+
});
|
|
423
442
|
}
|
|
424
443
|
async function embedTextCached(text) {
|
|
425
444
|
const existing = embeddingCache.get(text);
|
|
@@ -1116,7 +1135,7 @@ function getEntityEmbeddingsCount() {
|
|
|
1116
1135
|
return 0;
|
|
1117
1136
|
}
|
|
1118
1137
|
}
|
|
1119
|
-
var MODEL_REGISTRY, DEFAULT_MODEL, activeModelConfig, MAX_FILE_SIZE2, db,
|
|
1138
|
+
var MODEL_REGISTRY, DEFAULT_MODEL, activeModelConfig, MAX_FILE_SIZE2, db, embeddingsBuilding, worker, workerReady, workerDims, workerInitPromise, embedRequestId, pendingEmbeds, embeddingCache, EMBEDDING_CACHE_MAX, entityEmbeddingsMap, inferredCategoriesMap, EMBEDDING_TEXT_VERSION;
|
|
1120
1139
|
var init_embeddings = __esm({
|
|
1121
1140
|
"src/core/read/embeddings.ts"() {
|
|
1122
1141
|
"use strict";
|
|
@@ -1133,9 +1152,13 @@ var init_embeddings = __esm({
|
|
|
1133
1152
|
activeModelConfig = getModelConfig();
|
|
1134
1153
|
MAX_FILE_SIZE2 = 5 * 1024 * 1024;
|
|
1135
1154
|
db = null;
|
|
1136
|
-
pipeline = null;
|
|
1137
|
-
initPromise = null;
|
|
1138
1155
|
embeddingsBuilding = false;
|
|
1156
|
+
worker = null;
|
|
1157
|
+
workerReady = false;
|
|
1158
|
+
workerDims = 0;
|
|
1159
|
+
workerInitPromise = null;
|
|
1160
|
+
embedRequestId = 0;
|
|
1161
|
+
pendingEmbeds = /* @__PURE__ */ new Map();
|
|
1139
1162
|
embeddingCache = /* @__PURE__ */ new Map();
|
|
1140
1163
|
EMBEDDING_CACHE_MAX = 500;
|
|
1141
1164
|
entityEmbeddingsMap = /* @__PURE__ */ new Map();
|
|
@@ -1255,9 +1278,12 @@ function saveRecencyToStateDb(index, explicitStateDb) {
|
|
|
1255
1278
|
}
|
|
1256
1279
|
console.error(`[Flywheel] saveRecencyToStateDb: Saving ${index.lastMentioned.size} entries...`);
|
|
1257
1280
|
try {
|
|
1258
|
-
|
|
1259
|
-
|
|
1260
|
-
|
|
1281
|
+
const runInTransaction = stateDb2.db.transaction(() => {
|
|
1282
|
+
for (const [entityNameLower, timestamp] of index.lastMentioned) {
|
|
1283
|
+
recordEntityMention(stateDb2, entityNameLower, new Date(timestamp));
|
|
1284
|
+
}
|
|
1285
|
+
});
|
|
1286
|
+
runInTransaction();
|
|
1261
1287
|
const count = stateDb2.db.prepare("SELECT COUNT(*) as cnt FROM recency").get();
|
|
1262
1288
|
console.error(`[Flywheel] Saved recency: ${index.lastMentioned.size} entries \u2192 ${count.cnt} rows in table`);
|
|
1263
1289
|
} catch (e) {
|
|
@@ -1930,18 +1956,18 @@ function updateSuppressionList(stateDb2, now) {
|
|
|
1930
1956
|
`DELETE FROM wikilink_suppressions
|
|
1931
1957
|
WHERE datetime(updated_at, '+' || ? || ' days') <= datetime('now')`
|
|
1932
1958
|
).run(SUPPRESSION_TTL_DAYS);
|
|
1933
|
-
for (const
|
|
1934
|
-
const effectiveAlpha = getEffectiveAlpha(
|
|
1935
|
-
const posteriorMean = computePosteriorMean(
|
|
1936
|
-
const totalObs = effectiveAlpha +
|
|
1959
|
+
for (const stat4 of weightedStats) {
|
|
1960
|
+
const effectiveAlpha = getEffectiveAlpha(stat4.entity);
|
|
1961
|
+
const posteriorMean = computePosteriorMean(stat4.weightedCorrect, stat4.weightedFp, effectiveAlpha);
|
|
1962
|
+
const totalObs = effectiveAlpha + stat4.weightedCorrect + PRIOR_BETA + stat4.weightedFp;
|
|
1937
1963
|
if (totalObs < SUPPRESSION_MIN_OBSERVATIONS) {
|
|
1938
1964
|
continue;
|
|
1939
1965
|
}
|
|
1940
1966
|
if (posteriorMean < SUPPRESSION_POSTERIOR_THRESHOLD) {
|
|
1941
|
-
upsert.run(
|
|
1967
|
+
upsert.run(stat4.entity, 1 - posteriorMean);
|
|
1942
1968
|
updated++;
|
|
1943
1969
|
} else {
|
|
1944
|
-
remove.run(
|
|
1970
|
+
remove.run(stat4.entity);
|
|
1945
1971
|
}
|
|
1946
1972
|
}
|
|
1947
1973
|
});
|
|
@@ -2011,31 +2037,31 @@ function getAllFeedbackBoosts(stateDb2, folder, now) {
|
|
|
2011
2037
|
if (folder !== void 0) {
|
|
2012
2038
|
folderStatsMap = /* @__PURE__ */ new Map();
|
|
2013
2039
|
for (const gs of globalStats) {
|
|
2014
|
-
const
|
|
2015
|
-
if (
|
|
2040
|
+
const fs36 = getWeightedFolderStats(stateDb2, gs.entity, folder, now);
|
|
2041
|
+
if (fs36.rawTotal >= FEEDBACK_BOOST_MIN_SAMPLES) {
|
|
2016
2042
|
folderStatsMap.set(gs.entity, {
|
|
2017
|
-
weightedAccuracy:
|
|
2018
|
-
rawCount:
|
|
2043
|
+
weightedAccuracy: fs36.weightedAccuracy,
|
|
2044
|
+
rawCount: fs36.rawTotal
|
|
2019
2045
|
});
|
|
2020
2046
|
}
|
|
2021
2047
|
}
|
|
2022
2048
|
}
|
|
2023
2049
|
const boosts = /* @__PURE__ */ new Map();
|
|
2024
|
-
for (const
|
|
2025
|
-
if (
|
|
2050
|
+
for (const stat4 of globalStats) {
|
|
2051
|
+
if (stat4.rawTotal < FEEDBACK_BOOST_MIN_SAMPLES) continue;
|
|
2026
2052
|
let accuracy;
|
|
2027
2053
|
let sampleCount;
|
|
2028
|
-
const
|
|
2029
|
-
if (
|
|
2030
|
-
accuracy =
|
|
2031
|
-
sampleCount =
|
|
2054
|
+
const fs36 = folderStatsMap?.get(stat4.entity);
|
|
2055
|
+
if (fs36 && fs36.rawCount >= FEEDBACK_BOOST_MIN_SAMPLES) {
|
|
2056
|
+
accuracy = fs36.weightedAccuracy;
|
|
2057
|
+
sampleCount = fs36.rawCount;
|
|
2032
2058
|
} else {
|
|
2033
|
-
accuracy =
|
|
2034
|
-
sampleCount =
|
|
2059
|
+
accuracy = stat4.weightedAccuracy;
|
|
2060
|
+
sampleCount = stat4.rawTotal;
|
|
2035
2061
|
}
|
|
2036
2062
|
const boost = computeBoostFromAccuracy(accuracy, sampleCount);
|
|
2037
2063
|
if (boost !== 0) {
|
|
2038
|
-
boosts.set(
|
|
2064
|
+
boosts.set(stat4.entity, boost);
|
|
2039
2065
|
}
|
|
2040
2066
|
}
|
|
2041
2067
|
return boosts;
|
|
@@ -2043,18 +2069,18 @@ function getAllFeedbackBoosts(stateDb2, folder, now) {
|
|
|
2043
2069
|
function getAllSuppressionPenalties(stateDb2, now) {
|
|
2044
2070
|
const penalties = /* @__PURE__ */ new Map();
|
|
2045
2071
|
const weightedStats = getWeightedEntityStats(stateDb2, now);
|
|
2046
|
-
for (const
|
|
2047
|
-
const effectiveAlpha = getEffectiveAlpha(
|
|
2048
|
-
const posteriorMean = computePosteriorMean(
|
|
2049
|
-
const totalObs = effectiveAlpha +
|
|
2072
|
+
for (const stat4 of weightedStats) {
|
|
2073
|
+
const effectiveAlpha = getEffectiveAlpha(stat4.entity);
|
|
2074
|
+
const posteriorMean = computePosteriorMean(stat4.weightedCorrect, stat4.weightedFp, effectiveAlpha);
|
|
2075
|
+
const totalObs = effectiveAlpha + stat4.weightedCorrect + PRIOR_BETA + stat4.weightedFp;
|
|
2050
2076
|
if (totalObs >= SUPPRESSION_MIN_OBSERVATIONS) {
|
|
2051
2077
|
if (posteriorMean < SUPPRESSION_POSTERIOR_THRESHOLD) {
|
|
2052
2078
|
const penalty = Math.round(MAX_SUPPRESSION_PENALTY * (1 - posteriorMean / SUPPRESSION_POSTERIOR_THRESHOLD));
|
|
2053
2079
|
if (penalty < 0) {
|
|
2054
|
-
penalties.set(
|
|
2080
|
+
penalties.set(stat4.entity, penalty);
|
|
2055
2081
|
}
|
|
2056
2082
|
} else if (posteriorMean < SOFT_PENALTY_THRESHOLD) {
|
|
2057
|
-
penalties.set(
|
|
2083
|
+
penalties.set(stat4.entity, SOFT_PENALTY);
|
|
2058
2084
|
}
|
|
2059
2085
|
}
|
|
2060
2086
|
}
|
|
@@ -2632,8 +2658,8 @@ function clearLastMutationCommit() {
|
|
|
2632
2658
|
async function checkGitLock(vaultPath2) {
|
|
2633
2659
|
const lockPath = path10.join(vaultPath2, ".git/index.lock");
|
|
2634
2660
|
try {
|
|
2635
|
-
const
|
|
2636
|
-
const ageMs = Date.now() -
|
|
2661
|
+
const stat4 = await fs6.stat(lockPath);
|
|
2662
|
+
const ageMs = Date.now() - stat4.mtimeMs;
|
|
2637
2663
|
return {
|
|
2638
2664
|
locked: true,
|
|
2639
2665
|
stale: ageMs > STALE_LOCK_THRESHOLD_MS,
|
|
@@ -2655,8 +2681,8 @@ async function isGitRepo(vaultPath2) {
|
|
|
2655
2681
|
async function checkLockFile(vaultPath2) {
|
|
2656
2682
|
const lockPath = path10.join(vaultPath2, ".git/index.lock");
|
|
2657
2683
|
try {
|
|
2658
|
-
const
|
|
2659
|
-
const ageMs = Date.now() -
|
|
2684
|
+
const stat4 = await fs6.stat(lockPath);
|
|
2685
|
+
const ageMs = Date.now() - stat4.mtimeMs;
|
|
2660
2686
|
return { stale: ageMs > STALE_LOCK_THRESHOLD_MS, ageMs };
|
|
2661
2687
|
} catch {
|
|
2662
2688
|
return null;
|
|
@@ -2670,7 +2696,7 @@ function isLockContentionError(error) {
|
|
|
2670
2696
|
return false;
|
|
2671
2697
|
}
|
|
2672
2698
|
function sleep(ms) {
|
|
2673
|
-
return new Promise((
|
|
2699
|
+
return new Promise((resolve3) => setTimeout(resolve3, ms));
|
|
2674
2700
|
}
|
|
2675
2701
|
function calculateDelay(attempt, config2) {
|
|
2676
2702
|
let delay = config2.baseDelayMs * Math.pow(2, attempt);
|
|
@@ -4672,8 +4698,8 @@ async function applyProactiveSuggestions(filePath, vaultPath2, suggestions, conf
|
|
|
4672
4698
|
}
|
|
4673
4699
|
const fullPath = path11.join(vaultPath2, filePath);
|
|
4674
4700
|
try {
|
|
4675
|
-
const
|
|
4676
|
-
if (Date.now() -
|
|
4701
|
+
const stat4 = await fs7.stat(fullPath);
|
|
4702
|
+
if (Date.now() - stat4.mtimeMs < 3e4) {
|
|
4677
4703
|
return { applied: [], skipped: candidates.map((c) => c.entity) };
|
|
4678
4704
|
}
|
|
4679
4705
|
} catch {
|
|
@@ -5081,8 +5107,8 @@ var init_tool_embeddings_generated = __esm({
|
|
|
5081
5107
|
model: "Xenova/all-MiniLM-L6-v2",
|
|
5082
5108
|
dims: 384,
|
|
5083
5109
|
version: 1,
|
|
5084
|
-
generatedAt: "2026-04-
|
|
5085
|
-
sourceHash: "
|
|
5110
|
+
generatedAt: "2026-04-06T22:11:22.074Z",
|
|
5111
|
+
sourceHash: "55904c4f8b00ff85",
|
|
5086
5112
|
tools: [
|
|
5087
5113
|
{ name: "absorb_as_alias", category: "corrections", tier: 2, descriptionHash: "27554e8b6b3bb1a4", embedding: [-0.087313, -0.015109, 0.022541, 8661e-6, -0.024621, -0.027376, -9959e-6, -4143e-6, 0.020362, -0.025815, 0.03722, -0.017272, 0.010364, -0.082973, 0.063234, 0.105669, 0.030314, 0.109193, -0.024833, -0.022116, 0.020565, 0.067968, -0.013485, -4453e-6, 0.023703, -0.012531, -0.110704, 0.046425, 0.037009, -0.100492, 0.057064, 0.106952, -0.064645, 0.032072, 0.011054, 0.113279, 6113e-6, 2155e-6, 0.052647, -0.037832, 0.032187, -6735e-6, -0.027158, -0.033756, -0.071285, -0.025865, -0.040482, 0.02512, -0.037086, 4166e-6, -0.012929, -0.07895, -0.101903, 0.085107, -0.014636, 0.091582, -0.052795, 0.05756, -0.057044, -2231e-6, -0.013445, 2289e-6, -77e-5, -0.049304, -0.013433, -0.01156, 0.039263, 0.055036, -228e-5, -0.021411, 0.025402, -0.015392, -0.016927, -0.01263, 0.016506, 5128e-6, -0.045499, 0.041929, -0.098371, -0.102299, -0.05505, -0.021133, -0.011038, -0.045412, 0.051449, 0.043985, -0.026773, -0.061248, -0.013004, 0.020089, 0.020349, -0.049656, 0.14248, -0.023849, 1326e-6, 0.038924, 0.015142, -0.027207, 0.137747, 0.086333, -0.051942, 0.125201, -0.015227, 0.035816, -0.016593, -3143e-6, 0.016584, 0.057709, 3425e-6, -0.086785, 0.077055, 0.012249, 0.054973, -0.041238, 0.036758, -0.018482, 0.017911, -0.025632, 0.070721, -0.025979, 0.090299, 0.013505, -0.015338, 0.035118, -0.062938, -55e-6, -0.031485, 0, 0.048271, 0.118939, -7432e-6, -0.027482, -0.017351, -2898e-6, -0.036961, -3044e-6, -0.032485, -0.039268, 8085e-6, -0.01109, 0.025195, 273e-6, -0.081679, -0.043759, -1642e-6, 0.133163, 0.054599, 0.052329, -0.014879, 0.066345, -0.063461, 0.046176, -6885e-6, 0.050879, -0.032148, -0.03098, -0.01647, 2323e-6, -0.012937, 0.020916, 0.05669, 0.050599, -0.012922, 0.029857, -0.023119, -0.056459, -0.052397, -0.063056, 0.032488, 0.063419, 5355e-6, -0.081225, -2636e-6, -0.051448, -0.01502, 0.046703, 0.158323, -0.016006, 0.054453, -5225e-6, 0.055346, 3194e-6, -0.055126, -0.047608, -0.027439, -6931e-6, 0.015054, 0.070964, 0.016329, -7436e-6, -0.087056, 0.0326, -8886e-6, 0.069308, 1744e-6, -0.031456, 0.05816, -0.024318, -0.084045, 0.034875, -0.052924, 0.060689, -0.020979, -0.137039, -0.069438, 4228e-6, 0.103073, 0.026546, -0.043743, 0.015869, -1255e-6, -0.020976, -0.036293, 0.019493, 0.019183, -0.167767, -0.047504, -0.043037, -0.05305, -0.011494, 0.020628, -0.029303, 0.066295, -0, 0.06668, 6677e-6, -0.027402, 0.074721, -0.071961, 0.022582, 0.074355, 0.042852, -0.025373, 0.034536, 0.017667, -0.010542, -4169e-6, -0.083182, -2746e-6, -0.053237, 0.041962, -0.041424, -0.037738, 0.075779, 7597e-6, -0.035105, 0.089325, 0.059282, 0.087981, 0.014721, -6421e-6, -0.050171, 0.022545, -0.066806, 0.053691, -0.046373, -0.066624, -0.05594, -2923e-6, -0.072017, -0.035938, -0.031965, -0.078192, -0.01764, 0.047027, 0.05296, -0.039368, 0.060137, -0.014895, 2928e-6, -0.053409, 0.059899, -0.071938, -0.084993, 0.014731, -9255e-6, -0.012538, -0.057773, -0.01937, 0.011484, 0.118908, -4683e-6, -0.101681, -0.030016, 0.04375, 0.078497, -0.024205, -4214e-6, 0.041916, -0.032365, -0.03231, -8687e-6, -0.054573, 9854e-6, 3192e-6, -0.041575, 0.030278, -0.063586, 0.050707, -0.033235, 0.028844, -0.078475, -0.046236, 0.019996, -0.103771, -0.031058, 0.036113, 0.053975, -0.013333, -0.037514, -0.05237, 0.069865, -0.022002, 0.043238, -0.058168, -0.01832, 0.065564, 0.052553, -0.016286, -0, -0.060219, 0.015225, -0.044145, 0.023352, -0.052523, -0.013584, -0.073037, -0.033518, -0.01456, -7575e-6, 2766e-6, -0.030461, -0.045765, -0.042223, -0.032423, -0.03025, 0.020423, 0.066116, -0.085401, -0.038306, -0.12109, 0.040213, 131e-6, -0.04345, 0.070947, 0.014882, 7721e-6, 0.088877, 0.047515, -0.074231, 0.048281, -648e-6, 0.016151, 0.047549, -1148e-6, 0.028044, 0.088863, 0.014517, 0.022091, 0.123896, 0.05443, 0.032042, -0.05105, 0.069732, 0.057286, -0.060648, 108e-5, -0.050034, 0.03852, -0.017144, 0.024196, -0.032345, -0.031836, -0.030237, -0.01748, -1953e-6, 0.045463, 0.059662, 0.020283, -603e-5, 0.145025, -0.031073, 0.069219, 0.012386] },
|
|
5088
5114
|
{ name: "brief", category: "memory", tier: 1, descriptionHash: "cd54c8b5f8962c0c", embedding: [-0.03413, 0.038967, -0.058868, 5065e-6, 0.013581, -9201e-6, 0.12418, 0.084974, 0.0466, -0.027719, -0.03003, 2981e-6, -0.019524, 6126e-6, 0.121445, 0.030564, 0.113974, -0.019305, 0.010584, 0.022772, 0.040912, 0.049654, 0.012009, 0.014554, -317e-6, 0.010126, -0.084735, -1667e-6, 0.083471, -7537e-6, 0.013307, 0.106008, 0.040402, 0.065893, -0.017905, 0.099291, 0.017319, 0.015036, -6372e-6, -0.066617, -0.060547, -0.011005, -0.057781, 0.076661, 9708e-6, -0.045502, -0.044302, -9454e-6, -0.045664, 9896e-6, -0.053175, 0.012171, -0.021067, 0.071767, -8367e-6, 0.128232, -5307e-6, 0.069086, -0.038624, 0.028583, -0.068574, -0.100884, -0.052176, 0.044373, -0.012476, 0.041925, 0.032421, 9466e-6, 0.055237, -0.135804, -0.045271, -0.032277, -0.034088, 0.044972, -0.037657, 0.01615, 0.023087, -0.047546, 5856e-6, -0.118672, -0.013503, 0.027683, 0.021988, 623e-5, -9077e-6, -0.021581, 0.013314, -0.037775, -9507e-6, 0.037748, 85e-5, -0.052845, -7436e-6, 0.03521, 1699e-6, 0.028288, -0.035951, -0.049538, 3357e-6, 0.065678, 0.059998, 0.099599, 0.012784, 0.041595, -0.076292, -0.037029, -0.037229, 0.013993, -0.035633, 4893e-6, -0.057584, 0.047254, -0.010266, -0.037457, 0.077024, -0.074891, -0.038335, -0.034745, 0.026768, 0.120412, 0.06315, -0.034399, -0.048602, -0.025597, -0.086307, -0.035078, 0.03381, 0, 0.074016, -5576e-6, -0.035261, 0.135218, 8885e-6, 0.058899, -0.020769, -0.018972, -0.036681, -0.017513, 0.022473, 0.099641, -0.01237, 0.02122, 0.020966, -0.011241, -0.106938, 0.129492, 0.066344, -0.036365, -0.033113, -6609e-6, -6963e-6, -335e-5, 0.113098, 0.012043, 0.013074, -0.05108, -0.02582, 0.038526, -0.04915, -0.044315, -0.060091, -8148e-6, 0.053718, 0.02143, -5476e-6, -0.021335, -0.010914, -0.106699, -0.040708, 0.013624, 0.031717, -0.058864, -0.091039, -0.10624, -0.040266, 0.024783, 0.036104, 0.013351, 5674e-6, 0.013377, -0.014192, 0.012503, 6394e-6, -0.02841, -4971e-6, -0.022927, -2823e-6, 0.087578, 0.041583, 7853e-6, -0.083155, 0.025704, 0.033491, 0.011361, -0.04942, -0.044508, 0.0311, -0.046498, -0.027239, 3602e-6, 0.040659, 0.050427, -0.025982, 0.014929, 0.015421, 0.031525, -0.062248, 0.03429, 0.052807, -0.044957, -0.023206, 0.055626, -0.038784, 0.022958, 0.043242, -0.128127, -0.054922, 3364e-6, -0.076564, -0.037719, 0.03462, 0.055063, -0.070653, -0, 0.06233, -0.030029, -0.032604, 0.014582, 0.045522, 0.028487, 0.060517, -2969e-6, -0.114903, 0.015776, -0.035656, 5943e-6, 0.029417, 1415e-6, 0.010575, 6686e-6, 0.033255, -0.076697, -0.018056, 0.07942, 0.059409, -0.03671, -0.127963, 0.026159, 0.014287, -0.024613, -0.05576, -0.032465, -0.023479, -0.030419, 9631e-6, -9214e-6, -0.016757, 0.013094, -0.050212, -0.035049, 0.049743, -0.065495, -0.075293, -9875e-6, 0.129848, 0.020889, -0.079259, -0.026347, -0.02803, 2228e-6, -0.065164, 0.043506, -0.033239, -295e-6, -6674e-6, -0.011676, 0.014787, -0.070129, -0.065786, -0.041317, -3707e-6, -0.025125, -0.027828, -0.086907, 0.07926, 7317e-6, -0.053674, -0.034213, 0.054837, -0.062371, 0.036652, 0.070297, -0.090998, 0.015399, 0.052273, -0.051188, 0.039306, -0.066122, 0.040192, 0.02005, -0.022352, -0.17157, -0.039433, -7233e-6, -0.039524, 15e-4, -0.027335, 0.059864, 0.062908, 0.051305, -0.020745, 0.089525, -0.011786, -0.020093, -0.070926, -0.055612, -0.052107, 0.110824, -385e-5, -0, -0.070805, -0.035939, 0.03615, 0.036301, 0.044026, 2509e-6, -5092e-6, 0.068686, 0.037356, 0.02202, 0.025483, -0.032118, -0.107202, -0.04086, 0.048949, 0.038155, -5906e-6, 0.013435, -0.031491, -0.055225, 0.067576, 0.035719, -0.022875, 0.016182, 0.043324, 0.011605, 0.061764, 0.143727, 0.050779, -0.052731, -0.015323, 0.062416, -0.018611, -0.07632, -0.047169, 0.100932, 0.033838, -0.021418, 0.046654, 0.014842, 0.036839, -0.024439, 0.035967, 0.067279, -5978e-6, 0.097739, -0.058634, 0.020037, 1243e-6, -0.081814, -0.06543, 8175e-6, 5117e-6, 0.080321, 57e-6, 0.063212, 0.053892, -0.021493, 0.052762, 0.018396, 0.067694, 0.088151, -0.031927, -0.019349] },
|
|
@@ -5107,7 +5133,6 @@ var init_tool_embeddings_generated = __esm({
|
|
|
5107
5133
|
{ name: "get_note_structure", category: "read", tier: 1, descriptionHash: "d46b747577458fa3", embedding: [-0.034053, 0.058568, -0.013073, 0.051956, 1878e-6, -3484e-6, -0.021384, 0.029459, 0.01866, -0.048506, 4879e-6, -0.02044, 0.02816, -0.035958, 0.080657, 0.031094, 0.034978, 0.025658, 0.023314, -0.026633, 0.088011, 0.055726, 0.045466, -0.019004, -0.045637, 0.051535, -0.119519, -817e-5, 0.051132, -8649e-6, 0.044961, 0.056027, 0.074836, 0.074553, 475e-5, 0.110606, 1981e-6, -0.035258, 0.012263, -0.027338, -0.030202, 0.040594, -0.03311, 0.025563, 0.016389, -7492e-6, -0.057405, -1909e-6, -0.045447, 0.022976, -0.076963, -0.012285, -0.068218, 0.041681, 0.041577, 0.117179, 0.019101, -0.019711, -0.089762, -0.050572, 0.028838, -0.050339, -0.029523, -0.061273, -0.030107, 0.02912, 0.019308, -5468e-6, 0.049428, -0.14302, 0.095878, 9145e-6, 0.020457, 0.041474, 9214e-6, 4388e-6, -4607e-6, -0.014015, -0.047316, -0.11267, -0.098773, 0.044953, 8675e-6, 0.041169, 0.025942, -0.011891, 0.026525, -0.064685, -6678e-6, 0.061513, 0.096213, -0.123228, -0.065633, -0.019303, 8386e-6, 0.072118, 0.01913, -0.061346, 0.102101, 5084e-6, 0.055616, 0.078131, 0.079695, 0.018583, -0.035607, 0.0278, -0.045358, 0.060122, -0.048107, -0.049176, -0.011027, 0.064188, 0.053857, -0.01995, 6125e-6, -0.108854, -7305e-6, -0.03411, 0.045967, 0.111935, 0.112075, 0.01486, -0.022984, 0.015949, -0.102044, -0.012269, -0.075949, 0, 0.054186, 0.018959, 0.0149, 0.017011, -0.049196, 0.023439, 0.023984, 0.05285, -0.06726, -0.020796, -4855e-6, -7865e-6, -0.024857, 0.043349, -0.02489, -1547e-6, -0.045001, 0.06978, 0.019432, 0.03429, 0.011628, 7296e-6, 0.018451, -0.048771, 0.057362, 0.011788, -0.064353, -0.059757, -0.106931, -8745e-6, -0.036667, -0.079833, 0.024444, -0.047112, 0.016105, 0.06526, -0.040127, -4395e-6, -0.046705, -0.106663, 7097e-6, 3845e-6, 0.063465, -0.057979, -0.069587, 773e-6, -0.11854, 0.03829, 0.025318, 0.012997, 0.071065, 0.019042, -653e-5, 0.015978, 0.011882, 0.021631, 0.056059, 0.037697, -0.025745, 0.029873, 0.069977, -1341e-6, -0.017607, 0.032514, -0.040447, 0.023605, -0.032664, -0.0646, 0.069692, 8649e-6, -7163e-6, 0.047986, -7216e-6, 0.023747, -0.016205, -0.082133, -0.048612, -0.094448, 0.069621, -7387e-6, -0.038751, 0.01059, 0.040886, 0.077897, -0.032101, 0.034213, 0.053679, -0.182541, -0.026943, -0.061374, -0.044323, -0.04285, -0.047162, -0.073464, -8375e-6, -0, 0.045809, -0.051449, 0.014081, -0.057152, -0.024508, 0.044098, -0.031783, -2289e-6, -9969e-6, 0.082517, 0.02157, 0.014477, -0.029174, -0.04392, 0.011175, 0.048167, 9909e-6, -0.051525, 0.047285, 0.080488, -0.050922, -0.01143, -0.040418, 0.062125, 0.028396, -8963e-6, -0.051493, -0.048817, 0.027338, -0.066401, 0.017883, -0.053035, -0.053539, -0.036246, -0.057684, -0.034075, -414e-5, -0.073031, -0.040457, 0.086656, 0.068735, 0.107286, 4776e-6, -4959e-6, -0.047611, -0.028712, -0.024964, 0.089701, -0.045587, -0.043428, 0.053476, -0.030139, 3572e-6, -1346e-6, -0.018707, 0.049658, 5663e-6, 1265e-6, -0.078038, -0.049664, -0.022299, 0.065011, -0.11443, 0.034629, 3051e-6, -0.084661, 0.014807, -0.076934, -0.094602, -0.014275, -0.038493, 7669e-6, 0.05943, -0.032143, 0.065115, 0.079638, -0.061122, -0.014708, -0.043751, -0.029774, -0.015585, -0.015531, 0.043522, 0.07072, 0.040783, -0.031524, 9546e-6, 0.02525, -0.023371, -0.010383, -2826e-6, -0.059428, 9702e-6, 0.06052, 0.040492, -0, -0.11971, -0.057381, -0.063901, -0.019077, -5356e-6, -1707e-6, 0.040946, 0.026112, -0.042693, 5638e-6, 0.034895, -0.043335, -0.135079, -0.044002, -0.016958, 2444e-6, 0.091011, 0.011747, -0.040649, -0.039531, -0.015739, 0.053451, -0.049184, -1028e-6, 0.066912, 0.023815, 1227e-6, 0.099626, 0.038918, 0.016415, 0.082349, 0.038295, -0.012661, 5537e-6, 0.054001, 0.03846, 0.067522, -0.012906, -4587e-6, 0.111114, 0.082928, 0.054718, -0.064304, 0.059634, 0.073812, -0.026092, -0.040453, 0.016418, 0.038886, -0.059243, -0.028257, -0.024486, -0.051302, 7722e-6, -0.095123, 0.021788, 0.070279, 0.054412, 0.042015, -0.062366, 0.102527, 0.025488, 0.072279, 0.017399] },
|
|
5108
5134
|
{ name: "get_section_content", category: "read", tier: 1, descriptionHash: "3143db09c864e123", embedding: [-0.028641, 0.085473, -76e-6, 0.05119, 0.031131, 1587e-6, -0.018978, 0.057946, -0.01217, -0.034409, -567e-6, 8665e-6, 0.021315, -0.022961, 0.091059, -0.030405, 0.046316, 0.042966, 0.021119, -1504e-6, 0.053647, 0.101898, 8477e-6, 0.03071, -0.054229, 0.035659, -0.15261, 0.053486, -4781e-6, -0.043234, 0.043718, -0.012788, 0.018779, 0.011845, 8181e-6, 0.036182, 0.0978, -0.036718, 0.072551, 0.017413, -0.027154, 0.029073, -0.060769, 0.023862, 0.027807, -0.022091, -0.063303, -5347e-6, 7137e-6, -0.021798, -0.034714, -0.023498, -0.02925, 0.092221, 0.010238, 0.109993, 534e-6, -0.025775, -0.050855, 6795e-6, -0.064772, -0.069964, -4102e-6, -0.073128, -0.035828, 0.016207, -0.03324, 0.016634, -0.045777, -0.027336, 0.027186, -0.025611, 0.038306, 0.052737, 9481e-6, -0.025895, -0.050778, -0.043424, -0.049807, -0.119121, -0.084864, 0.066539, -0.016666, 0.049291, -0.018263, 5135e-6, -2983e-6, -0.012152, -0.070296, 0.027834, 0.053321, -0.082358, -0.014167, 0.030441, -0.064228, 0.044649, -144e-5, -0.109388, 0.060139, 0.015573, -8612e-6, 0.030612, 0.060786, -0.01802, -0.067729, -0.013319, -8888e-6, 0.028932, -0.045929, -0.042227, 0.010539, 0.033105, -0.015885, -4513e-6, 116e-6, -0.066676, 0.048411, -0.029626, 0.032187, 0.082548, 0.114786, -0.01838, -8558e-6, 0.065853, -0.074634, -0.039559, 0.031106, 0, 6209e-6, -8677e-6, 3492e-6, 0.05194, -0.032895, 0.03922, -0.031535, -898e-5, -0.025381, -0.014504, 0.013425, -0.047406, -7584e-6, 0.06063, -0.029333, -0.011628, 5507e-6, 0.057618, -0.025885, 0.023597, -0.031007, 2971e-6, 0.012595, -0.060759, 0.050706, 0.052725, -0.065455, 734e-6, -0.113944, -0.011068, -908e-5, -0.03675, 0.037886, -0.118776, 254e-5, 0.051742, 3988e-6, -2943e-6, -0.073215, -0.046089, -0.014969, -6248e-6, 0.06288, -0.03653, -0.076457, 0.040562, -0.053199, 0.046905, -665e-6, -0.03219, 0.052905, 0.018131, 0.047858, -0.034036, 0.052139, -0.031547, 3647e-6, 0.053643, -4297e-6, 7731e-6, 0.124256, 0.012433, -0.04248, 0.029914, -0.059878, 0.025681, -1956e-6, -0.046563, 167e-6, -2874e-6, -0.067715, 0.032702, -0.010757, 0.048113, 729e-6, -0.046407, -0.069157, -0.070698, 0.116455, -0.038527, -454e-5, 0.038641, 0.064124, 8841e-6, 8073e-6, 0.029897, 0.065531, -0.099762, -0.027115, -0.081608, -0.128888, -0.097702, 0.03308, -0.087019, 0.013349, -0, 0.072201, -0.014661, -0.048643, -0.060926, -0.077314, 0.059431, 0.011764, 0.035201, 0.016747, 0.085562, 0.018052, 9969e-6, -0.039091, -0.012121, 0.065632, -906e-5, -0.072452, -0.069153, 0.059193, 0.019054, -0.085421, -0.077256, -0.018214, 0.012881, 0.020715, 7903e-6, -0.055617, -0.029759, 0.015393, -0.088237, -8017e-6, -0.045987, -1644e-6, -8979e-6, -0.075813, -0.031571, -0.061005, -0.027525, -339e-5, 0.060508, 0.110903, 0.101027, 0.077668, -0.034899, -0.072861, 0.028758, 0.028136, 0.095881, -0.049, 0.016251, -0.045377, -0.04172, -4138e-6, 0.031363, -0.016481, 0.051365, -0.02863, 0.038089, -0.095247, -0.068709, -0.017717, 0.067932, -0.094599, 0.061901, 0.042007, -0.020073, 0.031228, -0.09808, -0.041746, -821e-6, -0.024428, -0.04163, 0.071431, -0.059914, 0.06119, 0.112077, -0.08753, 0.020743, -0.103866, 0.039082, -4396e-6, -0.02896, -0.056667, 0.066637, 0.090426, -0.014902, -0.050542, -0.016232, 0.015545, -0.017757, 7608e-6, -0.03554, 0.078521, 0.078539, -0.030191, -0, -0.017856, -0.069979, -0.012196, -0.062197, -0.054607, 0.061452, -0.028817, -0.059814, -0.033044, 0.023097, 5961e-6, -0.069378, -0.095493, -0.084676, -0.036096, 0.047724, 0.036811, 0.060726, -0.012988, -0.051958, -0.059858, 0.063799, -0.010038, -838e-5, 0.046756, 0.077427, -2525e-6, 0.093047, 0.057901, -0.037286, 0.114778, 0.032906, 0.026368, 0.016743, 0.085209, 0.042384, 0.038353, 0.051377, 0.079111, 0.114371, 0.081498, -557e-5, -0.036095, 0.027621, 0.078159, 2603e-6, -0.046535, 0.032286, 0.069105, -0.031222, -0.071619, -0.015424, -0.045878, 0.032742, -0.087811, 0.022644, 0.071666, 0.020854, -0.028094, -0.044219, 0.070801, 0.031554, 0.06052, 0.063509] },
|
|
5109
5135
|
{ name: "get_strong_connections", category: "graph", tier: 2, descriptionHash: "6e2af7b6029af542", embedding: [-0.037771, -0.027994, -0.068021, 0.023556, -0.090681, -0.051207, -0.041261, 0.017216, -0.06359, -0.055238, 806e-5, 0.02676, 8123e-6, 1787e-6, 6061e-6, 0.135593, 0.059854, 0.028837, -0.030354, -0.060799, 0.0423, -0.063322, -0.018217, -4433e-6, 0.047159, -0.055318, -0.083385, 0.060145, 0.073422, -0.064649, 356e-6, 5751e-6, -0.139108, 7324e-6, -0.042962, 0.037446, 0.053805, -0.037605, 372e-5, 0.011429, 0.026703, 0.020876, 0.03223, -0.03014, -0.040705, 0.016356, -0.101406, 0.074424, -0.047714, -0.037129, -0.088537, 0.012154, -0.057325, 0.045473, 0.084099, 0.054132, -5249e-6, -5968e-6, -0.055892, 0.068053, 0.054631, -0.04568, -0.069245, -0.020054, -0.04224, 5718e-6, -2155e-6, 0.114993, 7884e-6, 0.018219, 0.031962, -0.072873, -0.097566, 0.019057, 0.063863, 0.052558, 0.011555, -1668e-6, -0.067272, -0.120076, -0.06419, 0.01966, -0.028191, 0.045533, 0.068489, 814e-6, -0.012517, -0.081064, 0.038081, 0.052053, 0.036193, 0.040413, -0.052446, 0.026766, 0.028761, 0.060208, -0.025242, -0.087489, -0.04182, 0.056964, -0.017134, 0.016552, 5959e-6, -0.045877, 0.043168, 0.072253, -0.031332, 0.029309, 0.046305, -7642e-6, -0.022719, 0.034447, 0.022557, 3578e-6, -0.041477, -0.024104, -0.015113, 0.027006, 0.080433, 0.090614, 0.04795, 0.015571, -5917e-6, -0.030432, -0.036741, -0.040443, -4554e-6, 0, 0.059822, 0.0145, 0.051421, 0.015885, -0.022594, 0.037805, -0.078622, 0.014572, -0.061651, 4526e-6, -0.13038, 0.075147, -0.014407, 0.027354, 0.071657, -0.043857, 0.050021, 0.026305, 0.031753, -0.01056, 0.021751, -0.040921, -7686e-6, -0.02379, 0.114929, -0.034895, -9839e-6, 0.010689, -0.035789, 0.031663, -9746e-6, -0.039082, 0.017535, -0.013062, -0.015549, 0.02697, -0.067409, -0.018802, -0.025118, -0.024353, -0.022472, -0.04769, -0.022257, -0.021798, -0.036261, 0.023876, -0.072232, 0.017299, -0.036421, 9764e-6, -0.019015, -0.018019, 0.028643, 0.059689, 0.011619, -0.061575, -0.011098, 0.135227, 0.01339, 0.095882, 0.028497, -0.015913, -0.021305, 0.012422, 0.033127, 0.02329, -0.098138, -0.039889, 0.061132, 0.025942, -0.053474, 0.080174, 0.010111, -0.012041, -0.034366, -0.098504, -0.092239, -0.066017, 0.091857, 0.02822, -0.139999, 2266e-6, -2271e-6, 0.055157, -0.04945, 0.013613, 0.046267, -0.121393, -0.048062, -4372e-6, -0.082383, 3035e-6, 0.034201, -0.018272, 0.038456, -0, -2843e-6, 0.069342, 0.103103, 0.010287, 0.029563, -0.022873, 0.027775, -0.043618, 0.010446, 0.138289, 0.03564, 0.031568, 0.039643, -0.057704, 0.14409, -0.071936, -0.010229, -0.07411, 0.01354, 0.058899, -4457e-6, 0.05122, -0.064179, -1085e-6, 0.077797, -0.021331, 8365e-6, -0.110735, -0.012208, -2982e-6, 554e-6, 5155e-6, -0.081401, 7275e-6, -0.044218, 0.097863, -0.014108, 8492e-6, 0.040481, -0.026258, 0.065645, 0.06016, -0.0312, -0.026998, -0.014959, 0.047424, -0.05033, -0.019567, -0.101543, -0.033671, 0.016911, 0.041148, 0.018528, 0.058475, 0.011338, -1783e-6, -6998e-6, 0.051356, -0.057736, -0.025262, -0.010656, -0.061711, -0.043316, 0.076918, 0.016766, -0.030118, -1567e-6, -0.063203, -0.012617, 0.019781, 7747e-6, 0.083593, 0.064443, -259e-6, 0.030238, 0.019059, -0.058083, 9456e-6, -0.061151, 0.029125, -0.071687, 0.053585, 0.056561, 5823e-6, 0.023318, -0.020783, 0.025751, 0.035499, 0.068327, 0.019582, -0.015069, -0.02526, -0.041987, 3336e-6, -0.050373, -0, -0.076057, -0.060965, 8849e-6, -2043e-6, 0.015217, 0.080132, 0.037776, 0.092546, -0.037172, 0.115836, 0.026506, 6788e-6, -0.073694, 0.019286, -974e-5, -9829e-6, 0.046523, -0.018646, -0.041308, -0.059466, -0.096567, 192e-6, 0.025832, 0.129585, -0.01088, -0.06024, -0.019829, 0.028988, -0.011028, 0.017712, 0.022421, -0.043442, 0.01067, 0.013991, -0.031013, 0.152245, -0.121124, 0.078891, -0.028629, 0.117615, 0.026723, 0.03564, 0.032972, 0.05445, 0.111144, 0.037447, 0.02066, 0.018956, -8914e-6, -0.070642, -0.052423, -0.041498, -0.044652, -0.101854, -0.057583, -0.01058, -0.01979, -0.013734, -0.021211, -6494e-6, 2554e-6, 0.021907, 304e-5, -2321e-6] },
|
|
5110
|
-
{ name: "get_weighted_links", category: "graph", tier: 2, descriptionHash: "b15908c4739b5d3a", embedding: [-0.090975, -0.014501, -0.021864, 0.065818, -0.030286, -0.047781, -0.026542, 0.021761, -0.038294, -0.032738, -0.015163, -0.012753, 0.031894, 0.01047, 0.029989, 0.120474, 0.098771, 0.067441, -0.040694, -0.062644, 0.035177, -0.050144, -0.034699, -1753e-6, 0.070949, -0.10291, -0.13736, 0.074743, 0.089653, -0.05479, 0.020764, 0.020775, -0.10811, -0.010933, -0.097484, 0.018926, 0.046231, -0.062474, 0.022908, -0.021497, 3353e-6, 6996e-6, -1637e-6, -0.020593, -0.031638, 1062e-6, -0.07396, 0.049341, -0.096428, 0.032815, -0.058664, 0.01456, -0.032546, 0.070596, 0.048763, 0.05182, 0.023216, -0.039782, -0.049001, 0.037621, 0.029424, -0.047569, -0.074779, 0.011681, -0.012067, 3717e-6, -0.030751, 0.089352, 298e-6, -0.018922, 0.056772, -0.092662, -0.063705, 0.022077, 0.065903, 0.02897, -0.024127, -0.055941, -0.030059, -0.065825, -0.072135, 0.032097, -0.023324, 0.015092, 0.061272, -7666e-6, 0.012571, -0.051188, -0.010824, 0.079681, 0.013229, 0.065022, -0.012118, 0.063461, 0.017044, 0.059285, -0.04809, -0.079425, -0.016637, 0.076686, -5778e-6, 0.035252, 9646e-6, -0.021157, 0.022145, 6747e-6, 879e-6, 0.113067, 0.037145, -1402e-6, -0.036647, 0.037682, 0.04401, -6466e-6, -0.03851, -0.012131, 0.029901, 0.024441, 0.068556, 0.054587, 0.075806, 7062e-6, -0.016095, -0.076931, -0.022381, -0.035324, -0.02266, 0, 0.100173, -0.015921, 0.029145, -0.022108, -0.011857, 0.042613, -0.070996, -0.032842, -0.072239, -0.05262, -0.10894, 0.133753, 0.013103, 0.038695, 0.044727, -0.033728, 0.038247, 0.068295, 0.07883, -0.052155, 0.044765, -0.014218, 215e-6, 0.028915, 0.082827, -531e-6, -9761e-6, -0.019842, -0.06516, 0.047081, 4414e-6, -0.070453, -1103e-6, -0.052589, -0.018823, 0.012986, -0.037209, -0.010124, -0.011257, -0.071029, -0.016809, -0.037493, 331e-5, -0.014289, -0.078064, 7253e-6, -0.053571, 0.019083, -0.040748, 0.015793, 0.015338, -0.046805, 0.029152, 0.030541, -9975e-6, -0.024135, -0.011031, 0.086744, 0.013653, 0.032038, 0.037415, -0.013344, -0.040472, -3412e-6, -0.012778, 0.010936, -0.054764, -0.062977, 0.022929, 9276e-6, -2083e-6, 0.092949, 0.020496, 0.021255, -0.02846, -0.078688, -0.102784, -0.090458, 0.071563, 0.039953, -0.09925, -0.02562, 9363e-6, 0.026493, -0.04102, 0.024758, 0.024951, -0.134036, -0.039121, 8251e-6, -0.067827, -0.043155, -0.021372, -0.020859, 0.015264, -0, -0.029416, 0.080464, 0.060345, 0.010391, 0.02143, -6675e-6, 0.010375, -0.068239, -0.016398, 0.122661, 0.0456, 4852e-6, -0.02345, -0.025092, 0.133585, -0.079084, -0.025699, -0.044697, -0.05656, 0.03485, 0.040477, 0.051672, -0.082537, 0.09383, 0.095729, -0.021573, 0.015405, -0.051452, 81e-6, -0.022034, 4398e-6, -0.010902, -0.051642, 1343e-6, -0.02102, 0.073711, 0.024084, -0.039672, -0.012054, 3372e-6, 0.048955, 0.019228, -0.032866, -0.014474, -6002e-6, 0.021877, -0.070833, 6029e-6, -0.087879, -0.056169, 0.020016, 0.017023, 0.029297, 0.061129, -0.017747, -8161e-6, 0.017038, 0.056091, -0.092429, -0.026094, 0.016189, -0.020079, -0.0584, 0.066234, -1429e-6, -0.038221, 0.030045, -0.06633, -0.054358, 0.064258, 79e-6, 0.03817, 0.099264, -0.040309, 0.058427, -454e-6, -0.044228, 0.052338, -0.081565, -0.017557, -0.074933, 2475e-6, 0.127554, 7727e-6, 0.053678, -0.045102, 2107e-6, 0.037336, 0.040023, 4466e-6, -0.019027, -0.047474, -0.077896, 0.022258, -0.032852, -0, -0.07619, -0.01597, 0.030851, 0.057193, -0.021068, 0.108372, 0.055887, 0.076764, -0.017763, 0.10255, 0.034333, -0.039576, -0.061609, -0.02854, 0.014108, 0.016585, 0.030504, -4742e-6, -0.036712, -0.090062, -0.096437, -0.017134, 0.021224, 0.094701, 8389e-6, -0.012675, -0.020066, 0.035665, 0.050386, 0.028501, 0.038512, 238e-5, 295e-6, -0.039607, -0.024497, 0.142554, -0.075649, 0.028408, -0.039409, 0.119073, 0.046154, 0.060929, 0.039705, 0.05497, 0.116029, 0.047151, -0.059783, 0.068407, 0.039543, -0.086565, -0.01137, -0.08773, -0.061231, -0.037986, -0.052677, 0.015221, 0.022846, -7088e-6, 6404e-6, 0.010344, 0.112113, -0.020958, -6841e-6, 0.020835] },
|
|
5111
5136
|
{ name: "graph_analysis", category: "graph", tier: 2, descriptionHash: "21da4313470c8acf", embedding: [0.014982, 0.048667, -0.05496, 0.012859, -7511e-6, -0.080556, -0.080775, 0.010218, -6301e-6, 0.017034, 0.013734, -7477e-6, 0.060422, 0.076067, 1336e-6, 0.08975, -0.041889, 0.014917, 0.079108, -0.074126, 5897e-6, -0.056713, -0.010258, -0.042079, 0.062049, 8864e-6, -0.111993, 0.040664, 0.054887, -0.027314, -8775e-6, 0.049098, 0.016304, 0.015778, 2669e-6, 0.087052, 0.05313, 0.015003, 0.026028, -6206e-6, -0.033553, 0.01072, 0.017311, 0.035093, 0.012491, -0.034683, -0.153859, -2641e-6, -0.065432, 0.010869, -0.072863, 0.042287, -0.036151, 0.035371, 0.062681, 0.078202, 7565e-6, -0.027103, 8832e-6, -0.015145, 0.129478, -96e-5, -0.084373, 0.018726, 0.030673, 0.08512, 0.05594, 0.068198, 0.03111, 0.02847, 0.01319, -0.068583, -0.042534, 0.046815, 0.062125, 0.099523, -0.025556, 0.033946, -0.021172, -0.149886, -0.024221, -4303e-6, 2622e-6, 0.022859, -0.022048, 0.025957, -0.055911, -0.076048, 0.014287, 0.066012, 0.010988, 0.058647, -0.010238, -7619e-6, 0.046626, -6447e-6, -8203e-6, -0.041375, 3573e-6, 0.050071, 0.012537, -0.024124, 0.031998, -0.029242, -759e-5, 0.034055, -3655e-6, 0.019935, -0.020079, 3175e-6, -7819e-6, 0.024804, 0.023123, 8955e-6, 0.03206, -0.039055, -0.0511, -0.024222, 0.058775, 0.084928, 0.054938, -8055e-6, 0.067706, -0.057881, -0.017355, -0.017372, -0.071099, 0, 0.039272, -3494e-6, -0.049648, -0.017106, 0.026142, -7155e-6, -0.124206, -0.022045, -0.034048, 0.042819, -0.047638, 0.098044, -0.014169, 0.016236, 0.093998, 0.029911, 0.079728, 0.053739, -0.017549, -0.064304, 0.03097, -0.036439, 0.033522, 0.035343, 0.134186, 0.017999, 0.01137, -0.044759, -0.058738, 0.024135, -0.037312, 0.019298, 0.013909, 6484e-6, 0.038982, -0.014468, -6381e-6, -0.021227, -0.053476, -0.071868, -0.010886, -0.058535, 0.014366, -0.038675, -0.033031, 4711e-6, -0.013062, -0.031503, 0.01143, 0.02046, -0.024102, -6962e-6, -0.036209, 0.079632, -0.042118, -1449e-6, 0.013005, -1418e-6, 0.017152, 0.065533, 0.020589, -0.013602, -1018e-6, -0.029669, -0.035822, -0.026891, -0.12942, -0.02858, 0.076096, 0.044514, -0.054821, 0.082988, -6901e-6, 0.049194, -0.057347, -0.099937, -0.089271, -0.013113, -0.025257, -6699e-6, -0.083914, -0.079291, 0.014989, -0.010643, -1926e-6, -0.02845, 0.051667, -0.068924, -0.042244, -0.067379, -0.078613, -0.020605, -0.01071, 0.020394, 0.02361, -0, 5196e-6, 0.059459, 0.066098, 0.016319, 0.029665, -0.038921, 0.019445, -0.108754, 9862e-6, 0.099327, 0.011067, 0.019257, 7469e-6, -0.026524, 0.067341, -0.024194, -0.047803, -0.138884, -0.035914, 0.064449, 0.020511, -0.012535, -0.074021, 0.012927, 0.078131, 0.01318, -0.021434, -0.092091, 0.039101, 9615e-6, -0.034145, 0.013148, 0.011523, -0.010175, 0.019436, 0.023398, 0.101393, -0.080156, -0.03636, -0.066278, 0.05756, 0.068323, -0.095833, -0.029751, 0.031757, 0.075222, 66e-6, 0.073814, -0.151532, -0.067838, 0.023268, 0.060245, 0.072305, -0.038108, -0.024749, -9942e-6, 0.04971, 0.073733, -0.072968, 0.032388, 0.028846, -0.057119, -0.032219, 6511e-6, 1294e-6, -0.080719, 474e-5, -0.045133, -0.157085, 0.069242, 0.064041, 0.026467, -0.022417, -0.032153, 0.04462, -0.040503, -0.041883, -4582e-6, -5381e-6, -0.014891, -0.042522, -7419e-6, 0.060908, 0.053358, 0.013997, -697e-5, -8638e-6, 0.039554, 8026e-6, 0.027568, -0.042951, -0.046245, -0.118002, 0.030924, 0.032844, -0, -0.073586, -0.03406, -0.02731, -0.040197, 0.035654, -43e-4, 0.068621, 0.104104, -0.019369, 0.063457, 0.068685, -0.018536, -0.142823, -6219e-6, -0.040994, -0.039883, -504e-6, -0.011205, -0.037401, 0.014862, -0.0493, -1524e-6, -0.024527, 0.053348, 0.020769, -0.076086, -0.048086, 0.035365, 0.017626, -0.012496, 0.031508, 0.0174, 0.080662, -0.032491, -0.019471, 0.142096, 0.052662, 0.066275, -7575e-6, 0.089928, -0.020622, 0.022103, -0.021359, 5322e-6, 0.037768, 0.031636, -9026e-6, 0.091438, 0.049468, -0.069661, -0.018383, -0.064816, -0.094888, -0.050419, 0.015122, 0.029533, 0.01494, -0.021185, 0.085005, 0.033213, 0.107679, -0.02922, -1768e-6, -0.116227] },
|
|
5112
5137
|
{ name: "init_semantic", category: "search", tier: 1, descriptionHash: "43c65824a56583c8", embedding: [-0.036645, -0.048423, -0.02987, 0.017334, 918e-6, 0.017996, -0.055598, -0.046157, -0.060235, -0.03943, 0.0203, -0.068196, 0.06205, 4746e-6, 0.021267, 0.1163, 0.082818, 7109e-6, 7912e-6, -0.031837, 0.039406, 0.039051, 0.041681, -0.024567, -0.030271, -4424e-6, -0.073251, -0.01792, 0.06297, -0.021106, 0.068028, 0.119778, -8886e-6, 0.124277, -0.015507, 0.047549, -0.043916, -0.03781, 798e-6, -0.068685, -0.042466, 0.022345, -0.045979, 0.02311, 0.025188, 0.011397, -0.107553, -0.055501, -0.024378, 0.018865, -0.112677, -2974e-6, -0.063417, 0.01448, 0.06073, 0.052563, -0.029852, 0.026697, -0.026249, -0.095955, 0.011018, -0.064869, 0.03559, -0.013392, -0.025816, -6166e-6, 0.03396, -3985e-6, 0.074746, -0.051948, 0.04735, 5699e-6, -0.047815, 5083e-6, -6656e-6, 0.058819, 0.017751, 9618e-6, -0.034329, -0.142559, -0.092611, -0.011707, 0.054788, 0.026713, 0.046238, -0.058496, 0.053149, -0.064674, -7911e-6, 0.025146, 0.090716, -0.095411, -0.025432, -4719e-6, 0.044307, -9021e-6, 0.03782, 5209e-6, 0.090933, 0.010226, -0.031091, 0.059074, 0.050608, 0.02373, -0.066836, -6565e-6, -0.019631, -0.010734, 0.051661, -0.114177, -143e-5, 0.012429, 0.075123, -0.028144, 146e-5, -0.024961, 0.018168, -0.07083, 0.118612, 0.069403, 0.025245, 0.058002, -0.02929, -0.028592, -0.108462, 0.041775, -0.053198, 0, 0.081256, -6094e-6, -7254e-6, 0.056054, -0.015568, 0.037045, 0.028584, 0.106462, -0.131533, -0.058554, -0.077175, 0.046473, -0.028723, 0.082435, 0.02169, -0.05884, -0.066908, 7516e-6, -0.024083, -0.016896, 0.043299, 0.025071, -0.052559, -0.036259, 0.018016, 0.014868, 0.059475, -0.10813, -734e-6, 0.013911, -0.069934, -0.023654, -0.046397, 0.028024, 7712e-6, 0.013454, -0.034854, 0.039348, -0.084795, -0.118392, -0.010387, 0.027472, -0.013331, -0.125895, -0.041034, 0.016784, -0.037666, 0.010413, 0.062172, -0.028341, 0.054028, 0.056302, -0.026385, 0.017281, 0.080924, 0.022605, 0.028539, 0.040226, 0.033684, 4577e-6, 0.026979, -0.011067, 659e-6, 0.085469, -0.020598, 0.049251, 0.041391, -0.010572, 0.097357, 0.043209, 0.037071, 0.025847, 0.012736, -0.0629, -0.024554, -0.093576, -0.038353, -0.11029, -0.041252, 0.017235, -0.059938, -0.013057, 6945e-6, -0.02508, 1215e-6, -0.023817, 0.030486, -0.14928, 0.033516, -0.032182, 778e-5, -0.058548, -0.028677, -5839e-6, -0.018994, -0, 0.014996, -0.058951, 0.048915, 0.047534, -0.053714, -0.025611, 0.039118, 0.045065, -0.011793, 0.065329, 0.03063, -0.033068, 0.025043, -0.032686, -0.038037, 0.056003, -0.043733, -0.019769, 0.02776, 0.120434, -0.029215, 0.041728, -0.074871, 0.110722, 0.047525, 0.081546, 0.028591, -0.030607, -0.023528, -0.103818, 0.02561, -0.069368, -0.103536, -0.041664, -0.088307, 0.018, 31e-4, -0.02202, -0.099577, 0.04134, 8269e-6, 0.092631, -0.093147, 0.024291, 0.01071, -0.017115, -0.090242, 0.029033, 0.041009, -0.067994, 0.027573, -9146e-6, 0.032512, -0.033344, 1196e-6, -0.081688, 0.027215, 0.053545, -0.134254, 0.033339, 0.043814, -0.014692, 0.044891, 0.015723, -6774e-6, -0.021276, -0.036136, 0.043279, -0.04103, -3137e-6, -0.025336, 0.027017, 0.031852, 0.037979, 0.056888, 0.016986, 0.015888, -0.046773, -8154e-6, -0.053904, -0.066498, -0.012196, 0.056062, 0.091648, -0.044858, -73e-4, 0.01175, 0.061546, -0.017644, 0.02004, -66e-5, -0.018841, -0.018539, 0.079675, 0.022509, -0, -0.064331, -0.026576, -0.042327, 0.028332, -5853e-6, -0.024744, 0.047413, 0.051537, -0.056245, 4566e-6, 0.036773, -0.029659, -0.079398, 0.052442, 8523e-6, 0.020647, 9384e-6, -3593e-6, -0.014809, -0.013876, -328e-6, 0.079194, 0.010541, 0.048098, 0.018196, -6731e-6, 0.03661, 0.05604, 0.119197, 0.027253, -0.041915, 0.046821, -0.053771, -0.02169, 0.046453, 0.08273, 0.053455, 3144e-6, -0.037192, 0.043435, 0.073059, -0.034059, -0.036581, -0.041038, 0.088468, 0.015768, -0.094215, -0.021958, 0.035929, 0.011529, -0.025067, -0.013653, -0.04267, 0.0741, 4846e-6, 0.039491, -1457e-6, 7501e-6, 0.104915, -0.062235, 0.049405, -0.074123, 0.092452, 0.022295] },
|
|
5113
5138
|
{ name: "list_entities", category: "graph", tier: 2, descriptionHash: "151c9f9cc7ae7935", embedding: [9869e-6, 0.039221, -0.017985, 0.062127, 0.017846, 0.011479, -0.053497, 0.012181, -0.027631, 0.022112, 0.024476, -0.067664, 0.036259, -6546e-6, 0.060455, 0.083451, 0.04418, 0.055013, 0.05941, -0.150598, 0.090187, 0.018138, -0.029135, -0.021231, -5622e-6, -0.045522, -0.093901, 4966e-6, 0.019375, -0.045165, -0.046949, 0.08159, -0.05141, 0.107208, -0.062976, 0.015833, 0.072251, -0.034373, 7219e-6, -0.034998, 1076e-6, 0.013932, -0.015443, -0.025458, -0.026742, 0.020433, -0.110288, -0.017173, -0.059967, -572e-6, -0.07416, 0.038236, -0.052883, 0.05788, 0.068984, 0.076051, -0.018585, -0.029614, -0.060105, 8377e-6, 1809e-6, -0.016518, -9934e-6, 6265e-6, -0.053017, -9911e-6, 8147e-6, -404e-6, 0.043481, -0.098265, 0.080826, -0.038752, -0.055578, -0.021447, 0.046618, 5738e-6, 0.018936, 0.018056, -6225e-6, -0.09769, -0.11041, 0.089765, 0.041564, -4204e-6, -0.012703, -0.044349, -0.016736, -0.082801, -0.048237, 0.048849, -4514e-6, -0.014904, 0.091902, 0.011808, 0.06668, 0.059157, 0.067194, -0.081303, 0.044341, 0.016443, -0.039689, 0.02914, -0.032206, 0.021104, -0.073646, -0.013962, -0.014455, 0.040568, -0.022705, -8866e-6, -0.011802, 0.118062, -0.016973, -0.045874, 0.011322, -0.048643, -3256e-6, -0.0199, 0.063331, 0.037032, 0.042789, 0.03297, 6748e-6, -0.037267, -0.029454, 0.055477, -0.031838, 0, 0.132252, 0.032721, 0.040518, -0.029734, -0.088739, 0.028325, -0.027406, -8194e-6, -0.035274, 0.026574, -0.10169, 0.132857, -0.01054, 0.085067, 0.072249, -0.018404, 0.029723, 0.124009, 0.050307, -0.044323, 4088e-6, 0.034195, 8592e-6, 0.023349, 0.03524, 0.073328, -0.042406, -0.062921, -0.048544, 0.043889, -9885e-6, -0.046737, 4034e-6, 2817e-6, 0.023997, 0.066605, -0.041633, 0.023126, -0.028927, -0.076544, 0.027614, -0.025601, 0.022261, -0.039308, -0.08337, -102e-6, -0.039863, -0.058725, 0.041901, 0.062422, -261e-5, 155e-5, -0.02527, 0.047808, 0.016203, 0.020861, 0.072298, 7431e-6, -0.025393, 0.050597, 128e-6, -0.018836, -0.014498, 0.010012, -5951e-6, 0.029245, -0.029082, -0.042208, 0.06618, 0.011464, 0.046211, 0.100401, 0.096154, 101e-5, 893e-6, -0.065115, -0.074135, -0.146964, -0.034718, 0.025901, -0.050778, -0.039288, -0.060746, -0.017685, 0.029436, -0.042277, 3545e-6, -0.076755, 4314e-6, -0.032518, -0.07518, -2035e-6, 9925e-6, 121e-5, -0.031225, -0, 0.03046, -0.020084, 0.084786, -0.047479, 396e-6, -0.090925, 0.045119, 1007e-6, -0.090049, 0.087244, 1199e-6, -0.0213, -2816e-6, -0.034068, 0.046173, -0.019643, -0.052543, -0.061895, 4877e-6, 0.098381, -0.0366, -0.036437, -0.091761, 0.115674, 0.077214, -4719e-6, -0.036058, -0.074632, 0.040946, -0.080891, 0.076584, -0.071783, -0.030318, -0.018569, -6304e-6, -0.028519, -0.011312, -0.085765, -0.081931, -0.028463, -0.041507, 0.045099, -0.070759, 0.031346, 2321e-6, -0.014253, -9167e-6, 0.071664, -0.017914, -0.044684, -7361e-6, 0.033823, 0.064097, 0.034082, 0.031671, 9526e-6, -0.046141, 0.071486, -0.06172, -2236e-6, 0.030522, -3738e-6, -0.048973, 0.098027, 495e-5, -0.080678, 2526e-6, -0.049155, -0.064288, -0.01438, 0.01443, -0.017578, 9537e-6, -0.047826, 0.056887, -0.052009, -0.024801, 0.023291, -0.024461, 0.012786, -0.023644, -0.037693, 0.047088, 0.032393, 0.046701, -0.061738, 0.028013, 0.08225, 4238e-6, 0.039802, -0.028564, -0.050046, -0.115669, 0.074233, 0.050805, -0, -0.082516, 0.015736, -5736e-6, -0.033366, -0.028511, 9821e-6, 0.052369, 0.086908, -0.066551, 0.051093, 0.045218, -7851e-6, -0.121843, 4426e-6, 0.103404, -0.028686, 0.068992, 0.028774, 0.033047, 0.072594, -0.096302, -0.014749, -0.046137, -0.042746, -0.016003, -545e-5, -3868e-6, 0.047832, 0.046029, 0.038886, 0.025325, 0.070839, 0.015144, 8753e-6, 0.015014, 0.035623, 5691e-6, 0.010876, 4773e-6, 0.078394, 0.092455, 0.055167, -9887e-6, 0.067516, 0.051329, 0.031391, -0.01022, 0.017734, 0.064036, -0.063985, -0.124364, -0.058518, -0.089096, -0.042014, -0.023448, 0.04869, 0.013319, -0.032993, 0.058465, -0.016633, 0.130929, -0.055697, 7264e-6, -0.018472] },
|
|
@@ -5158,28 +5183,207 @@ var init_tool_embeddings_generated = __esm({
|
|
|
5158
5183
|
}
|
|
5159
5184
|
});
|
|
5160
5185
|
|
|
5161
|
-
// src/core/write/
|
|
5162
|
-
function estimateTokens(content) {
|
|
5163
|
-
const str = typeof content === "string" ? content : JSON.stringify(content);
|
|
5164
|
-
return Math.ceil(str.length / 4);
|
|
5165
|
-
}
|
|
5166
|
-
var HEADING_REGEX3;
|
|
5167
|
-
var init_constants2 = __esm({
|
|
5168
|
-
"src/core/write/constants.ts"() {
|
|
5169
|
-
"use strict";
|
|
5170
|
-
HEADING_REGEX3 = /^(#{1,6})\s+(.+)$/;
|
|
5171
|
-
}
|
|
5172
|
-
});
|
|
5173
|
-
|
|
5174
|
-
// src/core/write/writer.ts
|
|
5186
|
+
// src/core/write/path-security.ts
|
|
5175
5187
|
import fs20 from "fs/promises";
|
|
5176
5188
|
import path22 from "path";
|
|
5177
|
-
import matter5 from "gray-matter";
|
|
5178
|
-
import { createHash as createHash2 } from "node:crypto";
|
|
5179
5189
|
function isSensitivePath(filePath) {
|
|
5180
5190
|
const normalizedPath = filePath.replace(/\\/g, "/");
|
|
5181
5191
|
return SENSITIVE_PATH_PATTERNS.some((pattern) => pattern.test(normalizedPath));
|
|
5182
5192
|
}
|
|
5193
|
+
function isWithinDirectory(child, parent, allowEqual = false) {
|
|
5194
|
+
const rel = path22.relative(path22.resolve(parent), path22.resolve(child));
|
|
5195
|
+
if (rel === "") return allowEqual;
|
|
5196
|
+
const firstSeg = rel.split(path22.sep)[0];
|
|
5197
|
+
return firstSeg !== ".." && !path22.isAbsolute(rel);
|
|
5198
|
+
}
|
|
5199
|
+
function validatePath(vaultPath2, notePath) {
|
|
5200
|
+
if (notePath.startsWith("/")) {
|
|
5201
|
+
return false;
|
|
5202
|
+
}
|
|
5203
|
+
if (process.platform === "win32" && /^[a-zA-Z]:/.test(notePath)) {
|
|
5204
|
+
return false;
|
|
5205
|
+
}
|
|
5206
|
+
if (notePath.startsWith("\\")) {
|
|
5207
|
+
return false;
|
|
5208
|
+
}
|
|
5209
|
+
return isWithinDirectory(path22.resolve(vaultPath2, notePath), vaultPath2);
|
|
5210
|
+
}
|
|
5211
|
+
function sanitizeNotePath(notePath) {
|
|
5212
|
+
const dir = path22.dirname(notePath);
|
|
5213
|
+
let filename = path22.basename(notePath);
|
|
5214
|
+
const ext = filename.endsWith(".md") ? ".md" : "";
|
|
5215
|
+
let stem2 = ext ? filename.slice(0, -ext.length) : filename;
|
|
5216
|
+
stem2 = stem2.replace(/\s+/g, "-");
|
|
5217
|
+
stem2 = stem2.replace(/[?*<>|":]/g, "");
|
|
5218
|
+
stem2 = stem2.toLowerCase();
|
|
5219
|
+
stem2 = stem2.replace(/-{2,}/g, "-");
|
|
5220
|
+
stem2 = stem2.replace(/^-+|-+$/g, "");
|
|
5221
|
+
filename = stem2 + (ext || ".md");
|
|
5222
|
+
return dir === "." ? filename : path22.join(dir, filename).replace(/\\/g, "/");
|
|
5223
|
+
}
|
|
5224
|
+
async function validatePathSecure(vaultPath2, notePath) {
|
|
5225
|
+
if (notePath.startsWith("/")) {
|
|
5226
|
+
return {
|
|
5227
|
+
valid: false,
|
|
5228
|
+
reason: "Absolute paths not allowed"
|
|
5229
|
+
};
|
|
5230
|
+
}
|
|
5231
|
+
if (process.platform === "win32" && /^[a-zA-Z]:/.test(notePath)) {
|
|
5232
|
+
return {
|
|
5233
|
+
valid: false,
|
|
5234
|
+
reason: "Absolute paths not allowed"
|
|
5235
|
+
};
|
|
5236
|
+
}
|
|
5237
|
+
if (notePath.startsWith("\\")) {
|
|
5238
|
+
return {
|
|
5239
|
+
valid: false,
|
|
5240
|
+
reason: "Absolute paths not allowed"
|
|
5241
|
+
};
|
|
5242
|
+
}
|
|
5243
|
+
const firstSeg = path22.normalize(notePath).split(path22.sep).filter(Boolean)[0];
|
|
5244
|
+
if (firstSeg === "..") {
|
|
5245
|
+
return {
|
|
5246
|
+
valid: false,
|
|
5247
|
+
reason: "Path traversal not allowed"
|
|
5248
|
+
};
|
|
5249
|
+
}
|
|
5250
|
+
if (!isWithinDirectory(path22.resolve(vaultPath2, notePath), vaultPath2)) {
|
|
5251
|
+
return {
|
|
5252
|
+
valid: false,
|
|
5253
|
+
reason: "Path traversal not allowed"
|
|
5254
|
+
};
|
|
5255
|
+
}
|
|
5256
|
+
if (isSensitivePath(notePath)) {
|
|
5257
|
+
return {
|
|
5258
|
+
valid: false,
|
|
5259
|
+
reason: "Cannot write to sensitive file (credentials, keys, secrets)"
|
|
5260
|
+
};
|
|
5261
|
+
}
|
|
5262
|
+
try {
|
|
5263
|
+
const fullPath = path22.join(vaultPath2, notePath);
|
|
5264
|
+
try {
|
|
5265
|
+
await fs20.access(fullPath);
|
|
5266
|
+
const realPath = await fs20.realpath(fullPath);
|
|
5267
|
+
const realVaultPath = await fs20.realpath(vaultPath2);
|
|
5268
|
+
if (!isWithinDirectory(realPath, realVaultPath)) {
|
|
5269
|
+
return {
|
|
5270
|
+
valid: false,
|
|
5271
|
+
reason: "Symlink target is outside vault"
|
|
5272
|
+
};
|
|
5273
|
+
}
|
|
5274
|
+
const relativePath = path22.relative(realVaultPath, realPath);
|
|
5275
|
+
if (isSensitivePath(relativePath)) {
|
|
5276
|
+
return {
|
|
5277
|
+
valid: false,
|
|
5278
|
+
reason: "Symlink target is a sensitive file"
|
|
5279
|
+
};
|
|
5280
|
+
}
|
|
5281
|
+
} catch {
|
|
5282
|
+
const parentDir = path22.dirname(fullPath);
|
|
5283
|
+
try {
|
|
5284
|
+
await fs20.access(parentDir);
|
|
5285
|
+
const realParentPath = await fs20.realpath(parentDir);
|
|
5286
|
+
const realVaultPath = await fs20.realpath(vaultPath2);
|
|
5287
|
+
if (!isWithinDirectory(realParentPath, realVaultPath, true)) {
|
|
5288
|
+
return {
|
|
5289
|
+
valid: false,
|
|
5290
|
+
reason: "Parent directory symlink target is outside vault"
|
|
5291
|
+
};
|
|
5292
|
+
}
|
|
5293
|
+
} catch {
|
|
5294
|
+
}
|
|
5295
|
+
}
|
|
5296
|
+
} catch (error) {
|
|
5297
|
+
return {
|
|
5298
|
+
valid: false,
|
|
5299
|
+
reason: `Path validation error: ${error.message}`
|
|
5300
|
+
};
|
|
5301
|
+
}
|
|
5302
|
+
return { valid: true };
|
|
5303
|
+
}
|
|
5304
|
+
var SENSITIVE_PATH_PATTERNS;
|
|
5305
|
+
var init_path_security = __esm({
|
|
5306
|
+
"src/core/write/path-security.ts"() {
|
|
5307
|
+
"use strict";
|
|
5308
|
+
SENSITIVE_PATH_PATTERNS = [
|
|
5309
|
+
// Environment files (including backups, variations, and Windows ADS)
|
|
5310
|
+
/\.env($|\..*|~|\.swp|\.swo|:)/i,
|
|
5311
|
+
// .env, .env.local, .env~, .env.swp, .env:$DATA (ADS), etc.
|
|
5312
|
+
// Git credentials and config
|
|
5313
|
+
/\.git\/config$/i,
|
|
5314
|
+
// Git config (may contain tokens)
|
|
5315
|
+
/\.git\/credentials$/i,
|
|
5316
|
+
// Git credentials
|
|
5317
|
+
// SSL/TLS certificates and private keys (including backups)
|
|
5318
|
+
/\.pem($|\.bak|\.backup|\.old|\.orig|~)$/i,
|
|
5319
|
+
// SSL/TLS certificates + backups
|
|
5320
|
+
/\.key($|\.bak|\.backup|\.old|\.orig|~)$/i,
|
|
5321
|
+
// Private keys + backups
|
|
5322
|
+
/\.p12($|\.bak|\.backup|\.old|\.orig|~)$/i,
|
|
5323
|
+
// PKCS#12 certificates + backups
|
|
5324
|
+
/\.pfx($|\.bak|\.backup|\.old|\.orig|~)$/i,
|
|
5325
|
+
// Windows certificate format + backups
|
|
5326
|
+
/\.jks($|\.bak|\.backup|\.old|\.orig|~)$/i,
|
|
5327
|
+
// Java keystore + backups
|
|
5328
|
+
/\.crt($|\.bak|\.backup|\.old|\.orig|~)$/i,
|
|
5329
|
+
// Certificate files + backups
|
|
5330
|
+
// SSH keys
|
|
5331
|
+
/id_rsa/i,
|
|
5332
|
+
// SSH private key
|
|
5333
|
+
/id_ed25519/i,
|
|
5334
|
+
// SSH private key (ed25519)
|
|
5335
|
+
/id_ecdsa/i,
|
|
5336
|
+
// SSH private key (ecdsa)
|
|
5337
|
+
/id_dsa/i,
|
|
5338
|
+
// SSH private key (dsa)
|
|
5339
|
+
/\.ssh\/config$/i,
|
|
5340
|
+
// SSH config
|
|
5341
|
+
/authorized_keys$/i,
|
|
5342
|
+
// SSH authorized keys
|
|
5343
|
+
/known_hosts$/i,
|
|
5344
|
+
// SSH known hosts
|
|
5345
|
+
// Generic credentials/secrets files (including backups)
|
|
5346
|
+
/credentials\.json($|\.bak|\.backup|\.old|\.orig|~)$/i,
|
|
5347
|
+
// Cloud credentials + backups
|
|
5348
|
+
/secrets\.json($|\.bak|\.backup|\.old|\.orig|~)$/i,
|
|
5349
|
+
// Secrets files + backups
|
|
5350
|
+
/secrets\.ya?ml($|\.bak|\.backup|\.old|\.orig|~)$/i,
|
|
5351
|
+
// Secrets YAML + backups
|
|
5352
|
+
// Package manager auth
|
|
5353
|
+
/\.npmrc$/i,
|
|
5354
|
+
// npm config (may contain tokens)
|
|
5355
|
+
/\.netrc$/i,
|
|
5356
|
+
// Netrc (HTTP auth credentials)
|
|
5357
|
+
/\.yarnrc$/i,
|
|
5358
|
+
// Yarn config
|
|
5359
|
+
// Cloud provider credentials
|
|
5360
|
+
/\.aws\/credentials$/i,
|
|
5361
|
+
// AWS credentials
|
|
5362
|
+
/\.aws\/config$/i,
|
|
5363
|
+
// AWS config
|
|
5364
|
+
/gcloud\/credentials\.json/i,
|
|
5365
|
+
// Google Cloud credentials
|
|
5366
|
+
/\.azure\/credentials$/i,
|
|
5367
|
+
// Azure credentials
|
|
5368
|
+
/\.docker\/config\.json$/i,
|
|
5369
|
+
// Docker registry auth
|
|
5370
|
+
/\.kube\/config$/i,
|
|
5371
|
+
// Kubernetes config
|
|
5372
|
+
// System password files
|
|
5373
|
+
/\.htpasswd$/i,
|
|
5374
|
+
// Apache password file
|
|
5375
|
+
/shadow$/,
|
|
5376
|
+
// Unix shadow password file
|
|
5377
|
+
/passwd$/,
|
|
5378
|
+
// Unix password file
|
|
5379
|
+
// Hidden credential files (starting with dot)
|
|
5380
|
+
/^\.(credentials|secrets|tokens)$/i
|
|
5381
|
+
// .credentials, .secrets, .tokens
|
|
5382
|
+
];
|
|
5383
|
+
}
|
|
5384
|
+
});
|
|
5385
|
+
|
|
5386
|
+
// src/core/write/regex-safety.ts
|
|
5183
5387
|
function checkRegexSafety(pattern) {
|
|
5184
5388
|
if (pattern.length > MAX_REGEX_LENGTH) {
|
|
5185
5389
|
return `Regex pattern too long (${pattern.length} chars, max ${MAX_REGEX_LENGTH})`;
|
|
@@ -5216,21 +5420,62 @@ function safeRegexReplace(input, pattern, replacement, useRegex, global = false)
|
|
|
5216
5420
|
const regex = createSafeRegex(pattern, global ? "g" : void 0);
|
|
5217
5421
|
return input.replace(regex, replacement);
|
|
5218
5422
|
}
|
|
5219
|
-
|
|
5220
|
-
|
|
5221
|
-
|
|
5222
|
-
|
|
5223
|
-
|
|
5224
|
-
|
|
5225
|
-
|
|
5226
|
-
|
|
5227
|
-
|
|
5228
|
-
|
|
5423
|
+
var REDOS_PATTERNS, MAX_REGEX_LENGTH;
|
|
5424
|
+
var init_regex_safety = __esm({
|
|
5425
|
+
"src/core/write/regex-safety.ts"() {
|
|
5426
|
+
"use strict";
|
|
5427
|
+
REDOS_PATTERNS = [
|
|
5428
|
+
// Nested quantifiers: (a+)+, (a*)+, (a+)*, (a*)*, etc.
|
|
5429
|
+
/(\([^)]*[+*][^)]*\))[+*]/,
|
|
5430
|
+
// Quantifiers followed by optional same-type quantifiers
|
|
5431
|
+
/[+*]\??\s*[+*]/,
|
|
5432
|
+
// Overlapping character classes with quantifiers followed by similar
|
|
5433
|
+
/\[[^\]]*\][+*].*\[[^\]]*\][+*]/,
|
|
5434
|
+
// Multiple adjacent capturing groups with quantifiers
|
|
5435
|
+
/(\([^)]+[+*]\)){2,}/,
|
|
5436
|
+
// Extremely long alternation groups
|
|
5437
|
+
/\([^)]{100,}\)/
|
|
5438
|
+
];
|
|
5439
|
+
MAX_REGEX_LENGTH = 500;
|
|
5440
|
+
}
|
|
5441
|
+
});
|
|
5442
|
+
|
|
5443
|
+
// src/core/write/line-endings.ts
|
|
5444
|
+
function detectLineEnding(content) {
|
|
5445
|
+
const crlfCount = (content.match(/\r\n/g) || []).length;
|
|
5446
|
+
const lfCount = (content.match(/(?<!\r)\n/g) || []).length;
|
|
5447
|
+
return crlfCount > lfCount ? "CRLF" : "LF";
|
|
5448
|
+
}
|
|
5449
|
+
function normalizeLineEndings(content) {
|
|
5450
|
+
return content.replace(/\r\n/g, "\n");
|
|
5451
|
+
}
|
|
5452
|
+
function convertLineEndings(content, style) {
|
|
5453
|
+
const normalized = content.replace(/\r\n/g, "\n");
|
|
5229
5454
|
return style === "CRLF" ? normalized.replace(/\n/g, "\r\n") : normalized;
|
|
5230
5455
|
}
|
|
5231
5456
|
function normalizeTrailingNewline(content) {
|
|
5232
5457
|
return content.replace(/[\r\n\s]+$/, "") + "\n";
|
|
5233
5458
|
}
|
|
5459
|
+
var init_line_endings = __esm({
|
|
5460
|
+
"src/core/write/line-endings.ts"() {
|
|
5461
|
+
"use strict";
|
|
5462
|
+
}
|
|
5463
|
+
});
|
|
5464
|
+
|
|
5465
|
+
// src/core/write/constants.ts
|
|
5466
|
+
function estimateTokens(content) {
|
|
5467
|
+
const str = typeof content === "string" ? content : JSON.stringify(content);
|
|
5468
|
+
return Math.ceil(str.length / 4);
|
|
5469
|
+
}
|
|
5470
|
+
var HEADING_REGEX3;
|
|
5471
|
+
var init_constants2 = __esm({
|
|
5472
|
+
"src/core/write/constants.ts"() {
|
|
5473
|
+
"use strict";
|
|
5474
|
+
HEADING_REGEX3 = /^(#{1,6})\s+(.+)$/;
|
|
5475
|
+
}
|
|
5476
|
+
});
|
|
5477
|
+
|
|
5478
|
+
// src/core/write/markdown-structure.ts
|
|
5234
5479
|
function isEmptyPlaceholder(line) {
|
|
5235
5480
|
const trimmed = line.trim();
|
|
5236
5481
|
return EMPTY_PLACEHOLDER_PATTERNS.some((p) => p.test(trimmed));
|
|
@@ -5536,189 +5781,27 @@ function insertInSection(content, section, newContent, position, options) {
|
|
|
5536
5781
|
}
|
|
5537
5782
|
return lines.join("\n");
|
|
5538
5783
|
}
|
|
5539
|
-
|
|
5540
|
-
|
|
5541
|
-
|
|
5542
|
-
|
|
5543
|
-
|
|
5544
|
-
|
|
5545
|
-
|
|
5546
|
-
|
|
5547
|
-
|
|
5548
|
-
|
|
5549
|
-
|
|
5550
|
-
|
|
5551
|
-
|
|
5552
|
-
|
|
5553
|
-
|
|
5554
|
-
|
|
5555
|
-
|
|
5556
|
-
const ext = filename.endsWith(".md") ? ".md" : "";
|
|
5557
|
-
let stem2 = ext ? filename.slice(0, -ext.length) : filename;
|
|
5558
|
-
stem2 = stem2.replace(/\s+/g, "-");
|
|
5559
|
-
stem2 = stem2.replace(/[?*<>|":]/g, "");
|
|
5560
|
-
stem2 = stem2.toLowerCase();
|
|
5561
|
-
stem2 = stem2.replace(/-{2,}/g, "-");
|
|
5562
|
-
stem2 = stem2.replace(/^-+|-+$/g, "");
|
|
5563
|
-
filename = stem2 + (ext || ".md");
|
|
5564
|
-
return dir === "." ? filename : path22.join(dir, filename).replace(/\\/g, "/");
|
|
5565
|
-
}
|
|
5566
|
-
async function validatePathSecure(vaultPath2, notePath) {
|
|
5567
|
-
if (notePath.startsWith("/")) {
|
|
5568
|
-
return {
|
|
5569
|
-
valid: false,
|
|
5570
|
-
reason: "Absolute paths not allowed"
|
|
5571
|
-
};
|
|
5572
|
-
}
|
|
5573
|
-
if (process.platform === "win32" && /^[a-zA-Z]:/.test(notePath)) {
|
|
5574
|
-
return {
|
|
5575
|
-
valid: false,
|
|
5576
|
-
reason: "Absolute paths not allowed"
|
|
5577
|
-
};
|
|
5578
|
-
}
|
|
5579
|
-
if (notePath.startsWith("\\")) {
|
|
5580
|
-
return {
|
|
5581
|
-
valid: false,
|
|
5582
|
-
reason: "Absolute paths not allowed"
|
|
5583
|
-
};
|
|
5584
|
-
}
|
|
5585
|
-
if (notePath.startsWith("..")) {
|
|
5586
|
-
return {
|
|
5587
|
-
valid: false,
|
|
5588
|
-
reason: "Path traversal not allowed"
|
|
5589
|
-
};
|
|
5590
|
-
}
|
|
5591
|
-
const resolvedVault = path22.resolve(vaultPath2);
|
|
5592
|
-
const resolvedNote = path22.resolve(vaultPath2, notePath);
|
|
5593
|
-
if (!resolvedNote.startsWith(resolvedVault)) {
|
|
5594
|
-
return {
|
|
5595
|
-
valid: false,
|
|
5596
|
-
reason: "Path traversal not allowed"
|
|
5597
|
-
};
|
|
5598
|
-
}
|
|
5599
|
-
if (isSensitivePath(notePath)) {
|
|
5600
|
-
return {
|
|
5601
|
-
valid: false,
|
|
5602
|
-
reason: "Cannot write to sensitive file (credentials, keys, secrets)"
|
|
5603
|
-
};
|
|
5604
|
-
}
|
|
5605
|
-
try {
|
|
5606
|
-
const fullPath = path22.join(vaultPath2, notePath);
|
|
5607
|
-
try {
|
|
5608
|
-
await fs20.access(fullPath);
|
|
5609
|
-
const realPath = await fs20.realpath(fullPath);
|
|
5610
|
-
const realVaultPath = await fs20.realpath(vaultPath2);
|
|
5611
|
-
if (!realPath.startsWith(realVaultPath)) {
|
|
5612
|
-
return {
|
|
5613
|
-
valid: false,
|
|
5614
|
-
reason: "Symlink target is outside vault"
|
|
5615
|
-
};
|
|
5616
|
-
}
|
|
5617
|
-
const relativePath = path22.relative(realVaultPath, realPath);
|
|
5618
|
-
if (isSensitivePath(relativePath)) {
|
|
5619
|
-
return {
|
|
5620
|
-
valid: false,
|
|
5621
|
-
reason: "Symlink target is a sensitive file"
|
|
5622
|
-
};
|
|
5623
|
-
}
|
|
5624
|
-
} catch {
|
|
5625
|
-
const parentDir = path22.dirname(fullPath);
|
|
5626
|
-
try {
|
|
5627
|
-
await fs20.access(parentDir);
|
|
5628
|
-
const realParentPath = await fs20.realpath(parentDir);
|
|
5629
|
-
const realVaultPath = await fs20.realpath(vaultPath2);
|
|
5630
|
-
if (!realParentPath.startsWith(realVaultPath)) {
|
|
5631
|
-
return {
|
|
5632
|
-
valid: false,
|
|
5633
|
-
reason: "Parent directory symlink target is outside vault"
|
|
5634
|
-
};
|
|
5635
|
-
}
|
|
5636
|
-
} catch {
|
|
5637
|
-
}
|
|
5638
|
-
}
|
|
5639
|
-
} catch (error) {
|
|
5640
|
-
return {
|
|
5641
|
-
valid: false,
|
|
5642
|
-
reason: `Path validation error: ${error.message}`
|
|
5643
|
-
};
|
|
5644
|
-
}
|
|
5645
|
-
return { valid: true };
|
|
5646
|
-
}
|
|
5647
|
-
function computeContentHash(rawContent) {
|
|
5648
|
-
return createHash2("sha256").update(rawContent).digest("hex").slice(0, 16);
|
|
5649
|
-
}
|
|
5650
|
-
async function readVaultFile(vaultPath2, notePath) {
|
|
5651
|
-
if (!validatePath(vaultPath2, notePath)) {
|
|
5652
|
-
throw new Error("Invalid path: path traversal not allowed");
|
|
5653
|
-
}
|
|
5654
|
-
const fullPath = path22.join(vaultPath2, notePath);
|
|
5655
|
-
const [rawContent, stat5] = await Promise.all([
|
|
5656
|
-
fs20.readFile(fullPath, "utf-8"),
|
|
5657
|
-
fs20.stat(fullPath)
|
|
5658
|
-
]);
|
|
5659
|
-
const contentHash2 = computeContentHash(rawContent);
|
|
5660
|
-
const lineEnding = detectLineEnding(rawContent);
|
|
5661
|
-
const normalizedContent = normalizeLineEndings(rawContent);
|
|
5662
|
-
const parsed = matter5(normalizedContent);
|
|
5663
|
-
const frontmatter = deepCloneFrontmatter(parsed.data);
|
|
5664
|
-
return {
|
|
5665
|
-
content: parsed.content,
|
|
5666
|
-
frontmatter,
|
|
5667
|
-
rawContent,
|
|
5668
|
-
lineEnding,
|
|
5669
|
-
mtimeMs: stat5.mtimeMs,
|
|
5670
|
-
contentHash: contentHash2
|
|
5671
|
-
};
|
|
5672
|
-
}
|
|
5673
|
-
function deepCloneFrontmatter(obj) {
|
|
5674
|
-
if (obj === null || typeof obj !== "object") {
|
|
5675
|
-
return obj;
|
|
5676
|
-
}
|
|
5677
|
-
if (obj instanceof Date) {
|
|
5678
|
-
return new Date(obj.getTime());
|
|
5679
|
-
}
|
|
5680
|
-
if (Array.isArray(obj)) {
|
|
5681
|
-
return obj.map((item) => {
|
|
5682
|
-
if (item instanceof Date) {
|
|
5683
|
-
return new Date(item.getTime());
|
|
5684
|
-
}
|
|
5685
|
-
if (item !== null && typeof item === "object") {
|
|
5686
|
-
return deepCloneFrontmatter(item);
|
|
5687
|
-
}
|
|
5688
|
-
return item;
|
|
5689
|
-
});
|
|
5690
|
-
}
|
|
5691
|
-
const cloned = {};
|
|
5692
|
-
for (const key of Object.keys(obj)) {
|
|
5693
|
-
const value = obj[key];
|
|
5694
|
-
if (value instanceof Date) {
|
|
5695
|
-
cloned[key] = new Date(value.getTime());
|
|
5696
|
-
} else if (value !== null && typeof value === "object") {
|
|
5697
|
-
cloned[key] = deepCloneFrontmatter(value);
|
|
5698
|
-
} else {
|
|
5699
|
-
cloned[key] = value;
|
|
5700
|
-
}
|
|
5701
|
-
}
|
|
5702
|
-
return cloned;
|
|
5703
|
-
}
|
|
5704
|
-
async function writeVaultFile(vaultPath2, notePath, content, frontmatter, lineEnding = "LF", expectedHash) {
|
|
5705
|
-
const validation = await validatePathSecure(vaultPath2, notePath);
|
|
5706
|
-
if (!validation.valid) {
|
|
5707
|
-
throw new Error(`Invalid path: ${validation.reason}`);
|
|
5708
|
-
}
|
|
5709
|
-
const fullPath = path22.join(vaultPath2, notePath);
|
|
5710
|
-
if (expectedHash) {
|
|
5711
|
-
const currentRaw = await fs20.readFile(fullPath, "utf-8");
|
|
5712
|
-
const currentHash = computeContentHash(currentRaw);
|
|
5713
|
-
if (currentHash !== expectedHash) {
|
|
5714
|
-
throw new WriteConflictError(notePath);
|
|
5715
|
-
}
|
|
5784
|
+
var EMPTY_PLACEHOLDER_PATTERNS;
|
|
5785
|
+
var init_markdown_structure = __esm({
|
|
5786
|
+
"src/core/write/markdown-structure.ts"() {
|
|
5787
|
+
"use strict";
|
|
5788
|
+
init_constants2();
|
|
5789
|
+
EMPTY_PLACEHOLDER_PATTERNS = [
|
|
5790
|
+
/^\d+\.\s*$/,
|
|
5791
|
+
// "1. " or "2. " (numbered list placeholder)
|
|
5792
|
+
/^-\s*$/,
|
|
5793
|
+
// "- " (bullet placeholder)
|
|
5794
|
+
/^-\s*\[\s*\]\s*$/,
|
|
5795
|
+
// "- [ ] " (empty task placeholder)
|
|
5796
|
+
/^-\s*\[x\]\s*$/i,
|
|
5797
|
+
// "- [x] " (completed task placeholder)
|
|
5798
|
+
/^\*\s*$/
|
|
5799
|
+
// "* " (asterisk bullet placeholder)
|
|
5800
|
+
];
|
|
5716
5801
|
}
|
|
5717
|
-
|
|
5718
|
-
|
|
5719
|
-
|
|
5720
|
-
await fs20.writeFile(fullPath, output, "utf-8");
|
|
5721
|
-
}
|
|
5802
|
+
});
|
|
5803
|
+
|
|
5804
|
+
// src/core/write/content-mutation.ts
|
|
5722
5805
|
function removeFromSection(content, section, pattern, mode = "first", useRegex = false) {
|
|
5723
5806
|
const lines = content.split("\n");
|
|
5724
5807
|
const removedLines = [];
|
|
@@ -5954,114 +6037,112 @@ function injectMutationMetadata(frontmatter, scoping) {
|
|
|
5954
6037
|
frontmatter._last_modified_by = `session:${scoping.session_id}`;
|
|
5955
6038
|
}
|
|
5956
6039
|
}
|
|
5957
|
-
return frontmatter;
|
|
6040
|
+
return frontmatter;
|
|
6041
|
+
}
|
|
6042
|
+
var DiagnosticError;
|
|
6043
|
+
var init_content_mutation = __esm({
|
|
6044
|
+
"src/core/write/content-mutation.ts"() {
|
|
6045
|
+
"use strict";
|
|
6046
|
+
init_regex_safety();
|
|
6047
|
+
init_levenshtein();
|
|
6048
|
+
DiagnosticError = class extends Error {
|
|
6049
|
+
diagnostic;
|
|
6050
|
+
constructor(message, diagnostic) {
|
|
6051
|
+
super(message);
|
|
6052
|
+
this.name = "DiagnosticError";
|
|
6053
|
+
this.diagnostic = diagnostic;
|
|
6054
|
+
}
|
|
6055
|
+
};
|
|
6056
|
+
}
|
|
6057
|
+
});
|
|
6058
|
+
|
|
6059
|
+
// src/core/write/file-io.ts
|
|
6060
|
+
import fs21 from "fs/promises";
|
|
6061
|
+
import path23 from "path";
|
|
6062
|
+
import matter5 from "gray-matter";
|
|
6063
|
+
import { createHash as createHash2 } from "node:crypto";
|
|
6064
|
+
function computeContentHash(rawContent) {
|
|
6065
|
+
return createHash2("sha256").update(rawContent).digest("hex").slice(0, 16);
|
|
6066
|
+
}
|
|
6067
|
+
async function readVaultFile(vaultPath2, notePath) {
|
|
6068
|
+
const validation = await validatePathSecure(vaultPath2, notePath);
|
|
6069
|
+
if (!validation.valid) {
|
|
6070
|
+
throw new Error(`Invalid path: ${validation.reason}`);
|
|
6071
|
+
}
|
|
6072
|
+
const fullPath = path23.join(vaultPath2, notePath);
|
|
6073
|
+
const [rawContent, stat4] = await Promise.all([
|
|
6074
|
+
fs21.readFile(fullPath, "utf-8"),
|
|
6075
|
+
fs21.stat(fullPath)
|
|
6076
|
+
]);
|
|
6077
|
+
const contentHash2 = computeContentHash(rawContent);
|
|
6078
|
+
const lineEnding = detectLineEnding(rawContent);
|
|
6079
|
+
const normalizedContent = normalizeLineEndings(rawContent);
|
|
6080
|
+
const parsed = matter5(normalizedContent);
|
|
6081
|
+
const frontmatter = deepCloneFrontmatter(parsed.data);
|
|
6082
|
+
return {
|
|
6083
|
+
content: parsed.content,
|
|
6084
|
+
frontmatter,
|
|
6085
|
+
rawContent,
|
|
6086
|
+
lineEnding,
|
|
6087
|
+
mtimeMs: stat4.mtimeMs,
|
|
6088
|
+
contentHash: contentHash2
|
|
6089
|
+
};
|
|
6090
|
+
}
|
|
6091
|
+
function deepCloneFrontmatter(obj) {
|
|
6092
|
+
if (obj === null || typeof obj !== "object") {
|
|
6093
|
+
return obj;
|
|
6094
|
+
}
|
|
6095
|
+
if (obj instanceof Date) {
|
|
6096
|
+
return new Date(obj.getTime());
|
|
6097
|
+
}
|
|
6098
|
+
if (Array.isArray(obj)) {
|
|
6099
|
+
return obj.map((item) => {
|
|
6100
|
+
if (item instanceof Date) {
|
|
6101
|
+
return new Date(item.getTime());
|
|
6102
|
+
}
|
|
6103
|
+
if (item !== null && typeof item === "object") {
|
|
6104
|
+
return deepCloneFrontmatter(item);
|
|
6105
|
+
}
|
|
6106
|
+
return item;
|
|
6107
|
+
});
|
|
6108
|
+
}
|
|
6109
|
+
const cloned = {};
|
|
6110
|
+
for (const key of Object.keys(obj)) {
|
|
6111
|
+
const value = obj[key];
|
|
6112
|
+
if (value instanceof Date) {
|
|
6113
|
+
cloned[key] = new Date(value.getTime());
|
|
6114
|
+
} else if (value !== null && typeof value === "object") {
|
|
6115
|
+
cloned[key] = deepCloneFrontmatter(value);
|
|
6116
|
+
} else {
|
|
6117
|
+
cloned[key] = value;
|
|
6118
|
+
}
|
|
6119
|
+
}
|
|
6120
|
+
return cloned;
|
|
5958
6121
|
}
|
|
5959
|
-
|
|
5960
|
-
|
|
5961
|
-
|
|
6122
|
+
async function writeVaultFile(vaultPath2, notePath, content, frontmatter, lineEnding = "LF", expectedHash) {
|
|
6123
|
+
const validation = await validatePathSecure(vaultPath2, notePath);
|
|
6124
|
+
if (!validation.valid) {
|
|
6125
|
+
throw new Error(`Invalid path: ${validation.reason}`);
|
|
6126
|
+
}
|
|
6127
|
+
const fullPath = path23.join(vaultPath2, notePath);
|
|
6128
|
+
if (expectedHash) {
|
|
6129
|
+
const currentRaw = await fs21.readFile(fullPath, "utf-8");
|
|
6130
|
+
const currentHash = computeContentHash(currentRaw);
|
|
6131
|
+
if (currentHash !== expectedHash) {
|
|
6132
|
+
throw new WriteConflictError(notePath);
|
|
6133
|
+
}
|
|
6134
|
+
}
|
|
6135
|
+
let output = matter5.stringify(content, frontmatter);
|
|
6136
|
+
output = normalizeTrailingNewline(output);
|
|
6137
|
+
output = convertLineEndings(output, lineEnding);
|
|
6138
|
+
await fs21.writeFile(fullPath, output, "utf-8");
|
|
6139
|
+
}
|
|
6140
|
+
var WriteConflictError;
|
|
6141
|
+
var init_file_io = __esm({
|
|
6142
|
+
"src/core/write/file-io.ts"() {
|
|
5962
6143
|
"use strict";
|
|
5963
|
-
|
|
5964
|
-
|
|
5965
|
-
SENSITIVE_PATH_PATTERNS = [
|
|
5966
|
-
// Environment files (including backups, variations, and Windows ADS)
|
|
5967
|
-
/\.env($|\..*|~|\.swp|\.swo|:)/i,
|
|
5968
|
-
// .env, .env.local, .env~, .env.swp, .env:$DATA (ADS), etc.
|
|
5969
|
-
// Git credentials and config
|
|
5970
|
-
/\.git\/config$/i,
|
|
5971
|
-
// Git config (may contain tokens)
|
|
5972
|
-
/\.git\/credentials$/i,
|
|
5973
|
-
// Git credentials
|
|
5974
|
-
// SSL/TLS certificates and private keys (including backups)
|
|
5975
|
-
/\.pem($|\.bak|\.backup|\.old|\.orig|~)$/i,
|
|
5976
|
-
// SSL/TLS certificates + backups
|
|
5977
|
-
/\.key($|\.bak|\.backup|\.old|\.orig|~)$/i,
|
|
5978
|
-
// Private keys + backups
|
|
5979
|
-
/\.p12($|\.bak|\.backup|\.old|\.orig|~)$/i,
|
|
5980
|
-
// PKCS#12 certificates + backups
|
|
5981
|
-
/\.pfx($|\.bak|\.backup|\.old|\.orig|~)$/i,
|
|
5982
|
-
// Windows certificate format + backups
|
|
5983
|
-
/\.jks($|\.bak|\.backup|\.old|\.orig|~)$/i,
|
|
5984
|
-
// Java keystore + backups
|
|
5985
|
-
/\.crt($|\.bak|\.backup|\.old|\.orig|~)$/i,
|
|
5986
|
-
// Certificate files + backups
|
|
5987
|
-
// SSH keys
|
|
5988
|
-
/id_rsa/i,
|
|
5989
|
-
// SSH private key
|
|
5990
|
-
/id_ed25519/i,
|
|
5991
|
-
// SSH private key (ed25519)
|
|
5992
|
-
/id_ecdsa/i,
|
|
5993
|
-
// SSH private key (ecdsa)
|
|
5994
|
-
/id_dsa/i,
|
|
5995
|
-
// SSH private key (dsa)
|
|
5996
|
-
/\.ssh\/config$/i,
|
|
5997
|
-
// SSH config
|
|
5998
|
-
/authorized_keys$/i,
|
|
5999
|
-
// SSH authorized keys
|
|
6000
|
-
/known_hosts$/i,
|
|
6001
|
-
// SSH known hosts
|
|
6002
|
-
// Generic credentials/secrets files (including backups)
|
|
6003
|
-
/credentials\.json($|\.bak|\.backup|\.old|\.orig|~)$/i,
|
|
6004
|
-
// Cloud credentials + backups
|
|
6005
|
-
/secrets\.json($|\.bak|\.backup|\.old|\.orig|~)$/i,
|
|
6006
|
-
// Secrets files + backups
|
|
6007
|
-
/secrets\.ya?ml($|\.bak|\.backup|\.old|\.orig|~)$/i,
|
|
6008
|
-
// Secrets YAML + backups
|
|
6009
|
-
// Package manager auth
|
|
6010
|
-
/\.npmrc$/i,
|
|
6011
|
-
// npm config (may contain tokens)
|
|
6012
|
-
/\.netrc$/i,
|
|
6013
|
-
// Netrc (HTTP auth credentials)
|
|
6014
|
-
/\.yarnrc$/i,
|
|
6015
|
-
// Yarn config
|
|
6016
|
-
// Cloud provider credentials
|
|
6017
|
-
/\.aws\/credentials$/i,
|
|
6018
|
-
// AWS credentials
|
|
6019
|
-
/\.aws\/config$/i,
|
|
6020
|
-
// AWS config
|
|
6021
|
-
/gcloud\/credentials\.json/i,
|
|
6022
|
-
// Google Cloud credentials
|
|
6023
|
-
/\.azure\/credentials$/i,
|
|
6024
|
-
// Azure credentials
|
|
6025
|
-
/\.docker\/config\.json$/i,
|
|
6026
|
-
// Docker registry auth
|
|
6027
|
-
/\.kube\/config$/i,
|
|
6028
|
-
// Kubernetes config
|
|
6029
|
-
// System password files
|
|
6030
|
-
/\.htpasswd$/i,
|
|
6031
|
-
// Apache password file
|
|
6032
|
-
/shadow$/,
|
|
6033
|
-
// Unix shadow password file
|
|
6034
|
-
/passwd$/,
|
|
6035
|
-
// Unix password file
|
|
6036
|
-
// Hidden credential files (starting with dot)
|
|
6037
|
-
/^\.(credentials|secrets|tokens)$/i
|
|
6038
|
-
// .credentials, .secrets, .tokens
|
|
6039
|
-
];
|
|
6040
|
-
REDOS_PATTERNS = [
|
|
6041
|
-
// Nested quantifiers: (a+)+, (a*)+, (a+)*, (a*)*, etc.
|
|
6042
|
-
/(\([^)]*[+*][^)]*\))[+*]/,
|
|
6043
|
-
// Quantifiers followed by optional same-type quantifiers
|
|
6044
|
-
/[+*]\??\s*[+*]/,
|
|
6045
|
-
// Overlapping character classes with quantifiers followed by similar
|
|
6046
|
-
/\[[^\]]*\][+*].*\[[^\]]*\][+*]/,
|
|
6047
|
-
// Multiple adjacent capturing groups with quantifiers
|
|
6048
|
-
/(\([^)]+[+*]\)){2,}/,
|
|
6049
|
-
// Extremely long alternation groups
|
|
6050
|
-
/\([^)]{100,}\)/
|
|
6051
|
-
];
|
|
6052
|
-
MAX_REGEX_LENGTH = 500;
|
|
6053
|
-
EMPTY_PLACEHOLDER_PATTERNS = [
|
|
6054
|
-
/^\d+\.\s*$/,
|
|
6055
|
-
// "1. " or "2. " (numbered list placeholder)
|
|
6056
|
-
/^-\s*$/,
|
|
6057
|
-
// "- " (bullet placeholder)
|
|
6058
|
-
/^-\s*\[\s*\]\s*$/,
|
|
6059
|
-
// "- [ ] " (empty task placeholder)
|
|
6060
|
-
/^-\s*\[x\]\s*$/i,
|
|
6061
|
-
// "- [x] " (completed task placeholder)
|
|
6062
|
-
/^\*\s*$/
|
|
6063
|
-
// "* " (asterisk bullet placeholder)
|
|
6064
|
-
];
|
|
6144
|
+
init_path_security();
|
|
6145
|
+
init_line_endings();
|
|
6065
6146
|
WriteConflictError = class extends Error {
|
|
6066
6147
|
constructor(notePath) {
|
|
6067
6148
|
super(`Write conflict on ${notePath}: file was modified externally since it was read. Re-read and retry.`);
|
|
@@ -6069,14 +6150,19 @@ var init_writer = __esm({
|
|
|
6069
6150
|
this.name = "WriteConflictError";
|
|
6070
6151
|
}
|
|
6071
6152
|
};
|
|
6072
|
-
|
|
6073
|
-
|
|
6074
|
-
|
|
6075
|
-
|
|
6076
|
-
|
|
6077
|
-
|
|
6078
|
-
|
|
6079
|
-
|
|
6153
|
+
}
|
|
6154
|
+
});
|
|
6155
|
+
|
|
6156
|
+
// src/core/write/writer.ts
|
|
6157
|
+
var init_writer = __esm({
|
|
6158
|
+
"src/core/write/writer.ts"() {
|
|
6159
|
+
"use strict";
|
|
6160
|
+
init_path_security();
|
|
6161
|
+
init_regex_safety();
|
|
6162
|
+
init_line_endings();
|
|
6163
|
+
init_markdown_structure();
|
|
6164
|
+
init_content_mutation();
|
|
6165
|
+
init_file_io();
|
|
6080
6166
|
}
|
|
6081
6167
|
});
|
|
6082
6168
|
|
|
@@ -6106,8 +6192,8 @@ function createContext(variables = {}) {
|
|
|
6106
6192
|
steps: {}
|
|
6107
6193
|
};
|
|
6108
6194
|
}
|
|
6109
|
-
function resolvePath(obj,
|
|
6110
|
-
const parts =
|
|
6195
|
+
function resolvePath(obj, path40) {
|
|
6196
|
+
const parts = path40.split(".");
|
|
6111
6197
|
let current = obj;
|
|
6112
6198
|
for (const part of parts) {
|
|
6113
6199
|
if (current === void 0 || current === null) {
|
|
@@ -6564,8 +6650,8 @@ __export(conditions_exports, {
|
|
|
6564
6650
|
evaluateCondition: () => evaluateCondition,
|
|
6565
6651
|
shouldStepExecute: () => shouldStepExecute
|
|
6566
6652
|
});
|
|
6567
|
-
import
|
|
6568
|
-
import
|
|
6653
|
+
import fs29 from "fs/promises";
|
|
6654
|
+
import path31 from "path";
|
|
6569
6655
|
async function evaluateCondition(condition, vaultPath2, context) {
|
|
6570
6656
|
const interpolatedPath = condition.path ? interpolate(condition.path, context) : void 0;
|
|
6571
6657
|
const interpolatedSection = condition.section ? interpolate(condition.section, context) : void 0;
|
|
@@ -6618,9 +6704,9 @@ async function evaluateCondition(condition, vaultPath2, context) {
|
|
|
6618
6704
|
}
|
|
6619
6705
|
}
|
|
6620
6706
|
async function evaluateFileExists(vaultPath2, notePath, expectExists) {
|
|
6621
|
-
const fullPath =
|
|
6707
|
+
const fullPath = path31.join(vaultPath2, notePath);
|
|
6622
6708
|
try {
|
|
6623
|
-
await
|
|
6709
|
+
await fs29.access(fullPath);
|
|
6624
6710
|
return {
|
|
6625
6711
|
met: expectExists,
|
|
6626
6712
|
reason: expectExists ? `File exists: ${notePath}` : `File exists (expected not to): ${notePath}`
|
|
@@ -6633,9 +6719,9 @@ async function evaluateFileExists(vaultPath2, notePath, expectExists) {
|
|
|
6633
6719
|
}
|
|
6634
6720
|
}
|
|
6635
6721
|
async function evaluateSectionExists(vaultPath2, notePath, sectionName, expectExists) {
|
|
6636
|
-
const fullPath =
|
|
6722
|
+
const fullPath = path31.join(vaultPath2, notePath);
|
|
6637
6723
|
try {
|
|
6638
|
-
await
|
|
6724
|
+
await fs29.access(fullPath);
|
|
6639
6725
|
} catch {
|
|
6640
6726
|
return {
|
|
6641
6727
|
met: !expectExists,
|
|
@@ -6664,9 +6750,9 @@ async function evaluateSectionExists(vaultPath2, notePath, sectionName, expectEx
|
|
|
6664
6750
|
}
|
|
6665
6751
|
}
|
|
6666
6752
|
async function evaluateFrontmatterExists(vaultPath2, notePath, fieldName, expectExists) {
|
|
6667
|
-
const fullPath =
|
|
6753
|
+
const fullPath = path31.join(vaultPath2, notePath);
|
|
6668
6754
|
try {
|
|
6669
|
-
await
|
|
6755
|
+
await fs29.access(fullPath);
|
|
6670
6756
|
} catch {
|
|
6671
6757
|
return {
|
|
6672
6758
|
met: !expectExists,
|
|
@@ -6695,9 +6781,9 @@ async function evaluateFrontmatterExists(vaultPath2, notePath, fieldName, expect
|
|
|
6695
6781
|
}
|
|
6696
6782
|
}
|
|
6697
6783
|
async function evaluateFrontmatterEquals(vaultPath2, notePath, fieldName, expectedValue) {
|
|
6698
|
-
const fullPath =
|
|
6784
|
+
const fullPath = path31.join(vaultPath2, notePath);
|
|
6699
6785
|
try {
|
|
6700
|
-
await
|
|
6786
|
+
await fs29.access(fullPath);
|
|
6701
6787
|
} catch {
|
|
6702
6788
|
return {
|
|
6703
6789
|
met: false,
|
|
@@ -6839,9 +6925,9 @@ var init_taskHelpers = __esm({
|
|
|
6839
6925
|
});
|
|
6840
6926
|
|
|
6841
6927
|
// src/index.ts
|
|
6842
|
-
import * as
|
|
6928
|
+
import * as path39 from "path";
|
|
6843
6929
|
import { readFileSync as readFileSync6, realpathSync, existsSync as existsSync3 } from "fs";
|
|
6844
|
-
import { fileURLToPath as
|
|
6930
|
+
import { fileURLToPath as fileURLToPath3 } from "url";
|
|
6845
6931
|
import { dirname as dirname7, join as join20 } from "path";
|
|
6846
6932
|
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
6847
6933
|
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
|
|
@@ -7079,8 +7165,8 @@ function updateIndexProgress(parsed, total) {
|
|
|
7079
7165
|
function normalizeTarget(target) {
|
|
7080
7166
|
return target.toLowerCase().replace(/\.md$/, "");
|
|
7081
7167
|
}
|
|
7082
|
-
function normalizeNotePath(
|
|
7083
|
-
return
|
|
7168
|
+
function normalizeNotePath(path40) {
|
|
7169
|
+
return path40.toLowerCase().replace(/\.md$/, "");
|
|
7084
7170
|
}
|
|
7085
7171
|
async function buildVaultIndex(vaultPath2, options = {}) {
|
|
7086
7172
|
const { timeoutMs = DEFAULT_TIMEOUT_MS, onProgress } = options;
|
|
@@ -7128,6 +7214,7 @@ async function buildVaultIndexInternal(vaultPath2, startTime, onProgress) {
|
|
|
7128
7214
|
console.error(`Parsed ${parsedCount}/${files.length} files (${elapsed}s)`);
|
|
7129
7215
|
onProgress?.(parsedCount, files.length);
|
|
7130
7216
|
}
|
|
7217
|
+
await new Promise((resolve3) => setImmediate(resolve3));
|
|
7131
7218
|
}
|
|
7132
7219
|
if (parseErrors.length > 0) {
|
|
7133
7220
|
const msg = `Failed to parse ${parseErrors.length} file(s):`;
|
|
@@ -7253,7 +7340,7 @@ function findSimilarEntity(index, target) {
|
|
|
7253
7340
|
}
|
|
7254
7341
|
const maxDist = normalizedLen <= 10 ? 1 : 2;
|
|
7255
7342
|
let bestMatch;
|
|
7256
|
-
for (const [entity,
|
|
7343
|
+
for (const [entity, path40] of index.entities) {
|
|
7257
7344
|
const lenDiff = Math.abs(entity.length - normalizedLen);
|
|
7258
7345
|
if (lenDiff > maxDist) {
|
|
7259
7346
|
continue;
|
|
@@ -7261,7 +7348,7 @@ function findSimilarEntity(index, target) {
|
|
|
7261
7348
|
const dist = levenshteinDistance(normalized, entity);
|
|
7262
7349
|
if (dist > 0 && dist <= maxDist) {
|
|
7263
7350
|
if (!bestMatch || dist < bestMatch.distance) {
|
|
7264
|
-
bestMatch = { path:
|
|
7351
|
+
bestMatch = { path: path40, entity, distance: dist };
|
|
7265
7352
|
if (dist === 1) {
|
|
7266
7353
|
return bestMatch;
|
|
7267
7354
|
}
|
|
@@ -7685,8 +7772,8 @@ function normalizePath(filePath) {
|
|
|
7685
7772
|
function getRelativePath(vaultPath2, filePath) {
|
|
7686
7773
|
const normalizedVault = normalizePath(vaultPath2);
|
|
7687
7774
|
const normalizedFile = normalizePath(filePath);
|
|
7688
|
-
const
|
|
7689
|
-
return
|
|
7775
|
+
const relative2 = path5.posix.relative(normalizedVault, normalizedFile);
|
|
7776
|
+
return relative2;
|
|
7690
7777
|
}
|
|
7691
7778
|
function shouldWatch(filePath, vaultPath2) {
|
|
7692
7779
|
const normalized = normalizePath(filePath);
|
|
@@ -7820,30 +7907,30 @@ var EventQueue = class {
|
|
|
7820
7907
|
* Add a new event to the queue
|
|
7821
7908
|
*/
|
|
7822
7909
|
push(type, rawPath) {
|
|
7823
|
-
const
|
|
7910
|
+
const path40 = normalizePath(rawPath);
|
|
7824
7911
|
const now = Date.now();
|
|
7825
7912
|
const event = {
|
|
7826
7913
|
type,
|
|
7827
|
-
path:
|
|
7914
|
+
path: path40,
|
|
7828
7915
|
timestamp: now
|
|
7829
7916
|
};
|
|
7830
|
-
let pending = this.pending.get(
|
|
7917
|
+
let pending = this.pending.get(path40);
|
|
7831
7918
|
if (!pending) {
|
|
7832
7919
|
pending = {
|
|
7833
7920
|
events: [],
|
|
7834
7921
|
timer: null,
|
|
7835
7922
|
lastEvent: now
|
|
7836
7923
|
};
|
|
7837
|
-
this.pending.set(
|
|
7924
|
+
this.pending.set(path40, pending);
|
|
7838
7925
|
}
|
|
7839
7926
|
pending.events.push(event);
|
|
7840
7927
|
pending.lastEvent = now;
|
|
7841
|
-
console.error(`[flywheel] QUEUE: pushed ${type} for ${
|
|
7928
|
+
console.error(`[flywheel] QUEUE: pushed ${type} for ${path40}, pending=${this.pending.size}`);
|
|
7842
7929
|
if (pending.timer) {
|
|
7843
7930
|
clearTimeout(pending.timer);
|
|
7844
7931
|
}
|
|
7845
7932
|
pending.timer = setTimeout(() => {
|
|
7846
|
-
this.flushPath(
|
|
7933
|
+
this.flushPath(path40);
|
|
7847
7934
|
}, this.config.debounceMs);
|
|
7848
7935
|
if (this.pending.size >= this.config.batchSize) {
|
|
7849
7936
|
this.flush();
|
|
@@ -7864,10 +7951,10 @@ var EventQueue = class {
|
|
|
7864
7951
|
/**
|
|
7865
7952
|
* Flush a single path's events
|
|
7866
7953
|
*/
|
|
7867
|
-
flushPath(
|
|
7868
|
-
const pending = this.pending.get(
|
|
7954
|
+
flushPath(path40) {
|
|
7955
|
+
const pending = this.pending.get(path40);
|
|
7869
7956
|
if (!pending || pending.events.length === 0) return;
|
|
7870
|
-
console.error(`[flywheel] QUEUE: flushing ${
|
|
7957
|
+
console.error(`[flywheel] QUEUE: flushing ${path40}, events=${pending.events.length}`);
|
|
7871
7958
|
if (pending.timer) {
|
|
7872
7959
|
clearTimeout(pending.timer);
|
|
7873
7960
|
pending.timer = null;
|
|
@@ -7876,7 +7963,7 @@ var EventQueue = class {
|
|
|
7876
7963
|
if (coalescedType) {
|
|
7877
7964
|
const coalesced = {
|
|
7878
7965
|
type: coalescedType,
|
|
7879
|
-
path:
|
|
7966
|
+
path: path40,
|
|
7880
7967
|
originalEvents: [...pending.events]
|
|
7881
7968
|
};
|
|
7882
7969
|
this.onBatch({
|
|
@@ -7885,7 +7972,7 @@ var EventQueue = class {
|
|
|
7885
7972
|
timestamp: Date.now()
|
|
7886
7973
|
});
|
|
7887
7974
|
}
|
|
7888
|
-
this.pending.delete(
|
|
7975
|
+
this.pending.delete(path40);
|
|
7889
7976
|
}
|
|
7890
7977
|
/**
|
|
7891
7978
|
* Flush all pending events
|
|
@@ -7897,7 +7984,7 @@ var EventQueue = class {
|
|
|
7897
7984
|
}
|
|
7898
7985
|
if (this.pending.size === 0) return;
|
|
7899
7986
|
const events = [];
|
|
7900
|
-
for (const [
|
|
7987
|
+
for (const [path40, pending] of this.pending) {
|
|
7901
7988
|
if (pending.timer) {
|
|
7902
7989
|
clearTimeout(pending.timer);
|
|
7903
7990
|
}
|
|
@@ -7905,7 +7992,7 @@ var EventQueue = class {
|
|
|
7905
7992
|
if (coalescedType) {
|
|
7906
7993
|
events.push({
|
|
7907
7994
|
type: coalescedType,
|
|
7908
|
-
path:
|
|
7995
|
+
path: path40,
|
|
7909
7996
|
originalEvents: [...pending.events]
|
|
7910
7997
|
});
|
|
7911
7998
|
}
|
|
@@ -8099,8 +8186,8 @@ async function upsertNote(index, vaultPath2, notePath) {
|
|
|
8099
8186
|
releasedKeys = removeNoteFromIndex(index, notePath);
|
|
8100
8187
|
}
|
|
8101
8188
|
const fullPath = path7.join(vaultPath2, notePath);
|
|
8102
|
-
const
|
|
8103
|
-
const stats = await
|
|
8189
|
+
const fs36 = await import("fs/promises");
|
|
8190
|
+
const stats = await fs36.stat(fullPath);
|
|
8104
8191
|
const vaultFile = {
|
|
8105
8192
|
path: notePath,
|
|
8106
8193
|
absolutePath: fullPath,
|
|
@@ -8205,7 +8292,7 @@ async function processBatch(index, vaultPath2, batch, options = {}) {
|
|
|
8205
8292
|
}
|
|
8206
8293
|
onProgress?.(processed, total);
|
|
8207
8294
|
if (processed % YIELD_INTERVAL === 0 && processed < total) {
|
|
8208
|
-
await new Promise((
|
|
8295
|
+
await new Promise((resolve3) => setImmediate(resolve3));
|
|
8209
8296
|
}
|
|
8210
8297
|
}
|
|
8211
8298
|
const durationMs = Date.now() - startTime;
|
|
@@ -8297,31 +8384,31 @@ function createVaultWatcher(options) {
|
|
|
8297
8384
|
usePolling: config2.usePolling,
|
|
8298
8385
|
interval: config2.usePolling ? config2.pollInterval : void 0
|
|
8299
8386
|
});
|
|
8300
|
-
watcher.on("add", (
|
|
8301
|
-
console.error(`[flywheel] RAW EVENT: add ${
|
|
8302
|
-
if (shouldWatch(
|
|
8303
|
-
console.error(`[flywheel] ACCEPTED: add ${
|
|
8304
|
-
eventQueue.push("add",
|
|
8387
|
+
watcher.on("add", (path40) => {
|
|
8388
|
+
console.error(`[flywheel] RAW EVENT: add ${path40}`);
|
|
8389
|
+
if (shouldWatch(path40, vaultPath2)) {
|
|
8390
|
+
console.error(`[flywheel] ACCEPTED: add ${path40}`);
|
|
8391
|
+
eventQueue.push("add", path40);
|
|
8305
8392
|
} else {
|
|
8306
|
-
console.error(`[flywheel] FILTERED: add ${
|
|
8393
|
+
console.error(`[flywheel] FILTERED: add ${path40}`);
|
|
8307
8394
|
}
|
|
8308
8395
|
});
|
|
8309
|
-
watcher.on("change", (
|
|
8310
|
-
console.error(`[flywheel] RAW EVENT: change ${
|
|
8311
|
-
if (shouldWatch(
|
|
8312
|
-
console.error(`[flywheel] ACCEPTED: change ${
|
|
8313
|
-
eventQueue.push("change",
|
|
8396
|
+
watcher.on("change", (path40) => {
|
|
8397
|
+
console.error(`[flywheel] RAW EVENT: change ${path40}`);
|
|
8398
|
+
if (shouldWatch(path40, vaultPath2)) {
|
|
8399
|
+
console.error(`[flywheel] ACCEPTED: change ${path40}`);
|
|
8400
|
+
eventQueue.push("change", path40);
|
|
8314
8401
|
} else {
|
|
8315
|
-
console.error(`[flywheel] FILTERED: change ${
|
|
8402
|
+
console.error(`[flywheel] FILTERED: change ${path40}`);
|
|
8316
8403
|
}
|
|
8317
8404
|
});
|
|
8318
|
-
watcher.on("unlink", (
|
|
8319
|
-
console.error(`[flywheel] RAW EVENT: unlink ${
|
|
8320
|
-
if (shouldWatch(
|
|
8321
|
-
console.error(`[flywheel] ACCEPTED: unlink ${
|
|
8322
|
-
eventQueue.push("unlink",
|
|
8405
|
+
watcher.on("unlink", (path40) => {
|
|
8406
|
+
console.error(`[flywheel] RAW EVENT: unlink ${path40}`);
|
|
8407
|
+
if (shouldWatch(path40, vaultPath2)) {
|
|
8408
|
+
console.error(`[flywheel] ACCEPTED: unlink ${path40}`);
|
|
8409
|
+
eventQueue.push("unlink", path40);
|
|
8323
8410
|
} else {
|
|
8324
|
-
console.error(`[flywheel] FILTERED: unlink ${
|
|
8411
|
+
console.error(`[flywheel] FILTERED: unlink ${path40}`);
|
|
8325
8412
|
}
|
|
8326
8413
|
});
|
|
8327
8414
|
watcher.on("ready", () => {
|
|
@@ -11987,8 +12074,8 @@ function getNoteAccessFrequency(stateDb2, daysBack = 30) {
|
|
|
11987
12074
|
}
|
|
11988
12075
|
}
|
|
11989
12076
|
}
|
|
11990
|
-
return Array.from(noteMap.entries()).map(([
|
|
11991
|
-
path:
|
|
12077
|
+
return Array.from(noteMap.entries()).map(([path40, stats]) => ({
|
|
12078
|
+
path: path40,
|
|
11992
12079
|
access_count: stats.access_count,
|
|
11993
12080
|
last_accessed: stats.last_accessed,
|
|
11994
12081
|
tools_used: Array.from(stats.tools)
|
|
@@ -12103,7 +12190,7 @@ init_recency();
|
|
|
12103
12190
|
init_prospects();
|
|
12104
12191
|
init_cooccurrence();
|
|
12105
12192
|
init_retrievalCooccurrence();
|
|
12106
|
-
import * as
|
|
12193
|
+
import * as fs35 from "node:fs/promises";
|
|
12107
12194
|
import { createHash as createHash4 } from "node:crypto";
|
|
12108
12195
|
|
|
12109
12196
|
// src/vault-registry.ts
|
|
@@ -12334,7 +12421,6 @@ var TOOL_CATEGORY = {
|
|
|
12334
12421
|
get_common_neighbors: "graph",
|
|
12335
12422
|
get_backlinks: "graph",
|
|
12336
12423
|
get_forward_links: "graph",
|
|
12337
|
-
get_weighted_links: "graph",
|
|
12338
12424
|
get_strong_connections: "graph",
|
|
12339
12425
|
// schema (7 tools) -- schema intelligence + migrations
|
|
12340
12426
|
vault_schema: "schema",
|
|
@@ -12422,7 +12508,6 @@ var TOOL_TIER = {
|
|
|
12422
12508
|
get_common_neighbors: 2,
|
|
12423
12509
|
get_backlinks: 2,
|
|
12424
12510
|
get_forward_links: 2,
|
|
12425
|
-
get_weighted_links: 2,
|
|
12426
12511
|
get_strong_connections: 2,
|
|
12427
12512
|
suggest_wikilinks: 2,
|
|
12428
12513
|
validate_links: 2,
|
|
@@ -12677,10 +12762,10 @@ Use "flywheel_config" to inspect runtime configuration and set "tool_tier_overri
|
|
|
12677
12762
|
}
|
|
12678
12763
|
|
|
12679
12764
|
// src/tool-registry.ts
|
|
12680
|
-
import * as
|
|
12765
|
+
import * as path38 from "path";
|
|
12681
12766
|
import { dirname as dirname5, join as join18 } from "path";
|
|
12682
12767
|
import { statSync as statSync6, readFileSync as readFileSync5 } from "fs";
|
|
12683
|
-
import { fileURLToPath } from "url";
|
|
12768
|
+
import { fileURLToPath as fileURLToPath2 } from "url";
|
|
12684
12769
|
import { z as z39 } from "zod";
|
|
12685
12770
|
import { CallToolRequestSchema, ErrorCode, McpError } from "@modelcontextprotocol/sdk/types.js";
|
|
12686
12771
|
import { getSessionId } from "@velvetmonkey/vault-core";
|
|
@@ -13029,13 +13114,13 @@ function multiHopBackfill(primaryResults, index, stateDb2, config2 = {}) {
|
|
|
13029
13114
|
candidates.sort((a, b) => b.score - a.score);
|
|
13030
13115
|
return candidates.slice(0, cfg.maxBackfill).map((c) => c.result);
|
|
13031
13116
|
}
|
|
13032
|
-
function scoreCandidate(
|
|
13033
|
-
const note = index.notes.get(
|
|
13117
|
+
function scoreCandidate(path40, index, stateDb2) {
|
|
13118
|
+
const note = index.notes.get(path40);
|
|
13034
13119
|
const decay = recencyDecay(note?.modified);
|
|
13035
13120
|
let hubScore = 1;
|
|
13036
13121
|
if (stateDb2) {
|
|
13037
13122
|
try {
|
|
13038
|
-
const title = note?.title ??
|
|
13123
|
+
const title = note?.title ?? path40.replace(/\.md$/, "").split("/").pop() ?? "";
|
|
13039
13124
|
const entity = getEntityByName3(stateDb2, title);
|
|
13040
13125
|
if (entity) hubScore = entity.hubScore ?? 1;
|
|
13041
13126
|
} catch {
|
|
@@ -13495,11 +13580,11 @@ function applyEntityBridging(results, stateDb2, maxBridgesPerResult = 5) {
|
|
|
13495
13580
|
const linkMap = /* @__PURE__ */ new Map();
|
|
13496
13581
|
try {
|
|
13497
13582
|
const paths = results.map((r) => r.path).filter(Boolean);
|
|
13498
|
-
for (const
|
|
13583
|
+
for (const path40 of paths) {
|
|
13499
13584
|
const rows = stateDb2.db.prepare(
|
|
13500
13585
|
"SELECT target FROM note_links WHERE note_path = ?"
|
|
13501
|
-
).all(
|
|
13502
|
-
linkMap.set(
|
|
13586
|
+
).all(path40);
|
|
13587
|
+
linkMap.set(path40, new Set(rows.map((r) => r.target)));
|
|
13503
13588
|
}
|
|
13504
13589
|
} catch {
|
|
13505
13590
|
return;
|
|
@@ -14639,50 +14724,6 @@ function registerGraphTools(server2, getIndex, getVaultPath, getStateDb4) {
|
|
|
14639
14724
|
};
|
|
14640
14725
|
}
|
|
14641
14726
|
);
|
|
14642
|
-
server2.tool(
|
|
14643
|
-
"get_weighted_links",
|
|
14644
|
-
"Use when ranking outgoing links from a note by relationship strength. Produces weighted link entries reflecting edge survival, co-session access, and source activity. Returns ranked outgoing links with weight scores. Does not include incoming links \u2014 use get_strong_connections for bidirectional.",
|
|
14645
|
-
{
|
|
14646
|
-
path: z2.string().describe('Path to the note (e.g., "daily/2026-02-24.md")'),
|
|
14647
|
-
min_weight: z2.number().default(1).describe("Minimum weight threshold (default 1.0)"),
|
|
14648
|
-
limit: z2.number().default(20).describe("Maximum number of results to return")
|
|
14649
|
-
},
|
|
14650
|
-
async ({ path: notePath, min_weight, limit: requestedLimit }) => {
|
|
14651
|
-
const stateDb2 = getStateDb4?.();
|
|
14652
|
-
if (!stateDb2) {
|
|
14653
|
-
return { content: [{ type: "text", text: JSON.stringify({ error: "StateDb not initialized" }) }] };
|
|
14654
|
-
}
|
|
14655
|
-
const limit = Math.min(requestedLimit ?? 20, MAX_LIMIT);
|
|
14656
|
-
const now = Date.now();
|
|
14657
|
-
const rows = stateDb2.db.prepare(`
|
|
14658
|
-
SELECT target, weight, weight_updated_at
|
|
14659
|
-
FROM note_links
|
|
14660
|
-
WHERE note_path = ?
|
|
14661
|
-
ORDER BY weight DESC
|
|
14662
|
-
`).all(notePath);
|
|
14663
|
-
const results = rows.map((row) => {
|
|
14664
|
-
const daysSinceUpdated = row.weight_updated_at ? (now - row.weight_updated_at) / (1e3 * 60 * 60 * 24) : 0;
|
|
14665
|
-
const decayFactor = Math.max(0.1, 1 - daysSinceUpdated / 180);
|
|
14666
|
-
const effectiveWeight = Math.round(row.weight * decayFactor * 1e3) / 1e3;
|
|
14667
|
-
return {
|
|
14668
|
-
target: row.target,
|
|
14669
|
-
weight: row.weight,
|
|
14670
|
-
weight_effective: effectiveWeight,
|
|
14671
|
-
last_updated: row.weight_updated_at
|
|
14672
|
-
};
|
|
14673
|
-
}).filter((r) => r.weight_effective >= min_weight).slice(0, limit);
|
|
14674
|
-
return {
|
|
14675
|
-
content: [{
|
|
14676
|
-
type: "text",
|
|
14677
|
-
text: JSON.stringify({
|
|
14678
|
-
note: notePath,
|
|
14679
|
-
count: results.length,
|
|
14680
|
-
links: results
|
|
14681
|
-
}, null, 2)
|
|
14682
|
-
}]
|
|
14683
|
-
};
|
|
14684
|
-
}
|
|
14685
|
-
);
|
|
14686
14727
|
server2.tool(
|
|
14687
14728
|
"get_strong_connections",
|
|
14688
14729
|
"Use when finding the most important relationships for a note in both directions. Produces bidirectional connections ranked by combined edge weight. Returns both incoming and outgoing links sorted by strength. Does not compute path distances \u2014 use get_link_path for shortest paths.",
|
|
@@ -15021,16 +15062,16 @@ function registerWikilinkTools(server2, getIndex, getVaultPath, getStateDb4 = ()
|
|
|
15021
15062
|
const weightedStats = getWeightedEntityStats(stateDb3);
|
|
15022
15063
|
const statsMap = new Map(weightedStats.map((s) => [s.entity.toLowerCase(), s]));
|
|
15023
15064
|
for (const suggestion of scored.detailed) {
|
|
15024
|
-
const
|
|
15025
|
-
if (
|
|
15065
|
+
const stat4 = statsMap.get(suggestion.entity.toLowerCase());
|
|
15066
|
+
if (stat4) {
|
|
15026
15067
|
const effectiveAlpha = isAiConfigEntity(suggestion.entity) ? AI_CONFIG_PRIOR_ALPHA : PRIOR_ALPHA;
|
|
15027
|
-
const posteriorMean = computePosteriorMean(
|
|
15028
|
-
const totalObs = effectiveAlpha +
|
|
15068
|
+
const posteriorMean = computePosteriorMean(stat4.weightedCorrect, stat4.weightedFp, effectiveAlpha);
|
|
15069
|
+
const totalObs = effectiveAlpha + stat4.weightedCorrect + PRIOR_BETA + stat4.weightedFp;
|
|
15029
15070
|
suggestion.suppressionContext = {
|
|
15030
15071
|
posteriorMean: Math.round(posteriorMean * 1e3) / 1e3,
|
|
15031
15072
|
totalObservations: Math.round(totalObs * 10) / 10,
|
|
15032
15073
|
isSuppressed: totalObs >= SUPPRESSION_MIN_OBSERVATIONS && posteriorMean < SUPPRESSION_POSTERIOR_THRESHOLD,
|
|
15033
|
-
falsePositiveRate: Math.round(
|
|
15074
|
+
falsePositiveRate: Math.round(stat4.weightedFpRate * 1e3) / 1e3
|
|
15034
15075
|
};
|
|
15035
15076
|
}
|
|
15036
15077
|
}
|
|
@@ -15075,14 +15116,14 @@ function registerWikilinkTools(server2, getIndex, getVaultPath, getStateDb4 = ()
|
|
|
15075
15116
|
};
|
|
15076
15117
|
function findSimilarEntity2(target, entities) {
|
|
15077
15118
|
const targetLower = target.toLowerCase();
|
|
15078
|
-
for (const [name,
|
|
15119
|
+
for (const [name, path40] of entities) {
|
|
15079
15120
|
if (name.startsWith(targetLower) || targetLower.startsWith(name)) {
|
|
15080
|
-
return
|
|
15121
|
+
return path40;
|
|
15081
15122
|
}
|
|
15082
15123
|
}
|
|
15083
|
-
for (const [name,
|
|
15124
|
+
for (const [name, path40] of entities) {
|
|
15084
15125
|
if (name.includes(targetLower) || targetLower.includes(name)) {
|
|
15085
|
-
return
|
|
15126
|
+
return path40;
|
|
15086
15127
|
}
|
|
15087
15128
|
}
|
|
15088
15129
|
return void 0;
|
|
@@ -16102,8 +16143,8 @@ function registerHealthTools(server2, getIndex, getVaultPath, getConfig2 = () =>
|
|
|
16102
16143
|
daily_counts: z4.record(z4.number())
|
|
16103
16144
|
}).describe("Activity summary for the last 7 days")
|
|
16104
16145
|
};
|
|
16105
|
-
function isPeriodicNote3(
|
|
16106
|
-
const filename =
|
|
16146
|
+
function isPeriodicNote3(path40) {
|
|
16147
|
+
const filename = path40.split("/").pop() || "";
|
|
16107
16148
|
const nameWithoutExt = filename.replace(/\.md$/, "");
|
|
16108
16149
|
const patterns = [
|
|
16109
16150
|
/^\d{4}-\d{2}-\d{2}$/,
|
|
@@ -16118,7 +16159,7 @@ function registerHealthTools(server2, getIndex, getVaultPath, getConfig2 = () =>
|
|
|
16118
16159
|
// YYYY (yearly)
|
|
16119
16160
|
];
|
|
16120
16161
|
const periodicFolders = ["daily", "weekly", "monthly", "quarterly", "yearly", "journal", "journals"];
|
|
16121
|
-
const folder =
|
|
16162
|
+
const folder = path40.split("/")[0]?.toLowerCase() || "";
|
|
16122
16163
|
return patterns.some((p) => p.test(nameWithoutExt)) || periodicFolders.includes(folder);
|
|
16123
16164
|
}
|
|
16124
16165
|
async function runVaultStats() {
|
|
@@ -17225,13 +17266,13 @@ function registerPrimitiveTools(server2, getIndex, getVaultPath, getConfig2 = ()
|
|
|
17225
17266
|
max_content_chars: z6.number().default(2e4).describe("Max total chars of section content to include. Sections are truncated at paragraph boundaries.")
|
|
17226
17267
|
}
|
|
17227
17268
|
},
|
|
17228
|
-
async ({ path:
|
|
17269
|
+
async ({ path: path40, include_content, max_content_chars }) => {
|
|
17229
17270
|
const index = getIndex();
|
|
17230
17271
|
const vaultPath2 = getVaultPath();
|
|
17231
|
-
const result = await getNoteStructure(index,
|
|
17272
|
+
const result = await getNoteStructure(index, path40, vaultPath2);
|
|
17232
17273
|
if (!result) {
|
|
17233
17274
|
return {
|
|
17234
|
-
content: [{ type: "text", text: JSON.stringify({ error: "Note not found", path:
|
|
17275
|
+
content: [{ type: "text", text: JSON.stringify({ error: "Note not found", path: path40 }, null, 2) }]
|
|
17235
17276
|
};
|
|
17236
17277
|
}
|
|
17237
17278
|
let totalChars = 0;
|
|
@@ -17242,7 +17283,7 @@ function registerPrimitiveTools(server2, getIndex, getVaultPath, getConfig2 = ()
|
|
|
17242
17283
|
truncated = true;
|
|
17243
17284
|
break;
|
|
17244
17285
|
}
|
|
17245
|
-
const sectionResult = await getSectionContent(index,
|
|
17286
|
+
const sectionResult = await getSectionContent(index, path40, section.heading.text, vaultPath2, true);
|
|
17246
17287
|
if (sectionResult) {
|
|
17247
17288
|
let content = sectionResult.content;
|
|
17248
17289
|
const remaining = max_content_chars - totalChars;
|
|
@@ -17257,13 +17298,13 @@ function registerPrimitiveTools(server2, getIndex, getVaultPath, getConfig2 = ()
|
|
|
17257
17298
|
}
|
|
17258
17299
|
}
|
|
17259
17300
|
}
|
|
17260
|
-
const note = index.notes.get(
|
|
17301
|
+
const note = index.notes.get(path40);
|
|
17261
17302
|
const enriched = { ...result };
|
|
17262
17303
|
if (note) {
|
|
17263
17304
|
enriched.frontmatter = note.frontmatter;
|
|
17264
17305
|
enriched.tags = note.tags;
|
|
17265
17306
|
enriched.aliases = note.aliases;
|
|
17266
|
-
const normalizedPath =
|
|
17307
|
+
const normalizedPath = path40.toLowerCase().replace(/\.md$/, "");
|
|
17267
17308
|
const backlinks = index.backlinks.get(normalizedPath) || [];
|
|
17268
17309
|
enriched.backlink_count = backlinks.length;
|
|
17269
17310
|
enriched.outlink_count = note.outlinks.length;
|
|
@@ -17301,15 +17342,15 @@ function registerPrimitiveTools(server2, getIndex, getVaultPath, getConfig2 = ()
|
|
|
17301
17342
|
max_content_chars: z6.number().default(1e4).describe("Max chars of section content. Truncated at paragraph boundaries.")
|
|
17302
17343
|
}
|
|
17303
17344
|
},
|
|
17304
|
-
async ({ path:
|
|
17345
|
+
async ({ path: path40, heading, include_subheadings, max_content_chars }) => {
|
|
17305
17346
|
const index = getIndex();
|
|
17306
17347
|
const vaultPath2 = getVaultPath();
|
|
17307
|
-
const result = await getSectionContent(index,
|
|
17348
|
+
const result = await getSectionContent(index, path40, heading, vaultPath2, include_subheadings);
|
|
17308
17349
|
if (!result) {
|
|
17309
17350
|
return {
|
|
17310
17351
|
content: [{ type: "text", text: JSON.stringify({
|
|
17311
17352
|
error: "Section not found",
|
|
17312
|
-
path:
|
|
17353
|
+
path: path40,
|
|
17313
17354
|
heading
|
|
17314
17355
|
}, null, 2) }]
|
|
17315
17356
|
};
|
|
@@ -17370,16 +17411,16 @@ function registerPrimitiveTools(server2, getIndex, getVaultPath, getConfig2 = ()
|
|
|
17370
17411
|
offset: z6.coerce.number().default(0).describe("Number of results to skip (for pagination)")
|
|
17371
17412
|
}
|
|
17372
17413
|
},
|
|
17373
|
-
async ({ path:
|
|
17414
|
+
async ({ path: path40, status, has_due_date, folder, tag, limit: requestedLimit, offset }) => {
|
|
17374
17415
|
const limit = Math.min(requestedLimit ?? 25, MAX_LIMIT);
|
|
17375
17416
|
const index = getIndex();
|
|
17376
17417
|
const vaultPath2 = getVaultPath();
|
|
17377
17418
|
const config2 = getConfig2();
|
|
17378
|
-
if (
|
|
17379
|
-
const result2 = await getTasksFromNote(index,
|
|
17419
|
+
if (path40) {
|
|
17420
|
+
const result2 = await getTasksFromNote(index, path40, vaultPath2, getExcludeTags(config2));
|
|
17380
17421
|
if (!result2) {
|
|
17381
17422
|
return {
|
|
17382
|
-
content: [{ type: "text", text: JSON.stringify({ error: "Note not found", path:
|
|
17423
|
+
content: [{ type: "text", text: JSON.stringify({ error: "Note not found", path: path40 }, null, 2) }]
|
|
17383
17424
|
};
|
|
17384
17425
|
}
|
|
17385
17426
|
let filtered = result2;
|
|
@@ -17389,7 +17430,7 @@ function registerPrimitiveTools(server2, getIndex, getVaultPath, getConfig2 = ()
|
|
|
17389
17430
|
const paged2 = filtered.slice(offset, offset + limit);
|
|
17390
17431
|
return {
|
|
17391
17432
|
content: [{ type: "text", text: JSON.stringify({
|
|
17392
|
-
path:
|
|
17433
|
+
path: path40,
|
|
17393
17434
|
total_count: filtered.length,
|
|
17394
17435
|
returned_count: paged2.length,
|
|
17395
17436
|
open: result2.filter((t) => t.status === "open").length,
|
|
@@ -19371,8 +19412,8 @@ function registerNoteIntelligenceTools(server2, getIndex, getVaultPath, getConfi
|
|
|
19371
19412
|
// src/tools/write/mutations.ts
|
|
19372
19413
|
init_writer();
|
|
19373
19414
|
import { z as z12 } from "zod";
|
|
19374
|
-
import
|
|
19375
|
-
import
|
|
19415
|
+
import fs24 from "fs/promises";
|
|
19416
|
+
import path26 from "path";
|
|
19376
19417
|
|
|
19377
19418
|
// src/core/write/validator.ts
|
|
19378
19419
|
var TIMESTAMP_PATTERN = /^\*\*\d{2}:\d{2}\*\*/;
|
|
@@ -19590,63 +19631,63 @@ init_constants2();
|
|
|
19590
19631
|
init_writer();
|
|
19591
19632
|
init_wikilinks();
|
|
19592
19633
|
init_wikilinkFeedback();
|
|
19593
|
-
import
|
|
19594
|
-
import
|
|
19634
|
+
import fs23 from "fs/promises";
|
|
19635
|
+
import path25 from "path";
|
|
19595
19636
|
|
|
19596
19637
|
// src/core/write/policy/policyPaths.ts
|
|
19597
|
-
import
|
|
19598
|
-
import
|
|
19638
|
+
import fs22 from "fs/promises";
|
|
19639
|
+
import path24 from "path";
|
|
19599
19640
|
function getPoliciesDir(vaultPath2) {
|
|
19600
|
-
return
|
|
19641
|
+
return path24.join(vaultPath2, ".flywheel", "policies");
|
|
19601
19642
|
}
|
|
19602
19643
|
function getLegacyPoliciesDir(vaultPath2) {
|
|
19603
|
-
return
|
|
19644
|
+
return path24.join(vaultPath2, ".claude", "policies");
|
|
19604
19645
|
}
|
|
19605
19646
|
async function ensurePoliciesDir(vaultPath2) {
|
|
19606
19647
|
const dir = getPoliciesDir(vaultPath2);
|
|
19607
|
-
await
|
|
19648
|
+
await fs22.mkdir(dir, { recursive: true });
|
|
19608
19649
|
}
|
|
19609
19650
|
async function migratePoliciesIfNeeded(vaultPath2) {
|
|
19610
19651
|
const legacyDir = getLegacyPoliciesDir(vaultPath2);
|
|
19611
19652
|
let files;
|
|
19612
19653
|
try {
|
|
19613
|
-
files = await
|
|
19654
|
+
files = await fs22.readdir(legacyDir);
|
|
19614
19655
|
} catch {
|
|
19615
19656
|
return;
|
|
19616
19657
|
}
|
|
19617
19658
|
const yamlFiles = files.filter((f) => f.endsWith(".yaml") || f.endsWith(".yml"));
|
|
19618
19659
|
if (yamlFiles.length === 0) {
|
|
19619
19660
|
await tryRmdir(legacyDir);
|
|
19620
|
-
await tryRmdir(
|
|
19661
|
+
await tryRmdir(path24.join(vaultPath2, ".claude"));
|
|
19621
19662
|
return;
|
|
19622
19663
|
}
|
|
19623
19664
|
await ensurePoliciesDir(vaultPath2);
|
|
19624
19665
|
const destDir = getPoliciesDir(vaultPath2);
|
|
19625
19666
|
for (const file of yamlFiles) {
|
|
19626
|
-
const src =
|
|
19627
|
-
const dest =
|
|
19667
|
+
const src = path24.join(legacyDir, file);
|
|
19668
|
+
const dest = path24.join(destDir, file);
|
|
19628
19669
|
try {
|
|
19629
|
-
await
|
|
19670
|
+
await fs22.access(dest);
|
|
19630
19671
|
} catch {
|
|
19631
|
-
await
|
|
19672
|
+
await fs22.copyFile(src, dest);
|
|
19632
19673
|
}
|
|
19633
|
-
await
|
|
19674
|
+
await fs22.unlink(src);
|
|
19634
19675
|
}
|
|
19635
19676
|
await tryRmdir(legacyDir);
|
|
19636
|
-
await tryRmdir(
|
|
19677
|
+
await tryRmdir(path24.join(vaultPath2, ".claude"));
|
|
19637
19678
|
}
|
|
19638
19679
|
async function tryRmdir(dir) {
|
|
19639
19680
|
try {
|
|
19640
|
-
const remaining = await
|
|
19681
|
+
const remaining = await fs22.readdir(dir);
|
|
19641
19682
|
if (remaining.length === 0) {
|
|
19642
|
-
await
|
|
19683
|
+
await fs22.rmdir(dir);
|
|
19643
19684
|
}
|
|
19644
19685
|
} catch {
|
|
19645
19686
|
}
|
|
19646
19687
|
}
|
|
19647
19688
|
var migrationCache = /* @__PURE__ */ new Map();
|
|
19648
19689
|
async function ensureMigrated(vaultPath2) {
|
|
19649
|
-
const key =
|
|
19690
|
+
const key = path24.resolve(vaultPath2);
|
|
19650
19691
|
if (!migrationCache.has(key)) {
|
|
19651
19692
|
migrationCache.set(key, migratePoliciesIfNeeded(vaultPath2));
|
|
19652
19693
|
}
|
|
@@ -19702,7 +19743,7 @@ async function handleGitCommit(vaultPath2, notePath, commit, prefix) {
|
|
|
19702
19743
|
async function getPolicyHint(vaultPath2) {
|
|
19703
19744
|
try {
|
|
19704
19745
|
const policiesDir = getPoliciesDir(vaultPath2);
|
|
19705
|
-
const files = await
|
|
19746
|
+
const files = await fs23.readdir(policiesDir);
|
|
19706
19747
|
const yamlFiles = files.filter((f) => f.endsWith(".yaml") || f.endsWith(".yml"));
|
|
19707
19748
|
if (yamlFiles.length > 0) {
|
|
19708
19749
|
const names = yamlFiles.map((f) => f.replace(/\.ya?ml$/, "")).join(", ");
|
|
@@ -19713,9 +19754,9 @@ async function getPolicyHint(vaultPath2) {
|
|
|
19713
19754
|
return "";
|
|
19714
19755
|
}
|
|
19715
19756
|
async function ensureFileExists(vaultPath2, notePath) {
|
|
19716
|
-
const fullPath =
|
|
19757
|
+
const fullPath = path25.join(vaultPath2, notePath);
|
|
19717
19758
|
try {
|
|
19718
|
-
await
|
|
19759
|
+
await fs23.access(fullPath);
|
|
19719
19760
|
return null;
|
|
19720
19761
|
} catch {
|
|
19721
19762
|
const hint = await getPolicyHint(vaultPath2);
|
|
@@ -19918,17 +19959,17 @@ async function executeCreateNote(options) {
|
|
|
19918
19959
|
if (!pathCheck.valid) {
|
|
19919
19960
|
return { success: false, result: errorResult(notePath, `Path blocked: ${pathCheck.reason}`), filesWritten: [] };
|
|
19920
19961
|
}
|
|
19921
|
-
const fullPath =
|
|
19962
|
+
const fullPath = path25.join(vaultPath2, notePath);
|
|
19922
19963
|
let fileExists = false;
|
|
19923
19964
|
try {
|
|
19924
|
-
await
|
|
19965
|
+
await fs23.access(fullPath);
|
|
19925
19966
|
fileExists = true;
|
|
19926
19967
|
} catch {
|
|
19927
19968
|
}
|
|
19928
19969
|
if (fileExists && !overwrite) {
|
|
19929
19970
|
return { success: false, result: errorResult(notePath, `File already exists: ${notePath}. Use overwrite=true to replace.`), filesWritten: [] };
|
|
19930
19971
|
}
|
|
19931
|
-
await
|
|
19972
|
+
await fs23.mkdir(path25.dirname(fullPath), { recursive: true });
|
|
19932
19973
|
const { maybeApplyWikilinks: maybeApplyWikilinks2 } = await Promise.resolve().then(() => (init_wikilinks(), wikilinks_exports));
|
|
19933
19974
|
const { content: processedContent } = maybeApplyWikilinks2(content, skipWikilinks ?? false, notePath);
|
|
19934
19975
|
let finalFrontmatter = frontmatter;
|
|
@@ -19962,13 +20003,13 @@ async function executeDeleteNote(options) {
|
|
|
19962
20003
|
if (!pathCheck.valid) {
|
|
19963
20004
|
return { success: false, result: errorResult(notePath, `Path blocked: ${pathCheck.reason}`), filesWritten: [] };
|
|
19964
20005
|
}
|
|
19965
|
-
const fullPath =
|
|
20006
|
+
const fullPath = path25.join(vaultPath2, notePath);
|
|
19966
20007
|
try {
|
|
19967
|
-
await
|
|
20008
|
+
await fs23.access(fullPath);
|
|
19968
20009
|
} catch {
|
|
19969
20010
|
return { success: false, result: errorResult(notePath, `File not found: ${notePath}`), filesWritten: [] };
|
|
19970
20011
|
}
|
|
19971
|
-
await
|
|
20012
|
+
await fs23.unlink(fullPath);
|
|
19972
20013
|
const result = successResult(notePath, `Deleted note: ${notePath}`, {});
|
|
19973
20014
|
return { success: true, result, filesWritten: [notePath] };
|
|
19974
20015
|
} catch (error) {
|
|
@@ -19986,10 +20027,10 @@ async function createNoteFromTemplate(vaultPath2, notePath, config2) {
|
|
|
19986
20027
|
if (!validation.valid) {
|
|
19987
20028
|
throw new Error(`Path blocked: ${validation.reason}`);
|
|
19988
20029
|
}
|
|
19989
|
-
const fullPath =
|
|
19990
|
-
await
|
|
20030
|
+
const fullPath = path26.join(vaultPath2, notePath);
|
|
20031
|
+
await fs24.mkdir(path26.dirname(fullPath), { recursive: true });
|
|
19991
20032
|
const templates = config2.templates || {};
|
|
19992
|
-
const filename =
|
|
20033
|
+
const filename = path26.basename(notePath, ".md").toLowerCase();
|
|
19993
20034
|
let templatePath;
|
|
19994
20035
|
let periodicType;
|
|
19995
20036
|
const dailyPattern = /^\d{4}-\d{2}-\d{2}/;
|
|
@@ -20022,7 +20063,7 @@ async function createNoteFromTemplate(vaultPath2, notePath, config2) {
|
|
|
20022
20063
|
];
|
|
20023
20064
|
for (const candidate of candidates) {
|
|
20024
20065
|
try {
|
|
20025
|
-
await
|
|
20066
|
+
await fs24.access(path26.join(vaultPath2, candidate));
|
|
20026
20067
|
templatePath = candidate;
|
|
20027
20068
|
console.error(`[Flywheel] Template not in config but found at ${candidate} \u2014 using it`);
|
|
20028
20069
|
break;
|
|
@@ -20033,11 +20074,11 @@ async function createNoteFromTemplate(vaultPath2, notePath, config2) {
|
|
|
20033
20074
|
let templateContent;
|
|
20034
20075
|
if (templatePath) {
|
|
20035
20076
|
try {
|
|
20036
|
-
const absTemplatePath =
|
|
20037
|
-
templateContent = await
|
|
20077
|
+
const absTemplatePath = path26.join(vaultPath2, templatePath);
|
|
20078
|
+
templateContent = await fs24.readFile(absTemplatePath, "utf-8");
|
|
20038
20079
|
} catch {
|
|
20039
20080
|
console.error(`[Flywheel] Template at ${templatePath} not readable, using minimal fallback`);
|
|
20040
|
-
const title =
|
|
20081
|
+
const title = path26.basename(notePath, ".md");
|
|
20041
20082
|
templateContent = `---
|
|
20042
20083
|
---
|
|
20043
20084
|
|
|
@@ -20049,7 +20090,7 @@ async function createNoteFromTemplate(vaultPath2, notePath, config2) {
|
|
|
20049
20090
|
if (periodicType) {
|
|
20050
20091
|
console.error(`[Flywheel] No ${periodicType} template found in config or vault \u2014 using minimal fallback`);
|
|
20051
20092
|
}
|
|
20052
|
-
const title =
|
|
20093
|
+
const title = path26.basename(notePath, ".md");
|
|
20053
20094
|
templateContent = `---
|
|
20054
20095
|
---
|
|
20055
20096
|
|
|
@@ -20058,7 +20099,7 @@ async function createNoteFromTemplate(vaultPath2, notePath, config2) {
|
|
|
20058
20099
|
}
|
|
20059
20100
|
const now = /* @__PURE__ */ new Date();
|
|
20060
20101
|
const dateStr = now.toISOString().split("T")[0];
|
|
20061
|
-
templateContent = templateContent.replace(/\{\{date\}\}/g, dateStr).replace(/\{\{title\}\}/g,
|
|
20102
|
+
templateContent = templateContent.replace(/\{\{date\}\}/g, dateStr).replace(/\{\{title\}\}/g, path26.basename(notePath, ".md"));
|
|
20062
20103
|
const matter9 = (await import("gray-matter")).default;
|
|
20063
20104
|
const parsed = matter9(templateContent);
|
|
20064
20105
|
if (!parsed.data.date) {
|
|
@@ -20097,9 +20138,9 @@ function registerMutationTools(server2, getVaultPath, getConfig2 = () => ({})) {
|
|
|
20097
20138
|
let noteCreated = false;
|
|
20098
20139
|
let templateUsed;
|
|
20099
20140
|
if (create_if_missing && !dry_run) {
|
|
20100
|
-
const fullPath =
|
|
20141
|
+
const fullPath = path26.join(vaultPath2, notePath);
|
|
20101
20142
|
try {
|
|
20102
|
-
await
|
|
20143
|
+
await fs24.access(fullPath);
|
|
20103
20144
|
} catch {
|
|
20104
20145
|
const config2 = getConfig2();
|
|
20105
20146
|
const result = await createNoteFromTemplate(vaultPath2, notePath, config2);
|
|
@@ -20108,9 +20149,9 @@ function registerMutationTools(server2, getVaultPath, getConfig2 = () => ({})) {
|
|
|
20108
20149
|
}
|
|
20109
20150
|
}
|
|
20110
20151
|
if (create_if_missing && dry_run) {
|
|
20111
|
-
const fullPath =
|
|
20152
|
+
const fullPath = path26.join(vaultPath2, notePath);
|
|
20112
20153
|
try {
|
|
20113
|
-
await
|
|
20154
|
+
await fs24.access(fullPath);
|
|
20114
20155
|
} catch {
|
|
20115
20156
|
return {
|
|
20116
20157
|
content: [{
|
|
@@ -20594,8 +20635,8 @@ function registerFrontmatterTools(server2, getVaultPath) {
|
|
|
20594
20635
|
init_writer();
|
|
20595
20636
|
init_wikilinks();
|
|
20596
20637
|
import { z as z15 } from "zod";
|
|
20597
|
-
import
|
|
20598
|
-
import
|
|
20638
|
+
import fs25 from "fs/promises";
|
|
20639
|
+
import path27 from "path";
|
|
20599
20640
|
function registerNoteTools(server2, getVaultPath, getIndex) {
|
|
20600
20641
|
server2.tool(
|
|
20601
20642
|
"vault_create_note",
|
|
@@ -20621,23 +20662,23 @@ function registerNoteTools(server2, getVaultPath, getIndex) {
|
|
|
20621
20662
|
if (!validatePath(vaultPath2, notePath)) {
|
|
20622
20663
|
return formatMcpResult(errorResult(notePath, "Invalid path: path traversal not allowed"));
|
|
20623
20664
|
}
|
|
20624
|
-
const fullPath =
|
|
20665
|
+
const fullPath = path27.join(vaultPath2, notePath);
|
|
20625
20666
|
const existsCheck = await ensureFileExists(vaultPath2, notePath);
|
|
20626
20667
|
if (existsCheck === null && !overwrite) {
|
|
20627
20668
|
return formatMcpResult(errorResult(notePath, `File already exists: ${notePath}. Use overwrite=true to replace.`));
|
|
20628
20669
|
}
|
|
20629
|
-
const dir =
|
|
20630
|
-
await
|
|
20670
|
+
const dir = path27.dirname(fullPath);
|
|
20671
|
+
await fs25.mkdir(dir, { recursive: true });
|
|
20631
20672
|
let effectiveContent = content;
|
|
20632
20673
|
let effectiveFrontmatter = frontmatter;
|
|
20633
20674
|
if (template) {
|
|
20634
|
-
const templatePath =
|
|
20675
|
+
const templatePath = path27.join(vaultPath2, template);
|
|
20635
20676
|
try {
|
|
20636
|
-
const raw = await
|
|
20677
|
+
const raw = await fs25.readFile(templatePath, "utf-8");
|
|
20637
20678
|
const matter9 = (await import("gray-matter")).default;
|
|
20638
20679
|
const parsed = matter9(raw);
|
|
20639
20680
|
const dateStr = (/* @__PURE__ */ new Date()).toISOString().split("T")[0];
|
|
20640
|
-
const title =
|
|
20681
|
+
const title = path27.basename(notePath, ".md");
|
|
20641
20682
|
let templateContent = parsed.content.replace(/\{\{date\}\}/g, dateStr).replace(/\{\{title\}\}/g, title);
|
|
20642
20683
|
if (content) {
|
|
20643
20684
|
templateContent = templateContent.trimEnd() + "\n\n" + content;
|
|
@@ -20656,7 +20697,7 @@ function registerNoteTools(server2, getVaultPath, getIndex) {
|
|
|
20656
20697
|
effectiveFrontmatter.created = now.toISOString();
|
|
20657
20698
|
}
|
|
20658
20699
|
const warnings = [];
|
|
20659
|
-
const noteName =
|
|
20700
|
+
const noteName = path27.basename(notePath, ".md");
|
|
20660
20701
|
const existingAliases = Array.isArray(effectiveFrontmatter?.aliases) ? effectiveFrontmatter.aliases.filter((a) => typeof a === "string") : [];
|
|
20661
20702
|
const preflight = await checkPreflightSimilarity(noteName);
|
|
20662
20703
|
if (preflight.existingEntity) {
|
|
@@ -20797,8 +20838,8 @@ ${sources}`;
|
|
|
20797
20838
|
}
|
|
20798
20839
|
return formatMcpResult(errorResult(notePath, previewLines.join("\n")));
|
|
20799
20840
|
}
|
|
20800
|
-
const fullPath =
|
|
20801
|
-
await
|
|
20841
|
+
const fullPath = path27.join(vaultPath2, notePath);
|
|
20842
|
+
await fs25.unlink(fullPath);
|
|
20802
20843
|
const gitInfo = await handleGitCommit(vaultPath2, notePath, commit, "[Flywheel:Delete]");
|
|
20803
20844
|
const message = backlinkWarning ? `Deleted note: ${notePath}
|
|
20804
20845
|
|
|
@@ -20818,8 +20859,8 @@ init_writer();
|
|
|
20818
20859
|
init_git();
|
|
20819
20860
|
init_wikilinks();
|
|
20820
20861
|
import { z as z16 } from "zod";
|
|
20821
|
-
import
|
|
20822
|
-
import
|
|
20862
|
+
import fs26 from "fs/promises";
|
|
20863
|
+
import path28 from "path";
|
|
20823
20864
|
import matter6 from "gray-matter";
|
|
20824
20865
|
function escapeRegex(str) {
|
|
20825
20866
|
return str.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
@@ -20838,16 +20879,16 @@ function extractWikilinks2(content) {
|
|
|
20838
20879
|
return wikilinks;
|
|
20839
20880
|
}
|
|
20840
20881
|
function getTitleFromPath(filePath) {
|
|
20841
|
-
return
|
|
20882
|
+
return path28.basename(filePath, ".md");
|
|
20842
20883
|
}
|
|
20843
20884
|
async function findBacklinks(vaultPath2, targetTitle, targetAliases) {
|
|
20844
20885
|
const results = [];
|
|
20845
20886
|
const allTargets = [targetTitle, ...targetAliases].map((t) => t.toLowerCase());
|
|
20846
20887
|
async function scanDir(dir) {
|
|
20847
20888
|
const files = [];
|
|
20848
|
-
const entries = await
|
|
20889
|
+
const entries = await fs26.readdir(dir, { withFileTypes: true });
|
|
20849
20890
|
for (const entry of entries) {
|
|
20850
|
-
const fullPath =
|
|
20891
|
+
const fullPath = path28.join(dir, entry.name);
|
|
20851
20892
|
if (entry.isDirectory() && !entry.name.startsWith(".")) {
|
|
20852
20893
|
files.push(...await scanDir(fullPath));
|
|
20853
20894
|
} else if (entry.isFile() && entry.name.endsWith(".md")) {
|
|
@@ -20858,8 +20899,8 @@ async function findBacklinks(vaultPath2, targetTitle, targetAliases) {
|
|
|
20858
20899
|
}
|
|
20859
20900
|
const allFiles = await scanDir(vaultPath2);
|
|
20860
20901
|
for (const filePath of allFiles) {
|
|
20861
|
-
const relativePath =
|
|
20862
|
-
const content = await
|
|
20902
|
+
const relativePath = path28.relative(vaultPath2, filePath);
|
|
20903
|
+
const content = await fs26.readFile(filePath, "utf-8");
|
|
20863
20904
|
const wikilinks = extractWikilinks2(content);
|
|
20864
20905
|
const matchingLinks = [];
|
|
20865
20906
|
for (const link of wikilinks) {
|
|
@@ -20945,10 +20986,10 @@ function registerMoveNoteTools(server2, getVaultPath) {
|
|
|
20945
20986
|
};
|
|
20946
20987
|
return { content: [{ type: "text", text: JSON.stringify(result2, null, 2) }] };
|
|
20947
20988
|
}
|
|
20948
|
-
const oldFullPath =
|
|
20949
|
-
const newFullPath =
|
|
20989
|
+
const oldFullPath = path28.join(vaultPath2, oldPath);
|
|
20990
|
+
const newFullPath = path28.join(vaultPath2, newPath);
|
|
20950
20991
|
try {
|
|
20951
|
-
await
|
|
20992
|
+
await fs26.access(oldFullPath);
|
|
20952
20993
|
} catch {
|
|
20953
20994
|
const result2 = {
|
|
20954
20995
|
success: false,
|
|
@@ -20958,7 +20999,7 @@ function registerMoveNoteTools(server2, getVaultPath) {
|
|
|
20958
20999
|
return { content: [{ type: "text", text: JSON.stringify(result2, null, 2) }] };
|
|
20959
21000
|
}
|
|
20960
21001
|
try {
|
|
20961
|
-
await
|
|
21002
|
+
await fs26.access(newFullPath);
|
|
20962
21003
|
const result2 = {
|
|
20963
21004
|
success: false,
|
|
20964
21005
|
message: `Destination already exists: ${newPath}`,
|
|
@@ -20967,7 +21008,7 @@ function registerMoveNoteTools(server2, getVaultPath) {
|
|
|
20967
21008
|
return { content: [{ type: "text", text: JSON.stringify(result2, null, 2) }] };
|
|
20968
21009
|
} catch {
|
|
20969
21010
|
}
|
|
20970
|
-
const sourceContent = await
|
|
21011
|
+
const sourceContent = await fs26.readFile(oldFullPath, "utf-8");
|
|
20971
21012
|
const parsed = matter6(sourceContent);
|
|
20972
21013
|
const aliases = extractAliases2(parsed.data);
|
|
20973
21014
|
const oldTitle = getTitleFromPath(oldPath);
|
|
@@ -21027,9 +21068,9 @@ function registerMoveNoteTools(server2, getVaultPath) {
|
|
|
21027
21068
|
};
|
|
21028
21069
|
return { content: [{ type: "text", text: JSON.stringify(result2, null, 2) }] };
|
|
21029
21070
|
}
|
|
21030
|
-
const destDir =
|
|
21031
|
-
await
|
|
21032
|
-
await
|
|
21071
|
+
const destDir = path28.dirname(newFullPath);
|
|
21072
|
+
await fs26.mkdir(destDir, { recursive: true });
|
|
21073
|
+
await fs26.rename(oldFullPath, newFullPath);
|
|
21033
21074
|
let gitCommit;
|
|
21034
21075
|
let undoAvailable;
|
|
21035
21076
|
let staleLockDetected;
|
|
@@ -21103,12 +21144,12 @@ function registerMoveNoteTools(server2, getVaultPath) {
|
|
|
21103
21144
|
if (sanitizedTitle !== newTitle) {
|
|
21104
21145
|
console.error(`[Flywheel] Title sanitized: "${newTitle}" \u2192 "${sanitizedTitle}"`);
|
|
21105
21146
|
}
|
|
21106
|
-
const fullPath =
|
|
21107
|
-
const dir =
|
|
21108
|
-
const newPath = dir === "." ? `${sanitizedTitle}.md` :
|
|
21109
|
-
const newFullPath =
|
|
21147
|
+
const fullPath = path28.join(vaultPath2, notePath);
|
|
21148
|
+
const dir = path28.dirname(notePath);
|
|
21149
|
+
const newPath = dir === "." ? `${sanitizedTitle}.md` : path28.join(dir, `${sanitizedTitle}.md`);
|
|
21150
|
+
const newFullPath = path28.join(vaultPath2, newPath);
|
|
21110
21151
|
try {
|
|
21111
|
-
await
|
|
21152
|
+
await fs26.access(fullPath);
|
|
21112
21153
|
} catch {
|
|
21113
21154
|
const result2 = {
|
|
21114
21155
|
success: false,
|
|
@@ -21119,7 +21160,7 @@ function registerMoveNoteTools(server2, getVaultPath) {
|
|
|
21119
21160
|
}
|
|
21120
21161
|
if (fullPath !== newFullPath) {
|
|
21121
21162
|
try {
|
|
21122
|
-
await
|
|
21163
|
+
await fs26.access(newFullPath);
|
|
21123
21164
|
const result2 = {
|
|
21124
21165
|
success: false,
|
|
21125
21166
|
message: `A note with this title already exists: ${newPath}`,
|
|
@@ -21129,7 +21170,7 @@ function registerMoveNoteTools(server2, getVaultPath) {
|
|
|
21129
21170
|
} catch {
|
|
21130
21171
|
}
|
|
21131
21172
|
}
|
|
21132
|
-
const sourceContent = await
|
|
21173
|
+
const sourceContent = await fs26.readFile(fullPath, "utf-8");
|
|
21133
21174
|
const parsed = matter6(sourceContent);
|
|
21134
21175
|
const aliases = extractAliases2(parsed.data);
|
|
21135
21176
|
const oldTitle = getTitleFromPath(notePath);
|
|
@@ -21189,7 +21230,7 @@ function registerMoveNoteTools(server2, getVaultPath) {
|
|
|
21189
21230
|
return { content: [{ type: "text", text: JSON.stringify(result2, null, 2) }] };
|
|
21190
21231
|
}
|
|
21191
21232
|
if (fullPath !== newFullPath) {
|
|
21192
|
-
await
|
|
21233
|
+
await fs26.rename(fullPath, newFullPath);
|
|
21193
21234
|
}
|
|
21194
21235
|
let gitCommit;
|
|
21195
21236
|
let undoAvailable;
|
|
@@ -21237,8 +21278,8 @@ function registerMoveNoteTools(server2, getVaultPath) {
|
|
|
21237
21278
|
init_writer();
|
|
21238
21279
|
init_wikilinks();
|
|
21239
21280
|
import { z as z17 } from "zod";
|
|
21240
|
-
import
|
|
21241
|
-
import
|
|
21281
|
+
import fs27 from "fs/promises";
|
|
21282
|
+
import path29 from "path";
|
|
21242
21283
|
function registerMergeTools(server2, getVaultPath) {
|
|
21243
21284
|
server2.tool(
|
|
21244
21285
|
"merge_entities",
|
|
@@ -21365,7 +21406,7 @@ ${trimmedSource}`;
|
|
|
21365
21406
|
}
|
|
21366
21407
|
await writeVaultFile(vaultPath2, target_path, targetContent, targetFrontmatter, "LF", targetContentHash);
|
|
21367
21408
|
const fullSourcePath = `${vaultPath2}/${source_path}`;
|
|
21368
|
-
await
|
|
21409
|
+
await fs27.unlink(fullSourcePath);
|
|
21369
21410
|
initializeEntityIndex(vaultPath2).catch((err) => {
|
|
21370
21411
|
console.error(`[Flywheel] Entity cache rebuild failed: ${err}`);
|
|
21371
21412
|
});
|
|
@@ -21480,7 +21521,7 @@ ${trimmedSource}`;
|
|
|
21480
21521
|
}
|
|
21481
21522
|
let sourceDeleted = false;
|
|
21482
21523
|
if (sourceNoteFile) {
|
|
21483
|
-
await
|
|
21524
|
+
await fs27.unlink(`${vaultPath2}/${sourceNoteFile}`);
|
|
21484
21525
|
sourceDeleted = true;
|
|
21485
21526
|
}
|
|
21486
21527
|
initializeEntityIndex(vaultPath2).catch((err) => {
|
|
@@ -21529,21 +21570,21 @@ async function findSourceNote(vaultPath2, sourceName, excludePath) {
|
|
|
21529
21570
|
async function scanDir(dir) {
|
|
21530
21571
|
let entries;
|
|
21531
21572
|
try {
|
|
21532
|
-
entries = await
|
|
21573
|
+
entries = await fs27.readdir(dir, { withFileTypes: true });
|
|
21533
21574
|
} catch {
|
|
21534
21575
|
return null;
|
|
21535
21576
|
}
|
|
21536
21577
|
for (const entry of entries) {
|
|
21537
21578
|
if (entry.name.startsWith(".")) continue;
|
|
21538
|
-
const fullPath =
|
|
21579
|
+
const fullPath = path29.join(dir, entry.name);
|
|
21539
21580
|
if (entry.isDirectory()) {
|
|
21540
21581
|
const found = await scanDir(fullPath);
|
|
21541
21582
|
if (found) return found;
|
|
21542
21583
|
} else if (entry.isFile() && entry.name.endsWith(".md")) {
|
|
21543
|
-
const basename5 =
|
|
21584
|
+
const basename5 = path29.basename(entry.name, ".md");
|
|
21544
21585
|
if (basename5.toLowerCase() === targetLower) {
|
|
21545
|
-
const
|
|
21546
|
-
if (
|
|
21586
|
+
const relative2 = path29.relative(vaultPath2, fullPath).replace(/\\/g, "/");
|
|
21587
|
+
if (relative2 !== excludePath) return relative2;
|
|
21547
21588
|
}
|
|
21548
21589
|
}
|
|
21549
21590
|
}
|
|
@@ -21663,7 +21704,7 @@ Message: ${undoResult.undoneCommit.message}` : void 0
|
|
|
21663
21704
|
}
|
|
21664
21705
|
|
|
21665
21706
|
// src/tools/write/policy.ts
|
|
21666
|
-
import * as
|
|
21707
|
+
import * as path34 from "path";
|
|
21667
21708
|
import { z as z20 } from "zod";
|
|
21668
21709
|
|
|
21669
21710
|
// src/core/write/policy/index.ts
|
|
@@ -21672,8 +21713,8 @@ init_schema();
|
|
|
21672
21713
|
|
|
21673
21714
|
// src/core/write/policy/parser.ts
|
|
21674
21715
|
init_schema();
|
|
21675
|
-
import
|
|
21676
|
-
import
|
|
21716
|
+
import fs28 from "fs/promises";
|
|
21717
|
+
import path30 from "path";
|
|
21677
21718
|
import matter7 from "gray-matter";
|
|
21678
21719
|
function parseYaml(content) {
|
|
21679
21720
|
const parsed = matter7(`---
|
|
@@ -21698,7 +21739,7 @@ function parsePolicyString(yamlContent) {
|
|
|
21698
21739
|
}
|
|
21699
21740
|
async function loadPolicyFile(filePath) {
|
|
21700
21741
|
try {
|
|
21701
|
-
const content = await
|
|
21742
|
+
const content = await fs28.readFile(filePath, "utf-8");
|
|
21702
21743
|
return parsePolicyString(content);
|
|
21703
21744
|
} catch (error) {
|
|
21704
21745
|
if (error.code === "ENOENT") {
|
|
@@ -21724,14 +21765,14 @@ async function loadPolicyFile(filePath) {
|
|
|
21724
21765
|
async function loadPolicy(vaultPath2, policyName) {
|
|
21725
21766
|
await ensureMigrated(vaultPath2);
|
|
21726
21767
|
const policiesDir = getPoliciesDir(vaultPath2);
|
|
21727
|
-
const policyPath =
|
|
21768
|
+
const policyPath = path30.join(policiesDir, `${policyName}.yaml`);
|
|
21728
21769
|
try {
|
|
21729
|
-
await
|
|
21770
|
+
await fs28.access(policyPath);
|
|
21730
21771
|
return loadPolicyFile(policyPath);
|
|
21731
21772
|
} catch {
|
|
21732
|
-
const ymlPath =
|
|
21773
|
+
const ymlPath = path30.join(policiesDir, `${policyName}.yml`);
|
|
21733
21774
|
try {
|
|
21734
|
-
await
|
|
21775
|
+
await fs28.access(ymlPath);
|
|
21735
21776
|
return loadPolicyFile(ymlPath);
|
|
21736
21777
|
} catch {
|
|
21737
21778
|
return {
|
|
@@ -21871,8 +21912,8 @@ init_schema();
|
|
|
21871
21912
|
init_writer();
|
|
21872
21913
|
init_git();
|
|
21873
21914
|
init_wikilinks();
|
|
21874
|
-
import
|
|
21875
|
-
import
|
|
21915
|
+
import fs30 from "fs/promises";
|
|
21916
|
+
import path32 from "path";
|
|
21876
21917
|
init_constants2();
|
|
21877
21918
|
async function executeStep(step, vaultPath2, context, conditionResults, searchFn) {
|
|
21878
21919
|
const { execute, reason } = shouldStepExecute(step.when, conditionResults);
|
|
@@ -22063,12 +22104,12 @@ async function executeCreateNote2(params, vaultPath2, context) {
|
|
|
22063
22104
|
let frontmatter = params.frontmatter || {};
|
|
22064
22105
|
if (params.template) {
|
|
22065
22106
|
try {
|
|
22066
|
-
const templatePath =
|
|
22067
|
-
const raw = await
|
|
22107
|
+
const templatePath = path32.join(vaultPath2, String(params.template));
|
|
22108
|
+
const raw = await fs30.readFile(templatePath, "utf-8");
|
|
22068
22109
|
const matter9 = (await import("gray-matter")).default;
|
|
22069
22110
|
const parsed = matter9(raw);
|
|
22070
22111
|
const dateStr = (/* @__PURE__ */ new Date()).toISOString().split("T")[0];
|
|
22071
|
-
const title =
|
|
22112
|
+
const title = path32.basename(notePath, ".md");
|
|
22072
22113
|
let templateContent = parsed.content.replace(/\{\{date\}\}/g, dateStr).replace(/\{\{title\}\}/g, title);
|
|
22073
22114
|
if (content) {
|
|
22074
22115
|
templateContent = templateContent.trimEnd() + "\n\n" + content;
|
|
@@ -22101,9 +22142,9 @@ async function executeToggleTask(params, vaultPath2) {
|
|
|
22101
22142
|
const notePath = String(params.path || "");
|
|
22102
22143
|
const task = String(params.task || "");
|
|
22103
22144
|
const section = params.section ? String(params.section) : void 0;
|
|
22104
|
-
const fullPath =
|
|
22145
|
+
const fullPath = path32.join(vaultPath2, notePath);
|
|
22105
22146
|
try {
|
|
22106
|
-
await
|
|
22147
|
+
await fs30.access(fullPath);
|
|
22107
22148
|
} catch {
|
|
22108
22149
|
return { success: false, message: `File not found: ${notePath}`, path: notePath };
|
|
22109
22150
|
}
|
|
@@ -22384,15 +22425,15 @@ async function rollbackChanges(vaultPath2, originalContents, filesModified) {
|
|
|
22384
22425
|
const pathCheck = await validatePathSecure(vaultPath2, filePath);
|
|
22385
22426
|
if (!pathCheck.valid) continue;
|
|
22386
22427
|
const original = originalContents.get(filePath);
|
|
22387
|
-
const fullPath =
|
|
22428
|
+
const fullPath = path32.join(vaultPath2, filePath);
|
|
22388
22429
|
if (original === null) {
|
|
22389
22430
|
try {
|
|
22390
|
-
await
|
|
22431
|
+
await fs30.unlink(fullPath);
|
|
22391
22432
|
} catch {
|
|
22392
22433
|
}
|
|
22393
22434
|
} else if (original !== void 0) {
|
|
22394
22435
|
try {
|
|
22395
|
-
await
|
|
22436
|
+
await fs30.writeFile(fullPath, original);
|
|
22396
22437
|
} catch {
|
|
22397
22438
|
}
|
|
22398
22439
|
}
|
|
@@ -22438,27 +22479,27 @@ async function previewPolicy(policy, vaultPath2, variables) {
|
|
|
22438
22479
|
}
|
|
22439
22480
|
|
|
22440
22481
|
// src/core/write/policy/storage.ts
|
|
22441
|
-
import
|
|
22442
|
-
import
|
|
22482
|
+
import fs31 from "fs/promises";
|
|
22483
|
+
import path33 from "path";
|
|
22443
22484
|
async function listPolicies(vaultPath2) {
|
|
22444
22485
|
await ensureMigrated(vaultPath2);
|
|
22445
22486
|
const dir = getPoliciesDir(vaultPath2);
|
|
22446
22487
|
const policies = [];
|
|
22447
22488
|
try {
|
|
22448
|
-
const files = await
|
|
22489
|
+
const files = await fs31.readdir(dir);
|
|
22449
22490
|
for (const file of files) {
|
|
22450
22491
|
if (!file.endsWith(".yaml") && !file.endsWith(".yml")) {
|
|
22451
22492
|
continue;
|
|
22452
22493
|
}
|
|
22453
|
-
const filePath =
|
|
22454
|
-
const
|
|
22455
|
-
const content = await
|
|
22494
|
+
const filePath = path33.join(dir, file);
|
|
22495
|
+
const stat4 = await fs31.stat(filePath);
|
|
22496
|
+
const content = await fs31.readFile(filePath, "utf-8");
|
|
22456
22497
|
const metadata = extractPolicyMetadata(content);
|
|
22457
22498
|
policies.push({
|
|
22458
22499
|
name: metadata.name || file.replace(/\.ya?ml$/, ""),
|
|
22459
22500
|
description: metadata.description || "No description",
|
|
22460
22501
|
path: file,
|
|
22461
|
-
lastModified:
|
|
22502
|
+
lastModified: stat4.mtime,
|
|
22462
22503
|
version: metadata.version || "1.0",
|
|
22463
22504
|
requiredVariables: metadata.variables || []
|
|
22464
22505
|
});
|
|
@@ -22476,10 +22517,10 @@ async function writePolicyRaw(vaultPath2, policyName, content, overwrite = false
|
|
|
22476
22517
|
const dir = getPoliciesDir(vaultPath2);
|
|
22477
22518
|
await ensurePoliciesDir(vaultPath2);
|
|
22478
22519
|
const filename = `${policyName}.yaml`;
|
|
22479
|
-
const filePath =
|
|
22520
|
+
const filePath = path33.join(dir, filename);
|
|
22480
22521
|
if (!overwrite) {
|
|
22481
22522
|
try {
|
|
22482
|
-
await
|
|
22523
|
+
await fs31.access(filePath);
|
|
22483
22524
|
return {
|
|
22484
22525
|
success: false,
|
|
22485
22526
|
path: filename,
|
|
@@ -22496,7 +22537,7 @@ async function writePolicyRaw(vaultPath2, policyName, content, overwrite = false
|
|
|
22496
22537
|
message: `Invalid policy: ${validation.errors.map((e) => e.message).join("; ")}`
|
|
22497
22538
|
};
|
|
22498
22539
|
}
|
|
22499
|
-
await
|
|
22540
|
+
await fs31.writeFile(filePath, content, "utf-8");
|
|
22500
22541
|
return {
|
|
22501
22542
|
success: true,
|
|
22502
22543
|
path: filename,
|
|
@@ -22590,7 +22631,7 @@ function registerPolicyTools(server2, getVaultPath, getSearchFn) {
|
|
|
22590
22631
|
const policies = await listPolicies(vaultPath2);
|
|
22591
22632
|
const response = {
|
|
22592
22633
|
success: true,
|
|
22593
|
-
vault:
|
|
22634
|
+
vault: path34.basename(vaultPath2),
|
|
22594
22635
|
vault_path: vaultPath2,
|
|
22595
22636
|
count: policies.length,
|
|
22596
22637
|
policies: policies.map((p) => ({
|
|
@@ -23023,8 +23064,8 @@ function registerPolicyTools(server2, getVaultPath, getSearchFn) {
|
|
|
23023
23064
|
import { z as z21 } from "zod";
|
|
23024
23065
|
|
|
23025
23066
|
// src/core/write/tagRename.ts
|
|
23026
|
-
import * as
|
|
23027
|
-
import * as
|
|
23067
|
+
import * as fs32 from "fs/promises";
|
|
23068
|
+
import * as path35 from "path";
|
|
23028
23069
|
import matter8 from "gray-matter";
|
|
23029
23070
|
import { getProtectedZones as getProtectedZones2 } from "@velvetmonkey/vault-core";
|
|
23030
23071
|
function getNotesInFolder3(index, folder) {
|
|
@@ -23130,10 +23171,10 @@ async function renameTag(index, vaultPath2, oldTag, newTag, options) {
|
|
|
23130
23171
|
const previews = [];
|
|
23131
23172
|
let totalChanges = 0;
|
|
23132
23173
|
for (const note of affectedNotes) {
|
|
23133
|
-
const fullPath =
|
|
23174
|
+
const fullPath = path35.join(vaultPath2, note.path);
|
|
23134
23175
|
let fileContent;
|
|
23135
23176
|
try {
|
|
23136
|
-
fileContent = await
|
|
23177
|
+
fileContent = await fs32.readFile(fullPath, "utf-8");
|
|
23137
23178
|
} catch {
|
|
23138
23179
|
continue;
|
|
23139
23180
|
}
|
|
@@ -23206,7 +23247,7 @@ async function renameTag(index, vaultPath2, oldTag, newTag, options) {
|
|
|
23206
23247
|
previews.push(preview);
|
|
23207
23248
|
if (!dryRun) {
|
|
23208
23249
|
const newContent = matter8.stringify(updatedContent, fm);
|
|
23209
|
-
await
|
|
23250
|
+
await fs32.writeFile(fullPath, newContent, "utf-8");
|
|
23210
23251
|
}
|
|
23211
23252
|
}
|
|
23212
23253
|
}
|
|
@@ -24259,8 +24300,8 @@ function registerConfigTools(server2, getConfig2, setConfig, getStateDb4) {
|
|
|
24259
24300
|
init_wikilinks();
|
|
24260
24301
|
init_wikilinkFeedback();
|
|
24261
24302
|
import { z as z28 } from "zod";
|
|
24262
|
-
import * as
|
|
24263
|
-
import * as
|
|
24303
|
+
import * as fs33 from "fs/promises";
|
|
24304
|
+
import * as path36 from "path";
|
|
24264
24305
|
import { scanVaultEntities as scanVaultEntities4, SCHEMA_VERSION as SCHEMA_VERSION2 } from "@velvetmonkey/vault-core";
|
|
24265
24306
|
init_embeddings();
|
|
24266
24307
|
function hasSkipWikilinks(content) {
|
|
@@ -24273,16 +24314,16 @@ function hasSkipWikilinks(content) {
|
|
|
24273
24314
|
async function collectMarkdownFiles(dirPath, basePath, excludeFolders) {
|
|
24274
24315
|
const results = [];
|
|
24275
24316
|
try {
|
|
24276
|
-
const entries = await
|
|
24317
|
+
const entries = await fs33.readdir(dirPath, { withFileTypes: true });
|
|
24277
24318
|
for (const entry of entries) {
|
|
24278
24319
|
if (entry.name.startsWith(".")) continue;
|
|
24279
|
-
const fullPath =
|
|
24320
|
+
const fullPath = path36.join(dirPath, entry.name);
|
|
24280
24321
|
if (entry.isDirectory()) {
|
|
24281
24322
|
if (excludeFolders.some((f) => entry.name.toLowerCase() === f.toLowerCase())) continue;
|
|
24282
24323
|
const sub = await collectMarkdownFiles(fullPath, basePath, excludeFolders);
|
|
24283
24324
|
results.push(...sub);
|
|
24284
24325
|
} else if (entry.isFile() && entry.name.endsWith(".md")) {
|
|
24285
|
-
results.push(
|
|
24326
|
+
results.push(path36.relative(basePath, fullPath));
|
|
24286
24327
|
}
|
|
24287
24328
|
}
|
|
24288
24329
|
} catch {
|
|
@@ -24312,7 +24353,7 @@ var EXCLUDE_FOLDERS = [
|
|
|
24312
24353
|
];
|
|
24313
24354
|
function buildStatusReport(stateDb2, vaultPath2) {
|
|
24314
24355
|
const recommendations = [];
|
|
24315
|
-
const dbPath =
|
|
24356
|
+
const dbPath = path36.join(vaultPath2, ".flywheel", "state.db");
|
|
24316
24357
|
const statedbExists = stateDb2 !== null;
|
|
24317
24358
|
if (!statedbExists) {
|
|
24318
24359
|
recommendations.push("StateDb not initialized \u2014 server needs restart");
|
|
@@ -24439,10 +24480,10 @@ async function executeRun(stateDb2, vaultPath2) {
|
|
|
24439
24480
|
const allFiles = await collectMarkdownFiles(vaultPath2, vaultPath2, EXCLUDE_FOLDERS);
|
|
24440
24481
|
let eligible = 0;
|
|
24441
24482
|
for (const relativePath of allFiles) {
|
|
24442
|
-
const fullPath =
|
|
24483
|
+
const fullPath = path36.join(vaultPath2, relativePath);
|
|
24443
24484
|
let content;
|
|
24444
24485
|
try {
|
|
24445
|
-
content = await
|
|
24486
|
+
content = await fs33.readFile(fullPath, "utf-8");
|
|
24446
24487
|
} catch {
|
|
24447
24488
|
continue;
|
|
24448
24489
|
}
|
|
@@ -24497,10 +24538,10 @@ async function executeEnrich(stateDb2, vaultPath2, dryRun, batchSize, offset) {
|
|
|
24497
24538
|
const eligible = [];
|
|
24498
24539
|
let notesSkipped = 0;
|
|
24499
24540
|
for (const relativePath of allFiles) {
|
|
24500
|
-
const fullPath =
|
|
24541
|
+
const fullPath = path36.join(vaultPath2, relativePath);
|
|
24501
24542
|
let content;
|
|
24502
24543
|
try {
|
|
24503
|
-
content = await
|
|
24544
|
+
content = await fs33.readFile(fullPath, "utf-8");
|
|
24504
24545
|
} catch {
|
|
24505
24546
|
continue;
|
|
24506
24547
|
}
|
|
@@ -24527,8 +24568,8 @@ async function executeEnrich(stateDb2, vaultPath2, dryRun, batchSize, offset) {
|
|
|
24527
24568
|
match_count: result.linksAdded
|
|
24528
24569
|
});
|
|
24529
24570
|
if (!dryRun) {
|
|
24530
|
-
const fullPath =
|
|
24531
|
-
await
|
|
24571
|
+
const fullPath = path36.join(vaultPath2, relativePath);
|
|
24572
|
+
await fs33.writeFile(fullPath, result.content, "utf-8");
|
|
24532
24573
|
notesModified++;
|
|
24533
24574
|
if (stateDb2) {
|
|
24534
24575
|
trackWikilinkApplications(stateDb2, relativePath, entities, "enrichment");
|
|
@@ -24705,8 +24746,8 @@ function registerMetricsTools(server2, getIndex, getStateDb4) {
|
|
|
24705
24746
|
import { z as z30 } from "zod";
|
|
24706
24747
|
|
|
24707
24748
|
// src/core/read/similarity.ts
|
|
24708
|
-
import * as
|
|
24709
|
-
import * as
|
|
24749
|
+
import * as fs34 from "fs";
|
|
24750
|
+
import * as path37 from "path";
|
|
24710
24751
|
init_embeddings();
|
|
24711
24752
|
|
|
24712
24753
|
// src/core/read/mmr.ts
|
|
@@ -24776,10 +24817,10 @@ function extractKeyTerms(content, maxTerms = 15) {
|
|
|
24776
24817
|
}
|
|
24777
24818
|
function findSimilarNotes(db4, vaultPath2, index, sourcePath, options = {}) {
|
|
24778
24819
|
const limit = options.limit ?? 10;
|
|
24779
|
-
const absPath =
|
|
24820
|
+
const absPath = path37.join(vaultPath2, sourcePath);
|
|
24780
24821
|
let content;
|
|
24781
24822
|
try {
|
|
24782
|
-
content =
|
|
24823
|
+
content = fs34.readFileSync(absPath, "utf-8");
|
|
24783
24824
|
} catch {
|
|
24784
24825
|
return [];
|
|
24785
24826
|
}
|
|
@@ -24918,7 +24959,7 @@ function registerSimilarityTools(server2, getIndex, getVaultPath, getStateDb4) {
|
|
|
24918
24959
|
diversity: z30.number().min(0).max(1).optional().describe("Relevance vs diversity tradeoff (0=max diversity, 1=pure relevance, default: 0.7)")
|
|
24919
24960
|
}
|
|
24920
24961
|
},
|
|
24921
|
-
async ({ path:
|
|
24962
|
+
async ({ path: path40, limit, diversity }) => {
|
|
24922
24963
|
const index = getIndex();
|
|
24923
24964
|
const vaultPath2 = getVaultPath();
|
|
24924
24965
|
const stateDb2 = getStateDb4();
|
|
@@ -24927,10 +24968,10 @@ function registerSimilarityTools(server2, getIndex, getVaultPath, getStateDb4) {
|
|
|
24927
24968
|
content: [{ type: "text", text: JSON.stringify({ error: "StateDb not available" }) }]
|
|
24928
24969
|
};
|
|
24929
24970
|
}
|
|
24930
|
-
if (!index.notes.has(
|
|
24971
|
+
if (!index.notes.has(path40)) {
|
|
24931
24972
|
return {
|
|
24932
24973
|
content: [{ type: "text", text: JSON.stringify({
|
|
24933
|
-
error: `Note not found: ${
|
|
24974
|
+
error: `Note not found: ${path40}`,
|
|
24934
24975
|
hint: "Use the full relative path including .md extension"
|
|
24935
24976
|
}, null, 2) }]
|
|
24936
24977
|
};
|
|
@@ -24942,12 +24983,12 @@ function registerSimilarityTools(server2, getIndex, getVaultPath, getStateDb4) {
|
|
|
24942
24983
|
};
|
|
24943
24984
|
const useHybrid = hasEmbeddingsIndex();
|
|
24944
24985
|
const method = useHybrid ? "hybrid" : "bm25";
|
|
24945
|
-
const results = useHybrid ? await findHybridSimilarNotes(stateDb2.db, vaultPath2, index,
|
|
24986
|
+
const results = useHybrid ? await findHybridSimilarNotes(stateDb2.db, vaultPath2, index, path40, opts) : findSimilarNotes(stateDb2.db, vaultPath2, index, path40, opts);
|
|
24946
24987
|
return {
|
|
24947
24988
|
content: [{
|
|
24948
24989
|
type: "text",
|
|
24949
24990
|
text: JSON.stringify({
|
|
24950
|
-
source:
|
|
24991
|
+
source: path40,
|
|
24951
24992
|
method,
|
|
24952
24993
|
count: results.length,
|
|
24953
24994
|
similar: results
|
|
@@ -26821,7 +26862,7 @@ function registerVaultResources(server2, getIndex) {
|
|
|
26821
26862
|
}
|
|
26822
26863
|
|
|
26823
26864
|
// src/tool-registry.ts
|
|
26824
|
-
var __trFilename =
|
|
26865
|
+
var __trFilename = fileURLToPath2(import.meta.url);
|
|
26825
26866
|
var __trDirname = dirname5(__trFilename);
|
|
26826
26867
|
var trPkg = JSON.parse(readFileSync5(join18(__trDirname, "../package.json"), "utf-8"));
|
|
26827
26868
|
var ACTIVATION_PATTERNS = [
|
|
@@ -27053,7 +27094,7 @@ function applyToolGating(targetServer, categories, getDb4, registry, getVaultPat
|
|
|
27053
27094
|
let totalBytes = 0;
|
|
27054
27095
|
for (const p of notePaths) {
|
|
27055
27096
|
try {
|
|
27056
|
-
totalBytes += statSync6(
|
|
27097
|
+
totalBytes += statSync6(path38.join(vp, p)).size;
|
|
27057
27098
|
} catch {
|
|
27058
27099
|
}
|
|
27059
27100
|
}
|
|
@@ -27227,7 +27268,7 @@ function applyToolGating(targetServer, categories, getDb4, registry, getVaultPat
|
|
|
27227
27268
|
const serverAny = targetServer;
|
|
27228
27269
|
serverAny.server.setRequestHandler(CallToolRequestSchema, async (request, extra) => {
|
|
27229
27270
|
try {
|
|
27230
|
-
const tool =
|
|
27271
|
+
const tool = toolHandles.get(request.params.name);
|
|
27231
27272
|
if (!tool) {
|
|
27232
27273
|
throw new McpError(ErrorCode.InvalidParams, `Tool ${request.params.name} not found`);
|
|
27233
27274
|
}
|
|
@@ -27404,8 +27445,8 @@ function registerAllTools(targetServer, ctx, controller) {
|
|
|
27404
27445
|
}
|
|
27405
27446
|
|
|
27406
27447
|
// src/index.ts
|
|
27407
|
-
var
|
|
27408
|
-
var __dirname = dirname7(
|
|
27448
|
+
var __filename2 = fileURLToPath3(import.meta.url);
|
|
27449
|
+
var __dirname = dirname7(__filename2);
|
|
27409
27450
|
var pkg = JSON.parse(readFileSync6(join20(__dirname, "../package.json"), "utf-8"));
|
|
27410
27451
|
var vaultPath;
|
|
27411
27452
|
var resolvedVaultPath;
|
|
@@ -27420,6 +27461,7 @@ var serverReady = false;
|
|
|
27420
27461
|
var shutdownRequested = false;
|
|
27421
27462
|
var lastMcpRequestAt = 0;
|
|
27422
27463
|
var lastFullRebuildAt = 0;
|
|
27464
|
+
var startupScanFiles = null;
|
|
27423
27465
|
var deferredScheduler = null;
|
|
27424
27466
|
function getWatcherStatus() {
|
|
27425
27467
|
if (vaultRegistry) {
|
|
@@ -27628,7 +27670,7 @@ function buildVaultScope(ctx) {
|
|
|
27628
27670
|
pipelineActivity: ctx.pipelineActivity
|
|
27629
27671
|
};
|
|
27630
27672
|
}
|
|
27631
|
-
function activateVault(ctx) {
|
|
27673
|
+
function activateVault(ctx, skipEmbeddingLoad = false) {
|
|
27632
27674
|
globalThis.__flywheel_active_vault = ctx.name;
|
|
27633
27675
|
if (ctx.stateDb) {
|
|
27634
27676
|
setWriteStateDb(ctx.stateDb);
|
|
@@ -27637,7 +27679,9 @@ function activateVault(ctx) {
|
|
|
27637
27679
|
setProspectStateDb(ctx.stateDb);
|
|
27638
27680
|
setTaskCacheDatabase(ctx.stateDb.db);
|
|
27639
27681
|
setEmbeddingsDatabase(ctx.stateDb.db);
|
|
27640
|
-
|
|
27682
|
+
if (!skipEmbeddingLoad) {
|
|
27683
|
+
loadEntityEmbeddingsToMemory();
|
|
27684
|
+
}
|
|
27641
27685
|
}
|
|
27642
27686
|
setWikilinkConfig(ctx.flywheelConfig);
|
|
27643
27687
|
setCooccurrenceIndex(ctx.cooccurrenceIndex);
|
|
@@ -27714,6 +27758,7 @@ async function bootVault(ctx, startTime) {
|
|
|
27714
27758
|
if (sd) {
|
|
27715
27759
|
try {
|
|
27716
27760
|
const files = await scanVault(vp);
|
|
27761
|
+
startupScanFiles = files;
|
|
27717
27762
|
const noteCount = files.length;
|
|
27718
27763
|
serverLog("index", `[${ctx.name}] Found ${noteCount} markdown files`);
|
|
27719
27764
|
const newestMtime = files.reduce((max, f) => f.modified > max ? f.modified : max, /* @__PURE__ */ new Date(0));
|
|
@@ -27799,13 +27844,13 @@ async function main() {
|
|
|
27799
27844
|
const primaryCtx2 = await initializeVault(vaultConfigs[0].name, vaultConfigs[0].path);
|
|
27800
27845
|
vaultRegistry.addContext(primaryCtx2);
|
|
27801
27846
|
stateDb = primaryCtx2.stateDb;
|
|
27802
|
-
activateVault(primaryCtx2);
|
|
27847
|
+
activateVault(primaryCtx2, true);
|
|
27803
27848
|
} else {
|
|
27804
27849
|
vaultRegistry = new VaultRegistry("default");
|
|
27805
27850
|
const ctx = await initializeVault("default", vaultPath);
|
|
27806
27851
|
vaultRegistry.addContext(ctx);
|
|
27807
27852
|
stateDb = ctx.stateDb;
|
|
27808
|
-
activateVault(ctx);
|
|
27853
|
+
activateVault(ctx, true);
|
|
27809
27854
|
}
|
|
27810
27855
|
await initToolRouting();
|
|
27811
27856
|
if (stateDb) {
|
|
@@ -27993,37 +28038,11 @@ async function updateEntitiesInStateDb(vp, sd) {
|
|
|
27993
28038
|
serverLog("index", `Failed to update entities in StateDb: ${e instanceof Error ? e.message : e}`, "error");
|
|
27994
28039
|
}
|
|
27995
28040
|
}
|
|
27996
|
-
|
|
27997
|
-
|
|
27998
|
-
|
|
27999
|
-
let entries;
|
|
28000
|
-
try {
|
|
28001
|
-
entries = await fs34.readdir(dir, { withFileTypes: true });
|
|
28002
|
-
} catch {
|
|
28003
|
-
return;
|
|
28004
|
-
}
|
|
28005
|
-
for (const entry of entries) {
|
|
28006
|
-
const fullPath = path38.join(dir, entry.name);
|
|
28007
|
-
if (entry.isDirectory()) {
|
|
28008
|
-
if (entry.name.startsWith(".") || entry.name === "node_modules") continue;
|
|
28009
|
-
await scanDir(fullPath);
|
|
28010
|
-
} else if (entry.isFile() && entry.name.endsWith(".md")) {
|
|
28011
|
-
try {
|
|
28012
|
-
const stat5 = await fs34.stat(fullPath);
|
|
28013
|
-
if (stat5.mtimeMs > sinceMs) {
|
|
28014
|
-
events.push({
|
|
28015
|
-
type: "upsert",
|
|
28016
|
-
path: path38.relative(vaultPath2, fullPath),
|
|
28017
|
-
originalEvents: []
|
|
28018
|
-
});
|
|
28019
|
-
}
|
|
28020
|
-
} catch {
|
|
28021
|
-
}
|
|
28022
|
-
}
|
|
28023
|
-
}
|
|
28041
|
+
function buildStartupCatchupBatch(vaultPath2, sinceMs, preScannedFiles) {
|
|
28042
|
+
if (preScannedFiles) {
|
|
28043
|
+
return preScannedFiles.filter((f) => f.modified.getTime() > sinceMs).map((f) => ({ type: "upsert", path: f.path, originalEvents: [] }));
|
|
28024
28044
|
}
|
|
28025
|
-
|
|
28026
|
-
return events;
|
|
28045
|
+
return [];
|
|
28027
28046
|
}
|
|
28028
28047
|
var lastPurgeAt = Date.now();
|
|
28029
28048
|
function runPeriodicMaintenance(db4) {
|
|
@@ -28205,7 +28224,7 @@ async function runPostIndexWork(ctx) {
|
|
|
28205
28224
|
if (attempt < MAX_BUILD_RETRIES) {
|
|
28206
28225
|
const delay = 1e4;
|
|
28207
28226
|
serverLog("semantic", `Build failed (attempt ${attempt}/${MAX_BUILD_RETRIES}): ${msg}. Retrying in ${delay / 1e3}s...`, "error");
|
|
28208
|
-
await new Promise((
|
|
28227
|
+
await new Promise((resolve3) => setTimeout(resolve3, delay));
|
|
28209
28228
|
return attemptBuild(attempt + 1);
|
|
28210
28229
|
}
|
|
28211
28230
|
serverLog("semantic", `Embeddings build failed after ${MAX_BUILD_RETRIES} attempts: ${msg}`, "error");
|
|
@@ -28261,8 +28280,8 @@ async function runPostIndexWork(ctx) {
|
|
|
28261
28280
|
}
|
|
28262
28281
|
} catch {
|
|
28263
28282
|
try {
|
|
28264
|
-
const dir =
|
|
28265
|
-
const base =
|
|
28283
|
+
const dir = path39.dirname(rawPath);
|
|
28284
|
+
const base = path39.basename(rawPath);
|
|
28266
28285
|
const resolvedDir = realpathSync(dir).replace(/\\/g, "/");
|
|
28267
28286
|
for (const prefix of vaultPrefixes) {
|
|
28268
28287
|
if (resolvedDir.startsWith(prefix + "/") || resolvedDir === prefix) {
|
|
@@ -28294,7 +28313,7 @@ async function runPostIndexWork(ctx) {
|
|
|
28294
28313
|
continue;
|
|
28295
28314
|
}
|
|
28296
28315
|
try {
|
|
28297
|
-
const content = await
|
|
28316
|
+
const content = await fs35.readFile(path39.join(vp, event.path), "utf-8");
|
|
28298
28317
|
const hash = createHash4("sha256").update(content).digest("hex").slice(0, 16);
|
|
28299
28318
|
if (lastContentHashes.get(event.path) === hash) {
|
|
28300
28319
|
serverLog("watcher", `Hash unchanged, skipping: ${event.path}`);
|
|
@@ -28403,7 +28422,7 @@ async function runPostIndexWork(ctx) {
|
|
|
28403
28422
|
if (sd) {
|
|
28404
28423
|
const lastPipelineEvent = getRecentPipelineEvent(sd);
|
|
28405
28424
|
if (lastPipelineEvent) {
|
|
28406
|
-
const catchupEvents =
|
|
28425
|
+
const catchupEvents = buildStartupCatchupBatch(vp, lastPipelineEvent.timestamp, startupScanFiles);
|
|
28407
28426
|
if (catchupEvents.length > 0) {
|
|
28408
28427
|
console.error(`[Flywheel] Startup catch-up: ${catchupEvents.length} file(s) modified while offline`);
|
|
28409
28428
|
await handleBatch({ events: catchupEvents, renames: [], timestamp: Date.now() });
|
|
@@ -28423,6 +28442,7 @@ async function runPostIndexWork(ctx) {
|
|
|
28423
28442
|
watcher.start();
|
|
28424
28443
|
serverLog("watcher", "File watcher started");
|
|
28425
28444
|
}
|
|
28445
|
+
startupScanFiles = null;
|
|
28426
28446
|
if (process.env.FLYWHEEL_WATCH !== "false") {
|
|
28427
28447
|
startSweepTimer(() => ctx.vaultIndex, void 0, () => {
|
|
28428
28448
|
if (sd) runPeriodicMaintenance(sd);
|