engram-sdk 0.5.7 → 0.6.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cli.js +215 -60
- package/dist/cli.js.map +1 -1
- package/dist/content-filter.d.ts +15 -0
- package/dist/content-filter.d.ts.map +1 -0
- package/dist/content-filter.js +48 -0
- package/dist/content-filter.js.map +1 -0
- package/dist/hosted-client.d.ts +35 -0
- package/dist/hosted-client.d.ts.map +1 -1
- package/dist/hosted-client.js +68 -0
- package/dist/hosted-client.js.map +1 -1
- package/dist/hosted.d.ts.map +1 -1
- package/dist/hosted.js +217 -0
- package/dist/hosted.js.map +1 -1
- package/dist/import.d.ts +4 -0
- package/dist/import.d.ts.map +1 -1
- package/dist/import.js +279 -1
- package/dist/import.js.map +1 -1
- package/dist/mcp.js +193 -71
- package/dist/mcp.js.map +1 -1
- package/dist/server.d.ts.map +1 -1
- package/dist/server.js +7 -1
- package/dist/server.js.map +1 -1
- package/dist/vault.d.ts +4 -1
- package/dist/vault.d.ts.map +1 -1
- package/dist/vault.js +16 -6
- package/dist/vault.js.map +1 -1
- package/eval-mrcr-data/mrcr-compare-results.json +1163 -0
- package/eval-mrcr-data/mrcr-index.json +1 -0
- package/eval-mrcr-data/mrcr-opus-progress.json +3202 -0
- package/eval-mrcr-data/mrcr-opus-results.json +3266 -0
- package/eval-mrcr-data/mrcr-opus-v2-progress.json +162 -0
- package/eval-mrcr-data/mrcr-opus-v2-results.json +226 -0
- package/eval-mrcr-data/mrcr-results.json +33635 -0
- package/package.json +1 -1
package/dist/cli.js
CHANGED
|
@@ -4,13 +4,67 @@ import { runEval } from './eval.js';
|
|
|
4
4
|
import { checkForUpdates, getVersion } from './update-check.js';
|
|
5
5
|
import * as telemetry from './telemetry.js';
|
|
6
6
|
import { renderTree as renderMemoryTree, animateGrowth } from './memory-tree.js';
|
|
7
|
-
import { HostedClient, getHostedConfig, setHostedConfig, clearHostedConfig, federatedRecall } from './hosted-client.js';
|
|
7
|
+
import { HostedClient, getHostedConfig, setHostedConfig, clearHostedConfig, federatedRecall, getWriteQueue } from './hosted-client.js';
|
|
8
|
+
import { classifySensitive } from './content-filter.js';
|
|
8
9
|
import path from 'path';
|
|
9
10
|
import { homedir } from 'os';
|
|
10
11
|
import { parseArgs } from 'util';
|
|
11
12
|
// ============================================================
|
|
12
13
|
// Engram CLI — Quick interface for testing & exploration
|
|
13
14
|
// ============================================================
|
|
15
|
+
function getEngramInstructions() {
|
|
16
|
+
return `
|
|
17
|
+
## Engram — Persistent Memory
|
|
18
|
+
|
|
19
|
+
You have Engram memory tools via MCP. **Use them proactively** — do not wait to be asked.
|
|
20
|
+
|
|
21
|
+
### Session Start
|
|
22
|
+
- ALWAYS call \`engram_briefing\` at the start of every session to load context from past sessions.
|
|
23
|
+
|
|
24
|
+
### What to Remember (call \`engram_remember\` immediately)
|
|
25
|
+
Store ANY of these the moment you encounter them — do not batch, do not wait:
|
|
26
|
+
|
|
27
|
+
**From the user:**
|
|
28
|
+
- Preferences, opinions, personal facts, decisions, corrections
|
|
29
|
+
- "I prefer X", "we decided Y", "actually it's Z"
|
|
30
|
+
|
|
31
|
+
**From your own work:**
|
|
32
|
+
- When you read a file and synthesize useful knowledge (style guides, architecture patterns, workflow rules) — store the synthesis
|
|
33
|
+
- When you figure out HOW the user works (communication style, review habits, tool preferences) — store the observation
|
|
34
|
+
- When you discover project conventions, naming patterns, or implicit rules — store them
|
|
35
|
+
- When you build something and learn what works vs what doesn't — store the lesson
|
|
36
|
+
|
|
37
|
+
**The rule:** If this knowledge would be useful in a future session, store it NOW. Don't assume you'll remember — you won't.
|
|
38
|
+
|
|
39
|
+
### Team Vault
|
|
40
|
+
- When connected to a hosted vault, memories are shared with your team by default
|
|
41
|
+
- Use \`engram_private_session\` if the user wants a confidential session (nothing leaves the local machine)
|
|
42
|
+
- Use \`engram_invite\` to add a teammate when asked ("add Brian to engram", "invite tyler@company.com")
|
|
43
|
+
- Recall always searches both local + shared vaults, so you see everything
|
|
44
|
+
|
|
45
|
+
### Asking Questions
|
|
46
|
+
- When you need to ANSWER a question from memory: call \`engram_ask\` — it returns a synthesized answer with confidence, not raw memories
|
|
47
|
+
- When you need raw memory objects for processing: call \`engram_recall\`
|
|
48
|
+
- Prefer \`engram_ask\` for user-facing answers, \`engram_recall\` for your own analysis
|
|
49
|
+
|
|
50
|
+
### Alerts
|
|
51
|
+
- Periodically call \`engram_alerts\` to check for pending commitments, stale follow-ups, and contradictions
|
|
52
|
+
- Alerts are included in \`engram_briefing\` automatically, but call separately if you need a quick check
|
|
53
|
+
|
|
54
|
+
### Auditing External Memory
|
|
55
|
+
- If you maintain a CLAUDE.md, MEMORY.md, or similar file: periodically call \`engram_audit\` with its contents
|
|
56
|
+
- It will flag any claims that are outdated or contradicted by newer vault data
|
|
57
|
+
|
|
58
|
+
### Before Compacting / Session End
|
|
59
|
+
- Before context compaction or ending a session, call \`engram_checkpoint\` with a summary of:
|
|
60
|
+
- Decisions made and their reasoning
|
|
61
|
+
- Facts learned or corrected (especially things that changed from what you previously knew)
|
|
62
|
+
- Commitments and next steps
|
|
63
|
+
- Current project state
|
|
64
|
+
- This extracts durable memories from your context window before it is lost
|
|
65
|
+
- Your context window is the most accurate source of truth you have — and the most volatile. Save it.
|
|
66
|
+
`;
|
|
67
|
+
}
|
|
14
68
|
const HELP = `
|
|
15
69
|
engram — Universal memory layer for AI agents
|
|
16
70
|
|
|
@@ -18,6 +72,7 @@ Usage:
|
|
|
18
72
|
engram init Set up Engram for Claude Code / Cursor / VS Code / Gemini CLI / Codex
|
|
19
73
|
engram setup Alias for init
|
|
20
74
|
engram import --claude-code Import memory from Claude Code (no 200-line limit)
|
|
75
|
+
engram import --obsidian <path> Import an Obsidian vault (wikilinks, tags, frontmatter)
|
|
21
76
|
engram mcp Start the MCP server (stdio transport)
|
|
22
77
|
engram mcp --http Start the MCP server (HTTP transport, port 3801)
|
|
23
78
|
engram shadow start Start shadow mode (server + watcher, background)
|
|
@@ -37,6 +92,7 @@ Usage:
|
|
|
37
92
|
engram telemetry show View telemetry status and pending events
|
|
38
93
|
engram connect <url> --api-key <k> Connect to a hosted vault
|
|
39
94
|
engram disconnect Disconnect from hosted vault
|
|
95
|
+
engram invite <email> Invite a teammate to your shared vault
|
|
40
96
|
engram config set telemetry false Opt out of anonymous usage data
|
|
41
97
|
engram config get telemetry Check telemetry status
|
|
42
98
|
|
|
@@ -70,6 +126,7 @@ function parseCliArgs() {
|
|
|
70
126
|
salience: { type: 'string', default: '' },
|
|
71
127
|
confidence: { type: 'string', default: '' },
|
|
72
128
|
'claude-code': { type: 'boolean', default: false },
|
|
129
|
+
obsidian: { type: 'string', default: '' },
|
|
73
130
|
'include-sessions': { type: 'boolean', default: false },
|
|
74
131
|
'dry-run': { type: 'boolean', default: false },
|
|
75
132
|
'max-sessions': { type: 'string', default: '10' },
|
|
@@ -78,7 +135,10 @@ function parseCliArgs() {
|
|
|
78
135
|
private: { type: 'boolean', default: false },
|
|
79
136
|
local: { type: 'boolean', default: false },
|
|
80
137
|
'api-key': { type: 'string', default: '' },
|
|
138
|
+
role: { type: 'string', default: 'member' },
|
|
81
139
|
verbose: { type: 'boolean', default: false },
|
|
140
|
+
all: { type: 'boolean', default: false },
|
|
141
|
+
since: { type: 'string', default: '' },
|
|
82
142
|
},
|
|
83
143
|
});
|
|
84
144
|
return { values, positionals };
|
|
@@ -403,51 +463,7 @@ async function runInit(values) {
|
|
|
403
463
|
// 5. Add Engram instructions to CLAUDE.md (if Claude dir exists)
|
|
404
464
|
if (hasClaudeDir) {
|
|
405
465
|
const claudeMdPath = join(home, '.claude', 'CLAUDE.md');
|
|
406
|
-
const engramBlock =
|
|
407
|
-
## Engram — Persistent Memory
|
|
408
|
-
|
|
409
|
-
You have Engram memory tools via MCP. **Use them proactively** — do not wait to be asked.
|
|
410
|
-
|
|
411
|
-
### Session Start
|
|
412
|
-
- ALWAYS call \`engram_briefing\` at the start of every session to load context from past sessions.
|
|
413
|
-
|
|
414
|
-
### What to Remember (call \`engram_remember\` immediately)
|
|
415
|
-
Store ANY of these the moment you encounter them — do not batch, do not wait:
|
|
416
|
-
|
|
417
|
-
**From the user:**
|
|
418
|
-
- Preferences, opinions, personal facts, decisions, corrections
|
|
419
|
-
- "I prefer X", "we decided Y", "actually it's Z"
|
|
420
|
-
|
|
421
|
-
**From your own work:**
|
|
422
|
-
- When you read a file and synthesize useful knowledge (style guides, architecture patterns, workflow rules) — store the synthesis
|
|
423
|
-
- When you figure out HOW the user works (communication style, review habits, tool preferences) — store the observation
|
|
424
|
-
- When you discover project conventions, naming patterns, or implicit rules — store them
|
|
425
|
-
- When you build something and learn what works vs what doesn't — store the lesson
|
|
426
|
-
|
|
427
|
-
**The rule:** If this knowledge would be useful in a future session, store it NOW. Don't assume you'll remember — you won't.
|
|
428
|
-
|
|
429
|
-
### Asking Questions
|
|
430
|
-
- When you need to ANSWER a question from memory: call \`engram_ask\` — it returns a synthesized answer with confidence, not raw memories
|
|
431
|
-
- When you need raw memory objects for processing: call \`engram_recall\`
|
|
432
|
-
- Prefer \`engram_ask\` for user-facing answers, \`engram_recall\` for your own analysis
|
|
433
|
-
|
|
434
|
-
### Alerts
|
|
435
|
-
- Periodically call \`engram_alerts\` to check for pending commitments, stale follow-ups, and contradictions
|
|
436
|
-
- Alerts are included in \`engram_briefing\` automatically, but call separately if you need a quick check
|
|
437
|
-
|
|
438
|
-
### Auditing External Memory
|
|
439
|
-
- If you maintain a CLAUDE.md, MEMORY.md, or similar file: periodically call \`engram_audit\` with its contents
|
|
440
|
-
- It will flag any claims that are outdated or contradicted by newer vault data
|
|
441
|
-
|
|
442
|
-
### Before Compacting / Session End
|
|
443
|
-
- Before context compaction or ending a session, call \`engram_checkpoint\` with a summary of:
|
|
444
|
-
- Decisions made and their reasoning
|
|
445
|
-
- Facts learned or corrected (especially things that changed from what you previously knew)
|
|
446
|
-
- Commitments and next steps
|
|
447
|
-
- Current project state
|
|
448
|
-
- This extracts durable memories from your context window before it is lost
|
|
449
|
-
- Your context window is the most accurate source of truth you have — and the most volatile. Save it.
|
|
450
|
-
`;
|
|
466
|
+
const engramBlock = getEngramInstructions();
|
|
451
467
|
let claudeMd = '';
|
|
452
468
|
if (existsSync(claudeMdPath)) {
|
|
453
469
|
claudeMd = readFileSync(claudeMdPath, 'utf-8');
|
|
@@ -497,6 +513,9 @@ Store ANY of these the moment you encounter them — do not batch, do not wait:
|
|
|
497
513
|
'mcp__engram__engram_entities',
|
|
498
514
|
'mcp__engram__engram_stats',
|
|
499
515
|
'mcp__engram__engram_ingest',
|
|
516
|
+
'mcp__engram__engram_private_session',
|
|
517
|
+
'mcp__engram__engram_shared_session',
|
|
518
|
+
'mcp__engram__engram_invite',
|
|
500
519
|
];
|
|
501
520
|
let added = 0;
|
|
502
521
|
for (const tool of engramTools) {
|
|
@@ -913,6 +932,24 @@ async function main() {
|
|
|
913
932
|
await vault.close();
|
|
914
933
|
}
|
|
915
934
|
}
|
|
935
|
+
else if (values.obsidian) {
|
|
936
|
+
const { importObsidian } = await import('./import.js');
|
|
937
|
+
const vault = createVault(values);
|
|
938
|
+
try {
|
|
939
|
+
const result = await importObsidian({
|
|
940
|
+
vault,
|
|
941
|
+
vaultPath: values.obsidian,
|
|
942
|
+
dryRun: values['dry-run'],
|
|
943
|
+
verbose: values.verbose,
|
|
944
|
+
});
|
|
945
|
+
if (values.json) {
|
|
946
|
+
console.log(JSON.stringify(result, null, 2));
|
|
947
|
+
}
|
|
948
|
+
}
|
|
949
|
+
finally {
|
|
950
|
+
await vault.close();
|
|
951
|
+
}
|
|
952
|
+
}
|
|
916
953
|
else {
|
|
917
954
|
console.log(`
|
|
918
955
|
engram import — Migrate memory from other AI tools
|
|
@@ -922,6 +959,8 @@ Usage:
|
|
|
922
959
|
engram import --claude-code --dry-run Preview what would be imported
|
|
923
960
|
engram import --claude-code --include-sessions Also parse session transcripts
|
|
924
961
|
engram import --claude-code --verbose Show detailed progress
|
|
962
|
+
engram import --obsidian /path/to/vault Import from an Obsidian vault
|
|
963
|
+
engram import --obsidian ~/vault --dry-run Preview what would be imported
|
|
925
964
|
|
|
926
965
|
Options:
|
|
927
966
|
--include-sessions Parse JSONL session transcripts for high-signal messages
|
|
@@ -1046,12 +1085,62 @@ Engram has no limit, semantic search, and cross-project intelligence.
|
|
|
1046
1085
|
console.log(green('✓ API key verified'));
|
|
1047
1086
|
setHostedConfig(url, apiKey);
|
|
1048
1087
|
console.log(green('\n✓ Saved to ~/.config/engram/config.json'));
|
|
1049
|
-
|
|
1050
|
-
|
|
1051
|
-
|
|
1052
|
-
|
|
1053
|
-
|
|
1054
|
-
|
|
1088
|
+
// Auto-setup agent instructions if not already done
|
|
1089
|
+
const { existsSync, readFileSync, writeFileSync } = await import('fs');
|
|
1090
|
+
const { join } = await import('path');
|
|
1091
|
+
const home = homedir();
|
|
1092
|
+
const claudeDir = join(home, '.claude');
|
|
1093
|
+
const claudeMdPath = join(claudeDir, 'CLAUDE.md');
|
|
1094
|
+
if (existsSync(claudeDir)) {
|
|
1095
|
+
let claudeMd = existsSync(claudeMdPath) ? readFileSync(claudeMdPath, 'utf-8') : '';
|
|
1096
|
+
if (!claudeMd.includes('## Engram')) {
|
|
1097
|
+
console.log('\n📋 Setting up agent instructions...');
|
|
1098
|
+
// Run init-style CLAUDE.md setup
|
|
1099
|
+
const engramBlock = getEngramInstructions();
|
|
1100
|
+
writeFileSync(claudeMdPath, claudeMd + '\n' + engramBlock.trim() + '\n');
|
|
1101
|
+
console.log(green(' ✓ Added Engram instructions to ~/.claude/CLAUDE.md'));
|
|
1102
|
+
console.log(' Your agent will now use Engram proactively in every session.');
|
|
1103
|
+
}
|
|
1104
|
+
// Auto-approve MCP tools in Claude Code settings
|
|
1105
|
+
const settingsPath = join(claudeDir, 'settings.json');
|
|
1106
|
+
if (existsSync(settingsPath)) {
|
|
1107
|
+
try {
|
|
1108
|
+
const settings = JSON.parse(readFileSync(settingsPath, 'utf-8'));
|
|
1109
|
+
const allow = settings.permissions?.allow ?? [];
|
|
1110
|
+
const engramTools = [
|
|
1111
|
+
'mcp__engram__engram_remember', 'mcp__engram__engram_recall',
|
|
1112
|
+
'mcp__engram__engram_surface', 'mcp__engram__engram_briefing',
|
|
1113
|
+
'mcp__engram__engram_consolidate', 'mcp__engram__engram_connect',
|
|
1114
|
+
'mcp__engram__engram_forget', 'mcp__engram__engram_entities',
|
|
1115
|
+
'mcp__engram__engram_stats', 'mcp__engram__engram_ingest',
|
|
1116
|
+
'mcp__engram__engram_private_session', 'mcp__engram__engram_shared_session',
|
|
1117
|
+
'mcp__engram__engram_invite',
|
|
1118
|
+
];
|
|
1119
|
+
let added = 0;
|
|
1120
|
+
for (const tool of engramTools) {
|
|
1121
|
+
if (!allow.includes(tool)) {
|
|
1122
|
+
allow.push(tool);
|
|
1123
|
+
added++;
|
|
1124
|
+
}
|
|
1125
|
+
}
|
|
1126
|
+
if (added > 0) {
|
|
1127
|
+
if (!settings.permissions)
|
|
1128
|
+
settings.permissions = {};
|
|
1129
|
+
settings.permissions.allow = allow;
|
|
1130
|
+
writeFileSync(settingsPath, JSON.stringify(settings, null, 2));
|
|
1131
|
+
console.log(green(` ✓ Auto-approved ${added} Engram tools in Claude Code`));
|
|
1132
|
+
}
|
|
1133
|
+
}
|
|
1134
|
+
catch { /* settings parse error, skip */ }
|
|
1135
|
+
}
|
|
1136
|
+
}
|
|
1137
|
+
console.log('\n✅ You\'re all set! Your agent will now:');
|
|
1138
|
+
console.log(' • Store memories to the shared team vault automatically');
|
|
1139
|
+
console.log(' • Recall context from both local + shared vaults');
|
|
1140
|
+
console.log(' • Use /engram-private to switch a session to local-only mode');
|
|
1141
|
+
console.log('');
|
|
1142
|
+
console.log(` 📊 View your team dashboard at ${green('https://app.engram.fyi')}`);
|
|
1143
|
+
console.log('');
|
|
1055
1144
|
}
|
|
1056
1145
|
catch (err) {
|
|
1057
1146
|
console.error(`\n✗ Connection failed: ${err.message}`);
|
|
@@ -1059,6 +1148,34 @@ Engram has no limit, semantic search, and cross-project intelligence.
|
|
|
1059
1148
|
}
|
|
1060
1149
|
return;
|
|
1061
1150
|
}
|
|
1151
|
+
if (command === 'invite') {
|
|
1152
|
+
const email = positionals[1];
|
|
1153
|
+
if (!email) {
|
|
1154
|
+
console.error('Usage: engram invite <email> [--role member|readonly]');
|
|
1155
|
+
process.exit(1);
|
|
1156
|
+
}
|
|
1157
|
+
const hostedConfig = getHostedConfig();
|
|
1158
|
+
if (!hostedConfig) {
|
|
1159
|
+
console.error('Error: not connected to a hosted vault. Run: engram connect <url> --api-key <key>');
|
|
1160
|
+
process.exit(1);
|
|
1161
|
+
}
|
|
1162
|
+
try {
|
|
1163
|
+
const client = new HostedClient(hostedConfig);
|
|
1164
|
+
const role = values.role ?? 'member';
|
|
1165
|
+
const result = await client.invite(email, role);
|
|
1166
|
+
console.log(green(`✓ ${result.message}`));
|
|
1167
|
+
console.log(`\nSend them this:\n`);
|
|
1168
|
+
console.log(` npm install -g engram-sdk@latest`);
|
|
1169
|
+
console.log(` engram connect https://api.engram.fyi --api-key ${result.account.apiKey}`);
|
|
1170
|
+
console.log(`\nThat's it — their agent will automatically share memories with the team.`);
|
|
1171
|
+
console.log(`Team dashboard: ${green('https://app.engram.fyi')}`);
|
|
1172
|
+
}
|
|
1173
|
+
catch (err) {
|
|
1174
|
+
console.error(`Error: ${err.message}`);
|
|
1175
|
+
process.exit(1);
|
|
1176
|
+
}
|
|
1177
|
+
return;
|
|
1178
|
+
}
|
|
1062
1179
|
if (command === 'disconnect') {
|
|
1063
1180
|
const existing = getHostedConfig();
|
|
1064
1181
|
if (!existing) {
|
|
@@ -1108,14 +1225,50 @@ Engram has no limit, semantic search, and cross-project intelligence.
|
|
|
1108
1225
|
input.salience = parseFloat(values.salience);
|
|
1109
1226
|
if (values.confidence)
|
|
1110
1227
|
input.confidence = parseFloat(values.confidence);
|
|
1111
|
-
|
|
1112
|
-
|
|
1113
|
-
|
|
1228
|
+
// Always write locally first (write-through)
|
|
1229
|
+
const localVault = createVault(values);
|
|
1230
|
+
const localMem = localVault.remember(input);
|
|
1231
|
+
// Check for sensitive content before hosted write
|
|
1232
|
+
const sensitivity = classifySensitive(text);
|
|
1233
|
+
if (sensitivity.sensitive) {
|
|
1234
|
+
if (values.json) {
|
|
1235
|
+
console.log(JSON.stringify({ ...localMem, warning: `Stored locally only — sensitive content detected (${sensitivity.reason})` }, null, 2));
|
|
1236
|
+
}
|
|
1237
|
+
else {
|
|
1238
|
+
console.log(yellow(`⚠️ Stored locally only — sensitive content detected (${sensitivity.reason})`));
|
|
1239
|
+
printMemory(localMem, false);
|
|
1240
|
+
}
|
|
1241
|
+
await localVault.close();
|
|
1242
|
+
return;
|
|
1114
1243
|
}
|
|
1115
|
-
|
|
1116
|
-
|
|
1117
|
-
|
|
1244
|
+
// Write-through to hosted (async with retry queue)
|
|
1245
|
+
try {
|
|
1246
|
+
const mem = await client.remember(input);
|
|
1247
|
+
if (values.json) {
|
|
1248
|
+
console.log(JSON.stringify(mem, null, 2));
|
|
1249
|
+
}
|
|
1250
|
+
else {
|
|
1251
|
+
console.log(green('✓ Remembered (local + shared):'));
|
|
1252
|
+
printMemory(mem, false);
|
|
1253
|
+
}
|
|
1254
|
+
}
|
|
1255
|
+
catch (err) {
|
|
1256
|
+
getWriteQueue().enqueue(input);
|
|
1257
|
+
if (values.json) {
|
|
1258
|
+
console.log(JSON.stringify(localMem, null, 2));
|
|
1259
|
+
}
|
|
1260
|
+
else {
|
|
1261
|
+
console.log(yellow(`⚠️ Hosted write failed (queued for retry): ${err.message}`));
|
|
1262
|
+
console.log(green('✓ Remembered locally:'));
|
|
1263
|
+
printMemory(localMem, false);
|
|
1264
|
+
}
|
|
1265
|
+
}
|
|
1266
|
+
// Flush any queued writes
|
|
1267
|
+
const wq = getWriteQueue();
|
|
1268
|
+
if (wq.length > 0) {
|
|
1269
|
+
wq.flush(client).catch(() => { });
|
|
1118
1270
|
}
|
|
1271
|
+
await localVault.close();
|
|
1119
1272
|
return;
|
|
1120
1273
|
}
|
|
1121
1274
|
case 'stats': {
|
|
@@ -1365,8 +1518,10 @@ Engram has no limit, semantic search, and cross-project intelligence.
|
|
|
1365
1518
|
}
|
|
1366
1519
|
case 'sleep':
|
|
1367
1520
|
case 'consolidate': {
|
|
1368
|
-
|
|
1369
|
-
const
|
|
1521
|
+
const allFlag = values.all ?? process.argv.includes('--all');
|
|
1522
|
+
const sinceFlag = (values.since || undefined);
|
|
1523
|
+
console.log(yellow(`⏳ Running consolidation${allFlag ? ' (all episodes)' : sinceFlag ? ` (since ${sinceFlag})` : ''}...`));
|
|
1524
|
+
const report = await vault.consolidate({ all: !!allFlag, since: sinceFlag });
|
|
1370
1525
|
if (values.json) {
|
|
1371
1526
|
console.log(JSON.stringify(report, null, 2));
|
|
1372
1527
|
}
|