@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.
- package/dist/index.js +55 -4
- 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.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 (
|
|
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
|
|
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({
|
|
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(`
|