Skip to content

Latest commit

 

History

26 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

qabot

Arnés de QA y despliegue para la línea de comandos, y servidor MCP para agentes. Un mismo ciclo —probar en local, desplegar, pasar la batería contra lo desplegado, dar un veredicto— sea cual sea el proyecto.

Lo que lo distingue de un script de CI: no se fía de git. Le pregunta al destino qué tiene de verdad y detecta deriva — código que alguien editó directamente en el entorno y que un despliegue borraría sin avisar.

tipo en .qabot.json Para qué Despliega con
appsscript (por defecto) Google Apps Script clasp
cloudrun web sobre Cloud Run gcloud run deploy
generico cualquier otro proyecto lo que declare el proyecto

Los comandos son los mismos (estado, cambios, local, desplegar, remoto, ciclo, doctor); cada tipo los implementa con sus piezas. Lo que sigue describe el tipo appsscript; para Cloud Run y para cualquier otro proyecto, ver el final.

Módulo independiente: se instala dentro del proyecto destino con qabot install local, y a partir de ahí ese proyecto lleva sus propias pruebas en su propio repositorio.

Las pruebas las escribe un modelo local (gpt-oss:20b vía Ollama): el código y los diffs no salen de la máquina.

Instalación

Necesitas bash, python3 y node (18 o superior). Nada más: qabot no tiene dependencias de npm y no trae node_modules.

git clone https://github.com/FlEtsv/qabot.git
ln -sf "$PWD/qabot/bin/qabot" ~/.local/bin/qabot   # una vez

Comprueba que responde:

qabot ayuda

Después, en cada proyecto. Si no es Apps Script ni Cloud Run, empieza por la detección:

cd /mi/proyecto
qabot detectar             # mira qué hay y propone
qabot detectar --escribir  # lo guarda en .qabot.json
qabot doctor               # qué falta todavía

Para Apps Script:

cd /mi/proyecto && qabot install local

Copia dentro del proyecto:

Archivo De quién es
src/QA.js del módulo — se sobrescribe al reinstalar (así se actualiza)
tools/qa_local.js, tools/qa_generar.py del módulo — se sobrescriben
src/QA_Proyecto.js tuyo — solo se crea si no existe
src/QA_Suites.js tuyo — solo se crea si no existe

Puesta en marcha

  1. Adapta src/QA_Proyecto.js: entornos, qué vigilar, guardianes.
  2. Script Properties del proyecto Apps Script: QA_HABILITADO=true, QA_ENTORNO=STAGING, QA_TOKEN=<algo largo>.
  3. En tu doGet: if (params.vista === 'qa') return manejarVistaQA_(params);
  4. Rellena .qabot.json (no se sube a git: lleva tokens).

Anclado al proyecto real

qabot no se fía solo de git: le pregunta al proyecto Apps Script qué tiene de verdad, usando la Apps Script API con las credenciales que ya dejó clasp login.

qabot estado    # metadatos, versiones y despliegues reales
qabot cambios   # remoto vs tu copia, archivo a archivo y función a función

cambios detecta deriva: código que está en el proyecto y no en tu copia —alguien editó en el editor web— que un clasp push --force borraría sin avisar. Por eso qabot desplegar lo comprueba antes de empujar y se detiene si encuentra deriva.

Cuando le falta algo, lo pide

qabot doctor [entorno]

Comprueba node, la sesión de clasp (renovando el token de verdad, no mirando si el archivo existe), Ollama, la configuración del entorno, el acceso por API y el endpoint de QA. Sabe distinguir de quién es cada problema —clasp, gcloud, una Script Property, el acceso del despliegue— y en un terminal pregunta lo que falte y lo guarda. En modo no interactivo (CI, un agente) no pregunta: informa y sale con código 1.

Ciclo de una feature

