Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions .claude-plugin/marketplace.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "session-recall-marketplace",
"description": "Local shared-memory plugin for Claude Code and Codex sessions.",
"owner": { "name": "max" },
"description": "Local shared-memory plugin for Claude Code, Codex, and Cursor sessions.",
"owner": { "name": "Max Butorin" },
"plugins": [
{
"name": "session-recall",
Expand Down
4 changes: 2 additions & 2 deletions .claude-plugin/plugin.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "session-recall",
"version": "0.5.0",
"description": "Shared semantic recall over local Claude Code and Codex session history. Bundles MCP search tools, a deep-recall subagent, a trigger skill, an agent-driven setup skill (/session-recall:setup), and a background freshness hook.",
"author": { "name": "max" }
"description": "Shared semantic recall over local Claude Code, Codex, and Cursor history. Bundles MCP search tools, deep recall, guided setup, and a background freshness hook.",
"author": { "name": "Max Butorin" }
}
15 changes: 8 additions & 7 deletions .codex-plugin/plugin.json
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
{
"name": "session-recall",
"version": "0.3.0+codex.20260716100453",
"description": "Shared semantic recall over local Claude Code and Codex session history.",
"version": "0.5.0",
"description": "Shared semantic recall over local Claude Code, Codex, and Cursor history, with durable deep navigation and guided setup.",
"author": {
"name": "max"
"name": "Max Butorin"
},
"homepage": "https://github.com/AbsoluteMode/session-recall",
"repository": "https://github.com/AbsoluteMode/session-recall",
Expand All @@ -13,7 +13,8 @@
"recall",
"sessions",
"claude-code",
"codex"
"codex",
"cursor"
],
"skills": "./skills/",
"mcpServers": {
Expand All @@ -27,9 +28,9 @@
},
"interface": {
"displayName": "Session Recall",
"shortDescription": "Recall work from Claude Code and Codex.",
"longDescription": "Search one local semantic index of your Claude Code and Codex sessions, then drill into the original conversational trace.",
"developerName": "max",
"shortDescription": "Recall work from Claude Code, Codex, and Cursor.",
"longDescription": "Search one local semantic index of your Claude Code, Codex, and Cursor sessions, then drill into the original conversational trace.",
"developerName": "Max Butorin",
"category": "Productivity",
"capabilities": [
"Read"
Expand Down
16 changes: 16 additions & 0 deletions .cursor-plugin/marketplace.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
{
"name": "session-recall-marketplace",
"owner": {
"name": "Max Butorin"
},
"metadata": {
"description": "Local-first shared memory for Claude Code, Codex, and Cursor."
},
"plugins": [
{
"name": "session-recall",
"source": ".",
"description": "Search and navigate one local semantic index of Claude Code, Codex, and Cursor history."
}
]
}
35 changes: 35 additions & 0 deletions .cursor-plugin/plugin.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
{
"name": "session-recall",
"displayName": "Session Recall",
"version": "0.5.0",
"minClientVersions": {
"cursor": "2.5.0"
},
"description": "Shared semantic recall over local Claude Code, Codex, and Cursor history, with durable deep navigation and guided setup.",
"author": {
"name": "Max Butorin"
},
"homepage": "https://github.com/AbsoluteMode/session-recall",
"repository": "https://github.com/AbsoluteMode/session-recall",
"license": "MIT",
"keywords": [
"memory",
"recall",
"sessions",
"claude-code",
"codex",
"cursor",
"mcp"
],
"category": "developer-tools",
"tags": [
"memory",
"semantic-search",
"local-first"
],
"commands": "./commands/",
"agents": "./agents/",
"skills": "./skills/",
"hooks": "./hooks/hooks-cursor.json",
"mcpServers": "./mcp.json"
}
4 changes: 4 additions & 0 deletions .env.example
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,7 @@

# Voyage embeddings (https://www.voyageai.com)
VOYAGE_API_KEY=

# Optional only for a portable/custom Cursor profile. The standard macOS/Linux
# database path is detected automatically.
SESSION_RECALL_CURSOR_DB=
51 changes: 33 additions & 18 deletions README.es-ES.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,14 @@
[README en inglés](README.md), que es la referencia; versión en ruso:
[docs/README.ru.md](docs/README.ru.md).*

**Memoria compartida para Claude Code y Codex.** Retoma el trabajo de hace un mes sin tener que reexplicarlo: y Claude puede leer lo que Codex resolvió ayer, porque ambos motores alimentan un mismo índice. No es un archivo de resumen que alguien mantiene a mano: son los turnos reales, incluidas las llamadas a herramientas y el razonamiento, buscables por significado.
**Memoria compartida para Claude Code, Codex y Cursor.** Retoma el trabajo de hace un mes sin tener que reexplicarlo: Claude puede leer lo que Codex o Cursor resolvieron ayer, porque los tres alimentan un mismo índice. No es un archivo de resumen que alguien mantiene a mano: son los turnos reales, incluidas las llamadas a herramientas y el razonamiento, buscables por significado.

```console
$ session-recall index
indexed 2175 chunks from changed transcripts

your history: 1052 sessions spanning 168 days, 40,035 searchable fragments
Claude Code 372 · Codex 680
your history: 1053 sessions spanning 168 days, 40,037 searchable fragments
Claude Code 372 · Codex 680 · Cursor 1
busiest: sidekey, trend_detection, glitch
```

Expand All @@ -33,19 +33,19 @@ Cinco herramientas a través de MCP:

Bajo demanda (sin autoinyección proactiva en v1). Local y de código abierto.

`recall_search`, `grep` y `recent_sessions` también aceptan un opcional `scope_cwd`: pasa tu directorio de trabajo actual para limitar los resultados al repo actual (los worktrees colapsan a la raíz del repo); omítelo para recordatorios entre proyectos. Los resultados clasificados incluyen una marca de tiempo legible por humanos `when_human` junto con la época raw. Cada herramienta MCP acepta un `source` opcional (`claude` o `codex`); omítelo para usar el historial unificado. Los resultados incluyen procedencia como `source=claude` o `source=codex`. Las tres herramientas de descubrimiento también aceptan `on_date` para un solo día o `start_date` / `end_date` inclusivos (`YYYY-MM-DD`) más un `timezone` IANA opcional, para que un agente pueda restringir la recuperación a un día calendario local real en lugar de esperar que una fecha escrita en la consulta semántica afecte la clasificación. Si se omite `timezone`, Session Recall usa la zona horaria de la computadora que ejecuta el servidor MCP.
`recall_search`, `grep` y `recent_sessions` también aceptan un opcional `scope_cwd`: pasa tu directorio de trabajo actual para limitar los resultados al repo actual (los worktrees colapsan a la raíz del repo); omítelo para recordatorios entre proyectos. Los resultados clasificados incluyen una marca de tiempo legible por humanos `when_human` junto con la época raw. Cada herramienta MCP acepta un `source` opcional (`claude`, `codex` o `cursor`); omítelo para usar el historial unificado. Los resultados incluyen la procedencia correspondiente. Las tres herramientas de descubrimiento también aceptan `on_date` para un solo día o `start_date` / `end_date` inclusivos (`YYYY-MM-DD`) más un `timezone` IANA opcional, para que un agente pueda restringir la recuperación a un día calendario local real en lugar de esperar que una fecha escrita en la consulta semántica afecte la clasificación. Si se omite `timezone`, Session Recall usa la zona horaria de la computadora que ejecuta el servidor MCP.

**Estado:** v1, construido y validado con historial real. La clave del razonamiento de diseño está en [docs/decisions/](docs/decisions/).

## Cómo funciona

Las transcripciones de Claude Code y las sesiones de Codex desde `~/.codex/sessions` y `~/.codex/archived_sessions` comparten el mismo índice.
Las transcripciones de Claude Code, las sesiones de Codex desde `~/.codex/sessions` y `~/.codex/archived_sessions`, y las conversaciones de Cursor comparten el mismo índice. Cursor se lee desde su SQLite local y cada conversación se conserva como una instantánea JSONL normalizada dentro del directorio de datos de session-recall; por eso `expand_around`, `step` y `grep` siguen funcionando aunque Cursor esté cerrado o se desinstale.
Solo se incrusta la "superficie" de la conversación: los prompts del usuario y las respuestas de texto del asistente.
Las llamadas a herramientas, resultados, razonamiento y otros datos de traza no se incrustan, pero permanecen accesibles bajo demanda mediante `expand_around` (y `step`) o `grep`. Los archivos de transcripción raw de Codex permanecen locales; solo la superficie de conversación extraída se envía al proveedor de incrustaciones configurado.
Las llamadas a herramientas, resultados, razonamiento y otros datos de traza no se incrustan, pero permanecen accesibles bajo demanda mediante `expand_around` (y `step`) o `grep`. Las transcripciones originales de Claude/Codex y las instantáneas raw normalizadas de Cursor permanecen locales; solo la superficie de conversación extraída se envía al proveedor de incrustaciones configurado.

Incrustaciones: Voyage `voyage-4-large` (dim 1024) → SQLite (`sqlite-vec` KNN + FTS5, clasificación bm25) → Voyage `rerank-2.5` → top-k. La indexación es incremental (por metadatos de archivo, incluidos inode+tamaño de Codex) y económica en transcripciones en vivo: son solo de agregación, por lo que los fragmentos sin cambios coinciden por hash de contenido y se reutilizan sus vectores: solo los nuevos turnos consultan la API de incrustaciones. Mover una versión de Codex al archivo también reutiliza sus vectores existentes. Cada archivo se indexa en su propia transacción; un archivo fallido se registra y reintenta en la siguiente ejecución, sin abortar el resto. Los subprocesos laterales de Claude (`<session>/subagents/`) y las sesiones de subagentes generados por Codex se omiten intencionalmente: son herramientas internas, no la conversación principal usuario/agente.
La ruta sin configuración usa un modelo ONNX local elegido por idioma → SQLite (`sqlite-vec` KNN + FTS5, clasificación bm25) → top-k. Con una clave de Voyage se usa la ruta alojada de mayor calidad: `voyage-4-large` (dim 1024) → SQLite → `rerank-2.5`. La indexación es incremental y reutiliza los vectores de fragmentos sin cambios. Cada archivo o sesión se indexa en su propia transacción; un fallo se registra y se reintenta sin destruir los datos buenos anteriores.

Las incrustaciones son intercambiables (Voyage es el predeterminado); el reranker es opcional, y el sistema se degrada elegantemente a KNN + FTS sin él. Se detecta el cambio de proveedor/modelo de incrustación (una huella de incrustación forma parte de la firma de índice de cada archivo) y desencadena una reincrustación limpia en lugar de mezclar espacios vectoriales en silencio.
Las incrustaciones son intercambiables (el modelo local incluido es el predeterminado sin claves); el reranker es opcional, y el sistema se degrada elegantemente a KNN + FTS sin él. Se detecta el cambio de proveedor/modelo de incrustación y la búsqueda semántica se detiene hasta que todos los orígenes pertenezcan al mismo espacio vectorial.

## Instalación

Expand All @@ -58,7 +58,7 @@ pipx install git+https://github.com/AbsoluteMode/session-recall
session-recall index # first run walks your whole history; later runs are incremental
```

Eso es todo si tienes un servidor de incrustaciones local en ejecución: consulta [Embedding providers](#embedding-providers) para la configuración local gratuita. Para incrustaciones alojadas de Voyage, exporta una clave primero:
Eso es todo: sin una clave ni un servidor local, se descarga una vez el modelo ONNX incluido y luego se ejecuta en tu máquina. Consulta [Proveedores de incrustaciones](#proveedores-de-incrustaciones) para las demás opciones. Para usar las incrustaciones alojadas de Voyage, exporta una clave primero:

```bash
export VOYAGE_API_KEY=... # voyageai.com; put the line in your shell profile
Expand All @@ -79,6 +79,15 @@ Luego inicia una nueva sesión: los servidores MCP y las habilidades se cargan a

**Codex** — el manifiesto `.codex-plugin/plugin.json` está listo para colocar en un repo local o en tu marketplace personal; consulta la [local plugin installation guide](https://learn.chatgpt.com/docs/build-plugins#install-a-local-plugin-manually). Codex también te pedirá revisar los hooks recién instalados una vez mediante `/hooks`.

**Cursor** — el repositorio incluye un plugin nativo con MCP, skills, comandos, subagente de recall y un hook `sessionStart` en el formato de Cursor:

```bash
cursor-agent plugin marketplace add https://github.com/AbsoluteMode/session-recall.git
```

Después ejecuta `/add-plugin session-recall` dentro de Cursor Agent. Para desarrollo local se puede iniciar con `cursor-agent --plugin-dir /ruta/absoluta/a/session-recall`.
Cursor muestra su aprobación habitual una sola vez para el servidor MCP stdio local; aprueba `session-recall` para iniciar las herramientas.

### 3. Comprueba que funciona

```bash
Expand All @@ -87,7 +96,9 @@ session-recall search "something you actually discussed last week"

Los resultados con un `score` significan que la búsqueda semántica está activa. En el agente, `claude mcp list` debería mostrar `session-recall ✔ Connected`, y preguntarle sobre trabajo pasado debería activar `recall_search`.

No hay nada más que configurar: el hook `SessionStart` incluido vuelve a indexar en segundo plano a partir de entonces, por lo que el índice se mantiene actualizado con ambos hosts automáticamente.
No hay nada más que configurar: cada plugin nativo incluye el formato de hook de su host y vuelve a indexar en segundo plano, manteniendo actualizados los tres historiales.

Cursor se detecta automáticamente en su ruta de datos normal de macOS/Linux y no necesita estar abierto. Para un perfil portátil o personalizado, usa `SESSION_RECALL_CURSOR_DB=/ruta/a/User/globalStorage/state.vscdb`. Session Recall abre la base en modo de solo lectura y obtiene una copia coherente mediante la API de backup de SQLite.

### Solución de problemas

Expand All @@ -98,8 +109,9 @@ $ session-recall health
[ok ] Freshness 2 minutes behind
[warn] Embedder responded in 5828 ms
→ slow provider will make indexing crawl
[ok ] Corpus 1053 sessions (claude 373, codex 680)
[ok ] Sources claude, codex present
[ok ] Vector space builtin/BAAI/bge-small-en-v1.5/384
[ok ] Corpus 1054 sessions (claude 373, codex 680, cursor 1)
[ok ] Sources claude, codex, cursor present

verdict: AMBER (voyage/voyage-4-large, index at ~/.local/share/session-recall/index.db)
```
Expand All @@ -116,7 +128,7 @@ La frescura compara la transcripción más nueva en el disco con el turno más n
### Referencia de CLI

```bash
session-recall index --source claude|codex|all # defaults to all
session-recall index --source claude|codex|cursor|all # defaults to all
session-recall search "query" --source codex
session-recall recent --date 2026-07-14 # this computer's timezone
session-recall search "deployment work" --start-date 2026-07-14 \
Expand All @@ -125,7 +137,7 @@ session-recall grep "exact" --limit 100 # raw scan, no API key needed
session-recall prune # drop rows for deleted transcripts
```

`search`, `recent`, `grep` y `prune` aceptan un opcional `--source claude|codex`; omítelo para buscar en ambos. Los filtros de fecha son inclusivos y se puede omitir cualquiera de los límites; la zona horaria predeterminada es la de esta computadora y acepta cualquier nombre IANA. `grep` se limita a 100 coincidencias por defecto.
`search`, `recent`, `grep` y `prune` aceptan un opcional `--source claude|codex|cursor`; omítelo para buscar en el historial unificado. Los filtros de fecha son inclusivos y se puede omitir cualquiera de los límites; la zona horaria predeterminada es la de esta computadora y acepta cualquier nombre IANA. `grep` se limita a 100 coincidencias por defecto.

Para desarrollo, un virtualenv dentro del árbol también funciona:

Expand All @@ -150,8 +162,11 @@ Nada está atado a un solo proveedor. `SESSION_RECALL_EMBED=<preset>` establece
| `ollama` | **local, free** | `nomic-embed-text` | 768 | — |
| `lmstudio` | **local, free** | `nomic-embed-text-v1.5` | 768 | — |
| `openai` | hosted, needs a key | `text-embedding-3-large` | 1024 | — |
| `builtin-en` | **incluido, gratis** | `bge-small-en-v1.5` | 384 | — |
| `builtin-zh` | **incluido, gratis** | `bge-small-zh-v1.5` | 512 | — |
| `builtin-multi` | **incluido, gratis** | `paraphrase-multilingual-MiniLM-L12-v2` | 384 | — |

Sin ningún preset configurado, session-recall elige Voyage cuando `VOYAGE_API_KEY` está presente, y de lo contrario busca un servidor local que ya esté escuchando: mejor que predeterminar a un proveedor que está garantizado para rechazar la solicitud. Con una clave configurada, no se ejecuta la búsqueda.
Sin ningún preset configurado, session-recall elige Voyage cuando `VOYAGE_API_KEY` está presente, luego busca un servidor local que ya esté escuchando y, si no encuentra ninguno, usa el modelo ONNX incluido. Con una clave configurada, no se ejecuta la búsqueda local.

**Gratuito y local, de principio a fin:**

Expand Down Expand Up @@ -179,7 +194,7 @@ Sobre la elección del modelo: `nomic-embed-text` es el predeterminado porque es

## Mantener el índice actualizado

Si instalaste el plugin, esto ya está manejado: pasa a la siguiente sección. El hook `SessionStart` incluido funciona en ambos hosts y ejecuta `session-recall index` en segundo plano, y el `--source all` predeterminado actualiza ambos historiales. La indexación es incremental (omite archivos ya indexados por firma), por lo que mantenerse al día es económico.
Si instalaste el plugin, esto ya está manejado: pasa a la siguiente sección. El hook `SessionStart` incluido ejecuta `session-recall index` en segundo plano, y el `--source all` predeterminado actualiza Claude, Codex y Cursor. La indexación es incremental, por lo que mantenerse al día es económico.

Solo si registraste el servidor MCP manualmente, añade el hook tú mismo en `~/.claude/settings.json`:

Expand Down Expand Up @@ -221,5 +236,5 @@ Este es un repositorio público. **Solo entra código en él.**
- Datos, índices, transcripciones raw, incrustaciones → `~/.local/share/session-recall/`, **fuera del árbol del repo**. Físicamente no pueden ser commitados.
- Claves API → solo en el entorno (`VOYAGE_API_KEY`); `.gitignore` bloquea `.env`.
- Pruebas → solo fixtures sintéticos, nunca una porción real de una sesión.
- Las transcripciones de Claude Code junto con las transcripciones activas y archivadas de Codex se leen localmente. Solo el texto superficial de usuario/asistente se incrusta; los datos de traza de herramientas/razonamiento se mantienen fuera de las incrustaciones y se exponen solo mediante expansión raw explícita o grep.
- Los textos de los fragmentos SE ENVÍAN a tu proveedor de incrustación/rerank configurado (Voyage por defecto) — elige un proveedor en el que confíes con tus transcripciones, o apunta el proveedor compatible con OpenAI a un punto de conexión local.
- Las transcripciones de Claude Code, las transcripciones activas y archivadas de Codex y el SQLite de Cursor se leen localmente. Las instantáneas normalizadas de Cursor permanecen en el directorio de datos. Solo el texto superficial de usuario/asistente se incrusta; las herramientas y el razonamiento quedan fuera de las incrustaciones.
- Los textos de los fragmentos se envían al proveedor configurado. Sin claves, el proveedor incluido permanece completamente local; si eliges Voyage u otro endpoint alojado, usa uno en el que confíes.
Loading
Loading