memory-lucia 2.0.1 → 2.0.3
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/README.md +111 -111
- package/SKILL.md +121 -120
- package/database/schema.sql +152 -0
- package/migrations/v1-to-v2.js +213 -0
- package/package.json +35 -35
- package/references/API.md +364 -0
- package/GITHUB-SETUP.md +0 -81
- package/NPM-PUBLISH-GUIDE.md +0 -169
- package/PUBLISH-STEPS.md +0 -102
- package/publish-with-otp.bat +0 -13
- package/publish.bat +0 -17
- package/publish.sh +0 -20
- package/push-final.bat +0 -28
- package/push-gh-cli.bat +0 -21
- package/push-manual.bat +0 -24
- package/push-to-github.bat +0 -19
- package/push-with-gh.bat +0 -26
|
@@ -0,0 +1,213 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* Memory V1 to V2 Migration Script
|
|
4
|
+
* Migrates data from old memory format to V2 schema
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
const sqlite3 = require('sqlite3').verbose();
|
|
8
|
+
const fs = require('fs');
|
|
9
|
+
const path = require('path');
|
|
10
|
+
|
|
11
|
+
class MemoryMigration {
|
|
12
|
+
constructor(sourceDbPath, targetDbPath = './memory-v2.db') {
|
|
13
|
+
this.sourceDbPath = sourceDbPath;
|
|
14
|
+
this.targetDbPath = targetDbPath;
|
|
15
|
+
this.sourceDb = null;
|
|
16
|
+
this.targetDb = null;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
async init() {
|
|
20
|
+
// Check if source exists
|
|
21
|
+
if (!fs.existsSync(this.sourceDbPath)) {
|
|
22
|
+
throw new Error(`Source database not found: ${this.sourceDbPath}`);
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
// Open source database
|
|
26
|
+
this.sourceDb = new sqlite3.Database(this.sourceDbPath, sqlite3.OPEN_READONLY);
|
|
27
|
+
|
|
28
|
+
// Open/create target database
|
|
29
|
+
this.targetDb = new sqlite3.Database(this.targetDbPath);
|
|
30
|
+
|
|
31
|
+
console.log('✅ Connected to source and target databases');
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
async runSchema() {
|
|
35
|
+
const schemaPath = path.join(__dirname, '..', 'database', 'schema.sql');
|
|
36
|
+
|
|
37
|
+
if (!fs.existsSync(schemaPath)) {
|
|
38
|
+
throw new Error(`Schema file not found: ${schemaPath}`);
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
const schema = fs.readFileSync(schemaPath, 'utf8');
|
|
42
|
+
const statements = schema
|
|
43
|
+
.split(';')
|
|
44
|
+
.map(s => s.trim())
|
|
45
|
+
.filter(s => s.length > 0);
|
|
46
|
+
|
|
47
|
+
for (const statement of statements) {
|
|
48
|
+
await this.runTarget(statement);
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
console.log('✅ Target database schema initialized');
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
async migratePriorities() {
|
|
55
|
+
console.log('🔄 Migrating priorities...');
|
|
56
|
+
|
|
57
|
+
try {
|
|
58
|
+
const rows = await this.allSource(
|
|
59
|
+
"SELECT * FROM memory_priorities WHERE created_at >= datetime('now', '-90 days')"
|
|
60
|
+
);
|
|
61
|
+
|
|
62
|
+
for (const row of rows) {
|
|
63
|
+
await this.runTarget(
|
|
64
|
+
`INSERT INTO memory_priorities
|
|
65
|
+
(msg_id, conv_id, priority_level, reasoning, category, created_at)
|
|
66
|
+
VALUES (?, ?, ?, ?, ?, ?)`,
|
|
67
|
+
[row.msg_id, row.conv_id, row.priority_level, row.reasoning, row.category, row.created_at]
|
|
68
|
+
);
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
console.log(`✅ Migrated ${rows.length} priority records`);
|
|
72
|
+
} catch (err) {
|
|
73
|
+
console.log('ℹ️ No priorities to migrate or table does not exist');
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
async migrateLearning() {
|
|
78
|
+
console.log('🔄 Migrating learning records...');
|
|
79
|
+
|
|
80
|
+
try {
|
|
81
|
+
const rows = await this.allSource(
|
|
82
|
+
"SELECT * FROM memory_learning WHERE status != 'abandoned'"
|
|
83
|
+
);
|
|
84
|
+
|
|
85
|
+
for (const row of rows) {
|
|
86
|
+
await this.runTarget(
|
|
87
|
+
`INSERT INTO memory_learning
|
|
88
|
+
(msg_id, conv_id, topic, description, status, progress, started_at, updated_at, completed_at)
|
|
89
|
+
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)`,
|
|
90
|
+
[row.msg_id, row.conv_id, row.topic, row.description, row.status,
|
|
91
|
+
row.progress, row.started_at, row.updated_at, row.completed_at]
|
|
92
|
+
);
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
console.log(`✅ Migrated ${rows.length} learning records`);
|
|
96
|
+
} catch (err) {
|
|
97
|
+
console.log('ℹ️ No learning records to migrate or table does not exist');
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
async migrateDecisions() {
|
|
102
|
+
console.log('🔄 Migrating decisions...');
|
|
103
|
+
|
|
104
|
+
try {
|
|
105
|
+
const rows = await this.allSource(
|
|
106
|
+
"SELECT * FROM memory_decisions WHERE status IN ('pending', 'implemented')"
|
|
107
|
+
);
|
|
108
|
+
|
|
109
|
+
for (const row of rows) {
|
|
110
|
+
await this.runTarget(
|
|
111
|
+
`INSERT INTO memory_decisions
|
|
112
|
+
(msg_id, conv_id, summary, context, expected_outcome, actual_outcome,
|
|
113
|
+
status, review_scheduled_at, reviewed_at, created_at)
|
|
114
|
+
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`,
|
|
115
|
+
[row.msg_id, row.conv_id, row.summary, row.context, row.expected_outcome,
|
|
116
|
+
row.actual_outcome, row.status, row.review_scheduled_at, row.reviewed_at, row.created_at]
|
|
117
|
+
);
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
console.log(`✅ Migrated ${rows.length} decision records`);
|
|
121
|
+
} catch (err) {
|
|
122
|
+
console.log('ℹ️ No decisions to migrate or table does not exist');
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
async migrateEvolution() {
|
|
127
|
+
console.log('🔄 Migrating skill evolution...');
|
|
128
|
+
|
|
129
|
+
try {
|
|
130
|
+
const rows = await this.allSource(
|
|
131
|
+
"SELECT * FROM memory_evolution WHERE usage_count > 0"
|
|
132
|
+
);
|
|
133
|
+
|
|
134
|
+
for (const row of rows) {
|
|
135
|
+
await this.runTarget(
|
|
136
|
+
`INSERT INTO memory_evolution
|
|
137
|
+
(skill_name, category, usage_count, success_count, last_used_at, first_used_at)
|
|
138
|
+
VALUES (?, ?, ?, ?, ?, ?)`,
|
|
139
|
+
[row.skill_name, row.category, row.usage_count, row.success_count,
|
|
140
|
+
row.last_used_at, row.first_used_at]
|
|
141
|
+
);
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
console.log(`✅ Migrated ${rows.length} skill evolution records`);
|
|
145
|
+
} catch (err) {
|
|
146
|
+
console.log('ℹ️ No evolution records to migrate or table does not exist');
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
async runTarget(sql, params = []) {
|
|
151
|
+
return new Promise((resolve, reject) => {
|
|
152
|
+
this.targetDb.run(sql, params, function(err) {
|
|
153
|
+
if (err) reject(err);
|
|
154
|
+
else resolve({ id: this.lastID, changes: this.changes });
|
|
155
|
+
});
|
|
156
|
+
});
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
async allSource(sql, params = []) {
|
|
160
|
+
return new Promise((resolve, reject) => {
|
|
161
|
+
this.sourceDb.all(sql, params, (err, rows) => {
|
|
162
|
+
if (err) reject(err);
|
|
163
|
+
else resolve(rows);
|
|
164
|
+
});
|
|
165
|
+
});
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
async close() {
|
|
169
|
+
if (this.sourceDb) {
|
|
170
|
+
await new Promise((resolve) => this.sourceDb.close(resolve));
|
|
171
|
+
}
|
|
172
|
+
if (this.targetDb) {
|
|
173
|
+
await new Promise((resolve) => this.targetDb.close(resolve));
|
|
174
|
+
}
|
|
175
|
+
console.log('✅ Database connections closed');
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
async migrate() {
|
|
179
|
+
try {
|
|
180
|
+
await this.init();
|
|
181
|
+
await this.runSchema();
|
|
182
|
+
await this.migratePriorities();
|
|
183
|
+
await this.migrateLearning();
|
|
184
|
+
await this.migrateDecisions();
|
|
185
|
+
await this.migrateEvolution();
|
|
186
|
+
|
|
187
|
+
console.log('\n🎉 Migration completed successfully!');
|
|
188
|
+
console.log(`📁 New database: ${path.resolve(this.targetDbPath)}`);
|
|
189
|
+
} catch (err) {
|
|
190
|
+
console.error('\n❌ Migration failed:', err.message);
|
|
191
|
+
process.exit(1);
|
|
192
|
+
} finally {
|
|
193
|
+
await this.close();
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
// CLI usage
|
|
199
|
+
if (require.main === module) {
|
|
200
|
+
const sourceDb = process.argv[2];
|
|
201
|
+
const targetDb = process.argv[3] || './memory-v2.db';
|
|
202
|
+
|
|
203
|
+
if (!sourceDb) {
|
|
204
|
+
console.log('Usage: node migrations/v1-to-v2.js <source-v1.db> [target-v2.db]');
|
|
205
|
+
console.log('Example: node migrations/v1-to-v2.js ./memory-v1.db ./memory-v2.db');
|
|
206
|
+
process.exit(1);
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
const migration = new MemoryMigration(sourceDb, targetDb);
|
|
210
|
+
migration.migrate();
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
module.exports = MemoryMigration;
|
package/package.json
CHANGED
|
@@ -1,35 +1,35 @@
|
|
|
1
|
-
{
|
|
2
|
-
"name": "memory-lucia",
|
|
3
|
-
"version": "2.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/wen521/memory-lucia-.git"
|
|
30
|
-
},
|
|
31
|
-
"bugs": {
|
|
32
|
-
"url": "https://github.com/wen521/memory-lucia-/issues"
|
|
33
|
-
},
|
|
34
|
-
"homepage": "https://github.com/wen521/memory-lucia-#readme"
|
|
35
|
-
}
|
|
1
|
+
{
|
|
2
|
+
"name": "memory-lucia",
|
|
3
|
+
"version": "2.0.3",
|
|
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/wen521/memory-lucia-.git"
|
|
30
|
+
},
|
|
31
|
+
"bugs": {
|
|
32
|
+
"url": "https://github.com/wen521/memory-lucia-/issues"
|
|
33
|
+
},
|
|
34
|
+
"homepage": "https://github.com/wen521/memory-lucia-#readme"
|
|
35
|
+
}
|
|
@@ -0,0 +1,364 @@
|
|
|
1
|
+
# Memory V2 API Reference
|
|
2
|
+
|
|
3
|
+
Complete API documentation for the Memory V2 system.
|
|
4
|
+
|
|
5
|
+
## Table of Contents
|
|
6
|
+
|
|
7
|
+
- [Initialization](#initialization)
|
|
8
|
+
- [Priority Module](#priority-module)
|
|
9
|
+
- [Learning Module](#learning-module)
|
|
10
|
+
- [Decision Module](#decision-module)
|
|
11
|
+
- [Evolution Module](#evolution-module)
|
|
12
|
+
- [Dashboard](#dashboard)
|
|
13
|
+
- [Version Management](#version-management)
|
|
14
|
+
|
|
15
|
+
---
|
|
16
|
+
|
|
17
|
+
## Initialization
|
|
18
|
+
|
|
19
|
+
```javascript
|
|
20
|
+
const MemoryAPI = require('./api');
|
|
21
|
+
|
|
22
|
+
// Create instance
|
|
23
|
+
const api = new MemoryAPI('./memory-v2.db');
|
|
24
|
+
|
|
25
|
+
// Initialize database
|
|
26
|
+
await api.init();
|
|
27
|
+
|
|
28
|
+
// Close when done
|
|
29
|
+
await api.close();
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
---
|
|
33
|
+
|
|
34
|
+
## Priority Module
|
|
35
|
+
|
|
36
|
+
### analyzePriority(message)
|
|
37
|
+
Analyze a message and return priority assessment.
|
|
38
|
+
|
|
39
|
+
**Parameters:**
|
|
40
|
+
- `message` (string): The message to analyze
|
|
41
|
+
|
|
42
|
+
**Returns:**
|
|
43
|
+
```javascript
|
|
44
|
+
{
|
|
45
|
+
priority_level: 'critical' | 'high' | 'medium' | 'low',
|
|
46
|
+
reasoning: string,
|
|
47
|
+
category: string
|
|
48
|
+
}
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
### storePriority(msgId, convId, analysis)
|
|
52
|
+
Store priority analysis in database.
|
|
53
|
+
|
|
54
|
+
**Parameters:**
|
|
55
|
+
- `msgId` (string): Message ID
|
|
56
|
+
- `convId` (string): Conversation ID
|
|
57
|
+
- `analysis` (object): Result from analyzePriority
|
|
58
|
+
|
|
59
|
+
**Returns:** `Promise<{id: number}>`
|
|
60
|
+
|
|
61
|
+
### getHighPriority(limit = 10)
|
|
62
|
+
Get recent high/critical priority items.
|
|
63
|
+
|
|
64
|
+
**Parameters:**
|
|
65
|
+
- `limit` (number): Maximum results
|
|
66
|
+
|
|
67
|
+
**Returns:** `Promise<Array>`
|
|
68
|
+
|
|
69
|
+
### getPriorityStats()
|
|
70
|
+
Get priority distribution statistics.
|
|
71
|
+
|
|
72
|
+
**Returns:**
|
|
73
|
+
```javascript
|
|
74
|
+
{
|
|
75
|
+
critical: number,
|
|
76
|
+
high: number,
|
|
77
|
+
medium: number,
|
|
78
|
+
low: number,
|
|
79
|
+
total: number
|
|
80
|
+
}
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
---
|
|
84
|
+
|
|
85
|
+
## Learning Module
|
|
86
|
+
|
|
87
|
+
### startLearning(msgId, convId, message)
|
|
88
|
+
Start tracking a new learning topic.
|
|
89
|
+
|
|
90
|
+
**Parameters:**
|
|
91
|
+
- `msgId` (string): Message ID
|
|
92
|
+
- `convId` (string): Conversation ID
|
|
93
|
+
- `message` (string): Message describing the learning topic
|
|
94
|
+
|
|
95
|
+
**Returns:**
|
|
96
|
+
```javascript
|
|
97
|
+
{
|
|
98
|
+
id: number,
|
|
99
|
+
topic: string,
|
|
100
|
+
status: 'active',
|
|
101
|
+
progress: 0
|
|
102
|
+
}
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
### updateLearningProgress(learningId, updates)
|
|
106
|
+
Update learning progress.
|
|
107
|
+
|
|
108
|
+
**Parameters:**
|
|
109
|
+
- `learningId` (number): Learning record ID
|
|
110
|
+
- `updates` (object):
|
|
111
|
+
- `progress` (number): 0-100
|
|
112
|
+
- `status` (string): 'active' | 'paused' | 'completed' | 'abandoned'
|
|
113
|
+
|
|
114
|
+
### addMilestone(learningId, milestone)
|
|
115
|
+
Add a milestone to a learning record.
|
|
116
|
+
|
|
117
|
+
**Parameters:**
|
|
118
|
+
- `learningId` (number): Learning record ID
|
|
119
|
+
- `milestone` (object):
|
|
120
|
+
- `title` (string): Milestone title
|
|
121
|
+
- `description` (string): Optional description
|
|
122
|
+
|
|
123
|
+
### getActiveLearning(limit = 5)
|
|
124
|
+
Get currently active learning topics.
|
|
125
|
+
|
|
126
|
+
**Parameters:**
|
|
127
|
+
- `limit` (number): Maximum results
|
|
128
|
+
|
|
129
|
+
**Returns:** `Promise<Array>`
|
|
130
|
+
|
|
131
|
+
### getLearningStats()
|
|
132
|
+
Get learning statistics.
|
|
133
|
+
|
|
134
|
+
**Returns:**
|
|
135
|
+
```javascript
|
|
136
|
+
{
|
|
137
|
+
active: number,
|
|
138
|
+
completed: number,
|
|
139
|
+
total: number,
|
|
140
|
+
avg_progress: number
|
|
141
|
+
}
|
|
142
|
+
```
|
|
143
|
+
|
|
144
|
+
---
|
|
145
|
+
|
|
146
|
+
## Decision Module
|
|
147
|
+
|
|
148
|
+
### recordDecision(msgId, convId, decisionData)
|
|
149
|
+
Record a new decision.
|
|
150
|
+
|
|
151
|
+
**Parameters:**
|
|
152
|
+
- `msgId` (string): Message ID
|
|
153
|
+
- `convId` (string): Conversation ID
|
|
154
|
+
- `decisionData` (object):
|
|
155
|
+
- `summary` (string): Decision summary (required)
|
|
156
|
+
- `context` (string): Decision context
|
|
157
|
+
- `expectedOutcome` (string): Expected result
|
|
158
|
+
- `reviewDate` (string): ISO date for review
|
|
159
|
+
|
|
160
|
+
**Returns:** `Promise<{id: number}>`
|
|
161
|
+
|
|
162
|
+
### updateDecisionOutcome(decisionId, outcome)
|
|
163
|
+
Update the actual outcome of a decision.
|
|
164
|
+
|
|
165
|
+
**Parameters:**
|
|
166
|
+
- `decisionId` (number): Decision ID
|
|
167
|
+
- `outcome` (object):
|
|
168
|
+
- `actualOutcome` (string): What actually happened
|
|
169
|
+
- `status` (string): 'implemented' | 'validated' | 'rejected'
|
|
170
|
+
|
|
171
|
+
### getPendingDecisions()
|
|
172
|
+
Get decisions pending review or implementation.
|
|
173
|
+
|
|
174
|
+
**Returns:** `Promise<Array>`
|
|
175
|
+
|
|
176
|
+
### scheduleReview(decisionId, reviewDate)
|
|
177
|
+
Schedule a review for a decision.
|
|
178
|
+
|
|
179
|
+
**Parameters:**
|
|
180
|
+
- `decisionId` (number): Decision ID
|
|
181
|
+
- `reviewDate` (string): ISO date string
|
|
182
|
+
|
|
183
|
+
---
|
|
184
|
+
|
|
185
|
+
## Evolution Module
|
|
186
|
+
|
|
187
|
+
### recordSkillUsage(skillName, category, result)
|
|
188
|
+
Record skill usage.
|
|
189
|
+
|
|
190
|
+
**Parameters:**
|
|
191
|
+
- `skillName` (string): Name of the skill
|
|
192
|
+
- `category` (string): Skill category
|
|
193
|
+
- `result` (string): 'success' | 'failure'
|
|
194
|
+
|
|
195
|
+
### getTopSkills(limit = 10)
|
|
196
|
+
Get most frequently used skills.
|
|
197
|
+
|
|
198
|
+
**Parameters:**
|
|
199
|
+
- `limit` (number): Maximum results
|
|
200
|
+
|
|
201
|
+
**Returns:** `Promise<Array>`
|
|
202
|
+
|
|
203
|
+
### getSkillStats(skillName)
|
|
204
|
+
Get statistics for a specific skill.
|
|
205
|
+
|
|
206
|
+
**Parameters:**
|
|
207
|
+
- `skillName` (string): Skill name
|
|
208
|
+
|
|
209
|
+
**Returns:**
|
|
210
|
+
```javascript
|
|
211
|
+
{
|
|
212
|
+
skill_name: string,
|
|
213
|
+
category: string,
|
|
214
|
+
usage_count: number,
|
|
215
|
+
success_count: number,
|
|
216
|
+
success_rate: number,
|
|
217
|
+
last_used_at: string
|
|
218
|
+
}
|
|
219
|
+
```
|
|
220
|
+
|
|
221
|
+
---
|
|
222
|
+
|
|
223
|
+
## Dashboard
|
|
224
|
+
|
|
225
|
+
### getDashboard()
|
|
226
|
+
Get unified dashboard of all memory data.
|
|
227
|
+
|
|
228
|
+
**Returns:**
|
|
229
|
+
```javascript
|
|
230
|
+
{
|
|
231
|
+
summary: {
|
|
232
|
+
total_priorities: number,
|
|
233
|
+
total_learning: number,
|
|
234
|
+
total_decisions: number,
|
|
235
|
+
total_skills: number
|
|
236
|
+
},
|
|
237
|
+
recent: {
|
|
238
|
+
priorities: Array,
|
|
239
|
+
learning: Array,
|
|
240
|
+
decisions: Array
|
|
241
|
+
},
|
|
242
|
+
stats: {
|
|
243
|
+
priorities: Object,
|
|
244
|
+
learning: Object,
|
|
245
|
+
skills: Array
|
|
246
|
+
}
|
|
247
|
+
}
|
|
248
|
+
```
|
|
249
|
+
|
|
250
|
+
---
|
|
251
|
+
|
|
252
|
+
## Version Management
|
|
253
|
+
|
|
254
|
+
### createBackup(label)
|
|
255
|
+
Create a database backup.
|
|
256
|
+
|
|
257
|
+
**Parameters:**
|
|
258
|
+
- `label` (string): Optional label for the backup
|
|
259
|
+
|
|
260
|
+
**Returns:** `Promise<{backupPath: string}>`
|
|
261
|
+
|
|
262
|
+
### listBackups()
|
|
263
|
+
List all available backups.
|
|
264
|
+
|
|
265
|
+
**Returns:** `Promise<Array>`
|
|
266
|
+
|
|
267
|
+
### restoreBackup(backupPath)
|
|
268
|
+
Restore from a backup.
|
|
269
|
+
|
|
270
|
+
**Parameters:**
|
|
271
|
+
- `backupPath` (string): Path to backup file
|
|
272
|
+
|
|
273
|
+
**Returns:** `Promise<boolean>`
|
|
274
|
+
|
|
275
|
+
### cleanupBackups(keepCount = 10)
|
|
276
|
+
Clean up old backups, keeping only the specified number.
|
|
277
|
+
|
|
278
|
+
**Parameters:**
|
|
279
|
+
- `keepCount` (number): Number of backups to keep
|
|
280
|
+
|
|
281
|
+
---
|
|
282
|
+
|
|
283
|
+
## Database Views
|
|
284
|
+
|
|
285
|
+
The following SQL views are available for direct queries:
|
|
286
|
+
|
|
287
|
+
### v_pending_decisions
|
|
288
|
+
Decisions that need attention (pending, overdue, or due soon).
|
|
289
|
+
|
|
290
|
+
### v_skill_summary
|
|
291
|
+
Skill usage statistics with success rates.
|
|
292
|
+
|
|
293
|
+
### v_weekly_learning_report
|
|
294
|
+
Learning activity summary for the past week.
|
|
295
|
+
|
|
296
|
+
### v_high_priority
|
|
297
|
+
Combined view of high priority items and pending decisions.
|
|
298
|
+
|
|
299
|
+
---
|
|
300
|
+
|
|
301
|
+
## Error Handling
|
|
302
|
+
|
|
303
|
+
All API methods return Promises and may throw:
|
|
304
|
+
|
|
305
|
+
```javascript
|
|
306
|
+
try {
|
|
307
|
+
const result = await api.storePriority(msgId, convId, analysis);
|
|
308
|
+
} catch (err) {
|
|
309
|
+
console.error('API Error:', err.message);
|
|
310
|
+
}
|
|
311
|
+
```
|
|
312
|
+
|
|
313
|
+
Common errors:
|
|
314
|
+
- Database not initialized
|
|
315
|
+
- Invalid parameters
|
|
316
|
+
- Constraint violations
|
|
317
|
+
- File system errors (backups)
|
|
318
|
+
|
|
319
|
+
---
|
|
320
|
+
|
|
321
|
+
## Examples
|
|
322
|
+
|
|
323
|
+
### Complete Workflow
|
|
324
|
+
|
|
325
|
+
```javascript
|
|
326
|
+
const MemoryAPI = require('./api');
|
|
327
|
+
const api = new MemoryAPI('./memory-v2.db');
|
|
328
|
+
|
|
329
|
+
async function example() {
|
|
330
|
+
await api.init();
|
|
331
|
+
|
|
332
|
+
// Record a decision
|
|
333
|
+
const decision = await api.recordDecision('msg-123', 'conv-456', {
|
|
334
|
+
summary: 'Use SQLite for local storage',
|
|
335
|
+
context: 'Need embedded database for skill',
|
|
336
|
+
expectedOutcome: 'Simpler deployment'
|
|
337
|
+
});
|
|
338
|
+
|
|
339
|
+
// Start learning
|
|
340
|
+
const learning = await api.startLearning('msg-124', 'conv-456',
|
|
341
|
+
'Learning SQLite advanced features'
|
|
342
|
+
);
|
|
343
|
+
|
|
344
|
+
// Update progress
|
|
345
|
+
await api.updateLearningProgress(learning.id, { progress: 50 });
|
|
346
|
+
|
|
347
|
+
// Record skill usage
|
|
348
|
+
await api.recordSkillUsage('memory-v2', 'storage', 'success');
|
|
349
|
+
|
|
350
|
+
// Get dashboard
|
|
351
|
+
const dashboard = await api.getDashboard();
|
|
352
|
+
console.log(dashboard);
|
|
353
|
+
|
|
354
|
+
await api.close();
|
|
355
|
+
}
|
|
356
|
+
|
|
357
|
+
example();
|
|
358
|
+
```
|
|
359
|
+
|
|
360
|
+
---
|
|
361
|
+
|
|
362
|
+
## License
|
|
363
|
+
|
|
364
|
+
MIT
|