qabot generar HEAD~1   # el modelo escribe pruebas para lo que cambiaste
qabot revisar          # el modelo critica sus propias pruebas
qabot local            # segundos, sin desplegar nada
qabot ciclo            # local → staging → batería real → veredicto
qabot desplegar produccion   # solo con lo anterior en verde (pide confirmación)

Las tres garantías del arnés

  1. Política por entorno y por servicio, aplicada por código. Cada entorno declara en qué puede escribir (p. ej. producción: Drive y Sheets sí, ERP no). Lo no permitido se bloquea de verdad durante la suite: la llamada lanza excepción. Un entorno no declarado no puede escribir en nada.
  2. Todo lo que se crea se deshace, en orden inverso, pasen o fallen las pruebas. Lo que no se pueda deshacer se reporta como huérfano.
  3. Se verifica que el entorno queda como estaba: huella de hojas y carpetas antes y después. "Las pruebas pasan" y "el entorno quedó bien" son dos preguntas distintas y el informe responde a las dos.

Las pruebas de qabot mismo

pruebas/correr.sh

qabot vigila el código de otros proyectos; esto vigila el suyo. Comprueba los mecanismos que, si se rompieran en silencio, dejarían el arnés dando falsa seguridad: que se niega a desplegar con deriva, que la configuración de un entorno no viaja a otro, que el sello de versión no miente, que el guardián bloquea de verdad y que lo creado se deshace en orden inverso.

No tocan ningún proyecto ni ninguna cuenta: cada caso monta un proyecto de mentira en un directorio temporal, con dobles de clasp y de la Apps Script API. Dos bloques: pruebas/arnes.js (el núcleo, en Node) y pruebas/cli.sh (el comando, en bash).

Proyectos Cloud Run

cd /mi/proyecto-web && qabot install cloudrun

Copia tools/qa_http.mjs y tools/qa_version.mjs (del módulo, se sobrescriben) y crea qa/probes.mjs (tuyo). Rellena .qabot.json:

{
  "tipo": "cloudrun",
  "predeterminado": "produccion",
  "entornos": {
    "produccion": {
      "servicio": "mi-servicio",
      "region": "europe-west1",
      "proyecto": "mi-proyecto-gcp"
    }
  }
}

En qué se diferencia de Apps Script

Apps Script Cloud Run
Desplegar clasp push gcloud run deploy --source
Deriva proyecto remoto vs copia local SHA desplegado vs HEAD local
Batería doGet?vista=qa, dentro del proyecto sondas HTTP, desde fuera

La diferencia de fondo está en la batería. En Apps Script el código de prueba corre dentro del proyecto, con sus permisos, y por eso necesita un token y tiene que deshacer lo que crea. En Cloud Run corre fuera, contra la URL pública y sin sesión: no puede inspeccionar el estado interno, pero comprueba exactamente lo que ve un desconocido, que es donde un fallo de autorización se convierte en una fuga. No hace falta abrir ningún endpoint de QA, y la batería no necesita deshacer nada porque solo lee.

La deriva, aquí

qabot desplegar deja en la variable BUILD_INFO del servicio qué commit subió, si el árbol estaba sucio y los últimos diez cambios. qabot cambios la lee y la compara con tu HEAD:

  • lo desplegado es tu HEAD → al día;
  • tu copia va por delante → te dice cuántos commits y cuáles;
  • lo desplegado no es antecesor de tu HEAD → alguien desplegó desde otra rama o desde otra máquina.

Esto importa porque gcloud run deploy --source sube el directorio de trabajo, no el commit: sin la ficha, un despliegue hecho con cambios sin commitear es irreproducible y nada lo delata.

Cualquier otro proyecto: el tipo generico

Apps Script y Cloud Run los sabe de memoria. Para todo lo demás qabot no adivina: mira el repositorio, propone lo que puede deducir de ficheros reales, y deja por escrito lo que no sabe.

qabot detectar

qabot detectar

