mnemosyne-core 2.0.0 → 2.0.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.
@@ -137,6 +137,24 @@ interface Config {
137
137
  default_type: string;
138
138
  };
139
139
  }
140
+ declare const TEMPLATES: Record<string, {
141
+ name: string;
142
+ blocks: {
143
+ type: string;
144
+ content: string;
145
+ }[];
146
+ }>;
147
+ declare const ROLE_PERMISSIONS: Record<AssistantRole, {
148
+ actions: Action[];
149
+ pattern: string;
150
+ }>;
151
+ declare const PRIORITY: {
152
+ readonly IMMEDIATE: 0;
153
+ readonly HIGH: 1;
154
+ readonly NORMAL: 2;
155
+ readonly LOW: 3;
156
+ readonly SCHEDULED: 4;
157
+ };
140
158
 
141
159
  /**
142
160
  * Mnemosyne Store Engine
@@ -317,4 +335,4 @@ declare class Store extends EventEmitter {
317
335
  };
318
336
  }
319
337
 
320
- export { type Atom as A, type Config as C, type Project as P, Store as S };
338
+ export { type Assistant as A, type Block as B, type Config as C, type EventLogEntry as E, PRIORITY as P, type QueueEntry as Q, ROLE_PERMISSIONS as R, Store as S, TEMPLATES as T, type Action as a, type AssistantRole as b, type Atom as c, type Bond as d, type PermissionLevel as e, type Project as f };
@@ -137,6 +137,24 @@ interface Config {
137
137
  default_type: string;
138
138
  };
139
139
  }
140
+ declare const TEMPLATES: Record<string, {
141
+ name: string;
142
+ blocks: {
143
+ type: string;
144
+ content: string;
145
+ }[];
146
+ }>;
147
+ declare const ROLE_PERMISSIONS: Record<AssistantRole, {
148
+ actions: Action[];
149
+ pattern: string;
150
+ }>;
151
+ declare const PRIORITY: {
152
+ readonly IMMEDIATE: 0;
153
+ readonly HIGH: 1;
154
+ readonly NORMAL: 2;
155
+ readonly LOW: 3;
156
+ readonly SCHEDULED: 4;
157
+ };
140
158
 
141
159
  /**
142
160
  * Mnemosyne Store Engine
@@ -317,4 +335,4 @@ declare class Store extends EventEmitter {
317
335
  };
318
336
  }
319
337
 
320
- export { type Atom as A, type Config as C, type Project as P, Store as S };
338
+ export { type Assistant as A, type Block as B, type Config as C, type EventLogEntry as E, PRIORITY as P, type QueueEntry as Q, ROLE_PERMISSIONS as R, Store as S, TEMPLATES as T, type Action as a, type AssistantRole as b, type Atom as c, type Bond as d, type PermissionLevel as e, type Project as f };
package/dist/cli/index.js CHANGED
@@ -4351,7 +4351,7 @@ var require_filesystem = __commonJS({
4351
4351
  var LDD_PATH = "/usr/bin/ldd";
4352
4352
  var SELF_PATH = "/proc/self/exe";
4353
4353
  var MAX_LENGTH = 2048;
4354
- var readFileSync9 = (path) => {
4354
+ var readFileSync7 = (path) => {
4355
4355
  const fd = fs.openSync(path, "r");
4356
4356
  const buffer = Buffer.alloc(MAX_LENGTH);
4357
4357
  const bytesRead = fs.readSync(fd, buffer, 0, MAX_LENGTH, 0);
@@ -4376,7 +4376,7 @@ var require_filesystem = __commonJS({
4376
4376
  module2.exports = {
4377
4377
  LDD_PATH,
4378
4378
  SELF_PATH,
4379
- readFileSync: readFileSync9,
4379
+ readFileSync: readFileSync7,
4380
4380
  readFile
4381
4381
  };
4382
4382
  }
@@ -4425,7 +4425,7 @@ var require_detect_libc = __commonJS({
4425
4425
  "use strict";
4426
4426
  var childProcess = require("child_process");
4427
4427
  var { isLinux, getReport } = require_process();
4428
- var { LDD_PATH, SELF_PATH, readFile, readFileSync: readFileSync9 } = require_filesystem();
4428
+ var { LDD_PATH, SELF_PATH, readFile, readFileSync: readFileSync7 } = require_filesystem();
4429
4429
  var { interpreterPath } = require_elf();
4430
4430
  var cachedFamilyInterpreter;
4431
4431
  var cachedFamilyFilesystem;
@@ -4517,7 +4517,7 @@ var require_detect_libc = __commonJS({
4517
4517
  }
4518
4518
  cachedFamilyFilesystem = null;
4519
4519
  try {
4520
- const lddContent = readFileSync9(LDD_PATH);
4520
+ const lddContent = readFileSync7(LDD_PATH);
4521
4521
  cachedFamilyFilesystem = getFamilyFromLddContent(lddContent);
4522
4522
  } catch (e) {
4523
4523
  }
@@ -4542,7 +4542,7 @@ var require_detect_libc = __commonJS({
4542
4542
  }
4543
4543
  cachedFamilyInterpreter = null;
4544
4544
  try {
4545
- const selfContent = readFileSync9(SELF_PATH);
4545
+ const selfContent = readFileSync7(SELF_PATH);
4546
4546
  const path = interpreterPath(selfContent);
4547
4547
  cachedFamilyInterpreter = familyFromInterpreterPath(path);
4548
4548
  } catch (e) {
@@ -4606,7 +4606,7 @@ var require_detect_libc = __commonJS({
4606
4606
  }
4607
4607
  cachedVersionFilesystem = null;
4608
4608
  try {
4609
- const lddContent = readFileSync9(LDD_PATH);
4609
+ const lddContent = readFileSync7(LDD_PATH);
4610
4610
  const versionMatch = lddContent.match(RE_GLIBC_VERSION);
4611
4611
  if (versionMatch) {
4612
4612
  cachedVersionFilesystem = versionMatch[1];
@@ -13103,7 +13103,6 @@ var import_path9 = require("path");
13103
13103
 
13104
13104
  // src/core/Mnemosyne.ts
13105
13105
  var import_better_sqlite32 = __toESM(require("better-sqlite3"));
13106
- var import_fs5 = require("fs");
13107
13106
  var import_path5 = require("path");
13108
13107
 
13109
13108
  // src/core/types.ts
@@ -14352,8 +14351,8 @@ function mergeDeep2(target, source) {
14352
14351
  }
14353
14352
  return output;
14354
14353
  }
14355
- function loadConfig2(configPath) {
14356
- const path = configPath ? (0, import_path4.resolve)(configPath) : (0, import_path4.resolve)(process.cwd(), "config.yaml");
14354
+ function loadConfig2(configPath, baseDir = process.cwd()) {
14355
+ const path = configPath ? (0, import_path4.resolve)(configPath) : (0, import_path4.resolve)(baseDir, "config.yaml");
14357
14356
  if (!(0, import_fs4.existsSync)(path)) {
14358
14357
  if (!configPath) console.warn("[Config] config.yaml not found, using defaults");
14359
14358
  return defaultConfig2();
@@ -14369,23 +14368,237 @@ function loadConfig2(configPath) {
14369
14368
  }
14370
14369
  var MnemosyneConfig = class {
14371
14370
  config;
14371
+ baseDir;
14372
14372
  constructor(options) {
14373
- this.config = loadConfig2(options?.configPath);
14373
+ this.baseDir = options?.baseDir || process.cwd();
14374
+ this.config = loadConfig2(options?.configPath, this.baseDir);
14374
14375
  if (options?.overrides) {
14375
14376
  this.config = mergeDeep2(this.config, options.overrides);
14376
14377
  }
14377
14378
  }
14378
14379
  get dbPath() {
14379
- return (0, import_path4.resolve)(process.cwd(), this.config.database.path);
14380
+ return (0, import_path4.resolve)(this.baseDir, this.config.database.path);
14380
14381
  }
14381
14382
  get filesDir() {
14382
- return (0, import_path4.resolve)(process.cwd(), this.config.storage.files_dir);
14383
+ return (0, import_path4.resolve)(this.baseDir, this.config.storage.files_dir);
14383
14384
  }
14384
14385
  get backupsDir() {
14385
- return (0, import_path4.resolve)(process.cwd(), this.config.storage.backups_dir);
14386
+ return (0, import_path4.resolve)(this.baseDir, this.config.storage.backups_dir);
14387
+ }
14388
+ get baseDirPath() {
14389
+ return this.baseDir;
14386
14390
  }
14387
14391
  };
14388
14392
 
14393
+ // src/db/schema.ts
14394
+ var SCHEMA_SQL = `-- Mnemosyne v1.1 Database Schema
14395
+ -- SQLite with sqlite-vec extension for semantic search
14396
+
14397
+ -- PROJECTS (Spaces)
14398
+ CREATE TABLE IF NOT EXISTS projects (
14399
+ id TEXT PRIMARY KEY,
14400
+ name TEXT NOT NULL UNIQUE,
14401
+ description TEXT,
14402
+ icon TEXT DEFAULT '\u25C9',
14403
+ color TEXT DEFAULT '#6366f1',
14404
+ created_at INTEGER DEFAULT (unixepoch()),
14405
+ updated_at INTEGER DEFAULT (unixepoch()),
14406
+ owner TEXT DEFAULT 'human',
14407
+ metadata TEXT DEFAULT '{}'
14408
+ );
14409
+
14410
+ -- ATOMS (Ideas/Nodes)
14411
+ CREATE TABLE IF NOT EXISTS atoms (
14412
+ id TEXT PRIMARY KEY,
14413
+ project_id TEXT NOT NULL REFERENCES projects(id) ON DELETE CASCADE,
14414
+ parent_id TEXT REFERENCES atoms(id) ON DELETE CASCADE,
14415
+ title TEXT NOT NULL,
14416
+ summary TEXT,
14417
+ icon TEXT DEFAULT '\u25CF',
14418
+ color TEXT,
14419
+ x REAL,
14420
+ y REAL,
14421
+ auto_path TEXT,
14422
+ path_overridden INTEGER DEFAULT 0,
14423
+ status TEXT DEFAULT 'draft',
14424
+ status_updated_at INTEGER DEFAULT (unixepoch()),
14425
+ embedding_status TEXT DEFAULT 'pending',
14426
+ embedding_error TEXT,
14427
+ block_count INTEGER DEFAULT 0,
14428
+ bond_count INTEGER DEFAULT 0,
14429
+ template_id TEXT,
14430
+ created_at INTEGER DEFAULT (unixepoch()),
14431
+ updated_at INTEGER DEFAULT (unixepoch()),
14432
+ version INTEGER DEFAULT 1,
14433
+ locked_by TEXT,
14434
+ locked_at INTEGER,
14435
+ locked_reason TEXT,
14436
+ owner TEXT DEFAULT 'human',
14437
+ metadata TEXT DEFAULT '{}'
14438
+ );
14439
+
14440
+ -- BLOCKS (Content pieces inside atoms)
14441
+ CREATE TABLE IF NOT EXISTS blocks (
14442
+ id TEXT PRIMARY KEY,
14443
+ atom_id TEXT NOT NULL REFERENCES atoms(id) ON DELETE CASCADE,
14444
+ type TEXT NOT NULL DEFAULT 'text',
14445
+ content TEXT,
14446
+ order_index INTEGER DEFAULT 0,
14447
+ created_at INTEGER DEFAULT (unixepoch()),
14448
+ updated_at INTEGER DEFAULT (unixepoch()),
14449
+ metadata TEXT DEFAULT '{}'
14450
+ );
14451
+
14452
+ -- BONDS (Graph connections between atoms)
14453
+ CREATE TABLE IF NOT EXISTS bonds (
14454
+ id TEXT PRIMARY KEY,
14455
+ source_id TEXT NOT NULL REFERENCES atoms(id) ON DELETE CASCADE,
14456
+ target_id TEXT NOT NULL REFERENCES atoms(id) ON DELETE CASCADE,
14457
+ label TEXT DEFAULT 'connects',
14458
+ color TEXT,
14459
+ created_at INTEGER DEFAULT (unixepoch()),
14460
+ UNIQUE(source_id, target_id)
14461
+ );
14462
+
14463
+ -- ATTACHMENTS (Files in CAS)
14464
+ CREATE TABLE IF NOT EXISTS attachments (
14465
+ id TEXT PRIMARY KEY,
14466
+ block_id TEXT REFERENCES blocks(id) ON DELETE CASCADE,
14467
+ file_name TEXT NOT NULL,
14468
+ file_hash TEXT NOT NULL,
14469
+ file_size INTEGER,
14470
+ mime_type TEXT,
14471
+ created_at INTEGER DEFAULT (unixepoch()),
14472
+ UNIQUE(file_hash)
14473
+ );
14474
+
14475
+ -- EVENT LOG (Immutable audit trail)
14476
+ CREATE TABLE IF NOT EXISTS event_log (
14477
+ id TEXT PRIMARY KEY,
14478
+ timestamp INTEGER DEFAULT (unixepoch()),
14479
+ event_type TEXT NOT NULL,
14480
+ project_id TEXT,
14481
+ atom_id TEXT,
14482
+ block_id TEXT,
14483
+ bond_id TEXT,
14484
+ actor TEXT NOT NULL DEFAULT 'system',
14485
+ actor_type TEXT DEFAULT 'system',
14486
+ diff TEXT,
14487
+ trigger TEXT,
14488
+ metadata TEXT DEFAULT '{}'
14489
+ );
14490
+
14491
+ -- ASSISTANTS (AI Agents)
14492
+ CREATE TABLE IF NOT EXISTS assistants (
14493
+ id TEXT PRIMARY KEY,
14494
+ name TEXT NOT NULL,
14495
+ role TEXT DEFAULT 'worker',
14496
+ permissions TEXT DEFAULT '{"read":["*"],"write":[],"delete":false}',
14497
+ status TEXT DEFAULT 'active',
14498
+ provider TEXT,
14499
+ connected_at INTEGER DEFAULT (unixepoch()),
14500
+ last_seen INTEGER DEFAULT (unixepoch()),
14501
+ metadata TEXT DEFAULT '{}'
14502
+ );
14503
+
14504
+ -- QUEUE (Agent waitlist for locked atoms)
14505
+ CREATE TABLE IF NOT EXISTS queue (
14506
+ id TEXT PRIMARY KEY,
14507
+ atom_id TEXT NOT NULL REFERENCES atoms(id) ON DELETE CASCADE,
14508
+ assistant_id TEXT NOT NULL REFERENCES assistants(id) ON DELETE CASCADE,
14509
+ requested_at INTEGER DEFAULT (unixepoch()),
14510
+ priority INTEGER DEFAULT 5,
14511
+ status TEXT DEFAULT 'waiting',
14512
+ reason TEXT
14513
+ );
14514
+
14515
+ -- INDICES
14516
+ CREATE INDEX IF NOT EXISTS idx_atoms_project ON atoms(project_id);
14517
+ CREATE INDEX IF NOT EXISTS idx_atoms_parent ON atoms(parent_id);
14518
+ CREATE INDEX IF NOT EXISTS idx_atoms_locked ON atoms(locked_by) WHERE locked_by IS NOT NULL;
14519
+ -- idx_atoms_path_project is created by migration after auto_path column is added
14520
+ CREATE INDEX IF NOT EXISTS idx_blocks_atom ON blocks(atom_id);
14521
+ CREATE INDEX IF NOT EXISTS idx_bonds_source ON bonds(source_id);
14522
+ CREATE INDEX IF NOT EXISTS idx_bonds_target ON bonds(target_id);
14523
+ CREATE INDEX IF NOT EXISTS idx_event_log_time ON event_log(timestamp);
14524
+ CREATE INDEX IF NOT EXISTS idx_event_log_atom ON event_log(atom_id);
14525
+ CREATE INDEX IF NOT EXISTS idx_queue_atom ON queue(atom_id);
14526
+ CREATE INDEX IF NOT EXISTS idx_attachments_hash ON attachments(file_hash);
14527
+
14528
+ -- Auto-update block_count and bond_count triggers
14529
+ CREATE TRIGGER IF NOT EXISTS update_block_count_insert AFTER INSERT ON blocks BEGIN
14530
+ UPDATE atoms SET block_count = block_count + 1 WHERE id = NEW.atom_id;
14531
+ END;
14532
+
14533
+ CREATE TRIGGER IF NOT EXISTS update_block_count_delete AFTER DELETE ON blocks BEGIN
14534
+ UPDATE atoms SET block_count = block_count - 1 WHERE id = OLD.atom_id;
14535
+ END;
14536
+
14537
+ CREATE TRIGGER IF NOT EXISTS update_bond_count_insert AFTER INSERT ON bonds BEGIN
14538
+ UPDATE atoms SET bond_count = bond_count + 1 WHERE id = NEW.source_id OR id = NEW.target_id;
14539
+ END;
14540
+
14541
+ CREATE TRIGGER IF NOT EXISTS update_bond_count_delete AFTER DELETE ON bonds BEGIN
14542
+ UPDATE atoms SET bond_count = bond_count - 1 WHERE id = OLD.source_id OR id = OLD.target_id;
14543
+ END;
14544
+
14545
+ -- FTS5 FULL-TEXT SEARCH
14546
+ -- Separate tables to avoid rowid collisions between atoms and blocks
14547
+
14548
+ CREATE VIRTUAL TABLE IF NOT EXISTS search_atoms USING fts5(
14549
+ title, summary,
14550
+ content='atoms', content_rowid='rowid'
14551
+ );
14552
+
14553
+ CREATE VIRTUAL TABLE IF NOT EXISTS search_blocks USING fts5(
14554
+ content,
14555
+ content='blocks', content_rowid='rowid'
14556
+ );
14557
+
14558
+ -- Triggers to keep search_atoms in sync
14559
+ CREATE TRIGGER IF NOT EXISTS trig_search_atoms_insert AFTER INSERT ON atoms BEGIN
14560
+ INSERT INTO search_atoms(rowid, title, summary) VALUES (new.rowid, new.title, COALESCE(new.summary, ''));
14561
+ END;
14562
+
14563
+ CREATE TRIGGER IF NOT EXISTS trig_search_atoms_update AFTER UPDATE ON atoms BEGIN
14564
+ UPDATE search_atoms SET title = new.title, summary = COALESCE(new.summary, '') WHERE rowid = new.rowid;
14565
+ END;
14566
+
14567
+ CREATE TRIGGER IF NOT EXISTS trig_search_atoms_delete AFTER DELETE ON atoms BEGIN
14568
+ DELETE FROM search_atoms WHERE rowid = old.rowid;
14569
+ END;
14570
+
14571
+ -- Triggers to keep search_blocks in sync
14572
+ CREATE TRIGGER IF NOT EXISTS trig_search_blocks_insert AFTER INSERT ON blocks BEGIN
14573
+ INSERT INTO search_blocks(rowid, content) VALUES (new.rowid, COALESCE(new.content, ''));
14574
+ END;
14575
+
14576
+ CREATE TRIGGER IF NOT EXISTS trig_search_blocks_update AFTER UPDATE ON blocks BEGIN
14577
+ UPDATE search_blocks SET content = COALESCE(new.content, '') WHERE rowid = new.rowid;
14578
+ END;
14579
+
14580
+ CREATE TRIGGER IF NOT EXISTS trig_search_blocks_delete AFTER DELETE ON blocks BEGIN
14581
+ DELETE FROM search_blocks WHERE rowid = old.rowid;
14582
+ END;
14583
+
14584
+
14585
+ -- PER-ATOM PERMISSIONS (Granular access control)
14586
+ CREATE TABLE IF NOT EXISTS atom_permissions (
14587
+ id TEXT PRIMARY KEY,
14588
+ atom_id TEXT NOT NULL REFERENCES atoms(id) ON DELETE CASCADE,
14589
+ assistant_id TEXT NOT NULL REFERENCES assistants(id) ON DELETE CASCADE,
14590
+ level TEXT NOT NULL DEFAULT 'view',
14591
+ granted_by TEXT,
14592
+ granted_at INTEGER DEFAULT (unixepoch()),
14593
+ metadata TEXT DEFAULT '{}',
14594
+ UNIQUE(atom_id, assistant_id)
14595
+ );
14596
+
14597
+ -- sqlite-vec virtual table for semantic embeddings
14598
+ -- Created dynamically by connection.ts after loading the extension
14599
+ -- CREATE VIRTUAL TABLE IF NOT EXISTS atom_vectors USING vec0(atom_id TEXT PRIMARY KEY, embedding float[384]);
14600
+ `;
14601
+
14389
14602
  // src/core/Mnemosyne.ts
14390
14603
  var Mnemosyne = class {
14391
14604
  store;
@@ -14393,7 +14606,7 @@ var Mnemosyne = class {
14393
14606
  vecEnabled;
14394
14607
  db;
14395
14608
  constructor(options = {}) {
14396
- this.config = new MnemosyneConfig({ configPath: options.configPath });
14609
+ this.config = new MnemosyneConfig({ configPath: options.configPath, baseDir: options.baseDir });
14397
14610
  const cfg = this.config.config;
14398
14611
  const dbPath = options.dbPath || this.config.dbPath;
14399
14612
  this.db = new import_better_sqlite32.default(dbPath);
@@ -14402,17 +14615,15 @@ var Mnemosyne = class {
14402
14615
  this.db.pragma("synchronous = NORMAL");
14403
14616
  this.vecEnabled = false;
14404
14617
  try {
14405
- const vecPath = (0, import_path5.resolve)(process.cwd(), cfg.database.vec_extension_path);
14618
+ const vecPath = (0, import_path5.resolve)(this.config.baseDirPath || process.cwd(), cfg.database.vec_extension_path);
14406
14619
  this.db.loadExtension(vecPath);
14407
14620
  this.vecEnabled = true;
14408
14621
  console.log("[DB] sqlite-vec extension loaded");
14409
14622
  } catch (err) {
14410
14623
  console.warn("[DB] sqlite-vec not available:", err.message);
14411
14624
  }
14412
- const schemaPath = (0, import_path5.resolve)(process.cwd(), "src", "db", "schema.sql");
14413
14625
  try {
14414
- const schema = (0, import_fs5.readFileSync)(schemaPath, "utf-8");
14415
- this.db.exec(schema);
14626
+ this.db.exec(SCHEMA_SQL);
14416
14627
  } catch (err) {
14417
14628
  console.error("[DB] Failed to load schema:", err.message);
14418
14629
  }
@@ -14456,7 +14667,7 @@ var Mnemosyne = class {
14456
14667
 
14457
14668
  // src/server/MnemosyneServer.ts
14458
14669
  var import_http = require("http");
14459
- var import_fs8 = require("fs");
14670
+ var import_fs6 = require("fs");
14460
14671
  var import_path8 = require("path");
14461
14672
 
14462
14673
  // node_modules/ws/wrapper.mjs
@@ -15611,21 +15822,21 @@ function handleFiles(store, pathname, method, req, res, maxFileSizeMb) {
15611
15822
  // src/server/export-format.ts
15612
15823
  var import_adm_zip2 = __toESM(require("adm-zip"));
15613
15824
  var import_crypto2 = require("crypto");
15614
- var import_fs6 = require("fs");
15825
+ var import_fs5 = require("fs");
15615
15826
  var import_path6 = require("path");
15616
15827
  var DB_PATH = (0, import_path6.resolve)(process.cwd(), "data", "nexus.db");
15617
15828
  var FILES_DIR2 = (0, import_path6.resolve)(process.cwd(), "data", "files");
15618
15829
  function sha256File(path) {
15619
- return (0, import_crypto2.createHash)("sha256").update((0, import_fs6.readFileSync)(path)).digest("hex");
15830
+ return (0, import_crypto2.createHash)("sha256").update((0, import_fs5.readFileSync)(path)).digest("hex");
15620
15831
  }
15621
15832
  function sha256Dir(dir) {
15622
15833
  const hash = (0, import_crypto2.createHash)("sha256");
15623
15834
  function walk(p) {
15624
- const stat = (0, import_fs6.statSync)(p);
15835
+ const stat = (0, import_fs5.statSync)(p);
15625
15836
  if (stat.isFile()) {
15626
- hash.update((0, import_fs6.readFileSync)(p));
15837
+ hash.update((0, import_fs5.readFileSync)(p));
15627
15838
  } else if (stat.isDirectory()) {
15628
- for (const child of (0, import_fs6.readdirSync)(p).sort()) walk((0, import_path6.resolve)(p, child));
15839
+ for (const child of (0, import_fs5.readdirSync)(p).sort()) walk((0, import_path6.resolve)(p, child));
15629
15840
  }
15630
15841
  }
15631
15842
  walk(dir);
@@ -15634,11 +15845,11 @@ function sha256Dir(dir) {
15634
15845
  function buildMnemosyneExport(projectId, projectName) {
15635
15846
  const zip = new import_adm_zip2.default();
15636
15847
  zip.addLocalFile(DB_PATH, "", "nexus.db");
15637
- if ((0, import_fs6.existsSync)(FILES_DIR2)) {
15848
+ if ((0, import_fs5.existsSync)(FILES_DIR2)) {
15638
15849
  zip.addLocalFolder(FILES_DIR2, "files");
15639
15850
  }
15640
15851
  const dbChecksum = sha256File(DB_PATH);
15641
- const filesChecksum = (0, import_fs6.existsSync)(FILES_DIR2) ? sha256Dir(FILES_DIR2) : "";
15852
+ const filesChecksum = (0, import_fs5.existsSync)(FILES_DIR2) ? sha256Dir(FILES_DIR2) : "";
15642
15853
  const manifest = {
15643
15854
  version: "1.1",
15644
15855
  app: "Mnemosyne",
@@ -15994,7 +16205,6 @@ var WebSocketHandler = class {
15994
16205
 
15995
16206
  // src/db/connection.ts
15996
16207
  var import_better_sqlite33 = __toESM(require("better-sqlite3"));
15997
- var import_fs7 = require("fs");
15998
16208
  var import_path7 = require("path");
15999
16209
  init_config();
16000
16210
  var DB_PATH2 = process.env.MNEMOSYNE_DB_PATH || (0, import_path7.resolve)(process.cwd(), CONFIG.database.path);
@@ -16015,8 +16225,7 @@ function getDb() {
16015
16225
  console.warn("[DB] sqlite-vec not available:", err.message);
16016
16226
  vecEnabled = false;
16017
16227
  }
16018
- const schema = (0, import_fs7.readFileSync)((0, import_path7.resolve)(process.cwd(), "src", "db", "schema.sql"), "utf-8");
16019
- db.exec(schema);
16228
+ db.exec(SCHEMA_SQL);
16020
16229
  if (vecEnabled) {
16021
16230
  try {
16022
16231
  db.exec(`CREATE VIRTUAL TABLE IF NOT EXISTS atom_vectors USING vec0(atom_id TEXT PRIMARY KEY, embedding float[${CONFIG.embeddings.dimension}])`);
@@ -16115,8 +16324,8 @@ var MnemosyneServer = class {
16115
16324
  ];
16116
16325
  for (const dir of dirs) {
16117
16326
  const filePath = (0, import_path8.resolve)(dir, urlPath);
16118
- if ((0, import_fs8.existsSync)(filePath)) {
16119
- const data = (0, import_fs8.readFileSync)(filePath);
16327
+ if ((0, import_fs6.existsSync)(filePath)) {
16328
+ const data = (0, import_fs6.readFileSync)(filePath);
16120
16329
  res.writeHead(200, { "Content-Type": mime[ext] || "application/octet-stream" });
16121
16330
  res.end(data);
16122
16331
  return;
@@ -16138,7 +16347,7 @@ var MnemosyneServer = class {
16138
16347
  async function startCommand(options) {
16139
16348
  const dataDir = (0, import_path9.resolve)(options.dataDir);
16140
16349
  const dbPath = (0, import_path9.resolve)(dataDir, "nexus.db");
16141
- const brain = new Mnemosyne({ dbPath, configPath: options.config });
16350
+ const brain = new Mnemosyne({ dbPath, configPath: options.config, baseDir: dataDir });
16142
16351
  await brain.init();
16143
16352
  if (options.mcpTransport === "stdio" && options.mcp) {
16144
16353
  if (options.verbose) {
@@ -16182,7 +16391,7 @@ ${signal} received. Shutting down...`);
16182
16391
 
16183
16392
  // src/cli/commands/init.ts
16184
16393
  var import_path10 = require("path");
16185
- var import_fs9 = require("fs");
16394
+ var import_fs7 = require("fs");
16186
16395
  var DEFAULT_CONFIG = `database:
16187
16396
  path: ./data/nexus.db
16188
16397
  wal: true
@@ -16207,28 +16416,28 @@ server:
16207
16416
  async function initCommand(options) {
16208
16417
  const dataDir = (0, import_path10.resolve)(options.dataDir);
16209
16418
  const configPath = options.config ? (0, import_path10.resolve)(options.config) : (0, import_path10.resolve)(dataDir, "config.yaml");
16210
- if ((0, import_fs9.existsSync)(dataDir)) {
16419
+ if ((0, import_fs7.existsSync)(dataDir)) {
16211
16420
  console.log(`\u{1F4C1} Data directory already exists: ${dataDir}`);
16212
16421
  } else {
16213
- (0, import_fs9.mkdirSync)(dataDir, { recursive: true });
16422
+ (0, import_fs7.mkdirSync)(dataDir, { recursive: true });
16214
16423
  console.log(`\u2705 Created data directory: ${dataDir}`);
16215
16424
  }
16216
16425
  for (const sub of ["backups", "files", "exports"]) {
16217
16426
  const dir = (0, import_path10.resolve)(dataDir, sub);
16218
- if (!(0, import_fs9.existsSync)(dir)) {
16219
- (0, import_fs9.mkdirSync)(dir, { recursive: true });
16427
+ if (!(0, import_fs7.existsSync)(dir)) {
16428
+ (0, import_fs7.mkdirSync)(dir, { recursive: true });
16220
16429
  console.log(`\u2705 Created ${sub}/`);
16221
16430
  }
16222
16431
  }
16223
- if (!(0, import_fs9.existsSync)(configPath)) {
16224
- (0, import_fs9.writeFileSync)(configPath, DEFAULT_CONFIG, "utf-8");
16432
+ if (!(0, import_fs7.existsSync)(configPath)) {
16433
+ (0, import_fs7.writeFileSync)(configPath, DEFAULT_CONFIG, "utf-8");
16225
16434
  console.log(`\u2705 Created config: ${configPath}`);
16226
16435
  } else {
16227
16436
  console.log(`\u{1F4C4} Config already exists: ${configPath}`);
16228
16437
  }
16229
16438
  const dbPath = (0, import_path10.resolve)(dataDir, "nexus.db");
16230
- if (!(0, import_fs9.existsSync)(dbPath)) {
16231
- const brain = new Mnemosyne({ dbPath, configPath });
16439
+ if (!(0, import_fs7.existsSync)(dbPath)) {
16440
+ const brain = new Mnemosyne({ dbPath, configPath, baseDir: dataDir });
16232
16441
  await brain.init();
16233
16442
  await brain.close();
16234
16443
  console.log(`\u2705 Initialized database: ${dbPath}`);
@@ -16242,14 +16451,14 @@ async function initCommand(options) {
16242
16451
 
16243
16452
  // src/cli/commands/migrate.ts
16244
16453
  var import_path11 = require("path");
16245
- var import_fs10 = require("fs");
16454
+ var import_fs8 = require("fs");
16246
16455
  async function migrateCommand(options) {
16247
16456
  const fromPath = (0, import_path11.resolve)(options.from);
16248
16457
  const toPath = (0, import_path11.resolve)(options.to);
16249
16458
  console.log(`\u{1F504} Migrating v1.0 JSON \u2192 v2.0 SQLite`);
16250
16459
  console.log(` From: ${fromPath}`);
16251
16460
  console.log(` To: ${toPath}`);
16252
- const raw = (0, import_fs10.readFileSync)(fromPath, "utf-8");
16461
+ const raw = (0, import_fs8.readFileSync)(fromPath, "utf-8");
16253
16462
  const v1 = JSON.parse(raw);
16254
16463
  const brain = new Mnemosyne({ dbPath: toPath });
16255
16464
  await brain.init();
@@ -16300,7 +16509,7 @@ async function migrateCommand(options) {
16300
16509
 
16301
16510
  // src/cli/commands/export.ts
16302
16511
  var import_path12 = require("path");
16303
- var import_fs11 = require("fs");
16512
+ var import_fs9 = require("fs");
16304
16513
  async function exportCommand(options) {
16305
16514
  const dataDir = (0, import_path12.resolve)(options.dataDir || "./data");
16306
16515
  const format = options.format || "mnemosyne";
@@ -16316,12 +16525,12 @@ async function exportCommand(options) {
16316
16525
  if (format === "mnemosyne") {
16317
16526
  const buffer = buildMnemosyneExport(project.id, project.name);
16318
16527
  const outPath = output || (0, import_path12.resolve)(`${project.name}.mnemosyne`);
16319
- (0, import_fs11.writeFileSync)(outPath, buffer);
16528
+ (0, import_fs9.writeFileSync)(outPath, buffer);
16320
16529
  console.log(`\u2705 Exported to ${outPath} (${buffer.length} bytes)`);
16321
16530
  } else if (format === "markdown") {
16322
16531
  const md = exportMarkdown(brain.store, project.id);
16323
16532
  const outPath = output || (0, import_path12.resolve)(`${project.name}.md`);
16324
- (0, import_fs11.writeFileSync)(outPath, md, "utf-8");
16533
+ (0, import_fs9.writeFileSync)(outPath, md, "utf-8");
16325
16534
  console.log(`\u2705 Exported to ${outPath} (${md.length} chars)`);
16326
16535
  } else {
16327
16536
  console.error(`\u274C Unsupported format: ${format}`);