@slorenzot/memento-cli 0.3.0 → 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/index.js CHANGED
@@ -3,6 +3,9 @@
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 fs_1 = require("fs");
7
+ const path_1 = require("path");
8
+ const os_1 = require("os");
6
9
  const config = (0, memento_core_1.loadConfig)();
7
10
  const dbPath = (0, memento_core_1.resolveDbPath)(config);
8
11
  const projectId = (0, memento_core_1.getProjectId)(config);
@@ -19,26 +22,31 @@ const program = new commander_1.Command();
19
22
  program
20
23
  .name('memento')
21
24
  .description('Persistent memory system for AI coding agents')
22
- .version('0.2.0');
25
+ .version('1.0.0');
26
+ // ─── Search ─────────────────────────────────────────────────
23
27
  program
24
28
  .command('search <query>')
25
29
  .description('Search observations')
26
30
  .option('-t, --type <type>', 'Filter by type')
27
31
  .option('-p, --project <project>', 'Filter by project')
28
32
  .option('--limit <number>', 'Limit results')
33
+ .option('--include-deleted', 'Include soft-deleted observations')
29
34
  .action(async (query, options) => {
30
35
  const result = await memory.search({
31
36
  query,
32
37
  type: options.type,
33
38
  projectId: options.project,
34
39
  limit: options.limit ? parseInt(options.limit) : undefined,
40
+ includeDeleted: options.includeDeleted,
35
41
  });
36
42
  console.log(`Found ${result.total} observations:`);
37
43
  result.observations.forEach((obs) => {
38
- console.log(` [${obs.type}] ${obs.title}\n ${obs.content.substring(0, 100)}...`);
44
+ const deleted = obs.deletedAt ? ' [DELETED]' : '';
45
+ console.log(` [${obs.type}] ${obs.title}${deleted}\n ${obs.content.substring(0, 100)}...`);
39
46
  });
40
47
  memory.close();
41
48
  });
49
+ // ─── Save ───────────────────────────────────────────────────
42
50
  program
43
51
  .command('save <title> <content>')
44
52
  .description('Save an observation')
@@ -59,6 +67,7 @@ program
59
67
  console.log(`Saved observation: ${observation.uuid}`);
60
68
  memory.close();
61
69
  });
70
+ // ─── Get ────────────────────────────────────────────────────
62
71
  program
63
72
  .command('get <id>')
64
73
  .description('Get observation by ID')
@@ -72,6 +81,7 @@ program
72
81
  console.log(`[${observation.type}] ${observation.title}\n${observation.content}\nTopic: ${observation.topicKey || 'none'}\nCreated: ${observation.createdAt.toISOString()}`);
73
82
  memory.close();
74
83
  });
84
+ // ─── Update ─────────────────────────────────────────────────
75
85
  program
76
86
  .command('update <id>')
77
87
  .description('Update observation')
@@ -90,14 +100,124 @@ program
90
100
  console.log(`Updated observation: ${observation.uuid}`);
91
101
  memory.close();
92
102
  });
103
+ // ─── Delete (soft) ──────────────────────────────────────────
93
104
  program
94
105
  .command('delete <id>')
95
- .description('Delete observation')
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')
96
117
  .action(async (id) => {
97
- await memory.deleteObservation(parseInt(id));
98
- console.log(`Deleted observation ${id}`);
118
+ const obs = await memory.restoreObservation(parseInt(id));
119
+ console.log(`Restored observation: ${obs.uuid} — "${obs.title}"`);
120
+ memory.close();
121
+ });
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
+ }
99
140
  memory.close();
100
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 ───────────────────────────────────────────────
101
221
  program
102
222
  .command('timeline [project]')
103
223
  .description('Show timeline')
@@ -110,20 +230,84 @@ program
110
230
  });
111
231
  memory.close();
112
232
  });
233
+ // ─── Stats ──────────────────────────────────────────────────
113
234
  program
114
235
  .command('stats')
115
236
  .description('Show statistics')