Reconoce Node (npm, pnpm, yarn, bun), Python, Go, Rust, Maven, Gradle, Composer, Ruby y Makefile, y deduce los comandos solo de lo que el proyecto declara: un script de package.json, un objetivo del Makefile. Lo que no esté declarado no se propone — se pregunta.

Esa es la regla que lo mantiene honesto. Un comando inventado haría que el arnés dijera "verde" sobre algo que nadie ha ejecutado, y eso es peor que no tener arnés.

{
  "tipo": "generico",
  "comandos": {
    "local": "npm test",
    "construir": "npm run build",
    "bateria": "npm run e2e",
    "desplegar": { "staging": "make deploy staging" }
  }
}

Solo local es obligatorio. Lo que falte se salta diciéndolo, en vez de fingir que ha ido bien.

Lo que este tipo no puede hacer, y lo dice en su salida: un proyecto genérico no expone qué tiene desplegado, así que la deriva contra el entorno real no se comprueba. Eso solo lo saben appsscript y cloudrun, que sí pueden preguntárselo al destino.

El ciclo completo sobre un proyecto genérico:

qabot ciclo

Y cuando algo falta, doctor dice qué y cómo conseguirlo:

qabot doctor

Como servidor MCP

qabot se expone a cualquier agente que hable MCP — Claude Code, Codex, el que sea. No hay nada específico de un cliente.

claude mcp add --scope user qabot -- node /ruta/a/qabot/mcp/servidor.mjs

Para otros agentes, la entrada equivalente en su configuración:

{
  "mcpServers": {
    "qabot": { "command": "node", "args": ["/ruta/a/qabot/mcp/servidor.mjs"] }
  }
}

Nueve herramientas: qabot_detectar, qabot_configurar, qabot_estado, qabot_doctor, qabot_cambios, qabot_local, qabot_bateria, qabot_ciclo, qabot_desplegar.

El servidor habla JSON-RPC por stdio a pelo, sin SDK y sin dependencias: meterle un árbol de node_modules a una herramienta de la que cuelgan proyectos reales es más huella de la que justifica exponer nueve comandos.

Cómo pregunta cuando no sabe

qabot_detectar devuelve, además de su propuesta, una lista preguntas. Si no está vacía, el agente tiene instrucciones de trasladárselas al usuario con sus palabras y llamar después a qabot_configurar con las respuestas.

Funciona igual en cualquier cliente porque la duda viaja como dato en la respuesta, no como una capacidad del agente:

agente → qabot_detectar
qabot  → "reconozco Node; no encuentro batería ni despliegue" + 2 preguntas
agente → se las hace al usuario
usuario → contesta
agente → qabot_configurar {...}   → .qabot.json escrito

Junto a Code Timeline

Code Timeline lleva el historial revisable de los cambios; qabot los prueba y los despliega. Juntos cierran el ciclo: decides, se registra, se prueba, se despliega, y el resultado vuelve al historial.

Guía paso a paso de la instalación conjunta: INSTALACION-CONJUNTA.md.

Si code-timeline está en el PATH y el repositorio está vinculado allí, cada qabot ciclo deja constancia del veredicto. No es una dependencia: si no está instalado, qabot no se entera ni cambia de comportamiento. Ninguno de los dos necesita al otro para funcionar.

code-timeline qa --listar    # los ciclos registrados de este proyecto

Lo que todavía no está

qabot generar y qabot revisar (las pruebas que escribe el modelo local) solo funcionan en proyectos Apps Script. En Cloud Run las sondas se escriben a mano en qa/probes.mjs.

qabot generar y qabot revisar tampoco aplican al tipo generico: ahí las pruebas son las del propio proyecto, no unas que escriba un modelo.

Licencia

Apache 2.0 + Commons Clause — ver LICENSE. Úsalo para lo que quieras, también en tu empresa; lo único que no puedes es venderlo. No es open source según la OSI, porque restringe el uso.

About

Arnés de QA y despliegue para la línea de comandos, y servidor MCP para agentes. Detecta deriva contra lo realmente desplegado.

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages