mnemosyne-core 2.0.3 → 2.1.0
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/README.md +42 -25
- package/dist/{Store-BtdYuiUx.d.mts → Store-BJ8b6xbs.d.mts} +2 -0
- package/dist/{Store-BtdYuiUx.d.ts → Store-BJ8b6xbs.d.ts} +2 -0
- package/dist/cli/index.js +387 -5744
- package/dist/cli/index.js.map +1 -1
- package/dist/cli/index.mjs +387 -5744
- package/dist/cli/index.mjs.map +1 -1
- package/dist/{index-yTOihMUk.d.mts → index-2AoCh09i.d.mts} +1 -1
- package/dist/{index-B2oTMNlL.d.ts → index-BZrUZX8Z.d.ts} +1 -1
- package/dist/{index-B8PTQKy9.d.mts → index-CHbW0NJZ.d.mts} +1 -1
- package/dist/{index-DWk78ifo.d.ts → index-CfqixdlW.d.ts} +1 -1
- package/dist/index.d.mts +4 -4
- package/dist/index.d.ts +4 -4
- package/dist/index.js +281 -5726
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +281 -5726
- package/dist/index.mjs.map +1 -1
- package/dist/mcp/index.d.mts +2 -2
- package/dist/mcp/index.d.ts +2 -2
- package/dist/mcp/index.js +1 -1
- package/dist/mcp/index.js.map +1 -1
- package/dist/mcp/index.mjs +1 -1
- package/dist/mcp/index.mjs.map +1 -1
- package/dist/sdk/index.d.mts +202 -50
- package/dist/sdk/index.d.ts +202 -50
- package/dist/sdk/index.js +76 -34
- package/dist/sdk/index.js.map +1 -1
- package/dist/sdk/index.mjs +76 -34
- package/dist/sdk/index.mjs.map +1 -1
- package/dist/server/api.d.mts +1 -1
- package/dist/server/api.d.ts +1 -1
- package/dist/server/api.js +205 -160
- package/dist/server/api.js.map +1 -1
- package/dist/server/api.mjs +205 -160
- package/dist/server/api.mjs.map +1 -1
- package/dist/server/index.d.mts +2 -2
- package/dist/server/index.d.ts +2 -2
- package/dist/server/index.js +245 -5694
- package/dist/server/index.js.map +1 -1
- package/dist/server/index.mjs +245 -5694
- package/dist/server/index.mjs.map +1 -1
- package/dist/server/websocket.d.mts +1 -1
- package/dist/server/websocket.d.ts +1 -1
- package/dist/ws/index.d.mts +1 -1
- package/dist/ws/index.d.ts +1 -1
- package/package.json +1 -1
- package/dist/sharp-win32-x64-CXV3GA3G.node +0 -0
package/dist/server/api.mjs
CHANGED
|
@@ -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",
|
|
172
|
-
|
|
173
|
-
|
|
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
|
|
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,
|
|
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
|
|
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,
|
|
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
|
-
|
|
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
|
|
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
|
-
|
|
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, "
|
|
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
|
|
1623
|
+
return "2.1.0";
|
|
1579
1624
|
}
|
|
1580
1625
|
})();
|
|
1581
1626
|
function handleHealth(store, pathname, method, res) {
|