116
237
  .action(async () => {
117
238
  const result = await memory.search({});
239
+ const deleted = await memory.listDeleted({});
118
240
  const byType = {};
119
241
  result.observations.forEach((obs) => {
120
242
  byType[obs.type] = (byType[obs.type] || 0) + 1;
121
243
  });
122
- console.log(`Statistics:\n Total observations: ${result.total}\n By type:`);
244
+ console.log(`Statistics:`);
245
+ console.log(` Total observations: ${result.total}`);
246
+ console.log(` Soft-deleted: ${deleted.total}`);
247
+ console.log(` By type:`);
123
248
  Object.entries(byType).forEach(([type, count]) => {
124
249
  console.log(` ${type}: ${count}`);
125
250
  });
126
251
  memory.close();
127
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
+ });
128
312
  program.parseAsync(process.argv);
129
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":";;;AAEA,yCAAoC;AACpC,0DAAgG;AAGhG,MAAM,MAAM,GAAG,IAAA,yBAAU,GAAE,CAAC;AAC5B,MAAM,MAAM,GAAG,IAAA,4BAAa,EAAC,MAAM,CAAC,CAAC;AACrC,MAAM,SAAS,GAAG,IAAA,2BAAY,EAAC,MAAM,CAAC,CAAC;AACvC,MAAM,MAAM,GAAG,IAAI,2BAAY,CAAC,MAAM,CAAC,CAAC;AACxC,IAAI,eAAe,GAAkB,IAAI,CAAC;AAE1C,KAAK,UAAU,oBAAoB,CAAC,SAAiB;IACnD,IAAI,eAAe;QAAE,OAAO,eAAe,CAAC;IAC5C,MAAM,OAAO,GAAG,MAAM,MAAM,CAAC,aAAa,CAAC,EAAE,SAAS,EAAE,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,EAAE,EAAE,CAAC,CAAC;IACvF,eAAe,GAAG,OAAO,CAAC,EAAE,CAAC;IAC7B,OAAO,OAAO,CAAC,EAAE,CAAC;AACpB,CAAC;AAED,MAAM,OAAO,GAAG,IAAI,mBAAO,EAAE,CAAC;AAC9B,OAAO;KACJ,IAAI,CAAC,SAAS,CAAC;KACf,WAAW,CAAC,+CAA+C,CAAC;KAC5D,OAAO,CAAC,OAAO,CAAC,CAAC;AAEpB,OAAO;KACJ,OAAO,CAAC,gBAAgB,CAAC;KACzB,WAAW,CAAC,qBAAqB,CAAC;KAClC,MAAM,CAAC,mBAAmB,EAAE,gBAAgB,CAAC;KAC7C,MAAM,CAAC,yBAAyB,EAAE,mBAAmB,CAAC;KACtD,MAAM,CAAC,kBAAkB,EAAE,eAAe,CAAC;KAC3C,MAAM,CAAC,KAAK,EAAE,KAAa,EAAE,OAAY,EAAE,EAAE;IAC5C,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,MAAM,CAAC;QACjC,KAAK;QACL,IAAI,EAAE,OAAO,CAAC,IAAI;QAClB,SAAS,EAAE,OAAO,CAAC,OAAO;QAC1B,KAAK,EAAE,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,QAAQ,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,SAAS;KAC3D,CAAC,CAAC;IACH,OAAO,CAAC,GAAG,CAAC,SAAS,MAAM,CAAC,KAAK,gBAAgB,CAAC,CAAC;IACnD,MAAM,CAAC,YAAY,CAAC,OAAO,CAAC,CAAC,GAAgB,EAAE,EAAE;QAC/C,OAAO,CAAC,GAAG,CAAC,MAAM,GAAG,CAAC,IAAI,KAAK,GAAG,CAAC,KAAK,SAAS,GAAG,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC,EAAE,GAAG,CAAC,KAAK,CAAC,CAAC;IACvF,CAAC,CAAC,CAAC;IACH,MAAM,CAAC,KAAK,EAAE,CAAC;AACjB,CAAC,CAAC,CAAC;AAEL,OAAO;KACJ,OAAO,CAAC,wBAAwB,CAAC;KACjC,WAAW,CAAC,qBAAqB,CAAC;KAClC,MAAM,CAAC,mBAAmB,EAAE,kBAAkB,EAAE,MAAM,CAAC;KACvD,MAAM,CAAC,qBAAqB,EAAE,WAAW,CAAC;KAC1C,MAAM,CAAC,yBAAyB,EAAE,YAAY,EAAE,SAAS,CAAC;KAC1D,MAAM,CAAC,KAAK,EAAE,KAAa,EAAE,OAAe,EAAE,OAAY,EAAE,EAAE;IAC7D,MAAM,SAAS,GAAG,MAAM,oBAAoB,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC;IAC9D,MAAM,WAAW,GAAG,MAAM,MAAM,CAAC,iBAAiB,CAAC;QACjD,SAAS;QACT,KAAK;QACL,OAAO;QACP,IAAI,EAAE,OAAO,CAAC,IAAI;QAClB,QAAQ,EAAE,OAAO,CAAC,KAAK,IAAI,IAAI;QAC/B,SAAS,EAAE,OAAO,CAAC,OAAO;QAC1B,QAAQ,EAAE,EAAE;KACb,CAAC,CAAC;IACH,OAAO,CAAC,GAAG,CAAC,sBAAsB,WAAW,CAAC,IAAI,EAAE,CAAC,CAAC;IACtD,MAAM,CAAC,KAAK,EAAE,CAAC;AACjB,CAAC,CAAC,CAAC;AAEL,OAAO;KACJ,OAAO,CAAC,UAAU,CAAC;KACnB,WAAW,CAAC,uBAAuB,CAAC;KACpC,MAAM,CAAC,KAAK,EAAE,EAAU,EAAE,EAAE;IAC3B,MAAM,WAAW,GAAG,MAAM,MAAM,CAAC,cAAc,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,CAAC;IAC9D,IAAI,CAAC,WAAW,EAAE,CAAC;QACjB,OAAO,CAAC,KAAK,CAAC,uBAAuB,CAAC,CAAC;QACvC,MAAM,CAAC,KAAK,EAAE,CAAC;QACf,OAAO;IACT,CAAC;IACD,OAAO,CAAC,GAAG,CACT,IAAI,WAAW,CAAC,IAAI,KAAK,WAAW,CAAC,KAAK,KAAK,WAAW,CAAC,OAAO,YAAY,WAAW,CAAC,QAAQ,IAAI,MAAM,cAAc,WAAW,CAAC,SAAS,CAAC,WAAW,EAAE,EAAE,CAChK,CAAC;IACF,MAAM,CAAC,KAAK,EAAE,CAAC;AACjB,CAAC,CAAC,CAAC;AAEL,OAAO;KACJ,OAAO,CAAC,aAAa,CAAC;KACtB,WAAW,CAAC,oBAAoB,CAAC;KACjC,MAAM,CAAC,qBAAqB,EAAE,WAAW,CAAC;KAC1C,MAAM,CAAC,yBAAyB,EAAE,aAAa,CAAC;KAChD,MAAM,CAAC,qBAAqB,EAAE,eAAe,CAAC;KAC9C,MAAM,CAAC,KAAK,EAAE,EAAU,EAAE,OAAY,EAAE,EAAE;IACzC,MAAM,OAAO,GAAQ,EAAE,CAAC;IACxB,IAAI,OAAO,CAAC,KAAK;QAAE,OAAO,CAAC,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC;IACjD,IAAI,OAAO,CAAC,OAAO;QAAE,OAAO,CAAC,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC;IACvD,IAAI,OAAO,CAAC,KAAK;QAAE,OAAO,CAAC,QAAQ,GAAG,OAAO,CAAC,KAAK,CAAC;IACpD,MAAM,WAAW,GAAG,MAAM,MAAM,CAAC,iBAAiB,CAAC,QAAQ,CAAC,EAAE,CAAC,EAAE,OAAO,CAAC,CAAC;IAC1E,OAAO,CAAC,GAAG,CAAC,wBAAwB,WAAW,CAAC,IAAI,EAAE,CAAC,CAAC;IACxD,MAAM,CAAC,KAAK,EAAE,CAAC;AACjB,CAAC,CAAC,CAAC;AAEL,OAAO;KACJ,OAAO,CAAC,aAAa,CAAC;KACtB,WAAW,CAAC,oBAAoB,CAAC;KACjC,MAAM,CAAC,KAAK,EAAE,EAAU,EAAE,EAAE;IAC3B,MAAM,MAAM,CAAC,iBAAiB,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,CAAC;IAC7C,OAAO,CAAC,GAAG,CAAC,uBAAuB,EAAE,EAAE,CAAC,CAAC;IACzC,MAAM,CAAC,KAAK,EAAE,CAAC;AACjB,CAAC,CAAC,CAAC;AAEL,OAAO;KACJ,OAAO,CAAC,oBAAoB,CAAC;KAC7B,WAAW,CAAC,eAAe,CAAC;KAC5B,MAAM,CAAC,sBAAsB,EAAE,eAAe,EAAE,IAAI,CAAC;KACrD,MAAM,CAAC,KAAK,EAAE,OAAe,EAAE,OAAY,EAAE,EAAE;IAC9C,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,MAAM,CAAC,EAAE,SAAS,EAAE,OAAO,EAAE,KAAK,EAAE,QAAQ,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;IAC3F,OAAO,CAAC,GAAG,CAAC,aAAa,MAAM,CAAC,KAAK,iBAAiB,CAAC,CAAC;IACxD,MAAM,CAAC,YAAY,CAAC,OAAO,CAAC,CAAC,GAAgB,EAAE,EAAE;QAC/C,OAAO,CAAC,GAAG,CAAC,KAAK,GAAG,CAAC,SAAS,CAAC,kBAAkB,EAAE,KAAK,GAAG,CAAC,IAAI,KAAK,GAAG,CAAC,KAAK,EAAE,CAAC,CAAC;IACpF,CAAC,CAAC,CAAC;IACH,MAAM,CAAC,KAAK,EAAE,CAAC;AACjB,CAAC,CAAC,CAAC;AAEL,OAAO;KACJ,OAAO,CAAC,OAAO,CAAC;KAChB,WAAW,CAAC,iBAAiB,CAAC;KAC9B,MAAM,CAAC,KAAK,IAAI,EAAE;IACjB,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;IACvC,MAAM,MAAM,GAA2B,EAAE,CAAC;IAC1C,MAAM,CAAC,YAAY,CAAC,OAAO,CAAC,CAAC,GAAgB,EAAE,EAAE;QAC/C,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC;IACjD,CAAC,CAAC,CAAC;IACH,OAAO,CAAC,GAAG,CAAC,sCAAsC,MAAM,CAAC,KAAK,cAAc,CAAC,CAAC;IAC9E,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,EAAE,KAAK,CAAC,EAAE,EAAE;QAC/C,OAAO,CAAC,GAAG,CAAC,OAAO,IAAI,KAAK,KAAK,EAAE,CAAC,CAAC;IACvC,CAAC,CAAC,CAAC;IACH,MAAM,CAAC,KAAK,EAAE,CAAC;AACjB,CAAC,CAAC,CAAC;AAEL,OAAO,CAAC,UAAU,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC"}
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.3.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.6.0",
26
+ "@slorenzot/memento-core": "^1.0.0",
25
27
  "commander": "^12.0.0"
