Skip to main content
Glama

gitl

Action self-test

Revisor de historial de git con IA para CLI y CI. gitl (git-log-lens) lee el historial de git de un repositorio y lo convierte en un artefacto de ingeniería estructurado mediante LLM:

  • gitl review <rango> — Revisión con IA de un rango de commits / PR con puntuación de riesgo legible por máquina (low|medium|high) para control de CI (--fail-on=high → código de salida 2); transmite tokens al terminal en tiempo real; caché de respuestas LLM en disco con una caché remota compartida opcional para CI; plantillas de prompt de sistema personalizadas; --staged revisa los cambios en el área de preparación (sin commit) antes de git commit (también disponible como hook de pre-commit).

  • gitl changelog [<rango>] — Mantén un changelog estilo Keep a Changelog, agrupado por commits convencionales (por defecto, última etiqueta → HEAD); determinista por defecto, --ai opcionalmente lo reescribe con el modelo como prosa legible de notas de versión;

  • gitl digest [--days=N] [--repos=a,b,c] — resumen de actividad por autor/tema/archivo, incluyendo múltiples repositorios en paralelo; visor TUI interactivo (--tui).

Un binario CLI limpio más un wrapper de GitHub Action — sin servidor, sin base de datos, sin almacenamiento de claves alojado. BYOK (trae tu propia clave) con soporte multi-proveedor: API compatible con OpenAI, Ollama (local/autoalojado), Azure OpenAI, Anthropic nativo (Claude), Google Gemini. Sin telemetría.

Estado: v0.6.2 publicado — los tres comandos funcionan en repositorios reales con los tres formatos de salida (md|text|json). La Action publica revisiones de IA como comentarios fijos en PR y controla según la puntuación de riesgo. Los binarios de lanzamiento están compilados de forma cruzada, firmados con cosign y cubiertos por la procedencia de compilación SLSA L3 (ver VERIFY.md).

Inicio rápido

Requiere Go 1.22+ y git en PATH.

# build
go build ./...

# AI review of a commit range — streams tokens to the terminal in real time
GITL_API_KEY=sk-... go run ./cmd/gitl review HEAD~5..HEAD

# no key = deterministic offline review (heuristic risk, no network call)
go run ./cmd/gitl review HEAD~5..HEAD

# review staged (not yet committed) changes before `git commit`
go run ./cmd/gitl review --staged

# review a GitHub PR by number — requires the `gh` CLI (installed + authenticated);
# resolves base/head via gh, fetches `pull/N/head` locally when needed, and reviews
# the merge-base diff (base...head), same as GitHub shows
go run ./cmd/gitl review pr/42

# machine-readable output for CI + risk gating
go run ./cmd/gitl review HEAD~5..HEAD --format=json
go run ./cmd/gitl review HEAD~5..HEAD --fail-on=high   # exit code 2 on high risk
# exit codes: 0 = ok (risk below --fail-on), 1 = tool/runtime error (git/LLM/
# config failure), 2 = the --fail-on risk gate triggered — CI can branch on 2

# estimate cost without making an API call
go run ./cmd/gitl review HEAD~5..HEAD --dry-run

# custom system-prompt template (e.g. your team's review policy) — set via
# config only (prompt.system_template_file); there is no --system-template flag
# see Configuration → Custom templates below

# skip the on-disk LLM cache (always call the model)
go run ./cmd/gitl review HEAD~5..HEAD --no-cache

# disable streaming (non-interactive, buffered output)
go run ./cmd/gitl review HEAD~5..HEAD --no-stream

# suppress the informational offline-mode notice on stderr (errors and the
# review output are unaffected) — also via GITL_QUIET=1 or output.quiet: true
go run ./cmd/gitl review HEAD~5..HEAD --quiet

# changelog from last tag (or full history if no tags) — no LLM by default
go run ./cmd/gitl changelog
go run ./cmd/gitl changelog v1.2.0..HEAD --format=json

# AI changelog: the model rewrites the grouped result as release-note prose and
# reclassifies significant non-conventional commits out of "Other". Without an API
# key (or on a malformed model response) it falls back to the deterministic
# changelog with a warning — never fails. --dry-run/--max-cost-usd/--no-cache work
# the same as for review.
GITL_API_KEY=sk-... go run ./cmd/gitl changelog --ai

# activity summary for the last N days — no LLM
go run ./cmd/gitl digest --days=14

# multi-repo digest: runs in parallel; one unreachable repo does not fail the rest
go run ./cmd/gitl digest --repos=../service-a,../service-b --format=json

# interactive TUI viewer for digest (requires a TTY)
go run ./cmd/gitl digest --days=14 --tui

go run ./cmd/gitl version
go run ./cmd/gitl --help

# tests
go test ./...

Instalar:

# Go toolchain
go install github.com/akomyagin/gitl/cmd/gitl@latest

# Homebrew (macOS/Linux)
brew install akomyagin/tap/gitl

