@londer/cortex 0.2.0 → 0.2.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/CHANGELOG.md +31 -0
- package/dist/cli.js +162 -0
- package/dist/cli.js.map +1 -1
- package/dist/index.js +49 -1
- package/dist/index.js.map +1 -1
- package/dist/portability/dump.d.ts +19 -0
- package/dist/portability/dump.d.ts.map +1 -0
- package/dist/portability/dump.js +225 -0
- package/dist/portability/dump.js.map +1 -0
- package/dist/portability/exporter.d.ts +5 -0
- package/dist/portability/exporter.d.ts.map +1 -0
- package/dist/portability/exporter.js +116 -0
- package/dist/portability/exporter.js.map +1 -0
- package/dist/portability/importer.d.ts +12 -0
- package/dist/portability/importer.d.ts.map +1 -0
- package/dist/portability/importer.js +164 -0
- package/dist/portability/importer.js.map +1 -0
- package/dist/storage/sqlite.d.ts +9 -0
- package/dist/storage/sqlite.d.ts.map +1 -1
- package/dist/storage/sqlite.js +43 -0
- package/dist/storage/sqlite.js.map +1 -1
- package/dist/templates/claude-instructions.d.ts +1 -1
- package/dist/templates/claude-instructions.d.ts.map +1 -1
- package/dist/templates/claude-instructions.js +4 -0
- package/dist/templates/claude-instructions.js.map +1 -1
- package/dist/tools/export.d.ts +5 -0
- package/dist/tools/export.d.ts.map +1 -0
- package/dist/tools/export.js +24 -0
- package/dist/tools/export.js.map +1 -0
- package/dist/tools/import.d.ts +7 -0
- package/dist/tools/import.d.ts.map +1 -0
- package/dist/tools/import.js +25 -0
- package/dist/tools/import.js.map +1 -0
- package/dist/types/index.d.ts +98 -0
- package/dist/types/index.d.ts.map +1 -1
- package/package.json +1 -1
|
@@ -0,0 +1,225 @@
|
|
|
1
|
+
import { existsSync, mkdirSync, copyFileSync, readFileSync, writeFileSync, } from 'node:fs';
|
|
2
|
+
import { join, dirname } from 'node:path';
|
|
3
|
+
import { hostname } from 'node:os';
|
|
4
|
+
import { fileURLToPath } from 'node:url';
|
|
5
|
+
import { loadConfig } from '../config.js';
|
|
6
|
+
function getVersion() {
|
|
7
|
+
try {
|
|
8
|
+
const __dirname = dirname(fileURLToPath(import.meta.url));
|
|
9
|
+
const pkgPaths = [
|
|
10
|
+
join(__dirname, '..', '..', 'package.json'),
|
|
11
|
+
join(__dirname, '..', '..', '..', 'package.json'),
|
|
12
|
+
];
|
|
13
|
+
for (const p of pkgPaths) {
|
|
14
|
+
try {
|
|
15
|
+
const pkg = JSON.parse(readFileSync(p, 'utf-8'));
|
|
16
|
+
return pkg.version ?? '0.0.0';
|
|
17
|
+
}
|
|
18
|
+
catch { /* try next */ }
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
catch { /* fall through */ }
|
|
22
|
+
return '0.0.0';
|
|
23
|
+
}
|
|
24
|
+
export async function exportDump(outputDir) {
|
|
25
|
+
const config = loadConfig();
|
|
26
|
+
mkdirSync(outputDir, { recursive: true });
|
|
27
|
+
const components = { sqlite: false, qdrant: false, neo4j: false };
|
|
28
|
+
// 1. Copy SQLite database
|
|
29
|
+
try {
|
|
30
|
+
if (existsSync(config.sqlitePath)) {
|
|
31
|
+
copyFileSync(config.sqlitePath, join(outputDir, 'cortex.db'));
|
|
32
|
+
// Copy WAL and SHM files if they exist
|
|
33
|
+
const walPath = config.sqlitePath + '-wal';
|
|
34
|
+
const shmPath = config.sqlitePath + '-shm';
|
|
35
|
+
if (existsSync(walPath))
|
|
36
|
+
copyFileSync(walPath, join(outputDir, 'cortex.db-wal'));
|
|
37
|
+
if (existsSync(shmPath))
|
|
38
|
+
copyFileSync(shmPath, join(outputDir, 'cortex.db-shm'));
|
|
39
|
+
components.sqlite = true;
|
|
40
|
+
}
|
|
41
|
+
else {
|
|
42
|
+
console.error(`[cortex] SQLite database not found at ${config.sqlitePath}`);
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
catch (error) {
|
|
46
|
+
console.error(`[cortex] Failed to copy SQLite: ${error}`);
|
|
47
|
+
}
|
|
48
|
+
// 2. Qdrant snapshot
|
|
49
|
+
try {
|
|
50
|
+
const snapshotUrl = `${config.qdrantUrl}/collections/cortex_memories/snapshots`;
|
|
51
|
+
const createResp = await fetch(snapshotUrl, { method: 'POST' });
|
|
52
|
+
if (createResp.ok) {
|
|
53
|
+
const snapshotInfo = await createResp.json();
|
|
54
|
+
const snapshotName = snapshotInfo.result.name;
|
|
55
|
+
// Download the snapshot
|
|
56
|
+
const downloadUrl = `${snapshotUrl}/${snapshotName}`;
|
|
57
|
+
const downloadResp = await fetch(downloadUrl);
|
|
58
|
+
if (downloadResp.ok) {
|
|
59
|
+
const buffer = Buffer.from(await downloadResp.arrayBuffer());
|
|
60
|
+
writeFileSync(join(outputDir, 'qdrant-snapshot.tar'), buffer);
|
|
61
|
+
components.qdrant = true;
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
catch (error) {
|
|
66
|
+
console.error(`[cortex] Failed to create Qdrant snapshot: ${error}`);
|
|
67
|
+
}
|
|
68
|
+
// 3. Neo4j — export all nodes and relationships as JSON via Cypher
|
|
69
|
+
try {
|
|
70
|
+
const { default: neo4jDriver } = await import('neo4j-driver');
|
|
71
|
+
const driver = neo4jDriver.driver(config.neo4jUri, neo4jDriver.auth.basic(config.neo4jUser, config.neo4jPassword));
|
|
72
|
+
const session = driver.session();
|
|
73
|
+
try {
|
|
74
|
+
// Export entities
|
|
75
|
+
const entityResult = await session.run('MATCH (e:Entity) RETURN e.name AS name, e.project AS project, e.created_at AS created_at');
|
|
76
|
+
const entities = entityResult.records.map(r => ({
|
|
77
|
+
name: r.get('name'),
|
|
78
|
+
project: r.get('project'),
|
|
79
|
+
created_at: r.get('created_at')?.toString() ?? null,
|
|
80
|
+
}));
|
|
81
|
+
// Export relationships
|
|
82
|
+
const relResult = await session.run('MATCH (a)-[r]->(b) RETURN a.name AS from, type(r) AS relation, b.name AS to, r.project AS project, r.properties AS properties');
|
|
83
|
+
const relationships = relResult.records.map(r => ({
|
|
84
|
+
from: r.get('from'),
|
|
85
|
+
relation: r.get('relation'),
|
|
86
|
+
to: r.get('to'),
|
|
87
|
+
project: r.get('project'),
|
|
88
|
+
properties: r.get('properties'),
|
|
89
|
+
}));
|
|
90
|
+
// Export memory-entity links
|
|
91
|
+
const linkResult = await session.run('MATCH (m:Memory)-[:MENTIONS]->(e:Entity) RETURN m.id AS memory_id, e.name AS entity');
|
|
92
|
+
const memoryLinks = linkResult.records.map(r => ({
|
|
93
|
+
memory_id: r.get('memory_id'),
|
|
94
|
+
entity: r.get('entity'),
|
|
95
|
+
}));
|
|
96
|
+
writeFileSync(join(outputDir, 'neo4j-dump.json'), JSON.stringify({ entities, relationships, memoryLinks }, null, 2));
|
|
97
|
+
components.neo4j = true;
|
|
98
|
+
}
|
|
99
|
+
finally {
|
|
100
|
+
await session.close();
|
|
101
|
+
await driver.close();
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
catch (error) {
|
|
105
|
+
console.error(`[cortex] Failed to export Neo4j: ${error}`);
|
|
106
|
+
}
|
|
107
|
+
// 4. Write metadata
|
|
108
|
+
const metadata = {
|
|
109
|
+
version: getVersion(),
|
|
110
|
+
created_at: new Date().toISOString(),
|
|
111
|
+
source_instance: hostname(),
|
|
112
|
+
components,
|
|
113
|
+
};
|
|
114
|
+
writeFileSync(join(outputDir, 'metadata.json'), JSON.stringify(metadata, null, 2));
|
|
115
|
+
const componentList = Object.entries(components)
|
|
116
|
+
.map(([k, v]) => `${k}: ${v ? 'ok' : 'failed'}`)
|
|
117
|
+
.join(', ');
|
|
118
|
+
return {
|
|
119
|
+
success: components.sqlite, // SQLite is minimum required
|
|
120
|
+
message: `Dump exported to ${outputDir} (${componentList})`,
|
|
121
|
+
components,
|
|
122
|
+
};
|
|
123
|
+
}
|
|
124
|
+
export async function restoreDump(inputDir) {
|
|
125
|
+
const config = loadConfig();
|
|
126
|
+
const components = { sqlite: false, qdrant: false, neo4j: false };
|
|
127
|
+
// 1. Validate metadata
|
|
128
|
+
const metadataPath = join(inputDir, 'metadata.json');
|
|
129
|
+
if (!existsSync(metadataPath)) {
|
|
130
|
+
return { success: false, message: 'No metadata.json found in dump directory', components };
|
|
131
|
+
}
|
|
132
|
+
const metadata = JSON.parse(readFileSync(metadataPath, 'utf-8'));
|
|
133
|
+
console.error(`[cortex] Restoring dump from ${metadata.source_instance} (v${metadata.version}, ${metadata.created_at})`);
|
|
134
|
+
// 2. Restore SQLite
|
|
135
|
+
const dbPath = join(inputDir, 'cortex.db');
|
|
136
|
+
if (existsSync(dbPath)) {
|
|
137
|
+
try {
|
|
138
|
+
mkdirSync(dirname(config.sqlitePath), { recursive: true });
|
|
139
|
+
copyFileSync(dbPath, config.sqlitePath);
|
|
140
|
+
// Restore WAL and SHM if present
|
|
141
|
+
const walPath = join(inputDir, 'cortex.db-wal');
|
|
142
|
+
const shmPath = join(inputDir, 'cortex.db-shm');
|
|
143
|
+
if (existsSync(walPath))
|
|
144
|
+
copyFileSync(walPath, config.sqlitePath + '-wal');
|
|
145
|
+
if (existsSync(shmPath))
|
|
146
|
+
copyFileSync(shmPath, config.sqlitePath + '-shm');
|
|
147
|
+
components.sqlite = true;
|
|
148
|
+
}
|
|
149
|
+
catch (error) {
|
|
150
|
+
console.error(`[cortex] Failed to restore SQLite: ${error}`);
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
// 3. Restore Qdrant snapshot
|
|
154
|
+
const snapshotPath = join(inputDir, 'qdrant-snapshot.tar');
|
|
155
|
+
if (existsSync(snapshotPath)) {
|
|
156
|
+
try {
|
|
157
|
+
const snapshotData = readFileSync(snapshotPath);
|
|
158
|
+
const formData = new FormData();
|
|
159
|
+
formData.append('snapshot', new Blob([snapshotData]), 'snapshot.tar');
|
|
160
|
+
const uploadUrl = `${config.qdrantUrl}/collections/cortex_memories/snapshots/upload`;
|
|
161
|
+
const resp = await fetch(uploadUrl, {
|
|
162
|
+
method: 'POST',
|
|
163
|
+
body: formData,
|
|
164
|
+
});
|
|
165
|
+
components.qdrant = resp.ok;
|
|
166
|
+
if (!resp.ok) {
|
|
167
|
+
console.error(`[cortex] Qdrant snapshot restore failed: ${resp.statusText}`);
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
catch (error) {
|
|
171
|
+
console.error(`[cortex] Failed to restore Qdrant: ${error}`);
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
// 4. Restore Neo4j from JSON dump
|
|
175
|
+
const neo4jDumpPath = join(inputDir, 'neo4j-dump.json');
|
|
176
|
+
if (existsSync(neo4jDumpPath)) {
|
|
177
|
+
try {
|
|
178
|
+
const dump = JSON.parse(readFileSync(neo4jDumpPath, 'utf-8'));
|
|
179
|
+
const { default: neo4jDriver } = await import('neo4j-driver');
|
|
180
|
+
const driver = neo4jDriver.driver(config.neo4jUri, neo4jDriver.auth.basic(config.neo4jUser, config.neo4jPassword));
|
|
181
|
+
const session = driver.session();
|
|
182
|
+
try {
|
|
183
|
+
// Recreate entities (skip null/empty names)
|
|
184
|
+
for (const entity of dump.entities) {
|
|
185
|
+
if (!entity.name)
|
|
186
|
+
continue;
|
|
187
|
+
await session.run('MERGE (e:Entity {name: $name}) ON CREATE SET e.project = $project', { name: entity.name, project: entity.project });
|
|
188
|
+
}
|
|
189
|
+
// Recreate relationships (skip null names, use RELATED_TO as safe default)
|
|
190
|
+
const validRelations = ['DEPENDS_ON', 'USES', 'PART_OF', 'RELATED_TO', 'IMPLEMENTS', 'CALLS'];
|
|
191
|
+
for (const rel of dump.relationships) {
|
|
192
|
+
if (!rel.from || !rel.to)
|
|
193
|
+
continue;
|
|
194
|
+
const safeRelation = validRelations.includes(rel.relation) ? rel.relation : 'RELATED_TO';
|
|
195
|
+
await session.run(`MERGE (a:Entity {name: $from})
|
|
196
|
+
MERGE (b:Entity {name: $to})
|
|
197
|
+
MERGE (a)-[:${safeRelation}]->(b)`, { from: rel.from, to: rel.to });
|
|
198
|
+
}
|
|
199
|
+
// Recreate memory-entity links
|
|
200
|
+
for (const link of dump.memoryLinks) {
|
|
201
|
+
await session.run(`MERGE (m:Memory {id: $memoryId})
|
|
202
|
+
MERGE (e:Entity {name: $entity})
|
|
203
|
+
MERGE (m)-[:MENTIONS]->(e)`, { memoryId: link.memory_id, entity: link.entity });
|
|
204
|
+
}
|
|
205
|
+
components.neo4j = true;
|
|
206
|
+
}
|
|
207
|
+
finally {
|
|
208
|
+
await session.close();
|
|
209
|
+
await driver.close();
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
catch (error) {
|
|
213
|
+
console.error(`[cortex] Failed to restore Neo4j: ${error}`);
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
const componentList = Object.entries(components)
|
|
217
|
+
.map(([k, v]) => `${k}: ${v ? 'ok' : 'skipped/failed'}`)
|
|
218
|
+
.join(', ');
|
|
219
|
+
return {
|
|
220
|
+
success: components.sqlite,
|
|
221
|
+
message: `Dump restored (${componentList})`,
|
|
222
|
+
components,
|
|
223
|
+
};
|
|
224
|
+
}
|
|
225
|
+
//# sourceMappingURL=dump.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"dump.js","sourceRoot":"","sources":["../../src/portability/dump.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import type { SQLiteStore } from '../storage/sqlite.js';
|
|
2
|
+
import type { Neo4jStore } from '../storage/neo4j.js';
|
|
3
|
+
import type { CortexExportData, ExportFilters } from '../types/index.js';
|
|
4
|
+
export declare function exportMemories(sqlite: SQLiteStore, neo4j: Neo4jStore, filters?: ExportFilters): Promise<CortexExportData>;
|
|
5
|
+
//# sourceMappingURL=exporter.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"exporter.d.ts","sourceRoot":"","sources":["../../src/portability/exporter.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,sBAAsB,CAAC;AACxD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAC;AACtD,OAAO,KAAK,EACV,gBAAgB,EAIhB,aAAa,EACd,MAAM,mBAAmB,CAAC;AAmB3B,wBAAsB,cAAc,CAClC,MAAM,EAAE,WAAW,EACnB,KAAK,EAAE,UAAU,EACjB,OAAO,CAAC,EAAE,aAAa,GACtB,OAAO,CAAC,gBAAgB,CAAC,CAuG3B"}
|
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
import { hostname } from 'node:os';
|
|
2
|
+
import { readFileSync } from 'node:fs';
|
|
3
|
+
import { join, dirname } from 'node:path';
|
|
4
|
+
import { fileURLToPath } from 'node:url';
|
|
5
|
+
function getVersion() {
|
|
6
|
+
try {
|
|
7
|
+
const __dirname = dirname(fileURLToPath(import.meta.url));
|
|
8
|
+
const pkgPaths = [
|
|
9
|
+
join(__dirname, '..', '..', 'package.json'),
|
|
10
|
+
join(__dirname, '..', '..', '..', 'package.json'),
|
|
11
|
+
];
|
|
12
|
+
for (const p of pkgPaths) {
|
|
13
|
+
try {
|
|
14
|
+
const pkg = JSON.parse(readFileSync(p, 'utf-8'));
|
|
15
|
+
return pkg.version ?? '0.0.0';
|
|
16
|
+
}
|
|
17
|
+
catch { /* try next */ }
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
catch { /* fall through */ }
|
|
21
|
+
return '0.0.0';
|
|
22
|
+
}
|
|
23
|
+
export async function exportMemories(sqlite, neo4j, filters) {
|
|
24
|
+
// 1. Query memories from SQLite
|
|
25
|
+
const memories = sqlite.getAllActiveMemories({
|
|
26
|
+
project: filters?.project,
|
|
27
|
+
types: filters?.types,
|
|
28
|
+
since: filters?.since,
|
|
29
|
+
minAccess: filters?.min_access,
|
|
30
|
+
});
|
|
31
|
+
// 2. Build exported memories
|
|
32
|
+
const exportedMemories = memories.map(m => ({
|
|
33
|
+
id: m.id,
|
|
34
|
+
content: m.content,
|
|
35
|
+
type: m.type,
|
|
36
|
+
project: m.project,
|
|
37
|
+
tags: m.tags,
|
|
38
|
+
entities: m.entities,
|
|
39
|
+
source: m.source,
|
|
40
|
+
source_type: m.source_type ?? null,
|
|
41
|
+
visibility: m.visibility ?? 'project-only',
|
|
42
|
+
created_at: m.created_at,
|
|
43
|
+
access_count: m.access_count ?? 0,
|
|
44
|
+
staleness_score: m.staleness_score ?? 0,
|
|
45
|
+
}));
|
|
46
|
+
// 3. Collect unique entities from all memories
|
|
47
|
+
const entitySet = new Set();
|
|
48
|
+
for (const m of exportedMemories) {
|
|
49
|
+
for (const e of m.entities) {
|
|
50
|
+
entitySet.add(e);
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
// 4. Fetch entity connections from Neo4j
|
|
54
|
+
const exportedEntities = [];
|
|
55
|
+
let totalRelationships = 0;
|
|
56
|
+
for (const entityName of entitySet) {
|
|
57
|
+
try {
|
|
58
|
+
const graphResult = await neo4j.traverse(entityName, 1);
|
|
59
|
+
const connections = graphResult.connections.map(c => ({
|
|
60
|
+
entity: c.entity,
|
|
61
|
+
relation: c.relation,
|
|
62
|
+
direction: c.direction,
|
|
63
|
+
}));
|
|
64
|
+
totalRelationships += connections.length;
|
|
65
|
+
// Determine project from memories that reference this entity
|
|
66
|
+
const memoriesWithEntity = exportedMemories.filter(m => m.entities.includes(entityName));
|
|
67
|
+
const project = memoriesWithEntity[0]?.project ?? null;
|
|
68
|
+
exportedEntities.push({
|
|
69
|
+
name: entityName,
|
|
70
|
+
project,
|
|
71
|
+
connections,
|
|
72
|
+
});
|
|
73
|
+
}
|
|
74
|
+
catch {
|
|
75
|
+
// Neo4j may be unavailable — export entity without connections
|
|
76
|
+
const memoriesWithEntity = exportedMemories.filter(m => m.entities.includes(entityName));
|
|
77
|
+
exportedEntities.push({
|
|
78
|
+
name: entityName,
|
|
79
|
+
project: memoriesWithEntity[0]?.project ?? null,
|
|
80
|
+
connections: [],
|
|
81
|
+
});
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
// 5. Fetch project links
|
|
85
|
+
const projects = filters?.project
|
|
86
|
+
? [filters.project]
|
|
87
|
+
: [...new Set(exportedMemories.map(m => m.project).filter(Boolean))];
|
|
88
|
+
const projectLinks = sqlite.getProjectLinksForProjects(projects);
|
|
89
|
+
const exportedLinks = projectLinks.map(pl => ({
|
|
90
|
+
project_a: pl.project_a,
|
|
91
|
+
project_b: pl.project_b,
|
|
92
|
+
}));
|
|
93
|
+
// 6. Assemble export
|
|
94
|
+
return {
|
|
95
|
+
version: getVersion(),
|
|
96
|
+
exported_at: new Date().toISOString(),
|
|
97
|
+
source_instance: hostname(),
|
|
98
|
+
filters: {
|
|
99
|
+
project: filters?.project ?? null,
|
|
100
|
+
types: filters?.types ?? null,
|
|
101
|
+
date_range: filters?.since ?? null,
|
|
102
|
+
min_access: filters?.min_access ?? null,
|
|
103
|
+
},
|
|
104
|
+
data: {
|
|
105
|
+
memories: exportedMemories,
|
|
106
|
+
entities: exportedEntities,
|
|
107
|
+
project_links: exportedLinks,
|
|
108
|
+
},
|
|
109
|
+
stats: {
|
|
110
|
+
memories: exportedMemories.length,
|
|
111
|
+
entities: exportedEntities.length,
|
|
112
|
+
relationships: totalRelationships,
|
|
113
|
+
},
|
|
114
|
+
};
|
|
115
|
+
}
|
|
116
|
+
//# sourceMappingURL=exporter.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"exporter.js","sourceRoot":"","sources":["../../src/portability/exporter.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { SQLiteStore } from '../storage/sqlite.js';
|
|
2
|
+
import type { QdrantStore } from '../storage/qdrant.js';
|
|
3
|
+
import type { Neo4jStore } from '../storage/neo4j.js';
|
|
4
|
+
import type { Embedder } from '../embedding/embedder.js';
|
|
5
|
+
import type { CortexExportData, ImportResult } from '../types/index.js';
|
|
6
|
+
export declare function validateExportData(raw: unknown): CortexExportData;
|
|
7
|
+
export declare function importMemories(data: CortexExportData, sqlite: SQLiteStore, qdrant: QdrantStore, neo4j: Neo4jStore, embedder: Embedder, options?: {
|
|
8
|
+
merge?: boolean;
|
|
9
|
+
dryRun?: boolean;
|
|
10
|
+
projectOverride?: string;
|
|
11
|
+
}): Promise<ImportResult>;
|
|
12
|
+
//# sourceMappingURL=importer.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"importer.d.ts","sourceRoot":"","sources":["../../src/portability/importer.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,sBAAsB,CAAC;AACxD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,sBAAsB,CAAC;AACxD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAC;AACtD,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,0BAA0B,CAAC;AACzD,OAAO,KAAK,EACV,gBAAgB,EAKhB,YAAY,EACb,MAAM,mBAAmB,CAAC;AAU3B,wBAAgB,kBAAkB,CAAC,GAAG,EAAE,OAAO,GAAG,gBAAgB,CAkCjE;AAED,wBAAsB,cAAc,CAClC,IAAI,EAAE,gBAAgB,EACtB,MAAM,EAAE,WAAW,EACnB,MAAM,EAAE,WAAW,EACnB,KAAK,EAAE,UAAU,EACjB,QAAQ,EAAE,QAAQ,EAClB,OAAO,GAAE;IACP,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,eAAe,CAAC,EAAE,MAAM,CAAC;CACrB,GACL,OAAO,CAAC,YAAY,CAAC,CAsIvB"}
|
|
@@ -0,0 +1,164 @@
|
|
|
1
|
+
import { v4 as uuidv4 } from 'uuid';
|
|
2
|
+
const VALID_TYPES = new Set([
|
|
3
|
+
'insight', 'decision', 'pattern', 'snippet', 'fact', 'note',
|
|
4
|
+
]);
|
|
5
|
+
const VALID_VISIBILITIES = new Set([
|
|
6
|
+
'project-only', 'cross-project', 'global',
|
|
7
|
+
]);
|
|
8
|
+
export function validateExportData(raw) {
|
|
9
|
+
if (!raw || typeof raw !== 'object') {
|
|
10
|
+
throw new Error('Invalid export data: expected an object');
|
|
11
|
+
}
|
|
12
|
+
const data = raw;
|
|
13
|
+
if (typeof data.version !== 'string') {
|
|
14
|
+
throw new Error('Invalid export data: missing version');
|
|
15
|
+
}
|
|
16
|
+
if (!data.data || typeof data.data !== 'object') {
|
|
17
|
+
throw new Error('Invalid export data: missing data section');
|
|
18
|
+
}
|
|
19
|
+
const dataSection = data.data;
|
|
20
|
+
if (!Array.isArray(dataSection.memories)) {
|
|
21
|
+
throw new Error('Invalid export data: data.memories must be an array');
|
|
22
|
+
}
|
|
23
|
+
// Validate each memory has required fields
|
|
24
|
+
for (const mem of dataSection.memories) {
|
|
25
|
+
if (!mem || typeof mem !== 'object') {
|
|
26
|
+
throw new Error('Invalid export data: memory entry must be an object');
|
|
27
|
+
}
|
|
28
|
+
const m = mem;
|
|
29
|
+
if (typeof m.content !== 'string' || !m.content) {
|
|
30
|
+
throw new Error(`Invalid memory: missing content`);
|
|
31
|
+
}
|
|
32
|
+
if (typeof m.type !== 'string' || !VALID_TYPES.has(m.type)) {
|
|
33
|
+
throw new Error(`Invalid memory type: ${m.type}`);
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
return raw;
|
|
37
|
+
}
|
|
38
|
+
export async function importMemories(data, sqlite, qdrant, neo4j, embedder, options = {}) {
|
|
39
|
+
const { merge = false, dryRun = false, projectOverride } = options;
|
|
40
|
+
const result = {
|
|
41
|
+
imported: 0,
|
|
42
|
+
skipped: 0,
|
|
43
|
+
errors: 0,
|
|
44
|
+
details: [],
|
|
45
|
+
};
|
|
46
|
+
for (const exportedMem of data.data.memories) {
|
|
47
|
+
try {
|
|
48
|
+
// 1. Check if ID already exists
|
|
49
|
+
if (sqlite.memoryExists(exportedMem.id)) {
|
|
50
|
+
result.skipped++;
|
|
51
|
+
result.details.push({
|
|
52
|
+
id: exportedMem.id,
|
|
53
|
+
action: 'skipped',
|
|
54
|
+
reason: 'Memory with same ID already exists',
|
|
55
|
+
});
|
|
56
|
+
continue;
|
|
57
|
+
}
|
|
58
|
+
// 2. If merge mode, check embedding similarity
|
|
59
|
+
if (merge) {
|
|
60
|
+
const vector = await embedder.embed(exportedMem.content);
|
|
61
|
+
const similar = await qdrant.search(vector, undefined, 1);
|
|
62
|
+
if (similar.length > 0 && similar[0].score > 0.92) {
|
|
63
|
+
result.skipped++;
|
|
64
|
+
result.details.push({
|
|
65
|
+
id: exportedMem.id,
|
|
66
|
+
action: 'skipped',
|
|
67
|
+
reason: `Duplicate found (similarity: ${similar[0].score.toFixed(3)})`,
|
|
68
|
+
});
|
|
69
|
+
continue;
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
if (dryRun) {
|
|
73
|
+
result.imported++;
|
|
74
|
+
result.details.push({
|
|
75
|
+
id: exportedMem.id,
|
|
76
|
+
action: 'imported',
|
|
77
|
+
reason: 'Would be imported (dry run)',
|
|
78
|
+
});
|
|
79
|
+
continue;
|
|
80
|
+
}
|
|
81
|
+
// 3. Generate new UUID, embed, store
|
|
82
|
+
const newId = uuidv4();
|
|
83
|
+
const project = projectOverride ?? exportedMem.project;
|
|
84
|
+
const now = new Date().toISOString();
|
|
85
|
+
const memory = {
|
|
86
|
+
id: newId,
|
|
87
|
+
content: exportedMem.content,
|
|
88
|
+
type: exportedMem.type,
|
|
89
|
+
project,
|
|
90
|
+
tags: Array.isArray(exportedMem.tags) ? exportedMem.tags : [],
|
|
91
|
+
entities: Array.isArray(exportedMem.entities) ? exportedMem.entities : [],
|
|
92
|
+
source: exportedMem.source ?? 'import',
|
|
93
|
+
created_at: exportedMem.created_at ?? now,
|
|
94
|
+
updated_at: now,
|
|
95
|
+
is_deleted: 0,
|
|
96
|
+
source_type: exportedMem.source_type ?? 'import',
|
|
97
|
+
visibility: VALID_VISIBILITIES.has(exportedMem.visibility ?? '')
|
|
98
|
+
? exportedMem.visibility
|
|
99
|
+
: 'project-only',
|
|
100
|
+
access_count: 0,
|
|
101
|
+
last_accessed_at: null,
|
|
102
|
+
staleness_score: 0,
|
|
103
|
+
};
|
|
104
|
+
// Store in SQLite
|
|
105
|
+
sqlite.insertMemory(memory);
|
|
106
|
+
// Re-embed (don't trust imported vectors)
|
|
107
|
+
const vector = await embedder.embed(memory.content);
|
|
108
|
+
const payload = {
|
|
109
|
+
id: newId,
|
|
110
|
+
project: memory.project,
|
|
111
|
+
type: memory.type,
|
|
112
|
+
tags: memory.tags,
|
|
113
|
+
entities: memory.entities,
|
|
114
|
+
created_at: Math.floor(new Date(memory.created_at).getTime() / 1000),
|
|
115
|
+
};
|
|
116
|
+
await qdrant.upsert(newId, vector, payload);
|
|
117
|
+
// Link entities in Neo4j
|
|
118
|
+
if (memory.entities.length > 0) {
|
|
119
|
+
await neo4j.linkMemoryToEntities(newId, memory.entities);
|
|
120
|
+
}
|
|
121
|
+
result.imported++;
|
|
122
|
+
result.details.push({ id: newId, action: 'imported' });
|
|
123
|
+
}
|
|
124
|
+
catch (error) {
|
|
125
|
+
result.errors++;
|
|
126
|
+
result.details.push({
|
|
127
|
+
id: exportedMem.id,
|
|
128
|
+
action: 'error',
|
|
129
|
+
reason: error instanceof Error ? error.message : String(error),
|
|
130
|
+
});
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
// Recreate entity relationships from import data (skip in dry run)
|
|
134
|
+
if (!dryRun && data.data.entities) {
|
|
135
|
+
for (const entity of data.data.entities) {
|
|
136
|
+
for (const conn of entity.connections) {
|
|
137
|
+
try {
|
|
138
|
+
if (conn.direction === 'outgoing') {
|
|
139
|
+
await neo4j.createRelation(entity.name, conn.relation, conn.entity);
|
|
140
|
+
}
|
|
141
|
+
else {
|
|
142
|
+
await neo4j.createRelation(conn.entity, conn.relation, entity.name);
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
catch {
|
|
146
|
+
// Relationship creation errors are non-fatal
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
// Recreate project links (skip in dry run)
|
|
152
|
+
if (!dryRun && data.data.project_links) {
|
|
153
|
+
for (const link of data.data.project_links) {
|
|
154
|
+
try {
|
|
155
|
+
sqlite.linkProjects(link.project_a, link.project_b);
|
|
156
|
+
}
|
|
157
|
+
catch {
|
|
158
|
+
// Link creation errors are non-fatal
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
return result;
|
|
163
|
+
}
|
|
164
|
+
//# sourceMappingURL=importer.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"importer.js","sourceRoot":"","sources":["../../src/portability/importer.ts"],"names":[],"mappings":"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"}
|
package/dist/storage/sqlite.d.ts
CHANGED
|
@@ -43,6 +43,15 @@ export declare class SQLiteStore {
|
|
|
43
43
|
getAverageStaleness(): number;
|
|
44
44
|
getMemoryCountByType(): Record<string, number>;
|
|
45
45
|
getMemoryCountByProject(): Record<string, number>;
|
|
46
|
+
getAllActiveMemories(filters?: {
|
|
47
|
+
project?: string;
|
|
48
|
+
types?: string[];
|
|
49
|
+
since?: string;
|
|
50
|
+
minAccess?: number;
|
|
51
|
+
limit?: number;
|
|
52
|
+
}): Memory[];
|
|
53
|
+
getProjectLinksForProjects(projects: string[]): ProjectLink[];
|
|
54
|
+
memoryExists(id: string): boolean;
|
|
46
55
|
getStalenessScore(memoryId: string): number;
|
|
47
56
|
insertMemory(memory: Memory): void;
|
|
48
57
|
getMemory(id: string): Memory | null;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sqlite.d.ts","sourceRoot":"","sources":["../../src/storage/sqlite.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"sqlite.d.ts","sourceRoot":"","sources":["../../src/storage/sqlite.ts"],"names":[],"mappings":"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"}
|
package/dist/storage/sqlite.js
CHANGED
|
@@ -292,6 +292,49 @@ export class SQLiteStore {
|
|
|
292
292
|
}
|
|
293
293
|
return result;
|
|
294
294
|
}
|
|
295
|
+
getAllActiveMemories(filters) {
|
|
296
|
+
let query = 'SELECT * FROM memories WHERE is_deleted = 0';
|
|
297
|
+
const params = [];
|
|
298
|
+
if (filters?.project) {
|
|
299
|
+
query += ' AND project = ?';
|
|
300
|
+
params.push(filters.project);
|
|
301
|
+
}
|
|
302
|
+
if (filters?.types && filters.types.length > 0) {
|
|
303
|
+
const placeholders = filters.types.map(() => '?').join(',');
|
|
304
|
+
query += ` AND type IN (${placeholders})`;
|
|
305
|
+
params.push(...filters.types);
|
|
306
|
+
}
|
|
307
|
+
if (filters?.since) {
|
|
308
|
+
query += ' AND created_at >= ?';
|
|
309
|
+
params.push(filters.since);
|
|
310
|
+
}
|
|
311
|
+
if (filters?.minAccess !== undefined) {
|
|
312
|
+
query += ' AND access_count >= ?';
|
|
313
|
+
params.push(filters.minAccess);
|
|
314
|
+
}
|
|
315
|
+
query += ' ORDER BY created_at DESC';
|
|
316
|
+
if (filters?.limit) {
|
|
317
|
+
query += ' LIMIT ?';
|
|
318
|
+
params.push(filters.limit);
|
|
319
|
+
}
|
|
320
|
+
const rows = this.db.prepare(query).all(...params);
|
|
321
|
+
return rows.map(row => this.rowToMemory(row));
|
|
322
|
+
}
|
|
323
|
+
getProjectLinksForProjects(projects) {
|
|
324
|
+
if (projects.length === 0)
|
|
325
|
+
return this.getAllProjectLinks();
|
|
326
|
+
const placeholders = projects.map(() => '?').join(',');
|
|
327
|
+
const stmt = this.db.prepare(`
|
|
328
|
+
SELECT * FROM project_links
|
|
329
|
+
WHERE project_a IN (${placeholders}) OR project_b IN (${placeholders})
|
|
330
|
+
ORDER BY created_at DESC
|
|
331
|
+
`);
|
|
332
|
+
return stmt.all(...projects, ...projects);
|
|
333
|
+
}
|
|
334
|
+
memoryExists(id) {
|
|
335
|
+
const row = this.db.prepare('SELECT 1 FROM memories WHERE id = ? AND is_deleted = 0').get(id);
|
|
336
|
+
return row !== undefined;
|
|
337
|
+
}
|
|
295
338
|
getStalenessScore(memoryId) {
|
|
296
339
|
const row = this.db.prepare('SELECT staleness_score FROM memories WHERE id = ?').get(memoryId);
|
|
297
340
|
return row?.staleness_score ?? 0;
|