# Skill global: cargar contexto de Docmost al iniciar conversación

## Contexto

El usuario quiere que, al iniciar cualquier conversación de Claude Code, se cargue automáticamente el
contexto del proyecto actual desde Docmost (MCP `mcp__docmost__*`): listar los spaces, identificar cuál
corresponde al proyecto en el que se está trabajando, y leer el contenido completo de todas sus páginas.

Investigación realizada (en modo solo-lectura):
- No existe ningún CLAUDE.md global ni hook `SessionStart` hoy en `~/.claude/settings.json` (solo hay un
  hook `Notification` para email vía Gmail).
- Las **skills se activan por coincidencia de descripción**, no automáticamente al iniciar sesión. Para que
  algo corra *siempre* al inicio, el único mecanismo real es un **hook `SessionStart`**, cuyo `stdout` se
  inyecta como contexto adicional (esto es lo que documenta `hooks-guide.md` de Claude Code, ej. "Re-inject
  context after compaction"). El hook (bash) no puede llamar herramientas MCP directamente — eso solo lo
  puede hacer el modelo. Por eso el diseño es: **hook (bash) → inyecta instrucción → skill (markdown) →
  modelo ejecuta las llamadas MCP reales**.
- Ya existe en `background-orchestrator/SKILL.md` una lógica de detección de proyecto reutilizable
  (`package.json` → `pyproject.toml` → basename del repo git), que se reutiliza aquí tal cual.
- Verifiqué en vivo el MCP de Docmost: `list_spaces` devuelve `{id, name, slug, description, ...}`;
  `list_pages({spaceId})` devuelve el árbol de páginas (`id, title, parentPageId`) sin contenido;
  `get_page({pageId})` sí devuelve el contenido completo (`content`, markdown). Los nombres de space no
  siempre calzan literal con el nombre del repo (ej. space "Create React SSR App" vs. un repo en
  kebab-case), así que el match debe ser normalizado (minúsculas, sin espacios/guiones), no exacto.
  Algunos spaces ya tienen 30+ páginas con contenido extenso.

Decisiones confirmadas con el usuario:
1. **Leer todo siempre** — al detectar el space, leer el contenido completo de todas sus páginas (sin
   recortar ni resumir antes de cargar).
2. **Si no hay match** — preguntar al usuario (mostrar los spaces disponibles y dejar que elija uno o
   indique que no corresponde ninguno).
3. **Alcance** — el hook solo actúa si el cwd está dentro de un repo git; fuera de un repo no intenta nada.

## Diseño

### 1. Script del hook — `~/.claude/hooks/docmost-session-start.sh` (nuevo, `chmod +x`)

Bash puro, sin llamadas MCP (no puede hacerlas). Solo detecta el proyecto y, si aplica, imprime a stdout
una instrucción para que el modelo invoque la skill. Si no está en un repo git, no imprime nada (`exit 0`
silencioso → no se inyecta contexto ni se gasta turno en esto).

```bash
#!/bin/bash
# Solo actuar dentro de un repo git (decisión confirmada con el usuario)
git rev-parse --show-toplevel >/dev/null 2>&1 || exit 0

PROJECT_NAME=$(jq -r '.name // empty' package.json 2>/dev/null)
[ -z "$PROJECT_NAME" ] && PROJECT_NAME=$(grep -oP '^\s*name\s*=\s*"\K[^"]+' pyproject.toml 2>/dev/null | head -1)
[ -z "$PROJECT_NAME" ] && PROJECT_NAME=$(basename "$(git rev-parse --show-toplevel)")

cat <<EOF
[docmost-context] Nueva conversación detectada en el proyecto git "$PROJECT_NAME" ($(pwd)).
Antes de responder al primer mensaje del usuario, invoca la skill "docmost-context" (Skill tool,
skill: docmost-context, args: "$PROJECT_NAME") para cargar el contexto del proyecto desde Docmost.
Hazlo una sola vez al inicio de esta conversación; no la vuelvas a invocar en turnos posteriores salvo
que el usuario lo pida explícitamente.
EOF
```

### 2. Registrar el hook en `~/.claude/settings.json` (editar)

Añadir la clave `SessionStart` dentro de `hooks` (se conserva el `Notification` existente). Se registran
tres matchers por separado (`startup`, `resume`, `clear`) — deliberadamente **sin** `compact`, para no
releer 30+ páginas completas cada vez que el contexto se compacta a mitad de conversación:

```json
"SessionStart": [
  { "matcher": "startup", "hooks": [{ "type": "command", "command": "/home/aleleba/.claude/hooks/docmost-session-start.sh" }] },
  { "matcher": "resume",  "hooks": [{ "type": "command", "command": "/home/aleleba/.claude/hooks/docmost-session-start.sh" }] },
  { "matcher": "clear",   "hooks": [{ "type": "command", "command": "/home/aleleba/.claude/hooks/docmost-session-start.sh" }] }
]
```

También añadir a `permissions.allow`: `"mcp__docmost__list_spaces"` (los demás —`list_pages`, `get_page`,
`search`— ya están permitidos desde `background-orchestrator`).

### 3. Skill global — `~/.claude/skills/docmost-context/SKILL.md` (nuevo)

```yaml
---
name: docmost-context
description: >-
  Carga el contexto del proyecto actual desde Docmost (MCP) al inicio de una conversación: lista los
  spaces, identifica cuál corresponde al proyecto del directorio actual, y lee el contenido completo
  de todas sus páginas. Se activa automáticamente vía el hook SessionStart (ver
  ~/.claude/hooks/docmost-session-start.sh) — no requiere que el usuario la invoque a mano, aunque
  también responde a "carga el contexto de Docmost", "lee el proyecto en Docmost", "/docmost-context".
effort: medium
argument-hint: "[nombre del proyecto, si ya se conoce]"
---
```

Cuerpo (workflow):
1. **Determinar el nombre del proyecto**: usar el argumento recibido si viene; si no, repetir la misma
   detección de `background-orchestrator` (`package.json` → `pyproject.toml` → basename del repo git).
2. **Listar spaces**: `mcp__docmost__list_spaces`.
3. **Buscar coincidencia** comparando el nombre del proyecto contra `name` y `slug` de cada space,
   normalizando (minúsculas, sin espacios/guiones/guiones bajos) — match exacto normalizado, no
   substring débil.
   - **Una sola coincidencia** → usarla directamente, sin confirmar con el usuario.
   - **Cero coincidencias** → usar `AskUserQuestion` mostrando la lista de spaces disponibles, dejando
     elegir uno existente o responder que ninguno corresponde (en ese caso, no cargar nada y continuar
     la conversación normalmente).
   - **Varias coincidencias ambiguas** → preguntar igual, mostrando solo los candidatos ambiguos.
4. **Leer el space completo**: `mcp__docmost__list_pages({spaceId})` para obtener todas las páginas, y
   luego `mcp__docmost__get_page({pageId})` para **cada una** (contenido completo, sin omitir ninguna).
5. **No repetir el dump al usuario**: una vez cargado el contenido al contexto, responder con un mensaje
   breve (1-2 líneas) indicando qué space y cuántas páginas se cargaron — no transcribir el contenido de
   las páginas en el chat.
6. Ejecutar esto **una sola vez** por conversación (al primer turno, disparado por el hook); no repetir
   en turnos siguientes salvo pedido explícito del usuario.

## Verificación

1. `chmod +x ~/.claude/hooks/docmost-session-start.sh` y ejecutarlo manualmente dentro de un repo git y
   fuera de uno, confirmando que imprime la instrucción solo en el primer caso.
2. Iniciar una conversación nueva (`startup`) dentro de un repo con space conocido (ej. `Ro-ut`) y
   confirmar que el modelo invoca la skill sin que el usuario lo pida, y que reporta el space/páginas
   cargadas en 1-2 líneas.
3. Probar dentro de un repo **sin** space coincidente y confirmar que se dispara `AskUserQuestion` con la
   lista de spaces.
4. Si en la prueba real el `stdout` plano del hook no llega como contexto, usar como fallback el formato
   JSON documentado: `{"hookSpecificOutput": {"hookEventName": "SessionStart", "additionalContext": "..."}}`.
5. Confirmar que `/clear` también dispara la carga, y que `compact` (compactación automática) **no** la
   repite.