# npm — downloads the prebuilt binary for your platform from GitHub Releases
# and verifies its SHA256 checksum (no Go toolchain needed).
npx gitl-cli review HEAD~5..HEAD   # or: npm install -g gitl-cli

# Or download a signed release binary from GitHub Releases (see VERIFY.md)

Completado de shell

gitl incluye completados generados por cobra para bash, zsh, fish y PowerShell.

Homebrew instala los completados de bash/zsh/fish automáticamente (los archivos de lanzamiento también los incluyen en completions/). De lo contrario, actívalos bajo demanda:

# bash (current shell)
source <(gitl completion bash)
# bash (persistent) — Linux
gitl completion bash > /etc/bash_completion.d/gitl
# zsh (persistent)
gitl completion zsh > "${fpath[1]}/_gitl"
# fish
gitl completion fish > ~/.config/fish/completions/gitl.fish
# PowerShell
gitl completion powershell | Out-String | Invoke-Expression

Las banderas con conjuntos de valores fijos — --format (md|text|json), --fail-on (never|low|medium|high) y --provider — completan sus valores permitidos.

Prueba local multi-proveedor (Ollama)

docker-compose.yml inicia solo la dependencia de desarrollo — una instancia local de Ollama para probar el cliente LLM multi-proveedor (gitl en sí no está contenedorizado):

docker compose up ollama

Related MCP server: grippy-code-review

Configuración

La vía rápida: gitl init escribe un .gitl.yaml de inicio comentado en la raíz del repositorio (se niega a sobrescribir uno existente sin --force; --output escribe en otro lugar). Edítalo en lugar de copiar y pegar de esta sección — el resto a continuación es la referencia completa.

Dos niveles, fusionados por prioridad: bandera > env > .gitl.yaml (repo) > ~/.config/gitl/config.yaml (personal). El .gitl.yaml a nivel de repositorio se confirma como política de equipo compartida (umbral de riesgo, rutas excluidas, categorías de changelog). Sin una clave, gitl se ejecuta en modo offline determinista.

En modo offline — o cuando un modelo real omite un bloque de riesgo válido y gitl recurre a la heurística — el encabezado de riesgo se anota con *(heurístico)* (y "heuristic": true en --format=json), de modo que una puntuación determinista nunca se confunde con el propio juicio del modelo.

Proveedores (llm.provider)

# OpenAI-compatible API (default)
llm:
  provider: "openai"
  api_key: ""            # or env GITL_API_KEY
  base_url: "https://api.openai.com/v1"
  model: "gpt-4o-mini"

# Ollama — local/self-hosted, no key, free
llm:
  provider: "ollama"
  base_url: "http://localhost:11434/v1"
  model: "llama3.1"

# Azure OpenAI — custom auth/endpoint format
llm:
  provider: "azure_openai"
  api_key: ""             # or env GITL_API_KEY
  model: "gpt-4o-mini"    # used only for cost estimation
  azure_openai:
    endpoint: "https://<resource>.openai.azure.com"
    deployment: "<deployment-name>"
    api_version: "2024-08-01-preview"

# Anthropic (native Claude Messages API)
llm:
  provider: "anthropic"
  api_key: ""            # or env GITL_API_KEY
  model: "claude-sonnet-4-6"
  # base_url optional; defaults to https://api.anthropic.com

# Google Gemini (Google AI Studio)
llm:
  provider: "gemini"
  api_key: ""            # or env GITL_API_KEY
  model: "gemini-2.5-flash"
  # base_url optional; defaults to https://generativelanguage.googleapis.com/v1beta

Transmisión (output.stream)

Al revisar interactivamente (formato md o text en una TTY), gitl transmite tokens al terminal a medida que llegan — sin esperar la respuesta completa. La transmisión está activada por defecto y se desactiva automáticamente en CI (stdout no TTY), con --format=json, y cuando se configura un output.template_file personalizado (la plantilla necesita la respuesta completa, por lo que la revisión se almacena en búfer y se renderiza a través de ella en su lugar).

La transmisión está implementada actualmente solo para el proveedor compatible con OpenAI (openai / ollama / azure_openai). Con el proveedor nativo anthropic o gemini, gitl produce de forma transparente la misma revisión como una única respuesta almacenada en búfer (sin salida token por token) independientemente de output.stream / --no-stream.

output:
  stream: true   # default; set false to always buffer

Desactivar por llamada: gitl review HEAD~5..HEAD --no-stream

Color (output.color)

En un terminal interactivo, gitl review colorea el nivel de riesgo en el encabezado (HIGH rojo, MEDIUM amarillo, LOW verde). El color se desactiva automáticamente cuando stdout no es una TTY (tuberías, registros de CI) y nunca aparece en la salida --format=json. Precedencia, de mayor a menor:

  1. Variable de entorno NO_COLOR establecida (cualquier valor, incluso vacío) — color desactivado (no-color.org);

  2. output.color: false en la configuración (o GITL_OUTPUT_COLOR=false) — color desactivado;

  3. stdout no es una TTY — color desactivado;

  4. de lo contrario — color activado.

