mnemosyne-core 2.0.3 → 2.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (47) hide show
  1. package/README.md +42 -25
  2. package/dist/{Store-BtdYuiUx.d.mts → Store-BJ8b6xbs.d.mts} +2 -0
  3. package/dist/{Store-BtdYuiUx.d.ts → Store-BJ8b6xbs.d.ts} +2 -0
  4. package/dist/cli/index.js +387 -5744
  5. package/dist/cli/index.js.map +1 -1
  6. package/dist/cli/index.mjs +387 -5744
  7. package/dist/cli/index.mjs.map +1 -1
  8. package/dist/{index-yTOihMUk.d.mts → index-2AoCh09i.d.mts} +1 -1
  9. package/dist/{index-B2oTMNlL.d.ts → index-BZrUZX8Z.d.ts} +1 -1
  10. package/dist/{index-B8PTQKy9.d.mts → index-CHbW0NJZ.d.mts} +1 -1
  11. package/dist/{index-DWk78ifo.d.ts → index-CfqixdlW.d.ts} +1 -1
  12. package/dist/index.d.mts +4 -4
  13. package/dist/index.d.ts +4 -4
  14. package/dist/index.js +281 -5726
  15. package/dist/index.js.map +1 -1
  16. package/dist/index.mjs +281 -5726
  17. package/dist/index.mjs.map +1 -1
  18. package/dist/mcp/index.d.mts +2 -2
  19. package/dist/mcp/index.d.ts +2 -2
  20. package/dist/mcp/index.js +1 -1
  21. package/dist/mcp/index.js.map +1 -1
  22. package/dist/mcp/index.mjs +1 -1
  23. package/dist/mcp/index.mjs.map +1 -1
  24. package/dist/sdk/index.d.mts +144 -41
  25. package/dist/sdk/index.d.ts +144 -41
  26. package/dist/sdk/index.js +92 -34
  27. package/dist/sdk/index.js.map +1 -1
  28. package/dist/sdk/index.mjs +92 -34
  29. package/dist/sdk/index.mjs.map +1 -1
  30. package/dist/server/api.d.mts +1 -1
  31. package/dist/server/api.d.ts +1 -1
  32. package/dist/server/api.js +205 -160
  33. package/dist/server/api.js.map +1 -1
  34. package/dist/server/api.mjs +205 -160
  35. package/dist/server/api.mjs.map +1 -1
  36. package/dist/server/index.d.mts +2 -2
  37. package/dist/server/index.d.ts +2 -2
  38. package/dist/server/index.js +245 -5694
  39. package/dist/server/index.js.map +1 -1
  40. package/dist/server/index.mjs +245 -5694
  41. package/dist/server/index.mjs.map +1 -1
  42. package/dist/server/websocket.d.mts +1 -1
  43. package/dist/server/websocket.d.ts +1 -1
  44. package/dist/ws/index.d.mts +1 -1
  45. package/dist/ws/index.d.ts +1 -1
  46. package/package.json +1 -1
  47. package/dist/sharp-win32-x64-CXV3GA3G.node +0 -0
@@ -14,143 +14,6 @@ var __export = (target, all) => {
14
14
  __defProp(target, name, { get: all[name], enumerable: true });
15
15
  };
16
16
 
