gitl
gitl
ИИ-ревьюер истории git для CLI и CI. gitl (git-log-lens) читает историю git репозитория и превращает её в структурированный инженерный артефакт с помощью LLM:
gitl review <range>— ИИ-ревью диапазона коммитов / PR с машиночитаемой оценкой риска (low|medium|high) для гейтинга в CI (--fail-on=high→ код выхода 2); потоковая передача токенов в терминал в реальном времени; кэш ответов LLM на диске с опциональным общим удалённым кэшем для CI; пользовательские шаблоны системного промпта;--stagedревьюит staged (незакоммиченные) изменения передgit commit(также доступно как pre-commit hook).gitl changelog [<range>]— журнал изменений в стиле Keep a Changelog, сгруппированный по conventional commits (по умолчанию от последнего тега доHEAD); детерминированный по умолчанию,--aiопционально переписывает его моделью в читаемый текст релиз-ноутов;gitl digest [--days=N] [--repos=a,b,c]— сводка активности по автору/теме/файлу, включая несколько репозиториев параллельно; интерактивный TUI-просмотрщик (--tui).
Чистый CLI-бинарник плюс обёртка для GitHub Action — без сервера, без базы данных, без хостинга ключей. BYOK (принеси свой ключ) с поддержкой нескольких провайдеров: OpenAI-совместимый API, Ollama (локальный/самохостинг), Azure OpenAI, нативный Anthropic (Claude), Google Gemini. Без телеметрии.
Статус: выпущена
v0.6.2— все три команды работают на реальных репозиториях со всеми тремя форматами вывода (md|text|json). Action публикует ИИ-ревью как закреплённые комментарии к PR и гейтит по оценке риска. Релизные бинарники кросс-скомпилированы, подписаны cosign и покрыты SLSA L3 provenance сборки (см. VERIFY.md).
Быстрый старт
Требуется Go 1.22+ и git в 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 ./...Установка:
# 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)Дополнения для оболочки
gitl поставляет сгенерированные cobra дополнения для bash, zsh, fish и PowerShell.
Homebrew устанавливает дополнения для bash/zsh/fish автоматически (релизные архивы также содержат их в completions/). В противном случае включите их по требованию:
# 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Флаги с фиксированными наборами значений — --format (md|text|json), --fail-on (never|low|medium|high) и --provider — дополняют свои допустимые значения.
Локальный тест с несколькими провайдерами (Ollama)
docker-compose.yml запускает только dev-зависимость — локальный экземпляр Ollama для тестирования мультипровайдерного LLM-клиента (gitl сам не контейнеризирован):
docker compose up ollamaRelated MCP server: grippy-code-review
Конфигурация
Быстрый путь: gitl init записывает стартовый .gitl.yaml с комментариями в корень репозитория (отказываясь перезаписывать существующий без --force; --output записывает в другое место). Отредактируйте его вместо копирования из этого раздела — остальное ниже является полным справочником.
Два уровня, объединяются по приоритету:
флаг > env > .gitl.yaml (репозиторий) > ~/.config/gitl/config.yaml (личный).
Репозиторный .gitl.yaml коммитится как общая командная политика (порог риска, исключённые пути, категории журнала изменений). Без ключа gitl работает в детерминированном офлайн-режиме.
В офлайн-режиме — или когда реальная модель пропускает валидный блок риска и gitl откатывается к эвристике — заголовок риска помечается *(heuristic)* (и "heuristic": true в --format=json), чтобы детерминированная оценка никогда не принималась за собственное суждение модели.
Провайдеры (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Потоковая передача (output.stream)
При интерактивном ревью (md или text формат на TTY) gitl передаёт токены в терминал по мере их поступления — без ожидания полного ответа. Потоковая передача включена по умолчанию и автоматически отключается в CI (stdout не TTY), при --format=json и при настройке пользовательского output.template_file (шаблону нужен полный ответ, поэтому ревью буферизуется и рендерится через него).
Потоковая передача в настоящее время реализована только для OpenAI-совместимого провайдера (openai / ollama / azure_openai). С нативным провайдером anthropic или gemini gitl прозрачно выдаёт то же ревью как единый буферизованный ответ (без посимвольного вывода) независимо от output.stream / --no-stream.
output:
stream: true # default; set false to always bufferОтключить для одного вызова: gitl review HEAD~5..HEAD --no-stream
Цвет (output.color)
На интерактивном терминале gitl review раскрашивает уровень риска в заголовке (HIGH красным, MEDIUM жёлтым, LOW зелёным). Цвет автоматически отключается, когда stdout не является TTY (пайпы, логи CI), и никогда не появляется в выводе --format=json. Приоритет, от высшего к низшему:
Установлена переменная окружения
NO_COLOR(любое значение, даже пустое) — цвет выключен (no-color.org);output.color: falseв конфиге (илиGITL_OUTPUT_COLOR=false) — цвет выключен;stdout не является TTY — цвет выключен;
в противном случае — цвет включён.
output:
color: true # default; set false to disable ANSI colorТихий режим (output.quiet)
Без API-ключа review выводит информационное уведомление "using deterministic offline review" в stderr при каждом запуске (а changelog --ai выводит аналогичное уведомление об откате). В заведомо офлайн-контекстах — особенно в pre-commit hook, который срабатывает при каждом коммите — этот баннер является шумом. Подавите его любым из способов (каждый слой может независимо включить подавление):
флаг
--quietдляreview/changelog;установленная переменная окружения
GITL_QUIET(любое значение, даже пустое);output.quiet: trueв конфиге (илиGITL_OUTPUT_QUIET=true).
--quiet подавляет только информационный баннер: ошибки, отрендеренное ревью/журнал изменений на stdout и гейт --fail-on никогда не затрагиваются.
output:
quiet: false # default; set true to suppress the offline noticesКэш ответов LLM (cache)
gitl review кэширует ответы модели на диске (SHA-256 от провайдера + модели + промпта). Идентичные диффы мгновенно используют кэшированный результат без вызова API и затрат.
cache:
enabled: true # default
ttl_hours: 24 # entries older than this are ignoredКэш хранится в ~/.cache/gitl/review/ (совместимо с XDG). Отключить для одного вызова: gitl review HEAD~5..HEAD --no-cache
В --format=json каждый артефакт ревью несёт аддитивные метаданные запуска (schema_version остаётся 1; потребители, созданные до этого, видят тот же документ плюс два новых ключа):
{
"duration_ms": 1234,
"cache": { "hit": true, "tier": "local" }
}duration_ms— время всего запуска ревью в миллисекундах (попадание в кэш всё равно сообщает реальное, обычно крошечное число).cache.hit— было ли это ревью обслужено из кэша ответов LLM вместо свежего вызова модели.cache.tier— топология кэша, действующая для запуска:none(офлайн-режим,--no-cache,cache.enabled: falseилиttl_hours <= 0),local(только диск) илиtiered(диск + удалённый). Сообщает сконфигурированный режим, а не то, какой бэкенд обслужил конкретное попадание.
Намеренно нет поля usage (количество токенов): gitl не парсит использование провайдера из ответов, и постоянно пустое поле было бы хуже, чем отсутствующее. Оно будет добавлено — аддитивно, без изменения схемы — когда появится парсинг использования.
Общий удалённый кэш (cache.remote) — opt-in
Opt-in, выключен по умолчанию, BYO-бэкенд: gitl никогда не хостит сервис и не делает сетевых запросов к какому-либо кэшу, пока вы его не настроите. Полезно для холодных стартов CI — каждый раннер начинает с пустого диска, но общая HTTP KV-конечная точка позволяет одному раннеру переиспользовать ревью другого для того же диффа.
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При настройке локальный дисковый кэш остаётся первым уровнем: чтение проверяет диск, затем удалённый (попадание в удалённый кэш записывается на диск); запись идёт в оба.
Протокол — простое хранилище ключ-значение по HTTP — подойдёт любой статический объектный стор или крошечный обработчик:
GET {url}/{key}→200с телом JSON-записи, или404= промах. Любой другой статус, сетевая ошибка или таймаут считаются промахом.PUT {url}/{key}с JSON-записью в теле запроса (Content-Type: application/json) → любой2xx= сохранено.Если
token_envуказывает на переменную окружения с непустым значением, оба запроса несутAuthorization: Bearer <token>. Сам токен никогда не читается из файла конфигурации (та же дисциплина, что иGITL_API_KEY).Ключи — 64-символьные hex-строки SHA-256; значения непрозрачны для сервера.
Контракт безопасности: любой удалённый сбой (таймаут, 5xx, недоступная конечная точка) молча деградирует до локального кэша / без кэша — он никогда не приводит к сбою ревью. Хранимые записи содержат только ответ модели, ключ — непрозрачный хэш: ни дифф, ни текст промпта никогда не попадают в удалённый кэш. Записи старше ttl_hours игнорируются на стороне клиента независимо от того, что возвращает сервер.
Тренд риска (policy.risk_log_enabled)
Каждый запуск gitl review добавляет свой результат риска (уровень, диапазон, провайдер, временная метка) в локальный JSONL-лог: $XDG_DATA_HOME/gitl/risk-history.jsonl (по умолчанию ~/.local/share/gitl/risk-history.jsonl; %AppData%\gitl\ на Windows). gitl digest читает его и показывает секцию **"Risk trend (last N days)"** для каждого репозитория — количество ревью по уровням, направление высокого риска (последняя половина окна против более ранней) и последние несколько ревью. В --format=json это появляется как опциональное поле risk_trend (schema_version остаётся 1; потребители, созданные до этого, видят тот же документ, что и раньше). Репозитории без истории просто опускают секцию.
Ревью соотносятся с репозиторием по URL удалённого origin (при отсутствии origin — по пути рабочей копии).
Ограничение: история локальна для вашей машины — она не сохраняется между раннерами CI (каждый начинает с холодного диска), поэтому тренд — это функция для локальной разработки, а не для CI.
Отказ в конфиге (без CLI-флага):
policy:
risk_log_enabled: falseПользовательские шаблоны (prompt.*_template_file / output.template_file)
Независимые переопределения только через конфиг (ни для одного из них нет CLI-флага):
prompt.system_template_file— ваш собственный системный промпт для ревью, чтобы направить фокус модели (чек-лист безопасности, архитектурные ограничения, командные правила). Используется толькоgitl review:prompt: system_template_file: "./review-policy.md" # path relative to CWDШаблон системного промпта ревью имеет доступ к
{{ .Commits }},{{ .Diff }},{{ .Range }},{{ .Staged }}(см.internal/prompt/templates.go).prompt.changelog_system_template_file— ваш собственный системный промпт для журнала изменений, используется толькоgitl changelog --ai:prompt: changelog_system_template_file: "./changelog-policy.md" # path relative to CWDШаблон системного промпта журнала изменений имеет доступ к
{{ .Commits }},{{ .Range }},{{ .Grouped }}— не{{ .Diff }}:changelog --aiработает с метаданными коммитов, диффа нет, и шаблон в форме ревью, использующий.Diff, здесь не сработает. Именно поэтому два ключа раздельны: каждая команда читает только свой ключ, и любой из них может быть установлен без другого.output.template_file— ваш собственный шаблон рендера в форматеmdдля готового артефакта ревью:output: template_file: "./review-output.tmpl" # path relative to CWDШаблон вывода имеет функции рендера из
internal/render/render.go(render.TemplateFuncs()).
Примечание о доверии: ключи
prompt.*_template_file/output.template_fileмогут быть установлены репозиторным.gitl.yaml, а не только вашим личным конфигом — поэтому запускgitl reviewпротив клонированного репозитория, которым вы не управляете, может указать на шаблон внутри того же репозитория. Это предполагаемый механизм для общей командной политики ревью, а не ошибка:text/templateздесь не может читать произвольные файлы или выполнять код, но относитесь к.gitl.yamlнедоверенного репозитория с той же осторожностью, что и к его.git/hooksили скриптам сборки.
GitHub Action
gitl можно подключить как GitHub Action: он ИИ-ревьюит коммиты pull request и публикует комментарий с оценкой риска, опционально блокируя слияние выше порога. Action собирает gitl из исходников (go install на закреплённой версии). Также доступен в GitHub Marketplace, если вы предпочитаете добавить его оттуда.
Добавьте .github/workflows/gitl-review.yml в ваш репозиторий:
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Рекомендации по безопасности:
Ключ — только через
secrets.*.gitl-api-keyберётся изsecrets.GITL_API_KEY(задаётся в Settings → Secrets and variables → Actions) и никогда не захардкожен в YAML и не закоммичен. Если секрет не задан, Action работает в детерминированном offline-режиме (без сети, без затрат).Минимальные
permissions:. Нужны толькоpull-requests: write(для публикации комментария) иcontents: read(для checkout) — не выдавайте более широких прав.fetch-depth: 0обязателен. GitHub предоставляет SHA-хэшиbase/headв событииpull_request, но при shallow-клоне не получится разрешитьbase.sha..head.sha.fail-onпо умолчанию равенnever. Action только оставляет комментарий; он не блокирует merge, если вы явно не включите это (fail-on: highи т. п.) — тот же принцип «WARN по умолчанию, жёсткий гейт — явный opt-in», что и в CLI (--fail-on). Когда гейт срабатывает, job завершается с кодом выхода gitl2(risk gate) — настоящая ошибка инструмента завершается с кодом1, так что downstream-шаги могут отличить «рискованное изменение» от «gitl сломался».Конфиденциальность диффа. В CI дифф отправляется тому LLM-провайдеру, который настроен (по умолчанию: OpenAI-совместимый API). Для приватного кода используйте self-hosted/enterprise-провайдера (Ollama, Azure OpenAI) — см. Providers выше.
Выбор провайдера. По умолчанию Action использует провайдера из вашего конфига (OpenAI-совместимый, если не задан). Чтобы нацелиться на нативного провайдера, передайте
provider:(openai|ollama|azure_openai|anthropic|gemini), и опциональноmodel:иbase-url:, вместе сgitl-api-key:. Все три параметра необязательны и, если опущены, подхватываются из вашего.gitl.yaml/личного конфига и встроенных умолчаний gitl — см. Providers выше. Пример:provider: anthropicс ключом Claude вsecrets.GITL_API_KEY.Маскирование секретов. GitHub автоматически маскирует значения
secrets.*в логах runner'а как***, но это не повод печатать ключ в собственных шагах workflow.
Сводка рисков в описании PR (opt-in)
С update-pr-description: true (по умолчанию false) Action дополнительно поддерживает
компактный блок сводки рисков в конце описания PR — строку риска плюс
ссылку на полный комментарий ревью, обновляемую при каждом запуске:
- uses: akomyagin/gitl@v0.6.2
with:
gitl-api-key: ${{ secrets.GITL_API_KEY }}
update-pr-description: trueЭто opt-in, потому что редактирование описания PR более интрузивно, чем sticky-комментарий;
дополнительные права не нужны — pull-requests: write, уже требуемое для
комментария, покрывает и тело PR. Блок ограничен парой маркеров
<!-- gitl-review-summary -->, и заменяется только текст между маркерами —
всё, что вы пишете вне их, никогда не затрагивается. Пока только для GitHub
(игнорируется в Gitea Actions).
Gitea Actions (экспериментально)
Тот же action.yml работает и в Gitea Actions —
runner Gitea исполняет GitHub-совместимые composite-actions, и action gitl определяет
платформу во время выполнения по переменной GITEA_ACTIONS=true, которую act_runner
Gitea внедряет в каждый job. Единственная платформо-зависимая часть — публикация sticky-комментария
к PR — идёт через REST API Gitea
(POST/PATCH /api/v1/repos/{owner}/{repo}/issues/...) с помощью curl вместо
CLI gh, который говорит только с API GitHub. Пользователи GitHub не затронуты: без
GITEA_ACTIONS action ведёт себя ровно как раньше.
Добавьте .gitea/workflows/gitl-review.yml в ваш репозиторий (полный пример с комментариями:
.gitea/workflows/gitl-review.yml в этом репозитории):
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Требования: включённые Actions, свежий act_runner (с поддержкой node24) и образ runner'а
с bash, git, curl, jq и node. GITL_API_KEY кладётся в
секреты Actions Gitea, никогда в YAML — те же правила BYOK, что и на GitHub.
Статус проверки — прочтите, прежде чем полагаться на это. REST-вызовы на
curl(список комментариев, create, patch, sticky-детекция) были прогнаны против реального инстанса Gitea (gitea/giteaв Docker) end-to-end — list-empty → POST-create → re-list-finds-it → PATCH-update → по-прежнему ровно один комментарий. Эта часть работает как написано. Что ещё не проверено — окружающий CI-контекстact_runner: выглядят лиGITEA_ACTIONS/GITHUB_API_URL/payload события PR ровно так, как предполагается, внутри живого запуска workflow (это сверялось с исходниками Gitea/ act_runner/act-fork, а не прогонялось внутри реального job). Относитесь к CI-триггерному пути как к экспериментальному, пока кто-нибудь не подтвердит зелёный прогон end-to-end в настоящих Gitea Actions; баг-репорты с реальных инстансов очень приветствуются.
GitLab CI (экспериментально)
gitl также поставляет компонент GitLab CI/CD —
templates/gitl-review.yml — зеркало GitHub Action:
он устанавливает gitl через go install на закреплённой версии, ревьюит диапазон
merge request'а ($CI_MERGE_REQUEST_DIFF_BASE_SHA..$CI_COMMIT_SHA), рендерит комментарий через
общий платформо-нейтральный ci/comment.sh и создаёт/обновляет
sticky-заметку MR через REST API GitLab (тот же маркер <!-- gitl-review -->, что и на
GitHub/Gitea). Job выполняется только в пайплайнах merge request.
Компонент опубликован в каталоге GitLab CI/CD
через зеркало этого репозитория, обновляемое при релизах, по адресу
gitlab.com/alkom68/gitl (одностороннее GitHub → GitLab,
пушится на каждый релизный тег). На gitlab.com подключайте его как компонент каталога:
# .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"На self-hosted-инстансе GitLab include:component разрешает компоненты только
с того же инстанса — потребляйте шаблон через include:remote напрямую с
GitHub (inputs работают и с remote-подключением):
# .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"Настройка — две переменные CI/CD (Settings → CI/CD → Variables, обе masked, никогда в YAML):
GITL_API_KEY— BYOK-ключ LLM. Необязателен: без него gitl выполняет детерминированное offline-ревью (без сети, без затрат). Достаточно определить переменную проекта — она имеет приоритет над пустым умолчанием input'аgitl_api_keyкомпонента. Если используете input, передавайте ссылку на переменную (gitl_api_key: $MY_LLM_KEY), никогда не литеральное значение ключа: значения input'ов интерполируются в конфиг пайплайна.GITL_GITLAB_TOKEN— токен для публикации заметки MR (project access token или PAT, скоупapi, роль Reporter или выше; отправляется какPRIVATE-TOKEN). Если не задан, job откатывается наCI_JOB_TOKEN(заголовокJOB-TOKEN) — но в большинстве конфигураций GitLabCI_JOB_TOKENне авторизован для Notes API, так что откат, как ожидается, завершится ошибкой (с явным сообщением, а не тихим пропуском). ЯвныйGITL_GITLAB_TOKEN— надёжный путь.
Полный самопроверочный пайплайн с комментариями — он же ближайший аналог полного примера
использования — это .gitlab-ci-selftest.yml (запускается как
.gitlab-ci.yml в зеркале этого репозитория на GitLab).
Статус проверки — прочтите, прежде чем полагаться на это. REST-вызовы GitLab (список заметок MR + sticky-маркер-детекция,
POSTcreate,PUTupdate) и сам YAML компонента (spec:/inputs:-интерполяция,include:localс inputs, через CI Lint API) были проверены end-to-end против реального локального инстанса GitLab CE (gitlab/gitlab-ce19.2.0 в Docker) на настоящем merge request — list-empty → POST-create → re-list-finds-it → PUT-update → по-прежнему ровно одна заметка — с использованием ровно тех командcurl/jq, что в шаблоне. Что ещё не проверено — живой прогон пайплайна: значенияCI_MERGE_REQUEST_DIFF_BASE_SHA/CI_COMMIT_SHA/CI_JOB_URLвнутри реального пайплайна merge request взяты из документации GitLab, а не наблюдены, а отклонение отката наCI_JOB_TOKENописано по документации GitLab об allowlist job-токенов, а не воспроизведено. Относитесь к пайплайн-пути как к экспериментальному, пока кто-нибудь не подтвердит зелёный end-to-end прогон; баг-репорты приветствуются.
Заметка о доверии. Компонент скачивает
ci/comment.shиз зеркала GitLab (gitlab.com/alkom68/gitl) на версииgitl_versionи исполняет его — без проверки контрольной суммы/подписи, та же граница доверия, что и у строкиgo install ...@${gitl_version}прямо над ней (тот же репозиторий, тот же ref). Эта загрузка происходит независимо от того, как подключён компонент — Catalog илиinclude:remote— потому что подключение компонента доставляет только YAML-шаблон, а не файлы репозитория компонента, так что загрузку нельзя обойти механически. Скачивание с того же инстанса GitLab, который публикует компонент (а не с GitHub), сохраняет тот же namespace/ref — более честная модель доверия, чем кросс-хостовое скачивание. Если это важно для вашей threat model, закрепитеgitl_versionна SHA коммита, а не на теге (теги перемещаемы).
Bitbucket Pipelines (экспериментально)
Интеграция с Bitbucket поставляется как Pipe —
а pipes по определению являются Docker-образами, так что, в отличие от action для GitHub/Gitea и
компонента GitLab (обычные YAML-обёртки), это самодостаточный образ:
bitbucket-pipe/Dockerfile собирает статический бинарник
gitl и встраивает общий рендерер ci/comment.sh плюс
entrypoint bitbucket-pipe/pipe.sh. Pipe вычисляет
диапазон PR ($BITBUCKET_PR_DESTINATION_COMMIT..$BITBUCKET_COMMIT), запускает
gitl review --format=json и создаёт/обновляет sticky-комментарий PR через
REST API Bitbucket Cloud (тот же маркер <!-- gitl-review -->, что и на других
платформах). Справочник переменных: bitbucket-pipe/pipe.yml.
Статус образа. Опубликован на Docker Hub как
alkom68/gitl-review-pipeначиная сv0.5.2— jobdocker-publishрелизного workflow пушит:<version>и:latestна каждый релизный тег. В реестре существуют только0.5.2и новее: более ранние релизы предшествуют публикации (теги0.5.0/0.5.1никогда не пушились), так что не закрепляйте их.
# 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"Настройка — две защищённые переменные репозитория/workspace (Repository settings →
Pipelines → Repository variables; всегда ссылайтесь как $VAR, никогда не литеральными значениями
в YAML):
GITL_API_KEY— BYOK-ключ LLM. Необязателен: без него gitl выполняет детерминированное offline-ревью (без сети, без затрат).GITL_BITBUCKET_TOKEN— учётные данные для публикации комментария PR: access token репозитория/проекта/workspace со скоупомpullrequest:write, отправляемый какAuthorization: Bearer. Альтернатива: задайтеGITL_BITBUCKET_USER+GITL_BITBUCKET_APP_PASSWORD(app password со скоупомpullrequest:write) для Basic-аутентификации. Если не настроено ни то ни другое, pipe быстро завершается с явным сообщением — до траты любого LLM-бюджета.
Заметка о цепочке поставок (почему это отличается от компонента GitLab). Pipe не исполняет ничего, скачанного во время выполнения: бинарник
gitl,ci/comment.shи entrypoint встроены в версионированный образ из одного дерева исходников. Компоненту GitLab приходится скачиватьci/comment.shпо сети без проверки целостности (см. его заметку о доверии выше); pipe закрывает этот пробел по построению.
Статус проверки — прочтите, прежде чем полагаться на это. Сборка образа и полный внутриконтейнерный поток были проверены локально:
docker buildиз этого репозитория, затемdocker runна реальном тестовом git-репозитории с эмулированными переменнымиBITBUCKET_*— офлайн-ревью → корректный stickycomment.md→ создание комментария (POST), sticky-обновление (PUT, по-прежнему ровно один комментарий) и распространение кода выхода--fail-on, проверенные end-to-end на локальном моке API комментариев Bitbucket; fail-fast пути (отсутствующие переменные учётных данных/PR) и запасное уведомление на плохом диапазоне также были проверены в контейнере. Что ещё не проверено: всё, что касается реальной инфраструктуры Bitbucket — REST-вызовы к api.bitbucket.org (формы взяты из документации Atlassian API), точные предопределённые переменные внутри живого PR-пайплайна (BITBUCKET_PR_DESTINATION_COMMITи т.д. — документированные предположения, а не наблюдаемые значения), и то, как Pipelines монтирует клон в pipe-контейнеры. Относитесь к пути живого пайплайна как к экспериментальному, пока кто-нибудь не подтвердит зелёный прогон на реальном Bitbucket-воркспейсе; баг-репорты приветствуются.
Pre-commit хук (локально)
gitl поставляется с хуком фреймворка pre-commit, так что
gitl review --staged --quiet запускается автоматически перед каждым коммитом — локально,
офлайн и бесплатно по умолчанию (--quiet включён по умолчанию в манифесте хука, поэтому
офлайн-уведомление не печатается при каждом коммите).
Добавьте в .pre-commit-config.yaml вашего репозитория:
repos:
- repo: https://github.com/akomyagin/gitl
rev: v0.6.2 # pin to a released tag
hooks:
- id: gitl-reviewзатем выполните pre-commit install. Фреймворк сам собирает бинарник gitl
(language: golang) и кэширует окружение в ~/.cache/pre-commit/, так что
стоимость сборки оплачивается один раз, а не при каждом коммите.
Чтобы включить блокирующий хук с ограничением стоимости:
hooks:
- id: gitl-review
args: [--fail-on=high, --max-cost-usd=0.05] # opt-in: block on high risk, cap costЭкспортируйте GITL_API_KEY в вашем окружении для реального AI-ревью; без него
хук выполняет детерминированное офлайн-ревью (без сети, без затрат).
Что нужно знать:
Офлайн по умолчанию. Без API-ключа, без сети, без затрат на коммит. Установите
GITL_API_KEY, чтобы включить реальное AI-ревью.Неблокирующий по умолчанию. Хук выводит ревью, но не проваливает коммит — тот же принцип «WARN по умолчанию, жёсткий шлюз — явное согласие», что и в CLI/Action. Добавьте
args: [--fail-on=high]для блокировки.Задержка. Реальное API-ревью занимает несколько секунд; держите его вне горячего пути, оставив офлайн, или ограничьте с помощью
--max-cost-usd.Конфиденциальность диффа. С реальным ключом staged-дифф уходит вашему настроенному LLM-провайдеру — для приватного кода используйте self-hosted/enterprise-провайдера (Ollama, Azure OpenAI), см. Providers выше.
Подавление офлайн-уведомления. Манифест передаёт
--quietпо умолчанию, поэтому уведомление «using deterministic offline review» в stderr при каждом коммите замалчивается; тот же переключатель доступен вreview/changelogкак--quiet/GITL_QUIET, или на уровне репозитория черезoutput.quiet: true(MCP-сервер учитывает толькоoutput.quiet/GITL_OUTPUT_QUIET— у него нет флагов, поэтому короткий алиасGITL_QUIETтам не работает). Ошибки и сам вывод ревью не затрагиваются.
Без фреймворка pre-commit
Подойдёт и обычный git-хук:
# .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=highMCP-сервер
gitl mcp запускает gitl как stdio-сервер Model Context Protocol —
отдельный дополнительный канал по сравнению с использованием CLI/CI выше, для интерактивного
использования gitl внутри агентской сессии (Claude Desktop, Cursor, Windsurf и т.д.) вместо
вызова из командной строки. Он предоставляет два инструмента:
gitl_review— тот же движок ревью, что иgitl review:range/pr/staged(ровно один), опциональное переопределениеmodelна каждый вызов. Провайдер и endpoint фиксируются при запуске сервера по замыслу: вызывающий инструмент — это AI-агент, которым можно управлять через prompt injection внутри ревьюируемого содержимого — per-callbase_urlпозволил бы вредоносному коммиту перенаправить запрос и утечь реальный API-ключ. Всегда возвращает структурированный JSON-артефакт (без md/text-рендеринга, без стриминга — результат инструмента атомарен).risk.levelвозвращается как данные; в MCP-режиме нет--fail-on, поскольку нет кода выхода процесса, который можно было бы шлюзовать.gitl_digest— то же, чтоgitl digest:days(по умолчанию 7), опциональныйrepos. Без явного аргументаreposинструмент обрабатывает только рабочую директорию сервера (плюсdigest.reposиз.gitl.yaml, если настроено) — он никогда не обходит произвольные пути по собственной инициативе. Явный аргументreposучитывается как есть (вызывающий агент уже имеет доступ к файловой системе через свои инструменты; это не граница контроля доступа, а просто дефолт «не удивляй пользователя»).
Добавьте в конфиг вашего MCP-клиента (Claude Desktop, Cursor и т.д.):
{
"mcpServers": {
"gitl": {
"command": "gitl",
"args": ["mcp"]
}
}
}Конфиг загружается один раз при запуске так же, как и для обычных команд
(.gitl.yaml + личный конфиг + переменные окружения GITL_*, из директории, в
которой запущен gitl mcp). Без ключа вызовы инструментов работают в том же
детерминированном офлайн-режиме, что и CLI. stdout зарезервирован под протокол
MCP — туда никогда не пишется ничего человекочитаемого; предупреждения идут в
stderr.
Лицензия
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