output:
  color: true   # default; set false to disable ANSI color

Modo silencioso (output.quiet)

Sin una clave de API, review imprime un aviso informativo "usando revisión offline determinista" en stderr en cada ejecución (y changelog --ai imprime un aviso de respaldo análogo). En contextos conocidos como offline — sobre todo el hook de pre-commit, que se dispara en cada commit — ese banner es ruido. Suprímelo con cualquiera de (cada capa puede activar la supresión de forma independiente):

  1. la bandera --quiet en review / changelog;

  2. la variable de entorno GITL_QUIET establecida (cualquier valor, incluso vacío);

  3. output.quiet: true en la configuración (o GITL_OUTPUT_QUIET=true).

--quiet solo silencia el banner informativo: los errores, la revisión/changelog renderizada en stdout y el control --fail-on nunca se ven afectados.

output:
  quiet: false   # default; set true to suppress the offline notices

Caché de respuestas LLM (cache)

gitl review almacena en caché las respuestas del modelo en disco (SHA-256 de proveedor + modelo + prompt). Los diffs idénticos reutilizan el resultado en caché al instante, sin llamada a API ni costo.

cache:
  enabled: true    # default
  ttl_hours: 24    # entries older than this are ignored

La caché vive en ~/.cache/gitl/review/ (compatible con XDG). Desactivar por llamada: gitl review HEAD~5..HEAD --no-cache

En --format=json cada artefacto de revisión lleva metadatos de ejecución aditivos (schema_version permanece en 1; los consumidores que lo preceden ven el mismo documento más dos claves nuevas):

{
  "duration_ms": 1234,
  "cache": { "hit": true, "tier": "local" }
}
  • duration_ms — tiempo de pared de toda la ejecución de revisión, en milisegundos (un acierto de caché aún informa un número real, generalmente pequeño).

  • cache.hit — si esta revisión se sirvió desde la caché de respuestas LLM en lugar de una llamada al modelo fresca.

  • cache.tier — la topología de caché en efecto para la ejecución: none (modo offline, --no-cache, cache.enabled: false o ttl_hours <= 0), local (solo disco) o tiered (disco + remoto). Informa el modo configurado, no qué backend sirvió un acierto particular.

Deliberadamente no hay un campo usage (conteos de tokens) todavía: gitl no analiza el uso del proveedor de las respuestas, y un campo permanentemente vacío sería peor que uno ausente. Se agregará — de forma aditiva, sin cambio de esquema — cuando llegue el análisis de uso.

Caché remota compartida (cache.remote) — opt-in

Opt-in, desactivada por defecto, trae tu propio backend: gitl nunca aloja un servicio y no hace ninguna solicitud de red a ninguna caché hasta que configures una. Útil para arranques en frío de CI — cada runner comienza con un disco vacío, pero un endpoint HTTP KV compartido permite que un runner reutilice la revisión de otro del mismo diff.

cache:
  enabled: true
  ttl_hours: 24
  remote:                     # opt-in shared cache for CI cold starts (off by default)
    url: https://cache.example.com/gitl   # your endpoint; gitl hosts nothing
    token_env: GITL_REMOTE_CACHE_TOKEN    # env var holding an optional bearer token
    timeout_ms: 3000

Cuando se configura, la caché de disco local sigue siendo el primer nivel: las lecturas verifican el disco, luego el remoto (un acierto remoto se retroalimenta al disco); las escrituras van a ambos.

El protocolo es un almacén de clave-valor simple sobre HTTP — cualquier almacén de objetos estático o manejador pequeño funciona:

  • GET {url}/{key}200 con el cuerpo de la entrada JSON, o 404 = fallo. Cualquier otro estado, error de red o tiempo de espera se trata como un fallo.

  • PUT {url}/{key} con la entrada JSON como cuerpo de la solicitud (Content-Type: application/json) → cualquier 2xx = almacenado.

  • Si token_env nombra una variable de entorno con un valor no vacío, ambas solicitudes llevan Authorization: Bearer <token>. El token en sí nunca se lee de un archivo de configuración (misma disciplina que GITL_API_KEY).

  • Las claves son cadenas hex SHA-256 de 64 caracteres; los valores son opacos para el servidor.

Contrato de seguridad: cualquier fallo remoto (tiempo de espera, 5xx, endpoint inalcanzable) degradará silenciosamente a la caché local / sin caché — nunca falla la revisión. Las entradas almacenadas contienen solo la respuesta del modelo, clave por un hash opaco: ningún diff ni texto de prompt llega a la caché remota. Las entradas más antiguas que ttl_hours se ignoran en el lado del cliente independientemente de lo que devuelva el servidor.

Tendencia de riesgo (policy.risk_log_enabled)