17
- // src/config.ts
18
- import { readFileSync, existsSync } from "fs";
19
- import { resolve } from "path";
20
- function parseValue(v) {
21
- const trimmed = v.trim();
22
- if (trimmed === "true") return true;
23
- if (trimmed === "false") return false;
24
- if (trimmed === "null" || trimmed === "~") return null;
25
- if (/^-?\d+$/.test(trimmed)) return parseInt(trimmed, 10);
26
- if (/^-?\d+\.\d+$/.test(trimmed)) return parseFloat(trimmed);
27
- if (trimmed.startsWith('"') && trimmed.endsWith('"') || trimmed.startsWith("'") && trimmed.endsWith("'")) {
28
- return trimmed.slice(1, -1);
29
- }
30
- return trimmed;
31
- }
32
- function parseYaml(text) {
33
- const lines = text.split("\n");
34
- const root = {};
35
- const stack = [{ obj: root, indent: -1, isArray: false }];
36
- for (const rawLine of lines) {
37
- const commentIdx = rawLine.indexOf("#");
38
- const line = commentIdx >= 0 ? rawLine.slice(0, commentIdx) : rawLine;
39
- if (!line.trim()) continue;
40
- const indent = line.length - line.trimStart().length;
41
- const trimmed = line.trim();
42
- while (stack.length > 1 && stack[stack.length - 1].indent >= indent) {
43
- stack.pop();
44
- }
45
- const parent = stack[stack.length - 1];
46
- if (trimmed.startsWith("- ")) {
47
- const valueStr2 = trimmed.slice(2).trim();
48
- if (!parent.isArray) {
49
- }
50
- let target = parent.obj;
51
- if (!Array.isArray(target)) {
52
- target = [];
53
- }
54
- if (valueStr2.includes(":")) {
55
- const item = {};
56
- const colonIdx2 = valueStr2.indexOf(":");
57
- const k = valueStr2.slice(0, colonIdx2).trim();
58
- const v = valueStr2.slice(colonIdx2 + 1).trim();
59
- item[k] = parseValue(v);
60
- target.push(item);
61
- } else {
62
- target.push(parseValue(valueStr2));
63
- }
64
- continue;
65
- }
66
- const colonIdx = trimmed.indexOf(":");
67
- if (colonIdx === -1) continue;
68
- const key = trimmed.slice(0, colonIdx).trim();
69
- const valueStr = trimmed.slice(colonIdx + 1).trim();
70
- if (!valueStr) {
71
- const newObj = {};
72
- parent.obj[key] = newObj;
73
- stack.push({ obj: newObj, indent, isArray: false });
74
- } else {
75
- parent.obj[key] = parseValue(valueStr);
76
- }
77
- }
78
- return root;
79
- }
80
- function loadConfig() {
81
- const configPath = resolve(process.cwd(), "config.yaml");
82
- if (!existsSync(configPath)) {
83
- console.warn("[Config] config.yaml not found, using defaults");
84
- return defaultConfig();
85
- }
86
- try {
87
- const raw = readFileSync(configPath, "utf-8");
88
- const parsed = parseYaml(raw);
89
- return mergeDeep(defaultConfig(), parsed);
90
- } catch (err) {
91
- console.error("[Config] Failed to parse config.yaml:", err.message);
92
- return defaultConfig();
93
- }
94
- }
95
- function getVersion2() {
96
- try {
97
- const { readFileSync: readFileSync4 } = __require("fs");
98
- const { resolve: resolve4 } = __require("path");
99
- const pkg = JSON.parse(readFileSync4(resolve4(__dirname, "../package.json"), "utf-8"));
100
- return pkg.version;
101
- } catch {
102
- try {
103
- const { readFileSync: readFileSync4 } = __require("fs");
104
- const { resolve: resolve4 } = __require("path");
105
- const pkg = JSON.parse(readFileSync4(resolve4(process.cwd(), "package.json"), "utf-8"));
106
- return pkg.version;
107
- } catch {
108
- return "2.0.3";
109
- }
110
- }
111
- }
112
- function defaultConfig() {
113
- return {
114
- server: { port: 7321, host: "localhost", version: getVersion2() },
115
- database: { path: "data/nexus.db", wal_mode: true, vec_extension_path: "data/vec0" },
116
- storage: { files_dir: "data/files", max_file_size_mb: 50, backups_dir: "data/backups", backup_interval_hours: 24, max_backups: 7 },
117
- limits: { max_atoms_per_project: 1e4, rate_limit_requests: 100, rate_limit_window_ms: 6e4 },
118
- embeddings: { model: "Xenova/all-MiniLM-L6-v2", dimension: 384, max_text_length: 1e4 },
119
- features: { mcp_enabled: true, auto_index_enabled: true, file_processing_enabled: true },
120
- index: { debounce_ms: 3e4 },
121
- search: { semantic_weight: 0.6, fts_weight: 0.4 },
122
- bonds: { default_type: "relates" }
123
- };
124
- }
125
- function mergeDeep(target, source) {
126
- if (!source || typeof source !== "object") return target;
127
- const output = { ...target };
128
- for (const key of Object.keys(source)) {
129
- if (source[key] && typeof source[key] === "object" && !Array.isArray(source[key])) {
130
- output[key] = mergeDeep(target[key] || {}, source[key]);
131
- } else {
132
- output[key] = source[key];
133
- }
134
- }
135
- return output;
136
- }
137
- function getConfig() {
138
- if (!_config) _config = loadConfig();
139
- return _config;
140
- }
141
- var _config, CONFIG;
142
- var init_config = __esm({
143
- "src/config.ts"() {
144
- "use strict";
145
- _config = null;
146
- CONFIG = new Proxy({}, {
147
- get(_, prop) {
148
- return getConfig()[prop];
149
- }
150
- });
151
- }
152
- });
153
-
154
17
  // src/server/embedder.ts
