@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 +422 -0
- package/data/memento.db +0 -0
- package/data/memento.db-shm +0 -0
- package/data/memento.db-wal +0 -0
- package/dist/index.d.ts +2 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +89 -0
- package/dist/index.js.map +1 -0
- package/package.json +19 -17
- package/slorenzot-memento-cli-0.2.0.tgz +0 -0
- package/src/index.ts +91 -1
- package/tsconfig.json +9 -5
- package/dist/CLI.d.ts +0 -11
- package/dist/CLI.d.ts.map +0 -1
- package/dist/CLI.js +0 -173
- package/dist/CLI.js.map +0 -1
- package/src/CLI.test.ts +0 -60
- package/src/CLI.ts +0 -187
package/README.md
ADDED
|
@@ -0,0 +1,422 @@
|
|
|
1
|
+
# @slorenzot/memento-cli
|
|
2
|
+
|
|
3
|
+
[](https://www.npmjs.com/package/@slorenzot/memento-cli)
|
|
4
|
+
[](https://creativecommons.org/licenses/by-nc-nd/4.0/)
|
|
5
|
+
[](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.
|
package/data/memento.db
ADDED
|
Binary file
|
|
Binary file
|
|
Binary file
|
package/dist/index.d.ts
CHANGED
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"
|
|
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.
|
|
4
|
-
"description": "CLI interface for Memento",
|
|
5
|
-
"
|
|
6
|
-
|
|
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": "
|
|
16
|
+
"memento": "dist/index.js"
|
|
9
17
|
},
|
|
10
18
|
"scripts": {
|
|
11
|
-
"
|
|
12
|
-
"
|
|
13
|
-
"
|
|
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": "
|
|
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
|
-
"
|
|
29
|
+
"typescript": "^5.3.3"
|
|
28
30
|
}
|
|
29
31
|
}
|
|
Binary file
|
package/src/index.ts
CHANGED
|
@@ -1 +1,91 @@
|
|
|
1
|
-
|
|
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"
|
|
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":";;;AAAA,yCAAoC;AACpC,wCAA6C;AAI7C,MAAa,GAAG;IACN,OAAO,CAAU;IACjB,MAAM,CAAe;IACrB,eAAe,GAAkB,IAAI,CAAC;IAE9C,YAAY,SAAiB,mBAAmB;QAC9C,IAAI,CAAC,OAAO,GAAG,IAAI,mBAAO,EAAE,CAAC;QAC7B,IAAI,CAAC,MAAM,GAAG,IAAI,mBAAY,CAAC,MAAM,CAAC,CAAC;QACvC,IAAI,CAAC,aAAa,EAAE,CAAC;IACvB,CAAC;IAEO,aAAa;QACnB,IAAI,CAAC,OAAO;aACT,IAAI,CAAC,SAAS,CAAC;aACf,WAAW,CAAC,+CAA+C,CAAC;aAC5D,OAAO,CAAC,OAAO,CAAC,CAAC;QAEpB,IAAI,CAAC,OAAO;aACT,OAAO,CAAC,eAAe,CAAC;aACxB,WAAW,CAAC,qCAAqC,CAAC;aAClD,MAAM,CAAC,CAAC,KAAK,EAAE,EAAE;YAChB,OAAO,CAAC,GAAG,CAAC,oBAAoB,KAAK,IAAI,SAAS,EAAE,CAAC,CAAC;YACtD,OAAO,CAAC,GAAG,CAAC,+CAA+C,CAAC,CAAC;QAC/D,CAAC,CAAC,CAAC;QAEL,IAAI,CAAC,OAAO;aACT,OAAO,CAAC,cAAc,CAAC;aACvB,WAAW,CAAC,kBAAkB,CAAC;aAC/B,MAAM,CAAC,iBAAiB,EAAE,eAAe,EAAE,mBAAmB,CAAC;aAC/D,MAAM,CAAC,CAAC,IAAI,EAAE,OAAO,EAAE,EAAE;YACxB,OAAO,CAAC,GAAG,CAAC,+BAA+B,IAAI,IAAI,IAAI,EAAE,CAAC,CAAC;YAC3D,OAAO,CAAC,GAAG,CAAC,aAAa,OAAO,CAAC,EAAE,EAAE,CAAC,CAAC;YACvC,OAAO,CAAC,GAAG,CAAC,8CAA8C,CAAC,CAAC;QAC9D,CAAC,CAAC,CAAC;QAEL,IAAI,CAAC,OAAO;aACT,OAAO,CAAC,KAAK,CAAC;aACd,WAAW,CAAC,kBAAkB,CAAC;aAC/B,MAAM,CAAC,iBAAiB,EAAE,eAAe,EAAE,mBAAmB,CAAC;aAC/D,MAAM,CAAC,CAAC,OAAO,EAAE,EAAE;YAClB,OAAO,CAAC,GAAG,CAAC,qBAAqB,CAAC,CAAC;YACnC,OAAO,CAAC,GAAG,CAAC,aAAa,OAAO,CAAC,EAAE,EAAE,CAAC,CAAC;YACvC,OAAO,CAAC,GAAG,CAAC,8CAA8C,CAAC,CAAC;QAC9D,CAAC,CAAC,CAAC;QAEL,IAAI,CAAC,OAAO;aACT,OAAO,CAAC,gBAAgB,CAAC;aACzB,WAAW,CAAC,qBAAqB,CAAC;aAClC,MAAM,CAAC,mBAAmB,EAAE,gBAAgB,CAAC;aAC7C,MAAM,CAAC,yBAAyB,EAAE,mBAAmB,CAAC;aACtD,MAAM,CAAC,kBAAkB,EAAE,eAAe,CAAC;aAC3C,MAAM,CAAC,KAAK,EAAE,KAAK,EAAE,OAAO,EAAE,EAAE;YAC/B,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC;gBACtC,KAAK;gBACL,IAAI,EAAE,OAAO,CAAC,IAAuC;gBACrD,SAAS,EAAE,OAAO,CAAC,OAA6B;gBAChD,KAAK,EAAE,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,QAAQ,CAAC,OAAO,CAAC,KAAe,CAAC,CAAC,CAAC,CAAC,SAAS;aACrE,CAAC,CAAC;YACH,OAAO,CAAC,GAAG,CAAC,SAAS,MAAM,CAAC,KAAK,gBAAgB,CAAC,CAAC;YACnD,MAAM,CAAC,YAAY,CAAC,OAAO,CAAC,CAAC,GAAG,EAAE,EAAE;gBAClC,OAAO,CAAC,GAAG,CAAC,MAAM,GAAG,CAAC,IAAI,KAAK,GAAG,CAAC,KAAK,EAAE,CAAC,CAAC;gBAC5C,OAAO,CAAC,GAAG,CAAC,OAAO,GAAG,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC,EAAE,GAAG,CAAC,KAAK,CAAC,CAAC;YACzD,CAAC,CAAC,CAAC;QACL,CAAC,CAAC,CAAC;QAEL,IAAI,CAAC,OAAO;aACT,OAAO,CAAC,wBAAwB,CAAC;aACjC,WAAW,CAAC,qBAAqB,CAAC;aAClC,MAAM,CAAC,mBAAmB,EAAE,kBAAkB,EAAE,MAAM,CAAC;aACvD,MAAM,CAAC,qBAAqB,EAAE,WAAW,CAAC;aAC1C,MAAM,CAAC,yBAAyB,EAAE,YAAY,EAAE,SAAS,CAAC;aAC1D,MAAM,CAAC,KAAK,EAAE,KAAK,EAAE,OAAO,EAAE,OAAO,EAAE,EAAE;YACxC,MAAM,SAAS,GAAG,MAAM,IAAI,CAAC,oBAAoB,CAAC,OAAO,CAAC,OAAiB,CAAC,CAAC;YAC7E,MAAM,WAAW,GAAG,MAAM,IAAI,CAAC,MAAM,CAAC,iBAAiB,CAAC;gBACtD,SAAS;gBACT,KAAK;gBACL,OAAO;gBACP,IAAI,EAAE,OAAO,CAAC,IAA2B;gBACzC,QAAQ,EAAE,OAAO,CAAC,KAAK,IAAI,IAAI;gBAC/B,SAAS,EAAE,OAAO,CAAC,OAAiB;gBACpC,QAAQ,EAAE,EAAE;aACb,CAAC,CAAC;YACH,OAAO,CAAC,GAAG,CAAC,sBAAsB,WAAW,CAAC,IAAI,EAAE,CAAC,CAAC;QACxD,CAAC,CAAC,CAAC;QAEL,IAAI,CAAC,OAAO;aACT,OAAO,CAAC,UAAU,CAAC;aACnB,WAAW,CAAC,uBAAuB,CAAC;aACpC,MAAM,CAAC,KAAK,EAAE,EAAE,EAAE,EAAE;YACnB,MAAM,WAAW,GAAG,MAAM,IAAI,CAAC,MAAM,CAAC,cAAc,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,CAAC;YACnE,IAAI,CAAC,WAAW,EAAE,CAAC;gBACjB,OAAO,CAAC,KAAK,CAAC,uBAAuB,CAAC,CAAC;gBACvC,OAAO;YACT,CAAC;YACD,OAAO,CAAC,GAAG,CAAC,IAAI,WAAW,CAAC,IAAI,KAAK,WAAW,CAAC,KAAK,EAAE,CAAC,CAAC;YAC1D,OAAO,CAAC,GAAG,CAAC,WAAW,CAAC,OAAO,CAAC,CAAC;YACjC,OAAO,CAAC,GAAG,CAAC,UAAU,WAAW,CAAC,QAAQ,IAAI,MAAM,EAAE,CAAC,CAAC;YACxD,OAAO,CAAC,GAAG,CAAC,YAAY,WAAW,CAAC,SAAS,CAAC,WAAW,EAAE,EAAE,CAAC,CAAC;QACjE,CAAC,CAAC,CAAC;QAEL,IAAI,CAAC,OAAO;aACT,OAAO,CAAC,aAAa,CAAC;aACtB,WAAW,CAAC,oBAAoB,CAAC;aACjC,MAAM,CAAC,qBAAqB,EAAE,WAAW,CAAC;aAC1C,MAAM,CAAC,yBAAyB,EAAE,aAAa,CAAC;aAChD,MAAM,CAAC,qBAAqB,EAAE,eAAe,CAAC;aAC9C,MAAM,CAAC,KAAK,EAAE,EAAE,EAAE,OAAO,EAAE,EAAE;YAC5B,MAAM,OAAO,GAAyB,EAAE,CAAC;YACzC,IAAI,OAAO,CAAC,KAAK;gBAAE,OAAO,CAAC,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC;YACjD,IAAI,OAAO,CAAC,OAAO;gBAAE,OAAO,CAAC,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC;YACvD,IAAI,OAAO,CAAC,KAAK;gBAAE,OAAO,CAAC,QAAQ,GAAG,OAAO,CAAC,KAAK,CAAC;YAEpD,MAAM,WAAW,GAAG,MAAM,IAAI,CAAC,MAAM,CAAC,iBAAiB,CAAC,QAAQ,CAAC,EAAE,CAAC,EAAE,OAAO,CAAC,CAAC;YAC/E,OAAO,CAAC,GAAG,CAAC,wBAAwB,WAAW,CAAC,IAAI,EAAE,CAAC,CAAC;QAC1D,CAAC,CAAC,CAAC;QAEL,IAAI,CAAC,OAAO;aACT,OAAO,CAAC,aAAa,CAAC;aACtB,WAAW,CAAC,oBAAoB,CAAC;aACjC,MAAM,CAAC,KAAK,EAAE,EAAE,EAAE,EAAE;YACnB,MAAM,IAAI,CAAC,MAAM,CAAC,iBAAiB,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,CAAC;YAClD,OAAO,CAAC,GAAG,CAAC,uBAAuB,EAAE,EAAE,CAAC,CAAC;QAC3C,CAAC,CAAC,CAAC;QAEL,IAAI,CAAC,OAAO;aACT,OAAO,CAAC,oBAAoB,CAAC;aAC7B,WAAW,CAAC,+BAA+B,CAAC;aAC5C,MAAM,CAAC,sBAAsB,EAAE,eAAe,EAAE,IAAI,CAAC;aACrD,MAAM,CAAC,KAAK,EAAE,OAAO,EAAE,OAAO,EAAE,EAAE;YACjC,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC;gBACtC,SAAS,EAAE,OAAO;gBAClB,KAAK,EAAE,QAAQ,CAAC,OAAO,CAAC,KAAe,CAAC;aACzC,CAAC,CAAC;YACH,OAAO,CAAC,GAAG,CAAC,aAAa,MAAM,CAAC,KAAK,iBAAiB,CAAC,CAAC;YACxD,MAAM,CAAC,YAAY,CAAC,OAAO,CAAC,CAAC,GAAG,EAAE,EAAE;gBAClC,MAAM,IAAI,GAAG,GAAG,CAAC,SAAS,CAAC,kBAAkB,EAAE,CAAC;gBAChD,OAAO,CAAC,GAAG,CAAC,KAAK,IAAI,KAAK,GAAG,CAAC,IAAI,KAAK,GAAG,CAAC,KAAK,EAAE,CAAC,CAAC;YACtD,CAAC,CAAC,CAAC;QACL,CAAC,CAAC,CAAC;QAEL,IAAI,CAAC,OAAO;aACT,OAAO,CAAC,OAAO,CAAC;aAChB,WAAW,CAAC,iBAAiB,CAAC;aAC9B,MAAM,CAAC,KAAK,IAAI,EAAE;YACjB,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;YAC5C,MAAM,MAAM,GAAG,MAAM,CAAC,YAAY,CAAC,MAAM,CACvC,CAAC,GAAG,EAAE,GAAG,EAAE,EAAE;gBACX,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC;gBACzC,OAAO,GAAG,CAAC;YACb,CAAC,EACD,EAA4B,CAC7B,CAAC;YACF,OAAO,CAAC,GAAG,CAAC,aAAa,CAAC,CAAC;YAC3B,OAAO,CAAC,GAAG,CAAC,yBAAyB,MAAM,CAAC,KAAK,EAAE,CAAC,CAAC;YACrD,OAAO,CAAC,GAAG,CAAC,YAAY,CAAC,CAAC;YAC1B,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,EAAE,KAAK,CAAC,EAAE,EAAE;gBAC/C,OAAO,CAAC,GAAG,CAAC,OAAO,IAAI,KAAK,KAAK,EAAE,CAAC,CAAC;YACvC,CAAC,CAAC,CAAC;QACL,CAAC,CAAC,CAAC;IACP,CAAC;IAEO,KAAK,CAAC,oBAAoB,CAAC,SAAiB;QAClD,IAAI,IAAI,CAAC,eAAe,EAAE,CAAC;YACzB,OAAO,IAAI,CAAC,eAAe,CAAC;QAC9B,CAAC;QACD,MAAM,OAAO,GAAG,MAAM,IAAI,CAAC,MAAM,CAAC,aAAa,CAAC;YAC9C,SAAS;YACT,OAAO,EAAE,IAAI;YACb,QAAQ,EAAE,EAAE;SACb,CAAC,CAAC;QACH,IAAI,CAAC,eAAe,GAAG,OAAO,CAAC,EAAE,CAAC;QAClC,OAAO,OAAO,CAAC,EAAE,CAAC;IACpB,CAAC;IAED,KAAK,CAAC,GAAG,CAAC,OAAiB,OAAO,CAAC,IAAI;QACrC,MAAM,IAAI,CAAC,OAAO,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC;IACtC,CAAC;IAED,KAAK;QACH,IAAI,CAAC,MAAM,CAAC,KAAK,EAAE,CAAC;IACtB,CAAC;CACF;AArLD,kBAqLC"}
|
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
|
-
}
|