Cada ejecución de gitl review agrega su resultado de riesgo (nivel, rango, proveedor, marca de tiempo) a un registro JSONL local: $XDG_DATA_HOME/gitl/risk-history.jsonl (por defecto ~/.local/share/gitl/risk-history.jsonl; %AppData%\gitl\ en Windows). gitl digest lo lee y muestra una sección **"Tendencia de riesgo (últimos N días)"** por repositorio — conteo de revisiones por nivel, dirección de alto riesgo (mitad reciente vs mitad anterior de la ventana) y las últimas revisiones. En --format=json aparece como un campo opcional risk_trend (schema_version permanece en 1; los consumidores que lo preceden ven el mismo documento que antes). Los repositorios sin historial simplemente omiten la sección.

Las revisiones se correlacionan con un repositorio por su URL remota origin (recurriendo a la ruta del árbol de trabajo cuando no hay origin).

Limitación: el historial es local a tu máquina — no persiste entre runners de CI (cada uno comienza con un disco frío), por lo que la tendencia es una característica para uso local del desarrollador, no para CI.

Opta por no participar en la configuración (sin bandera CLI):

policy:
  risk_log_enabled: false

Plantillas personalizadas (prompt.*_template_file / output.template_file)

Anulaciones independientes, solo de configuración (no hay bandera CLI para ninguna de ellas):

  • prompt.system_template_file — tu propio prompt de sistema de revisión, para dirigir el enfoque del modelo (lista de verificación de seguridad, restricciones de arquitectura, reglas de equipo). Usado solo por gitl review:

    prompt:
      system_template_file: "./review-policy.md"   # path relative to CWD

    La plantilla de prompt de sistema de revisión tiene acceso a {{ .Commits }}, {{ .Diff }}, {{ .Range }}, {{ .Staged }} (ver internal/prompt/templates.go).

  • prompt.changelog_system_template_file — tu propio prompt de sistema de changelog, usado solo por gitl changelog --ai:

    prompt:
      changelog_system_template_file: "./changelog-policy.md"   # path relative to CWD

    La plantilla de prompt de sistema de changelog tiene acceso a {{ .Commits }}, {{ .Range }}, {{ .Grouped }}no {{ .Diff }}: changelog --ai trabaja a partir de metadatos de commits, no hay diff, y una plantilla con forma de revisión que use .Diff fallaría aquí. Es exactamente por eso que las dos claves están separadas: cada comando solo lee su propia clave, y cualquiera puede establecerse sin la otra.

  • output.template_file — tu propia plantilla de renderizado de formato md para el artefacto de revisión terminado:

    output:
      template_file: "./review-output.tmpl"   # path relative to CWD

    La plantilla de salida tiene las funciones de plantilla de renderizado en internal/render/render.go (render.TemplateFuncs()).

Nota de confianza: las claves prompt.*_template_file/output.template_file pueden establecerse mediante un .gitl.yaml a nivel de repositorio, no solo tu configuración personal — por lo que ejecutar gitl review contra un repositorio clonado que no controlas puede apuntarlo a una plantilla dentro de ese mismo repositorio. Este es el mecanismo previsto para la política de revisión compartida de un equipo, no un error: text/template aquí no puede leer archivos arbitrarios ni ejecutar código, pero trata el .gitl.yaml de un repositorio no confiable con la misma precaución que le darías a sus .git/hooks o scripts de compilación.

GitHub Action

gitl se puede conectar como una GitHub Action: revisa con IA los commits de una solicitud de extracción y publica un comentario con la puntuación de riesgo, bloqueando opcionalmente la fusión por encima de un umbral. La Action compila gitl desde el código fuente (go install en una versión fijada). También está listada en el GitHub Marketplace si prefieres agregarla desde allí.

Agrega .github/workflows/gitl-review.yml a tu repositorio:

name: gitl review
on:
  pull_request:

permissions:
  contents: read          # for checkout
  pull-requests: write    # to post the review comment

jobs:
  review:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v7
        with:
          fetch-depth: 0    # required: without full history base..head won't resolve

      - uses: akomyagin/gitl@v0.6.2
        with:
          gitl-api-key: ${{ secrets.GITL_API_KEY }}   # BYOK, see below
          fail-on: high                               # optional: block merge on high risk

