memorix 1.9.4 → 1.9.5
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/CHANGELOG.md +33 -1
- package/README.md +6 -5
- package/README.zh-CN.md +6 -5
- package/dist/cli/index.js +890 -325
- package/dist/index.d.ts +3 -1
- package/dist/index.js +251 -104
- package/dist/maintenance-runner.js +144 -113
- package/dist/media-audio-runner.js +57 -26
- package/dist/media-video-runner.js +57 -26
- package/dist/memcode-runtime/CHANGELOG.md +33 -1
- package/dist/sdk.d.ts +1 -0
- package/dist/sdk.js +1012 -842
- package/dist/types.d.ts +1 -1
- package/dist/vector-backfill-runner.js +57 -26
- package/docs/AGENT_OPERATOR_PLAYBOOK.md +47 -3
- package/docs/API_REFERENCE.md +3 -1
- package/docs/CONFIGURATION.md +15 -1
- package/docs/DOCKER.md +23 -3
- package/docs/INTEGRATIONS.md +1 -1
- package/docs/KNOWN_ISSUES_AND_ROADMAP.md +26 -1
- package/docs/MULTI-DEVICE-SYNC-RESEARCH.md +4 -0
- package/docs/SETUP.md +55 -0
- package/package.json +2 -2
- package/plugins/antigravity/memorix/plugin.json +1 -1
- package/plugins/claude/memorix/.claude-plugin/plugin.json +1 -1
- package/plugins/codebuddy/memorix/.codebuddy-plugin/plugin.json +1 -1
- package/plugins/codex/memorix/.codex-plugin/plugin.json +1 -1
- package/plugins/copilot/memorix/plugin.json +1 -1
- package/plugins/gemini/memorix/gemini-extension.json +1 -1
- package/plugins/hermes/memorix/plugin.yaml +1 -1
- package/plugins/omp/memorix/package.json +1 -1
- package/plugins/openclaw/memorix/.codex-plugin/plugin.json +1 -1
- package/plugins/pi/memorix/package.json +1 -1
- package/server.json +2 -2
- package/src/cli/command-guide.ts +2 -2
- package/src/cli/commands/agent-integrations.ts +57 -0
- package/src/cli/commands/background.ts +11 -2
- package/src/cli/commands/serve-http.ts +193 -42
- package/src/cli/commands/setup.ts +77 -10
- package/src/cli/commands/sync-store.ts +47 -12
- package/src/cli/commands/sync.ts +26 -0
- package/src/dashboard/server.ts +10 -12
- package/src/integrations/registry.ts +1 -1
- package/src/memory/graph.ts +10 -8
- package/src/memory/session.ts +1 -1
- package/src/sdk.ts +24 -0
- package/src/server/mcp-binding-store.ts +14 -3
- package/src/server.ts +2 -2
- package/src/store/file-lock.ts +28 -3
- package/src/store/graph-store.ts +178 -46
- package/src/store/persistence.ts +14 -9
- package/src/store/sqlite-db.ts +6 -3
- package/src/store/sqlite-store.ts +32 -27
- package/src/sync/engine.ts +9 -7
- package/src/sync/namespace.ts +23 -0
- package/src/sync/policy.ts +19 -4
- package/src/sync/store-port.ts +43 -13
- package/src/sync/types.ts +2 -0
- package/src/types.ts +1 -1
- package/src/workspace/mcp-adapters/grok.ts +32 -0
package/dist/index.js
CHANGED
|
@@ -707,18 +707,21 @@ CREATE TABLE IF NOT EXISTS chat_transcript (
|
|
|
707
707
|
`;
|
|
708
708
|
CREATE_GRAPH_ENTITIES_TABLE = `
|
|
709
709
|
CREATE TABLE IF NOT EXISTS graph_entities (
|
|
710
|
-
|
|
710
|
+
projectId TEXT NOT NULL,
|
|
711
|
+
name TEXT NOT NULL,
|
|
711
712
|
entityType TEXT NOT NULL DEFAULT '',
|
|
712
|
-
observations TEXT NOT NULL DEFAULT '[]'
|
|
713
|
+
observations TEXT NOT NULL DEFAULT '[]',
|
|
714
|
+
PRIMARY KEY (projectId, name)
|
|
713
715
|
);
|
|
714
716
|
`;
|
|
715
717
|
CREATE_GRAPH_RELATIONS_TABLE = `
|
|
716
718
|
CREATE TABLE IF NOT EXISTS graph_relations (
|
|
717
719
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
720
|
+
projectId TEXT NOT NULL,
|
|
718
721
|
from_entity TEXT NOT NULL,
|
|
719
722
|
to_entity TEXT NOT NULL,
|
|
720
723
|
relationType TEXT NOT NULL DEFAULT '',
|
|
721
|
-
UNIQUE(from_entity, to_entity, relationType)
|
|
724
|
+
UNIQUE(projectId, from_entity, to_entity, relationType)
|
|
722
725
|
);
|
|
723
726
|
`;
|
|
724
727
|
CREATE_CODE_FILES_TABLE = `
|
|
@@ -1518,6 +1521,21 @@ CREATE UNIQUE INDEX IF NOT EXISTS idx_maintenance_jobs_active_dedupe
|
|
|
1518
1521
|
import { promises as fs2 } from "fs";
|
|
1519
1522
|
import { randomUUID } from "crypto";
|
|
1520
1523
|
import path4 from "path";
|
|
1524
|
+
function canReclaimStaleLock(raw) {
|
|
1525
|
+
try {
|
|
1526
|
+
const parsed = JSON.parse(raw);
|
|
1527
|
+
const pid = Number(parsed.pid);
|
|
1528
|
+
if (!Number.isSafeInteger(pid) || pid < 1) return true;
|
|
1529
|
+
try {
|
|
1530
|
+
process.kill(pid, 0);
|
|
1531
|
+
return false;
|
|
1532
|
+
} catch (error) {
|
|
1533
|
+
return error.code !== "EPERM";
|
|
1534
|
+
}
|
|
1535
|
+
} catch {
|
|
1536
|
+
return true;
|
|
1537
|
+
}
|
|
1538
|
+
}
|
|
1521
1539
|
async function acquireLock(lockPath) {
|
|
1522
1540
|
for (let i2 = 0; i2 < MAX_RETRIES; i2++) {
|
|
1523
1541
|
try {
|
|
@@ -1531,9 +1549,12 @@ async function acquireLock(lockPath) {
|
|
|
1531
1549
|
try {
|
|
1532
1550
|
const stat5 = await fs2.stat(lockPath);
|
|
1533
1551
|
if (Date.now() - stat5.mtimeMs > LOCK_STALE_MS) {
|
|
1534
|
-
await fs2.
|
|
1535
|
-
|
|
1536
|
-
|
|
1552
|
+
const raw2 = await fs2.readFile(lockPath, "utf8").catch(() => "");
|
|
1553
|
+
if (canReclaimStaleLock(raw2)) {
|
|
1554
|
+
await fs2.unlink(lockPath).catch(() => {
|
|
1555
|
+
});
|
|
1556
|
+
continue;
|
|
1557
|
+
}
|
|
1537
1558
|
}
|
|
1538
1559
|
} catch {
|
|
1539
1560
|
continue;
|
|
@@ -1544,6 +1565,10 @@ async function acquireLock(lockPath) {
|
|
|
1544
1565
|
}
|
|
1545
1566
|
}
|
|
1546
1567
|
}
|
|
1568
|
+
const raw = await fs2.readFile(lockPath, "utf8").catch(() => "");
|
|
1569
|
+
if (!canReclaimStaleLock(raw)) {
|
|
1570
|
+
throw new Error(`Failed to acquire lock: ${lockPath} (owner is still running)`);
|
|
1571
|
+
}
|
|
1547
1572
|
await fs2.unlink(lockPath).catch(() => {
|
|
1548
1573
|
});
|
|
1549
1574
|
try {
|
|
@@ -1782,6 +1807,11 @@ async function listProjectDirs(baseDir) {
|
|
|
1782
1807
|
}
|
|
1783
1808
|
}
|
|
1784
1809
|
async function migrateSubdirsToFlat(baseDir) {
|
|
1810
|
+
const base = baseDir ?? resolveDefaultDataDir();
|
|
1811
|
+
await fs4.mkdir(base, { recursive: true });
|
|
1812
|
+
return withFileLock(base, () => migrateSubdirsToFlatUnlocked(base));
|
|
1813
|
+
}
|
|
1814
|
+
async function migrateSubdirsToFlatUnlocked(baseDir) {
|
|
1785
1815
|
const base = baseDir ?? resolveDefaultDataDir();
|
|
1786
1816
|
await fs4.mkdir(base, { recursive: true });
|
|
1787
1817
|
let entries;
|
|
@@ -1838,7 +1868,7 @@ async function migrateSubdirsToFlat(baseDir) {
|
|
|
1838
1868
|
for (const { obs } of subdirData) {
|
|
1839
1869
|
for (const o of obs) {
|
|
1840
1870
|
const isDuplicate = allObs.some(
|
|
1841
|
-
(existing) => existing.title === o.title && existing.createdAt === o.createdAt
|
|
1871
|
+
(existing) => existing.title === o.title && existing.createdAt === o.createdAt && existing.projectId === o.projectId
|
|
1842
1872
|
);
|
|
1843
1873
|
if (!isDuplicate) {
|
|
1844
1874
|
allObs.push(o);
|
|
@@ -1871,18 +1901,14 @@ async function migrateSubdirsToFlat(baseDir) {
|
|
|
1871
1901
|
mergedRelations.push(rel);
|
|
1872
1902
|
}
|
|
1873
1903
|
}
|
|
1874
|
-
await
|
|
1875
|
-
await
|
|
1876
|
-
path6.join(base, "counter.json"),
|
|
1877
|
-
JSON.stringify({ nextId: allObs.length + 1 }),
|
|
1878
|
-
"utf-8"
|
|
1879
|
-
);
|
|
1904
|
+
await atomicWriteFile(path6.join(base, "observations.json"), JSON.stringify(allObs, null, 2));
|
|
1905
|
+
await atomicWriteFile(path6.join(base, "counter.json"), JSON.stringify({ nextId: allObs.length + 1 }));
|
|
1880
1906
|
const graphLines = [
|
|
1881
1907
|
...[...entityMap.values()].map((e2) => JSON.stringify({ type: "entity", name: e2.name, entityType: e2.entityType, observations: e2.observations })),
|
|
1882
1908
|
...mergedRelations.map((r2) => JSON.stringify({ type: "relation", from: r2.from, to: r2.to, relationType: r2.relationType }))
|
|
1883
1909
|
];
|
|
1884
1910
|
if (graphLines.length > 0) {
|
|
1885
|
-
await
|
|
1911
|
+
await atomicWriteFile(path6.join(base, "graph.jsonl"), graphLines.join("\n"));
|
|
1886
1912
|
}
|
|
1887
1913
|
let allSessions = [];
|
|
1888
1914
|
try {
|
|
@@ -1900,7 +1926,7 @@ async function migrateSubdirsToFlat(baseDir) {
|
|
|
1900
1926
|
}
|
|
1901
1927
|
}
|
|
1902
1928
|
if (allSessions.length > 0) {
|
|
1903
|
-
await
|
|
1929
|
+
await atomicWriteFile(path6.join(base, "sessions.json"), JSON.stringify(allSessions, null, 2));
|
|
1904
1930
|
}
|
|
1905
1931
|
const backupDir = path6.join(base, ".migrated-subdirs");
|
|
1906
1932
|
await fs4.mkdir(backupDir, { recursive: true });
|
|
@@ -1936,6 +1962,7 @@ var init_persistence = __esm({
|
|
|
1936
1962
|
"src/store/persistence.ts"() {
|
|
1937
1963
|
"use strict";
|
|
1938
1964
|
init_esm_shims();
|
|
1965
|
+
init_file_lock();
|
|
1939
1966
|
init_persistence_json();
|
|
1940
1967
|
}
|
|
1941
1968
|
});
|
|
@@ -1943,6 +1970,7 @@ var init_persistence = __esm({
|
|
|
1943
1970
|
// src/store/graph-store.ts
|
|
1944
1971
|
var graph_store_exports = {};
|
|
1945
1972
|
__export(graph_store_exports, {
|
|
1973
|
+
DEFAULT_GRAPH_PROJECT_ID: () => DEFAULT_GRAPH_PROJECT_ID,
|
|
1946
1974
|
GraphSqliteStore: () => GraphSqliteStore,
|
|
1947
1975
|
getGraphStore: () => getGraphStore,
|
|
1948
1976
|
initGraphStore: () => initGraphStore,
|
|
@@ -1972,37 +2000,106 @@ function entityToRow(entity) {
|
|
|
1972
2000
|
observations: JSON.stringify(entity.observations ?? [])
|
|
1973
2001
|
};
|
|
1974
2002
|
}
|
|
1975
|
-
|
|
1976
|
-
|
|
1977
|
-
|
|
1978
|
-
|
|
1979
|
-
|
|
1980
|
-
|
|
2003
|
+
function ensureScopedGraphSchema(db2) {
|
|
2004
|
+
const entityColumns = db2.prepare("PRAGMA table_info(graph_entities)").all();
|
|
2005
|
+
if (!entityColumns.some((column) => column.name === "projectId")) {
|
|
2006
|
+
const migrate = db2.transaction(() => {
|
|
2007
|
+
db2.exec("ALTER TABLE graph_entities RENAME TO graph_entities_legacy_unscoped");
|
|
2008
|
+
db2.exec(CREATE_SCOPED_GRAPH_ENTITIES);
|
|
2009
|
+
db2.exec(`INSERT INTO graph_entities (projectId, name, entityType, observations)
|
|
2010
|
+
SELECT '${LEGACY_GRAPH_PROJECT_ID}', name, entityType, observations
|
|
2011
|
+
FROM graph_entities_legacy_unscoped`);
|
|
2012
|
+
db2.exec("DROP TABLE graph_entities_legacy_unscoped");
|
|
2013
|
+
});
|
|
2014
|
+
migrate();
|
|
2015
|
+
} else {
|
|
2016
|
+
db2.exec(CREATE_SCOPED_GRAPH_ENTITIES);
|
|
2017
|
+
}
|
|
2018
|
+
const relationColumns = db2.prepare("PRAGMA table_info(graph_relations)").all();
|
|
2019
|
+
if (!relationColumns.some((column) => column.name === "projectId")) {
|
|
2020
|
+
const migrate = db2.transaction(() => {
|
|
2021
|
+
db2.exec("ALTER TABLE graph_relations RENAME TO graph_relations_legacy_unscoped");
|
|
2022
|
+
db2.exec(CREATE_SCOPED_GRAPH_RELATIONS);
|
|
2023
|
+
db2.exec(`INSERT INTO graph_relations (projectId, from_entity, to_entity, relationType)
|
|
2024
|
+
SELECT '${LEGACY_GRAPH_PROJECT_ID}', from_entity, to_entity, relationType
|
|
2025
|
+
FROM graph_relations_legacy_unscoped`);
|
|
2026
|
+
db2.exec("DROP TABLE graph_relations_legacy_unscoped");
|
|
2027
|
+
});
|
|
2028
|
+
migrate();
|
|
2029
|
+
} else {
|
|
2030
|
+
db2.exec(CREATE_SCOPED_GRAPH_RELATIONS);
|
|
2031
|
+
}
|
|
2032
|
+
}
|
|
2033
|
+
function graphStoreKey(dataDir, projectId) {
|
|
2034
|
+
return `${path7.resolve(dataDir)}\0${projectId}`;
|
|
1981
2035
|
}
|
|
1982
|
-
function
|
|
1983
|
-
|
|
1984
|
-
|
|
2036
|
+
async function initGraphStore(dataDir, projectId = DEFAULT_GRAPH_PROJECT_ID) {
|
|
2037
|
+
const key = graphStoreKey(dataDir, projectId);
|
|
2038
|
+
const existing = _graphStores.get(key);
|
|
2039
|
+
if (existing) {
|
|
2040
|
+
_graphStores.delete(key);
|
|
2041
|
+
_graphStores.set(key, existing);
|
|
2042
|
+
_activeGraphKey = key;
|
|
2043
|
+
return existing;
|
|
2044
|
+
}
|
|
2045
|
+
const store = new GraphSqliteStore();
|
|
2046
|
+
await store.init(dataDir, projectId);
|
|
2047
|
+
_graphStores.set(key, store);
|
|
2048
|
+
while (_graphStores.size > MAX_GRAPH_STORE_CACHE) {
|
|
2049
|
+
const oldest = _graphStores.keys().next().value;
|
|
2050
|
+
if (!oldest) break;
|
|
2051
|
+
_graphStores.delete(oldest);
|
|
2052
|
+
}
|
|
2053
|
+
_activeGraphKey = key;
|
|
2054
|
+
return store;
|
|
2055
|
+
}
|
|
2056
|
+
function getGraphStore(dataDir, projectId) {
|
|
2057
|
+
const key = dataDir && projectId ? graphStoreKey(dataDir, projectId) : _activeGraphKey;
|
|
2058
|
+
const store = key ? _graphStores.get(key) : void 0;
|
|
2059
|
+
if (!store) throw new Error("[memorix] GraphStore not initialized \u2014 call initGraphStore() first");
|
|
2060
|
+
return store;
|
|
1985
2061
|
}
|
|
1986
2062
|
function resetGraphStore() {
|
|
1987
|
-
|
|
2063
|
+
for (const store of _graphStores.values()) {
|
|
1988
2064
|
try {
|
|
1989
|
-
|
|
2065
|
+
store.close();
|
|
1990
2066
|
} catch {
|
|
1991
2067
|
}
|
|
1992
2068
|
}
|
|
1993
|
-
|
|
1994
|
-
|
|
2069
|
+
_graphStores.clear();
|
|
2070
|
+
_activeGraphKey = null;
|
|
1995
2071
|
}
|
|
1996
|
-
var GraphSqliteStore,
|
|
2072
|
+
var DEFAULT_GRAPH_PROJECT_ID, LEGACY_GRAPH_PROJECT_ID, MAX_GRAPH_STORE_CACHE, CREATE_SCOPED_GRAPH_ENTITIES, CREATE_SCOPED_GRAPH_RELATIONS, GraphSqliteStore, _graphStores, _activeGraphKey;
|
|
1997
2073
|
var init_graph_store = __esm({
|
|
1998
2074
|
"src/store/graph-store.ts"() {
|
|
1999
2075
|
"use strict";
|
|
2000
2076
|
init_esm_shims();
|
|
2001
2077
|
init_sqlite_db();
|
|
2002
2078
|
init_persistence();
|
|
2079
|
+
DEFAULT_GRAPH_PROJECT_ID = "__default__";
|
|
2080
|
+
LEGACY_GRAPH_PROJECT_ID = "__legacy__";
|
|
2081
|
+
MAX_GRAPH_STORE_CACHE = 32;
|
|
2082
|
+
CREATE_SCOPED_GRAPH_ENTITIES = `
|
|
2083
|
+
CREATE TABLE IF NOT EXISTS graph_entities (
|
|
2084
|
+
projectId TEXT NOT NULL,
|
|
2085
|
+
name TEXT NOT NULL,
|
|
2086
|
+
entityType TEXT NOT NULL DEFAULT '',
|
|
2087
|
+
observations TEXT NOT NULL DEFAULT '[]',
|
|
2088
|
+
PRIMARY KEY (projectId, name)
|
|
2089
|
+
);`;
|
|
2090
|
+
CREATE_SCOPED_GRAPH_RELATIONS = `
|
|
2091
|
+
CREATE TABLE IF NOT EXISTS graph_relations (
|
|
2092
|
+
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
2093
|
+
projectId TEXT NOT NULL,
|
|
2094
|
+
from_entity TEXT NOT NULL,
|
|
2095
|
+
to_entity TEXT NOT NULL,
|
|
2096
|
+
relationType TEXT NOT NULL DEFAULT '',
|
|
2097
|
+
UNIQUE(projectId, from_entity, to_entity, relationType)
|
|
2098
|
+
);`;
|
|
2003
2099
|
GraphSqliteStore = class {
|
|
2004
2100
|
db = null;
|
|
2005
2101
|
dataDir = "";
|
|
2102
|
+
projectId = DEFAULT_GRAPH_PROJECT_ID;
|
|
2006
2103
|
stmtInsertEntity = null;
|
|
2007
2104
|
stmtUpdateEntityObs = null;
|
|
2008
2105
|
stmtDeleteEntity = null;
|
|
@@ -2012,45 +2109,89 @@ var init_graph_store = __esm({
|
|
|
2012
2109
|
stmtDeleteRelation = null;
|
|
2013
2110
|
stmtDeleteRelationsByEntity = null;
|
|
2014
2111
|
stmtSelectAllRelations = null;
|
|
2015
|
-
async init(dataDir) {
|
|
2112
|
+
async init(dataDir, projectId = DEFAULT_GRAPH_PROJECT_ID) {
|
|
2016
2113
|
this.dataDir = dataDir;
|
|
2114
|
+
this.projectId = projectId;
|
|
2017
2115
|
this.db = getDatabase(dataDir);
|
|
2116
|
+
ensureScopedGraphSchema(this.db);
|
|
2018
2117
|
this.stmtInsertEntity = this.db.prepare(
|
|
2019
|
-
`INSERT OR REPLACE INTO graph_entities (name, entityType, observations) VALUES (@name, @entityType, @observations)`
|
|
2118
|
+
`INSERT OR REPLACE INTO graph_entities (projectId, name, entityType, observations) VALUES (@projectId, @name, @entityType, @observations)`
|
|
2020
2119
|
);
|
|
2021
2120
|
this.stmtUpdateEntityObs = this.db.prepare(
|
|
2022
|
-
`UPDATE graph_entities SET observations = @observations WHERE name = @name`
|
|
2121
|
+
`UPDATE graph_entities SET observations = @observations WHERE projectId = @projectId AND name = @name`
|
|
2023
2122
|
);
|
|
2024
|
-
this.stmtDeleteEntity = this.db.prepare(`DELETE FROM graph_entities WHERE name = ?`);
|
|
2025
|
-
this.stmtSelectAllEntities = this.db.prepare(`SELECT * FROM graph_entities`);
|
|
2026
|
-
this.stmtSelectEntityByName = this.db.prepare(`SELECT * FROM graph_entities WHERE name = ?`);
|
|
2123
|
+
this.stmtDeleteEntity = this.db.prepare(`DELETE FROM graph_entities WHERE projectId = ? AND name = ?`);
|
|
2124
|
+
this.stmtSelectAllEntities = this.db.prepare(`SELECT * FROM graph_entities WHERE projectId = ? ORDER BY name`);
|
|
2125
|
+
this.stmtSelectEntityByName = this.db.prepare(`SELECT * FROM graph_entities WHERE projectId = ? AND name = ?`);
|
|
2027
2126
|
this.stmtInsertRelation = this.db.prepare(
|
|
2028
|
-
`INSERT OR IGNORE INTO graph_relations (from_entity, to_entity, relationType) VALUES (@from, @to, @relationType)`
|
|
2127
|
+
`INSERT OR IGNORE INTO graph_relations (projectId, from_entity, to_entity, relationType) VALUES (@projectId, @from, @to, @relationType)`
|
|
2029
2128
|
);
|
|
2030
2129
|
this.stmtDeleteRelation = this.db.prepare(
|
|
2031
|
-
`DELETE FROM graph_relations WHERE from_entity = ? AND to_entity = ? AND relationType = ?`
|
|
2130
|
+
`DELETE FROM graph_relations WHERE projectId = ? AND from_entity = ? AND to_entity = ? AND relationType = ?`
|
|
2032
2131
|
);
|
|
2033
2132
|
this.stmtDeleteRelationsByEntity = this.db.prepare(
|
|
2034
|
-
`DELETE FROM graph_relations WHERE from_entity = ? OR to_entity =
|
|
2133
|
+
`DELETE FROM graph_relations WHERE projectId = ? AND (from_entity = ? OR to_entity = ?)`
|
|
2035
2134
|
);
|
|
2036
|
-
this.stmtSelectAllRelations = this.db.prepare(`SELECT * FROM graph_relations`);
|
|
2135
|
+
this.stmtSelectAllRelations = this.db.prepare(`SELECT * FROM graph_relations WHERE projectId = ? ORDER BY id`);
|
|
2037
2136
|
await this.migrateFromJsonlIfNeeded();
|
|
2038
2137
|
}
|
|
2039
2138
|
async migrateFromJsonlIfNeeded() {
|
|
2040
|
-
const count2 = this.db.prepare(`SELECT COUNT(*) AS cnt FROM graph_entities
|
|
2139
|
+
const count2 = this.db.prepare(`SELECT COUNT(*) AS cnt FROM graph_entities WHERE projectId = ?`).get(this.projectId);
|
|
2140
|
+
const totalCount = this.db.prepare(`SELECT COUNT(*) AS cnt FROM graph_entities`).get();
|
|
2041
2141
|
if (count2.cnt > 0) return;
|
|
2142
|
+
if (totalCount.cnt > 0) return;
|
|
2042
2143
|
const jsonlPath = path7.join(this.dataDir, "graph.jsonl");
|
|
2043
2144
|
if (!fs5.existsSync(jsonlPath)) return;
|
|
2044
2145
|
try {
|
|
2045
2146
|
const data = await loadGraphJsonl(this.dataDir);
|
|
2046
2147
|
if (data.entities.length === 0 && data.relations.length === 0) return;
|
|
2047
2148
|
console.error(`[memorix] Migrating graph from JSONL to SQLite (${data.entities.length} entities, ${data.relations.length} relations)...`);
|
|
2149
|
+
const observations2 = this.db.prepare("SELECT id, projectId FROM observations").all();
|
|
2150
|
+
const projectByObservationId = new Map(observations2.map((row) => [row.id, row.projectId]));
|
|
2151
|
+
const projectsByEntity = /* @__PURE__ */ new Map();
|
|
2152
|
+
for (const entity of data.entities) {
|
|
2153
|
+
const projects = /* @__PURE__ */ new Set();
|
|
2154
|
+
for (const content of entity.observations ?? []) {
|
|
2155
|
+
const match2 = /^\[#(\d+)\]/.exec(content);
|
|
2156
|
+
const projectId = match2 ? projectByObservationId.get(Number(match2[1])) : void 0;
|
|
2157
|
+
if (projectId) projects.add(projectId);
|
|
2158
|
+
}
|
|
2159
|
+
projectsByEntity.set(entity.name, projects);
|
|
2160
|
+
}
|
|
2161
|
+
let changed = true;
|
|
2162
|
+
while (changed) {
|
|
2163
|
+
changed = false;
|
|
2164
|
+
for (const relation of data.relations) {
|
|
2165
|
+
const from = projectsByEntity.get(relation.from) ?? /* @__PURE__ */ new Set();
|
|
2166
|
+
const to = projectsByEntity.get(relation.to) ?? /* @__PURE__ */ new Set();
|
|
2167
|
+
if (from.size > 0 && to.size === 0) {
|
|
2168
|
+
projectsByEntity.set(relation.to, new Set(from));
|
|
2169
|
+
changed = true;
|
|
2170
|
+
} else if (to.size > 0 && from.size === 0) {
|
|
2171
|
+
projectsByEntity.set(relation.from, new Set(to));
|
|
2172
|
+
changed = true;
|
|
2173
|
+
}
|
|
2174
|
+
}
|
|
2175
|
+
}
|
|
2176
|
+
const entityRows = data.entities.flatMap((entity) => {
|
|
2177
|
+
const projects = projectsByEntity.get(entity.name) ?? /* @__PURE__ */ new Set();
|
|
2178
|
+
const owners = projects.size > 0 ? [...projects] : [this.projectId];
|
|
2179
|
+
return owners.map((projectId) => ({ ...entityToRow(entity), projectId }));
|
|
2180
|
+
});
|
|
2181
|
+
const projectSet = new Set(entityRows.map((row) => String(row.projectId)));
|
|
2182
|
+
const relationRows = data.relations.flatMap((relation) => {
|
|
2183
|
+
const from = projectsByEntity.get(relation.from) ?? /* @__PURE__ */ new Set();
|
|
2184
|
+
const to = projectsByEntity.get(relation.to) ?? /* @__PURE__ */ new Set();
|
|
2185
|
+
const shared = [...from].filter((projectId) => to.has(projectId));
|
|
2186
|
+
const owners = shared.length > 0 ? shared : from.size === 0 && to.size === 0 ? [this.projectId] : [];
|
|
2187
|
+
return owners.filter((projectId) => projectSet.has(projectId)).map((projectId) => ({ projectId, from: relation.from, to: relation.to, relationType: relation.relationType }));
|
|
2188
|
+
});
|
|
2048
2189
|
const insertAll = this.db.transaction(() => {
|
|
2049
|
-
for (const entity of
|
|
2050
|
-
this.stmtInsertEntity.run(
|
|
2190
|
+
for (const entity of entityRows) {
|
|
2191
|
+
this.stmtInsertEntity.run(entity);
|
|
2051
2192
|
}
|
|
2052
|
-
for (const
|
|
2053
|
-
this.stmtInsertRelation.run(
|
|
2193
|
+
for (const relation of relationRows) {
|
|
2194
|
+
this.stmtInsertRelation.run(relation);
|
|
2054
2195
|
}
|
|
2055
2196
|
});
|
|
2056
2197
|
insertAll();
|
|
@@ -2060,10 +2201,10 @@ var init_graph_store = __esm({
|
|
|
2060
2201
|
}
|
|
2061
2202
|
}
|
|
2062
2203
|
loadEntities() {
|
|
2063
|
-
return this.stmtSelectAllEntities.all().map(rowToEntity);
|
|
2204
|
+
return this.stmtSelectAllEntities.all(this.projectId).map(rowToEntity);
|
|
2064
2205
|
}
|
|
2065
2206
|
loadRelations() {
|
|
2066
|
-
return this.stmtSelectAllRelations.all().map((row) => ({
|
|
2207
|
+
return this.stmtSelectAllRelations.all(this.projectId).map((row) => ({
|
|
2067
2208
|
from: row.from_entity,
|
|
2068
2209
|
to: row.to_entity,
|
|
2069
2210
|
relationType: row.relationType
|
|
@@ -2072,7 +2213,7 @@ var init_graph_store = __esm({
|
|
|
2072
2213
|
insertEntities(entities) {
|
|
2073
2214
|
const insertAll = this.db.transaction(() => {
|
|
2074
2215
|
for (const entity of entities) {
|
|
2075
|
-
this.stmtInsertEntity.run(entityToRow(entity));
|
|
2216
|
+
this.stmtInsertEntity.run({ ...entityToRow(entity), projectId: this.projectId });
|
|
2076
2217
|
}
|
|
2077
2218
|
});
|
|
2078
2219
|
insertAll();
|
|
@@ -2080,7 +2221,7 @@ var init_graph_store = __esm({
|
|
|
2080
2221
|
insertRelations(relations) {
|
|
2081
2222
|
const insertAll = this.db.transaction(() => {
|
|
2082
2223
|
for (const rel of relations) {
|
|
2083
|
-
this.stmtInsertRelation.run({ from: rel.from, to: rel.to, relationType: rel.relationType });
|
|
2224
|
+
this.stmtInsertRelation.run({ projectId: this.projectId, from: rel.from, to: rel.to, relationType: rel.relationType });
|
|
2084
2225
|
}
|
|
2085
2226
|
});
|
|
2086
2227
|
insertAll();
|
|
@@ -2088,8 +2229,8 @@ var init_graph_store = __esm({
|
|
|
2088
2229
|
deleteEntities(names) {
|
|
2089
2230
|
const deleteAll = this.db.transaction(() => {
|
|
2090
2231
|
for (const name of names) {
|
|
2091
|
-
this.stmtDeleteRelationsByEntity.run(name, name);
|
|
2092
|
-
this.stmtDeleteEntity.run(name);
|
|
2232
|
+
this.stmtDeleteRelationsByEntity.run(this.projectId, name, name);
|
|
2233
|
+
this.stmtDeleteEntity.run(this.projectId, name);
|
|
2093
2234
|
}
|
|
2094
2235
|
});
|
|
2095
2236
|
deleteAll();
|
|
@@ -2097,7 +2238,7 @@ var init_graph_store = __esm({
|
|
|
2097
2238
|
deleteRelations(relations) {
|
|
2098
2239
|
const deleteAll = this.db.transaction(() => {
|
|
2099
2240
|
for (const rel of relations) {
|
|
2100
|
-
this.stmtDeleteRelation.run(rel.from, rel.to, rel.relationType);
|
|
2241
|
+
this.stmtDeleteRelation.run(this.projectId, rel.from, rel.to, rel.relationType);
|
|
2101
2242
|
}
|
|
2102
2243
|
});
|
|
2103
2244
|
deleteAll();
|
|
@@ -2105,13 +2246,13 @@ var init_graph_store = __esm({
|
|
|
2105
2246
|
addObservations(updates) {
|
|
2106
2247
|
const updateAll = this.db.transaction(() => {
|
|
2107
2248
|
for (const u of updates) {
|
|
2108
|
-
const row = this.stmtSelectEntityByName.get(u.entityName);
|
|
2249
|
+
const row = this.stmtSelectEntityByName.get(this.projectId, u.entityName);
|
|
2109
2250
|
if (!row) continue;
|
|
2110
2251
|
const existing = safeJsonParse(row.observations, []);
|
|
2111
2252
|
const newObs = u.contents.filter((c) => !existing.includes(c));
|
|
2112
2253
|
if (newObs.length > 0) {
|
|
2113
2254
|
existing.push(...newObs);
|
|
2114
|
-
this.stmtUpdateEntityObs.run({ name: u.entityName, observations: JSON.stringify(existing) });
|
|
2255
|
+
this.stmtUpdateEntityObs.run({ projectId: this.projectId, name: u.entityName, observations: JSON.stringify(existing) });
|
|
2115
2256
|
}
|
|
2116
2257
|
}
|
|
2117
2258
|
});
|
|
@@ -2120,11 +2261,11 @@ var init_graph_store = __esm({
|
|
|
2120
2261
|
deleteObservations(deletions) {
|
|
2121
2262
|
const deleteAll = this.db.transaction(() => {
|
|
2122
2263
|
for (const d of deletions) {
|
|
2123
|
-
const row = this.stmtSelectEntityByName.get(d.entityName);
|
|
2264
|
+
const row = this.stmtSelectEntityByName.get(this.projectId, d.entityName);
|
|
2124
2265
|
if (!row) continue;
|
|
2125
2266
|
const existing = safeJsonParse(row.observations, []);
|
|
2126
2267
|
const filtered = existing.filter((o) => !d.observations.includes(o));
|
|
2127
|
-
this.stmtUpdateEntityObs.run({ name: d.entityName, observations: JSON.stringify(filtered) });
|
|
2268
|
+
this.stmtUpdateEntityObs.run({ projectId: this.projectId, name: d.entityName, observations: JSON.stringify(filtered) });
|
|
2128
2269
|
}
|
|
2129
2270
|
});
|
|
2130
2271
|
deleteAll();
|
|
@@ -2135,13 +2276,13 @@ var init_graph_store = __esm({
|
|
|
2135
2276
|
*/
|
|
2136
2277
|
replaceAll(entities, relations) {
|
|
2137
2278
|
const replaceAll = this.db.transaction(() => {
|
|
2138
|
-
this.db.prepare("DELETE FROM graph_relations").run();
|
|
2139
|
-
this.db.prepare("DELETE FROM graph_entities").run();
|
|
2279
|
+
this.db.prepare("DELETE FROM graph_relations WHERE projectId = ?").run(this.projectId);
|
|
2280
|
+
this.db.prepare("DELETE FROM graph_entities WHERE projectId = ?").run(this.projectId);
|
|
2140
2281
|
for (const entity of entities) {
|
|
2141
|
-
this.stmtInsertEntity.run(entityToRow(entity));
|
|
2282
|
+
this.stmtInsertEntity.run({ ...entityToRow(entity), projectId: this.projectId });
|
|
2142
2283
|
}
|
|
2143
2284
|
for (const rel of relations) {
|
|
2144
|
-
this.stmtInsertRelation.run({ from: rel.from, to: rel.to, relationType: rel.relationType });
|
|
2285
|
+
this.stmtInsertRelation.run({ projectId: this.projectId, from: rel.from, to: rel.to, relationType: rel.relationType });
|
|
2145
2286
|
}
|
|
2146
2287
|
});
|
|
2147
2288
|
replaceAll();
|
|
@@ -2149,8 +2290,8 @@ var init_graph_store = __esm({
|
|
|
2149
2290
|
close() {
|
|
2150
2291
|
}
|
|
2151
2292
|
};
|
|
2152
|
-
|
|
2153
|
-
|
|
2293
|
+
_graphStores = /* @__PURE__ */ new Map();
|
|
2294
|
+
_activeGraphKey = null;
|
|
2154
2295
|
}
|
|
2155
2296
|
});
|
|
2156
2297
|
|
|
@@ -2165,11 +2306,14 @@ var init_graph = __esm({
|
|
|
2165
2306
|
entities = [];
|
|
2166
2307
|
relations = [];
|
|
2167
2308
|
projectDir;
|
|
2309
|
+
projectId;
|
|
2310
|
+
store = null;
|
|
2168
2311
|
initialized = false;
|
|
2169
2312
|
/** Index: lowercase entity name → Entity for O(1) lookups */
|
|
2170
2313
|
entityIndex = /* @__PURE__ */ new Map();
|
|
2171
|
-
constructor(projectDir2) {
|
|
2314
|
+
constructor(projectDir2, projectId = "__default__") {
|
|
2172
2315
|
this.projectDir = projectDir2;
|
|
2316
|
+
this.projectId = projectId;
|
|
2173
2317
|
}
|
|
2174
2318
|
/** Rebuild the entity name index */
|
|
2175
2319
|
rebuildIndex() {
|
|
@@ -2181,10 +2325,9 @@ var init_graph = __esm({
|
|
|
2181
2325
|
/** Load graph from SQLite on first access */
|
|
2182
2326
|
async init() {
|
|
2183
2327
|
if (this.initialized) return;
|
|
2184
|
-
await initGraphStore(this.projectDir);
|
|
2185
|
-
|
|
2186
|
-
this.
|
|
2187
|
-
this.relations = store.loadRelations();
|
|
2328
|
+
this.store = await initGraphStore(this.projectDir, this.projectId);
|
|
2329
|
+
this.entities = this.store.loadEntities();
|
|
2330
|
+
this.relations = this.store.loadRelations();
|
|
2188
2331
|
this.rebuildIndex();
|
|
2189
2332
|
this.initialized = true;
|
|
2190
2333
|
}
|
|
@@ -2198,8 +2341,8 @@ var init_graph = __esm({
|
|
|
2198
2341
|
}
|
|
2199
2342
|
/** Persist current state to SQLite */
|
|
2200
2343
|
async save() {
|
|
2201
|
-
|
|
2202
|
-
store.replaceAll(this.entities, this.relations);
|
|
2344
|
+
if (!this.store) throw new Error("[memorix] KnowledgeGraphManager not initialized");
|
|
2345
|
+
this.store.replaceAll(this.entities, this.relations);
|
|
2203
2346
|
}
|
|
2204
2347
|
/** Create new entities (skip duplicates by name) */
|
|
2205
2348
|
async createEntities(entities) {
|
|
@@ -6986,6 +7129,7 @@ var init_sqlite_store = __esm({
|
|
|
6986
7129
|
init_sqlite_db();
|
|
6987
7130
|
init_sqlite_reliability();
|
|
6988
7131
|
init_sqlite_fts();
|
|
7132
|
+
init_file_lock();
|
|
6989
7133
|
SqliteBackend = class {
|
|
6990
7134
|
db = null;
|
|
6991
7135
|
dataDir = "";
|
|
@@ -7149,38 +7293,43 @@ var init_sqlite_store = __esm({
|
|
|
7149
7293
|
}
|
|
7150
7294
|
// ── Migration ────────────────────────────────────────────────────
|
|
7151
7295
|
async migrateFromJsonIfNeeded() {
|
|
7152
|
-
const count2 = this.db.prepare(`SELECT COUNT(*) AS cnt FROM observations`).get();
|
|
7153
|
-
if (count2.cnt > 0) return;
|
|
7154
7296
|
const jsonPath = path10.join(this.dataDir, "observations.json");
|
|
7155
7297
|
if (!fs7.existsSync(jsonPath)) return;
|
|
7156
|
-
|
|
7298
|
+
await withFileLock(this.dataDir, async () => {
|
|
7299
|
+
const count2 = this.db.prepare(`SELECT COUNT(*) AS cnt FROM observations`).get();
|
|
7300
|
+
if (count2.cnt > 0) return;
|
|
7157
7301
|
const raw = fs7.readFileSync(jsonPath, "utf-8");
|
|
7158
|
-
const
|
|
7302
|
+
const parsed = JSON.parse(raw);
|
|
7303
|
+
if (!Array.isArray(parsed)) {
|
|
7304
|
+
throw new Error("[memorix] observations.json migration refused: expected a JSON array");
|
|
7305
|
+
}
|
|
7306
|
+
const observations2 = parsed;
|
|
7159
7307
|
if (observations2.length === 0) return;
|
|
7308
|
+
if (observations2.some((obs) => !obs || !Number.isSafeInteger(obs.id) || obs.id < 1 || typeof obs.projectId !== "string")) {
|
|
7309
|
+
throw new Error("[memorix] observations.json migration refused: invalid observation record");
|
|
7310
|
+
}
|
|
7160
7311
|
console.error(`[memorix] Migrating ${observations2.length} observations from JSON to SQLite...`);
|
|
7161
7312
|
const insertMany = this.db.transaction((obsList) => {
|
|
7162
7313
|
for (const obs of obsList) {
|
|
7163
7314
|
this.stmtInsert.run(obsToRow(obs));
|
|
7164
7315
|
}
|
|
7165
|
-
|
|
7166
|
-
|
|
7167
|
-
|
|
7168
|
-
if (fs7.existsSync(counterPath)) {
|
|
7169
|
-
try {
|
|
7316
|
+
const counterPath = path10.join(this.dataDir, "counter.json");
|
|
7317
|
+
let counterNextId;
|
|
7318
|
+
if (fs7.existsSync(counterPath)) {
|
|
7170
7319
|
const counterData = JSON.parse(fs7.readFileSync(counterPath, "utf-8"));
|
|
7171
|
-
const
|
|
7172
|
-
|
|
7173
|
-
|
|
7174
|
-
|
|
7320
|
+
const candidate = counterData.nextId ?? counterData.next_id;
|
|
7321
|
+
if (candidate !== void 0 && (!Number.isSafeInteger(candidate) || Number(candidate) < 1)) {
|
|
7322
|
+
throw new Error("[memorix] counter.json migration refused: nextId must be a positive integer");
|
|
7323
|
+
}
|
|
7324
|
+
counterNextId = candidate === void 0 ? void 0 : Number(candidate);
|
|
7175
7325
|
}
|
|
7176
|
-
|
|
7177
|
-
this.rawSaveIdCounter(Math.max(
|
|
7178
|
-
|
|
7179
|
-
|
|
7326
|
+
const maxId = Math.max(...obsList.map((obs) => obs.id));
|
|
7327
|
+
this.rawSaveIdCounter(Math.max(counterNextId ?? 1, maxId + 1));
|
|
7328
|
+
this.bumpGeneration();
|
|
7329
|
+
});
|
|
7330
|
+
insertMany(observations2);
|
|
7180
7331
|
console.error(`[memorix] Migration complete. ${observations2.length} observations now in SQLite.`);
|
|
7181
|
-
}
|
|
7182
|
-
console.error(`[memorix] JSON\u2192SQLite migration failed (non-fatal, data preserved in JSON): ${err}`);
|
|
7183
|
-
}
|
|
7332
|
+
});
|
|
7184
7333
|
}
|
|
7185
7334
|
// ── Public read ──────────────────────────────────────────────────
|
|
7186
7335
|
async loadAll() {
|
|
@@ -159802,7 +159951,7 @@ var init_request_context = __esm({
|
|
|
159802
159951
|
function getMcpServerInfo() {
|
|
159803
159952
|
return {
|
|
159804
159953
|
name: "memorix",
|
|
159805
|
-
version: true ? "1.9.
|
|
159954
|
+
version: true ? "1.9.5" : "1.0.1"
|
|
159806
159955
|
};
|
|
159807
159956
|
}
|
|
159808
159957
|
function createMcpDiscoverResult(capabilities, serverInfo) {
|
|
@@ -160197,7 +160346,7 @@ async function getSessionContext(projectDir2, projectId, limit2 = 3, reader2) {
|
|
|
160197
160346
|
let graphNeighbors = [];
|
|
160198
160347
|
if (!reader2 && activeEntities.length > 0) {
|
|
160199
160348
|
try {
|
|
160200
|
-
const graphMgr = new KnowledgeGraphManager(projectDir2);
|
|
160349
|
+
const graphMgr = new KnowledgeGraphManager(projectDir2, projectId);
|
|
160201
160350
|
await graphMgr.init();
|
|
160202
160351
|
const { relations } = await graphMgr.readGraph();
|
|
160203
160352
|
const activeSet = new Set(activeEntities.map((n) => n.toLowerCase()));
|
|
@@ -166539,8 +166688,7 @@ async function handleApi(req, res, dataDir, projectId, projectName, baseDir, pro
|
|
|
166539
166688
|
break;
|
|
166540
166689
|
}
|
|
166541
166690
|
case "/graph": {
|
|
166542
|
-
await initGraphStore(effectiveDataDir);
|
|
166543
|
-
const gStore = getGraphStore();
|
|
166691
|
+
const gStore = await initGraphStore(effectiveDataDir, effectiveProjectId);
|
|
166544
166692
|
const graph = { entities: gStore.loadEntities(), relations: gStore.loadRelations() };
|
|
166545
166693
|
const graphObs = filterDashboardObservations(
|
|
166546
166694
|
await getObservationStore().loadByProject(effectiveProjectId, { status: "active" }),
|
|
@@ -166584,8 +166732,8 @@ async function handleApi(req, res, dataDir, projectId, projectName, baseDir, pro
|
|
|
166584
166732
|
break;
|
|
166585
166733
|
}
|
|
166586
166734
|
case "/stats": {
|
|
166587
|
-
await initGraphStore(effectiveDataDir);
|
|
166588
|
-
const graph = { entities:
|
|
166735
|
+
const gStore = await initGraphStore(effectiveDataDir, effectiveProjectId);
|
|
166736
|
+
const graph = { entities: gStore.loadEntities(), relations: gStore.loadRelations() };
|
|
166589
166737
|
const observations2 = filterDashboardObservations(
|
|
166590
166738
|
await getObservationStore().loadByProject(effectiveProjectId, { status: "active" }),
|
|
166591
166739
|
effectiveProjectId
|
|
@@ -166778,15 +166926,15 @@ async function handleApi(req, res, dataDir, projectId, projectName, baseDir, pro
|
|
|
166778
166926
|
case "/knowledge-graph": {
|
|
166779
166927
|
const { generateKnowledgeGraph: generateKnowledgeGraph2 } = await Promise.resolve().then(() => (init_knowledge_graph(), knowledge_graph_exports));
|
|
166780
166928
|
const { initMiniSkillStore: initMiniSkillStore2, getMiniSkillStore: getMiniSkillStore2 } = await Promise.resolve().then(() => (init_mini_skill_store(), mini_skill_store_exports));
|
|
166781
|
-
const { initGraphStore: initGraphStore2
|
|
166929
|
+
const { initGraphStore: initGraphStore2 } = await Promise.resolve().then(() => (init_graph_store(), graph_store_exports));
|
|
166782
166930
|
await initMiniSkillStore2(effectiveDataDir);
|
|
166783
|
-
await initGraphStore2(effectiveDataDir);
|
|
166931
|
+
const gStore = await initGraphStore2(effectiveDataDir, effectiveProjectId);
|
|
166784
166932
|
const allObs = filterDashboardObservations(
|
|
166785
166933
|
await getObservationStore().loadByProject(effectiveProjectId, { status: "active" }),
|
|
166786
166934
|
effectiveProjectId
|
|
166787
166935
|
);
|
|
166788
166936
|
const skills = await getMiniSkillStore2().loadByProject(effectiveProjectId);
|
|
166789
|
-
const fullGraph = { entities:
|
|
166937
|
+
const fullGraph = { entities: gStore.loadEntities(), relations: gStore.loadRelations() };
|
|
166790
166938
|
const scoped = scopeKnowledgeGraphToProject(fullGraph, allObs);
|
|
166791
166939
|
const graph = generateKnowledgeGraph2({
|
|
166792
166940
|
projectId: effectiveProjectId,
|
|
@@ -166983,8 +167131,7 @@ async function handleApi(req, res, dataDir, projectId, projectName, baseDir, pro
|
|
|
166983
167131
|
} else {
|
|
166984
167132
|
await obsStore.remove(obsId);
|
|
166985
167133
|
try {
|
|
166986
|
-
await initGraphStore(effectiveDataDir);
|
|
166987
|
-
const gStore = getGraphStore();
|
|
167134
|
+
const gStore = await initGraphStore(effectiveDataDir, effectiveProjectId);
|
|
166988
167135
|
const prefix = `[#${obsId}] `;
|
|
166989
167136
|
const deletions = [];
|
|
166990
167137
|
for (const entity of gStore.loadEntities()) {
|
|
@@ -166999,8 +167146,8 @@ async function handleApi(req, res, dataDir, projectId, projectName, baseDir, pro
|
|
|
166999
167146
|
break;
|
|
167000
167147
|
}
|
|
167001
167148
|
if (apiPath === "/export") {
|
|
167002
|
-
await initGraphStore(effectiveDataDir);
|
|
167003
|
-
const fullGraph = { entities:
|
|
167149
|
+
const gStore = await initGraphStore(effectiveDataDir, effectiveProjectId);
|
|
167150
|
+
const fullGraph = { entities: gStore.loadEntities(), relations: gStore.loadRelations() };
|
|
167004
167151
|
const observations2 = filterDashboardObservations(
|
|
167005
167152
|
await getObservationStore().loadByProject(effectiveProjectId, { status: "active" }),
|
|
167006
167153
|
effectiveProjectId
|
|
@@ -170445,7 +170592,7 @@ async function createMemorixServer(cwd, existingServer, sharedTeam, options = {}
|
|
|
170445
170592
|
const store = getObservationStore();
|
|
170446
170593
|
console.error(`[memorix] ObservationStore backend: ${store.getBackendName()}, generation: ${store.getGeneration()}`);
|
|
170447
170594
|
}
|
|
170448
|
-
let graphManager = new KnowledgeGraphManager(projectDir2);
|
|
170595
|
+
let graphManager = new KnowledgeGraphManager(projectDir2, project.id);
|
|
170449
170596
|
if (!deferProjectRuntimeInit) {
|
|
170450
170597
|
await graphManager.init();
|
|
170451
170598
|
await initObservations(projectDir2);
|
|
@@ -170457,7 +170604,7 @@ async function createMemorixServer(cwd, existingServer, sharedTeam, options = {}
|
|
|
170457
170604
|
await initObservationStore(projectDir2);
|
|
170458
170605
|
await initMiniSkillStore(projectDir2);
|
|
170459
170606
|
await initSessionStore(projectDir2);
|
|
170460
|
-
graphManager = new KnowledgeGraphManager(projectDir2);
|
|
170607
|
+
graphManager = new KnowledgeGraphManager(projectDir2, project.id);
|
|
170461
170608
|
await graphManager.init();
|
|
170462
170609
|
await initObservations(projectDir2);
|
|
170463
170610
|
const indexed = await prepareSearchIndex();
|
|
@@ -175513,7 +175660,7 @@ var init_serve_shared = __esm({
|
|
|
175513
175660
|
|
|
175514
175661
|
// src/cli/version.ts
|
|
175515
175662
|
function getCliVersion() {
|
|
175516
|
-
return true ? "1.9.
|
|
175663
|
+
return true ? "1.9.5" : pkg.version;
|
|
175517
175664
|
}
|
|
175518
175665
|
var init_version3 = __esm({
|
|
175519
175666
|
"src/cli/version.ts"() {
|