configuracion de entorno de desarrollo

This commit is contained in:
Carlos Sandoval
2026-09-02 18:02:43 +00:00
commit bc9fb0dd0f
22 changed files with 1985 additions and 0 deletions
@@ -0,0 +1,17 @@
# Spec: dev-environment
## ADDED Requirements
### Requirement: Contenedor de desarrollo con Go 1.22
El sistema SHALL incluir un devcontainer basado en la imagen oficial `mcr.microsoft.com/devcontainers/go:1-1.22-bookworm` que permita desarrollar el proyecto sin Go instalado localmente.
#### Scenario: Apertura del proyecto en el contenedor
- **WHEN** el usuario abre el proyecto en DevPod o Dev Containers
- **THEN** el contenedor se construye a partir de la imagen oficial de Go 1.22 y dispone del toolchain necesario para compilar y ejecutar el proyecto
### Requirement: Tooling del editor preconfigurado
El devcontainer SHALL preconfigurar el soporte de `gopls` (language server de Go) e instalar `golangci-lint`, además de las extensiones básicas de Go para el editor.
#### Scenario: Experiencia de edición en el contenedor
- **WHEN** el desarrollador edita archivos Go dentro del devcontainer
- **THEN** dispone de autocompletado y diagnóstico vía gopls, de linting vía golangci-lint y de las extensiones de Go instaladas automáticamente
@@ -0,0 +1,38 @@
# Spec: mcp-server
## ADDED Requirements
### Requirement: Arranque del servidor por defecto
Cuando el binario se ejecuta sin argumentos, el sistema SHALL iniciar el servidor MCP usando transporte stdio.
#### Scenario: Ejecución sin argumentos
- **WHEN** el usuario ejecuta el binario sin ningún argumento
- **THEN** el sistema arranca el servidor MCP en modo stdio y queda a la espera de mensajes del cliente
### Requirement: Comando version
El sistema SHALL exponer el comando `version` que imprime la versión del binario.
#### Scenario: Consulta de versión
- **WHEN** el usuario ejecuta el binario con el argumento `version`
- **THEN** el sistema imprime por stdout la versión inyectada en tiempo de compilación mediante `-ldflags`
### Requirement: Comando update
El sistema SHALL exponer el comando `update` que ejecuta el proceso de auto-actualización del binario.
#### Scenario: Ejecución de actualización
- **WHEN** el usuario ejecuta el binario con el argumento `update`
- **THEN** el sistema consulta la última release de Gitea y aplica la actualización si existe una versión superior
### Requirement: Metadatos de build inyectados
El sistema SHALL definir variables globales (`Version`, `GiteaURL`, `RepoOwner`, `RepoName`) que MUST ser inyectables en tiempo de compilación mediante `-ldflags -X`.
#### Scenario: Compilación con ldflags
- **WHEN** el binario se compila pasando valores para `main.Version`, `main.GiteaURL`, `main.RepoOwner` y `main.RepoName` vía `-ldflags`
- **THEN** el comando `version` y la lógica de auto-update utilizan esos valores en tiempo de ejecución
### Requirement: Registro de herramientas MCP
El servidor MCP SHALL registrar las herramientas `outline_list_collections`, `outline_search`, `outline_get_document` y `outline_create_document` y MUST exponerlas vía el protocolo MCP.
#### Scenario: Listado de herramientas desde un cliente MCP
- **WHEN** un cliente MCP solicita la lista de herramientas disponibles
- **THEN** el servidor responde incluyendo las cuatro herramientas de Outline con sus esquemas de entrada definidos
@@ -0,0 +1,61 @@
# Spec: outline-api-client
## ADDED Requirements
### Requirement: Configuración por variables de entorno
El sistema SHALL configurar el cliente de Outline a partir de las variables de entorno `OUTLINE_URL` (URL base de la instancia) y `OUTLINE_API_KEY` (token de API).
#### Scenario: Cliente configurado correctamente
- **WHEN** las variables `OUTLINE_URL` y `OUTLINE_API_KEY` están definidas en el entorno
- **THEN** el cliente construye las peticiones contra la URL base indicada y autentica con el token provisto
#### Scenario: Variables de entorno ausentes
- **WHEN** `OUTLINE_URL` o `OUTLINE_API_KEY` no están definidas al invocar una herramienta
- **THEN** el sistema responde con un mensaje de error descriptivo indicando la configuración faltante
### Requirement: Petición POST genérica autenticada
El cliente HTTP SHALL implementar un método genérico para realizar peticiones POST a los endpoints de la API de Outline, incluyendo el header `Authorization: Bearer <TOKEN>` y el body en formato JSON.
#### Scenario: Petición autenticada
- **WHEN** el cliente envía una petición a cualquier endpoint de la API de Outline
- **THEN** la petición incluye el header `Authorization: Bearer` con el token configurado y el payload serializado como JSON
#### Scenario: Error de la API de Outline
- **WHEN** la API de Outline responde con un código HTTP de error
- **THEN** el sistema propaga un error descriptivo (incluyendo el código y el mensaje de la API) hacia el llamador
### Requirement: Herramienta outline_list_collections
La herramienta `outline_list_collections` SHALL invocar el endpoint `/api/collections.list` y devolver el ID, el nombre y la descripción de cada colección.
#### Scenario: Listado de colecciones exitoso
- **WHEN** se invoca `outline_list_collections` sin parámetros
- **THEN** la herramienta devuelve la lista de colecciones con sus campos `id`, `name` y `description`
### Requirement: Herramienta outline_search
La herramienta `outline_search` SHALL invocar el endpoint `/api/documents.search` recibiendo el parámetro `query` y devolver los resultados de la búsqueda.
#### Scenario: Búsqueda con resultados
- **WHEN** se invoca `outline_search` con un `query` válido
- **THEN** la herramienta devuelve los documentos coincidentes con su información relevante (título, id y extracto)
#### Scenario: Búsqueda sin resultados
- **WHEN** se invoca `outline_search` con un `query` que no coincide con ningún documento
- **THEN** la herramienta devuelve una lista vacía sin error
### Requirement: Herramienta outline_get_document
La herramienta `outline_get_document` SHALL invocar el endpoint `/api/documents.info` recibiendo el parámetro `id` y devolver el título y el texto del documento en formato Markdown.
#### Scenario: Lectura de documento existente
- **WHEN** se invoca `outline_get_document` con el `id` de un documento existente
- **THEN** la herramienta devuelve el título del documento y su contenido en Markdown
#### Scenario: Documento inexistente
- **WHEN** se invoca `outline_get_document` con un `id` que no corresponde a ningún documento
- **THEN** la herramienta devuelve un error indicando que el documento no fue encontrado
### Requirement: Herramienta outline_create_document
La herramienta `outline_create_document` SHALL invocar el endpoint `/api/documents.create` recibiendo los parámetros `title`, `text` (Markdown) y `collection_id`, y devolver la información del documento creado.
#### Scenario: Creación de documento exitosa
- **WHEN** se invoca `outline_create_document` con `title`, `text` y un `collection_id` válido
- **THEN** la herramienta crea el documento en la colección indicada y devuelve su `id` y `title`
@@ -0,0 +1,42 @@
# Spec: release-pipeline
## ADDED Requirements
### Requirement: Disparo por tags de versión
El pipeline de release SHALL ejecutarse cuando se realice push de tags cuyo nombre comience con `v` (por ejemplo `v1.0.0`).
#### Scenario: Push de tag de release
- **WHEN** se pushea al repositorio un tag que empieza con `v`
- **THEN** el workflow de Gitea Actions se dispara automáticamente
#### Scenario: Push sin tag de release
- **WHEN** se pushea una rama sin tags o un tag que no empieza con `v`
- **THEN** el workflow de release no se ejecuta
### Requirement: Entorno de compilación
El pipeline SHALL utilizar una imagen de Ubuntu y SHALL configurar Go 1.22 como versión del toolchain antes de compilar.
#### Scenario: Job de build
- **WHEN** el pipeline se ejecuta
- **THEN** el entorno de build dispone de Go 1.22 instalado sobre una imagen Ubuntu
### Requirement: Inyección de variables en la compilación
El pipeline SHALL inyectar en tiempo de compilación las variables `Version`, `GiteaURL`, `RepoOwner` y `RepoName` mediante `-ldflags`, derivadas del tag y del repositorio.
#### Scenario: Compilación con metadatos
- **WHEN** el pipeline compila los binarios
- **THEN** los binarios resultantes contienen la versión del tag y los datos del repositorio Gitea para el mecanismo de auto-update
### Requirement: Compilación multi-plataforma estática
El pipeline SHALL compilar binarios estáticos (`CGO_ENABLED=0`) para las plataformas linux/amd64, darwin/arm64 y windows/amd64.
#### Scenario: Artefactos generados
- **WHEN** el job de build completa la compilación
- **THEN** se generan tres binarios estáticos: uno para linux amd64, uno para darwin arm64 (Apple Silicon) y uno para windows amd64
### Requirement: Publicación del release en Gitea
El pipeline SHALL publicar un release en Gitea asociado al tag, adjuntando los binarios compilados como assets, utilizando la acción oficial de Gitea o un CLI compatible.
#### Scenario: Release publicado
- **WHEN** la compilación multi-plataforma finaliza con éxito
- **THEN** se crea (o actualiza) el release del tag en Gitea con los tres binarios adjuntos
@@ -0,0 +1,47 @@
# Spec: self-update
## ADDED Requirements
### Requirement: Consulta de la última release de Gitea
El sistema SHALL consultar el endpoint `/api/v1/repos/{owner}/{repo}/releases/latest` de la instancia de Gitea configurada para obtener la última release disponible.
#### Scenario: Consulta exitosa de última release
- **WHEN** se ejecuta la lógica de auto-actualización y la API de Gitea responde correctamente
- **THEN** el sistema obtiene el tag de la release y la lista de assets publicados
#### Scenario: Gitea no accesible
- **WHEN** la instancia de Gitea no es accesible o responde con error
- **THEN** el sistema finaliza con un mensaje de error sin modificar el binario actual
### Requirement: Comparación de versiones
El sistema SHALL comparar la versión actual del binario (`Version` inyectada vía ldflags) con el tag de la última release de Gitea, y MUST omitir la actualización si la versión actual es igual o superior.
#### Scenario: Versión actualizada disponible
- **WHEN** el tag de Gitea indica una versión superior a la versión actual
- **THEN** el sistema procede a descargar el asset correspondiente
#### Scenario: Versión ya actualizada
- **WHEN** la versión actual es igual o superior al tag de la última release
- **THEN** el sistema informa que no hay actualizaciones y no realiza cambios en el binario
### Requirement: Descarga del asset compatible
El sistema SHALL seleccionar el asset de la release cuyo nombre corresponda al sistema operativo y arquitectura actuales (`runtime.GOOS`, `runtime.GOARCH`), y MUST descargarlo antes de aplicar la actualización.
#### Scenario: Asset compatible disponible
- **WHEN** la release contiene un asset que coincide con el `GOOS`/`GOARCH` actuales
- **THEN** el sistema descarga dicho asset para aplicar la actualización
#### Scenario: Asset compatible no disponible
- **WHEN** la release no contiene un asset para la plataforma actual
- **THEN** el sistema finaliza con un error indicando que no existe binario para la plataforma
### Requirement: Aplicación del binario descargado
El sistema SHALL aplicar el binario descargado utilizando `selfupdate.Apply` (github.com/minio/selfupdate), reemplazando el binario en ejecución.
#### Scenario: Actualización aplicada correctamente
- **WHEN** el asset descargado es un binario válido
- **THEN** el sistema reemplaza el binario actual mediante `selfupdate.Apply` e informa el éxito de la operación
#### Scenario: Asset corrupto o inválido
- **WHEN** el asset descargado no es un binario válido
- **THEN** el sistema aborta la actualización e informa el error sin dejar el binario en estado inconsistente