26
28
  },
27
29
  "devDependencies": {
package/src/index.ts CHANGED
@@ -2,7 +2,10 @@
2
2
 
3
3
  import { Command } from 'commander';
4
4
  import { MemoryEngine, loadConfig, resolveDbPath, getProjectId } from '@slorenzot/memento-core';
5
- import type { Observation } 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
10
  const config = loadConfig();
8
11
  const dbPath = resolveDbPath(config);
@@ -21,7 +24,9 @@ const program = new Command();
21
24
  program
22
25
  .name('memento')
23
26
  .description('Persistent memory system for AI coding agents')
24
- .version('0.2.0');
27
+ .version('1.0.0');
28
+
29
+ // ─── Search ─────────────────────────────────────────────────
25
30
 
26
31
  program
27
32
  .command('search <query>')
@@ -29,20 +34,27 @@ program
29
34
  .option('-t, --type <type>', 'Filter by type')
30
35
  .option('-p, --project <project>', 'Filter by project')
31
36
  .option('--limit <number>', 'Limit results')
37
+ .option('--include-deleted', 'Include soft-deleted observations')
32
38
  .action(async (query: string, options: any) => {
33
39
  const result = await memory.search({
34
40
  query,
35
41
  type: options.type,
36
42
  projectId: options.project,
37
43
  limit: options.limit ? parseInt(options.limit) : undefined,
44
+ includeDeleted: options.includeDeleted,
38
45
  });
39
46
  console.log(`Found ${result.total} observations:`);
40
47
  result.observations.forEach((obs: Observation) => {
41
- console.log(` [${obs.type}] ${obs.title}\n ${obs.content.substring(0, 100)}...`);
48
+ const deleted = obs.deletedAt ? ' [DELETED]' : '';
49
+ console.log(
50
+ ` [${obs.type}] ${obs.title}${deleted}\n ${obs.content.substring(0, 100)}...`
51
+ );
42
52
  });
43
53
  memory.close();
44
54
  });
45
55
 
56
+ // ─── Save ───────────────────────────────────────────────────
57
+
46
58
  program
47
59
  .command('save <title> <content>')
48
60
  .description('Save an observation')
@@ -64,6 +76,8 @@ program
64
76
  memory.close();
65
77
  });
