@trlc/super-memory 1.3.8 → 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 +55 -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.8';
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,6 +529,11 @@ 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
+ });
530
537
  // Log audit
531
538
  await fetch(`${CONVEX_URL}/api/mutation`, {
532
539
  method: 'POST',
@@ -548,6 +555,21 @@ async function cmdSync(args) {
548
555
  console.warn(`⚠️ Error uploading memory: ${err}`);
549
556
  }
550
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
+ }
551
573
  if (uploadedCount > 0) {
552
574
  console.log(`✅ Uploaded ${uploadedCount} memories to cloud\n`);
553
575
  }
@@ -731,6 +753,7 @@ function getLocalStats() {
731
753
  return stats;
732
754
  }
733
755
  // Helper: Get local memories for sync (push to cloud)
756
+ // Now tracks file/line and ignores already synced memories
734
757
  function getLocalMemoriesForSync() {
735
758
  const memories = [];
736
759
  const memoryDir = getMemoryDir();
@@ -741,9 +764,16 @@ function getLocalMemoriesForSync() {
741
764
  const filePath = join(memoryDir, file);
742
765
  const content = readFileSync(filePath, 'utf-8');
743
766
  const lines = content.split('\n');
744
- for (const line of lines) {
767
+ for (let i = 0; i < lines.length; i++) {
768
+ const line = lines[i];
745
769
  const emojiMatch = line.match(/^(🔴|🟡|🟤|🟣)\s*\[?(GOTCHA|PROBLEM|DECISION|DISCOVERY)\]?\s*(.+)$/i);
746
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
+ }
747
777
  const emoji = emojiMatch[1];
748
778
  const categoryMap = {
749
779
  '🔴': 'gotcha',
@@ -752,16 +782,37 @@ function getLocalMemoriesForSync() {
752
782
  '🟣': 'discovery',
753
783
  };
754
784
  const category = categoryMap[emoji] || 'discovery';
755
- const content = emojiMatch[3].trim();
785
+ const memContent = emojiMatch[3].trim();
756
786
  // Extract timestamp from filename (YYYY-MM-DD.md)
757
787
  const dateStr = file.replace('.md', '');
758
788
  const timestamp = new Date(dateStr).getTime() || Date.now();
759
- memories.push({ content, category, timestamp });
789
+ memories.push({
790
+ content: memContent,
791
+ category,
792
+ timestamp,
793
+ filePath,
794
+ lineIndex: i
795
+ });
760
796
  }
761
797
  }
762
798
  }
763
799
  return memories;
764
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
+ }
765
816
  // COMMAND: help
766
817
  function cmdHelp() {
767
818
  console.log(`
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@trlc/super-memory",
3
- "version": "1.3.8",
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": {