Mejores prácticas de seguridad:

  • Clave únicamente mediante secrets.*. gitl-api-key proviene de secrets.GITL_API_KEY (definida en Settings → Secrets and variables → Actions), nunca codificada en el YAML ni confirmada en el repositorio. Si el secreto no está definido, la Action se ejecuta en modo sin conexión determinista (sin red, sin coste).

  • permissions: mínimos. Solo se necesitan pull-requests: write (para publicar el comentario) y contents: read (para el checkout) — no concedas permisos más amplios.

  • fetch-depth: 0 es obligatorio. GitHub proporciona los SHA de base/head en el evento pull_request, pero un clon superficial no puede resolver base.sha..head.sha.

  • fail-on por defecto es never. La Action solo comenta; no bloquea las fusiones a menos que lo actives explícitamente (fail-on: high, etc.) — el mismo principio de "WARN por defecto, bloqueo estricto es una adhesión explícita" que en la CLI (--fail-on). Cuando el bloqueo se activa, el job falla con el código de salida 2 de gitl (bloqueo por riesgo) — un error real de la herramienta falla con 1, de modo que los pasos posteriores pueden distinguir entre "cambio arriesgado" y "gitl se rompió".

  • Privacidad del diff. En CI, el diff se envía al proveedor de LLM que esté configurado (por defecto: API compatible con OpenAI). Para código privado, usa un proveedor autoalojado/empresarial (Ollama, Azure OpenAI) — consulta Providers más arriba.

  • Selección de proveedor. Por defecto la Action usa el proveedor de tu configuración (compatible con OpenAI si no está definido). Para apuntar a un proveedor nativo, pasa provider: (openai|ollama|azure_openai|anthropic|gemini), y opcionalmente model: y base-url:, junto con gitl-api-key:. Los tres son opcionales y, cuando se omiten, recurren a tu .gitl.yaml/configuración personal y a los valores predeterminados integrados de gitl — consulta Providers más arriba. Ejemplo: provider: anthropic con una clave de Claude en secrets.GITL_API_KEY.

  • Enmascaramiento de secretos. GitHub enmascara automáticamente los valores de secrets.* en los registros del runner como ***, pero eso no es motivo para imprimir la clave en tus propios pasos del workflow.

Resumen de riesgo en la descripción del PR (adhesión voluntaria)

Con update-pr-description: true (por defecto false), la Action además mantiene un bloque compacto de resumen de riesgo al final de la descripción del PR — la línea de riesgo más un enlace de vuelta al comentario de revisión completo, actualizado en cada ejecución:

      - uses: akomyagin/gitl@v0.6.2
        with:
          gitl-api-key: ${{ secrets.GITL_API_KEY }}
          update-pr-description: true

Es una adhesión voluntaria porque editar la descripción del PR es más intrusivo que un comentario fijo; no se necesitan permisos adicionales — pull-requests: write, ya requerido para el comentario, también cubre el cuerpo del PR. El bloque está delimitado por el par de marcadores <!-- gitl-review-summary -->, y solo se reemplaza el texto entre los marcadores — todo lo que escribas fuera de ellos nunca se toca. Solo en GitHub por ahora (se ignora en Gitea Actions).

Gitea Actions (experimental)

La misma action.yml también se ejecuta en Gitea Actions — el runner de Gitea ejecuta acciones compuestas de estilo GitHub, y la action de gitl detecta la plataforma en tiempo de ejecución mediante la variable GITEA_ACTIONS=true que el act_runner de Gitea inyecta en cada job. La única parte específica de la plataforma — publicar el comentario fijo del PR — pasa entonces por la API REST de Gitea (POST/PATCH /api/v1/repos/{owner}/{repo}/issues/...) con curl en lugar de la CLI gh, que solo habla con la API de GitHub. Los usuarios de GitHub no se ven afectados: sin GITEA_ACTIONS la action se comporta exactamente igual que antes.

Añade .gitea/workflows/gitl-review.yml a tu repositorio (ejemplo completo comentado: .gitea/workflows/gitl-review.yml en este repositorio):

name: gitl review
on:
  pull_request:

jobs:
  review:
    runs-on: ubuntu-latest
    steps:
      - uses: https://github.com/actions/checkout@v7
        with:
          fetch-depth: 0
      - uses: https://github.com/akomyagin/gitl@v0.6.2
        with:
          gitl-api-key: ${{ secrets.GITL_API_KEY }}   # BYOK; omit for offline mode

Requisitos: Actions habilitadas, un act_runner reciente (compatible con node24) y una imagen de runner que proporcione bash, git, curl, jq y node. GITL_API_KEY se guarda en los secretos de Actions de Gitea, nunca en el YAML — las mismas reglas BYOK que en GitHub.

Estado de verificación — léelo antes de confiar en esto. Las llamadas REST basadas en curl (listar comentarios, crear, parchear, detección de fijado) se probaron contra una instancia real de Gitea (gitea/gitea en Docker) de extremo a extremo — lista vacía → POST-crear → re-listar-la-encuentra → PATCH-actualizar → sigue habiendo exactamente un comentario. Esa parte funciona tal como está escrita. Lo que aún no está verificado es el contexto circundante del CI de act_runner: si GITEA_ACTIONS/GITHUB_API_URL/el payload del evento de PR tienen exactamente el aspecto asumido dentro de una ejecución real de workflow (esto se contrastó con el código fuente de Gitea/ act_runner/act-fork, no se ejecutó dentro de un job real). Trata la ruta de disparo del CI como experimental hasta que alguien confirme una ejecución en verde de extremo a extremo dentro de Gitea Actions real; los informes de errores de instancias reales son muy bienvenidos.

GitLab CI (experimental)

