gitl
gitl
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;--stagedrevisa los cambios en el área de preparación (sin commit) antes degit 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,--aiopcionalmente 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.2publicado — 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-ExpressionLas 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 ollamaRelated 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/v1betaTransmisió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 bufferDesactivar 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:
Variable de entorno
NO_COLORestablecida (cualquier valor, incluso vacío) — color desactivado (no-color.org);output.color: falseen la configuración (oGITL_OUTPUT_COLOR=false) — color desactivado;stdout no es una TTY — color desactivado;
de lo contrario — color activado.
output:
color: true # default; set false to disable ANSI colorModo 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):
la bandera
--quietenreview/changelog;la variable de entorno
GITL_QUIETestablecida (cualquier valor, incluso vacío);output.quiet: trueen la configuración (oGITL_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 noticesCaché 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 ignoredLa 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: falseottl_hours <= 0),local(solo disco) otiered(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: 3000Cuando 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}→200con el cuerpo de la entrada JSON, o404= 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) → cualquier2xx= almacenado.Si
token_envnombra una variable de entorno con un valor no vacío, ambas solicitudes llevanAuthorization: Bearer <token>. El token en sí nunca se lee de un archivo de configuración (misma disciplina queGITL_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: falsePlantillas 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 porgitl review:prompt: system_template_file: "./review-policy.md" # path relative to CWDLa plantilla de prompt de sistema de revisión tiene acceso a
{{ .Commits }},{{ .Diff }},{{ .Range }},{{ .Staged }}(verinternal/prompt/templates.go).prompt.changelog_system_template_file— tu propio prompt de sistema de changelog, usado solo porgitl changelog --ai:prompt: changelog_system_template_file: "./changelog-policy.md" # path relative to CWDLa plantilla de prompt de sistema de changelog tiene acceso a
{{ .Commits }},{{ .Range }},{{ .Grouped }}— no{{ .Diff }}:changelog --aitrabaja a partir de metadatos de commits, no hay diff, y una plantilla con forma de revisión que use.Difffallarí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 formatomdpara el artefacto de revisión terminado:output: template_file: "./review-output.tmpl" # path relative to CWDLa 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_filepueden establecerse mediante un.gitl.yamla nivel de repositorio, no solo tu configuración personal — por lo que ejecutargitl reviewcontra 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/templateaquí no puede leer archivos arbitrarios ni ejecutar código, pero trata el.gitl.yamlde un repositorio no confiable con la misma precaución que le darías a sus.git/hookso 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 riskMejores prácticas de seguridad:
Clave únicamente mediante
secrets.*.gitl-api-keyproviene desecrets.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 necesitanpull-requests: write(para publicar el comentario) ycontents: read(para el checkout) — no concedas permisos más amplios.fetch-depth: 0es obligatorio. GitHub proporciona los SHA debase/headen el eventopull_request, pero un clon superficial no puede resolverbase.sha..head.sha.fail-onpor defecto esnever. 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 salida2de gitl (bloqueo por riesgo) — un error real de la herramienta falla con1, 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 opcionalmentemodel:ybase-url:, junto congitl-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: anthropiccon una clave de Claude ensecrets.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: trueEs 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 modeRequisitos: 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/giteaen 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 deact_runner: siGITEA_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 GitLab —
templates/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íogitl_api_keydel 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, ámbitoapi, rol de Reporter o superior; se envía comoPRIVATE-TOKEN). Si no está definido, el job recurre aCI_JOB_TOKEN(cabeceraJOB-TOKEN) — pero en la mayoría de las configuraciones de GitLab,CI_JOB_TOKENno 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). UnGITL_GITLAB_TOKENexplí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,
POSTcrear,PUTactualizar) y el propio YAML del componente (interpolación despec:/inputs:,include:localcon inputs, mediante la API de CI Lint) se verificaron de extremo a extremo contra una instancia local real de GitLab CE (gitlab/gitlab-ce19.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 decurl/jqde la plantilla. Lo que aún no está verificado es una ejecución real de pipeline: los valores deCI_MERGE_REQUEST_DIFF_BASE_SHA/CI_COMMIT_SHA/CI_JOB_URLdentro 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 reservaCI_JOB_TOKENestá 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.shdel espejo de GitLab (gitlab.com/alkom68/gitl) engitl_versiony lo ejecuta — sin comprobación de checksum/firma, el mismo límite de confianza que la líneago install ...@${gitl_version}justo encima (mismo repositorio, misma ref). Esta descarga ocurre independientemente de cómo se incluya el componente — Catálogo oinclude: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, fijagitl_versiona 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-pipedesdev0.5.2— el jobdocker-publishdel workflow de lanzamiento publica:<version>y:latesten cada etiqueta de lanzamiento. Solo existen0.5.2y posteriores en el registro: las versiones anteriores son anteriores a la publicación (las etiquetas0.5.0/0.5.1nunca 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 ámbitopullrequest:write, enviado comoAuthorization: Bearer. Alternativa: defineGITL_BITBUCKET_USER+GITL_BITBUCKET_APP_PASSWORD(contraseña de aplicación conpullrequest: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.shy el punto de entrada están todos integrados en la imagen versionada desde un único árbol fuente. El componente de GitLab tiene que descargarci/comment.sha 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 builddesde este repositorio, y luegodocker runcontra un repositorio git de prueba real con variablesBITBUCKET_*emuladas — revisión offline →comment.mdadhesivo 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_COMMITetc. 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-reviewy 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 costExporta 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_KEYpara 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
--quietpor defecto, de modo que el aviso por stderr de "usando revisión offline determinista" por commit queda silenciado; el mismo interruptor está disponible enreview/changelogcomo--quiet/GITL_QUIET, o en todo el repositorio medianteoutput.quiet: true(el servidor MCP solo respetaoutput.quiet/GITL_OUTPUT_QUIET— no tiene flags, así que el alias cortoGITL_QUIETno 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=highServidor 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 quegitl review:range/pr/staged(exactamente uno), con override opcional demodelpor 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 — unbase_urlpor 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.levelse devuelve como dato; no hay--fail-onen modo MCP porque no hay código de salida de proceso que controlar.gitl_digest— igual quegitl digest:days(por defecto 7),reposopcional. Sin un argumentoreposexplícito, la herramienta solo procesa el directorio de trabajo del servidor (másdigest.reposde.gitl.yaml, si está configurado) — nunca recorre rutas arbitrarias por iniciativa propia. Un argumentoreposexplí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.
This server cannot be installed
Maintenance
Related MCP Connectors
AI-native git hosting — repos, PRs, issues, CI gates, and AI code review over MCP (60 tools).
Zero-secret MCP gateway for AI agents: risk-scored, audited calls with human-in-the-loop approval.
Zero-config MCP security scanner for AI-generated apps. 25K+ vulnerability patterns.
MCP server for secureFlows: token-free URL builders and integration-linting tools for AI agents.
Related MCP Servers
- AlicenseAqualityBmaintenanceA local Git intelligence MCP server that provides deep repository analytics including hotspots, temporal coupling, knowledge maps, churn analysis, and risk scoring for AI agents.1212MIT
- AlicenseNot gradedqualityCmaintenanceOpen-source AI code review MCP server for local git diff auditing with deterministic security rules and AI-powered analysis using any OpenAI-compatible model.4MIT
- AlicenseNot gradedqualityBmaintenanceMCP server for automated code review using AI agents. It analyzes code diffs or file paths for bugs, security issues, and style violations.MIT
- AlicenseNot gradedqualityCmaintenanceMCP server for AI code provenance, enabling traceability of file changes to AI agents, sessions, and prompts, plus reporting on AI-generated code activity.11MIT
Latest Blog Posts
- Who's Calling? MCP Hosts Are an Identity Blind Spot (And the Spec Knows It)By Om-Shree-0709 on .mcpAgent IdentityOAuth 2.1
- Your AI Chatbot Just Exposed Your CEO's Salary to an InternBy Om-Shree-0709 on .Agent IdentityMCP SecurityOAuth Delegation
- Why MCP Servers Need Execution Sandboxing (And Why Your Current Stack Isn't Enough)By Om-Shree-0709 on .Agentic AiPrompt InjectionWebAssembly
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