@trlc/super-memory 1.3.5 ā 1.3.7
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/index.js +82 -3
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -22,7 +22,7 @@ import { homedir } from 'os';
|
|
|
22
22
|
import { join } from 'path';
|
|
23
23
|
import readline from 'readline';
|
|
24
24
|
const CONVEX_URL = 'https://clear-lemming-473.convex.cloud';
|
|
25
|
-
const VERSION = '1.3.
|
|
25
|
+
const VERSION = '1.3.7';
|
|
26
26
|
// Paths
|
|
27
27
|
const getBaseDir = () => join(homedir(), '.openclaw', 'workspace');
|
|
28
28
|
const getMemoryDir = () => join(getBaseDir(), 'memory');
|
|
@@ -349,7 +349,10 @@ You: [runs] super-memory save "User dislikes cilantro" --category=discovery
|
|
|
349
349
|
|
|
350
350
|
š¤ OpenClaw Integration:
|
|
351
351
|
Skill installed: ~/.openclaw/workspace/skills/super-memory/SKILL.md
|
|
352
|
-
|
|
352
|
+
|
|
353
|
+
š Optimization Guide:
|
|
354
|
+
Visit https://redlobstercartel.ai/super-memory/install
|
|
355
|
+
to learn how to optimize your Super Memory usage
|
|
353
356
|
|
|
354
357
|
š¦ Welcome to The Red Lobster Cartel!
|
|
355
358
|
`);
|
|
@@ -490,7 +493,50 @@ async function cmdSync(args) {
|
|
|
490
493
|
}
|
|
491
494
|
console.log('š Syncing with cloud...\n');
|
|
492
495
|
try {
|
|
493
|
-
//
|
|
496
|
+
// STEP 1: Push local memories to cloud
|
|
497
|
+
console.log('š¤ Checking for local memories to upload...');
|
|
498
|
+
const localMemories = getLocalMemoriesForSync();
|
|
499
|
+
let uploadedCount = 0;
|
|
500
|
+
for (const mem of localMemories) {
|
|
501
|
+
try {
|
|
502
|
+
// Generate salt for this memory
|
|
503
|
+
const salt = generateSalt();
|
|
504
|
+
// Encrypt content
|
|
505
|
+
const key = deriveKey(config.licenseKey, salt);
|
|
506
|
+
const encrypted = encrypt(mem.content, key);
|
|
507
|
+
if (!encrypted) {
|
|
508
|
+
console.warn(`ā ļø Failed to encrypt memory: ${mem.content.substring(0, 50)}...`);
|
|
509
|
+
continue;
|
|
510
|
+
}
|
|
511
|
+
// Push to cloud
|
|
512
|
+
const pushResponse = await fetch(`${CONVEX_URL}/api/mutation`, {
|
|
513
|
+
method: 'POST',
|
|
514
|
+
headers: { 'Content-Type': 'application/json' },
|
|
515
|
+
body: JSON.stringify({
|
|
516
|
+
path: 'memories:push',
|
|
517
|
+
args: {
|
|
518
|
+
licenseKey: config.licenseKey,
|
|
519
|
+
encryptedContent: encrypted.encrypted,
|
|
520
|
+
iv: encrypted.iv,
|
|
521
|
+
salt: salt,
|
|
522
|
+
category: mem.category,
|
|
523
|
+
timestamp: mem.timestamp,
|
|
524
|
+
},
|
|
525
|
+
}),
|
|
526
|
+
});
|
|
527
|
+
const pushResult = await pushResponse.json();
|
|
528
|
+
if (pushResult.status === 'success') {
|
|
529
|
+
uploadedCount++;
|
|
530
|
+
}
|
|
531
|
+
}
|
|
532
|
+
catch (err) {
|
|
533
|
+
console.warn(`ā ļø Error uploading memory: ${err}`);
|
|
534
|
+
}
|
|
535
|
+
}
|
|
536
|
+
if (uploadedCount > 0) {
|
|
537
|
+
console.log(`ā
Uploaded ${uploadedCount} memories to cloud\n`);
|
|
538
|
+
}
|
|
539
|
+
// STEP 2: Pull from cloud
|
|
494
540
|
const response = await fetch(`${CONVEX_URL}/api/query`, {
|
|
495
541
|
method: 'POST',
|
|
496
542
|
headers: { 'Content-Type': 'application/json' },
|
|
@@ -549,6 +595,7 @@ async function cmdSync(args) {
|
|
|
549
595
|
config.lastSyncAt = Date.now();
|
|
550
596
|
saveConfig(config);
|
|
551
597
|
console.log(`\nā
Sync complete!`);
|
|
598
|
+
console.log(` Uploaded: ${uploadedCount} memories`);
|
|
552
599
|
console.log(` Downloaded: ${syncedCount} memories`);
|
|
553
600
|
console.log(` Last sync: ${new Date().toLocaleString()}\n`);
|
|
554
601
|
}
|
|
@@ -653,6 +700,38 @@ function getLocalStats() {
|
|
|
653
700
|
}
|
|
654
701
|
return stats;
|
|
655
702
|
}
|
|
703
|
+
// Helper: Get local memories for sync (push to cloud)
|
|
704
|
+
function getLocalMemoriesForSync() {
|
|
705
|
+
const memories = [];
|
|
706
|
+
const memoryDir = getMemoryDir();
|
|
707
|
+
if (!existsSync(memoryDir))
|
|
708
|
+
return memories;
|
|
709
|
+
const files = readdirSync(memoryDir).filter(f => f.endsWith('.md') && !f.includes('INDEX'));
|
|
710
|
+
for (const file of files) {
|
|
711
|
+
const filePath = join(memoryDir, file);
|
|
712
|
+
const content = readFileSync(filePath, 'utf-8');
|
|
713
|
+
const lines = content.split('\n');
|
|
714
|
+
for (const line of lines) {
|
|
715
|
+
const emojiMatch = line.match(/^(š“|š”|š¤|š£)\s*\[?(GOTCHA|PROBLEM|DECISION|DISCOVERY)\]?\s*(.+)$/i);
|
|
716
|
+
if (emojiMatch) {
|
|
717
|
+
const emoji = emojiMatch[1];
|
|
718
|
+
const categoryMap = {
|
|
719
|
+
'š“': 'gotcha',
|
|
720
|
+
'š”': 'problem',
|
|
721
|
+
'š¤': 'decision',
|
|
722
|
+
'š£': 'discovery',
|
|
723
|
+
};
|
|
724
|
+
const category = categoryMap[emoji] || 'discovery';
|
|
725
|
+
const content = emojiMatch[3].trim();
|
|
726
|
+
// Extract timestamp from filename (YYYY-MM-DD.md)
|
|
727
|
+
const dateStr = file.replace('.md', '');
|
|
728
|
+
const timestamp = new Date(dateStr).getTime() || Date.now();
|
|
729
|
+
memories.push({ content, category, timestamp });
|
|
730
|
+
}
|
|
731
|
+
}
|
|
732
|
+
}
|
|
733
|
+
return memories;
|
|
734
|
+
}
|
|
656
735
|
// COMMAND: help
|
|
657
736
|
function cmdHelp() {
|
|
658
737
|
console.log(`
|