gitl también incluye un componente de CI/CD de GitLabtemplates/gitl-review.yml — que replica la GitHub Action: instala gitl con go install en una versión fijada, revisa el rango del merge request ($CI_MERGE_REQUEST_DIFF_BASE_SHA..$CI_COMMIT_SHA), renderiza el comentario mediante el ci/comment.sh compartido e independiente de la plataforma, y crea/actualiza una nota fija en el MR a través de la API REST de GitLab (el mismo marcador <!-- gitl-review --> que en GitHub/Gitea). El job solo se ejecuta en pipelines de merge request.

El componente está publicado en el Catálogo de CI/CD de GitLab mediante un espejo de este repositorio en el momento del lanzamiento en gitlab.com/alkom68/gitl (unidireccional GitHub → GitLab, publicado en cada etiqueta de lanzamiento). En gitlab.com, inclúyelo como componente de catálogo:

# .gitlab-ci.yml (gitlab.com)
include:
  - component: gitlab.com/alkom68/gitl/gitl-review@v0.6.2
    inputs:
      fail_on: "never"      # default; set "high" to block risky MRs
      # max_cost_usd: "0.50"
      # gitl_version: "v0.6.2"

En una instancia de GitLab autoalojada, include:component solo resuelve componentes de la misma instancia — consume la plantilla mediante include:remote directamente desde GitHub en su lugar (los inputs funcionan con includes remotos):

# .gitlab-ci.yml (self-hosted GitLab)
include:
  - remote: "https://raw.githubusercontent.com/akomyagin/gitl/v0.6.2/templates/gitl-review.yml"
    inputs:
      fail_on: "never"

Configuración — dos variables de CI/CD (Settings → CI/CD → Variables, ambas enmascaradas, nunca en el YAML):

  • GITL_API_KEY — la clave LLM BYOK. Opcional: sin ella gitl ejecuta la revisión sin conexión determinista (sin red, sin coste). Definir la variable de proyecto es suficiente — tiene prioridad sobre el input vacío gitl_api_key del componente. Si usas el input en su lugar, pasa una referencia de variable (gitl_api_key: $MY_LLM_KEY), nunca una clave literal: los valores de los inputs se interpolan en la configuración del pipeline.

  • GITL_GITLAB_TOKEN — token para publicar la nota del MR (token de acceso de proyecto o PAT, ámbito api, rol de Reporter o superior; se envía como PRIVATE-TOKEN). Si no está definido, el job recurre a CI_JOB_TOKEN (cabecera JOB-TOKEN) — pero en la mayoría de las configuraciones de GitLab, CI_JOB_TOKEN no está autorizado para la API de Notes, por lo que se espera que el recurso de reserva falle (con un mensaje de error explícito, no una omisión silenciosa). Un GITL_GITLAB_TOKEN explícito es la vía fiable.

Un pipeline de autoprueba completo comentado — también lo más parecido a un ejemplo de uso completo — es .gitlab-ci-selftest.yml (ejecutable como .gitlab-ci.yml en un espejo de GitLab de este repositorio).

Estado de verificación — léelo antes de confiar en esto. Las llamadas REST de GitLab (listar notas de MR + detección de marcador fijo, POST crear, PUT actualizar) y el propio YAML del componente (interpolación de spec:/inputs:, include:local con inputs, mediante la API de CI Lint) se verificaron de extremo a extremo contra una instancia local real de GitLab CE (gitlab/gitlab-ce 19.2.0 en Docker) en un merge request real — lista vacía → POST-crear → re-listar-la-encuentra → PUT-actualizar → sigue habiendo exactamente una nota — usando los comandos exactos de curl/jq de la plantilla. Lo que aún no está verificado es una ejecución real de pipeline: los valores de CI_MERGE_REQUEST_DIFF_BASE_SHA/CI_COMMIT_SHA/CI_JOB_URL dentro de un pipeline real de merge request están escritos a partir de la documentación de GitLab, no observados, y el rechazo del recurso de reserva CI_JOB_TOKEN está documentado según la documentación de la lista de permitidos de job-token de GitLab, no reproducido. Trata la ruta del pipeline como experimental hasta que alguien confirme una ejecución en verde de extremo a extremo; los informes de errores son bienvenidos.

Nota de confianza. El componente descarga ci/comment.sh del espejo de GitLab (gitlab.com/alkom68/gitl) en gitl_version y lo ejecuta — sin comprobación de checksum/firma, el mismo límite de confianza que la línea go install ...@${gitl_version} justo encima (mismo repositorio, misma ref). Esta descarga ocurre independientemente de cómo se incluya el componente — Catálogo o include:remote — porque un include de componente solo envía la plantilla YAML, no los archivos del repositorio del componente, por lo que la descarga no se puede evitar mecánicamente. Descargar desde la misma instancia de GitLab que publica el componente (en lugar de desde GitHub) mantiene el mismo espacio de nombres/misma ref, un modelo de confianza más honesto que una descarga entre hosts. Si eso importa para tu modelo de amenazas, fija gitl_version a un SHA de commit en lugar de una etiqueta (las etiquetas son movibles).

