v0.9.7 - Motor Python, corrección de anclas Gitignore, ciclo de vida del motor y seguridad

Aspectos destacados

docmd v0.9.7 introduce el Motor Python, corrige una regresión crítica en el manejo de .gitignore introducida en v0.9.6, unifica la gestión del ciclo de vida de los procesos de motor y aporta mejoras de seguridad en la CLI y el servidor de desarrollo.

  • Motor Python (@docmd/engine-python): Un nuevo adaptador de motor basado en Python 3 (>= 3.8) para acelerar el descubrimiento de archivos, el análisis del historial de Git y la indexación de búsqueda mediante un pool de trabajadores stdio de alto rendimiento.
  • Ciclo de vida unificado del motor (@docmd/api, @docmd/core): Métodos estandarizados shutdown() y destroy() en todos los motores (js, rust, python) con gestión automática de inactividad de trabajadores y salidas de proceso limpias.
  • Integración de docmd-search 0.1.6: Integración de búsqueda y dependencias peer actualizadas a docmd-search >=0.1.6 con soporte nativo para el motor Python.
  • Corrección de patrones gitignore anclados (#244): Los patrones anclados (p. ej. /airo) ahora se comparan relativos al directorio raíz del proyecto, no contra la ruta absoluta del sistema de archivos. Anteriormente, si el patrón coincidía con el nombre de cualquier carpeta ancestral en la ruta absoluta, todas las páginas eran excluidas silenciosamente y las compilaciones reportaban Generated 0 pages.
  • Cumplimiento de config.exclude en MCP (#245): search_docs, list_docs y validate_docs ahora respetan config.exclude. Anteriormente, los archivos excluidos (como borradores o páginas archivadas) aún se exponían a los agentes de IA a través de las herramientas MCP.
  • Prevención de inyección de shell: Se reemplazó execSync con interpolación de shell por spawnSync con arrays de argumentos explícitos en el comando doctor y en la indexación de búsqueda.
  • Endurecimiento XSS y path traversal en el servidor de desarrollo: Las URL reflejadas en páginas de error 404/500 ahora se escapan con HTML, y los destinos de redirección se validan estrictamente.
  • Canonicalización de rutas de activos: La resolución de activos del servidor en vivo ahora aplica un límite de ruta segura canónica.

Motor Python (@docmd/engine-python)

v0.9.7 expande la arquitectura multimo-motor de docmd junto a JavaScript y Rust incorporando Python:

  • Detección automática y configuración cero: Si Python 3 está disponible en el PATH del sistema, "engine": "python" en docmd.config.json activa automáticamente el motor Python. Si no está disponible, docmd recurre fluidamente al motor JS.
  • Pool de trabajadores persistente: Funciona a través de un trabajador JSON-RPC por stdio optimizado con limpieza por inactividad, eliminando el coste de inicialización de subprocesos entre tareas.
  • Integración con plugins: Impulsa de forma directa la extracción de registros de Git, la indexación de búsqueda y el escaneo por lotes de archivos.

Ciclo de vida y gestión de recursos (@docmd/api, @docmd/core)

  • Apagado estandarizado: Hooks shutdown() y destroy() en la interfaz Engine en todos los paquetes de motor (@docmd/engine-js, @docmd/engine-rust, @docmd/engine-python).
  • Liberación de recursos: Las canalizaciones de compilación y desarrollo invocan sistemáticamente shutdownEngines() al finalizar para liberar pipes, memoria y enlaces nativos.
  • Trabajador inactivo: El proceso trabajador de Python se termina automáticamente en inactividad, evitando escuchadores huérfanos en segundo plano.

Regresión de patrones gitignore anclados (@docmd/core)

Error corregido (#244): Desde que v0.9.6 introdujo la conciencia de .gitignore para el descubrimiento de páginas, los patrones anclados con / inicial eran despojados de dicha barra y comparados contra la ruta absoluta completa de cada archivo. Esto significaba que /airo (destinado a ignorar un binario en la raíz del repositorio) también excluiría cada archivo bajo /Users/alguien/github/airo/docs/.

Causa raíz: isExcludedPath eliminaba el / inicial y ejecutaba normalizedPath.includes('/airo/') contra la ruta absoluta completa.

Corrección: Los patrones anclados ahora se comparan solo contra la ruta relativa al directorio fuente de nivel superior. Los patrones no anclados (sin / inicial) conservan su comportamiento de coincidencia en cualquier parte de la ruta.

Endurecimiento de seguridad (@docmd/core, @docmd/plugins-search, @docmd/live)

  • Comando doctor: execSync reemplazado por spawnSync(['npm', 'doctor']) con shell: false.
  • Subproceso de indexación de búsqueda: Endurecido de igual manera.
  • Servidor de desarrollo (docmd dev): req.url reflejado en errores 404 y 500 ahora se escapa con HTML. Los destinos de redirección se validan contra una lista de permitidos.
  • Resolución de activos del servidor en vivo: Todas las rutas de activos se resuelven a través de canonicalSafePath.

Cumplimiento de config.exclude en MCP (@docmd/core)

Error corregido (#245): search_docs, list_docs y validate_docs en el servidor MCP ignoraban config.exclude. La función interna findMarkdownFiles() solo omitía node_modules y directorios con punto, sin consultar los patrones de exclusión añadidos en v0.9.6. Esto significaba que los agentes de IA podían descubrir y leer documentación deliberadamente excluida del sitio publicado (p. ej. especificaciones archivadas, borradores internos).

Corrección: search_docs y list_docs ahora utilizan findFilesRecursive() (el mismo explorador de archivos utilizado por el pipeline de compilación), que ya aplica config.exclude, .gitignore y todas las reglas de exclusión estándar. validate_docs transmite config.exclude al explorador de archivos del validador de enlaces. La salida de la compilación y los resultados de las herramientas MCP ahora coinciden en qué archivos constituyen documentación publicada.

Qué esperar en 0.9.8

  • Verificación de integridad de paquetes después de instalaciones batch pre-flight para detectar paquetes semi-extraídos.
  • Mejoras adicionales en el motor de coincidencia de gitignore (patrones de negación !, archivos .gitignore por subdirectorio).