@slorenzot/memento-cli 0.1.1 → 0.2.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/README.md ADDED
@@ -0,0 +1,422 @@
1
+ # @slorenzot/memento-cli
2
+
3
+ [![NPM Version](https://img.shields.io/npm/v/@slorenzot/memento-cli.svg)](https://www.npmjs.com/package/@slorenzot/memento-cli)
4
+ [![License: CC BY-NC-ND 4.0](https://img.shields.io/badge/License-CC_BY--NC--ND_4.0-lightgrey.svg)](https://creativecommons.org/licenses/by-nc-nd/4.0/)
5
+ [![TypeScript](https://img.shields.io/badge/TypeScript-5.3+-blue.svg)](https://www.typescriptlang.org/)
6
+
7
+ > Command line interface for Memento memory system with search, management, and administrative commands for AI coding agents.
8
+
9
+ ## 🚀 Instalación
10
+
11
+ ```bash
12
+ # Using Bun (recomendado)
13
+ bun add -g @slorenzot/memento-cli
14
+
15
+ # Using npm
16
+ npm install -g @slorenzot/memento-cli
17
+
18
+ # Using yarn
19
+ yarn global add @slorenzot/memento-cli
20
+ ```
21
+
22
+ ## 💡 Uso Básico
23
+
24
+ ### Shell/Bun
25
+ ```bash
26
+ # Ver ayuda general
27
+ memento --help
28
+
29
+ # Ver versión
30
+ memento --version
31
+ ```
32
+
33
+ ## 🔧 Comandos Disponibles
34
+
35
+ ### Comandos Principales
36
+
37
+ #### `search [query]`
38
+ Busca observaciones en la memoria usando búsqueda full-text.
39
+
40
+ **Parámetros:**
41
+ - `query` (opcional): Texto de búsqueda
42
+
43
+ **Opciones:**
44
+ - `--type, -t`: Filtrar por tipo (`decision|bug|discovery|note`)
45
+ - `--project, -p`: Filtrar por ID de proyecto
46
+ - `--limit, -l`: Número máximo de resultados
47
+ - `--offset, -o`: Paginación de resultados
48
+
49
+ **Ejemplos:**
50
+ ```bash
51
+ # Búsqueda simple
52
+ memento search "arquitectura base de datos"
53
+
54
+ # Búsqueda filtrada
55
+ memento search "configuración" --type decision --limit 5
56
+
57
+ # Búsqueda en proyecto específico
58
+ memento search "bug" --project my-app --type bug
59
+ ```
60
+
61
+ ---
62
+
63
+ #### `save [title] [content]`
64
+ Guarda una nueva observación en la memoria.
65
+
66
+ **Parámetros:**
67
+ - `title`: Título de la observación
68
+ - `content`: Contenido de la observación
69
+
70
+ **Opciones:**
71
+ - `--type, -t`: Tipo de observación (`decision|bug|discovery|note`)
72
+ - `--topic, -k`: Tópico o categoría
73
+ - `--project, -p`: ID del proyecto
74
+ - `--metadata, -m`: Metadatos JSON
75
+
76
+ **Ejemplos:**
77
+ ```bash
78
+ # Guardar observación simple
79
+ memento save "Decisión importante" "Usar PostgreSQL en producción"
80
+
81
+ # Guardar con tipo y proyecto
82
+ memento save "Bug encontrado" "Error de conexión" --type bug --project my-app
83
+
84
+ # Guardar con metadatos
85
+ memento save "Configuración completada" "Servidor listo" --metadata '{"status":"ready","port":3000}'
86
+ ```
87
+
88
+ ---
89
+
90
+ #### `get [id]`
91
+ Obtiene una observación específica por ID.
92
+
93
+ **Parámetros:**
94
+ - `id`: ID numérico de la observación
95
+
96
+ **Ejemplos:**
97
+ ```bash
98
+ # Obtener observación por ID
99
+ memento get 123
100
+
101
+ # La salida mostrará todos los detalles de la observación
102
+ ```
103
+
104
+ ---
105
+
106
+ #### `update <id> [options]`
107
+ Actualiza una observación existente.
108
+
109
+ **Parámetros:**
110
+ - `id`: ID numérico de la observación
111
+
112
+ **Opciones:**
113
+ - `--title, -t`: Nuevo título
114
+ - `--content, -c`: Nuevo contenido
115
+ - `--type`: Nuevo tipo
116
+ - `--topic, -k`: Nuevo tópico
117
+
118
+ **Ejemplos:**
119
+ ```bash
120
+ # Actualizar título
121
+ memento update 123 --title "Título corregido"
122
+
123
+ # Actualizar contenido
124
+ memento update 123 --content "Contenido actualizado"
125
+
126
+ # Actualizar múltiples campos
127
+ memento update 123 --title "Nuevo" --type decision
128
+ ```
129
+
130
+ ---
131
+
132
+ #### `delete <id>`
133
+ Elimina una observación por ID.
134
+
135
+ **Parámetros:**
136
+ - `id`: ID numérico de la observación
137
+
138
+ **Ejemplos:**
139
+ ```bash
140
+ # Eliminar observación
141
+ memento delete 123
142
+ ```
143
+
144
+ ---
145
+
146
+ ### Comandos de Sesiones
147
+
148
+ #### `session start [project]`
149
+ Inicia una nueva sesión de seguimiento.
150
+
151
+ **Parámetros:**
152
+ - `project` (opcional): ID del proyecto
153
+
154
+ **Ejemplos:**
155
+ ```bash
156
+ # Iniciar sesión
157
+ memento session start my-app
158
+ ```
159
+
160
+ ---
161
+
162
+ #### `session end <id>`
163
+ Finaliza una sesión activa.
164
+
165
+ **Parámetros:**
166
+ - `id`: ID numérico de la sesión
167
+
168
+ **Ejemplos:**
169
+ ```bash
170
+ # Finalizar sesión
171
+ memento session end 456
172
+ ```
173
+
174
+ ---
175
+
176
+ #### `session list [project]`
177
+ Lista sesiones del proyecto.
178
+
179
+ **Parámetros:**
180
+ - `project` (opcional): ID del proyecto
181
+
182
+ **Opciones:**
183
+ - `--limit, -l`: Número máximo de resultados
184
+
185
+ **Ejemplos:**
186
+ ```bash
187
+ # Listar todas las sesiones
188
+ memento session list
189
+
190
+ # Listar sesiones de proyecto específico
191
+ memento session list my-app --limit 10
192
+ ```
193
+
194
+ ---
195
+
196
+ ### Comandos de Utilidad
197
+
198
+ #### `stats`
199
+ Muestra estadísticas del sistema de memoria.
200
+
201
+ **Ejemplos:**
202
+ ```bash
203
+ # Ver estadísticas
204
+ memento stats
205
+
206
+ # Salida esperada:
207
+ # Total observaciones: 150
208
+ # Por tipo: decision: 45, bug: 30, discovery: 50, note: 25
209
+ # Sesiones activas: 3
210
+ # Última actualización: 2024-04-04 10:30:00
211
+ ```
212
+
213
+ ---
214
+
215
+ #### `timeline [project]`
216
+ Muestra una línea temporal de observaciones.
217
+
218
+ **Parámetros:**
219
+ - `project` (opcional): ID del proyecto
220
+
221
+ **Opciones:**
222
+ - `--limit, -l`: Número máximo de resultados
223
+ - `--session, -s`: Filtrar por sesión ID
224
+
225
+ **Ejemplos:**
226
+ ```bash
227
+ # Ver timeline completo
228
+ memento timeline
229
+
230
+ # Ver timeline de proyecto específico
231
+ memento timeline my-app --limit 20
232
+ ```
233
+
234
+ ---
235
+
236
+ ## 📝 API Programática
237
+
238
+ ### Uso en Node.js/TypeScript
239
+
240
+ ```typescript
241
+ import { CLI } from '@slorenzot/memento-cli';
242
+
243
+ // Crear instancia CLI
244
+ const cli = new CLI('./data/memento.db');
245
+
246
+ // Ejecutar comando programáticamente
247
+ // Nota: Este uso es para integración personalizada
248
+ // Para uso normal, usar los comandos de shell
249
+
250
+ // Los comandos principales se ejecutan a través del método run()
251
+ cli.run(['search', 'arquitectura']);
252
+
253
+ // Cerrar conexión
254
+ cli.close();
255
+ ```
256
+
257
+ ## ⚡ Ejemplos Prácticos
258
+
259
+ ### Ejemplo 1: Flujo de Trabajo Completo
260
+
261
+ ```bash
262
+ # Iniciar sesión para seguimiento
263
+ SESSION_ID=$(memento session start my-app | grep "ID:" | cut -d' ' -f2)
264
+ echo "Sesión iniciada: $SESSION_ID"
265
+
266
+ # Guardar observaciones durante el trabajo
267
+ memento save "Decisión de arquitectura" "Usar microservicios" --project my-app
268
+ memento save "Bug encontrado" "Error en autenticación" --type bug --project my-app
269
+
270
+ # Buscar decisiones anteriores
271
+ memento search "arquitectura" --type decision --project my-app
272
+
273
+ # Finalizar sesión
274
+ memento session end $SESSION_ID
275
+ ```
276
+
277
+ ### Ejemplo 2: Script de Búsqueda y Análisis
278
+
279
+ ```bash
280
+ #!/bin/bash
281
+
282
+ # Buscar bugs del proyecto
283
+ echo "=== Buscando bugs en proyecto ==="
284
+ memento search "bug" --type bug --project my-app --limit 10
285
+
286
+ # Buscar decisiones recientes
287
+ echo ""
288
+ echo "=== Decisiones recientes ==="
289
+ memento search --type decision --project my-app --limit 5
290
+
291
+ # Mostrar estadísticas
292
+ echo ""
293
+ echo "=== Estadísticas del sistema ==="
294
+ memento stats
295
+ ```
296
+
297
+ ### Ejemplo 3: Integración con Git Hooks
298
+
299
+ ```bash
300
+ # pre-commit hook
301
+ #!/bin/bash
302
+
303
+ # Guardar commits como observaciones
304
+ MESSAGE=$(git log -1 --pretty=%B)
305
+ memento save "Commit: $(git rev-parse --short HEAD)" "$MESSAGE" --type note
306
+
307
+ echo "Commit guardado en Memento"
308
+ ```
309
+
310
+ ### Ejemplo 4: Exportación y Backup
311
+
312
+ ```bash
313
+ # Exportar observaciones del proyecto
314
+ memento timeline my-app --limit 1000 > backup-observations.txt
315
+
316
+ # Crear backup con metadatos
317
+ echo "Backup creado: $(date)" > backup-info.txt
318
+ memento stats >> backup-info.txt
319
+ ```
320
+
321
+ ## 🔧 Configuración
322
+
323
+ ### Archivo de Configuración
324
+
325
+ La CLI busca configuración en `~/.memento/config.json`:
326
+
327
+ ```json
328
+ {
329
+ "databasePath": "./data/memento.db",
330
+ "defaultProject": "my-app",
331
+ "outputFormat": "json",
332
+ "pagination": {
333
+ "limit": 20,
334
+ "offset": 0
335
+ }
336
+ }
337
+ ```
338
+
339
+ ### Variables de Entorno
340
+
341
+ - `MEMENTO_DB_PATH`: Ruta personalizada de base de datos
342
+ - `MEMENTO_DEFAULT_PROJECT`: Proyecto por defecto
343
+
344
+ **Ejemplos:**
345
+ ```bash
346
+ # Usar base de datos personalizada
347
+ export MEMENTO_DB_PATH="/custom/path/database.db"
348
+ memento search "query"
349
+ ```
350
+
351
+ ## ⚠️ Licencia Restrictiva
352
+
353
+ Este paquete está bajo **Licencia CC BY-NC-ND 4.0**:
354
+ - ✅ **Uso personal y educacional permitido**
355
+ - ✅ **Compartir con atribución al autor**
356
+ - ❌ **Uso comercial NO permitido**
357
+ - ❌ **Modificaciones o forks NO permitidos**
358
+
359
+ **Autor**: Soulberto Lorenzo (slorenzot@gmail.com)
360
+
361
+ ## 🔄 Dependencias
362
+
363
+ ### Dependencias Principales
364
+ - `@slorenzot/memento-core` - Motor de memoria
365
+ - `commander` - Framework de CLI
366
+ - `chalk` - Colores en terminal
367
+ - `ora` - Indicadores de progreso
368
+ - `ink` - Componentes de UI en terminal
369
+ - `zod` - Validación de esquemas
370
+
371
+ ### Peer Dependencies
372
+ - `bun` v1.0+ (recomendado)
373
+ - `node` v20+ (compatible)
374
+
375
+ ## 🛠️ Desarrollo
376
+
377
+ ```bash
378
+ # Clonar el proyecto
379
+ git clone https://github.com/slorenzot/memento.git
380
+ cd memento/packages/cli
381
+
382
+ # Instalar dependencias
383
+ bun install
384
+
385
+ # Desarrollo
386
+ bun run dev
387
+
388
+ # Build
389
+ bun run build
390
+
391
+ # Tests
392
+ bun test
393
+ ```
394
+
395
+ ## 📋 Changelog
396
+
397
+ ### [0.1.1] - 2024-04-04
398
+ - **Fixed**: Actualización de dependencias core
399
+ - **Fixed**: Mejora en manejo de argumentos CLI
400
+ - **Updated**: Optimización de salida de comandos
401
+
402
+ ### [0.1.0] - 2024-04-04
403
+ - **Added**: Versión inicial de la CLI
404
+ - **Added**: Comandos de gestión de memoria
405
+ - **Added**: Comandos de búsqueda y estadísticas
406
+ - **Added**: Soporte completo de colores y progreso
407
+
408
+ ## 👤 Autor
409
+
410
+ **Soulberto Lorenzo**
411
+ - GitHub: [@slorenzot](https://github.com/slorenzot)
412
+ - Email: slorenzot@gmail.com
413
+
414
+ ## 📄 Licencia
415
+
416
+ Este paquete está bajo Licencia **Creative Commons Attribution-NonCommercial-NoDerivs 4.0 International**.
417
+
418
+ [Ver Licencia Completa](https://github.com/slorenzot/memento/blob/main/LICENSE)
419
+
420
+ ---
421
+
422
+ **⚠️ Importante**: Este paquete tiene licencia restrictiva. Respeta los términos de la licencia CC BY-NC-ND 4.0.
Binary file
Binary file
Binary file
package/dist/index.d.ts CHANGED
@@ -1,2 +1,3 @@
1
- export { CLI } from './CLI';
1
+ #!/usr/bin/env node
2
+ export {};
2
3
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,GAAG,EAAE,MAAM,OAAO,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":""}
package/dist/index.js ADDED
@@ -0,0 +1,89 @@
1
+ #!/usr/bin/env node
2
+ "use strict";
3
+ Object.defineProperty(exports, "__esModule", { value: true });
4
+ const commander_1 = require("commander");
5
+ const memento_core_1 = require("@slorenzot/memento-core");
6
+ const dbPath = process.env.MEMENTO_DB_PATH || "./data/memento.db";
7
+ const memory = new memento_core_1.MemoryEngine(dbPath);
8
+ let activeSessionId = null;
9
+ async function getOrCreateSessionId(projectId) {
10
+ if (activeSessionId)
11
+ return activeSessionId;
12
+ const session = await memory.createSession({ projectId, endedAt: null, metadata: {} });
13
+ activeSessionId = session.id;
14
+ return session.id;
15
+ }
16
+ const program = new commander_1.Command();
17
+ program.name("memento").description("Persistent memory system for AI coding agents").version("0.2.0");
18
+ program.command("search <query>").description("Search observations")
19
+ .option("-t, --type <type>", "Filter by type")
20
+ .option("-p, --project <project>", "Filter by project")
21
+ .option("--limit <number>", "Limit results")
22
+ .action(async (query, options) => {
23
+ const result = await memory.search({ query, type: options.type, projectId: options.project, limit: options.limit ? parseInt(options.limit) : undefined });
24
+ console.log(`Found ${result.total} observations:`);
25
+ result.observations.forEach((obs) => { console.log(` [${obs.type}] ${obs.title}\n ${obs.content.substring(0, 100)}...`); });
26
+ memory.close();
27
+ });
28
+ program.command("save <title> <content>").description("Save an observation")
29
+ .option("-t, --type <type>", "Observation type", "note")
30
+ .option("-k, --topic <topic>", "Topic key")
31
+ .option("-p, --project <project>", "Project ID", "default")
32
+ .action(async (title, content, options) => {
33
+ const sessionId = await getOrCreateSessionId(options.project);
34
+ const observation = await memory.createObservation({ sessionId, title, content, type: options.type, topicKey: options.topic || null, projectId: options.project, metadata: {} });
35
+ console.log(`Saved observation: ${observation.uuid}`);
36
+ memory.close();
37
+ });
38
+ program.command("get <id>").description("Get observation by ID")
39
+ .action(async (id) => {
40
+ const observation = await memory.getObservation(parseInt(id));
41
+ if (!observation) {
42
+ console.error("Observation not found");
43
+ memory.close();
44
+ return;
45
+ }
46
+ console.log(`[${observation.type}] ${observation.title}\n${observation.content}\nTopic: ${observation.topicKey || "none"}\nCreated: ${observation.createdAt.toISOString()}`);
47
+ memory.close();
48
+ });
49
+ program.command("update <id>").description("Update observation")
50
+ .option("-t, --title <title>", "New title")
51
+ .option("-c, --content <content>", "New content")
52
+ .option("-k, --topic <topic>", "New topic key")
53
+ .action(async (id, options) => {
54
+ const updates = {};
55
+ if (options.title)
56
+ updates.title = options.title;
57
+ if (options.content)
58
+ updates.content = options.content;
59
+ if (options.topic)
60
+ updates.topicKey = options.topic;
61
+ const observation = await memory.updateObservation(parseInt(id), updates);
62
+ console.log(`Updated observation: ${observation.uuid}`);
63
+ memory.close();
64
+ });
65
+ program.command("delete <id>").description("Delete observation")
66
+ .action(async (id) => {
67
+ await memory.deleteObservation(parseInt(id));
68
+ console.log(`Deleted observation ${id}`);
69
+ memory.close();
70
+ });
71
+ program.command("timeline [project]").description("Show timeline")
72
+ .option("-l, --limit <number>", "Limit results", "20")
73
+ .action(async (project, options) => {
74
+ const result = await memory.search({ projectId: project, limit: parseInt(options.limit) });
75
+ console.log(`Timeline (${result.total} observations):`);
76
+ result.observations.forEach((obs) => { console.log(` ${obs.createdAt.toLocaleDateString()} [${obs.type}] ${obs.title}`); });
77
+ memory.close();
78
+ });
79
+ program.command("stats").description("Show statistics")
80
+ .action(async () => {
81
+ const result = await memory.search({});
82
+ const byType = {};
83
+ result.observations.forEach((obs) => { byType[obs.type] = (byType[obs.type] || 0) + 1; });
84
+ console.log(`Statistics:\n Total observations: ${result.total}\n By type:`);
85
+ Object.entries(byType).forEach(([type, count]) => { console.log(` ${type}: ${count}`); });
86
+ memory.close();
87
+ });
88
+ program.parseAsync(process.argv);
89
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,29 +1,31 @@
1
1
  {
2
2
  "name": "@slorenzot/memento-cli",
3
- "version": "0.1.1",
4
- "description": "CLI interface for Memento",
5
- "main": "./dist/index.js",
6
- "types": "./dist/index.d.ts",
3
+ "version": "0.2.0",
4
+ "description": "CLI interface for Memento memory system",
5
+ "keywords": [
6
+ "memento",
7
+ "memory",
8
+ "cli"
9
+ ],
10
+ "license": "CC-BY-NC-ND-4.0",
11
+ "author": "Soulberto Lorenzo",
12
+ "type": "commonjs",
13
+ "main": "dist/index.js",
14
+ "types": "dist/index.d.ts",
7
15
  "bin": {
8
- "memento": "./dist/cli.js"
16
+ "memento": "dist/index.js"
9
17
  },
10
18
  "scripts": {
11
- "dev": "bun run src/cli.ts",
12
- "build": "bun tsc --declaration --declarationMap --emitDeclarationOnly --outDir ./dist",
13
- "test": "bun test",
14
- "typecheck": "bun tsc --noEmit"
19
+ "build": "tsc",
20
+ "start": "node dist/index.js",
21
+ "prepare": "npm run build"
15
22
  },
16
23
  "dependencies": {
17
- "@slorenzot/memento-core": "^0.1.0",
18
- "commander": "^12.0.0",
19
- "ink": "^4.4.1",
20
- "chalk": "^5.3.0",
21
- "ora": "^8.0.1",
22
- "zod": "^3.22.4",
23
- "dotenv": "^16.4.1"
24
+ "@slorenzot/memento-core": "file:../../../tmp/core-build/slorenzot-memento-core-0.2.0.tgz",
25
+ "commander": "^12.0.0"
24
26
  },
25
27
  "devDependencies": {
26
28
  "@types/node": "^20.11.0",
27
- "bun-types": "^1.3.11"
29
+ "typescript": "^5.3.3"
28
30
  }
29
31
  }
Binary file
package/src/index.ts CHANGED
@@ -1 +1,91 @@
1
- export { CLI } from './CLI';
1
+ #!/usr/bin/env node
2
+
3
+ import { Command } from "commander";
4
+ import { MemoryEngine } from "@slorenzot/memento-core";
5
+ import type { Observation } from "@slorenzot/memento-core";
6
+
7
+ const dbPath = process.env.MEMENTO_DB_PATH || "./data/memento.db";
8
+ const memory = new MemoryEngine(dbPath);
9
+ let activeSessionId: number | null = null;
10
+
11
+ async function getOrCreateSessionId(projectId: string): Promise<number> {
12
+ if (activeSessionId) return activeSessionId;
13
+ const session = await memory.createSession({ projectId, endedAt: null, metadata: {} });
14
+ activeSessionId = session.id;
15
+ return session.id;
16
+ }
17
+
18
+ const program = new Command();
19
+ program.name("memento").description("Persistent memory system for AI coding agents").version("0.2.0");
20
+
21
+ program.command("search <query>").description("Search observations")
22
+ .option("-t, --type <type>", "Filter by type")
23
+ .option("-p, --project <project>", "Filter by project")
24
+ .option("--limit <number>", "Limit results")
25
+ .action(async (query: string, options: any) => {
26
+ const result = await memory.search({ query, type: options.type, projectId: options.project, limit: options.limit ? parseInt(options.limit) : undefined });
27
+ console.log(`Found ${result.total} observations:`);
28
+ result.observations.forEach((obs: Observation) => { console.log(` [${obs.type}] ${obs.title}\n ${obs.content.substring(0, 100)}...`); });
29
+ memory.close();
30
+ });
31
+
32
+ program.command("save <title> <content>").description("Save an observation")
33
+ .option("-t, --type <type>", "Observation type", "note")
34
+ .option("-k, --topic <topic>", "Topic key")
35
+ .option("-p, --project <project>", "Project ID", "default")
36
+ .action(async (title: string, content: string, options: any) => {
37
+ const sessionId = await getOrCreateSessionId(options.project);
38
+ const observation = await memory.createObservation({ sessionId, title, content, type: options.type, topicKey: options.topic || null, projectId: options.project, metadata: {} });
39
+ console.log(`Saved observation: ${observation.uuid}`);
40
+ memory.close();
41
+ });
42
+
43
+ program.command("get <id>").description("Get observation by ID")
44
+ .action(async (id: string) => {
45
+ const observation = await memory.getObservation(parseInt(id));
46
+ if (!observation) { console.error("Observation not found"); memory.close(); return; }
47
+ console.log(`[${observation.type}] ${observation.title}\n${observation.content}\nTopic: ${observation.topicKey || "none"}\nCreated: ${observation.createdAt.toISOString()}`);
48
+ memory.close();
49
+ });
50
+
51
+ program.command("update <id>").description("Update observation")
52
+ .option("-t, --title <title>", "New title")
53
+ .option("-c, --content <content>", "New content")
54
+ .option("-k, --topic <topic>", "New topic key")
55
+ .action(async (id: string, options: any) => {
56
+ const updates: any = {};
57
+ if (options.title) updates.title = options.title;
58
+ if (options.content) updates.content = options.content;
59
+ if (options.topic) updates.topicKey = options.topic;
60
+ const observation = await memory.updateObservation(parseInt(id), updates);
61
+ console.log(`Updated observation: ${observation.uuid}`);
62
+ memory.close();
63
+ });
64
+
65
+ program.command("delete <id>").description("Delete observation")
66
+ .action(async (id: string) => {
67
+ await memory.deleteObservation(parseInt(id));
68
+ console.log(`Deleted observation ${id}`);
69
+ memory.close();
70
+ });
71
+
72
+ program.command("timeline [project]").description("Show timeline")
73
+ .option("-l, --limit <number>", "Limit results", "20")
74
+ .action(async (project: string, options: any) => {
75
+ const result = await memory.search({ projectId: project, limit: parseInt(options.limit) });
76
+ console.log(`Timeline (${result.total} observations):`);
77
+ result.observations.forEach((obs: Observation) => { console.log(` ${obs.createdAt.toLocaleDateString()} [${obs.type}] ${obs.title}`); });
78
+ memory.close();
79
+ });
80
+
81
+ program.command("stats").description("Show statistics")
82
+ .action(async () => {
83
+ const result = await memory.search({});
84
+ const byType: Record<string, number> = {};
85
+ result.observations.forEach((obs: Observation) => { byType[obs.type] = (byType[obs.type] || 0) + 1; });
86
+ console.log(`Statistics:\n Total observations: ${result.total}\n By type:`);
87
+ Object.entries(byType).forEach(([type, count]) => { console.log(` ${type}: ${count}`); });
88
+ memory.close();
89
+ });
90
+
91
+ program.parseAsync(process.argv);
package/tsconfig.json CHANGED
@@ -1,14 +1,18 @@
1
1
  {
2
- "extends": "../../tsconfig.json",
3
2
  "compilerOptions": {
3
+ "target": "ES2022",
4
+ "module": "Node16",
5
+ "moduleResolution": "Node16",
4
6
  "outDir": "./dist",
5
7
  "rootDir": "./src",
8
+ "strict": true,
9
+ "esModuleInterop": true,
10
+ "skipLibCheck": true,
11
+ "forceConsistentCasingInFileNames": true,
6
12
  "declaration": true,
7
13
  "declarationMap": true,
8
- "sourceMap": true,
9
- "removeComments": true,
10
- "types": ["bun-types"]
14
+ "sourceMap": true
11
15
  },
12
16
  "include": ["src/**/*"],
13
- "exclude": ["node_modules", "dist", "**/*.test.ts", "**/*.test.tsx"]
17
+ "exclude": ["node_modules", "dist", "**/*.test.ts"]
14
18
  }
package/dist/CLI.d.ts DELETED
@@ -1,11 +0,0 @@
1
- export declare class CLI {
2
- private program;
3
- private memory;
4
- private activeSessionId;
5
- constructor(dbPath?: string);
6
- private setupCommands;
7
- private getOrCreateSessionId;
8
- run(argv?: string[]): Promise<void>;
9
- close(): void;
10
- }
11
- //# sourceMappingURL=CLI.d.ts.map
package/dist/CLI.d.ts.map DELETED
@@ -1 +0,0 @@
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;gBAElC,MAAM,GAAE,MAA4B;IAMhD,OAAO,CAAC,aAAa;YAsJP,oBAAoB;IAa5B,GAAG,CAAC,IAAI,GAAE,MAAM,EAAiB;IAIvC,KAAK;CAGN"}
package/dist/CLI.js DELETED
@@ -1,173 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.CLI = void 0;
4
- const commander_1 = require("commander");
5
- const core_1 = require("@memento/core");
6
- class CLI {
7
- program;
8
- memory;
9
- activeSessionId = null;
10
- constructor(dbPath = './data/memento.db') {
11
- this.program = new commander_1.Command();
12
- this.memory = new core_1.MemoryEngine(dbPath);
13
- this.setupCommands();
14
- }
15
- setupCommands() {
16
- this.program
17
- .name('memento')
18
- .description('Persistent memory system for AI coding agents')
19
- .version('0.1.0');
20
- this.program
21
- .command('setup [agent]')
22
- .description('Setup configuration for an AI agent')
23
- .action((agent) => {
24
- console.log(`Setup for agent: ${agent || 'default'}`);
25
- console.log('Configuration saved to ~/.memento/config.json');
26
- });
27
- this.program
28
- .command('serve [port]')
29
- .description('Start API server')
30
- .option('-d, --db <path>', 'Database path', './data/memento.db')
31
- .action((port, options) => {
32
- console.log(`Starting API server on port ${port || 3000}`);
33
- console.log(`Database: ${options.db}`);
34
- console.log('Note: API server not implemented in CLI mode');
35
- });
36
- this.program
37
- .command('mcp')
38
- .description('Start MCP server')
39
- .option('-d, --db <path>', 'Database path', './data/memento.db')
40
- .action((options) => {
41
- console.log(`Starting MCP server`);
42
- console.log(`Database: ${options.db}`);
43
- console.log('Note: MCP server not implemented in CLI mode');
44
- });
45
- this.program
46
- .command('search <query>')
47
- .description('Search observations')
48
- .option('-t, --type <type>', 'Filter by type')
49
- .option('-p, --project <project>', 'Filter by project')
50
- .option('--limit <number>', 'Limit results')
51
- .action(async (query, options) => {
52
- const result = await this.memory.search({
53
- query,
54
- type: options.type,
55
- projectId: options.project,
56
- limit: options.limit ? parseInt(options.limit) : undefined,
57
- });
58
- console.log(`Found ${result.total} observations:`);
59
- result.observations.forEach((obs) => {
60
- console.log(` [${obs.type}] ${obs.title}`);
61
- console.log(` ${obs.content.substring(0, 100)}...`);
62
- });
63
- });
64
- this.program
65
- .command('save <title> <content>')
66
- .description('Save an observation')
67
- .option('-t, --type <type>', 'Observation type', 'note')
68
- .option('-k, --topic <topic>', 'Topic key')
69
- .option('-p, --project <project>', 'Project ID', 'default')
70
- .action(async (title, content, options) => {
71
- const sessionId = await this.getOrCreateSessionId(options.project);
72
- const observation = await this.memory.createObservation({
73
- sessionId,
74
- title,
75
- content,
76
- type: options.type,
77
- topicKey: options.topic || null,
78
- projectId: options.project,
79
- metadata: {},
80
- });
81
- console.log(`Saved observation: ${observation.uuid}`);
82
- });
83
- this.program
84
- .command('get <id>')
85
- .description('Get observation by ID')
86
- .action(async (id) => {
87
- const observation = await this.memory.getObservation(parseInt(id));
88
- if (!observation) {
89
- console.error('Observation not found');
90
- return;
91
- }
92
- console.log(`[${observation.type}] ${observation.title}`);
93
- console.log(observation.content);
94
- console.log(`Topic: ${observation.topicKey || 'none'}`);
95
- console.log(`Created: ${observation.createdAt.toISOString()}`);
96
- });
97
- this.program
98
- .command('update <id>')
99
- .description('Update observation')
100
- .option('-t, --title <title>', 'New title')
101
- .option('-c, --content <content>', 'New content')
102
- .option('-k, --topic <topic>', 'New topic key')
103
- .action(async (id, options) => {
104
- const updates = {};
105
- if (options.title)
106
- updates.title = options.title;
107
- if (options.content)
108
- updates.content = options.content;
109
- if (options.topic)
110
- updates.topicKey = options.topic;
111
- const observation = await this.memory.updateObservation(parseInt(id), updates);
112
- console.log(`Updated observation: ${observation.uuid}`);
113
- });
114
- this.program
115
- .command('delete <id>')
116
- .description('Delete observation')
117
- .action(async (id) => {
118
- await this.memory.deleteObservation(parseInt(id));
119
- console.log(`Deleted observation ${id}`);
120
- });
121
- this.program
122
- .command('timeline [project]')
123
- .description('Show timeline of observations')
124
- .option('-l, --limit <number>', 'Limit results', '20')
125
- .action(async (project, options) => {
126
- const result = await this.memory.search({
127
- projectId: project,
128
- limit: parseInt(options.limit),
129
- });
130
- console.log(`Timeline (${result.total} observations):`);
131
- result.observations.forEach((obs) => {
132
- const date = obs.createdAt.toLocaleDateString();
133
- console.log(` ${date} [${obs.type}] ${obs.title}`);
134
- });
135
- });
136
- this.program
137
- .command('stats')
138
- .description('Show statistics')
139
- .action(async () => {
140
- const result = await this.memory.search({});
141
- const byType = result.observations.reduce((acc, obs) => {
142
- acc[obs.type] = (acc[obs.type] || 0) + 1;
143
- return acc;
144
- }, {});
145
- console.log('Statistics:');
146
- console.log(` Total observations: ${result.total}`);
147
- console.log(' By type:');
148
- Object.entries(byType).forEach(([type, count]) => {
149
- console.log(` ${type}: ${count}`);
150
- });
151
- });
152
- }
153
- async getOrCreateSessionId(projectId) {
154
- if (this.activeSessionId) {
155
- return this.activeSessionId;
156
- }
157
- const session = await this.memory.createSession({
158
- projectId,
159
- endedAt: null,
160
- metadata: {},
161
- });
162
- this.activeSessionId = session.id;
163
- return session.id;
164
- }
165
- async run(argv = process.argv) {
166
- await this.program.parseAsync(argv);
167
- }
168
- close() {
169
- this.memory.close();
170
- }
171
- }
172
- exports.CLI = CLI;
173
- //# sourceMappingURL=CLI.js.map
package/dist/CLI.js.map DELETED
@@ -1 +0,0 @@
1
- {"version":3,"file":"CLI.js","sourceRoot":"","sources":["../src/CLI.ts"],"names":[],"mappings":"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"}
package/src/CLI.test.ts DELETED
@@ -1,60 +0,0 @@
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 DELETED
@@ -1,187 +0,0 @@
1
- import { Command } from 'commander';
2
- import { MemoryEngine } 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
-
11
- constructor(dbPath: string = './data/memento.db') {
12
- this.program = new Command();
13
- this.memory = new MemoryEngine(dbPath);
14
- this.setupCommands();
15
- }
16
-
17
- private setupCommands() {
18
- this.program
19
- .name('memento')
20
- .description('Persistent memory system for AI coding agents')
21
- .version('0.1.0');
22
-
23
- this.program
24
- .command('setup [agent]')
25
- .description('Setup configuration for an AI agent')
26
- .action((agent) => {
27
- console.log(`Setup for agent: ${agent || 'default'}`);
28
- console.log('Configuration saved to ~/.memento/config.json');
29
- });
30
-
31
- this.program
32
- .command('serve [port]')
33
- .description('Start API server')
34
- .option('-d, --db <path>', 'Database path', './data/memento.db')
35
- .action((port, options) => {
36
- console.log(`Starting API server on port ${port || 3000}`);
37
- console.log(`Database: ${options.db}`);
38
- console.log('Note: API server not implemented in CLI mode');
39
- });
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
-
51
- this.program
52
- .command('search <query>')
53
- .description('Search observations')
54
- .option('-t, --type <type>', 'Filter by type')
55
- .option('-p, --project <project>', 'Filter by project')
56
- .option('--limit <number>', 'Limit results')
57
- .action(async (query, options) => {
58
- const result = await this.memory.search({
59
- query,
60
- type: options.type as Observation['type'] | undefined,
61
- projectId: options.project as string | undefined,
62
- limit: options.limit ? parseInt(options.limit as string) : undefined,
63
- });
64
- console.log(`Found ${result.total} observations:`);
65
- result.observations.forEach((obs) => {
66
- console.log(` [${obs.type}] ${obs.title}`);
67
- console.log(` ${obs.content.substring(0, 100)}...`);
68
- });
69
- });
70
-
71
- this.program
72
- .command('save <title> <content>')
73
- .description('Save an observation')
74
- .option('-t, --type <type>', 'Observation type', 'note')
75
- .option('-k, --topic <topic>', 'Topic key')
76
- .option('-p, --project <project>', 'Project ID', 'default')
77
- .action(async (title, content, options) => {
78
- const sessionId = await this.getOrCreateSessionId(options.project as string);
79
- const observation = await this.memory.createObservation({
80
- sessionId,
81
- title,
82
- content,
83
- type: options.type as Observation['type'],
84
- topicKey: options.topic || null,
85
- projectId: options.project as string,
86
- metadata: {},
87
- });
88
- console.log(`Saved observation: ${observation.uuid}`);
89
- });
90
-
91
- this.program
92
- .command('get <id>')
93
- .description('Get observation by ID')
94
- .action(async (id) => {
95
- const observation = await this.memory.getObservation(parseInt(id));
96
- if (!observation) {
97
- console.error('Observation not found');
98
- return;
99
- }
100
- console.log(`[${observation.type}] ${observation.title}`);
101
- console.log(observation.content);
102
- console.log(`Topic: ${observation.topicKey || 'none'}`);
103
- console.log(`Created: ${observation.createdAt.toISOString()}`);
104
- });
105
-
106
- this.program
107
- .command('update <id>')
108
- .description('Update observation')
109
- .option('-t, --title <title>', 'New title')
110
- .option('-c, --content <content>', 'New content')
111
- .option('-k, --topic <topic>', 'New topic key')
112
- .action(async (id, options) => {
113
- const updates: Partial<Observation> = {};
114
- if (options.title) updates.title = options.title;
115
- if (options.content) updates.content = options.content;
116
- if (options.topic) updates.topicKey = options.topic;
117
-
118
- const observation = await this.memory.updateObservation(parseInt(id), updates);
119
- console.log(`Updated observation: ${observation.uuid}`);
120
- });
121
-
122
- this.program
123
- .command('delete <id>')
124
- .description('Delete observation')
125
- .action(async (id) => {
126
- await this.memory.deleteObservation(parseInt(id));
127
- console.log(`Deleted observation ${id}`);
128
- });
129
-
130
- this.program
131
- .command('timeline [project]')
132
- .description('Show timeline of observations')
133
- .option('-l, --limit <number>', 'Limit results', '20')
134
- .action(async (project, options) => {
135
- const result = await this.memory.search({
136
- projectId: project,
137
- limit: parseInt(options.limit as string),
138
- });
139
- console.log(`Timeline (${result.total} observations):`);
140
- result.observations.forEach((obs) => {
141
- const date = obs.createdAt.toLocaleDateString();
142
- console.log(` ${date} [${obs.type}] ${obs.title}`);
143
- });
144
- });
145
-
146
- this.program
147
- .command('stats')
148
- .description('Show statistics')
149
- .action(async () => {
150
- const result = await this.memory.search({});
151
- const byType = result.observations.reduce(
152
- (acc, obs) => {
153
- acc[obs.type] = (acc[obs.type] || 0) + 1;
154
- return acc;
155
- },
156
- {} as Record<string, number>
157
- );
158
- console.log('Statistics:');
159
- console.log(` Total observations: ${result.total}`);
160
- console.log(' By type:');
161
- Object.entries(byType).forEach(([type, count]) => {
162
- console.log(` ${type}: ${count}`);
163
- });
164
- });
165
- }
166
-
167
- private async getOrCreateSessionId(projectId: string): Promise<number> {
168
- if (this.activeSessionId) {
169
- return this.activeSessionId;
170
- }
171
- const session = await this.memory.createSession({
172
- projectId,
173
- endedAt: null,
174
- metadata: {},
175
- });
176
- this.activeSessionId = session.id;
177
- return session.id;
178
- }
179
-
180
- async run(argv: string[] = process.argv) {
181
- await this.program.parseAsync(argv);
182
- }
183
-
184
- close() {
185
- this.memory.close();
186
- }
187
- }