mnemosyne-core 2.0.0 → 2.0.2
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/{Store-N3j0Vaj6.d.mts → Store-BtdYuiUx.d.mts} +19 -1
- package/dist/{Store-N3j0Vaj6.d.ts → Store-BtdYuiUx.d.ts} +19 -1
- package/dist/cli/index.js +310 -55
- package/dist/cli/index.js.map +1 -1
- package/dist/cli/index.mjs +294 -39
- package/dist/cli/index.mjs.map +1 -1
- package/dist/dashboard/index.html +9401 -0
- package/dist/index-B2oTMNlL.d.ts +115 -0
- package/dist/index-B8PTQKy9.d.mts +115 -0
- package/dist/index-DWk78ifo.d.ts +98 -0
- package/dist/index-yTOihMUk.d.mts +98 -0
- package/dist/index.d.mts +45 -0
- package/dist/index.d.ts +45 -0
- package/dist/index.js +13008 -0
- package/dist/index.js.map +1 -0
- package/dist/index.mjs +12978 -0
- package/dist/index.mjs.map +1 -0
- package/dist/mcp/index.d.mts +3 -93
- package/dist/mcp/index.d.ts +3 -93
- package/dist/server/api.d.mts +1 -1
- package/dist/server/api.d.ts +1 -1
- package/dist/server/api.js +24 -3
- package/dist/server/api.js.map +1 -1
- package/dist/server/api.mjs +30 -3
- package/dist/server/api.mjs.map +1 -1
- package/dist/server/index.d.mts +7 -110
- package/dist/server/index.d.ts +7 -110
- package/dist/server/index.js +252 -20
- package/dist/server/index.js.map +1 -1
- package/dist/server/index.mjs +251 -19
- 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 +12 -12
package/dist/cli/index.mjs
CHANGED
|
@@ -3554,9 +3554,22 @@ function loadConfig() {
|
|
|
3554
3554
|
return defaultConfig();
|
|
3555
3555
|
}
|
|
3556
3556
|
}
|
|
3557
|
+
function getVersion() {
|
|
3558
|
+
try {
|
|
3559
|
+
const pkg = JSON.parse(readFileSync(resolve(__dirname, "../package.json"), "utf-8"));
|
|
3560
|
+
return pkg.version;
|
|
3561
|
+
} catch {
|
|
3562
|
+
try {
|
|
3563
|
+
const pkg = JSON.parse(readFileSync(resolve(process.cwd(), "package.json"), "utf-8"));
|
|
3564
|
+
return pkg.version;
|
|
3565
|
+
} catch {
|
|
3566
|
+
return "2.0.1";
|
|
3567
|
+
}
|
|
3568
|
+
}
|
|
3569
|
+
}
|
|
3557
3570
|
function defaultConfig() {
|
|
3558
3571
|
return {
|
|
3559
|
-
server: { port: 7321, host: "localhost", version:
|
|
3572
|
+
server: { port: 7321, host: "localhost", version: getVersion() },
|
|
3560
3573
|
database: { path: "data/nexus.db", wal_mode: true, vec_extension_path: "data/vec0" },
|
|
3561
3574
|
storage: { files_dir: "data/files", max_file_size_mb: 50, backups_dir: "data/backups", backup_interval_hours: 24, max_backups: 7 },
|
|
3562
3575
|
limits: { max_atoms_per_project: 1e4, rate_limit_requests: 100, rate_limit_window_ms: 6e4 },
|
|
@@ -4355,7 +4368,7 @@ var require_filesystem = __commonJS({
|
|
|
4355
4368
|
var LDD_PATH = "/usr/bin/ldd";
|
|
4356
4369
|
var SELF_PATH = "/proc/self/exe";
|
|
4357
4370
|
var MAX_LENGTH = 2048;
|
|
4358
|
-
var
|
|
4371
|
+
var readFileSync7 = (path) => {
|
|
4359
4372
|
const fd = fs.openSync(path, "r");
|
|
4360
4373
|
const buffer = Buffer.alloc(MAX_LENGTH);
|
|
4361
4374
|
const bytesRead = fs.readSync(fd, buffer, 0, MAX_LENGTH, 0);
|
|
@@ -4380,7 +4393,7 @@ var require_filesystem = __commonJS({
|
|
|
4380
4393
|
module2.exports = {
|
|
4381
4394
|
LDD_PATH,
|
|
4382
4395
|
SELF_PATH,
|
|
4383
|
-
readFileSync:
|
|
4396
|
+
readFileSync: readFileSync7,
|
|
4384
4397
|
readFile
|
|
4385
4398
|
};
|
|
4386
4399
|
}
|
|
@@ -4429,7 +4442,7 @@ var require_detect_libc = __commonJS({
|
|
|
4429
4442
|
"use strict";
|
|
4430
4443
|
var childProcess = __require("child_process");
|
|
4431
4444
|
var { isLinux, getReport } = require_process();
|
|
4432
|
-
var { LDD_PATH, SELF_PATH, readFile, readFileSync:
|
|
4445
|
+
var { LDD_PATH, SELF_PATH, readFile, readFileSync: readFileSync7 } = require_filesystem();
|
|
4433
4446
|
var { interpreterPath } = require_elf();
|
|
4434
4447
|
var cachedFamilyInterpreter;
|
|
4435
4448
|
var cachedFamilyFilesystem;
|
|
@@ -4521,7 +4534,7 @@ var require_detect_libc = __commonJS({
|
|
|
4521
4534
|
}
|
|
4522
4535
|
cachedFamilyFilesystem = null;
|
|
4523
4536
|
try {
|
|
4524
|
-
const lddContent =
|
|
4537
|
+
const lddContent = readFileSync7(LDD_PATH);
|
|
4525
4538
|
cachedFamilyFilesystem = getFamilyFromLddContent(lddContent);
|
|
4526
4539
|
} catch (e) {
|
|
4527
4540
|
}
|
|
@@ -4546,7 +4559,7 @@ var require_detect_libc = __commonJS({
|
|
|
4546
4559
|
}
|
|
4547
4560
|
cachedFamilyInterpreter = null;
|
|
4548
4561
|
try {
|
|
4549
|
-
const selfContent =
|
|
4562
|
+
const selfContent = readFileSync7(SELF_PATH);
|
|
4550
4563
|
const path = interpreterPath(selfContent);
|
|
4551
4564
|
cachedFamilyInterpreter = familyFromInterpreterPath(path);
|
|
4552
4565
|
} catch (e) {
|
|
@@ -4610,7 +4623,7 @@ var require_detect_libc = __commonJS({
|
|
|
4610
4623
|
}
|
|
4611
4624
|
cachedVersionFilesystem = null;
|
|
4612
4625
|
try {
|
|
4613
|
-
const lddContent =
|
|
4626
|
+
const lddContent = readFileSync7(LDD_PATH);
|
|
4614
4627
|
const versionMatch = lddContent.match(RE_GLIBC_VERSION);
|
|
4615
4628
|
if (versionMatch) {
|
|
4616
4629
|
cachedVersionFilesystem = versionMatch[1];
|
|
@@ -13100,7 +13113,6 @@ import { resolve as resolve9 } from "path";
|
|
|
13100
13113
|
|
|
13101
13114
|
// src/core/Mnemosyne.ts
|
|
13102
13115
|
import Database from "better-sqlite3";
|
|
13103
|
-
import { readFileSync as readFileSync4 } from "fs";
|
|
13104
13116
|
import { resolve as resolve5 } from "path";
|
|
13105
13117
|
|
|
13106
13118
|
// src/core/types.ts
|
|
@@ -14324,9 +14336,26 @@ function parseYaml2(text) {
|
|
|
14324
14336
|
}
|
|
14325
14337
|
return root;
|
|
14326
14338
|
}
|
|
14339
|
+
function getVersion2() {
|
|
14340
|
+
try {
|
|
14341
|
+
const { readFileSync: readFileSync7 } = __require("fs");
|
|
14342
|
+
const { resolve: resolve13 } = __require("path");
|
|
14343
|
+
const pkg = JSON.parse(readFileSync7(resolve13(__dirname, "../../package.json"), "utf-8"));
|
|
14344
|
+
return pkg.version;
|
|
14345
|
+
} catch {
|
|
14346
|
+
try {
|
|
14347
|
+
const { readFileSync: readFileSync7 } = __require("fs");
|
|
14348
|
+
const { resolve: resolve13 } = __require("path");
|
|
14349
|
+
const pkg = JSON.parse(readFileSync7(resolve13(process.cwd(), "package.json"), "utf-8"));
|
|
14350
|
+
return pkg.version;
|
|
14351
|
+
} catch {
|
|
14352
|
+
return "2.0.1";
|
|
14353
|
+
}
|
|
14354
|
+
}
|
|
14355
|
+
}
|
|
14327
14356
|
function defaultConfig2() {
|
|
14328
14357
|
return {
|
|
14329
|
-
server: { port: 7321, host: "localhost", version:
|
|
14358
|
+
server: { port: 7321, host: "localhost", version: getVersion2() },
|
|
14330
14359
|
database: { path: "data/nexus.db", wal_mode: true, vec_extension_path: "data/vec0" },
|
|
14331
14360
|
storage: { files_dir: "data/files", max_file_size_mb: 50, backups_dir: "data/backups", backup_interval_hours: 24, max_backups: 7 },
|
|
14332
14361
|
limits: { max_atoms_per_project: 1e4, rate_limit_requests: 100, rate_limit_window_ms: 6e4 },
|
|
@@ -14349,8 +14378,8 @@ function mergeDeep2(target, source) {
|
|
|
14349
14378
|
}
|
|
14350
14379
|
return output;
|
|
14351
14380
|
}
|
|
14352
|
-
function loadConfig2(configPath) {
|
|
14353
|
-
const path = configPath ? resolve4(configPath) : resolve4(
|
|
14381
|
+
function loadConfig2(configPath, baseDir = process.cwd()) {
|
|
14382
|
+
const path = configPath ? resolve4(configPath) : resolve4(baseDir, "config.yaml");
|
|
14354
14383
|
if (!existsSync4(path)) {
|
|
14355
14384
|
if (!configPath) console.warn("[Config] config.yaml not found, using defaults");
|
|
14356
14385
|
return defaultConfig2();
|
|
@@ -14366,23 +14395,237 @@ function loadConfig2(configPath) {
|
|
|
14366
14395
|
}
|
|
14367
14396
|
var MnemosyneConfig = class {
|
|
14368
14397
|
config;
|
|
14398
|
+
baseDir;
|
|
14369
14399
|
constructor(options) {
|
|
14370
|
-
this.
|
|
14400
|
+
this.baseDir = options?.baseDir || process.cwd();
|
|
14401
|
+
this.config = loadConfig2(options?.configPath, this.baseDir);
|
|
14371
14402
|
if (options?.overrides) {
|
|
14372
14403
|
this.config = mergeDeep2(this.config, options.overrides);
|
|
14373
14404
|
}
|
|
14374
14405
|
}
|
|
14375
14406
|
get dbPath() {
|
|
14376
|
-
return resolve4(
|
|
14407
|
+
return resolve4(this.baseDir, this.config.database.path);
|
|
14377
14408
|
}
|
|
14378
14409
|
get filesDir() {
|
|
14379
|
-
return resolve4(
|
|
14410
|
+
return resolve4(this.baseDir, this.config.storage.files_dir);
|
|
14380
14411
|
}
|
|
14381
14412
|
get backupsDir() {
|
|
14382
|
-
return resolve4(
|
|
14413
|
+
return resolve4(this.baseDir, this.config.storage.backups_dir);
|
|
14414
|
+
}
|
|
14415
|
+
get baseDirPath() {
|
|
14416
|
+
return this.baseDir;
|
|
14383
14417
|
}
|
|
14384
14418
|
};
|
|
14385
14419
|
|
|
14420
|
+
// src/db/schema.ts
|
|
14421
|
+
var SCHEMA_SQL = `-- Mnemosyne v1.1 Database Schema
|
|
14422
|
+
-- SQLite with sqlite-vec extension for semantic search
|
|
14423
|
+
|
|
14424
|
+
-- PROJECTS (Spaces)
|
|
14425
|
+
CREATE TABLE IF NOT EXISTS projects (
|
|
14426
|
+
id TEXT PRIMARY KEY,
|
|
14427
|
+
name TEXT NOT NULL UNIQUE,
|
|
14428
|
+
description TEXT,
|
|
14429
|
+
icon TEXT DEFAULT '\u25C9',
|
|
14430
|
+
color TEXT DEFAULT '#6366f1',
|
|
14431
|
+
created_at INTEGER DEFAULT (unixepoch()),
|
|
14432
|
+
updated_at INTEGER DEFAULT (unixepoch()),
|
|
14433
|
+
owner TEXT DEFAULT 'human',
|
|
14434
|
+
metadata TEXT DEFAULT '{}'
|
|
14435
|
+
);
|
|
14436
|
+
|
|
14437
|
+
-- ATOMS (Ideas/Nodes)
|
|
14438
|
+
CREATE TABLE IF NOT EXISTS atoms (
|
|
14439
|
+
id TEXT PRIMARY KEY,
|
|
14440
|
+
project_id TEXT NOT NULL REFERENCES projects(id) ON DELETE CASCADE,
|
|
14441
|
+
parent_id TEXT REFERENCES atoms(id) ON DELETE CASCADE,
|
|
14442
|
+
title TEXT NOT NULL,
|
|
14443
|
+
summary TEXT,
|
|
14444
|
+
icon TEXT DEFAULT '\u25CF',
|
|
14445
|
+
color TEXT,
|
|
14446
|
+
x REAL,
|
|
14447
|
+
y REAL,
|
|
14448
|
+
auto_path TEXT,
|
|
14449
|
+
path_overridden INTEGER DEFAULT 0,
|
|
14450
|
+
status TEXT DEFAULT 'draft',
|
|
14451
|
+
status_updated_at INTEGER DEFAULT (unixepoch()),
|
|
14452
|
+
embedding_status TEXT DEFAULT 'pending',
|
|
14453
|
+
embedding_error TEXT,
|
|
14454
|
+
block_count INTEGER DEFAULT 0,
|
|
14455
|
+
bond_count INTEGER DEFAULT 0,
|
|
14456
|
+
template_id TEXT,
|
|
14457
|
+
created_at INTEGER DEFAULT (unixepoch()),
|
|
14458
|
+
updated_at INTEGER DEFAULT (unixepoch()),
|
|
14459
|
+
version INTEGER DEFAULT 1,
|
|
14460
|
+
locked_by TEXT,
|
|
14461
|
+
locked_at INTEGER,
|
|
14462
|
+
locked_reason TEXT,
|
|
14463
|
+
owner TEXT DEFAULT 'human',
|
|
14464
|
+
metadata TEXT DEFAULT '{}'
|
|
14465
|
+
);
|
|
14466
|
+
|
|
14467
|
+
-- BLOCKS (Content pieces inside atoms)
|
|
14468
|
+
CREATE TABLE IF NOT EXISTS blocks (
|
|
14469
|
+
id TEXT PRIMARY KEY,
|
|
14470
|
+
atom_id TEXT NOT NULL REFERENCES atoms(id) ON DELETE CASCADE,
|
|
14471
|
+
type TEXT NOT NULL DEFAULT 'text',
|
|
14472
|
+
content TEXT,
|
|
14473
|
+
order_index INTEGER DEFAULT 0,
|
|
14474
|
+
created_at INTEGER DEFAULT (unixepoch()),
|
|
14475
|
+
updated_at INTEGER DEFAULT (unixepoch()),
|
|
14476
|
+
metadata TEXT DEFAULT '{}'
|
|
14477
|
+
);
|
|
14478
|
+
|
|
14479
|
+
-- BONDS (Graph connections between atoms)
|
|
14480
|
+
CREATE TABLE IF NOT EXISTS bonds (
|
|
14481
|
+
id TEXT PRIMARY KEY,
|
|
14482
|
+
source_id TEXT NOT NULL REFERENCES atoms(id) ON DELETE CASCADE,
|
|
14483
|
+
target_id TEXT NOT NULL REFERENCES atoms(id) ON DELETE CASCADE,
|
|
14484
|
+
label TEXT DEFAULT 'connects',
|
|
14485
|
+
color TEXT,
|
|
14486
|
+
created_at INTEGER DEFAULT (unixepoch()),
|
|
14487
|
+
UNIQUE(source_id, target_id)
|
|
14488
|
+
);
|
|
14489
|
+
|
|
14490
|
+
-- ATTACHMENTS (Files in CAS)
|
|
14491
|
+
CREATE TABLE IF NOT EXISTS attachments (
|
|
14492
|
+
id TEXT PRIMARY KEY,
|
|
14493
|
+
block_id TEXT REFERENCES blocks(id) ON DELETE CASCADE,
|
|
14494
|
+
file_name TEXT NOT NULL,
|
|
14495
|
+
file_hash TEXT NOT NULL,
|
|
14496
|
+
file_size INTEGER,
|
|
14497
|
+
mime_type TEXT,
|
|
14498
|
+
created_at INTEGER DEFAULT (unixepoch()),
|
|
14499
|
+
UNIQUE(file_hash)
|
|
14500
|
+
);
|
|
14501
|
+
|
|
14502
|
+
-- EVENT LOG (Immutable audit trail)
|
|
14503
|
+
CREATE TABLE IF NOT EXISTS event_log (
|
|
14504
|
+
id TEXT PRIMARY KEY,
|
|
14505
|
+
timestamp INTEGER DEFAULT (unixepoch()),
|
|
14506
|
+
event_type TEXT NOT NULL,
|
|
14507
|
+
project_id TEXT,
|
|
14508
|
+
atom_id TEXT,
|
|
14509
|
+
block_id TEXT,
|
|
14510
|
+
bond_id TEXT,
|
|
14511
|
+
actor TEXT NOT NULL DEFAULT 'system',
|
|
14512
|
+
actor_type TEXT DEFAULT 'system',
|
|
14513
|
+
diff TEXT,
|
|
14514
|
+
trigger TEXT,
|
|
14515
|
+
metadata TEXT DEFAULT '{}'
|
|
14516
|
+
);
|
|
14517
|
+
|
|
14518
|
+
-- ASSISTANTS (AI Agents)
|
|
14519
|
+
CREATE TABLE IF NOT EXISTS assistants (
|
|
14520
|
+
id TEXT PRIMARY KEY,
|
|
14521
|
+
name TEXT NOT NULL,
|
|
14522
|
+
role TEXT DEFAULT 'worker',
|
|
14523
|
+
permissions TEXT DEFAULT '{"read":["*"],"write":[],"delete":false}',
|
|
14524
|
+
status TEXT DEFAULT 'active',
|
|
14525
|
+
provider TEXT,
|
|
14526
|
+
connected_at INTEGER DEFAULT (unixepoch()),
|
|
14527
|
+
last_seen INTEGER DEFAULT (unixepoch()),
|
|
14528
|
+
metadata TEXT DEFAULT '{}'
|
|
14529
|
+
);
|
|
14530
|
+
|
|
14531
|
+
-- QUEUE (Agent waitlist for locked atoms)
|
|
14532
|
+
CREATE TABLE IF NOT EXISTS queue (
|
|
14533
|
+
id TEXT PRIMARY KEY,
|
|
14534
|
+
atom_id TEXT NOT NULL REFERENCES atoms(id) ON DELETE CASCADE,
|
|
14535
|
+
assistant_id TEXT NOT NULL REFERENCES assistants(id) ON DELETE CASCADE,
|
|
14536
|
+
requested_at INTEGER DEFAULT (unixepoch()),
|
|
14537
|
+
priority INTEGER DEFAULT 5,
|
|
14538
|
+
status TEXT DEFAULT 'waiting',
|
|
14539
|
+
reason TEXT
|
|
14540
|
+
);
|
|
14541
|
+
|
|
14542
|
+
-- INDICES
|
|
14543
|
+
CREATE INDEX IF NOT EXISTS idx_atoms_project ON atoms(project_id);
|
|
14544
|
+
CREATE INDEX IF NOT EXISTS idx_atoms_parent ON atoms(parent_id);
|
|
14545
|
+
CREATE INDEX IF NOT EXISTS idx_atoms_locked ON atoms(locked_by) WHERE locked_by IS NOT NULL;
|
|
14546
|
+
-- idx_atoms_path_project is created by migration after auto_path column is added
|
|
14547
|
+
CREATE INDEX IF NOT EXISTS idx_blocks_atom ON blocks(atom_id);
|
|
14548
|
+
CREATE INDEX IF NOT EXISTS idx_bonds_source ON bonds(source_id);
|
|
14549
|
+
CREATE INDEX IF NOT EXISTS idx_bonds_target ON bonds(target_id);
|
|
14550
|
+
CREATE INDEX IF NOT EXISTS idx_event_log_time ON event_log(timestamp);
|
|
14551
|
+
CREATE INDEX IF NOT EXISTS idx_event_log_atom ON event_log(atom_id);
|
|
14552
|
+
CREATE INDEX IF NOT EXISTS idx_queue_atom ON queue(atom_id);
|
|
14553
|
+
CREATE INDEX IF NOT EXISTS idx_attachments_hash ON attachments(file_hash);
|
|
14554
|
+
|
|
14555
|
+
-- Auto-update block_count and bond_count triggers
|
|
14556
|
+
CREATE TRIGGER IF NOT EXISTS update_block_count_insert AFTER INSERT ON blocks BEGIN
|
|
14557
|
+
UPDATE atoms SET block_count = block_count + 1 WHERE id = NEW.atom_id;
|
|
14558
|
+
END;
|
|
14559
|
+
|
|
14560
|
+
CREATE TRIGGER IF NOT EXISTS update_block_count_delete AFTER DELETE ON blocks BEGIN
|
|
14561
|
+
UPDATE atoms SET block_count = block_count - 1 WHERE id = OLD.atom_id;
|
|
14562
|
+
END;
|
|
14563
|
+
|
|
14564
|
+
CREATE TRIGGER IF NOT EXISTS update_bond_count_insert AFTER INSERT ON bonds BEGIN
|
|
14565
|
+
UPDATE atoms SET bond_count = bond_count + 1 WHERE id = NEW.source_id OR id = NEW.target_id;
|
|
14566
|
+
END;
|
|
14567
|
+
|
|
14568
|
+
CREATE TRIGGER IF NOT EXISTS update_bond_count_delete AFTER DELETE ON bonds BEGIN
|
|
14569
|
+
UPDATE atoms SET bond_count = bond_count - 1 WHERE id = OLD.source_id OR id = OLD.target_id;
|
|
14570
|
+
END;
|
|
14571
|
+
|
|
14572
|
+
-- FTS5 FULL-TEXT SEARCH
|
|
14573
|
+
-- Separate tables to avoid rowid collisions between atoms and blocks
|
|
14574
|
+
|
|
14575
|
+
CREATE VIRTUAL TABLE IF NOT EXISTS search_atoms USING fts5(
|
|
14576
|
+
title, summary,
|
|
14577
|
+
content='atoms', content_rowid='rowid'
|
|
14578
|
+
);
|
|
14579
|
+
|
|
14580
|
+
CREATE VIRTUAL TABLE IF NOT EXISTS search_blocks USING fts5(
|
|
14581
|
+
content,
|
|
14582
|
+
content='blocks', content_rowid='rowid'
|
|
14583
|
+
);
|
|
14584
|
+
|
|
14585
|
+
-- Triggers to keep search_atoms in sync
|
|
14586
|
+
CREATE TRIGGER IF NOT EXISTS trig_search_atoms_insert AFTER INSERT ON atoms BEGIN
|
|
14587
|
+
INSERT INTO search_atoms(rowid, title, summary) VALUES (new.rowid, new.title, COALESCE(new.summary, ''));
|
|
14588
|
+
END;
|
|
14589
|
+
|
|
14590
|
+
CREATE TRIGGER IF NOT EXISTS trig_search_atoms_update AFTER UPDATE ON atoms BEGIN
|
|
14591
|
+
UPDATE search_atoms SET title = new.title, summary = COALESCE(new.summary, '') WHERE rowid = new.rowid;
|
|
14592
|
+
END;
|
|
14593
|
+
|
|
14594
|
+
CREATE TRIGGER IF NOT EXISTS trig_search_atoms_delete AFTER DELETE ON atoms BEGIN
|
|
14595
|
+
DELETE FROM search_atoms WHERE rowid = old.rowid;
|
|
14596
|
+
END;
|
|
14597
|
+
|
|
14598
|
+
-- Triggers to keep search_blocks in sync
|
|
14599
|
+
CREATE TRIGGER IF NOT EXISTS trig_search_blocks_insert AFTER INSERT ON blocks BEGIN
|
|
14600
|
+
INSERT INTO search_blocks(rowid, content) VALUES (new.rowid, COALESCE(new.content, ''));
|
|
14601
|
+
END;
|
|
14602
|
+
|
|
14603
|
+
CREATE TRIGGER IF NOT EXISTS trig_search_blocks_update AFTER UPDATE ON blocks BEGIN
|
|
14604
|
+
UPDATE search_blocks SET content = COALESCE(new.content, '') WHERE rowid = new.rowid;
|
|
14605
|
+
END;
|
|
14606
|
+
|
|
14607
|
+
CREATE TRIGGER IF NOT EXISTS trig_search_blocks_delete AFTER DELETE ON blocks BEGIN
|
|
14608
|
+
DELETE FROM search_blocks WHERE rowid = old.rowid;
|
|
14609
|
+
END;
|
|
14610
|
+
|
|
14611
|
+
|
|
14612
|
+
-- PER-ATOM PERMISSIONS (Granular access control)
|
|
14613
|
+
CREATE TABLE IF NOT EXISTS atom_permissions (
|
|
14614
|
+
id TEXT PRIMARY KEY,
|
|
14615
|
+
atom_id TEXT NOT NULL REFERENCES atoms(id) ON DELETE CASCADE,
|
|
14616
|
+
assistant_id TEXT NOT NULL REFERENCES assistants(id) ON DELETE CASCADE,
|
|
14617
|
+
level TEXT NOT NULL DEFAULT 'view',
|
|
14618
|
+
granted_by TEXT,
|
|
14619
|
+
granted_at INTEGER DEFAULT (unixepoch()),
|
|
14620
|
+
metadata TEXT DEFAULT '{}',
|
|
14621
|
+
UNIQUE(atom_id, assistant_id)
|
|
14622
|
+
);
|
|
14623
|
+
|
|
14624
|
+
-- sqlite-vec virtual table for semantic embeddings
|
|
14625
|
+
-- Created dynamically by connection.ts after loading the extension
|
|
14626
|
+
-- CREATE VIRTUAL TABLE IF NOT EXISTS atom_vectors USING vec0(atom_id TEXT PRIMARY KEY, embedding float[384]);
|
|
14627
|
+
`;
|
|
14628
|
+
|
|
14386
14629
|
// src/core/Mnemosyne.ts
|
|
14387
14630
|
var Mnemosyne = class {
|
|
14388
14631
|
store;
|
|
@@ -14390,7 +14633,7 @@ var Mnemosyne = class {
|
|
|
14390
14633
|
vecEnabled;
|
|
14391
14634
|
db;
|
|
14392
14635
|
constructor(options = {}) {
|
|
14393
|
-
this.config = new MnemosyneConfig({ configPath: options.configPath });
|
|
14636
|
+
this.config = new MnemosyneConfig({ configPath: options.configPath, baseDir: options.baseDir });
|
|
14394
14637
|
const cfg = this.config.config;
|
|
14395
14638
|
const dbPath = options.dbPath || this.config.dbPath;
|
|
14396
14639
|
this.db = new Database(dbPath);
|
|
@@ -14399,17 +14642,21 @@ var Mnemosyne = class {
|
|
|
14399
14642
|
this.db.pragma("synchronous = NORMAL");
|
|
14400
14643
|
this.vecEnabled = false;
|
|
14401
14644
|
try {
|
|
14402
|
-
|
|
14645
|
+
let vecPath;
|
|
14646
|
+
try {
|
|
14647
|
+
const sqliteVec = __require("sqlite-vec");
|
|
14648
|
+
vecPath = sqliteVec.getLoadablePath();
|
|
14649
|
+
} catch {
|
|
14650
|
+
vecPath = resolve5(this.config.baseDirPath || process.cwd(), cfg.database.vec_extension_path);
|
|
14651
|
+
}
|
|
14403
14652
|
this.db.loadExtension(vecPath);
|
|
14404
14653
|
this.vecEnabled = true;
|
|
14405
14654
|
console.log("[DB] sqlite-vec extension loaded");
|
|
14406
14655
|
} catch (err) {
|
|
14407
14656
|
console.warn("[DB] sqlite-vec not available:", err.message);
|
|
14408
14657
|
}
|
|
14409
|
-
const schemaPath = resolve5(process.cwd(), "src", "db", "schema.sql");
|
|
14410
14658
|
try {
|
|
14411
|
-
|
|
14412
|
-
this.db.exec(schema);
|
|
14659
|
+
this.db.exec(SCHEMA_SQL);
|
|
14413
14660
|
} catch (err) {
|
|
14414
14661
|
console.error("[DB] Failed to load schema:", err.message);
|
|
14415
14662
|
}
|
|
@@ -14453,7 +14700,7 @@ var Mnemosyne = class {
|
|
|
14453
14700
|
|
|
14454
14701
|
// src/server/MnemosyneServer.ts
|
|
14455
14702
|
import { createServer } from "http";
|
|
14456
|
-
import { readFileSync as
|
|
14703
|
+
import { readFileSync as readFileSync5, existsSync as existsSync6 } from "fs";
|
|
14457
14704
|
import { resolve as resolve8 } from "path";
|
|
14458
14705
|
|
|
14459
14706
|
// node_modules/ws/wrapper.mjs
|
|
@@ -15608,19 +15855,19 @@ function handleFiles(store, pathname, method, req, res, maxFileSizeMb) {
|
|
|
15608
15855
|
// src/server/export-format.ts
|
|
15609
15856
|
import AdmZip2 from "adm-zip";
|
|
15610
15857
|
import { createHash as createHash2 } from "crypto";
|
|
15611
|
-
import { readFileSync as
|
|
15858
|
+
import { readFileSync as readFileSync4, existsSync as existsSync5, readdirSync as readdirSync2, statSync as statSync2 } from "fs";
|
|
15612
15859
|
import { resolve as resolve6 } from "path";
|
|
15613
15860
|
var DB_PATH = resolve6(process.cwd(), "data", "nexus.db");
|
|
15614
15861
|
var FILES_DIR2 = resolve6(process.cwd(), "data", "files");
|
|
15615
15862
|
function sha256File(path) {
|
|
15616
|
-
return createHash2("sha256").update(
|
|
15863
|
+
return createHash2("sha256").update(readFileSync4(path)).digest("hex");
|
|
15617
15864
|
}
|
|
15618
15865
|
function sha256Dir(dir) {
|
|
15619
15866
|
const hash = createHash2("sha256");
|
|
15620
15867
|
function walk(p) {
|
|
15621
15868
|
const stat = statSync2(p);
|
|
15622
15869
|
if (stat.isFile()) {
|
|
15623
|
-
hash.update(
|
|
15870
|
+
hash.update(readFileSync4(p));
|
|
15624
15871
|
} else if (stat.isDirectory()) {
|
|
15625
15872
|
for (const child of readdirSync2(p).sort()) walk(resolve6(p, child));
|
|
15626
15873
|
}
|
|
@@ -15761,12 +16008,20 @@ function handleEvents(store, pathname, method, res, searchParams) {
|
|
|
15761
16008
|
}
|
|
15762
16009
|
|
|
15763
16010
|
// src/api/routes/health.ts
|
|
16011
|
+
var PKG_VERSION = (() => {
|
|
16012
|
+
try {
|
|
16013
|
+
const pkg = JSON.parse(__require("fs").readFileSync(__require("path").resolve(__dirname, "../../../package.json"), "utf-8"));
|
|
16014
|
+
return pkg.version;
|
|
16015
|
+
} catch {
|
|
16016
|
+
return "2.0.1";
|
|
16017
|
+
}
|
|
16018
|
+
})();
|
|
15764
16019
|
function handleHealth(store, pathname, method, res) {
|
|
15765
|
-
if (pathname === "/health" && method === "GET") {
|
|
16020
|
+
if ((pathname === "/health" || pathname === "/api/v1/health") && method === "GET") {
|
|
15766
16021
|
const stats = store.getStats();
|
|
15767
16022
|
json(res, 200, {
|
|
15768
16023
|
status: "ok",
|
|
15769
|
-
version:
|
|
16024
|
+
version: PKG_VERSION,
|
|
15770
16025
|
storage: "sqlite",
|
|
15771
16026
|
database: store.config.database.path,
|
|
15772
16027
|
uptime: process.uptime(),
|
|
@@ -15992,7 +16247,6 @@ var WebSocketHandler = class {
|
|
|
15992
16247
|
// src/db/connection.ts
|
|
15993
16248
|
init_config();
|
|
15994
16249
|
import Database2 from "better-sqlite3";
|
|
15995
|
-
import { readFileSync as readFileSync6 } from "fs";
|
|
15996
16250
|
import { resolve as resolve7 } from "path";
|
|
15997
16251
|
var DB_PATH2 = process.env.MNEMOSYNE_DB_PATH || resolve7(process.cwd(), CONFIG.database.path);
|
|
15998
16252
|
var db = null;
|
|
@@ -16012,8 +16266,7 @@ function getDb() {
|
|
|
16012
16266
|
console.warn("[DB] sqlite-vec not available:", err.message);
|
|
16013
16267
|
vecEnabled = false;
|
|
16014
16268
|
}
|
|
16015
|
-
|
|
16016
|
-
db.exec(schema);
|
|
16269
|
+
db.exec(SCHEMA_SQL);
|
|
16017
16270
|
if (vecEnabled) {
|
|
16018
16271
|
try {
|
|
16019
16272
|
db.exec(`CREATE VIRTUAL TABLE IF NOT EXISTS atom_vectors USING vec0(atom_id TEXT PRIMARY KEY, embedding float[${CONFIG.embeddings.dimension}])`);
|
|
@@ -16045,7 +16298,6 @@ var Store2 = class extends Store {
|
|
|
16045
16298
|
};
|
|
16046
16299
|
|
|
16047
16300
|
// src/server/MnemosyneServer.ts
|
|
16048
|
-
init_config();
|
|
16049
16301
|
var MnemosyneServer = class {
|
|
16050
16302
|
store;
|
|
16051
16303
|
api;
|
|
@@ -16053,8 +16305,9 @@ var MnemosyneServer = class {
|
|
|
16053
16305
|
httpServer;
|
|
16054
16306
|
brain;
|
|
16055
16307
|
constructor(options = {}, brain) {
|
|
16056
|
-
const
|
|
16057
|
-
const
|
|
16308
|
+
const cfg = brain?.config?.config;
|
|
16309
|
+
const port = options.port ?? cfg?.server?.port ?? 7321;
|
|
16310
|
+
const host = options.host ?? cfg?.server?.host ?? "localhost";
|
|
16058
16311
|
const enableDashboard = options.dashboard !== false;
|
|
16059
16312
|
const enableWebsocket = options.websocket !== false;
|
|
16060
16313
|
process.on("uncaughtException", (err) => {
|
|
@@ -16082,8 +16335,9 @@ var MnemosyneServer = class {
|
|
|
16082
16335
|
const wss = new import_websocket_server.default({ server: this.httpServer });
|
|
16083
16336
|
this.wsHandler = new WebSocketHandler(wss, this.store);
|
|
16084
16337
|
}
|
|
16338
|
+
const version = cfg?.server?.version || "2.0.1";
|
|
16085
16339
|
this.httpServer.listen(port, () => {
|
|
16086
|
-
console.log(`Mnemosyne v${
|
|
16340
|
+
console.log(`Mnemosyne v${version} \u2014 port ${port}`);
|
|
16087
16341
|
console.log(`Dashboard: http://${host}:${port}/dashboard`);
|
|
16088
16342
|
console.log(`API: http://${host}:${port}/api/v1`);
|
|
16089
16343
|
console.log(`MCP: http://${host}:${port}/mcp/manifest`);
|
|
@@ -16108,12 +16362,13 @@ var MnemosyneServer = class {
|
|
|
16108
16362
|
};
|
|
16109
16363
|
const dirs = [
|
|
16110
16364
|
resolve8(process.cwd(), "src/dashboard"),
|
|
16111
|
-
resolve8(process.cwd(), "dashboard")
|
|
16365
|
+
resolve8(process.cwd(), "dashboard"),
|
|
16366
|
+
resolve8(__dirname, "../dashboard")
|
|
16112
16367
|
];
|
|
16113
16368
|
for (const dir of dirs) {
|
|
16114
16369
|
const filePath = resolve8(dir, urlPath);
|
|
16115
16370
|
if (existsSync6(filePath)) {
|
|
16116
|
-
const data =
|
|
16371
|
+
const data = readFileSync5(filePath);
|
|
16117
16372
|
res.writeHead(200, { "Content-Type": mime[ext] || "application/octet-stream" });
|
|
16118
16373
|
res.end(data);
|
|
16119
16374
|
return;
|
|
@@ -16135,7 +16390,7 @@ var MnemosyneServer = class {
|
|
|
16135
16390
|
async function startCommand(options) {
|
|
16136
16391
|
const dataDir = resolve9(options.dataDir);
|
|
16137
16392
|
const dbPath = resolve9(dataDir, "nexus.db");
|
|
16138
|
-
const brain = new Mnemosyne({ dbPath, configPath: options.config });
|
|
16393
|
+
const brain = new Mnemosyne({ dbPath, configPath: options.config, baseDir: dataDir });
|
|
16139
16394
|
await brain.init();
|
|
16140
16395
|
if (options.mcpTransport === "stdio" && options.mcp) {
|
|
16141
16396
|
if (options.verbose) {
|
|
@@ -16225,7 +16480,7 @@ async function initCommand(options) {
|
|
|
16225
16480
|
}
|
|
16226
16481
|
const dbPath = resolve10(dataDir, "nexus.db");
|
|
16227
16482
|
if (!existsSync7(dbPath)) {
|
|
16228
|
-
const brain = new Mnemosyne({ dbPath, configPath });
|
|
16483
|
+
const brain = new Mnemosyne({ dbPath, configPath, baseDir: dataDir });
|
|
16229
16484
|
await brain.init();
|
|
16230
16485
|
await brain.close();
|
|
16231
16486
|
console.log(`\u2705 Initialized database: ${dbPath}`);
|
|
@@ -16239,14 +16494,14 @@ async function initCommand(options) {
|
|
|
16239
16494
|
|
|
16240
16495
|
// src/cli/commands/migrate.ts
|
|
16241
16496
|
import { resolve as resolve11 } from "path";
|
|
16242
|
-
import { readFileSync as
|
|
16497
|
+
import { readFileSync as readFileSync6 } from "fs";
|
|
16243
16498
|
async function migrateCommand(options) {
|
|
16244
16499
|
const fromPath = resolve11(options.from);
|
|
16245
16500
|
const toPath = resolve11(options.to);
|
|
16246
16501
|
console.log(`\u{1F504} Migrating v1.0 JSON \u2192 v2.0 SQLite`);
|
|
16247
16502
|
console.log(` From: ${fromPath}`);
|
|
16248
16503
|
console.log(` To: ${toPath}`);
|
|
16249
|
-
const raw =
|
|
16504
|
+
const raw = readFileSync6(fromPath, "utf-8");
|
|
16250
16505
|
const v1 = JSON.parse(raw);
|
|
16251
16506
|
const brain = new Mnemosyne({ dbPath: toPath });
|
|
16252
16507
|
await brain.init();
|