Bitbucket Pipelines (experimental)

La integración con Bitbucket se distribuye como una Pipe — y las pipes son imágenes de Docker por definición, así que a diferencia de la action de GitHub/Gitea y del componente de GitLab (envoltorios YAML simples) esta es una imagen autocontenida: bitbucket-pipe/Dockerfile compila un binario estático de gitl e incorpora el renderizador compartido ci/comment.sh más el punto de entrada bitbucket-pipe/pipe.sh. La pipe resuelve el rango del PR ($BITBUCKET_PR_DESTINATION_COMMIT..$BITBUCKET_COMMIT), ejecuta gitl review --format=json y crea/actualiza un comentario fijo en el PR mediante la API REST de Bitbucket Cloud (el mismo marcador <!-- gitl-review --> que en las otras plataformas). Referencia de variables: bitbucket-pipe/pipe.yml.

Estado de la imagen. Publicada en Docker Hub como alkom68/gitl-review-pipe desde v0.5.2 — el job docker-publish del workflow de lanzamiento publica :<version> y :latest en cada etiqueta de lanzamiento. Solo existen 0.5.2 y posteriores en el registro: las versiones anteriores son anteriores a la publicación (las etiquetas 0.5.0/0.5.1 nunca se publicaron), así que no las fijes.

# bitbucket-pipelines.yml
pipelines:
  pull-requests:
    '**':
      - step:
          name: gitl review
          clone:
            depth: full   # the default depth-50 clone may not contain the PR base commit
          script:
            - pipe: docker://alkom68/gitl-review-pipe:0.6.2
              variables:
                GITL_API_KEY: $GITL_API_KEY                    # BYOK; omit for offline review
                GITL_BITBUCKET_TOKEN: $GITL_BITBUCKET_TOKEN    # posts the PR comment
                # FAIL_ON: "high"        # default "never" — comment only, no gate
                # MAX_COST_USD: "0.50"

Configuración — dos variables seguras de repositorio/espacio de trabajo (Repository settings → Pipelines → Repository variables; siempre referenciadas como $VAR, nunca valores literales en el YAML):

  • GITL_API_KEY — la clave LLM BYOK. Opcional: sin ella gitl ejecuta la revisión sin conexión determinista (sin red, sin coste).

  • GITL_BITBUCKET_TOKEN — credencial para publicar el comentario del PR: un token de acceso de repositorio/proyecto/espacio de trabajo con el ámbito pullrequest:write, enviado como Authorization: Bearer. Alternativa: define GITL_BITBUCKET_USER + GITL_BITBUCKET_APP_PASSWORD (contraseña de aplicación con pullrequest:write) para autenticación Basic en su lugar. Si no se configura ninguna, la pipe falla rápidamente con un mensaje explícito — antes de gastar cualquier presupuesto de LLM.

Nota sobre la cadena de suministro (por qué esto difiere del componente de GitLab). La pipe no ejecuta nada descargado en tiempo de ejecución: el binario gitl, ci/comment.sh y el punto de entrada están todos integrados en la imagen versionada desde un único árbol fuente. El componente de GitLab tiene que descargar ci/comment.sh a través de la red sin comprobación de integridad (consulta su nota de confianza más arriba); la pipe cierra esa brecha por construcción.

Estado de verificación: léelo antes de confiar en esto. La compilación de la imagen y el flujo completo dentro del contenedor se verificaron localmente: docker build desde este repositorio, y luego docker run contra un repositorio git de prueba real con variables BITBUCKET_* emuladas — revisión offline → comment.md adhesivo correcto → creación de comentario (POST), actualización adhesiva (PUT, sigue habiendo exactamente un comentario) y propagación del código de salida de --fail-on, probado de extremo a extremo contra un mock local de la API de comentarios de Bitbucket; también se probaron en el contenedor las rutas de fallo rápido (variables de credencial/PR ausentes) y el aviso de respaldo en un rango inválido. Lo que aún no está verificado: todo lo que toca la infraestructura real de Bitbucket — las llamadas REST contra api.bitbucket.org (las formas se tomaron de la documentación de la API de Atlassian), las variables predefinidas exactas dentro de un pipeline de PR en vivo (BITBUCKET_PR_DESTINATION_COMMIT etc. son suposiciones documentadas, no valores observados), y cómo Pipelines monta el clon en los contenedores de pipe. Trata la ruta de pipeline en vivo como experimental hasta que alguien confirme una ejecución exitosa en un workspace real de Bitbucket; se agradecen los informes de errores.

Hook de pre-commit (local)

gitl incluye un hook del framework pre-commit para que gitl review --staged --quiet se ejecute automáticamente antes de cada commit — localmente, offline y sin coste por defecto (--quiet está activado por defecto en el manifiesto del hook para que el aviso offline no se reimprima en cada commit).

Añade a tu .pre-commit-config.yaml del repositorio:

repos:
  - repo: https://github.com/akomyagin/gitl
    rev: v0.6.2   # pin to a released tag
    hooks:
      - id: gitl-review

