@trlc/super-memory 1.3.7 → 1.3.9

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.
Files changed (2) hide show
  1. package/dist/index.js +85 -4
  2. 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.7';
25
+ const VERSION = '1.3.9';
26
26
  // Paths
27
27
  const getBaseDir = () => join(homedir(), '.openclaw', 'workspace');
28
28
  const getMemoryDir = () => join(getBaseDir(), 'memory');
@@ -497,6 +497,8 @@ async function cmdSync(args) {
497
497
  console.log('📤 Checking for local memories to upload...');
498
498
  const localMemories = getLocalMemoriesForSync();
499
499
  let uploadedCount = 0;
500
+ // Track successful uploads to mark as synced (with offset adjustment)
501
+ const successfulUploads = [];
500
502
  for (const mem of localMemories) {
501
503
  try {
502
504
  // Generate salt for this memory
@@ -527,12 +529,47 @@ async function cmdSync(args) {
527
529
  const pushResult = await pushResponse.json();
528
530
  if (pushResult.status === 'success') {
529
531
  uploadedCount++;
532
+ // Track for marking as synced
533
+ successfulUploads.push({
534
+ filePath: mem.filePath,
535
+ lineIndex: mem.lineIndex
536
+ });
537
+ // Log audit
538
+ await fetch(`${CONVEX_URL}/api/mutation`, {
539
+ method: 'POST',
540
+ headers: { 'Content-Type': 'application/json' },
541
+ body: JSON.stringify({
542
+ path: 'audit:logCli',
543
+ args: {
544
+ licenseKey: config.licenseKey,
545
+ action: 'memory_save',
546
+ details: `Saved ${mem.category}: ${mem.content.substring(0, 50)}...`,
547
+ ipAddress: 'cli',
548
+ deviceInfo: config.deviceId,
549
+ },
550
+ }),
551
+ });
530
552
  }
531
553
  }
532
554
  catch (err) {
533
555
  console.warn(`⚠️ Error uploading memory: ${err}`);
534
556
  }
535
557
  }
558
+ // Mark all successfully uploaded memories as synced
559
+ // Process by file to handle line index offsets correctly
560
+ const uploadsByFile = new Map();
561
+ for (const upload of successfulUploads) {
562
+ const existing = uploadsByFile.get(upload.filePath) || [];
563
+ existing.push(upload.lineIndex);
564
+ uploadsByFile.set(upload.filePath, existing);
565
+ }
566
+ for (const [filePath, lineIndexes] of uploadsByFile) {
567
+ // Sort in reverse order to prevent index shifting issues
568
+ const sortedIndexes = lineIndexes.sort((a, b) => b - a);
569
+ for (const lineIndex of sortedIndexes) {
570
+ markMemoryAsSynced(filePath, lineIndex);
571
+ }
572
+ }
536
573
  if (uploadedCount > 0) {
537
574
  console.log(`✅ Uploaded ${uploadedCount} memories to cloud\n`);
538
575
  }
@@ -598,6 +635,21 @@ async function cmdSync(args) {
598
635
  console.log(` Uploaded: ${uploadedCount} memories`);
599
636
  console.log(` Downloaded: ${syncedCount} memories`);
600
637
  console.log(` Last sync: ${new Date().toLocaleString()}\n`);
638
+ // Log sync audit
639
+ await fetch(`${CONVEX_URL}/api/mutation`, {
640
+ method: 'POST',
641
+ headers: { 'Content-Type': 'application/json' },
642
+ body: JSON.stringify({
643
+ path: 'audit:logCli',
644
+ args: {
645
+ licenseKey: config.licenseKey,
646
+ action: 'sync_push',
647
+ details: `Sync: ${uploadedCount} up, ${syncedCount} down`,
648
+ ipAddress: 'cli',
649
+ deviceInfo: config.deviceId,
650
+ },
651
+ }),
652
+ });
601
653
  }
602
654
  catch (error) {
603
655
  console.error(`❌ Sync failed: ${error.message}\n`);
@@ -701,6 +753,7 @@ function getLocalStats() {
701
753
  return stats;
702
754
  }
703
755
  // Helper: Get local memories for sync (push to cloud)
756
+ // Now tracks file/line and ignores already synced memories
704
757
  function getLocalMemoriesForSync() {
705
758
  const memories = [];
706
759
  const memoryDir = getMemoryDir();
@@ -711,9 +764,16 @@ function getLocalMemoriesForSync() {
711
764
  const filePath = join(memoryDir, file);
712
765
  const content = readFileSync(filePath, 'utf-8');
713
766
  const lines = content.split('\n');
714
- for (const line of lines) {
767
+ for (let i = 0; i < lines.length; i++) {
768
+ const line = lines[i];
715
769
  const emojiMatch = line.match(/^(🔴|🟡|🟤|🟣)\s*\[?(GOTCHA|PROBLEM|DECISION|DISCOVERY)\]?\s*(.+)$/i);
716
770
  if (emojiMatch) {
771
+ // Check if next line is a sync marker
772
+ const nextLine = lines[i + 1] || '';
773
+ if (nextLine.trim().startsWith('<!-- synced:')) {
774
+ // Already synced, skip this memory
775
+ continue;
776
+ }
717
777
  const emoji = emojiMatch[1];
718
778
  const categoryMap = {
719
779
  '🔴': 'gotcha',
@@ -722,16 +782,37 @@ function getLocalMemoriesForSync() {
722
782
  '🟣': 'discovery',
723
783
  };
724
784
  const category = categoryMap[emoji] || 'discovery';
725
- const content = emojiMatch[3].trim();
785
+ const memContent = emojiMatch[3].trim();
726
786
  // Extract timestamp from filename (YYYY-MM-DD.md)
727
787
  const dateStr = file.replace('.md', '');
728
788
  const timestamp = new Date(dateStr).getTime() || Date.now();
729
- memories.push({ content, category, timestamp });
789
+ memories.push({
790
+ content: memContent,
791
+ category,
792
+ timestamp,
793
+ filePath,
794
+ lineIndex: i
795
+ });
730
796
  }
731
797
  }
732
798
  }
733
799
  return memories;
734
800
  }
801
+ // Helper: Mark a memory as synced by adding marker after the line
802
+ function markMemoryAsSynced(filePath, lineIndex) {
803
+ try {
804
+ const content = readFileSync(filePath, 'utf-8');
805
+ const lines = content.split('\n');
806
+ // Create sync marker with ISO timestamp
807
+ const syncMarker = `<!-- synced: ${new Date().toISOString()} -->`;
808
+ // Insert marker after the memory line
809
+ lines.splice(lineIndex + 1, 0, syncMarker);
810
+ writeFileSync(filePath, lines.join('\n'));
811
+ }
812
+ catch (err) {
813
+ console.warn(`⚠️ Failed to mark memory as synced: ${err}`);
814
+ }
815
+ }
735
816
  // COMMAND: help
736
817
  function cmdHelp() {
737
818
  console.log(`
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@trlc/super-memory",
3
- "version": "1.3.7",
3
+ "version": "1.3.9",
4
4
  "description": "Super Memory CLI - AI-powered persistent memory by The Red Lobster Cartel",
5
5
  "main": "dist/index.js",
6
6
  "bin": {