66
78
 
79
+ // ─── Get ────────────────────────────────────────────────────
80
+
67
81
  program
68
82
  .command('get <id>')
69
83
  .description('Get observation by ID')
@@ -80,6 +94,8 @@ program
80
94
  memory.close();
81
95
  });
82
96
 
97
+ // ─── Update ─────────────────────────────────────────────────
98
+
83
99
  program
84
100
  .command('update <id>')
85
101
  .description('Update observation')
@@ -96,15 +112,148 @@ program
96
112
  memory.close();
97
113
  });
98
114
 
115
+ // ─── Delete (soft) ──────────────────────────────────────────
116
+
99
117
  program
100
118
  .command('delete <id>')
101
- .description('Delete observation')
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')
102
134
  .action(async (id: string) => {
103
- await memory.deleteObservation(parseInt(id));
104
- console.log(`Deleted observation ${id}`);
135
+ const obs = await memory.restoreObservation(parseInt(id));
136
+ console.log(`Restored observation: ${obs.uuid} — "${obs.title}"`);
105
137
  memory.close();
106
138
  });
107
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
+ });
179
+ memory.close();
180
+ });
181
+
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
+
108
257
  program
109
258
  .command('timeline [project]')
110
259
  .description('Show timeline')
@@ -118,20 +267,103 @@ program
118
267
  memory.close();
119
268
  });
120
269
 
270
+ // ─── Stats ──────────────────────────────────────────────────
271
+
121
272
  program
122
273
  .command('stats')
123
274
  .description('Show statistics')
124
275
  .action(async () => {
125
276
  const result = await memory.search({});
277
+ const deleted = await memory.listDeleted({});
126
278
  const byType: Record<string, number> = {};
127
279
  result.observations.forEach((obs: Observation) => {
128
280
  byType[obs.type] = (byType[obs.type] || 0) + 1;
129
281
  });
130
- console.log(`Statistics:\n Total observations: ${result.total}\n By type:`);
282
+ console.log(`Statistics:`);
283
+ console.log(` Total observations: ${result.total}`);
284
+ console.log(` Soft-deleted: ${deleted.total}`);
285
+ console.log(` By type:`);
131
286
  Object.entries(byType).forEach(([type, count]) => {
132
287
  console.log(` ${type}: ${count}`);
133
288
  });
134
289
  memory.close();
135
290
  });
136
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
+
137
369
  program.parseAsync(process.argv);