y luego ejecuta pre-commit install. El framework compila el binario de gitl por sí mismo (language: golang) y guarda en caché el entorno en ~/.cache/pre-commit/, de modo que el coste de compilación se paga una sola vez, no en cada commit.

Para optar por un hook bloqueante con un límite de coste:

hooks:
  - id: gitl-review
    args: [--fail-on=high, --max-cost-usd=0.05]   # opt-in: block on high risk, cap cost

Exporta GITL_API_KEY en tu entorno para una revisión real de IA; sin ella, el hook realiza la revisión offline determinista (sin red, sin coste).

Cosas que debes saber:

  • Offline por defecto. Sin clave de API, sin red, sin coste por commit. Establece GITL_API_KEY para optar por una revisión real de IA.

  • No bloqueante por defecto. El hook imprime la revisión pero no hace fallar el commit — el mismo principio de "WARN por defecto, bloqueo estricto es opt-in explícito" que la CLI/Acción. Añade args: [--fail-on=high] para bloquear.

  • Latencia. Una revisión con API real tarda unos segundos; mantenla fuera de la ruta crítica dejándola offline, o limítala con --max-cost-usd.

  • Privacidad del diff. Con una clave real, el diff en staged va a tu proveedor de LLM configurado — usa un proveedor autoalojado/empresarial (Ollama, Azure OpenAI) para código privado; consulta Proveedores arriba.

  • Suprimir el aviso offline. El manifiesto pasa --quiet por defecto, de modo que el aviso por stderr de "usando revisión offline determinista" por commit queda silenciado; el mismo interruptor está disponible en review/changelog como --quiet / GITL_QUIET, o en todo el repositorio mediante output.quiet: true (el servidor MCP solo respeta output.quiet/GITL_OUTPUT_QUIET — no tiene flags, así que el alias corto GITL_QUIET no aplica allí). Los errores y la propia salida de la revisión no se ven afectados.

Sin el framework pre-commit

Un hook git simple también funciona:

# .git/hooks/pre-commit  (chmod +x)
#!/usr/bin/env bash
set -euo pipefail
# Offline, non-blocking review of staged changes (WARN by default); --quiet
# suppresses the per-commit offline notice on stderr.
gitl review --staged --quiet || true
# To block the commit on high risk instead, replace the line above with:
#   gitl review --staged --quiet --fail-on=high

Servidor MCP

gitl mcp ejecuta gitl como un servidor stdio de Model Context Protocol — un canal adicional y separado del uso CLI/CI anterior, para usar gitl de forma interactiva dentro de una sesión de agente (Claude Desktop, Cursor, Windsurf, etc.) en lugar de invocarlo desde la shell. Expone dos herramientas:

  • gitl_review — el mismo motor de revisión que gitl review: range/pr/staged (exactamente uno), con override opcional de model por llamada. El proveedor y el endpoint se fijan en el arranque del servidor por diseño: quien llama a la herramienta es un agente de IA, que puede ser manipulado mediante inyección de prompts dentro del contenido revisado — un base_url por llamada permitiría que un commit malicioso redirigiera la solicitud y filtrara la clave de API real. Siempre devuelve el artefacto JSON estructurado (sin renderizado md/text, sin streaming — el resultado de una herramienta es atómico). risk.level se devuelve como dato; no hay --fail-on en modo MCP porque no hay código de salida de proceso que controlar.

  • gitl_digest — igual que gitl digest: days (por defecto 7), repos opcional. Sin un argumento repos explícito, la herramienta solo procesa el directorio de trabajo del servidor (más digest.repos de .gitl.yaml, si está configurado) — nunca recorre rutas arbitrarias por iniciativa propia. Un argumento repos explícito se respeta tal cual (el agente que llama ya tiene acceso al sistema de archivos a través de sus propias herramientas; esto no es un límite de control de acceso, solo un valor por defecto de "no sorprender al usuario").

Añade a la configuración de tu cliente MCP (Claude Desktop, Cursor, etc.):

{
  "mcpServers": {
    "gitl": {
      "command": "gitl",
      "args": ["mcp"]
    }
  }
}

La configuración se carga una sola vez al arrancar, igual que con los comandos normales (.gitl.yaml + config personal + variables de entorno GITL_*, desde el directorio en el que se lanza gitl mcp). Sin clave, las llamadas a las herramientas se ejecutan en el mismo modo offline determinista que la CLI. stdout está reservado para el protocolo MCP — nunca se escribe nada legible para humanos allí; las advertencias van a stderr.

Licencia

MIT.

Tool Schema Changelog

Recent tool additions, removals, and schema changes observed during successful MCP inspections. Dates show when Glama detected each change.

No tool schema history has been recorded yet.

Maintenance

ActivityMaintained
ResponsivenessNo issues

Related MCP Connectors

Related MCP Servers

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/akomyagin/gitl'

If you have feedback or need assistance with the MCP directory API, please join our Discord server