155
18
  var embedder_exports = {};
156
19
  __export(embedder_exports, {
@@ -159,20 +22,18 @@ __export(embedder_exports, {
159
22
  isReady: () => isReady
160
23
  });
161
24
  import { pipeline } from "@xenova/transformers";
162
- async function getExtractor() {
163
- if (extractor) return extractor;
164
- if (loadError) return null;
25
+ async function getExtractor(model) {
26
+ if (extractor && loadedModel === model) return extractor;
27
+ if (loadError && loadedModel === model) return null;
165
28
  if (loading) {
166
29
  while (loading) await new Promise((r) => setTimeout(r, 100));
167
- return extractor;
30
+ return extractor && loadedModel === model ? extractor : null;
168
31
  }
169
32
  loading = true;
170
33
  try {
171
- extractor = await pipeline("feature-extraction", CONFIG.embeddings.model, {
172
- quantized: true
173
- // Use quantized model for faster download
174
- });
175
- console.log(`[Embedder] Model loaded: ${CONFIG.embeddings.model}`);
34
+ extractor = await pipeline("feature-extraction", model, { quantized: true });
35
+ loadedModel = model;
36
+ console.log(`[Embedder] Model loaded: ${model}`);
176
37
  return extractor;
177
38
  } catch (err) {
178
39
  loadError = err;
@@ -182,10 +43,11 @@ async function getExtractor() {
182
43
  loading = false;
183
44
  }
184
45
  }
185
- async function embedText(text) {
186
- const ext = await getExtractor();
46
+ async function embedText(text, model, maxLength) {
47
+ const m = model || DEFAULT_MODEL;
48
+ const ext = await getExtractor(m);
187
49
  if (!ext) return null;
188
- const truncated = text.slice(0, CONFIG.embeddings.max_text_length);
50
+ const truncated = text.slice(0, maxLength || DEFAULT_MAX_LENGTH);
189
51
  if (!truncated.trim()) return null;
190
52
  try {
191
53
  const output = await ext(truncated, { pooling: "mean", normalize: true });
@@ -195,12 +57,13 @@ async function embedText(text) {
195
57
  return null;
196
58
  }
197
59
  }
198
- async function embedTexts(texts) {
199
- const ext = await getExtractor();
60
+ async function embedTexts(texts, model, maxLength) {
61
+ const m = model || DEFAULT_MODEL;
62
+ const ext = await getExtractor(m);
200
63
  if (!ext) return texts.map(() => null);
201
64
  const results = [];
202
65
  for (const text of texts) {
203
- const truncated = text.slice(0, CONFIG.embeddings.max_text_length);
66
+ const truncated = text.slice(0, maxLength || DEFAULT_MAX_LENGTH);
204
67
  if (!truncated.trim()) {
205
68
  results.push(null);
206
69
  continue;
@@ -217,14 +80,16 @@ async function embedTexts(texts) {
217
80
  function isReady() {
218
81
  return extractor !== null;
219
82
  }
220
- var extractor, loading, loadError;
83
+ var DEFAULT_MODEL, DEFAULT_MAX_LENGTH, extractor, loading, loadError, loadedModel;
221
84
  var init_embedder = __esm({
222
85
  "src/server/embedder.ts"() {
223
86
  "use strict";
224
- init_config();
87
+ DEFAULT_MODEL = "Xenova/all-MiniLM-L6-v2";
88
+ DEFAULT_MAX_LENGTH = 1e4;
225
89
  extractor = null;
226
90
  loading = false;
227
91
  loadError = null;
92
+ loadedModel = "";
228
93
  }
229
94
  });
230
95
 
@@ -458,7 +323,7 @@ function getVersion() {
458
323
  const pkg = JSON.parse(readFileSync4(resolve4(process.cwd(), "package.json"), "utf-8"));
459
324
  return pkg.version;
460
325
  } catch {
461
- return "2.0.3";
326
+ return "2.1.0";
462
327
  }
463
328
  }
464
329
  }
@@ -614,7 +479,25 @@ function setCorsHeaders(res) {
614
479
  }
615
480
  function authenticate(store, req) {
616
481
  const token = req.headers.authorization?.replace("Bearer ", "");
617
- return token ? store.getAssistant(token) : void 0;
482
+ if (token) {
483
+ return store.getAssistant(token);
484
+ }
485
+ const host = req.headers.host || "";
486
+ const isLocalhost = host.startsWith("localhost:") || host.startsWith("127.0.0.1:") || host === "localhost" || host === "127.0.0.1";
487
+ if (isLocalhost) {
488
+ return {
489
+ id: "local-dev",
490
+ name: "Local Developer",
491
+ role: "owner",
492
+ permissions: {},
493
+ status: "active",
494
+ provider: null,
495
+ connected_at: Date.now(),
496
+ last_seen: Date.now(),
497
+ metadata: {}
498
+ };
499
+ }
500
+ return void 0;
618
501
  }
619
502
 
620
503
  // src/api/utils.ts
@@ -925,6 +808,16 @@ function handleAssistants(store, pathname, method, res, body) {
925
808
  json(res, 200, { assistants });
926
809
  return true;
927
810
  }
811
+ if (pathname.match(/^\/api\/v1\/assistants\/[^\/]+$/) && method === "GET") {
812
+ const id = pathname.replace("/api/v1/assistants/", "");
813
+ const assistant = store.getAssistant(id);
814
+ if (!assistant) {
815
+ json(res, 404, { error: "assistant_not_found" });
816
+ return true;
817
+ }
818
+ json(res, 200, { assistant });
819
+ return true;
820
+ }
928
821
  if (pathname.match(/^\/api\/v1\/assistants\/[^\/]+$/) && method === "PATCH") {
929
822
  const id = pathname.replace("/api/v1/assistants/", "");
930
823
  const a = body;
@@ -965,6 +858,22 @@ function handleProjects(store, pathname, method, res, body, searchParams) {
965
858
  json(res, 200, { success: true, project });
966
859
  return true;
967
860
  }
861
+ if (pathname.match(/^\/api\/v1\/projects\/[^/]+$/) && method === "GET") {
862
+ const id = pathname.replace("/api/v1/projects/", "");
863
+ const project = store.getProject(id);
864
+ if (!project) {
865
+ json(res, 404, { error: "project_not_found" });
866
+ return true;
867
+ }
868
+ json(res, 200, { project });
869
+ return true;
870
+ }
871
+ if (pathname.match(/^\/api\/v1\/projects\/[^/]+$/) && method === "DELETE") {
872
+ const id = pathname.replace("/api/v1/projects/", "");
873
+ const ok = store.deleteProject(id);
874
+ json(res, ok ? 200 : 404, { success: ok });
875
+ return true;
876
+ }
968
877
  const projectIndexMatch = pathname.match(/^\/api\/v1\/projects\/([^/]+)\/index$/);
969
878
  if (projectIndexMatch && method === "GET") {
970
879
  const projectId = resolveProjectId(store, projectIndexMatch[1]);
@@ -1196,6 +1105,10 @@ function handleAtoms(store, pathname, method, res, body, searchParams, assistant
1196
1105
 
1197
1106
  // src/api/routes/bonds.ts
1198
1107
  function handleBonds(store, pathname, method, res, body) {
1108
+ if (pathname === "/api/v1/bonds" && method === "GET") {
1109
+ json(res, 200, store.getAllBonds());
1110
+ return true;
1111
+ }
1199
1112
  if (pathname.match(/^\/api\/v1\/atoms\/[^\/]+\/bonds$/) && method === "GET") {
1200
1113
  const atomId = pathname.replace("/api/v1/atoms/", "").replace("/bonds", "");
1201
1114
  json(res, 200, store.getBondsByAtom(atomId));
@@ -1323,7 +1236,7 @@ async function handleSearch(store, pathname, method, res, searchParams) {
1323
1236
  let results = [];
1324
1237
  if (semantic) {
1325
1238
  const { embedText: embedText2 } = await Promise.resolve().then(() => (init_embedder(), embedder_exports));
1326
- const queryEmbedding = await embedText2(q);
1239
+ const queryEmbedding = await embedText2(q, store.config.embeddings.model, store.config.embeddings.max_text_length);
1327
1240
  if (queryEmbedding) {
1328
1241
  results = store.searchHybrid(projectId, q, queryEmbedding, limit);
1329
1242
  } else {
@@ -1339,10 +1252,142 @@ async function handleSearch(store, pathname, method, res, searchParams) {
1339
1252
  }
1340
1253
 
1341
1254
  // src/server/files.ts
1342
- init_config();
1343
1255
  import { createHash } from "crypto";
1344
1256
  import { mkdirSync, existsSync as existsSync2, writeFileSync, readFileSync as readFileSync2 } from "fs";
1345
1257
  import { resolve as resolve2, dirname } from "path";
1258
+
1259
+ // src/config.ts
1260
+ import { readFileSync, existsSync } from "fs";
1261
+ import { resolve } from "path";
1262
+ function parseValue(v) {
1263
+ const trimmed = v.trim();
1264
+ if (trimmed === "true") return true;
1265
+ if (trimmed === "false") return false;
1266
+ if (trimmed === "null" || trimmed === "~") return null;
1267
+ if (/^-?\d+$/.test(trimmed)) return parseInt(trimmed, 10);
1268
+ if (/^-?\d+\.\d+$/.test(trimmed)) return parseFloat(trimmed);
1269
+ if (trimmed.startsWith('"') && trimmed.endsWith('"') || trimmed.startsWith("'") && trimmed.endsWith("'")) {
1270
+ return trimmed.slice(1, -1);
1271
+ }
1272
+ return trimmed;
1273
+ }
1274
+ function parseYaml(text) {
1275
+ const lines = text.split("\n");
1276
+ const root = {};
1277
+ const stack = [{ obj: root, indent: -1, isArray: false }];
1278
+ for (const rawLine of lines) {
1279
+ const commentIdx = rawLine.indexOf("#");
1280
+ const line = commentIdx >= 0 ? rawLine.slice(0, commentIdx) : rawLine;
1281
+ if (!line.trim()) continue;
1282
+ const indent = line.length - line.trimStart().length;
1283
+ const trimmed = line.trim();
1284
+ while (stack.length > 1 && stack[stack.length - 1].indent >= indent) {
1285
+ stack.pop();
1286
+ }
1287
+ const parent = stack[stack.length - 1];
1288
+ if (trimmed.startsWith("- ")) {
1289
+ const valueStr2 = trimmed.slice(2).trim();
1290
+ if (!parent.isArray) {
1291
+ }
1292
+ let target = parent.obj;
1293
+ if (!Array.isArray(target)) {
1294
+ target = [];
1295
+ }
1296
+ if (valueStr2.includes(":")) {
1297
+ const item = {};
1298
+ const colonIdx2 = valueStr2.indexOf(":");
1299
+ const k = valueStr2.slice(0, colonIdx2).trim();
1300
+ const v = valueStr2.slice(colonIdx2 + 1).trim();
1301
+ item[k] = parseValue(v);
1302
+ target.push(item);
1303
+ } else {
1304
+ target.push(parseValue(valueStr2));
1305
+ }
1306
+ continue;
1307
+ }
1308
+ const colonIdx = trimmed.indexOf(":");
1309
+ if (colonIdx === -1) continue;
1310
+ const key = trimmed.slice(0, colonIdx).trim();
1311
+ const valueStr = trimmed.slice(colonIdx + 1).trim();
1312
+ if (!valueStr) {
1313
+ const newObj = {};
1314
+ parent.obj[key] = newObj;
1315
+ stack.push({ obj: newObj, indent, isArray: false });
1316
+ } else {
1317
+ parent.obj[key] = parseValue(valueStr);
1318
+ }
1319
+ }
1320
+ return root;
1321
+ }
1322
+ function loadConfig() {
1323
+ const configPath = resolve(process.cwd(), "config.yaml");
1324
+ if (!existsSync(configPath)) {
1325
+ console.warn("[Config] config.yaml not found, using defaults");
1326
+ return defaultConfig();
1327
+ }
1328
+ try {
1329
+ const raw = readFileSync(configPath, "utf-8");
1330
+ const parsed = parseYaml(raw);
1331
+ return mergeDeep(defaultConfig(), parsed);
1332
+ } catch (err) {
1333
+ console.error("[Config] Failed to parse config.yaml:", err.message);
1334
+ return defaultConfig();
1335
+ }
1336
+ }
1337
+ function getVersion2() {
1338
+ try {
1339
+ const { readFileSync: readFileSync4 } = __require("fs");
1340
+ const { resolve: resolve4 } = __require("path");
1341
+ const pkg = JSON.parse(readFileSync4(resolve4(__dirname, "../package.json"), "utf-8"));
1342
+ return pkg.version;
1343
+ } catch {
1344
+ try {
1345
+ const { readFileSync: readFileSync4 } = __require("fs");
1346
+ const { resolve: resolve4 } = __require("path");
1347
+ const pkg = JSON.parse(readFileSync4(resolve4(process.cwd(), "package.json"), "utf-8"));
1348
+ return pkg.version;
1349
+ } catch {
1350
+ return "2.1.0";
1351
+ }
1352
+ }
1353
+ }
1354
+ function defaultConfig() {
1355
+ return {
1356
+ server: { port: 7321, host: "localhost", version: getVersion2() },
1357
+ database: { path: "data/nexus.db", wal_mode: true, vec_extension_path: "data/vec0" },
1358
+ storage: { files_dir: "data/files", max_file_size_mb: 50, backups_dir: "data/backups", backup_interval_hours: 24, max_backups: 7 },
1359
+ limits: { max_atoms_per_project: 1e4, rate_limit_requests: 100, rate_limit_window_ms: 6e4 },
1360
+ embeddings: { model: "Xenova/all-MiniLM-L6-v2", dimension: 384, max_text_length: 1e4 },
1361
+ features: { mcp_enabled: true, auto_index_enabled: true, file_processing_enabled: true },
1362
+ index: { debounce_ms: 3e4 },
1363
+ search: { semantic_weight: 0.6, fts_weight: 0.4 },
1364
+ bonds: { default_type: "relates" }
1365
+ };
1366
+ }
1367
+ function mergeDeep(target, source) {
1368
+ if (!source || typeof source !== "object") return target;
1369
+ const output = { ...target };
1370
+ for (const key of Object.keys(source)) {
1371
+ if (source[key] && typeof source[key] === "object" && !Array.isArray(source[key])) {
1372
+ output[key] = mergeDeep(target[key] || {}, source[key]);
1373
+ } else {
1374
+ output[key] = source[key];
1375
+ }
1376
+ }
1377
+ return output;
1378
+ }
1379
+ var _config = null;
1380
+ function getConfig() {
1381
+ if (!_config) _config = loadConfig();
1382
+ return _config;
1383
+ }
1384
+ var CONFIG = new Proxy({}, {
1385
+ get(_, prop) {
1386
+ return getConfig()[prop];
1387
+ }
1388
+ });
1389
+
1390
+ // src/server/files.ts
1346
1391
  function getFilesDir() {
1347
1392
  return resolve2(process.cwd(), CONFIG.storage.files_dir);
1348
1393
  }
@@ -1572,10 +1617,10 @@ function handleEvents(store, pathname, method, res, searchParams) {
1572
1617
  // src/api/routes/health.ts
1573
1618
  var PKG_VERSION = (() => {
1574
1619
  try {
1575
- const pkg = JSON.parse(__require("fs").readFileSync(__require("path").resolve(__dirname, "../../../package.json"), "utf-8"));
1620
+ const pkg = JSON.parse(__require("fs").readFileSync(__require("path").resolve(__dirname, "../../package.json"), "utf-8"));
1576
1621
  return pkg.version;
1577
1622
  } catch {
1578
- return "2.0.3";
1623
+ return "2.1.0";
1579
1624
  }
1580
1625
  })();
1581
1626
  function handleHealth(store, pathname, method, res) {