165 lines
7.8 KiB
Markdown
165 lines
7.8 KiB
Markdown
---
|
|
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 solo las páginas
|
|
más relevantes (arquitectura, estructura, tecnologías, estilo de código, etc.). 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]"
|
|
---
|
|
|
|
# docmost-context — Cargar contexto relevante del proyecto desde Docmost
|
|
|
|
Lee solo las páginas más importantes de Docmost para arrancar la conversación con contexto
|
|
estructural, en lugar de leer todo ciegamente.
|
|
|
|
Se dispara automáticamente al inicio de la conversación vía el hook `SessionStart`
|
|
(`~/.claude/hooks/docmost-session-start.sh`), que inyecta una instrucción con el `PROJECT_NAME` ya
|
|
detectado. También puede invocarse a mano.
|
|
|
|
## Workflow
|
|
|
|
### 1. Determinar el nombre del proyecto
|
|
- Si vino como argumento (`args`), úsalo directamente.
|
|
- Si no, detéctalo en este orden de prioridad (igual que `agent-orchestrator`):
|
|
```bash
|
|
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 2>/dev/null || pwd)")
|
|
```
|
|
|
|
### 2. Listar spaces
|
|
Llama a `mcp__docmost__list_spaces`.
|
|
|
|
### 3. Buscar la coincidencia
|
|
Compara `PROJECT_NAME` contra el `name` y el `slug` de cada space, **normalizando** ambos lados antes de
|
|
comparar: minúsculas, sin espacios/guiones/guiones bajos, y **sin el scope de npm** si lo tiene (quita el
|
|
prefijo `@algo/` de nombres tipo `@aleleba/create-react-component-library` → `create-react-component-library`)
|
|
— los nombres de space no siempre calzan literal con el nombre del repo o del `package.json`
|
|
(ej. space "Create React SSR App" vs. repo `create-react-ssr-app`, o `@aleleba/create-react-component-library`
|
|
vs. space "Create React Component Library").
|
|
|
|
Si tras esa normalización no hay match exacto, prueba también un match por contención (el nombre
|
|
normalizado de uno está contenido en el del otro) antes de darte por vencido.
|
|
|
|
- **Una sola coincidencia** → úsala directamente, sin confirmar con el usuario.
|
|
- **Cero coincidencias** → usa `AskUserQuestion` mostrando la lista de spaces disponibles (nombre +
|
|
descripción) y deja elegir uno existente, o la opción de que ninguno corresponde. Si el usuario dice
|
|
que ninguno corresponde, no cargues nada y continúa la conversación normalmente — no insistas.
|
|
- **Varias coincidencias ambiguas** → pregunta igual, mostrando solo los candidatos ambiguos.
|
|
|
|
### 4. Dos pasos: puntuar y leer
|
|
|
|
Llama a `mcp__docmost__list_pages({spaceId})` para obtener el árbol completo de páginas.
|
|
No llames a `get_page` todavía. Primero **puntuar** todas las páginas, luego **leer** solo las seleccionadas.
|
|
|
|
#### Paso A: Puntuar cada página
|
|
|
|
Asigna un score a cada página con esta fórmula:
|
|
|
|
```
|
|
score = keyword_score + depth_score + name_quality + topic_bonus
|
|
```
|
|
|
|
**keyword_score** (2 puntos por cada keyword que coincida con el nombre o ruta de la página):
|
|
|
|
| Categoría | Keywords |
|
|
|---|---|
|
|
| Arquitectura y estructura | arquitectura, estructura, stack, tecnologías, componentes, layout, routing, routes, endpoints, models, schema, database, base de datos |
|
|
| Configuración y herramientas | config, configuration, tsconfig, vite.config, next.config, eslint, prettier, biome, tailwind, tailwind.config, dependencies, dependencias |
|
|
| Convenios y estilo | estilo de código, convenciones, code style, coding conventions, guidelines, guía, style guide |
|
|
| Onboarding y setup | onboarding, setup, getting started, entorno, environment, variables, entorno, configuración, install, instalación |
|
|
| Testing | testing, tests, jest, vitest, cypress, playwright, e2e, integration |
|
|
| Deploy y CI/CD | deploy, deployment, CI/CD, pipeline, github actions, vercel, netlify, docker, docker-compose |
|
|
| Migración y estado | migración, migrations, roadmap, estado actual, changelog, release |
|
|
| API y backend | API, endpoint, route, controller, service, middleware |
|
|
| Genéricos (páginas raíz) | overview, introduction, getting started, readme, documentación, inicio, home |
|
|
|
|
**depth_score** (basado en la profundidad en la jerarquía):
|
|
- 0 niveles (página raíz): **+3**
|
|
- 1 nivel de profundidad: **+2**
|
|
- 2 niveles de profundidad: **+1**
|
|
- 3+ niveles de profundidad: **+0**
|
|
|
|
**name_quality** (1 si el nombre es significativo, 0 si no):
|
|
- **+1** si el nombre no es "Untitled", "Sin título", vacío, o genérico sin contexto
|
|
- **+0** si el nombre es vacío, "Untitled", o similar
|
|
|
|
**topic_bonus** (2 puntos si la página coincide con el tema del usuario, 0 si no):
|
|
|
|
Si el mensaje del usuario o el hook mencionan un tema específico, aplica bonus:
|
|
|
|
| Tema del usuario | Keywords de bonus |
|
|
|---|---|
|
|
| Testing | test, jest, vitest, cypress, playwright, e2e |
|
|
| Deploy/CI/CD | deploy, CI/CD, pipeline, docker, vercel, github actions |
|
|
| Database | database, schema, migration, prisma, drizzle, kysely |
|
|
| UI/Components | component, design system, tailwind, theme, layout |
|
|
| API/Backend | API, endpoint, route, controller, service |
|
|
|
|
El topic_bonus es un **extra** sobre el keyword_score base. No reemplaza las keywords de
|
|
arquitectura/estructura — se suma a ellas.
|
|
|
|
#### Paso B: Reglas de selección
|
|
|
|
Clasifica las páginas en tres tiers según el score:
|
|
|
|
| Tier | Score | Qué hacer |
|
|
|---|---|---|
|
|
| **Crítico** | >= 8 | Leer completo con `get_page` |
|
|
| **Importante** | 4-7 | Leer título + snippet (primeros 300 caracteres) |
|
|
| **Nice-to-know** | < 4 | No leer contenido, solo anotar título |
|
|
|
|
**Límite de páginas completas:** máximo **5 páginas** se leen en detalle.
|
|
|
|
**Regla de selección según el total de páginas del space:**
|
|
|
|
| Total páginas | Páginas completas | Snippets | Ignorar |
|
|
|---|---|---|---|
|
|
| 0-3 | Todas | 0 | 0 |
|
|
| 4-10 | Top 3-5 | Resto | 0 |
|
|
| 11+ | Top 5 | Siguientes 5 | Resto |
|
|
|
|
**Lectura parcial con contenido-gated expansion (para tier "Importante"):**
|
|
|
|
1. Leer título + primeros 300 caracteres del contenido.
|
|
2. Evaluar: ¿el snippet contiene información relevante para el tema que el usuario está trabajando?
|
|
3. Si SÍ → leer la página completa con `get_page`.
|
|
4. Si NO → descartar, no leer más.
|
|
|
|
**Páginas ignoradas:** solo anotar el título en el reporte final. No llamar a `get_page`.
|
|
|
|
### 5. Leer solo lo seleccionado
|
|
|
|
Para cada página seleccionada:
|
|
|
|
- **Tier Crítico** (hasta 5 páginas): llamar a `mcp__docmost__get_page({pageId})` y leer el contenido completo.
|
|
- **Tier Importante** (lectura parcial): llamar a `get_page`, leer solo título + primeros 300 caracteres.
|
|
Si el snippet es relevante para el tema del usuario, leer el resto.
|
|
- **Tier Nice-to-know**: no llamar a `get_page`. Solo usar el título de la lista.
|
|
|
|
### 6. Reportar, no transcribir
|
|
|
|
Una vez cargado, responde con un mensaje breve (1-2 líneas): qué space se usó y cuántas páginas
|
|
relevantes se cargaron. No repitas el contenido de las páginas en el chat — ya quedó en tu contexto
|
|
para usarlo cuando haga falta.
|
|
|
|
Ejemplo de reporte:
|
|
|
|
```
|
|
Contexto cargado desde Docmost:
|
|
- Space: <nombre>
|
|
- Fase 1 (baseline): <n> páginas (arquitectura, estructura, tecnologías)
|
|
- Fase 2 (contexto específico): <n> páginas (<temas>)
|
|
Total: <n> páginas relevantes cargadas.
|
|
```
|
|
|
|
### 7. Una sola vez por conversación
|
|
|
|
Ejecuta esto una sola vez, al primer turno disparado por el hook. No lo repitas en turnos posteriores
|
|
de la misma conversación salvo que el usuario lo pida explícitamente (ej. "recarga el contexto de
|
|
Docmost").
|