memory-lucia 2.0.0
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/LICENSE +21 -0
- package/NPM-PUBLISH-GUIDE.md +169 -0
- package/PUBLISH-STEPS.md +102 -0
- package/README.md +64 -0
- package/SKILL.md +120 -0
- package/api/index.js +255 -0
- package/database/init.js +137 -0
- package/modules/decision.js +267 -0
- package/modules/evolution.js +286 -0
- package/modules/learning.js +267 -0
- package/modules/priority.js +174 -0
- package/modules/version.js +286 -0
- package/package.json +35 -0
- package/publish-with-otp.bat +13 -0
- package/publish.bat +17 -0
- package/publish.sh +20 -0
- package/scripts/init-memory.js +30 -0
|
@@ -0,0 +1,174 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Priority Module
|
|
3
|
+
* Automatic message priority classification and scoring
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
class PriorityModule {
|
|
7
|
+
constructor(db) {
|
|
8
|
+
this.db = db;
|
|
9
|
+
this.keywords = {
|
|
10
|
+
critical: ['urgent', 'emergency', 'critical', 'asap', 'immediately', 'deadline', 'blocked'],
|
|
11
|
+
high: ['important', 'priority', 'required', 'needed', 'should', 'recommend'],
|
|
12
|
+
medium: ['consider', 'maybe', 'optional', 'suggestion', 'idea'],
|
|
13
|
+
low: ['nice to have', 'someday', 'eventually', 'wish', 'dream']
|
|
14
|
+
};
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* Analyze message and determine priority
|
|
19
|
+
* @param {string} message - Message content
|
|
20
|
+
* @param {object} context - Additional context
|
|
21
|
+
* @returns {object} Priority analysis result
|
|
22
|
+
*/
|
|
23
|
+
async analyze(message, context = {}) {
|
|
24
|
+
const content = message.toLowerCase();
|
|
25
|
+
let priorityLevel = 4; // Default: Low
|
|
26
|
+
let importanceScore = 0;
|
|
27
|
+
const detectedKeywords = [];
|
|
28
|
+
|
|
29
|
+
// Check for critical keywords
|
|
30
|
+
for (const keyword of this.keywords.critical) {
|
|
31
|
+
if (content.includes(keyword)) {
|
|
32
|
+
priorityLevel = Math.min(priorityLevel, 1);
|
|
33
|
+
importanceScore += 25;
|
|
34
|
+
detectedKeywords.push({ word: keyword, level: 'critical' });
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
// Check for high priority keywords
|
|
39
|
+
for (const keyword of this.keywords.high) {
|
|
40
|
+
if (content.includes(keyword)) {
|
|
41
|
+
priorityLevel = Math.min(priorityLevel, 2);
|
|
42
|
+
importanceScore += 15;
|
|
43
|
+
detectedKeywords.push({ word: keyword, level: 'high' });
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
// Check for medium priority keywords
|
|
48
|
+
for (const keyword of this.keywords.medium) {
|
|
49
|
+
if (content.includes(keyword)) {
|
|
50
|
+
priorityLevel = Math.min(priorityLevel, 3);
|
|
51
|
+
importanceScore += 10;
|
|
52
|
+
detectedKeywords.push({ word: keyword, level: 'medium' });
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
// Context-based scoring
|
|
57
|
+
if (context.isMentioned) importanceScore += 10;
|
|
58
|
+
if (context.isReply) importanceScore += 5;
|
|
59
|
+
if (context.isDirectMessage) importanceScore += 10;
|
|
60
|
+
|
|
61
|
+
// Cap score at 100
|
|
62
|
+
importanceScore = Math.min(importanceScore, 100);
|
|
63
|
+
|
|
64
|
+
return {
|
|
65
|
+
priorityLevel,
|
|
66
|
+
importanceScore,
|
|
67
|
+
keywords: detectedKeywords,
|
|
68
|
+
contextSummary: this.generateSummary(message, detectedKeywords)
|
|
69
|
+
};
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
/**
|
|
73
|
+
* Store priority record
|
|
74
|
+
*/
|
|
75
|
+
async store(messageId, conversationId, analysis) {
|
|
76
|
+
const sql = `
|
|
77
|
+
INSERT INTO memory_priorities
|
|
78
|
+
(message_id, conversation_id, priority_level, importance_score, keywords, context_summary)
|
|
79
|
+
VALUES (?, ?, ?, ?, ?, ?)
|
|
80
|
+
`;
|
|
81
|
+
|
|
82
|
+
await this.db.run(sql, [
|
|
83
|
+
messageId,
|
|
84
|
+
conversationId,
|
|
85
|
+
analysis.priorityLevel,
|
|
86
|
+
analysis.importanceScore,
|
|
87
|
+
JSON.stringify(analysis.keywords),
|
|
88
|
+
analysis.contextSummary
|
|
89
|
+
]);
|
|
90
|
+
|
|
91
|
+
return { success: true, messageId, priority: analysis.priorityLevel };
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
/**
|
|
95
|
+
* Get messages by priority level
|
|
96
|
+
*/
|
|
97
|
+
async getByPriority(level, limit = 50) {
|
|
98
|
+
const sql = `
|
|
99
|
+
SELECT * FROM memory_priorities
|
|
100
|
+
WHERE priority_level = ?
|
|
101
|
+
ORDER BY importance_score DESC, created_at DESC
|
|
102
|
+
LIMIT ?
|
|
103
|
+
`;
|
|
104
|
+
return await this.db.all(sql, [level, limit]);
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
/**
|
|
108
|
+
* Get high priority messages
|
|
109
|
+
*/
|
|
110
|
+
async getHighPriority(limit = 20) {
|
|
111
|
+
const sql = `
|
|
112
|
+
SELECT * FROM v_high_priority_messages
|
|
113
|
+
LIMIT ?
|
|
114
|
+
`;
|
|
115
|
+
return await this.db.all(sql, [limit]);
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
/**
|
|
119
|
+
* Search by priority range
|
|
120
|
+
*/
|
|
121
|
+
async searchByPriorityRange(minLevel = 1, maxLevel = 4) {
|
|
122
|
+
const sql = `
|
|
123
|
+
SELECT * FROM memory_priorities
|
|
124
|
+
WHERE priority_level BETWEEN ? AND ?
|
|
125
|
+
ORDER BY priority_level ASC, importance_score DESC
|
|
126
|
+
`;
|
|
127
|
+
return await this.db.all(sql, [minLevel, maxLevel]);
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
/**
|
|
131
|
+
* Auto-cleanup low priority old records
|
|
132
|
+
*/
|
|
133
|
+
async cleanupOldLowPriority(days = 30) {
|
|
134
|
+
const sql = `
|
|
135
|
+
DELETE FROM memory_priorities
|
|
136
|
+
WHERE priority_level = 4
|
|
137
|
+
AND created_at < datetime('now', '-${days} days')
|
|
138
|
+
`;
|
|
139
|
+
const result = await this.db.run(sql);
|
|
140
|
+
return { deleted: result.changes };
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
/**
|
|
144
|
+
* Generate context summary
|
|
145
|
+
*/
|
|
146
|
+
generateSummary(message, keywords) {
|
|
147
|
+
const sentences = message.split(/[.!?]+/).filter(s => s.trim().length > 0);
|
|
148
|
+
const firstSentence = sentences[0]?.trim() || message.substring(0, 100);
|
|
149
|
+
|
|
150
|
+
return {
|
|
151
|
+
firstSentence,
|
|
152
|
+
keywordCount: keywords.length,
|
|
153
|
+
detectedWords: keywords.map(k => k.word)
|
|
154
|
+
};
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
/**
|
|
158
|
+
* Get priority statistics
|
|
159
|
+
*/
|
|
160
|
+
async getStats() {
|
|
161
|
+
const sql = `
|
|
162
|
+
SELECT
|
|
163
|
+
priority_level,
|
|
164
|
+
COUNT(*) as count,
|
|
165
|
+
AVG(importance_score) as avg_score
|
|
166
|
+
FROM memory_priorities
|
|
167
|
+
GROUP BY priority_level
|
|
168
|
+
ORDER BY priority_level
|
|
169
|
+
`;
|
|
170
|
+
return await this.db.all(sql);
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
module.exports = PriorityModule;
|
|
@@ -0,0 +1,286 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Version Manager Module
|
|
3
|
+
* Handle database backups, migrations, and rollbacks
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
const fs = require('fs');
|
|
7
|
+
const path = require('path');
|
|
8
|
+
const crypto = require('crypto');
|
|
9
|
+
|
|
10
|
+
class VersionManager {
|
|
11
|
+
constructor(db, backupDir = './backups') {
|
|
12
|
+
this.db = db;
|
|
13
|
+
this.backupDir = backupDir;
|
|
14
|
+
|
|
15
|
+
// Ensure backup directory exists
|
|
16
|
+
if (!fs.existsSync(backupDir)) {
|
|
17
|
+
fs.mkdirSync(backupDir, { recursive: true });
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* Create database backup
|
|
23
|
+
*/
|
|
24
|
+
async createBackup(description = '', type = 'full') {
|
|
25
|
+
const timestamp = new Date().toISOString().replace(/[:.]/g, '-');
|
|
26
|
+
const backupName = `memory-v2-${type}-${timestamp}`;
|
|
27
|
+
const backupPath = path.join(this.backupDir, `${backupName}.db`);
|
|
28
|
+
|
|
29
|
+
// Copy database file
|
|
30
|
+
const dbPath = this.db.dbPath;
|
|
31
|
+
await this.copyFile(dbPath, backupPath);
|
|
32
|
+
|
|
33
|
+
// Calculate checksum
|
|
34
|
+
const checksum = await this.calculateChecksum(backupPath);
|
|
35
|
+
const stats = fs.statSync(backupPath);
|
|
36
|
+
|
|
37
|
+
// Record version
|
|
38
|
+
const result = await this.db.run(
|
|
39
|
+
`INSERT INTO memory_versions
|
|
40
|
+
(version_name, version_type, description, backup_path, backup_size, checksum)
|
|
41
|
+
VALUES (?, ?, ?, ?, ?, ?)`,
|
|
42
|
+
[backupName, type, description, backupPath, stats.size, checksum]
|
|
43
|
+
);
|
|
44
|
+
|
|
45
|
+
// Record table statistics
|
|
46
|
+
await this.recordTableStats(result.id);
|
|
47
|
+
|
|
48
|
+
return {
|
|
49
|
+
success: true,
|
|
50
|
+
versionId: result.id,
|
|
51
|
+
backupPath,
|
|
52
|
+
size: stats.size,
|
|
53
|
+
checksum
|
|
54
|
+
};
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
/**
|
|
58
|
+
* Copy file (promise wrapper)
|
|
59
|
+
*/
|
|
60
|
+
copyFile(src, dest) {
|
|
61
|
+
return new Promise((resolve, reject) => {
|
|
62
|
+
fs.copyFile(src, dest, (err) => {
|
|
63
|
+
if (err) reject(err);
|
|
64
|
+
else resolve();
|
|
65
|
+
});
|
|
66
|
+
});
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
/**
|
|
70
|
+
* Calculate file checksum
|
|
71
|
+
*/
|
|
72
|
+
calculateChecksum(filePath) {
|
|
73
|
+
return new Promise((resolve, reject) => {
|
|
74
|
+
const hash = crypto.createHash('sha256');
|
|
75
|
+
const stream = fs.createReadStream(filePath);
|
|
76
|
+
|
|
77
|
+
stream.on('data', data => hash.update(data));
|
|
78
|
+
stream.on('end', () => resolve(hash.digest('hex')));
|
|
79
|
+
stream.on('error', reject);
|
|
80
|
+
});
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
/**
|
|
84
|
+
* Record table statistics
|
|
85
|
+
*/
|
|
86
|
+
async recordTableStats(versionId) {
|
|
87
|
+
const tables = [
|
|
88
|
+
'memory_priorities',
|
|
89
|
+
'memory_learning',
|
|
90
|
+
'memory_learning_milestones',
|
|
91
|
+
'memory_decisions',
|
|
92
|
+
'memory_evolution',
|
|
93
|
+
'memory_evolution_history',
|
|
94
|
+
'memory_versions',
|
|
95
|
+
'memory_version_stats'
|
|
96
|
+
];
|
|
97
|
+
|
|
98
|
+
for (const table of tables) {
|
|
99
|
+
try {
|
|
100
|
+
const count = await this.db.get(
|
|
101
|
+
`SELECT COUNT(*) as count FROM ${table}`
|
|
102
|
+
);
|
|
103
|
+
|
|
104
|
+
await this.db.run(
|
|
105
|
+
`INSERT INTO memory_version_stats (version_id, table_name, record_count)
|
|
106
|
+
VALUES (?, ?, ?)`,
|
|
107
|
+
[versionId, table, count.count]
|
|
108
|
+
);
|
|
109
|
+
} catch (err) {
|
|
110
|
+
console.warn(`Table ${table} not found or error:`, err.message);
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
/**
|
|
116
|
+
* List all versions
|
|
117
|
+
*/
|
|
118
|
+
async listVersions() {
|
|
119
|
+
const sql = `
|
|
120
|
+
SELECT v.*,
|
|
121
|
+
GROUP_CONCAT(s.table_name || ': ' || s.record_count, ', ') as table_stats
|
|
122
|
+
FROM memory_versions v
|
|
123
|
+
LEFT JOIN memory_version_stats s ON v.id = s.version_id
|
|
124
|
+
GROUP BY v.id
|
|
125
|
+
ORDER BY v.created_at DESC
|
|
126
|
+
`;
|
|
127
|
+
return await this.db.all(sql);
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
/**
|
|
131
|
+
* Get active version
|
|
132
|
+
*/
|
|
133
|
+
async getActiveVersion() {
|
|
134
|
+
return await this.db.get(
|
|
135
|
+
`SELECT * FROM memory_versions WHERE is_active = 1`
|
|
136
|
+
);
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
/**
|
|
140
|
+
* Activate version
|
|
141
|
+
*/
|
|
142
|
+
async activateVersion(versionId) {
|
|
143
|
+
// Deactivate current active version
|
|
144
|
+
await this.db.run(
|
|
145
|
+
`UPDATE memory_versions SET is_active = 0 WHERE is_active = 1`
|
|
146
|
+
);
|
|
147
|
+
|
|
148
|
+
// Activate new version
|
|
149
|
+
await this.db.run(
|
|
150
|
+
`UPDATE memory_versions
|
|
151
|
+
SET is_active = 1, activated_at = CURRENT_TIMESTAMP
|
|
152
|
+
WHERE id = ?`,
|
|
153
|
+
[versionId]
|
|
154
|
+
);
|
|
155
|
+
|
|
156
|
+
return { success: true, versionId };
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
/**
|
|
160
|
+
* Rollback to version
|
|
161
|
+
*/
|
|
162
|
+
async rollbackToVersion(versionId) {
|
|
163
|
+
const version = await this.db.get(
|
|
164
|
+
`SELECT * FROM memory_versions WHERE id = ?`,
|
|
165
|
+
[versionId]
|
|
166
|
+
);
|
|
167
|
+
|
|
168
|
+
if (!version) {
|
|
169
|
+
return { success: false, error: 'Version not found' };
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
if (!fs.existsSync(version.backup_path)) {
|
|
173
|
+
return { success: false, error: 'Backup file not found' };
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
// Create backup before rollback
|
|
177
|
+
await this.createBackup(`Pre-rollback to v${versionId}`, 'pre-rollback');
|
|
178
|
+
|
|
179
|
+
// Copy backup to active database
|
|
180
|
+
await this.copyFile(version.backup_path, this.db.dbPath);
|
|
181
|
+
|
|
182
|
+
// Activate version
|
|
183
|
+
await this.activateVersion(versionId);
|
|
184
|
+
|
|
185
|
+
return {
|
|
186
|
+
success: true,
|
|
187
|
+
rolledBackTo: version.version_name,
|
|
188
|
+
timestamp: version.created_at
|
|
189
|
+
};
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
/**
|
|
193
|
+
* Delete old backups
|
|
194
|
+
*/
|
|
195
|
+
async cleanupOldBackups(days = 30, keepLastN = 5) {
|
|
196
|
+
// Get backups to delete
|
|
197
|
+
const oldBackups = await this.db.all(
|
|
198
|
+
`SELECT * FROM memory_versions
|
|
199
|
+
WHERE version_type = 'full'
|
|
200
|
+
AND created_at < datetime('now', '-${days} days')
|
|
201
|
+
ORDER BY created_at DESC`
|
|
202
|
+
);
|
|
203
|
+
|
|
204
|
+
// Keep last N backups
|
|
205
|
+
const toDelete = oldBackups.slice(keepLastN);
|
|
206
|
+
let deletedCount = 0;
|
|
207
|
+
|
|
208
|
+
for (const backup of toDelete) {
|
|
209
|
+
try {
|
|
210
|
+
if (fs.existsSync(backup.backup_path)) {
|
|
211
|
+
fs.unlinkSync(backup.backup_path);
|
|
212
|
+
}
|
|
213
|
+
await this.db.run(
|
|
214
|
+
`DELETE FROM memory_version_stats WHERE version_id = ?`,
|
|
215
|
+
[backup.id]
|
|
216
|
+
);
|
|
217
|
+
await this.db.run(
|
|
218
|
+
`DELETE FROM memory_versions WHERE id = ?`,
|
|
219
|
+
[backup.id]
|
|
220
|
+
);
|
|
221
|
+
deletedCount++;
|
|
222
|
+
} catch (err) {
|
|
223
|
+
console.error(`Failed to delete backup ${backup.version_name}:`, err);
|
|
224
|
+
}
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
return { deleted: deletedCount };
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
/**
|
|
231
|
+
* Get backup statistics
|
|
232
|
+
*/
|
|
233
|
+
async getBackupStats() {
|
|
234
|
+
const stats = await this.db.get(
|
|
235
|
+
`SELECT
|
|
236
|
+
COUNT(*) as total_backups,
|
|
237
|
+
SUM(backup_size) as total_size,
|
|
238
|
+
AVG(backup_size) as avg_size,
|
|
239
|
+
MAX(created_at) as last_backup,
|
|
240
|
+
MIN(created_at) as first_backup
|
|
241
|
+
FROM memory_versions
|
|
242
|
+
WHERE version_type = 'full'`
|
|
243
|
+
);
|
|
244
|
+
|
|
245
|
+
return {
|
|
246
|
+
totalBackups: stats.total_backups || 0,
|
|
247
|
+
totalSize: stats.total_size || 0,
|
|
248
|
+
avgSize: stats.avg_size || 0,
|
|
249
|
+
lastBackup: stats.last_backup,
|
|
250
|
+
firstBackup: stats.first_backup
|
|
251
|
+
};
|
|
252
|
+
}
|
|
253
|
+
|
|
254
|
+
/**
|
|
255
|
+
* Verify backup integrity
|
|
256
|
+
*/
|
|
257
|
+
async verifyBackup(versionId) {
|
|
258
|
+
const version = await this.db.get(
|
|
259
|
+
`SELECT * FROM memory_versions WHERE id = ?`,
|
|
260
|
+
[versionId]
|
|
261
|
+
);
|
|
262
|
+
|
|
263
|
+
if (!version) {
|
|
264
|
+
return { valid: false, error: 'Version not found' };
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
if (!fs.existsSync(version.backup_path)) {
|
|
268
|
+
return { valid: false, error: 'Backup file missing' };
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
const currentChecksum = await this.calculateChecksum(version.backup_path);
|
|
272
|
+
|
|
273
|
+
if (currentChecksum !== version.checksum) {
|
|
274
|
+
return {
|
|
275
|
+
valid: false,
|
|
276
|
+
error: 'Checksum mismatch',
|
|
277
|
+
expected: version.checksum,
|
|
278
|
+
actual: currentChecksum
|
|
279
|
+
};
|
|
280
|
+
}
|
|
281
|
+
|
|
282
|
+
return { valid: true, checksum: currentChecksum };
|
|
283
|
+
}
|
|
284
|
+
}
|
|
285
|
+
|
|
286
|
+
module.exports = VersionManager;
|
package/package.json
ADDED
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "memory-lucia",
|
|
3
|
+
"version": "2.0.0",
|
|
4
|
+
"description": "Advanced memory system for OpenClaw agents with priority analysis, learning tracking, decision recording, and skill evolution",
|
|
5
|
+
"main": "api/index.js",
|
|
6
|
+
"scripts": {
|
|
7
|
+
"start": "node api/index.js",
|
|
8
|
+
"init": "node scripts/init-memory.js",
|
|
9
|
+
"test": "node tests/test.js",
|
|
10
|
+
"backup": "node scripts/backup.js"
|
|
11
|
+
},
|
|
12
|
+
"keywords": [
|
|
13
|
+
"openclaw",
|
|
14
|
+
"skill",
|
|
15
|
+
"memory",
|
|
16
|
+
"learning",
|
|
17
|
+
"decision",
|
|
18
|
+
"priority",
|
|
19
|
+
"evolution",
|
|
20
|
+
"sqlite"
|
|
21
|
+
],
|
|
22
|
+
"author": "Chief of Staff",
|
|
23
|
+
"license": "MIT",
|
|
24
|
+
"dependencies": {
|
|
25
|
+
"sqlite3": "^5.1.6"
|
|
26
|
+
},
|
|
27
|
+
"repository": {
|
|
28
|
+
"type": "git",
|
|
29
|
+
"url": "https://github.com/YOUR_USERNAME/memory-lucia.git"
|
|
30
|
+
},
|
|
31
|
+
"bugs": {
|
|
32
|
+
"url": "https://github.com/YOUR_USERNAME/memory-lucia/issues"
|
|
33
|
+
},
|
|
34
|
+
"homepage": "https://github.com/YOUR_USERNAME/memory-lucia#readme"
|
|
35
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
@echo off
|
|
2
|
+
echo 🚀 Publishing memory-lucia to npm...
|
|
3
|
+
echo.
|
|
4
|
+
echo This package requires 2FA authentication.
|
|
5
|
+
echo.
|
|
6
|
+
echo Please enter your 6-digit 2FA code from your Authenticator app:
|
|
7
|
+
set /p OTP="2FA Code: "
|
|
8
|
+
echo.
|
|
9
|
+
echo Publishing with OTP: %OTP%
|
|
10
|
+
npm publish --access=public --otp=%OTP%
|
|
11
|
+
echo.
|
|
12
|
+
echo ✅ Done!
|
|
13
|
+
pause
|
package/publish.bat
ADDED
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
@echo off
|
|
2
|
+
echo 🚀 Publishing memory-lucia to npm...
|
|
3
|
+
echo.
|
|
4
|
+
|
|
5
|
+
echo Logging in to npm...
|
|
6
|
+
npm login --auth-type=legacy
|
|
7
|
+
|
|
8
|
+
echo.
|
|
9
|
+
echo Publishing package...
|
|
10
|
+
npm publish --access=public
|
|
11
|
+
|
|
12
|
+
echo.
|
|
13
|
+
echo ✅ Published!
|
|
14
|
+
echo.
|
|
15
|
+
echo Users can now install with:
|
|
16
|
+
echo npm install memory-lucia
|
|
17
|
+
pause
|
package/publish.sh
ADDED
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
# Memory Lucia Publish Script
|
|
3
|
+
|
|
4
|
+
echo "🚀 Publishing memory-lucia to npm..."
|
|
5
|
+
echo ""
|
|
6
|
+
|
|
7
|
+
# Login
|
|
8
|
+
echo "Logging in to npm..."
|
|
9
|
+
npm login --auth-type=legacy
|
|
10
|
+
|
|
11
|
+
# Publish
|
|
12
|
+
echo ""
|
|
13
|
+
echo "Publishing package..."
|
|
14
|
+
npm publish --access=public
|
|
15
|
+
|
|
16
|
+
echo ""
|
|
17
|
+
echo "✅ Published!"
|
|
18
|
+
echo ""
|
|
19
|
+
echo "Users can now install with:"
|
|
20
|
+
echo " npm install memory-lucia"
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Initialize Memory V2 Database
|
|
3
|
+
* Usage: node scripts/init-memory.js [database-path]
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
const MemoryAPI = require('../api');
|
|
7
|
+
const path = require('path');
|
|
8
|
+
|
|
9
|
+
const dbPath = process.argv[2] || './memory-v2.db';
|
|
10
|
+
|
|
11
|
+
console.log('🚀 Initializing Memory V2 Database...\n');
|
|
12
|
+
|
|
13
|
+
(async () => {
|
|
14
|
+
try {
|
|
15
|
+
const api = new MemoryAPI(dbPath);
|
|
16
|
+
await api.init();
|
|
17
|
+
|
|
18
|
+
console.log('✅ Database initialized successfully!');
|
|
19
|
+
console.log(`📁 Location: ${path.resolve(dbPath)}`);
|
|
20
|
+
console.log('\nNext steps:');
|
|
21
|
+
console.log(' 1. Use the API to track learning, decisions, etc.');
|
|
22
|
+
console.log(' 2. Run tests: npm test');
|
|
23
|
+
console.log(' 3. Create backups: npm run backup');
|
|
24
|
+
|
|
25
|
+
await api.close();
|
|
26
|
+
} catch (err) {
|
|
27
|
+
console.error('❌ Initialization failed:', err.message);
|
|
28
|
+
process.exit(1);
|
|
29
|
+
}
|
|
30
|
+
})();
|