@slorenzot/memento-cli 0.2.1 → 1.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/dist/CLI.d.ts +12 -0
- package/dist/CLI.d.ts.map +1 -0
- package/dist/CLI.js +178 -0
- package/dist/CLI.js.map +1 -0
- package/dist/index.js +254 -30
- package/dist/index.js.map +1 -1
- package/package.json +6 -4
- package/src/CLI.test.ts +60 -0
- package/src/CLI.ts +192 -0
- package/src/index.ts +311 -33
- package/data/memento.db +0 -0
- package/data/memento.db-shm +0 -0
- package/data/memento.db-wal +0 -0
- package/slorenzot-memento-cli-0.2.0.tgz +0 -0
package/dist/CLI.d.ts
ADDED
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
export declare class CLI {
|
|
2
|
+
private program;
|
|
3
|
+
private memory;
|
|
4
|
+
private activeSessionId;
|
|
5
|
+
private projectId;
|
|
6
|
+
constructor();
|
|
7
|
+
private setupCommands;
|
|
8
|
+
private getOrCreateSessionId;
|
|
9
|
+
run(argv?: string[]): Promise<void>;
|
|
10
|
+
close(): void;
|
|
11
|
+
}
|
|
12
|
+
//# sourceMappingURL=CLI.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"CLI.d.ts","sourceRoot":"","sources":["../src/CLI.ts"],"names":[],"mappings":"AAKA,qBAAa,GAAG;IACd,OAAO,CAAC,OAAO,CAAU;IACzB,OAAO,CAAC,MAAM,CAAe;IAC7B,OAAO,CAAC,eAAe,CAAuB;IAC9C,OAAO,CAAC,SAAS,CAAS;;IAY1B,OAAO,CAAC,aAAa;YAsJP,oBAAoB;IAa5B,GAAG,CAAC,IAAI,GAAE,MAAM,EAAiB;IAIvC,KAAK;CAGN"}
|
package/dist/CLI.js
ADDED
|
@@ -0,0 +1,178 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.CLI = void 0;
|
|
4
|
+
const commander_1 = require("commander");
|
|
5
|
+
const memento_core_1 = require("@slorenzot/memento-core");
|
|
6
|
+
// @ts-ignore
|
|
7
|
+
class CLI {
|
|
8
|
+
program;
|
|
9
|
+
memory;
|
|
10
|
+
activeSessionId = null;
|
|
11
|
+
projectId;
|
|
12
|
+
constructor() {
|
|
13
|
+
const config = (0, memento_core_1.loadConfig)();
|
|
14
|
+
const dbPath = (0, memento_core_1.resolveDbPath)(config);
|
|
15
|
+
this.projectId = (0, memento_core_1.getProjectId)(config);
|
|
16
|
+
this.program = new commander_1.Command();
|
|
17
|
+
this.memory = new memento_core_1.MemoryEngine(dbPath);
|
|
18
|
+
this.setupCommands();
|
|
19
|
+
}
|
|
20
|
+
setupCommands() {
|
|
21
|
+
this.program
|
|
22
|
+
.name('memento')
|
|
23
|
+
.description('Persistent memory system for AI coding agents')
|
|
24
|
+
.version('0.1.0');
|
|
25
|
+
this.program
|
|
26
|
+
.command('setup [agent]')
|
|
27
|
+
.description('Setup configuration for an AI agent')
|
|
28
|
+
.action((agent) => {
|
|
29
|
+
console.log(`Setup for agent: ${agent || 'default'}`);
|
|
30
|
+
console.log('Configuration saved to ~/.memento/config.json');
|
|
31
|
+
});
|
|
32
|
+
this.program
|
|
33
|
+
.command('serve [port]')
|
|
34
|
+
.description('Start API server')
|
|
35
|
+
.option('-d, --db <path>', 'Database path', './data/memento.db')
|
|
36
|
+
.action((port, options) => {
|
|
37
|
+
console.log(`Starting API server on port ${port || 3000}`);
|
|
38
|
+
console.log(`Database: ${options.db}`);
|
|
39
|
+
console.log('Note: API server not implemented in CLI mode');
|
|
40
|
+
});
|
|
41
|
+
this.program
|
|
42
|
+
.command('mcp')
|
|
43
|
+
.description('Start MCP server')
|
|
44
|
+
.option('-d, --db <path>', 'Database path', './data/memento.db')
|
|
45
|
+
.action((options) => {
|
|
46
|
+
console.log(`Starting MCP server`);
|
|
47
|
+
console.log(`Database: ${options.db}`);
|
|
48
|
+
console.log('Note: MCP server not implemented in CLI mode');
|
|
49
|
+
});
|
|
50
|
+
this.program
|
|
51
|
+
.command('search <query>')
|
|
52
|
+
.description('Search observations')
|
|
53
|
+
.option('-t, --type <type>', 'Filter by type')
|
|
54
|
+
.option('-p, --project <project>', 'Filter by project')
|
|
55
|
+
.option('--limit <number>', 'Limit results')
|
|
56
|
+
.action(async (query, options) => {
|
|
57
|
+
const result = await this.memory.search({
|
|
58
|
+
query,
|
|
59
|
+
type: options.type,
|
|
60
|
+
projectId: options.project,
|
|
61
|
+
limit: options.limit ? parseInt(options.limit) : undefined,
|
|
62
|
+
});
|
|
63
|
+
console.log(`Found ${result.total} observations:`);
|
|
64
|
+
result.observations.forEach((obs) => {
|
|
65
|
+
console.log(` [${obs.type}] ${obs.title}`);
|
|
66
|
+
console.log(` ${obs.content.substring(0, 100)}...`);
|
|
67
|
+
});
|
|
68
|
+
});
|
|
69
|
+
this.program
|
|
70
|
+
.command('save <title> <content>')
|
|
71
|
+
.description('Save an observation')
|
|
72
|
+
.option('-t, --type <type>', 'Observation type', 'note')
|
|
73
|
+
.option('-k, --topic <topic>', 'Topic key')
|
|
74
|
+
.option('-p, --project <project>', 'Project ID', this.projectId)
|
|
75
|
+
.action(async (title, content, options) => {
|
|
76
|
+
const sessionId = await this.getOrCreateSessionId(options.project);
|
|
77
|
+
const observation = await this.memory.createObservation({
|
|
78
|
+
sessionId,
|
|
79
|
+
title,
|
|
80
|
+
content,
|
|
81
|
+
type: options.type,
|
|
82
|
+
topicKey: options.topic || null,
|
|
83
|
+
projectId: options.project,
|
|
84
|
+
metadata: {},
|
|
85
|
+
});
|
|
86
|
+
console.log(`Saved observation: ${observation.uuid}`);
|
|
87
|
+
});
|
|
88
|
+
this.program
|
|
89
|
+
.command('get <id>')
|
|
90
|
+
.description('Get observation by ID')
|
|
91
|
+
.action(async (id) => {
|
|
92
|
+
const observation = await this.memory.getObservation(parseInt(id));
|
|
93
|
+
if (!observation) {
|
|
94
|
+
console.error('Observation not found');
|
|
95
|
+
return;
|
|
96
|
+
}
|
|
97
|
+
console.log(`[${observation.type}] ${observation.title}`);
|
|
98
|
+
console.log(observation.content);
|
|
99
|
+
console.log(`Topic: ${observation.topicKey || 'none'}`);
|
|
100
|
+
console.log(`Created: ${observation.createdAt.toISOString()}`);
|
|
101
|
+
});
|
|
102
|
+
this.program
|
|
103
|
+
.command('update <id>')
|
|
104
|
+
.description('Update observation')
|
|
105
|
+
.option('-t, --title <title>', 'New title')
|
|
106
|
+
.option('-c, --content <content>', 'New content')
|
|
107
|
+
.option('-k, --topic <topic>', 'New topic key')
|
|
108
|
+
.action(async (id, options) => {
|
|
109
|
+
const updates = {};
|
|
110
|
+
if (options.title)
|
|
111
|
+
updates.title = options.title;
|
|
112
|
+
if (options.content)
|
|
113
|
+
updates.content = options.content;
|
|
114
|
+
if (options.topic)
|
|
115
|
+
updates.topicKey = options.topic;
|
|
116
|
+
const observation = await this.memory.updateObservation(parseInt(id), updates);
|
|
117
|
+
console.log(`Updated observation: ${observation.uuid}`);
|
|
118
|
+
});
|
|
119
|
+
this.program
|
|
120
|
+
.command('delete <id>')
|
|
121
|
+
.description('Delete observation')
|
|
122
|
+
.action(async (id) => {
|
|
123
|
+
await this.memory.deleteObservation(parseInt(id));
|
|
124
|
+
console.log(`Deleted observation ${id}`);
|
|
125
|
+
});
|
|
126
|
+
this.program
|
|
127
|
+
.command('timeline [project]')
|
|
128
|
+
.description('Show timeline of observations')
|
|
129
|
+
.option('-l, --limit <number>', 'Limit results', '20')
|
|
130
|
+
.action(async (project, options) => {
|
|
131
|
+
const result = await this.memory.search({
|
|
132
|
+
projectId: project,
|
|
133
|
+
limit: parseInt(options.limit),
|
|
134
|
+
});
|
|
135
|
+
console.log(`Timeline (${result.total} observations):`);
|
|
136
|
+
result.observations.forEach((obs) => {
|
|
137
|
+
const date = obs.createdAt.toLocaleDateString();
|
|
138
|
+
console.log(` ${date} [${obs.type}] ${obs.title}`);
|
|
139
|
+
});
|
|
140
|
+
});
|
|
141
|
+
this.program
|
|
142
|
+
.command('stats')
|
|
143
|
+
.description('Show statistics')
|
|
144
|
+
.action(async () => {
|
|
145
|
+
const result = await this.memory.search({});
|
|
146
|
+
const byType = result.observations.reduce((acc, obs) => {
|
|
147
|
+
acc[obs.type] = (acc[obs.type] || 0) + 1;
|
|
148
|
+
return acc;
|
|
149
|
+
}, {});
|
|
150
|
+
console.log('Statistics:');
|
|
151
|
+
console.log(` Total observations: ${result.total}`);
|
|
152
|
+
console.log(' By type:');
|
|
153
|
+
Object.entries(byType).forEach(([type, count]) => {
|
|
154
|
+
console.log(` ${type}: ${count}`);
|
|
155
|
+
});
|
|
156
|
+
});
|
|
157
|
+
}
|
|
158
|
+
async getOrCreateSessionId(projectId) {
|
|
159
|
+
if (this.activeSessionId) {
|
|
160
|
+
return this.activeSessionId;
|
|
161
|
+
}
|
|
162
|
+
const session = await this.memory.createSession({
|
|
163
|
+
projectId,
|
|
164
|
+
endedAt: null,
|
|
165
|
+
metadata: {},
|
|
166
|
+
});
|
|
167
|
+
this.activeSessionId = session.id;
|
|
168
|
+
return session.id;
|
|
169
|
+
}
|
|
170
|
+
async run(argv = process.argv) {
|
|
171
|
+
await this.program.parseAsync(argv);
|
|
172
|
+
}
|
|
173
|
+
close() {
|
|
174
|
+
this.memory.close();
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
exports.CLI = CLI;
|
|
178
|
+
//# sourceMappingURL=CLI.js.map
|
package/dist/CLI.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"CLI.js","sourceRoot":"","sources":["../src/CLI.ts"],"names":[],"mappings":"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"}
|
package/dist/index.js
CHANGED
|
@@ -3,7 +3,12 @@
|
|
|
3
3
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
4
4
|
const commander_1 = require("commander");
|
|
5
5
|
const memento_core_1 = require("@slorenzot/memento-core");
|
|
6
|
-
const
|
|
6
|
+
const fs_1 = require("fs");
|
|
7
|
+
const path_1 = require("path");
|
|
8
|
+
const os_1 = require("os");
|
|
9
|
+
const config = (0, memento_core_1.loadConfig)();
|
|
10
|
+
const dbPath = (0, memento_core_1.resolveDbPath)(config);
|
|
11
|
+
const projectId = (0, memento_core_1.getProjectId)(config);
|
|
7
12
|
const memory = new memento_core_1.MemoryEngine(dbPath);
|
|
8
13
|
let activeSessionId = null;
|
|
9
14
|
async function getOrCreateSessionId(projectId) {
|
|
@@ -14,42 +19,75 @@ async function getOrCreateSessionId(projectId) {
|
|
|
14
19
|
return session.id;
|
|
15
20
|
}
|
|
16
21
|
const program = new commander_1.Command();
|
|
17
|
-
program
|
|
18
|
-
|
|
19
|
-
.
|
|
20
|
-
.
|
|
21
|
-
|
|
22
|
+
program
|
|
23
|
+
.name('memento')
|
|
24
|
+
.description('Persistent memory system for AI coding agents')
|
|
25
|
+
.version('1.0.0');
|
|
26
|
+
// ─── Search ─────────────────────────────────────────────────
|
|
27
|
+
program
|
|
28
|
+
.command('search <query>')
|
|
29
|
+
.description('Search observations')
|
|
30
|
+
.option('-t, --type <type>', 'Filter by type')
|
|
31
|
+
.option('-p, --project <project>', 'Filter by project')
|
|
32
|
+
.option('--limit <number>', 'Limit results')
|
|
33
|
+
.option('--include-deleted', 'Include soft-deleted observations')
|
|
22
34
|
.action(async (query, options) => {
|
|
23
|
-
const result = await memory.search({
|
|
35
|
+
const result = await memory.search({
|
|
36
|
+
query,
|
|
37
|
+
type: options.type,
|
|
38
|
+
projectId: options.project,
|
|
39
|
+
limit: options.limit ? parseInt(options.limit) : undefined,
|
|
40
|
+
includeDeleted: options.includeDeleted,
|
|
41
|
+
});
|
|
24
42
|
console.log(`Found ${result.total} observations:`);
|
|
25
|
-
result.observations.forEach((obs) => {
|
|
43
|
+
result.observations.forEach((obs) => {
|
|
44
|
+
const deleted = obs.deletedAt ? ' [DELETED]' : '';
|
|
45
|
+
console.log(` [${obs.type}] ${obs.title}${deleted}\n ${obs.content.substring(0, 100)}...`);
|
|
46
|
+
});
|
|
26
47
|
memory.close();
|
|
27
48
|
});
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
.
|
|
31
|
-
.
|
|
49
|
+
// ─── Save ───────────────────────────────────────────────────
|
|
50
|
+
program
|
|
51
|
+
.command('save <title> <content>')
|
|
52
|
+
.description('Save an observation')
|
|
53
|
+
.option('-t, --type <type>', 'Observation type', 'note')
|
|
54
|
+
.option('-k, --topic <topic>', 'Topic key')
|
|
55
|
+
.option('-p, --project <project>', 'Project ID', projectId)
|
|
32
56
|
.action(async (title, content, options) => {
|
|
33
57
|
const sessionId = await getOrCreateSessionId(options.project);
|
|
34
|
-
const observation = await memory.createObservation({
|
|
58
|
+
const observation = await memory.createObservation({
|
|
59
|
+
sessionId,
|
|
60
|
+
title,
|
|
61
|
+
content,
|
|
62
|
+
type: options.type,
|
|
63
|
+
topicKey: options.topic || null,
|
|
64
|
+
projectId: options.project,
|
|
65
|
+
metadata: {},
|
|
66
|
+
});
|
|
35
67
|
console.log(`Saved observation: ${observation.uuid}`);
|
|
36
68
|
memory.close();
|
|
37
69
|
});
|
|
38
|
-
|
|
70
|
+
// ─── Get ────────────────────────────────────────────────────
|
|
71
|
+
program
|
|
72
|
+
.command('get <id>')
|
|
73
|
+
.description('Get observation by ID')
|
|
39
74
|
.action(async (id) => {
|
|
40
75
|
const observation = await memory.getObservation(parseInt(id));
|
|
41
76
|
if (!observation) {
|
|
42
|
-
console.error(
|
|
77
|
+
console.error('Observation not found');
|
|
43
78
|
memory.close();
|
|
44
79
|
return;
|
|
45
80
|
}
|
|
46
|
-
console.log(`[${observation.type}] ${observation.title}\n${observation.content}\nTopic: ${observation.topicKey ||
|
|
81
|
+
console.log(`[${observation.type}] ${observation.title}\n${observation.content}\nTopic: ${observation.topicKey || 'none'}\nCreated: ${observation.createdAt.toISOString()}`);
|
|
47
82
|
memory.close();
|
|
48
83
|
});
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
.
|
|
52
|
-
.
|
|
84
|
+
// ─── Update ─────────────────────────────────────────────────
|
|
85
|
+
program
|
|
86
|
+
.command('update <id>')
|
|
87
|
+
.description('Update observation')
|
|
88
|
+
.option('-t, --title <title>', 'New title')
|
|
89
|
+
.option('-c, --content <content>', 'New content')
|
|
90
|
+
.option('-k, --topic <topic>', 'New topic key')
|
|
53
91
|
.action(async (id, options) => {
|
|
54
92
|
const updates = {};
|
|
55
93
|
if (options.title)
|
|
@@ -62,28 +100,214 @@ program.command("update <id>").description("Update observation")
|
|
|
62
100
|
console.log(`Updated observation: ${observation.uuid}`);
|
|
63
101
|
memory.close();
|
|
64
102
|
});
|
|
65
|
-
|
|
103
|
+
// ─── Delete (soft) ──────────────────────────────────────────
|
|
104
|
+
program
|
|
105
|
+
.command('delete <id>')
|
|
106
|
+
.description('Soft-delete observation (can be restored)')
|
|
107
|
+
.option('-r, --reason <reason>', 'Reason for deletion')
|
|
108
|
+
.action(async (id, options) => {
|
|
109
|
+
await memory.deleteObservation(parseInt(id), options.reason);
|
|
110
|
+
console.log(`Soft-deleted observation ${id} (use 'restore' to undo, 'purge' to permanently delete)`);
|
|
111
|
+
memory.close();
|
|
112
|
+
});
|
|
113
|
+
// ─── Restore ────────────────────────────────────────────────
|
|
114
|
+
program
|
|
115
|
+
.command('restore <id>')
|
|
116
|
+
.description('Restore a soft-deleted observation')
|
|
66
117
|
.action(async (id) => {
|
|
67
|
-
await memory.
|
|
68
|
-
console.log(`
|
|
118
|
+
const obs = await memory.restoreObservation(parseInt(id));
|
|
119
|
+
console.log(`Restored observation: ${obs.uuid} — "${obs.title}"`);
|
|
69
120
|
memory.close();
|
|
70
121
|
});
|
|
71
|
-
|
|
72
|
-
|
|
122
|
+
// ─── Purge ──────────────────────────────────────────────────
|
|
123
|
+
program
|
|
124
|
+
.command('purge')
|
|
125
|
+
.description('Permanently delete soft-deleted observations (IRREVERSIBLE)')
|
|
126
|
+
.option('-p, --project <project>', 'Purge only for this project')
|
|
127
|
+
.option('--yes', 'Skip confirmation')
|
|
128
|
+
.action(async (options) => {
|
|
129
|
+
if (!options.yes) {
|
|
130
|
+
console.error('⚠️ This will PERMANENTLY delete all soft-deleted observations.');
|
|
131
|
+
console.error(' Use --yes to confirm.');
|
|
132
|
+
memory.close();
|
|
133
|
+
return;
|
|
134
|
+
}
|
|
135
|
+
const result = await memory.purgeObservations({ projectId: options.project });
|
|
136
|
+
console.log(`Purged ${result.purgedCount} observations permanently.`);
|
|
137
|
+
if (result.purgedIds.length > 0) {
|
|
138
|
+
console.log(`IDs: ${result.purgedIds.join(', ')}`);
|
|
139
|
+
}
|
|
140
|
+
memory.close();
|
|
141
|
+
});
|
|
142
|
+
// ─── List Deleted ───────────────────────────────────────────
|
|
143
|
+
program
|
|
144
|
+
.command('list-deleted')
|
|
145
|
+
.description('List soft-deleted observations')
|
|
146
|
+
.option('-p, --project <project>', 'Filter by project')
|
|
147
|
+
.option('-l, --limit <number>', 'Limit results', '20')
|
|
148
|
+
.action(async (options) => {
|
|
149
|
+
const result = await memory.listDeleted({
|
|
150
|
+
projectId: options.project,
|
|
151
|
+
limit: parseInt(options.limit),
|
|
152
|
+
});
|
|
153
|
+
console.log(`Soft-deleted observations (${result.total} total):`);
|
|
154
|
+
result.observations.forEach((obs) => {
|
|
155
|
+
console.log(` [#${obs.id}] ${obs.title} — deleted: ${obs.deletedAt?.toISOString()}`);
|
|
156
|
+
});
|
|
157
|
+
memory.close();
|
|
158
|
+
});
|
|
159
|
+
// ─── Merge ──────────────────────────────────────────────────
|
|
160
|
+
program
|
|
161
|
+
.command('merge')
|
|
162
|
+
.description('Merge related observations')
|
|
163
|
+
.requiredOption('-p, --project <project>', 'Project ID')
|
|
164
|
+
.option('-s, --strategy <strategy>', 'Strategy: by_topic, by_similarity, by_ids', 'by_topic')
|
|
165
|
+
.option('-k, --topic <topic>', 'Merge only this topic key')
|
|
166
|
+
.option('--dry-run', 'Preview candidates without executing')
|
|
167
|
+
.action(async (options) => {
|
|
168
|
+
const results = await memory.mergeObservations({
|
|
169
|
+
projectId: options.project,
|
|
170
|
+
topicKey: options.topic,
|
|
171
|
+
strategy: options.strategy,
|
|
172
|
+
dryRun: options.dryRun,
|
|
173
|
+
});
|
|
174
|
+
if (options.dryRun) {
|
|
175
|
+
console.log(`Merge candidates (dry run — no changes made):`);
|
|
176
|
+
}
|
|
177
|
+
else {
|
|
178
|
+
console.log(`Merge results:`);
|
|
179
|
+
}
|
|
180
|
+
for (const r of results) {
|
|
181
|
+
console.log(` Merged ${r.originalCount} obs → #${r.mergedObservation.id} "${r.mergedObservation.title}" (deleted: ${r.deletedIds.join(', ')})`);
|
|
182
|
+
}
|
|
183
|
+
if (results.length === 0) {
|
|
184
|
+
console.log(' No candidates found for merging.');
|
|
185
|
+
}
|
|
186
|
+
memory.close();
|
|
187
|
+
});
|
|
188
|
+
// ─── Export ─────────────────────────────────────────────────
|
|
189
|
+
program
|
|
190
|
+
.command('export')
|
|
191
|
+
.description('Export observations to JSON, XML, or TXT')
|
|
192
|
+
.option('-f, --format <format>', 'Format: json, xml, txt', 'json')
|
|
193
|
+
.option('-p, --project <project>', 'Filter by project')
|
|
194
|
+
.option('-t, --type <type>', 'Filter by type')
|
|
195
|
+
.option('-k, --topic <topic>', 'Filter by topic key')
|
|
196
|
+
.option('--from <date>', 'Export from this date (ISO format)')
|
|
197
|
+
.option('--to <date>', 'Export until this date (ISO format)')
|
|
198
|
+
.option('--include-deleted', 'Include soft-deleted observations')
|
|
199
|
+
.option('-o, --output <file>', 'Output file path (default: stdout)')
|
|
200
|
+
.action(async (options) => {
|
|
201
|
+
const result = await memory.exportObservations({
|
|
202
|
+
format: options.format,
|
|
203
|
+
projectId: options.project,
|
|
204
|
+
type: options.type,
|
|
205
|
+
topicKey: options.topic,
|
|
206
|
+
dateFrom: options.from ? new Date(options.from) : undefined,
|
|
207
|
+
dateTo: options.to ? new Date(options.to) : undefined,
|
|
208
|
+
includeDeleted: options.includeDeleted,
|
|
209
|
+
});
|
|
210
|
+
if (options.output) {
|
|
211
|
+
const { writeFileSync } = await import('fs');
|
|
212
|
+
writeFileSync(options.output, result.content, 'utf-8');
|
|
213
|
+
console.error(`Exported ${result.recordCount} observations to ${options.output} (${result.format})`);
|
|
214
|
+
}
|
|
215
|
+
else {
|
|
216
|
+
console.log(result.content);
|
|
217
|
+
}
|
|
218
|
+
memory.close();
|
|
219
|
+
});
|
|
220
|
+
// ─── Timeline ───────────────────────────────────────────────
|
|
221
|
+
program
|
|
222
|
+
.command('timeline [project]')
|
|
223
|
+
.description('Show timeline')
|
|
224
|
+
.option('-l, --limit <number>', 'Limit results', '20')
|
|
73
225
|
.action(async (project, options) => {
|
|
74
226
|
const result = await memory.search({ projectId: project, limit: parseInt(options.limit) });
|
|
75
227
|
console.log(`Timeline (${result.total} observations):`);
|
|
76
|
-
result.observations.forEach((obs) => {
|
|
228
|
+
result.observations.forEach((obs) => {
|
|
229
|
+
console.log(` ${obs.createdAt.toLocaleDateString()} [${obs.type}] ${obs.title}`);
|
|
230
|
+
});
|
|
77
231
|
memory.close();
|
|
78
232
|
});
|
|
79
|
-
|
|
233
|
+
// ─── Stats ──────────────────────────────────────────────────
|
|
234
|
+
program
|
|
235
|
+
.command('stats')
|
|
236
|
+
.description('Show statistics')
|
|
80
237
|
.action(async () => {
|
|
81
238
|
const result = await memory.search({});
|
|
239
|
+
const deleted = await memory.listDeleted({});
|
|
82
240
|
const byType = {};
|
|
83
|
-
result.observations.forEach((obs) => {
|
|
84
|
-
|
|
85
|
-
|
|
241
|
+
result.observations.forEach((obs) => {
|
|
242
|
+
byType[obs.type] = (byType[obs.type] || 0) + 1;
|
|
243
|
+
});
|
|
244
|
+
console.log(`Statistics:`);
|
|
245
|
+
console.log(` Total observations: ${result.total}`);
|
|
246
|
+
console.log(` Soft-deleted: ${deleted.total}`);
|
|
247
|
+
console.log(` By type:`);
|
|
248
|
+
Object.entries(byType).forEach(([type, count]) => {
|
|
249
|
+
console.log(` ${type}: ${count}`);
|
|
250
|
+
});
|
|
86
251
|
memory.close();
|
|
87
252
|
});
|
|
253
|
+
// ─── Install Skill ──────────────────────────────────────────
|
|
254
|
+
program
|
|
255
|
+
.command('install-skill')
|
|
256
|
+
.description('Install Memento AI skill for coding agents')
|
|
257
|
+
.option('--target <target>', 'Target: opencode, claude, or a custom path', 'opencode')
|
|
258
|
+
.action(async (options) => {
|
|
259
|
+
const target = options.target;
|
|
260
|
+
// Resolve SKILL.md source — try multiple locations
|
|
261
|
+
const possiblePaths = [
|
|
262
|
+
// When installed as npm package
|
|
263
|
+
(0, path_1.join)((0, path_1.dirname)(require.resolve('@slorenzot/memento-mcp-server/package.json')), 'skills', 'memento', 'SKILL.md'),
|
|
264
|
+
].filter(() => {
|
|
265
|
+
try {
|
|
266
|
+
require.resolve('@slorenzot/memento-mcp-server/package.json');
|
|
267
|
+
return true;
|
|
268
|
+
}
|
|
269
|
+
catch {
|
|
270
|
+
return false;
|
|
271
|
+
}
|
|
272
|
+
});
|
|
273
|
+
// Fallback: relative to this CLI package (monorepo dev)
|
|
274
|
+
possiblePaths.push((0, path_1.join)(__dirname, '..', '..', 'mcp-server', 'skills', 'memento', 'SKILL.md'), (0, path_1.join)(__dirname, '..', '..', '..', 'packages', 'mcp-server', 'skills', 'memento', 'SKILL.md'));
|
|
275
|
+
let sourcePath = null;
|
|
276
|
+
for (const p of possiblePaths) {
|
|
277
|
+
if ((0, fs_1.existsSync)(p)) {
|
|
278
|
+
sourcePath = p;
|
|
279
|
+
break;
|
|
280
|
+
}
|
|
281
|
+
}
|
|
282
|
+
if (!sourcePath) {
|
|
283
|
+
console.error('Error: Could not find SKILL.md file.');
|
|
284
|
+
console.error('Searched in:', possiblePaths);
|
|
285
|
+
console.error('Make sure @slorenzot/memento-mcp-server is installed.');
|
|
286
|
+
process.exit(1);
|
|
287
|
+
}
|
|
288
|
+
// Determine destination
|
|
289
|
+
let destDir;
|
|
290
|
+
switch (target) {
|
|
291
|
+
case 'opencode':
|
|
292
|
+
destDir = (0, path_1.join)((0, os_1.homedir)(), '.config', 'opencode', 'skills', 'memento');
|
|
293
|
+
break;
|
|
294
|
+
case 'claude':
|
|
295
|
+
destDir = (0, path_1.join)((0, os_1.homedir)(), '.claude', 'skills', 'memento');
|
|
296
|
+
break;
|
|
297
|
+
default:
|
|
298
|
+
// Custom path
|
|
299
|
+
destDir = (0, path_1.join)(target, 'memento');
|
|
300
|
+
break;
|
|
301
|
+
}
|
|
302
|
+
const destPath = (0, path_1.join)(destDir, 'SKILL.md');
|
|
303
|
+
// Create directory and copy
|
|
304
|
+
(0, fs_1.mkdirSync)(destDir, { recursive: true });
|
|
305
|
+
(0, fs_1.copyFileSync)(sourcePath, destPath);
|
|
306
|
+
console.log(`✓ Memento skill installed successfully!`);
|
|
307
|
+
console.log(` Source: ${sourcePath}`);
|
|
308
|
+
console.log(` Target: ${destPath}`);
|
|
309
|
+
console.log(` Agent: ${target}`);
|
|
310
|
+
console.log(`\n The AI agent will now know how to use all memento_mem_* tools.`);
|
|
311
|
+
});
|
|
88
312
|
program.parseAsync(process.argv);
|
|
89
313
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,11 +1,13 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@slorenzot/memento-cli",
|
|
3
|
-
"version": "0.
|
|
4
|
-
"description": "CLI interface for Memento memory system",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "CLI interface for Memento memory system with merge, export, soft-delete, and skill installation",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"memento",
|
|
7
7
|
"memory",
|
|
8
|
-
"cli"
|
|
8
|
+
"cli",
|
|
9
|
+
"merge",
|
|
10
|
+
"export"
|
|
9
11
|
],
|
|
10
12
|
"license": "CC-BY-NC-ND-4.0",
|
|
11
13
|
"author": "Soulberto Lorenzo",
|
|
@@ -21,7 +23,7 @@
|
|
|
21
23
|
"prepare": "npm run build"
|
|
22
24
|
},
|
|
23
25
|
"dependencies": {
|
|
24
|
-
"@slorenzot/memento-core": "^0.
|
|
26
|
+
"@slorenzot/memento-core": "^1.0.0",
|
|
25
27
|
"commander": "^12.0.0"
|
|
26
28
|
},
|
|
27
29
|
"devDependencies": {
|
package/src/CLI.test.ts
ADDED
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
import { describe, it, expect, beforeEach, afterEach } from 'bun:test';
|
|
2
|
+
import { CLI } from './CLI';
|
|
3
|
+
|
|
4
|
+
describe('CLI', () => {
|
|
5
|
+
let cli: CLI;
|
|
6
|
+
let testDbPath: string;
|
|
7
|
+
|
|
8
|
+
beforeEach(() => {
|
|
9
|
+
testDbPath = `/tmp/test-cli-${Date.now()}.db`;
|
|
10
|
+
cli = new CLI(testDbPath);
|
|
11
|
+
});
|
|
12
|
+
|
|
13
|
+
afterEach(() => {
|
|
14
|
+
cli.close();
|
|
15
|
+
});
|
|
16
|
+
|
|
17
|
+
it('should initialize without errors', () => {
|
|
18
|
+
expect(cli).toBeDefined();
|
|
19
|
+
});
|
|
20
|
+
|
|
21
|
+
describe('Commands', () => {
|
|
22
|
+
it('should have all required commands', () => {
|
|
23
|
+
const commands = cli['program'].commands;
|
|
24
|
+
|
|
25
|
+
const commandNames = commands.map((c) => c.name());
|
|
26
|
+
expect(commandNames).toContain('setup');
|
|
27
|
+
expect(commandNames).toContain('serve');
|
|
28
|
+
expect(commandNames).toContain('mcp');
|
|
29
|
+
expect(commandNames).toContain('search');
|
|
30
|
+
expect(commandNames).toContain('save');
|
|
31
|
+
expect(commandNames).toContain('get');
|
|
32
|
+
expect(commandNames).toContain('update');
|
|
33
|
+
expect(commandNames).toContain('delete');
|
|
34
|
+
expect(commandNames).toContain('timeline');
|
|
35
|
+
expect(commandNames).toContain('stats');
|
|
36
|
+
});
|
|
37
|
+
|
|
38
|
+
it('should have proper descriptions', () => {
|
|
39
|
+
const commands = cli['program'].commands;
|
|
40
|
+
|
|
41
|
+
const setupCommand = commands.find((c) => c.name() === 'setup');
|
|
42
|
+
expect(setupCommand).toBeDefined();
|
|
43
|
+
expect(setupCommand?.description()).toContain('Setup');
|
|
44
|
+
|
|
45
|
+
const searchCommand = commands.find((c) => c.name() === 'search');
|
|
46
|
+
expect(searchCommand).toBeDefined();
|
|
47
|
+
expect(searchCommand?.description()).toContain('Search');
|
|
48
|
+
});
|
|
49
|
+
});
|
|
50
|
+
|
|
51
|
+
describe('Session Management', () => {
|
|
52
|
+
it('should create and track active session', async () => {
|
|
53
|
+
const sessionId = await cli['getOrCreateSessionId']('test-project');
|
|
54
|
+
expect(sessionId).toBeDefined();
|
|
55
|
+
|
|
56
|
+
const sameSessionId = await cli['getOrCreateSessionId']('test-project');
|
|
57
|
+
expect(sameSessionId).toBe(sessionId);
|
|
58
|
+
});
|
|
59
|
+
});
|
|
60
|
+
});
|
package/src/CLI.ts
ADDED
|
@@ -0,0 +1,192 @@
|
|
|
1
|
+
import { Command } from 'commander';
|
|
2
|
+
import { MemoryEngine, loadConfig, resolveDbPath, getProjectId } from '@slorenzot/memento-core';
|
|
3
|
+
import type { Observation } from '@slorenzot/memento-core';
|
|
4
|
+
|
|
5
|
+
// @ts-ignore
|
|
6
|
+
export class CLI {
|
|
7
|
+
private program: Command;
|
|
8
|
+
private memory: MemoryEngine;
|
|
9
|
+
private activeSessionId: number | null = null;
|
|
10
|
+
private projectId: string;
|
|
11
|
+
|
|
12
|
+
constructor() {
|
|
13
|
+
const config = loadConfig();
|
|
14
|
+
const dbPath = resolveDbPath(config);
|
|
15
|
+
this.projectId = getProjectId(config);
|
|
16
|
+
|
|
17
|
+
this.program = new Command();
|
|
18
|
+
this.memory = new MemoryEngine(dbPath);
|
|
19
|
+
this.setupCommands();
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
private setupCommands() {
|
|
23
|
+
this.program
|
|
24
|
+
.name('memento')
|
|
25
|
+
.description('Persistent memory system for AI coding agents')
|
|
26
|
+
.version('0.1.0');
|
|
27
|
+
|
|
28
|
+
this.program
|
|
29
|
+
.command('setup [agent]')
|
|
30
|
+
.description('Setup configuration for an AI agent')
|
|
31
|
+
.action((agent) => {
|
|
32
|
+
console.log(`Setup for agent: ${agent || 'default'}`);
|
|
33
|
+
console.log('Configuration saved to ~/.memento/config.json');
|
|
34
|
+
});
|
|
35
|
+
|
|
36
|
+
this.program
|
|
37
|
+
.command('serve [port]')
|
|
38
|
+
.description('Start API server')
|
|
39
|
+
.option('-d, --db <path>', 'Database path', './data/memento.db')
|
|
40
|
+
.action((port, options) => {
|
|
41
|
+
console.log(`Starting API server on port ${port || 3000}`);
|
|
42
|
+
console.log(`Database: ${options.db}`);
|
|
43
|
+
console.log('Note: API server not implemented in CLI mode');
|
|
44
|
+
});
|
|
45
|
+
|
|
46
|
+
this.program
|
|
47
|
+
.command('mcp')
|
|
48
|
+
.description('Start MCP server')
|
|
49
|
+
.option('-d, --db <path>', 'Database path', './data/memento.db')
|
|
50
|
+
.action((options) => {
|
|
51
|
+
console.log(`Starting MCP server`);
|
|
52
|
+
console.log(`Database: ${options.db}`);
|
|
53
|
+
console.log('Note: MCP server not implemented in CLI mode');
|
|
54
|
+
});
|
|
55
|
+
|
|
56
|
+
this.program
|
|
57
|
+
.command('search <query>')
|
|
58
|
+
.description('Search observations')
|
|
59
|
+
.option('-t, --type <type>', 'Filter by type')
|
|
60
|
+
.option('-p, --project <project>', 'Filter by project')
|
|
61
|
+
.option('--limit <number>', 'Limit results')
|
|
62
|
+
.action(async (query, options) => {
|
|
63
|
+
const result = await this.memory.search({
|
|
64
|
+
query,
|
|
65
|
+
type: options.type as Observation['type'] | undefined,
|
|
66
|
+
projectId: options.project as string | undefined,
|
|
67
|
+
limit: options.limit ? parseInt(options.limit as string) : undefined,
|
|
68
|
+
});
|
|
69
|
+
console.log(`Found ${result.total} observations:`);
|
|
70
|
+
result.observations.forEach((obs) => {
|
|
71
|
+
console.log(` [${obs.type}] ${obs.title}`);
|
|
72
|
+
console.log(` ${obs.content.substring(0, 100)}...`);
|
|
73
|
+
});
|
|
74
|
+
});
|
|
75
|
+
|
|
76
|
+
this.program
|
|
77
|
+
.command('save <title> <content>')
|
|
78
|
+
.description('Save an observation')
|
|
79
|
+
.option('-t, --type <type>', 'Observation type', 'note')
|
|
80
|
+
.option('-k, --topic <topic>', 'Topic key')
|
|
81
|
+
.option('-p, --project <project>', 'Project ID', this.projectId)
|
|
82
|
+
.action(async (title, content, options) => {
|
|
83
|
+
const sessionId = await this.getOrCreateSessionId(options.project as string);
|
|
84
|
+
const observation = await this.memory.createObservation({
|
|
85
|
+
sessionId,
|
|
86
|
+
title,
|
|
87
|
+
content,
|
|
88
|
+
type: options.type as Observation['type'],
|
|
89
|
+
topicKey: options.topic || null,
|
|
90
|
+
projectId: options.project as string,
|
|
91
|
+
metadata: {},
|
|
92
|
+
});
|
|
93
|
+
console.log(`Saved observation: ${observation.uuid}`);
|
|
94
|
+
});
|
|
95
|
+
|
|
96
|
+
this.program
|
|
97
|
+
.command('get <id>')
|
|
98
|
+
.description('Get observation by ID')
|
|
99
|
+
.action(async (id) => {
|
|
100
|
+
const observation = await this.memory.getObservation(parseInt(id));
|
|
101
|
+
if (!observation) {
|
|
102
|
+
console.error('Observation not found');
|
|
103
|
+
return;
|
|
104
|
+
}
|
|
105
|
+
console.log(`[${observation.type}] ${observation.title}`);
|
|
106
|
+
console.log(observation.content);
|
|
107
|
+
console.log(`Topic: ${observation.topicKey || 'none'}`);
|
|
108
|
+
console.log(`Created: ${observation.createdAt.toISOString()}`);
|
|
109
|
+
});
|
|
110
|
+
|
|
111
|
+
this.program
|
|
112
|
+
.command('update <id>')
|
|
113
|
+
.description('Update observation')
|
|
114
|
+
.option('-t, --title <title>', 'New title')
|
|
115
|
+
.option('-c, --content <content>', 'New content')
|
|
116
|
+
.option('-k, --topic <topic>', 'New topic key')
|
|
117
|
+
.action(async (id, options) => {
|
|
118
|
+
const updates: Partial<Observation> = {};
|
|
119
|
+
if (options.title) updates.title = options.title;
|
|
120
|
+
if (options.content) updates.content = options.content;
|
|
121
|
+
if (options.topic) updates.topicKey = options.topic;
|
|
122
|
+
|
|
123
|
+
const observation = await this.memory.updateObservation(parseInt(id), updates);
|
|
124
|
+
console.log(`Updated observation: ${observation.uuid}`);
|
|
125
|
+
});
|
|
126
|
+
|
|
127
|
+
this.program
|
|
128
|
+
.command('delete <id>')
|
|
129
|
+
.description('Delete observation')
|
|
130
|
+
.action(async (id) => {
|
|
131
|
+
await this.memory.deleteObservation(parseInt(id));
|
|
132
|
+
console.log(`Deleted observation ${id}`);
|
|
133
|
+
});
|
|
134
|
+
|
|
135
|
+
this.program
|
|
136
|
+
.command('timeline [project]')
|
|
137
|
+
.description('Show timeline of observations')
|
|
138
|
+
.option('-l, --limit <number>', 'Limit results', '20')
|
|
139
|
+
.action(async (project, options) => {
|
|
140
|
+
const result = await this.memory.search({
|
|
141
|
+
projectId: project,
|
|
142
|
+
limit: parseInt(options.limit as string),
|
|
143
|
+
});
|
|
144
|
+
console.log(`Timeline (${result.total} observations):`);
|
|
145
|
+
result.observations.forEach((obs) => {
|
|
146
|
+
const date = obs.createdAt.toLocaleDateString();
|
|
147
|
+
console.log(` ${date} [${obs.type}] ${obs.title}`);
|
|
148
|
+
});
|
|
149
|
+
});
|
|
150
|
+
|
|
151
|
+
this.program
|
|
152
|
+
.command('stats')
|
|
153
|
+
.description('Show statistics')
|
|
154
|
+
.action(async () => {
|
|
155
|
+
const result = await this.memory.search({});
|
|
156
|
+
const byType = result.observations.reduce(
|
|
157
|
+
(acc, obs) => {
|
|
158
|
+
acc[obs.type] = (acc[obs.type] || 0) + 1;
|
|
159
|
+
return acc;
|
|
160
|
+
},
|
|
161
|
+
{} as Record<string, number>
|
|
162
|
+
);
|
|
163
|
+
console.log('Statistics:');
|
|
164
|
+
console.log(` Total observations: ${result.total}`);
|
|
165
|
+
console.log(' By type:');
|
|
166
|
+
Object.entries(byType).forEach(([type, count]) => {
|
|
167
|
+
console.log(` ${type}: ${count}`);
|
|
168
|
+
});
|
|
169
|
+
});
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
private async getOrCreateSessionId(projectId: string): Promise<number> {
|
|
173
|
+
if (this.activeSessionId) {
|
|
174
|
+
return this.activeSessionId;
|
|
175
|
+
}
|
|
176
|
+
const session = await this.memory.createSession({
|
|
177
|
+
projectId,
|
|
178
|
+
endedAt: null,
|
|
179
|
+
metadata: {},
|
|
180
|
+
});
|
|
181
|
+
this.activeSessionId = session.id;
|
|
182
|
+
return session.id;
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
async run(argv: string[] = process.argv) {
|
|
186
|
+
await this.program.parseAsync(argv);
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
close() {
|
|
190
|
+
this.memory.close();
|
|
191
|
+
}
|
|
192
|
+
}
|
package/src/index.ts
CHANGED
|
@@ -1,10 +1,15 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
|
|
3
|
-
import { Command } from
|
|
4
|
-
import { MemoryEngine } from
|
|
5
|
-
import type { Observation } from
|
|
3
|
+
import { Command } from 'commander';
|
|
4
|
+
import { MemoryEngine, loadConfig, resolveDbPath, getProjectId } from '@slorenzot/memento-core';
|
|
5
|
+
import type { Observation, ExportFormat } from '@slorenzot/memento-core';
|
|
6
|
+
import { existsSync, mkdirSync, copyFileSync } from 'fs';
|
|
7
|
+
import { join, dirname } from 'path';
|
|
8
|
+
import { homedir } from 'os';
|
|
6
9
|
|
|
7
|
-
const
|
|
10
|
+
const config = loadConfig();
|
|
11
|
+
const dbPath = resolveDbPath(config);
|
|
12
|
+
const projectId = getProjectId(config);
|
|
8
13
|
const memory = new MemoryEngine(dbPath);
|
|
9
14
|
let activeSessionId: number | null = null;
|
|
10
15
|
|
|
@@ -16,42 +21,87 @@ async function getOrCreateSessionId(projectId: string): Promise<number> {
|
|
|
16
21
|
}
|
|
17
22
|
|
|
18
23
|
const program = new Command();
|
|
19
|
-
program
|
|
24
|
+
program
|
|
25
|
+
.name('memento')
|
|
26
|
+
.description('Persistent memory system for AI coding agents')
|
|
27
|
+
.version('1.0.0');
|
|
20
28
|
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
.
|
|
29
|
+
// ─── Search ─────────────────────────────────────────────────
|
|
30
|
+
|
|
31
|
+
program
|
|
32
|
+
.command('search <query>')
|
|
33
|
+
.description('Search observations')
|
|
34
|
+
.option('-t, --type <type>', 'Filter by type')
|
|
35
|
+
.option('-p, --project <project>', 'Filter by project')
|
|
36
|
+
.option('--limit <number>', 'Limit results')
|
|
37
|
+
.option('--include-deleted', 'Include soft-deleted observations')
|
|
25
38
|
.action(async (query: string, options: any) => {
|
|
26
|
-
const result = await memory.search({
|
|
39
|
+
const result = await memory.search({
|
|
40
|
+
query,
|
|
41
|
+
type: options.type,
|
|
42
|
+
projectId: options.project,
|
|
43
|
+
limit: options.limit ? parseInt(options.limit) : undefined,
|
|
44
|
+
includeDeleted: options.includeDeleted,
|
|
45
|
+
});
|
|
27
46
|
console.log(`Found ${result.total} observations:`);
|
|
28
|
-
result.observations.forEach((obs: Observation) => {
|
|
47
|
+
result.observations.forEach((obs: Observation) => {
|
|
48
|
+
const deleted = obs.deletedAt ? ' [DELETED]' : '';
|
|
49
|
+
console.log(
|
|
50
|
+
` [${obs.type}] ${obs.title}${deleted}\n ${obs.content.substring(0, 100)}...`
|
|
51
|
+
);
|
|
52
|
+
});
|
|
29
53
|
memory.close();
|
|
30
54
|
});
|
|
31
55
|
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
.
|
|
56
|
+
// ─── Save ───────────────────────────────────────────────────
|
|
57
|
+
|
|
58
|
+
program
|
|
59
|
+
.command('save <title> <content>')
|
|
60
|
+
.description('Save an observation')
|
|
61
|
+
.option('-t, --type <type>', 'Observation type', 'note')
|
|
62
|
+
.option('-k, --topic <topic>', 'Topic key')
|
|
63
|
+
.option('-p, --project <project>', 'Project ID', projectId)
|
|
36
64
|
.action(async (title: string, content: string, options: any) => {
|
|
37
65
|
const sessionId = await getOrCreateSessionId(options.project);
|
|
38
|
-
const observation = await memory.createObservation({
|
|
66
|
+
const observation = await memory.createObservation({
|
|
67
|
+
sessionId,
|
|
68
|
+
title,
|
|
69
|
+
content,
|
|
70
|
+
type: options.type,
|
|
71
|
+
topicKey: options.topic || null,
|
|
72
|
+
projectId: options.project,
|
|
73
|
+
metadata: {},
|
|
74
|
+
});
|
|
39
75
|
console.log(`Saved observation: ${observation.uuid}`);
|
|
40
76
|
memory.close();
|
|
41
77
|
});
|
|
42
78
|
|
|
43
|
-
|
|
79
|
+
// ─── Get ────────────────────────────────────────────────────
|
|
80
|
+
|
|
81
|
+
program
|
|
82
|
+
.command('get <id>')
|
|
83
|
+
.description('Get observation by ID')
|
|
44
84
|
.action(async (id: string) => {
|
|
45
85
|
const observation = await memory.getObservation(parseInt(id));
|
|
46
|
-
if (!observation) {
|
|
47
|
-
|
|
86
|
+
if (!observation) {
|
|
87
|
+
console.error('Observation not found');
|
|
88
|
+
memory.close();
|
|
89
|
+
return;
|
|
90
|
+
}
|
|
91
|
+
console.log(
|
|
92
|
+
`[${observation.type}] ${observation.title}\n${observation.content}\nTopic: ${observation.topicKey || 'none'}\nCreated: ${observation.createdAt.toISOString()}`
|
|
93
|
+
);
|
|
48
94
|
memory.close();
|
|
49
95
|
});
|
|
50
96
|
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
.
|
|
97
|
+
// ─── Update ─────────────────────────────────────────────────
|
|
98
|
+
|
|
99
|
+
program
|
|
100
|
+
.command('update <id>')
|
|
101
|
+
.description('Update observation')
|
|
102
|
+
.option('-t, --title <title>', 'New title')
|
|
103
|
+
.option('-c, --content <content>', 'New content')
|
|
104
|
+
.option('-k, --topic <topic>', 'New topic key')
|
|
55
105
|
.action(async (id: string, options: any) => {
|
|
56
106
|
const updates: any = {};
|
|
57
107
|
if (options.title) updates.title = options.title;
|
|
@@ -62,30 +112,258 @@ program.command("update <id>").description("Update observation")
|
|
|
62
112
|
memory.close();
|
|
63
113
|
});
|
|
64
114
|
|
|
65
|
-
|
|
115
|
+
// ─── Delete (soft) ──────────────────────────────────────────
|
|
116
|
+
|
|
117
|
+
program
|
|
118
|
+
.command('delete <id>')
|
|
119
|
+
.description('Soft-delete observation (can be restored)')
|
|
120
|
+
.option('-r, --reason <reason>', 'Reason for deletion')
|
|
121
|
+
.action(async (id: string, options: any) => {
|
|
122
|
+
await memory.deleteObservation(parseInt(id), options.reason);
|
|
123
|
+
console.log(
|
|
124
|
+
`Soft-deleted observation ${id} (use 'restore' to undo, 'purge' to permanently delete)`
|
|
125
|
+
);
|
|
126
|
+
memory.close();
|
|
127
|
+
});
|
|
128
|
+
|
|
129
|
+
// ─── Restore ────────────────────────────────────────────────
|
|
130
|
+
|
|
131
|
+
program
|
|
132
|
+
.command('restore <id>')
|
|
133
|
+
.description('Restore a soft-deleted observation')
|
|
66
134
|
.action(async (id: string) => {
|
|
67
|
-
await memory.
|
|
68
|
-
console.log(`
|
|
135
|
+
const obs = await memory.restoreObservation(parseInt(id));
|
|
136
|
+
console.log(`Restored observation: ${obs.uuid} — "${obs.title}"`);
|
|
137
|
+
memory.close();
|
|
138
|
+
});
|
|
139
|
+
|
|
140
|
+
// ─── Purge ──────────────────────────────────────────────────
|
|
141
|
+
|
|
142
|
+
program
|
|
143
|
+
.command('purge')
|
|
144
|
+
.description('Permanently delete soft-deleted observations (IRREVERSIBLE)')
|
|
145
|
+
.option('-p, --project <project>', 'Purge only for this project')
|
|
146
|
+
.option('--yes', 'Skip confirmation')
|
|
147
|
+
.action(async (options: any) => {
|
|
148
|
+
if (!options.yes) {
|
|
149
|
+
console.error('⚠️ This will PERMANENTLY delete all soft-deleted observations.');
|
|
150
|
+
console.error(' Use --yes to confirm.');
|
|
151
|
+
memory.close();
|
|
152
|
+
return;
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
const result = await memory.purgeObservations({ projectId: options.project });
|
|
156
|
+
console.log(`Purged ${result.purgedCount} observations permanently.`);
|
|
157
|
+
if (result.purgedIds.length > 0) {
|
|
158
|
+
console.log(`IDs: ${result.purgedIds.join(', ')}`);
|
|
159
|
+
}
|
|
160
|
+
memory.close();
|
|
161
|
+
});
|
|
162
|
+
|
|
163
|
+
// ─── List Deleted ───────────────────────────────────────────
|
|
164
|
+
|
|
165
|
+
program
|
|
166
|
+
.command('list-deleted')
|
|
167
|
+
.description('List soft-deleted observations')
|
|
168
|
+
.option('-p, --project <project>', 'Filter by project')
|
|
169
|
+
.option('-l, --limit <number>', 'Limit results', '20')
|
|
170
|
+
.action(async (options: any) => {
|
|
171
|
+
const result = await memory.listDeleted({
|
|
172
|
+
projectId: options.project,
|
|
173
|
+
limit: parseInt(options.limit),
|
|
174
|
+
});
|
|
175
|
+
console.log(`Soft-deleted observations (${result.total} total):`);
|
|
176
|
+
result.observations.forEach((obs: Observation) => {
|
|
177
|
+
console.log(` [#${obs.id}] ${obs.title} — deleted: ${obs.deletedAt?.toISOString()}`);
|
|
178
|
+
});
|
|
69
179
|
memory.close();
|
|
70
180
|
});
|
|
71
181
|
|
|
72
|
-
|
|
73
|
-
|
|
182
|
+
// ─── Merge ──────────────────────────────────────────────────
|
|
183
|
+
|
|
184
|
+
program
|
|
185
|
+
.command('merge')
|
|
186
|
+
.description('Merge related observations')
|
|
187
|
+
.requiredOption('-p, --project <project>', 'Project ID')
|
|
188
|
+
.option('-s, --strategy <strategy>', 'Strategy: by_topic, by_similarity, by_ids', 'by_topic')
|
|
189
|
+
.option('-k, --topic <topic>', 'Merge only this topic key')
|
|
190
|
+
.option('--dry-run', 'Preview candidates without executing')
|
|
191
|
+
.action(async (options: any) => {
|
|
192
|
+
const results = await memory.mergeObservations({
|
|
193
|
+
projectId: options.project,
|
|
194
|
+
topicKey: options.topic,
|
|
195
|
+
strategy: options.strategy,
|
|
196
|
+
dryRun: options.dryRun,
|
|
197
|
+
});
|
|
198
|
+
|
|
199
|
+
if (options.dryRun) {
|
|
200
|
+
console.log(`Merge candidates (dry run — no changes made):`);
|
|
201
|
+
} else {
|
|
202
|
+
console.log(`Merge results:`);
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
for (const r of results) {
|
|
206
|
+
console.log(
|
|
207
|
+
` Merged ${r.originalCount} obs → #${r.mergedObservation.id} "${r.mergedObservation.title}" (deleted: ${r.deletedIds.join(', ')})`
|
|
208
|
+
);
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
if (results.length === 0) {
|
|
212
|
+
console.log(' No candidates found for merging.');
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
memory.close();
|
|
216
|
+
});
|
|
217
|
+
|
|
218
|
+
// ─── Export ─────────────────────────────────────────────────
|
|
219
|
+
|
|
220
|
+
program
|
|
221
|
+
.command('export')
|
|
222
|
+
.description('Export observations to JSON, XML, or TXT')
|
|
223
|
+
.option('-f, --format <format>', 'Format: json, xml, txt', 'json')
|
|
224
|
+
.option('-p, --project <project>', 'Filter by project')
|
|
225
|
+
.option('-t, --type <type>', 'Filter by type')
|
|
226
|
+
.option('-k, --topic <topic>', 'Filter by topic key')
|
|
227
|
+
.option('--from <date>', 'Export from this date (ISO format)')
|
|
228
|
+
.option('--to <date>', 'Export until this date (ISO format)')
|
|
229
|
+
.option('--include-deleted', 'Include soft-deleted observations')
|
|
230
|
+
.option('-o, --output <file>', 'Output file path (default: stdout)')
|
|
231
|
+
.action(async (options: any) => {
|
|
232
|
+
const result = await memory.exportObservations({
|
|
233
|
+
format: options.format as ExportFormat,
|
|
234
|
+
projectId: options.project,
|
|
235
|
+
type: options.type,
|
|
236
|
+
topicKey: options.topic,
|
|
237
|
+
dateFrom: options.from ? new Date(options.from) : undefined,
|
|
238
|
+
dateTo: options.to ? new Date(options.to) : undefined,
|
|
239
|
+
includeDeleted: options.includeDeleted,
|
|
240
|
+
});
|
|
241
|
+
|
|
242
|
+
if (options.output) {
|
|
243
|
+
const { writeFileSync } = await import('fs');
|
|
244
|
+
writeFileSync(options.output, result.content, 'utf-8');
|
|
245
|
+
console.error(
|
|
246
|
+
`Exported ${result.recordCount} observations to ${options.output} (${result.format})`
|
|
247
|
+
);
|
|
248
|
+
} else {
|
|
249
|
+
console.log(result.content);
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
memory.close();
|
|
253
|
+
});
|
|
254
|
+
|
|
255
|
+
// ─── Timeline ───────────────────────────────────────────────
|
|
256
|
+
|
|
257
|
+
program
|
|
258
|
+
.command('timeline [project]')
|
|
259
|
+
.description('Show timeline')
|
|
260
|
+
.option('-l, --limit <number>', 'Limit results', '20')
|
|
74
261
|
.action(async (project: string, options: any) => {
|
|
75
262
|
const result = await memory.search({ projectId: project, limit: parseInt(options.limit) });
|
|
76
263
|
console.log(`Timeline (${result.total} observations):`);
|
|
77
|
-
result.observations.forEach((obs: Observation) => {
|
|
264
|
+
result.observations.forEach((obs: Observation) => {
|
|
265
|
+
console.log(` ${obs.createdAt.toLocaleDateString()} [${obs.type}] ${obs.title}`);
|
|
266
|
+
});
|
|
78
267
|
memory.close();
|
|
79
268
|
});
|
|
80
269
|
|
|
81
|
-
|
|
270
|
+
// ─── Stats ──────────────────────────────────────────────────
|
|
271
|
+
|
|
272
|
+
program
|
|
273
|
+
.command('stats')
|
|
274
|
+
.description('Show statistics')
|
|
82
275
|
.action(async () => {
|
|
83
276
|
const result = await memory.search({});
|
|
277
|
+
const deleted = await memory.listDeleted({});
|
|
84
278
|
const byType: Record<string, number> = {};
|
|
85
|
-
result.observations.forEach((obs: Observation) => {
|
|
86
|
-
|
|
87
|
-
|
|
279
|
+
result.observations.forEach((obs: Observation) => {
|
|
280
|
+
byType[obs.type] = (byType[obs.type] || 0) + 1;
|
|
281
|
+
});
|
|
282
|
+
console.log(`Statistics:`);
|
|
283
|
+
console.log(` Total observations: ${result.total}`);
|
|
284
|
+
console.log(` Soft-deleted: ${deleted.total}`);
|
|
285
|
+
console.log(` By type:`);
|
|
286
|
+
Object.entries(byType).forEach(([type, count]) => {
|
|
287
|
+
console.log(` ${type}: ${count}`);
|
|
288
|
+
});
|
|
88
289
|
memory.close();
|
|
89
290
|
});
|
|
90
291
|
|
|
292
|
+
// ─── Install Skill ──────────────────────────────────────────
|
|
293
|
+
|
|
294
|
+
program
|
|
295
|
+
.command('install-skill')
|
|
296
|
+
.description('Install Memento AI skill for coding agents')
|
|
297
|
+
.option('--target <target>', 'Target: opencode, claude, or a custom path', 'opencode')
|
|
298
|
+
.action(async (options: any) => {
|
|
299
|
+
const target = options.target;
|
|
300
|
+
|
|
301
|
+
// Resolve SKILL.md source — try multiple locations
|
|
302
|
+
const possiblePaths = [
|
|
303
|
+
// When installed as npm package
|
|
304
|
+
join(
|
|
305
|
+
dirname(require.resolve('@slorenzot/memento-mcp-server/package.json')),
|
|
306
|
+
'skills',
|
|
307
|
+
'memento',
|
|
308
|
+
'SKILL.md'
|
|
309
|
+
),
|
|
310
|
+
].filter(() => {
|
|
311
|
+
try {
|
|
312
|
+
require.resolve('@slorenzot/memento-mcp-server/package.json');
|
|
313
|
+
return true;
|
|
314
|
+
} catch {
|
|
315
|
+
return false;
|
|
316
|
+
}
|
|
317
|
+
});
|
|
318
|
+
|
|
319
|
+
// Fallback: relative to this CLI package (monorepo dev)
|
|
320
|
+
possiblePaths.push(
|
|
321
|
+
join(__dirname, '..', '..', 'mcp-server', 'skills', 'memento', 'SKILL.md'),
|
|
322
|
+
join(__dirname, '..', '..', '..', 'packages', 'mcp-server', 'skills', 'memento', 'SKILL.md')
|
|
323
|
+
);
|
|
324
|
+
|
|
325
|
+
let sourcePath: string | null = null;
|
|
326
|
+
for (const p of possiblePaths) {
|
|
327
|
+
if (existsSync(p)) {
|
|
328
|
+
sourcePath = p;
|
|
329
|
+
break;
|
|
330
|
+
}
|
|
331
|
+
}
|
|
332
|
+
|
|
333
|
+
if (!sourcePath) {
|
|
334
|
+
console.error('Error: Could not find SKILL.md file.');
|
|
335
|
+
console.error('Searched in:', possiblePaths);
|
|
336
|
+
console.error('Make sure @slorenzot/memento-mcp-server is installed.');
|
|
337
|
+
process.exit(1);
|
|
338
|
+
}
|
|
339
|
+
|
|
340
|
+
// Determine destination
|
|
341
|
+
let destDir: string;
|
|
342
|
+
|
|
343
|
+
switch (target) {
|
|
344
|
+
case 'opencode':
|
|
345
|
+
destDir = join(homedir(), '.config', 'opencode', 'skills', 'memento');
|
|
346
|
+
break;
|
|
347
|
+
case 'claude':
|
|
348
|
+
destDir = join(homedir(), '.claude', 'skills', 'memento');
|
|
349
|
+
break;
|
|
350
|
+
default:
|
|
351
|
+
// Custom path
|
|
352
|
+
destDir = join(target, 'memento');
|
|
353
|
+
break;
|
|
354
|
+
}
|
|
355
|
+
|
|
356
|
+
const destPath = join(destDir, 'SKILL.md');
|
|
357
|
+
|
|
358
|
+
// Create directory and copy
|
|
359
|
+
mkdirSync(destDir, { recursive: true });
|
|
360
|
+
copyFileSync(sourcePath, destPath);
|
|
361
|
+
|
|
362
|
+
console.log(`✓ Memento skill installed successfully!`);
|
|
363
|
+
console.log(` Source: ${sourcePath}`);
|
|
364
|
+
console.log(` Target: ${destPath}`);
|
|
365
|
+
console.log(` Agent: ${target}`);
|
|
366
|
+
console.log(`\n The AI agent will now know how to use all memento_mem_* tools.`);
|
|
367
|
+
});
|
|
368
|
+
|
|
91
369
|
program.parseAsync(process.argv);
|
package/data/memento.db
DELETED
|
Binary file
|
package/data/memento.db-shm
DELETED
|
Binary file
|
package/data/memento.db-wal
DELETED
|
Binary file
|
|
Binary file
|