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.
@@ -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: "2.0.0" },
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 readFileSync9 = (path) => {
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: readFileSync9,
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: readFileSync9 } = require_filesystem();
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 = readFileSync9(LDD_PATH);
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 = readFileSync9(SELF_PATH);
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 = readFileSync9(LDD_PATH);
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: "2.0.0" },
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(process.cwd(), "config.yaml");
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.config = loadConfig2(options?.configPath);
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(process.cwd(), this.config.database.path);
14407
+ return resolve4(this.baseDir, this.config.database.path);
14377
14408
  }
14378
14409
  get filesDir() {
14379
- return resolve4(process.cwd(), this.config.storage.files_dir);
14410
+ return resolve4(this.baseDir, this.config.storage.files_dir);
14380
14411
  }
14381
14412
  get backupsDir() {
14382
- return resolve4(process.cwd(), this.config.storage.backups_dir);
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
- const vecPath = resolve5(process.cwd(), cfg.database.vec_extension_path);
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
- const schema = readFileSync4(schemaPath, "utf-8");
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 readFileSync7, existsSync as existsSync6 } from "fs";
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 readFileSync5, existsSync as existsSync5, readdirSync as readdirSync2, statSync as statSync2 } from "fs";
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(readFileSync5(path)).digest("hex");
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(readFileSync5(p));
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: "2.0.0",
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
- const schema = readFileSync6(resolve7(process.cwd(), "src", "db", "schema.sql"), "utf-8");
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 port = options.port ?? CONFIG.server.port;
16057
- const host = options.host ?? CONFIG.server.host;
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${CONFIG.server.version} \u2014 port ${port}`);
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 = readFileSync7(filePath);
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 readFileSync8 } from "fs";
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 = readFileSync8(fromPath, "utf-8");
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();