engram-sdk 0.4.4 → 0.5.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/.mcpregistry_github_token +1 -0
- package/.mcpregistry_registry_token +1 -0
- package/Dockerfile +12 -14
- package/dist/cli.js +149 -2
- package/dist/cli.js.map +1 -1
- package/dist/import.d.ts +31 -0
- package/dist/import.d.ts.map +1 -0
- package/dist/import.js +460 -0
- package/dist/import.js.map +1 -0
- package/dist/mcp.js +65 -10
- package/dist/mcp.js.map +1 -1
- package/dist/memory-tree.d.ts +20 -0
- package/dist/memory-tree.d.ts.map +1 -0
- package/dist/memory-tree.js +346 -0
- package/dist/memory-tree.js.map +1 -0
- package/dist/server.d.ts.map +1 -1
- package/dist/server.js +41 -4
- package/dist/server.js.map +1 -1
- package/dist/telemetry.d.ts +58 -0
- package/dist/telemetry.d.ts.map +1 -0
- package/dist/telemetry.js +234 -0
- package/dist/telemetry.js.map +1 -0
- package/dist/types.d.ts +9 -0
- package/dist/types.d.ts.map +1 -1
- package/dist/update-check.d.ts +11 -0
- package/dist/update-check.d.ts.map +1 -0
- package/dist/update-check.js +115 -0
- package/dist/update-check.js.map +1 -0
- package/package.json +2 -1
- package/server.json +3 -3
package/dist/import.js
ADDED
|
@@ -0,0 +1,460 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* engram import — Migrate memory from other AI tools into Engram
|
|
3
|
+
*
|
|
4
|
+
* Supports:
|
|
5
|
+
* --claude-code Import from Claude Code (CLAUDE.md + auto memory + session transcripts)
|
|
6
|
+
*
|
|
7
|
+
* Claude Code caps auto memory at 200 lines per project, siloed per repo.
|
|
8
|
+
* Engram has no limit, semantic search across everything, and cross-project intelligence.
|
|
9
|
+
* Import in one command. Keep using Claude Code — Engram just makes it smarter.
|
|
10
|
+
*/
|
|
11
|
+
import { readFileSync, existsSync, readdirSync, statSync } from 'fs';
|
|
12
|
+
import { join, basename } from 'path';
|
|
13
|
+
import { homedir } from 'os';
|
|
14
|
+
// ── Formatting helpers ─────────────────────────────────────
|
|
15
|
+
function bold(s) { return `\x1b[1m${s}\x1b[0m`; }
|
|
16
|
+
function dim(s) { return `\x1b[2m${s}\x1b[0m`; }
|
|
17
|
+
function green(s) { return `\x1b[32m${s}\x1b[0m`; }
|
|
18
|
+
function yellow(s) { return `\x1b[33m${s}\x1b[0m`; }
|
|
19
|
+
function cyan(s) { return `\x1b[36m${s}\x1b[0m`; }
|
|
20
|
+
function red(s) { return `\x1b[31m${s}\x1b[0m`; }
|
|
21
|
+
// ── Discovery ──────────────────────────────────────────────
|
|
22
|
+
function discoverClaudeCodeSources() {
|
|
23
|
+
const home = homedir();
|
|
24
|
+
const sources = [];
|
|
25
|
+
const claudeDir = join(home, '.claude');
|
|
26
|
+
if (!existsSync(claudeDir)) {
|
|
27
|
+
return sources;
|
|
28
|
+
}
|
|
29
|
+
// 1. User-level CLAUDE.md
|
|
30
|
+
const userClaudeMd = join(claudeDir, 'CLAUDE.md');
|
|
31
|
+
if (existsSync(userClaudeMd)) {
|
|
32
|
+
const content = readFileSync(userClaudeMd, 'utf-8');
|
|
33
|
+
sources.push({
|
|
34
|
+
path: userClaudeMd,
|
|
35
|
+
project: '~global',
|
|
36
|
+
type: 'claude-md',
|
|
37
|
+
content,
|
|
38
|
+
lineCount: content.split('\n').length,
|
|
39
|
+
});
|
|
40
|
+
}
|
|
41
|
+
// 2. User-level rules
|
|
42
|
+
const userRulesDir = join(claudeDir, 'rules');
|
|
43
|
+
if (existsSync(userRulesDir)) {
|
|
44
|
+
for (const file of findMarkdownFiles(userRulesDir)) {
|
|
45
|
+
const content = readFileSync(file, 'utf-8');
|
|
46
|
+
sources.push({
|
|
47
|
+
path: file,
|
|
48
|
+
project: '~global',
|
|
49
|
+
type: 'rules',
|
|
50
|
+
content,
|
|
51
|
+
lineCount: content.split('\n').length,
|
|
52
|
+
});
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
// 3. Per-project auto memory and sessions
|
|
56
|
+
const projectsDir = join(claudeDir, 'projects');
|
|
57
|
+
if (existsSync(projectsDir)) {
|
|
58
|
+
for (const projectSlug of readdirSync(projectsDir)) {
|
|
59
|
+
const projectPath = join(projectsDir, projectSlug);
|
|
60
|
+
if (!statSync(projectPath).isDirectory())
|
|
61
|
+
continue;
|
|
62
|
+
const projectName = decodeProjectSlug(projectSlug);
|
|
63
|
+
// Auto memory files
|
|
64
|
+
const memoryDir = join(projectPath, 'memory');
|
|
65
|
+
if (existsSync(memoryDir)) {
|
|
66
|
+
for (const file of findMarkdownFiles(memoryDir)) {
|
|
67
|
+
const content = readFileSync(file, 'utf-8');
|
|
68
|
+
if (content.trim().length === 0)
|
|
69
|
+
continue;
|
|
70
|
+
sources.push({
|
|
71
|
+
path: file,
|
|
72
|
+
project: projectName,
|
|
73
|
+
type: 'auto-memory',
|
|
74
|
+
content,
|
|
75
|
+
lineCount: content.split('\n').length,
|
|
76
|
+
});
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
// Session transcripts (JSONL)
|
|
80
|
+
const jsonlFiles = readdirSync(projectPath)
|
|
81
|
+
.filter(f => f.endsWith('.jsonl'))
|
|
82
|
+
.map(f => ({
|
|
83
|
+
name: f,
|
|
84
|
+
path: join(projectPath, f),
|
|
85
|
+
mtime: statSync(join(projectPath, f)).mtimeMs,
|
|
86
|
+
size: statSync(join(projectPath, f)).size,
|
|
87
|
+
}))
|
|
88
|
+
.sort((a, b) => b.mtime - a.mtime); // newest first
|
|
89
|
+
for (const jsonl of jsonlFiles) {
|
|
90
|
+
sources.push({
|
|
91
|
+
path: jsonl.path,
|
|
92
|
+
project: projectName,
|
|
93
|
+
type: 'session-transcript',
|
|
94
|
+
content: '', // loaded on demand (can be huge)
|
|
95
|
+
lineCount: 0,
|
|
96
|
+
});
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
// 4. Project-level CLAUDE.md in cwd
|
|
101
|
+
const cwd = process.cwd();
|
|
102
|
+
for (const relPath of ['CLAUDE.md', '.claude/CLAUDE.md', 'CLAUDE.local.md']) {
|
|
103
|
+
const fullPath = join(cwd, relPath);
|
|
104
|
+
if (existsSync(fullPath)) {
|
|
105
|
+
const content = readFileSync(fullPath, 'utf-8');
|
|
106
|
+
sources.push({
|
|
107
|
+
path: fullPath,
|
|
108
|
+
project: basename(cwd),
|
|
109
|
+
type: 'claude-md',
|
|
110
|
+
content,
|
|
111
|
+
lineCount: content.split('\n').length,
|
|
112
|
+
});
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
// Project rules in cwd
|
|
116
|
+
const cwdRulesDir = join(cwd, '.claude', 'rules');
|
|
117
|
+
if (existsSync(cwdRulesDir)) {
|
|
118
|
+
for (const file of findMarkdownFiles(cwdRulesDir)) {
|
|
119
|
+
const content = readFileSync(file, 'utf-8');
|
|
120
|
+
sources.push({
|
|
121
|
+
path: file,
|
|
122
|
+
project: basename(cwd),
|
|
123
|
+
type: 'rules',
|
|
124
|
+
content,
|
|
125
|
+
lineCount: content.split('\n').length,
|
|
126
|
+
});
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
return sources;
|
|
130
|
+
}
|
|
131
|
+
function findMarkdownFiles(dir) {
|
|
132
|
+
const files = [];
|
|
133
|
+
try {
|
|
134
|
+
for (const entry of readdirSync(dir, { withFileTypes: true })) {
|
|
135
|
+
const fullPath = join(dir, entry.name);
|
|
136
|
+
if (entry.isDirectory()) {
|
|
137
|
+
files.push(...findMarkdownFiles(fullPath));
|
|
138
|
+
}
|
|
139
|
+
else if (entry.name.endsWith('.md')) {
|
|
140
|
+
files.push(fullPath);
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
catch {
|
|
145
|
+
// Permission denied or similar
|
|
146
|
+
}
|
|
147
|
+
return files;
|
|
148
|
+
}
|
|
149
|
+
function decodeProjectSlug(slug) {
|
|
150
|
+
// Claude Code encodes paths like: -Users-thomasstockham-Desktop-Scout
|
|
151
|
+
// Decode back to a readable project name
|
|
152
|
+
const parts = slug.split('-').filter(Boolean);
|
|
153
|
+
// Try to find a reasonable project name from the path
|
|
154
|
+
// Skip "Users" and username, take the last meaningful parts
|
|
155
|
+
if (parts.length >= 3 && parts[0] === 'Users') {
|
|
156
|
+
const projectParts = parts.slice(2); // skip "Users" and username
|
|
157
|
+
return projectParts.join('/');
|
|
158
|
+
}
|
|
159
|
+
return slug;
|
|
160
|
+
}
|
|
161
|
+
// ── Parsing ────────────────────────────────────────────────
|
|
162
|
+
function parseMarkdownIntoChunks(source) {
|
|
163
|
+
const chunks = [];
|
|
164
|
+
const lines = source.content.split('\n');
|
|
165
|
+
let currentSection = '';
|
|
166
|
+
let currentLines = [];
|
|
167
|
+
function flush() {
|
|
168
|
+
const text = currentLines.join('\n').trim();
|
|
169
|
+
if (text.length < 10)
|
|
170
|
+
return; // skip trivially short chunks
|
|
171
|
+
// Extract potential entities (capitalized words, @mentions, paths)
|
|
172
|
+
const entities = extractEntities(text);
|
|
173
|
+
const topics = extractTopics(text, source);
|
|
174
|
+
chunks.push({
|
|
175
|
+
content: text,
|
|
176
|
+
source,
|
|
177
|
+
section: currentSection || undefined,
|
|
178
|
+
entities: entities.length > 0 ? entities : undefined,
|
|
179
|
+
topics: topics.length > 0 ? topics : undefined,
|
|
180
|
+
});
|
|
181
|
+
}
|
|
182
|
+
for (const line of lines) {
|
|
183
|
+
const headerMatch = line.match(/^(#{1,3})\s+(.+)/);
|
|
184
|
+
if (headerMatch) {
|
|
185
|
+
flush();
|
|
186
|
+
currentSection = headerMatch[2].trim();
|
|
187
|
+
currentLines = [];
|
|
188
|
+
}
|
|
189
|
+
else {
|
|
190
|
+
currentLines.push(line);
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
flush();
|
|
194
|
+
return chunks;
|
|
195
|
+
}
|
|
196
|
+
function extractEntities(text) {
|
|
197
|
+
const entities = new Set();
|
|
198
|
+
// Extract @mentions
|
|
199
|
+
for (const match of text.matchAll(/@(\w+)/g)) {
|
|
200
|
+
entities.add(match[1]);
|
|
201
|
+
}
|
|
202
|
+
// Extract quoted terms
|
|
203
|
+
for (const match of text.matchAll(/[`"']([A-Z][a-zA-Z0-9]+(?:\s+[A-Z][a-zA-Z0-9]+)*)[`"']/g)) {
|
|
204
|
+
if (match[1].length < 30)
|
|
205
|
+
entities.add(match[1]);
|
|
206
|
+
}
|
|
207
|
+
return [...entities].slice(0, 10);
|
|
208
|
+
}
|
|
209
|
+
function extractTopics(text, source) {
|
|
210
|
+
const topics = new Set();
|
|
211
|
+
// Add source type as topic
|
|
212
|
+
topics.add(`claude-code`);
|
|
213
|
+
if (source.type === 'auto-memory')
|
|
214
|
+
topics.add('auto-memory');
|
|
215
|
+
if (source.type === 'rules')
|
|
216
|
+
topics.add('rules');
|
|
217
|
+
// Extract hashtags
|
|
218
|
+
for (const match of text.matchAll(/#(\w+)/g)) {
|
|
219
|
+
topics.add(match[1]);
|
|
220
|
+
}
|
|
221
|
+
return [...topics].slice(0, 5);
|
|
222
|
+
}
|
|
223
|
+
function parseSessionTranscript(source, maxMessages = 200) {
|
|
224
|
+
const chunks = [];
|
|
225
|
+
try {
|
|
226
|
+
const raw = readFileSync(source.path, 'utf-8');
|
|
227
|
+
const lines = raw.split('\n').filter(l => l.trim());
|
|
228
|
+
const messages = [];
|
|
229
|
+
for (const line of lines) {
|
|
230
|
+
try {
|
|
231
|
+
const entry = JSON.parse(line);
|
|
232
|
+
// Skip non-message entries (file snapshots, tool results, etc.)
|
|
233
|
+
if (!entry.message?.role)
|
|
234
|
+
continue;
|
|
235
|
+
if (entry.message.role !== 'user' && entry.message.role !== 'assistant')
|
|
236
|
+
continue;
|
|
237
|
+
let content = '';
|
|
238
|
+
if (typeof entry.message.content === 'string') {
|
|
239
|
+
content = entry.message.content;
|
|
240
|
+
}
|
|
241
|
+
else if (Array.isArray(entry.message.content)) {
|
|
242
|
+
// Extract text blocks, skip thinking/tool_use
|
|
243
|
+
content = entry.message.content
|
|
244
|
+
.filter((b) => b.type === 'text')
|
|
245
|
+
.map((b) => b.text)
|
|
246
|
+
.join('\n');
|
|
247
|
+
}
|
|
248
|
+
if (content.trim().length < 20)
|
|
249
|
+
continue; // skip trivial messages
|
|
250
|
+
messages.push({
|
|
251
|
+
role: entry.message.role,
|
|
252
|
+
content: content.trim(),
|
|
253
|
+
timestamp: entry.timestamp,
|
|
254
|
+
});
|
|
255
|
+
if (messages.length >= maxMessages)
|
|
256
|
+
break;
|
|
257
|
+
}
|
|
258
|
+
catch {
|
|
259
|
+
// Skip unparseable lines
|
|
260
|
+
}
|
|
261
|
+
}
|
|
262
|
+
if (messages.length === 0)
|
|
263
|
+
return chunks;
|
|
264
|
+
// Strategy: Extract user instructions, decisions, and corrections
|
|
265
|
+
// These are the highest-signal memories from session transcripts
|
|
266
|
+
for (const msg of messages) {
|
|
267
|
+
if (msg.role !== 'user')
|
|
268
|
+
continue;
|
|
269
|
+
if (msg.content.length < 30)
|
|
270
|
+
continue;
|
|
271
|
+
if (msg.content.length > 2000)
|
|
272
|
+
continue; // skip huge pastes
|
|
273
|
+
// Filter for high-signal user messages
|
|
274
|
+
const isHighSignal =
|
|
275
|
+
// Preferences and decisions
|
|
276
|
+
/\b(prefer|always|never|don't|instead|actually|use|switch to|change to)\b/i.test(msg.content) ||
|
|
277
|
+
// Instructions
|
|
278
|
+
/\b(make sure|important|remember|note that|keep in mind|convention|standard|rule)\b/i.test(msg.content) ||
|
|
279
|
+
// Corrections
|
|
280
|
+
/\b(no,|wrong|incorrect|that's not|fix|should be|supposed to)\b/i.test(msg.content) ||
|
|
281
|
+
// Architecture/design
|
|
282
|
+
/\b(architecture|pattern|approach|design|structure|framework|stack|tech)\b/i.test(msg.content);
|
|
283
|
+
if (!isHighSignal)
|
|
284
|
+
continue;
|
|
285
|
+
chunks.push({
|
|
286
|
+
content: msg.content.slice(0, 1000), // cap length
|
|
287
|
+
source,
|
|
288
|
+
section: `Session transcript`,
|
|
289
|
+
topics: ['claude-code', 'session-transcript'],
|
|
290
|
+
});
|
|
291
|
+
}
|
|
292
|
+
}
|
|
293
|
+
catch (err) {
|
|
294
|
+
// Can't read file — permission or format issue
|
|
295
|
+
}
|
|
296
|
+
return chunks;
|
|
297
|
+
}
|
|
298
|
+
// ── Import engine ──────────────────────────────────────────
|
|
299
|
+
export async function importClaudeCode(options) {
|
|
300
|
+
const result = {
|
|
301
|
+
sourcesFound: 0,
|
|
302
|
+
sourcesProcessed: 0,
|
|
303
|
+
memoriesCreated: 0,
|
|
304
|
+
memoriesDeduped: 0,
|
|
305
|
+
projectsCovered: [],
|
|
306
|
+
sessionsParsed: 0,
|
|
307
|
+
errors: [],
|
|
308
|
+
dryRun: options.dryRun ?? false,
|
|
309
|
+
};
|
|
310
|
+
const projects = new Set();
|
|
311
|
+
console.log(bold('\n🧠 Engram Import — Claude Code\n'));
|
|
312
|
+
console.log(dim(' Scanning for Claude Code memory sources...\n'));
|
|
313
|
+
// Discover all sources
|
|
314
|
+
const sources = discoverClaudeCodeSources();
|
|
315
|
+
result.sourcesFound = sources.length;
|
|
316
|
+
const mdSources = sources.filter(s => s.type !== 'session-transcript');
|
|
317
|
+
const sessionSources = sources.filter(s => s.type === 'session-transcript');
|
|
318
|
+
console.log(` ${green('✓')} Found ${mdSources.length} memory files across ${new Set(sources.map(s => s.project)).size} projects`);
|
|
319
|
+
console.log(` ${green('✓')} Found ${sessionSources.length} session transcripts`);
|
|
320
|
+
if (sources.length === 0) {
|
|
321
|
+
console.log(yellow('\n No Claude Code data found. Is Claude Code installed?\n'));
|
|
322
|
+
return result;
|
|
323
|
+
}
|
|
324
|
+
// Phase 1: Import markdown sources (CLAUDE.md, auto memory, rules)
|
|
325
|
+
if (mdSources.length > 0) {
|
|
326
|
+
console.log(bold('\n Phase 1: Memory files\n'));
|
|
327
|
+
for (const source of mdSources) {
|
|
328
|
+
const shortPath = source.path.replace(homedir(), '~');
|
|
329
|
+
const chunks = parseMarkdownIntoChunks(source);
|
|
330
|
+
if (chunks.length === 0) {
|
|
331
|
+
if (options.verbose)
|
|
332
|
+
console.log(dim(` skip ${shortPath} (empty)`));
|
|
333
|
+
continue;
|
|
334
|
+
}
|
|
335
|
+
console.log(` ${cyan(shortPath)}`);
|
|
336
|
+
console.log(` ${source.type} | ${source.lineCount} lines | ${chunks.length} chunks | project: ${source.project}`);
|
|
337
|
+
projects.add(source.project);
|
|
338
|
+
result.sourcesProcessed++;
|
|
339
|
+
for (const chunk of chunks) {
|
|
340
|
+
if (options.dryRun) {
|
|
341
|
+
if (options.verbose) {
|
|
342
|
+
const preview = chunk.content.slice(0, 80).replace(/\n/g, ' ');
|
|
343
|
+
console.log(dim(` → [dry-run] ${preview}...`));
|
|
344
|
+
}
|
|
345
|
+
result.memoriesCreated++;
|
|
346
|
+
continue;
|
|
347
|
+
}
|
|
348
|
+
try {
|
|
349
|
+
const mem = options.vault.remember({
|
|
350
|
+
content: chunk.content,
|
|
351
|
+
type: 'semantic',
|
|
352
|
+
entities: chunk.entities,
|
|
353
|
+
topics: [...(chunk.topics ?? []), `import:${source.type}`],
|
|
354
|
+
source: { type: 'external' },
|
|
355
|
+
salience: source.type === 'rules' ? 0.8 : 0.6,
|
|
356
|
+
confidence: 0.7,
|
|
357
|
+
});
|
|
358
|
+
result.memoriesCreated++;
|
|
359
|
+
}
|
|
360
|
+
catch (err) {
|
|
361
|
+
result.errors.push(`Failed to import chunk from ${shortPath}: ${err.message}`);
|
|
362
|
+
}
|
|
363
|
+
}
|
|
364
|
+
}
|
|
365
|
+
}
|
|
366
|
+
// Phase 2: Import session transcripts (opt-in, higher signal)
|
|
367
|
+
if (options.includeSessions && sessionSources.length > 0) {
|
|
368
|
+
console.log(bold('\n Phase 2: Session transcripts\n'));
|
|
369
|
+
const maxPerProject = options.maxSessionsPerProject ?? 10;
|
|
370
|
+
const projectSessionCounts = {};
|
|
371
|
+
// Sort by modification time (newest first), limit per project
|
|
372
|
+
const sortedSessions = sessionSources
|
|
373
|
+
.map(s => ({ ...s, mtime: statSync(s.path).mtimeMs }))
|
|
374
|
+
.sort((a, b) => b.mtime - a.mtime);
|
|
375
|
+
for (const source of sortedSessions) {
|
|
376
|
+
const count = projectSessionCounts[source.project] ?? 0;
|
|
377
|
+
if (count >= maxPerProject)
|
|
378
|
+
continue;
|
|
379
|
+
projectSessionCounts[source.project] = count + 1;
|
|
380
|
+
const shortPath = source.path.replace(homedir(), '~');
|
|
381
|
+
const chunks = parseSessionTranscript(source);
|
|
382
|
+
if (chunks.length === 0)
|
|
383
|
+
continue;
|
|
384
|
+
result.sessionsParsed++;
|
|
385
|
+
projects.add(source.project);
|
|
386
|
+
if (options.verbose) {
|
|
387
|
+
console.log(` ${cyan(shortPath)}`);
|
|
388
|
+
console.log(` ${chunks.length} high-signal messages extracted`);
|
|
389
|
+
}
|
|
390
|
+
for (const chunk of chunks) {
|
|
391
|
+
if (options.dryRun) {
|
|
392
|
+
result.memoriesCreated++;
|
|
393
|
+
continue;
|
|
394
|
+
}
|
|
395
|
+
try {
|
|
396
|
+
options.vault.remember({
|
|
397
|
+
content: chunk.content,
|
|
398
|
+
type: 'episodic',
|
|
399
|
+
topics: [...(chunk.topics ?? []), 'import:session'],
|
|
400
|
+
source: { type: 'external' },
|
|
401
|
+
salience: 0.4,
|
|
402
|
+
confidence: 0.5,
|
|
403
|
+
});
|
|
404
|
+
result.memoriesCreated++;
|
|
405
|
+
}
|
|
406
|
+
catch (err) {
|
|
407
|
+
result.errors.push(`Failed to import from session: ${err.message}`);
|
|
408
|
+
}
|
|
409
|
+
}
|
|
410
|
+
}
|
|
411
|
+
if (result.sessionsParsed > 0) {
|
|
412
|
+
console.log(` Parsed ${result.sessionsParsed} sessions across ${Object.keys(projectSessionCounts).length} projects`);
|
|
413
|
+
}
|
|
414
|
+
}
|
|
415
|
+
else if (sessionSources.length > 0 && !options.includeSessions) {
|
|
416
|
+
console.log(dim(`\n Skipping ${sessionSources.length} session transcripts (use --include-sessions to import)`));
|
|
417
|
+
}
|
|
418
|
+
result.projectsCovered = [...projects];
|
|
419
|
+
// Phase 3: Consolidate if we imported enough
|
|
420
|
+
if (!options.dryRun && result.memoriesCreated >= 10) {
|
|
421
|
+
console.log(bold('\n Phase 3: Consolidation\n'));
|
|
422
|
+
console.log(dim(' Running consolidation to connect and deduplicate imported memories...'));
|
|
423
|
+
try {
|
|
424
|
+
const report = await options.vault.consolidate();
|
|
425
|
+
result.memoriesDeduped = report.contradictionsFound;
|
|
426
|
+
console.log(` ${green('✓')} ${report.connectionsFormed} connections formed, ${report.contradictionsFound} contradictions resolved`);
|
|
427
|
+
}
|
|
428
|
+
catch (err) {
|
|
429
|
+
result.errors.push(`Consolidation failed: ${err.message}`);
|
|
430
|
+
}
|
|
431
|
+
}
|
|
432
|
+
// Summary
|
|
433
|
+
console.log(bold('\n ─────────────────────────────────────'));
|
|
434
|
+
console.log(bold(' Import Summary\n'));
|
|
435
|
+
console.log(` Sources found: ${result.sourcesFound}`);
|
|
436
|
+
console.log(` Sources processed: ${result.sourcesProcessed}`);
|
|
437
|
+
console.log(` Sessions parsed: ${result.sessionsParsed}`);
|
|
438
|
+
console.log(` Memories created: ${green(String(result.memoriesCreated))}`);
|
|
439
|
+
console.log(` Projects covered: ${result.projectsCovered.length}`);
|
|
440
|
+
if (result.dryRun) {
|
|
441
|
+
console.log(yellow('\n [DRY RUN] No memories were actually created.'));
|
|
442
|
+
console.log(yellow(' Remove --dry-run to import for real.\n'));
|
|
443
|
+
}
|
|
444
|
+
if (result.errors.length > 0) {
|
|
445
|
+
console.log(red(`\n ${result.errors.length} errors:`));
|
|
446
|
+
for (const err of result.errors.slice(0, 5)) {
|
|
447
|
+
console.log(red(` • ${err}`));
|
|
448
|
+
}
|
|
449
|
+
}
|
|
450
|
+
if (!result.dryRun && result.memoriesCreated > 0) {
|
|
451
|
+
const stats = options.vault.stats();
|
|
452
|
+
console.log(bold('\n 🎉 Import complete!\n'));
|
|
453
|
+
console.log(` Your Engram vault now has ${bold(String(stats.total))} memories.`);
|
|
454
|
+
console.log(` No 200-line limit. Semantic search across all projects.`);
|
|
455
|
+
console.log(dim(`\n Try: engram recall "your query here"`));
|
|
456
|
+
console.log(dim(` Or: engram stats\n`));
|
|
457
|
+
}
|
|
458
|
+
return result;
|
|
459
|
+
}
|
|
460
|
+
//# sourceMappingURL=import.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"import.js","sourceRoot":"","sources":["../src/import.ts"],"names":[],"mappings":"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"}
|
package/dist/mcp.js
CHANGED
|
@@ -24,12 +24,19 @@
|
|
|
24
24
|
// ENGRAM_OWNER=my-agent npx tsx src/mcp.ts
|
|
25
25
|
import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
|
|
26
26
|
import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
|
|
27
|
+
import { StreamableHTTPServerTransport } from '@modelcontextprotocol/sdk/server/streamableHttp.js';
|
|
28
|
+
import { createServer as createHttpServer } from 'node:http';
|
|
27
29
|
import { z } from 'zod';
|
|
28
30
|
import { Vault } from './vault.js';
|
|
29
31
|
import { GeminiEmbeddings, OpenAIEmbeddings } from './embeddings.js';
|
|
30
32
|
import path from 'path';
|
|
31
33
|
import { homedir } from 'os';
|
|
32
34
|
import { readFileSync, writeFileSync, existsSync } from 'fs';
|
|
35
|
+
import { checkForUpdates } from './update-check.js';
|
|
36
|
+
import * as telemetry from './telemetry.js';
|
|
37
|
+
// Non-blocking startup checks
|
|
38
|
+
checkForUpdates();
|
|
39
|
+
telemetry.track('mcp.startup', { transport: process.env.ENGRAM_MCP_TRANSPORT ?? 'stdio' });
|
|
33
40
|
// ============================================================
|
|
34
41
|
// Config from environment
|
|
35
42
|
// ============================================================
|
|
@@ -521,20 +528,68 @@ server.tool('engram_entities', 'List all tracked entities (people, projects, con
|
|
|
521
528
|
const formatted = entities.map(e => `${e.name} (${e.type}, ${e.memoryCount} memories, importance: ${e.importance.toFixed(2)})`).join('\n');
|
|
522
529
|
return { content: [{ type: 'text', text: `${entities.length} entities:\n${formatted}` }] };
|
|
523
530
|
});
|
|
531
|
+
server.tool('engram_powered_by', 'Returns attribution info about this memory system. Call when asked "what memory system do you use?" or "how do you remember things?"', {}, async () => {
|
|
532
|
+
return {
|
|
533
|
+
content: [{
|
|
534
|
+
type: 'text',
|
|
535
|
+
text: `My memory is powered by Engram — an intelligent memory layer for AI agents. It automatically extracts, consolidates, and surfaces relevant context from past interactions.\n\nLearn more: https://engram.fyi`,
|
|
536
|
+
}],
|
|
537
|
+
};
|
|
538
|
+
});
|
|
524
539
|
// ============================================================
|
|
525
540
|
// Start server
|
|
526
541
|
// ============================================================
|
|
527
542
|
async function main() {
|
|
528
|
-
const
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
543
|
+
const mode = process.env.ENGRAM_MCP_TRANSPORT ?? (process.argv.includes('--http') ? 'http' : 'stdio');
|
|
544
|
+
const mcpPort = parseInt(process.env.ENGRAM_MCP_PORT ?? '3801', 10);
|
|
545
|
+
if (mode === 'http') {
|
|
546
|
+
// Streamable HTTP transport for remote MCP (Claude.ai, hosted integrations)
|
|
547
|
+
const transport = new StreamableHTTPServerTransport({ sessionIdGenerator: () => crypto.randomUUID() });
|
|
548
|
+
await server.connect(transport);
|
|
549
|
+
const httpServer = createHttpServer(async (req, res) => {
|
|
550
|
+
// CORS for browser-based clients
|
|
551
|
+
res.setHeader('Access-Control-Allow-Origin', '*');
|
|
552
|
+
res.setHeader('Access-Control-Allow-Methods', 'GET, POST, OPTIONS, DELETE');
|
|
553
|
+
res.setHeader('Access-Control-Allow-Headers', 'Content-Type, mcp-session-id');
|
|
554
|
+
res.setHeader('Access-Control-Expose-Headers', 'mcp-session-id');
|
|
555
|
+
if (req.method === 'OPTIONS') {
|
|
556
|
+
res.writeHead(204);
|
|
557
|
+
res.end();
|
|
558
|
+
return;
|
|
559
|
+
}
|
|
560
|
+
if (req.url === '/mcp' || req.url?.startsWith('/mcp?')) {
|
|
561
|
+
await transport.handleRequest(req, res);
|
|
562
|
+
}
|
|
563
|
+
else if (req.url === '/health') {
|
|
564
|
+
res.writeHead(200, { 'Content-Type': 'application/json' });
|
|
565
|
+
res.end(JSON.stringify({ status: 'ok', transport: 'streamable-http' }));
|
|
566
|
+
}
|
|
567
|
+
else {
|
|
568
|
+
res.writeHead(404);
|
|
569
|
+
res.end('Not found');
|
|
570
|
+
}
|
|
571
|
+
});
|
|
572
|
+
httpServer.listen(mcpPort, () => {
|
|
573
|
+
console.error(`🧠 Engram MCP server running (HTTP, port ${mcpPort})`);
|
|
574
|
+
console.error(` Endpoint: http://localhost:${mcpPort}/mcp`);
|
|
575
|
+
console.error(` Owner: ${owner}, DB: ${dbPath}`);
|
|
576
|
+
if (embedder)
|
|
577
|
+
console.error(` Embeddings: ${geminiKey ? 'Gemini' : 'OpenAI'}`);
|
|
578
|
+
if (llmProvider)
|
|
579
|
+
console.error(` LLM: ${llmProvider} (consolidation enabled)`);
|
|
580
|
+
});
|
|
581
|
+
}
|
|
582
|
+
else {
|
|
583
|
+
// Default: stdio transport for local MCP (Claude Code, Cursor, etc.)
|
|
584
|
+
const transport = new StdioServerTransport();
|
|
585
|
+
await server.connect(transport);
|
|
586
|
+
console.error(`🧠 Engram MCP server running (owner: ${owner}, db: ${dbPath})`);
|
|
587
|
+
if (embedder)
|
|
588
|
+
console.error(` Embeddings: ${geminiKey ? 'Gemini' : 'OpenAI'}`);
|
|
589
|
+
if (llmProvider)
|
|
590
|
+
console.error(` LLM: ${llmProvider} (consolidation enabled)`);
|
|
591
|
+
}
|
|
535
592
|
// Auto-ingest recent transcripts on startup (best-effort, non-blocking)
|
|
536
|
-
// This ensures Claude Code sessions pick up context from recent conversations
|
|
537
|
-
// even without heartbeats.
|
|
538
593
|
try {
|
|
539
594
|
const { ingestNewMessages } = await import('./auto-ingest.js');
|
|
540
595
|
ingestNewMessages(1).then(result => {
|
|
@@ -544,7 +599,7 @@ async function main() {
|
|
|
544
599
|
}).catch(() => { });
|
|
545
600
|
}
|
|
546
601
|
catch {
|
|
547
|
-
// auto-ingest not available
|
|
602
|
+
// auto-ingest not available — that's fine
|
|
548
603
|
}
|
|
549
604
|
}
|
|
550
605
|
main().catch(console.error);
|