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.
- 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 +255 -46
- package/dist/cli/index.js.map +1 -1
- package/dist/cli/index.mjs +239 -30
- package/dist/cli/index.mjs.map +1 -1
- 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 +12962 -0
- package/dist/index.js.map +1 -0
- package/dist/index.mjs +12932 -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/index.d.mts +7 -110
- package/dist/server/index.d.ts +7 -110
- package/dist/server/index.js +221 -12
- package/dist/server/index.js.map +1 -1
- package/dist/server/index.mjs +220 -11
- 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 +11 -11
|
@@ -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
|
|
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
|
|
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
|
|
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:
|
|
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:
|
|
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 =
|
|
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 =
|
|
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 =
|
|
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)(
|
|
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.
|
|
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)(
|
|
14380
|
+
return (0, import_path4.resolve)(this.baseDir, this.config.database.path);
|
|
14380
14381
|
}
|
|
14381
14382
|
get filesDir() {
|
|
14382
|
-
return (0, import_path4.resolve)(
|
|
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)(
|
|
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
|
-
|
|
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
|
|
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
|
|
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,
|
|
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,
|
|
15835
|
+
const stat = (0, import_fs5.statSync)(p);
|
|
15625
15836
|
if (stat.isFile()) {
|
|
15626
|
-
hash.update((0,
|
|
15837
|
+
hash.update((0, import_fs5.readFileSync)(p));
|
|
15627
15838
|
} else if (stat.isDirectory()) {
|
|
15628
|
-
for (const child of (0,
|
|
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,
|
|
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,
|
|
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
|
-
|
|
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,
|
|
16119
|
-
const data = (0,
|
|
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
|
|
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,
|
|
16419
|
+
if ((0, import_fs7.existsSync)(dataDir)) {
|
|
16211
16420
|
console.log(`\u{1F4C1} Data directory already exists: ${dataDir}`);
|
|
16212
16421
|
} else {
|
|
16213
|
-
(0,
|
|
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,
|
|
16219
|
-
(0,
|
|
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,
|
|
16224
|
-
(0,
|
|
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,
|
|
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
|
|
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,
|
|
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
|
|
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,
|
|
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,
|
|
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}`);
|