# gitflic-cli — полная документация (для LLM) > gitflic-cli — консольный клиент (CLI) для GitFlic: 100% покрытие REST API (~199 эндпоинтов, 20 модулей), ноль зависимостей и MCP-сервер для AI-агентов. > Источник: https://cli-gitflic.ru/ • Сгенерировано из docs/. ================================================================================ # https://cli-gitflic.ru/api-coverage.html ================================================================================ # Покрытие API Сравнение того, что GitFlic REST документирует, с тем, что CLI реально оборачивает. Полный список эндпоинтов в [docs.gitflic.ru/latest/api](https://docs.gitflic.ru/latest/api/). **Покрыты все 20 разделов публичного REST API** (≈199 задокументированных эндпоинтов; со scope-вариантами project / company / team / instance — заметно больше). Большинство протестировано вживую против `api.gitflic.ru`; часть — code-only там, где нужны admin-права или Enterprise/Atlas. | # | Раздел | Покрытие | Заметки | |---|---|---:|---| | 1 | **merge-request** (`mr`) | **100%** | lifecycle + discussions + by-commit + approval rules/configuration + squash/method/template (team/company) + apply-settings | | 2 | **mergeRequestDiscussion** | **100%** | list / get-one / create / reply / resolve / delete | | 3 | **branch** | **100%** | branches + compare + compare-file + commits-between + branch-protection (project/team/company) | | 4 | **tag** | **100%** | tag list/get/create + tag-protection (team/company CRUD + apply). Удаления тега в REST нет | | 5 | **release** | **100%** | CRUD + file upload/download/delete | | 6 | **issue** | **100%** | CRUD + comments + relations + files/link/unlink + `issue attach` | | 7 | **commit** | **100%** | list (`/commits`) + get/file/diff/for-file + commit-diff + tag-diff + cherry-pick | | 8 | **blob** | **100%** | get (raw) + download + recursive + file-size | | 9 | **settings** (user) | **100%** | ssh add + oauth CRUD + access-token + transport-token + смена профиля | | 10 | **user** | **100%** | me / get / projects / followers / following | | 11 | **project** | **100%** | CRUD + search/my/shared + members/teams + fork/mirror/import + archive + files + change-setting + deploy-token + run-script | | 12 | **team** | **100%** | list/my/shared/get/create/transfer + members + import (edit/delete — UI-only) | | 13 | **company** | **100%** | list/my/shared/get/create + members + import | | 14 | **environment** | **100%** | environment-protection (team/company CRUD + apply) | | 15 | **webhook** | **100%** | list/get/create/edit/delete | | 16 | **package-registry** (`registry package`) | **100%** | CRUD (3 scope) + upload/download для всех форматов | | 16b | **registry-repository** (`registry repo`) | **100%** ¹ | CRUD + packages + per-format up/down (Enterprise/Atlas-only, code-only) | | 17 | **cicd** | **100%** | pipeline/job lifecycle + artifacts + variables + pipeline-lifetime | | 18 | **runner** | **100%** ² | project/company/instance scopes | | 19 | **admin** | **100%** ² | user CRUD + ban + ssh-key + push-stats + 18 settings + ldap import | | 20 | **saml** | **100%** ² | `/admin/saml` list/create/edit/change-status | | — | **mcp-server** | — | MCP-обёртка поверх CLI | > ¹ Enterprise/Atlas-only — на публичном инстансе 404. > ² Требует прав администратора — обычным токеном не тестируется. Полная машиночитаемая карта эндпоинтов: метод+путь по каждому разделу — в исходниках спеки (`docs.gitflic.ru/latest/api/
/`). ## Как добавить покрытие 1. Посмотри `lib/cmd/.mjs` для паттерна. 2. Создай новый модуль или расширь существующий. 3. Напиши тесты в `lib/__tests__/.test.mjs`. 4. Обнови эту таблицу. ## См. также - [Все команды](/commands/) - [Известные проблемы](known-issues.md) - [MCP-сервер](mcp-server.md) ================================================================================ # https://cli-gitflic.ru/auth/ ================================================================================ # Аутентификация CLI поддерживает несколько сценариев хранения токена с автоматическим выбором самого безопасного доступного бэкенда. ## Краткая картина | Где лежит токен | Как попадает туда | Когда это работает | |---|---|---| | **macOS Keychain** | `gitflic auth login` | На любом маке (бинарь `security` встроен) | | **Linux libsecret** | `gitflic auth login` | Если установлен `secret-tool` (libsecret + GNOME Keyring / KWallet) | | **Файл с chmod 0600** | fallback | Если ничего из вышеперечисленного не нашлось — с warning в stderr | | **env var `GITFLIC_TOKEN`** | `export GITFLIC_TOKEN=...` в шелле | Универсально, но требует ручной настройки | | **`--token `** (per-call override). 2. **`GITFLIC_TOKEN`** env var. 3. **`account-bind:`** — если `flags.project` задан (per-project override, см. [Per-project bindings](per-project.md)). 4. **`token:`** — если `auth switch` установил активный аккаунт. 5. **`token`** — legacy-ключ для default-аккаунта (если `active-account` не задан). 6. **die** с подсказкой: `no token. Run gitflic auth login --token ...`. Каждый уровень проверяется по очереди. Ничего не "проваливается" молча. ## Угрозы и защита Подробный разбор — [auth/security.md](security.md). TL;DR: | Угроза | Защита | |---|---| | Стиллер ищет `~/.zshrc`, `~/.aws/credentials`, `~/.netrc` | Keychain не попадает в plaintext grep | | Бэкап диска украден | Keychain зашифрован паролем юзера (без него не расшифровать) | | Другой юзер на маке | File mode `chmod 0600`, keychain — owner-only | | Стиллер запущен от твоего юзера | Все токены утекают — это game over независимо от нас | | Токен ушёл в scrollback / history | `alias list/get` маскирует sensitive значения | ## Что НЕ реализовано (по сравнению с `gh`) - ❌ OAuth browser flow — GitFlic OAuth-документация не подтверждена, нет смысла делать вслепую. - ❌ `git credential.helper` интеграция — отдельная UX-история, есть в планах. - ❌ TTL / auto-refresh токенов — нужна поддержка expiry в API GitFlic. Если что-то из этого нужно — отдельным коммитом. ================================================================================ # https://cli-gitflic.ru/auth/login.html ================================================================================ # `auth login` / `logout` / `status` / `list` ## login ```bash gitflic auth login --token xxxx-xxxx-xxxx # вставить напрямую echo $TOKEN | gitflic auth login --stdin # из stdin (удобно для scripts) gitflic auth login --token xxxx --as work # в named-аккаунт ``` Что происходит: 1. CLI читает токен из `--token`, `--stdin` или `GITFLIC_TOKEN` (по порядку). 2. Дёргает `GET /user/me` с этим токеном. 3. Если 200 — показывает identity (alias + email) и сохраняет в keychain. 4. Если 401/403/сетевая ошибка — **die**, токен НЕ сохраняется. ``` gitflic: logged in as tikhon (account: default, backend: keychain) ``` Если бэкенд — не keychain, а файл (например, на сервере без `secret-tool`), будет warning: ``` gitflic: WARNING — storing 'token' in plaintext file /home/u/.config/gitflic-cli/config.json (chmod 0600). gitflic: For stronger protection, install an OS keychain … ``` ### Многословие флагов | Флаг | Что делает | |---|---| | `--token ` | Значение токена (иначе читает из `--stdin` / `GITFLIC_TOKEN`) | | `--stdin` | Читает токен из stdin (до первого перевода строки, или весь stdin если однострочный) | | `--as ` | Сохраняет в `token:`, делает активным (см. [multi-account](multi-account.md)) | | `--api-base ` | Override API base для валидационного запроса | ## logout ```bash gitflic auth logout # удалить активный аккаунт gitflic auth logout --as work # удалить конкретный named gitflic auth logout --all # удалить ВСЕ токены + все bindings ``` С `logout --all` CLI: 1. Удаляет все `token:*` ключи из secret store + file fallback. 2. Удаляет `active-account` если был. 3. Удаляет все `account-bind:*` (привязки на удалённые аккаунты — мёртвые). 4. Сообщает: `gitflic: all tokens cleared (3 account key(s), 2 binding(s))`. Keychain-записи (`security find-generic-password`) после этого не находятся (exit code 44). ## status ```bash gitflic auth status ``` ``` account: work backend: keychain identity: user-work api: https://api.gitflic.ru ``` Exit code 1 если токен не доходит до API (network / 401 / 403). Это полезно для pre-flight checks в CI: ```bash gitflic auth status || echo "auth broken, run gitflic auth login" ``` ## list ```bash gitflic auth list ``` ``` default def***aaa * personal per***ccc work wor***bbb (active: personal, backend: keychain) ``` - `*` — активный аккаунт (используется для команд без `--project` или без `account-bind`). - Все токены маскированы (`abc***xyz`), даже если вывод направлен в pipe/log. - `(active: X, backend: Y)` — последняя строка показывает какой бэкенд используется. ================================================================================ # https://cli-gitflic.ru/auth/multi-account.html ================================================================================ # Multi-account Если у тебя несколько личностей на GitFlic (рабочая + личная, например), `--as ` позволяет хранить токены для каждой отдельно. ## Базовый flow ```bash gitflic auth login --token def-xxxx # default аккаунт gitflic auth login --as work --token work-yyyy # work-аккаунт gitflic auth login --as personal --token pers-zz # personal gitflic auth list # default def***xxx # * work wor***yyy ← активный сейчас # personal per***zzz gitflic auth switch personal # переключиться gitflic auth status # identity от personal ``` `auth switch` валидирует, что токен для указанного аккаунта существует. Если нет — отказывается: ``` gitflic: auth switch: no token stored for account 'ghost'. gitflic: run: gitflic auth login --as ghost ``` ## Resolution chain с multi-account Когда `flags.project` НЕ задан: 1. `--token ` 2. `GITFLIC_TOKEN` env 3. `token:` (или `token` если active не задан) 4. die `active-account` хранится в `~/.config/gitflic-cli/config.json`, меняется через `auth switch`. ## Где живут токены | Аккаунт | Storage key | Бэкенд | |---|---|---| | `default` | `token` | OS keychain (если есть) или файл | | `work` | `token:work` | то же | | `personal` | `token:personal` | то же | Default-аккаунт использует legacy-ключ `token` для backward-compat с первой версией CLI (когда multi-account ещё не было). ## Очистка ```bash gitflic auth logout --as work # удалить только work gitflic auth logout --all # удалить ВСЕ ``` `logout --all` дополнительно чистит все `account-bind:*` (per-project привязки, см. [per-project.md](per-project.md)). ## Сценарии ### Один юзер, разные GitFlic-инстансы (cloud + self-hosted) ```bash gitflic auth login --as cloud --token xxx GITFLIC_API_BASE=https://git.corp.io gitflic auth login --as corp --token yyy gitflic alias set api-base https://api.gitflic.ru # для cloud gitflic auth switch cloud gitflic mr list --project FerdBur/wave # → cloud-токен, api.gitflic.ru GITFLIC_API_BASE=https://git.corp.io gitflic auth switch corp gitflic mr list --project myteam/internal # → corp-токен, self-hosted ``` ### Личное и рабочее в одном репо Используй [per-project bindings](per-project.md): ```bash gitflic auth bind FerdBur/wave work # этот проект — от work gitflic auth bind tikhon/personal personal # этот — от personal # любые команды автоматически подставят правильный токен ``` ================================================================================ # https://cli-gitflic.ru/auth/per-project.html ================================================================================ # Per-project account bindings Привязка `` говорит CLI: "когда пользователь работает с этим проектом, всегда используй токен этого аккаунта". Полезно, если: - В разных репозиториях у тебя разные личности (работа vs личное). - У одного проекта — два владельца (maintainer в work-аккаунте, contributor в personal). - Ты хочешь автоматический роутинг без `auth switch` перед каждой командой. ## Команды ```bash gitflic auth bind # создать привязку gitflic auth unbind # удалить gitflic auth bindings # список всех привязок ``` `` — это `owner/alias` (то же, что передаёшь в `--project`). ## Пример ```bash # Настраиваем 2 аккаунта gitflic auth login --as work --token work-xxx gitflic auth login --as personal --token pers-yyy # Привязываем проекты gitflic auth bind FerdBur/wave work gitflic auth bind tikhon/personal personal gitflic auth bindings # FerdBur/wave → work # tikhon/personal → personal # Теперь команды автоматически подставляют правильный токен gitflic mr list --project FerdBur/wave # → token:work gitflic mr list --project tikhon/personal # → token:personal # Команды без --project используют active-account (как раньше) gitflic auth switch personal gitflic user me # → token:personal (от active) ``` ## Как это работает внутри Привязка хранится в config-файле как `account-bind:FerdBur/wave = work`. `resolveToken` (в `lib/http.mjs`) делает: ```js 1. --token flag → вернуть 2. GITFLIC_TOKEN env → вернуть 3. Если flags.project задан: account-bind: → secretGet(token:) → вернуть 4. token: → вернуть 5. token (legacy default) → вернуть 6. die ``` Шаг 3 — это новая проверка, она **перебивает** active-account, когда проект задан. ## Валидация `auth bind ` отказывается, если у `` нет токена: ``` gitflic: auth bind: no token stored for account 'ghost'. gitflic: run: gitflic auth login --as ghost first. ``` Это чтобы не плодить мёртвые привязки. Если привязка указывает на аккаунт, токен которого потом удалили, при следующей команде будет warning + fallthrough: ``` gitflic: WARNING — project 'FerdBur/wave' is bound to account 'ghost' but no token is stored for it. gitflic: run: gitflic auth login --as ghost (or: gitflic auth unbind FerdBur/wave) ``` (Используется `token:` или legacy `token` как fallback.) ## Где живёт привязка ``` ~/.config/gitflic-cli/config.json: { "token": "def-xxx", // default аккаунт "token:work": "work-yyy", "token:personal": "pers-zzz", "active-account": "default", "account-bind:FerdBur/wave": "work", "account-bind:tikhon/personal": "personal" } ``` На macOS все эти `token*` ключи лежат в Keychain, `account-bind:*` и `active-account` — в файле. ## Авто-детект проекта CLI умеет авто-определять проект из `git remote get-url origin` (если ты внутри git-клона). Это работает и с привязками: ```bash cd ~/code/FerdBur/wave # клон с origin = git@gitflic.ru:FerdBur/wave.git gitflic mr list # → flags.project = "FerdBur/wave" → binding → token:work ``` Не нужно каждый раз писать `--project`. ## См. также - [Аутентификация](/auth/) - [Multi-account](multi-account.md) - [auth login](login.md) ================================================================================ # https://cli-gitflic.ru/auth/security.html ================================================================================ # Безопасность хранения токенов ## Угрозы и защита — TL;DR | Угроза | Защита | Уровень | |---|---|---| | Стиллер ищет `~/.zshrc`, `~/.aws/credentials`, `~/.netrc` | Токен в Keychain, не в plaintext файлах | ✅ Невозможно промахнуться | | Бэкап диска украден | Keychain зашифрован на пароль юзера + системный ключ | ✅ Без пароля не расшифровать | | Другой юзер на shared-хосте | File mode `0600` (только owner); keychain — owner-only | ✅ Другой uid не прочитает | | Screen-share / video-call | `alias list/get` маскирует значения | ✅ Не утечёт в кадр | | Стиллер запущен от твоего юзера | Все токены читаются тем же процессом | ❌ Не защищает (но и `gh`/`glab` тоже) | | Токен в shell history | `GITFLIC_TOKEN=...` попадает в `~/.zsh_history` | ⚠️ Используй `--token ` или read из файла | ## Подробно по каждому сценарию ### 1. Хранение на диске `gitflic auth login` выбирает бэкенд в таком порядке: ``` macOS → security add-generic-password (login.keychain, encrypted at rest) Linux → secret-tool store (gnome-keyring / kwallet) иначе → ~/.config/gitflic-cli/config.json (chmod 0600, fallback) ``` Управляется переменной `GITFLIC_NO_SECRET_STORE=1` (полностью отключает keychain-путь — тогда токен хранится только в env var). ### 2. File fallback — почему `chmod 0600` достаточно Когда keychain недоступен (например, в Docker-контейнере без `dbus`), CLI пишет в файл. Режим `0600` означает "только владелец может читать и писать". ```bash $ ls -la ~/.config/gitflic-cli/config.json -rw------- 1 user staff 200 Jun 22 10:30 config.json ``` Это **не панацея**: любой процесс, запущенный от твоего юзера, прочитает файл. Это та же модель угроз, что и для `~/.ssh/id_ed25519` или `~/.aws/credentials`. Если у тебя **shared-сервер** с несколькими юзерами — инсталлируй `secret-tool` и привязывай к GNOME Keyring / KWallet. ### 3. Защита от утечки в scrollback `gitflic alias list` и `gitflic alias get token` маскируют значения: ```bash $ gitflic alias list token = def***xxx (token backend: keychain) $ gitflic alias get token def***xxx (masked — pass --reveal to print the full value) $ gitflic alias get token --reveal def-xxxx-1234-xxxx ``` Даже если вывод уйдёт в screencast, в лог CI, или в chat — там будет `def***xxx`, не реальный токен. `--reveal` нужен редко (для отладки). В скриптах и пайпах НЕ используй его без крайней нужды. ### 4. Защита в process memory Токен существует в памяти процесса только на время выполнения одной команды. Каждый вызов `gitflic ...` — отдельный процесс Node, токен живёт ~миллисекунды. Если в системе есть подозрительный процесс, делающий `ps aux` — он увидит аргументы командной строки, но НЕ значение env var другого процесса. Поэтому `GITFLIC_TOKEN=... gitflic ...` лучше чем `gitflic --token xxx` (последнее видно в `ps`). ### 5. Stiller, запущенный от твоего юзера — единственная реальная угроза Если на твоей маке запустился malware с твоими привилегиями: - `security find-generic-password -w -s gitflic-cli` — **прочитает токен** (login.keychain разлочен пока ты залогинен). - `secret-tool lookup service gitflic-cli` — аналогично на Linux. - `cat ~/.config/gitflic-cli/config.json` — если file fallback, тоже прочитает. Все три — game over для токена. **Это та же модель угроз, что и для `gh auth login` / `glab auth login` / `aws-vault`.** Что реально защищает от такого: | Защита | Усилие | Эффект | |---|---|---| | **Отдельный keychain с паролем** (`security create-keychain -p "strong" gitflic`) | низкое | Токен не доступен пока keychain залочен | | **Hardware token (YubiKey)** для OAuth/WebAuthn | высокое | Токен вообще не на маке, выдаётся по запросу | | **mTLS / SSH cert вместо bearer-токена** | среднее | Нет секрета для кражи | `gitflic-cli` сейчас НЕ реализует ни одну из этих защит (это уровень `gh`/`glab`/`aws-vault` — отраслевой стандарт). Если нужна отдельная залочка — скажи, добавлю отдельным коммитом. ## Сводка по бэкендам | Бэкенд | Когда доступен | Где хранится | Уровень защиты | |---|---|---|---| | macOS Keychain | На любом маке (бинарь `security` встроен) | `~/Library/Keychains/login.keychain-db` (зашифрован) | Хороший (game over только при локальном malware) | | Linux libsecret | Если установлен `secret-tool` (libsecret + gnome-keyring / kwallet) | GNOME Keyring / KWallet (зашифровано) | Хороший | | Файл `chmod 0600` | Всегда (fallback) | `~/.config/gitflic-cli/config.json` | Базовый (читается любым процессом юзера) | ## Что я НЕ рекомендую - ❌ Хранить токен в `~/.zshrc` (mode 0644 → world-readable + утекает в любой `git add .` если zshrc в dotfiles-репо). - ❌ Коммитить `.env` с токеном (даже в private-репо). - ❌ Использовать один и тот же токен для всего (нет blast-radius control). - ❌ Передавать `--token xxx` через CI logs. ## Связанное - [Multi-account](multi-account.md) — несколько токенов с разными scope. - [Per-project bindings](per-project.md) — роутинг токенов по проектам. ================================================================================ # https://cli-gitflic.ru/changelog.html ================================================================================ # Changelog Все значимые изменения в `gitflic-cli`. Формат — приближённый к [Keep a Changelog](https://keepachangelog.com/). ## [gitflic-cli-mcp 0.4.1] — 2026-06-24 Багфиксы slim-слоя, найденные при live-прогоне всех 77 тулзов «в бою». - **`gitflic_user_search`** через slim возвращал пусто — клиентский `q`-фильтр искал только по `title`/`description`, а у юзеров их нет. Haystack расширен (`username`/`fullName`/`name`/`alias`/`tagName`). - **Пустой `*_list`** незамапленного тула отдавал сырую обёртку `{page}` вместо `{items:[],total,returned:0}`. Fallback расширен на любой `*_list`/`*_search`. ## [0.3.5] — 2026-06-24 Ещё несколько частичных edit'ов затирали поля (PUT заменяет объект целиком → нужен read-merge): - **`branch protection edit`** — правка одного поля сохраняет остальные (проверено вживую). Также **`settings oauth edit`** и **`registry repo edit`**. - **`mr discuss delete`** — слал `POST` → GitFlic **405**; теперь `DELETE` (проверено вживую). `mr discuss reply`/`resolve`/`delete` работают через CLI (нужен `rootNote.uuid`). ## [0.3.4] — 2026-06-23 - **`issue close` / `reopen` / `edit`** больше не затирают `title`/`description` — раньше `close` молча превращал заголовок в `«stub»` (GitFlic PUT заменяет объект целиком; теперь read-merge). ## [0.3.3] + gitflic-cli-mcp [0.4.0] — 2026-06-23 — сжатие токенов MCP MCP больше не отдаёт LLM «сырой» JSON GitFlic — на реальных данных **≈70% экономии токенов** (на коммитах/ветках до 84%). - **MCP: сжатие ответов** — list-обёртка `{_embedded,page}` → `{items,total,matched,returned}`, проекция сущностей, вырезание косметики (avatar/cover/hexColor/`_links`), `status` → enum-скаляр. Два режима: `GITFLIC_MCP_OUTPUT=slim|full` + `GITFLIC_MCP_RAW`. Поканальные `raw:true` / `fields:[…]`. Клиентская фильтрация списков (`label`/`q`/`assignee`/…). Новый approval-тул `gitflic_webhook_reveal_secret`; `secret` вебхука маскируется в `secretSet`. Тулзов: **77**. См. [MCP-сервер → Сжатие ответов](/mcp-server#сжатие-ответов-экономия-токенов). - **CLI: fix пагинации `--all`** — пейджер был 1-индексным, а списки GitFlic 0-индексные → терялась первая страница (`issue list --all` отдавал 40 из 60). `user projects`/`followers`/`following` → поддержка `--all`. ## [0.3.2] + gitflic-cli-mcp [0.3.1] — 2026-06-23 Багфиксы из живого E2E-прогона всех MCP-тулзов. Добавлен `scripts/e2e-live.mjs`. - **CLI `project edit`** — `PUT /project` (405) → теперь `…/setting/change-setting` (title/description/language). - **CLI `mr create`** — требует непустой `--description` (иначе GitFlic 422). - **CLI `blob get`/`recursive`/`download`** — работают без `--commit` (по `--branch` или дефолтной ветке). - **MCP `gitflic_blob_files`** → `blob recursive` (звал несуществующую `blob files`). - **MCP `gitflic_blob_archive`** — удалён (нет репо-тарбола в REST). Тулзов: 76. - **MCP `gitflic_mr_create`** — `description` обязателен; **`gitflic_project_edit`** — убраны visibility/default-branch. ## [0.3.1] — 2026-06-23 - **Fix `gitflic release create` / `release edit`** — не отправлялось обязательное поле `preRelease`, из-за чего GitFlic API падал с 500/422. Теперь `preRelease` шлётся всегда (default `false`); `edit` дочитывает текущий релиз и мёржит изменения. Добавлены unit-тесты. ## [gitflic-cli-mcp 0.3.0] — 2026-06-23 > Релиз только MCP-пакета. CLI `gitflic-cli` без изменений (0.3.0). - **`GITFLIC_MCP_NO_DESTRUCTIVE=1`** — overlay-флаг, который жёстко убирает 7 удаляющих тулзов (`*_delete`) на уровне регистрации (надёжнее approval-prompt'а). Остальные мутации, включая `gitflic_mr_merge`, остаются и идут через подтверждение хоста. Цепочка: база → `READONLY` → `NO_DESTRUCTIVE` → `EXCLUDE`. ## [gitflic-cli-mcp 0.2.0] — 2026-06-23 > Релиз только MCP-пакета. CLI `gitflic-cli` без изменений (0.3.0). ### MCP-сервер (`gitflic-cli-mcp`) - **Фильтрация набора тулзов** для экономии контекста модели. Через env-переменные: `GITFLIC_MCP_GROUPS` (по группам, напр. `mr,issue`), `GITFLIC_MCP_READONLY=1` (только read-only), `GITFLIC_MCP_TOOLS` (allowlist), `GITFLIC_MCP_EXCLUDE` (denylist). По умолчанию регистрируются все 77 тулзов. См. [MCP-сервер → Ограничение набора тулзов](/mcp-server#ограничение-набора-тулзов-экономия-контекста). - **Fix MCP-аннотаций:** `gitflic_project_list_my` и `gitflic_mr_by_commit` помечены read-only; `gitflic_mr_discuss_resolve` помечен write. Итог: 40 read / 37 write. ## [0.3.0] — 2026-06-23 100% покрытие публичного REST API GitFlic — все 20 разделов (≈199 эндпоинтов со scope-вариантами). Бо́льшая часть протестирована вживую против `api.gitflic.ru` (62/62 проверки green). Подробности — в [api-coverage.md](api-coverage.md). ### Added - **HTTP-хелперы** (`lib/http.mjs`): `httpText` (raw-контент, `Accept: */*`), `httpDownload` (бинарное скачивание в файл), `httpUploadFile` (raw-PUT для реестра пакетов). `Accept`/`parse`/`contentType` прокинуты в `httpWithRetry`. - **registry** — полностью переписан: `registry package` (list/get/versions/version/files/delete + upload/download для generic/maven/npm/pypi/nuget/composer/opm/cran/rubygem/cargo/conda в scope project/company/instance) и `registry repo` (registry-repository). Per-format upload использует флаг `--fmt` (не `--format`). - **runner** — переписан под реальные пути `/project|company|admin/runners`: scope-параметр + edit/shutdown/delete/jobs/registration-info. - **saml** — переписан под `/admin/saml`. - **cicd** — artifacts, job-операции, restart/cancel/delete, variables, pipeline-lifetime (team/company). - **branch / tag / environment / mr** — team/company-scoped операции (protection rules, MR approval rules/configuration/squash/method/template, apply-settings-to-projects) с единым флагом `--scope team|company` + `--team/--company`. - **release** — upload/download/delete файлов релиза (multipart, поле `files`). - **issue** — relations CRUD, files (list/link/unlink), `issue attach` (upload+link). - **commit** — for-file, tag-diff, cherry-pick. - **blob** — download/recursive/file-size (raw `Accept: */*`). - **project** — search/my/shared, create-fork, mirror push/manual-update, archive, attachments, change-setting, run-script, allowed-owners, project-size. - **admin** — user CRUD + ban/unban + ssh-key + push-stats + 18 settings-мутаторов + ldap import (admin-only). - **team/company** — my/shared/create/members/import. ### Changed - **Диспетчер** (`lib/gitflic.mjs`): команды с `--scope team|company` больше не требуют `--project` (раньше падали «could not detect project»). - Реестр: исправлены неверные пути (`/registry/...` база, `version-list`/`package-file`, dotted maven groupId). - Убраны несуществующие в REST `team edit/delete` и `company edit/delete` (405 — только web UI; для смены владельца — `team transfer`). - Тесты: 166 unit-тестов (добавлены тесты `htmlUnescape`). ### Fixed - **BUG-001:** `mr diff` теперь декодирует HTML-entities (`"`/`<`/`>`/`&`) через `htmlUnescape()` — диффы читаемы; покрыто тестами. - **commit list** исправлен на `/commits`; **cherry-pick** — на `/branch/cherry-pick`. - **release-list** — `/release` вместо `/release/list` (404). ## [0.2.0] — 2026-06-23 > Не выпускалось отдельным тегом — вошло в 0.3.0. ### Changed - **CI/CD выпилен.** Удалён `gitflic-ci.yaml` и страница `docs/ci-cd.md`: на публичном `gitflic.ru` нет shared runners, а self-hosted `runner.jar` требует платный VPS. Сборка/релиз — локально (`npm run build`, `npm run release`), дока — статикой на Timeweb. ### Fixed - `cicd pipeline list` в pretty-режиме показывал `(no pipelines)` при наличии записей — реальный HAL-ключ `restPipelineModelList` (а не `pipelineList`). Поправлено в `lib/cmd/cicd.mjs` (со старыми ключами как fallback). ## [0.1.0] — 2026-06-22 ### Added - **OS-keychain token storage** (`lib/secret.mjs`) — macOS Keychain / Linux libsecret / chmod 0600 file fallback. - **`auth` модуль** (login/logout/status/list/switch/bind/unbind/bindings) с валидацией токена ДО сохранения. - **Multi-account** через `--as ` + `auth switch`. - **Per-project account bindings** (`auth bind `). - **TUI mode** для `mr list` (`--tui`). - **NDJSON streaming** для list endpoints (`--stream` / `GITFLIC_STREAM=1`). - **`--all` auto-pagination** для 12 list endpoints. - **Shell completion** для bash/zsh/fish (`gitflic completion `). - **Format flags** `--color` / `--no-color` + env `NO_COLOR` / `FORCE_COLOR`. - **File-based project-UUID cache** + `gitflic cache` команда. - **HTTP retry** on 429/502/503/504 с exponential backoff + jitter. - **MCP-сервер** — 77 типизированных тулов для AI-агентов. - **Multipart upload** для release assets + issue attachments. ### Fixed - **`lib/tui.mjs` сломан в production** — `import { process } from "node:process"` падает SyntaxError на нативном Node ESM. vitest/esbuild молча маскировал баг. Поправлено на `import process from "node:process"`. ## [0.0.x] — initial development - MVP: ~150 эндпоинтов GitFlic REST в CLI. - Bash + PowerShell установщики. - Zero runtime dependencies (только Node 18+ stdlib). - Конфиг в `~/.config/gitflic-cli/config.json`. ================================================================================ # https://cli-gitflic.ru/commands/admin.html ================================================================================ # Admin endpoints (`gitflic admin ...`) > ⚠️ Все команды требуют **admin-токен** (instance-admin права). Для обычного токена вернётся 403/404. Code-only: реализовано по спеке, не live-tested на публичном SaaS. Покрытие admin-API: управление пользователями (CRUD), бан/разбан, SSH-ключи, push-статистика, настройки сервиса и импорт из LDAP. ## Пользователи ### user list Список всех пользователей инстанса (legacy-эндпоинт, отсутствует в публичной REST-доке — может вернуть 404). ```bash gitflic admin user list --all --format json gitflic admin user list --page 0 --size 50 ``` ### user create Создать пользователя (`POST /user`). ```bash gitflic admin user create --email ivan@example.com --password 'S3cret!' --alias ivanov ``` ### user change-email Сменить email пользователя. ```bash gitflic admin user change-email ivanov --email new@example.com ``` ### user change-username Сменить username пользователя. ```bash gitflic admin user change-username ivanov --username petrov ``` ### user change-password Сменить пароль пользователя. ```bash gitflic admin user change-password ivanov --password 'N3wPass!' --password-confirm 'N3wPass!' ``` ### user ban / unban Заблокировать (причина ≤ 128 символов) или разблокировать пользователя. Указывается **UUID** пользователя. ```bash gitflic admin user ban 3f1c2a90-... --reason "spam" gitflic admin user unban 3f1c2a90-... ``` ## SSH-ключи пользователя ### user key-create Добавить SSH-ключ пользователю. ```bash gitflic admin user key-create ivanov --public-key "ssh-ed25519 AAAA..." --title "laptop" --expires-at 2027-01-01T00:00:00Z ``` ### user key-list Список SSH-ключей пользователя. ```bash gitflic admin user key-list ivanov --format json ``` ## Проекты ### project list Список всех проектов инстанса (legacy-эндпоинт, может вернуть 404). ```bash gitflic admin project list --all --format json ``` ## Push-статистика ### push-stats all Push-статистика по всем пользователям. ```bash gitflic admin push-stats all --page 0 --size 100 --format json ``` ### push-stats specified Push-статистика по конкретным пользователям (UUID списком или через `--uuids`). ```bash gitflic admin push-stats specified a1b2c3 d4e5f6 gitflic admin push-stats specified --uuids a1b2c3,d4e5f6 --format json ``` ## Настройки сервиса ### settings get Показать объект настроек сервиса. ```bash gitflic admin settings get --format json ``` ### settings set Обновить группу настроек (`POST /admin/settings/`). Группа передаётся первым аргументом, далее — флаги группы. ```bash # регистрация / способы аутентификации gitflic admin settings set registration --disable-ldap-auth --disable-mail-auth # скачивание файлов и релизов анонимами gitflic admin settings set download --file-download true gitflic admin settings set download-release --download-from-anon-user-enable false # pull анонимом, авто-подтверждение, валидация email gitflic admin settings set pull --pull-repo-from-anon-user false gitflic admin settings set auto-confirm --auto-confirm true gitflic admin settings set email-validation --enable-email-validation true # валидация доменов (white/black-list) gitflic admin settings set domain-validation --enable-domain-validation true --enable-white-list true --white-list-domains example.com,corp.ru # лимиты API gitflic admin settings set api-limit --disable-api-limit false --user-api-count-limit 1000 # кастомный SSH-порт gitflic admin settings set ssh-port --enable-custom-ssh-port true --ssh-port 2222 # доступ к глобальному registry анонимам gitflic admin settings set anonymous-global-registry-access --anonymous-global-registry-access false # авто-права для публичных репозиториев gitflic admin settings set public-repository-auto-permission --enabled true # лаг и интервалы обновления зеркал gitflic admin settings set mirror-update-lag --project-update-lag 5 gitflic admin settings set mirror-update-interval --push-mirror-update-interval-minutes 15 --pull-mirror-update-interval-minutes 30 # таймаут неактивной сессии gitflic admin settings set session-max-inactive-interval --session-max-inactive-interval-minutes 60 # права на создание сущностей gitflic admin settings set create-permissions --enable-create-project true --enable-create-team true --enable-create-company false # страница входа и доступные провайдеры gitflic admin settings set login-page --login-page-url BASIC --is-enable-basic --is-enable-ldap # блокировка аккаунта при неудачных попытках gitflic admin settings set lock-account --lock-user true --max-attempts 5 --time-to-lock-user 30 --time-to-count-fail-user-login-attempts 15 # архив паролей пользователя gitflic admin settings set archive-password --enable-archive-user-passwords true --max-user-archived-passwords 5 ``` Доступные группы и флаги: | Группа | Флаги | |---|---| | `registration` | `--disable-ldap-auth` `--disable-saml-auth` `--disable-oidc-auth` `--disable-mail-auth` | | `download` | `--file-download ` | | `pull` | `--pull-repo-from-anon-user ` | | `download-release` | `--download-from-anon-user-enable ` | | `auto-confirm` | `--auto-confirm ` | | `email-validation` | `--enable-email-validation ` | | `domain-validation` | `--enable-domain-validation ` `--enable-white-list ` `--black-list-domains a,b` `--white-list-domains a,b` | | `api-limit` | `--disable-api-limit ` `--user-api-count-limit ` | | `ssh-port` | `--enable-custom-ssh-port ` `--ssh-port ` | | `anonymous-global-registry-access` | `--anonymous-global-registry-access ` | | `public-repository-auto-permission` | `--enabled ` | | `mirror-update-lag` | `--project-update-lag ` | | `session-max-inactive-interval` | `--session-max-inactive-interval-minutes ` | | `mirror-update-interval` | `--push-mirror-update-interval-minutes ` `--pull-mirror-update-interval-minutes ` | | `create-permissions` | `--enable-create-project ` `--enable-create-team ` `--enable-create-company ` | | `login-page` | `--login-page-url BASIC\|SAML\|LDAP\|OIDC` `--is-enable-basic` `--is-enable-ldap` `--is-enable-saml` `--is-enable-oidc` | | `lock-account` | `--lock-user ` `--max-attempts ` `--time-to-lock-user ` `--time-to-count-fail-user-login-attempts ` | | `archive-password` | `--enable-archive-user-passwords ` `--max-user-archived-passwords ` | ## LDAP ### ldap import Запустить синхронизацию пользователей из LDAP по UUID конфигурации. ```bash gitflic admin ldap import 7c8d9e10-... ``` ## См. также - [SAML SSO](saml.md) — тоже требует прав инстанс-админа. - [CI/CD, вебхуки, агенты](cicd-webhook.md#runner) — раннеры инстанса (`gitflic runner`). - [Пользователи и команды](user-team.md) — управление пользователями. - [Известные проблемы](../known-issues.md) — почему admin отдаёт 403/404 обычным токеном. ================================================================================ # https://cli-gitflic.ru/commands/alias.html ================================================================================ # `alias` Persistent key-value конфиг. Управляет тем, что **не является токеном** — `default-project`, `api-base`, и т.п. > Для токенов и привязок используй [`auth`](/auth/) — отдельная подсистема с keychain-бэкендом и маскированием. ## Подкоманды ```bash gitflic alias set default-project tikhon/wave # сохранить gitflic alias get default-project # прочитать gitflic alias unset default-project # удалить gitflic alias list # все ключи gitflic alias path # путь к config-файлу gitflic alias clear # удалить весь config ``` ## Известные ключи | Ключ | Что делает | |---|---| | `default-project` | Авто-подставляется в `--project` если не указан и git-remote не дал авто-детект | | `api-base` | API endpoint (если не задан `GITFLIC_API_BASE` и не передан `--api-base`) | | `token` | **DEPRECATED для прямого использования** — ставь через `gitflic auth login` | ## Где лежит `$XDG_CONFIG_HOME/gitflic-cli/config.json` или `~/.config/gitflic-cli/config.json`. Режим файла — `chmod 0600`, директория — `chmod 0700` (защита от случайной утечки при permissive umask). ## Отключить `GITFLIC_NO_CONFIG=1` — игнорировать config-файл (полезно для CI, чтобы не подхватить токен из девелоперской машины). ## Маскирование `alias list` маскирует sensitive ключи (`token`, `*password*`, `*secret*`, `*api-key*`, `*private-key*`): ``` default-project = tikhon/wave token = def***xxx (token backend: keychain) ``` `alias get token` тоже маскирует по умолчанию + выводит hint про `--reveal`. ================================================================================ # https://cli-gitflic.ru/commands/branch-tag.html ================================================================================ # Ветки и теги ## branch ```bash gitflic branch list --project FerdBur/wave # все ветки gitflic branch list --project FerdBur/wave --all # авто-пагинация gitflic branch get master --project FerdBur/wave # детали gitflic branch default --project FerdBur/wave # default branch проекта ``` ### create / delete ```bash gitflic branch create my-feature --project FerdBur/wave gitflic branch create my-feature --project FerdBur/wave --from master # от другой ветки (по умолчанию master) gitflic branch delete my-feature --project FerdBur/wave ``` ### compare File-level diff между двумя ветками: ```bash gitflic branch compare my-feature --project FerdBur/wave gitflic branch compare my-feature --base master --project FerdBur/wave ``` ### compare-file Diff одного файла между двумя коммитами: ```bash gitflic branch compare-file --project FerdBur/wave \ --file-path src/main.js \ --base-hash \ --compare-hash ``` ### commits Список коммитов между двумя хэшами (base должен быть старше): ```bash gitflic branch commits --project FerdBur/wave \ --base-hash \ --compare-hash --format json ``` ### Branch protection По умолчанию правила привязаны к проекту. Для company/team-уровня добавьте `--scope company|team` и `--company/--team `. ```bash gitflic branch protection list --project FerdBur/wave gitflic branch protection list --project FerdBur/wave --all gitflic branch protection get --project FerdBur/wave gitflic branch protection create --project FerdBur/wave \ --branch-template master \ --allowed-to-push NO_ONE \ --allowed-to-merge DEVELOPER # Флаги: # --allow-force-push — разрешить force push # --code-owner-approval — требовать code-owner approval # --auto-merge — auto-merge когда все checks pass gitflic branch protection edit --project FerdBur/wave \ --allowed-to-merge ADMINS gitflic branch protection delete --project FerdBur/wave ``` `NO_ONE | DEVELOPER | ADMINS` — уровни доступа для push/merge. Company/team scope: ```bash gitflic branch protection list --scope team --team tikhon gitflic branch protection create --scope company --company acme \ --branch-template "release/*" \ --allowed-to-push ADMINS \ --allowed-to-merge ADMINS # Применить настройки protection company/team к её проектам: gitflic branch protection apply-settings --scope team --team tikhon ``` ## tag ```bash gitflic tag list --project FerdBur/wave # все теги gitflic tag list --project FerdBur/wave --all # авто-пагинация gitflic tag get v1.0.0 --project FerdBur/wave # ⚠️ может вернуть 400 — см. ниже gitflic tag create v1.0.0 --project FerdBur/wave --branch master gitflic tag create v1.0.0 --project FerdBur/wave --commit --message "Release" gitflic tag delete v1.0.0 --project FerdBur/wave # см. ниже ``` > ⚠️ `tag get ` возвращает HTTP 400 от GitFlic для любого имени — это поведение API. Получайте тег через `tag list` + grep. > ⚠️ В GitFlic нет REST-эндпоинта для удаления тегов. Команда `tag delete` — no-op с предупреждением. Удаляйте тег через git: `git push origin :v1.0.0`. ### Tag protection (team/company scope) Правила защиты тегов живут на уровне team/company, не проекта. Передавайте `--scope team|company` с `--team/--company `. ```bash gitflic tag protection list --scope team --team tikhon gitflic tag protection get --scope company --company acme gitflic tag protection create --scope team --team tikhon \ --tag-template "v*" \ --allow-to-create ADMINS gitflic tag protection edit --scope team --team tikhon \ --allow-to-create DEVELOPER gitflic tag protection delete --scope team --team tikhon # Применить настройки tag-protection team/company к её проектам: gitflic tag protection apply-settings --scope team --team tikhon ``` `NO_ONE | DEVELOPER | ADMINS` — уровни доступа для создания тегов. ## См. также - [Merge Requests](mr.md) - [Коммиты и файлы](commit-blob.md) - [Известные проблемы](../known-issues.md) ================================================================================ # https://cli-gitflic.ru/commands/cache.html ================================================================================ # `cache` Локальный file-based кеш для project UUID resolution (alias → UUID маппинг стабильно между запросами). ```bash gitflic cache path # путь к файлу кеша gitflic cache info # размер, количество записей, TTL gitflic cache clear # удалить весь кеш ``` ## Где лежит `$XDG_CACHE_HOME/gitflic-cli/cache.json` или `~/.cache/gitflic-cli/cache.json`. ## Когда полезно По умолчанию CLI кеширует резолв `owner/alias → UUID` на 1 час. Это экономит ~50-200ms на каждый вызов `gitflic mr list` etc. ```bash # Если проект переименовали / перенесли — сбрось кеш gitflic cache clear # Или для одного вызова — отключи кеш GITFLIC_NO_CACHE=1 gitflic mr list --project x/y ``` ## Структура ```json { "project:https://api.gitflic.ru:tikhon/wave": { "v": {"id": "abc-123-def", "alias": "wave", ...}, "e": 1719000000000 } } ``` `e` — epoch ms, после которого запись считается протухшей. ## См. также - [alias](alias.md) - [Флаги](../flags.md) - [Все команды](/commands/) ================================================================================ # https://cli-gitflic.ru/commands/cicd-webhook.html ================================================================================ # CI/CD, вебхуки, environments, runners ## cicd Команды CI/CD: пайплайны, джобы, артефакты, переменные и время хранения пайплайнов. Project-scoped команды требуют `--project owner/alias` (или git origin). ### Пайплайны ```bash gitflic cicd pipeline list --project FerdBur/wave # список пайплайнов gitflic cicd pipeline list --project FerdBur/wave --all # все страницы gitflic cicd pipeline --project FerdBur/wave # детали (см. known-issues) # Запуск пайплайна по ветке или тегу gitflic cicd pipeline start --project FerdBur/wave --ref feature/x gitflic cicd pipeline start --project FerdBur/wave --ref v1.0.0 --tag # С переменными (флаг --var повторяемый) gitflic cicd pipeline start --project FerdBur/wave --ref main \ --var DEPLOY_ENV=staging --var DEBUG=true # Жизненный цикл gitflic cicd pipeline restart --project FerdBur/wave gitflic cicd pipeline cancel --project FerdBur/wave gitflic cicd pipeline delete --project FerdBur/wave ``` ### Артефакты пайплайна ```bash gitflic cicd pipeline artifacts --project FerdBur/wave # список артефактов gitflic cicd pipeline artifacts --project FerdBur/wave --all gitflic cicd pipeline artifacts-download --project FerdBur/wave \ --out pipeline-artifacts.zip # скачать архив ``` ### Джобы ```bash gitflic cicd jobs --project FerdBur/wave # джобы пайплайна gitflic cicd jobs --project FerdBur/wave --all gitflic cicd job get --project FerdBur/wave # одна джоба gitflic cicd job restart --project FerdBur/wave gitflic cicd job cancel --project FerdBur/wave ``` ### Артефакты джобы ```bash gitflic cicd job artifacts --project FerdBur/wave --all # список gitflic cicd job artifacts-download --project FerdBur/wave \ --out job-artifacts.zip # все артефакты архивом gitflic cicd job artifact-download --project FerdBur/wave \ --out artifact.bin # один артефакт gitflic cicd job artifact-lock --project FerdBur/wave gitflic cicd job artifact-unlock --project FerdBur/wave gitflic cicd job delete-artifact --project FerdBur/wave ``` ### Переменные CI/CD По умолчанию — переменные уровня проекта. Для company/team-уровня — `--scope`, для инстанса — `--scope admin` (нужны права администратора). ```bash gitflic cicd variable --project FerdBur/wave # переменные проекта gitflic cicd variable --scope team --team tikhon --format json # переменные команды gitflic cicd variable --scope company --company acme # переменные компании gitflic cicd variable --scope admin # инстанс (admin-only) ``` ### Время хранения пайплайнов (pipeline-lifetime) Настраивается на уровне company/team (нужен `--team/--company ` или `--scope`). ```bash gitflic cicd pipeline-lifetime get --team tikhon --format json gitflic cicd pipeline-lifetime edit --team tikhon --lifetime 30 --enabled true gitflic cicd pipeline-lifetime apply-settings-to-projects --team tikhon # применить ко всем проектам scope ``` > `cicd pipeline ` на публичном `api.gitflic.ru` может вернуть 404 — поведение GitFlic, см. known-issues. Используйте `cicd pipeline list`. ## runner Раннеры (CI/CD-агенты). Область задаётся флагом `--scope project|company|instance`: - `--scope project` (по умолчанию) — раннеры проекта (резолвится по `--project owner/alias` или git origin) - `--scope company --company ` — раннеры компании - `--scope instance` — раннеры всего сервиса через `/admin/runners` (нужны права администратора инстанса) ```bash gitflic runner list --project FerdBur/wave --all # раннеры в scope gitflic runner list --scope company --company acme --format json gitflic runner get --project FerdBur/wave # один раннер # Джобы раннера (или всех раннеров scope) gitflic runner jobs --project FerdBur/wave gitflic runner jobs --status RUNNING --project FerdBur/wave # Регистрация gitflic runner registration-info --scope company --company acme # URL + токен регистрации gitflic runner reset-token --scope instance # сброс токена (instance, admin) # Управление gitflic runner edit --project FerdBur/wave \ --name build-01 --active true --tags linux,docker \ --run-untagged false --max-timeout 3600 --locked false --protected true gitflic runner shutdown --project FerdBur/wave gitflic runner delete --project FerdBur/wave ``` > `--scope instance` (и `reset-token`) требуют прав администратора инстанса — обычный токен получит 403/404. Реализовано по спеке, протестировать на публичном SaaS нельзя. ## webhook Вебхуки проекта (требуют `--project owner/alias`). ```bash gitflic webhook list --project FerdBur/wave gitflic webhook get --project FerdBur/wave # Создание (по умолчанию включены все события) gitflic webhook create --project FerdBur/wave \ --url https://example.com/hook \ --secret s3cr3t \ --event PUSH --event MERGE_REQUEST_CREATE --event MERGE gitflic webhook update --project FerdBur/wave \ --url https://example.com/hook2 --event PIPELINE_FAIL # незаданные поля сохраняются gitflic webhook delete --project FerdBur/wave ``` События: `COLLABORATOR_ADD`, `COLLABORATOR_DELETE`, `COLLABORATOR_UPDATE`, `ISSUE_UPDATE`, `ISSUE_CREATE`, `NEW_ISSUE_NOTE`, `TAG_DELETE`, `TAG_CREATE`, `BRANCH_UPDATE`, `BRANCH_DELETE`, `BRANCH_CREATE`, `MERGE_REQUEST_CREATE`, `MERGE_REQUEST_UPDATE`, `MERGE`, `MERGE_REQUEST_CLOSE`, `MERGE_REQUEST_CANCEL`, `MERGE_REQUEST_ACCEPT`, `DISCUSSION_CREATE`, `DISCUSSION_COMMENT_CREATE`, `PIPELINE_NEW`, `PIPELINE_SUCCESS`, `PIPELINE_FAIL`, `WEBHOOK_SEND`. ## environment Environment protection rules — на уровне team/company, не проекта. ```bash gitflic environment protection list --project tikhon # project тут = team alias gitflic environment protection create \ --project tikhon \ --template production \ --allow-to-deploy ADMINS gitflic environment protection delete --project tikhon ``` > Универсального CRUD для environments (создание/удаление как сущности) **нет в публичном REST**. Environments живут как deploy-targets per pipeline job, управляются через Web UI. ## См. также - [Проекты](project.md) - [Релизы](release.md) - [Все команды](/commands/) ================================================================================ # https://cli-gitflic.ru/commands/commit-blob.html ================================================================================ # Коммиты и файлы ## commit Команды коммитов требуют `--project owner/alias`. ### list / commits (список коммитов) ```bash gitflic commit list --project FerdBur/wave # коммиты default branch gitflic commit list --project FerdBur/wave --branch feature/x # другой ветки gitflic commit list --project FerdBur/wave --page 0 --size 100 ``` `commits` — тот же список, но через эндпоинт `/commits` (альтернативная пагинация): ```bash gitflic commit commits --project FerdBur/wave --branch master --format json ``` ### get (один коммит) ```bash gitflic commit get abc1234 --project FerdBur/wave ``` ### files (файлы в коммите) ```bash gitflic commit files abc1234 --project FerdBur/wave # Список файлов, которых коснулся коммит. ``` ### diff (один файл) ```bash gitflic commit diff abc1234 src/auth/login.ts --project FerdBur/wave # Diff для конкретного файла в коммите. ``` ### for-file (последний коммит файла) ```bash gitflic commit for-file abc1234 src/auth/login.ts --project FerdBur/wave # Последний коммит, затронувший указанный файл. ``` ### compare (два коммита) ```bash gitflic commit compare abc1234 def5678 --project FerdBur/wave gitflic commit compare abc1234 def5678 --project FerdBur/wave --ignore-collapsed # Сравнение двух коммитов (commit/diff). ``` ### tag-diff (два тега) ```bash gitflic commit tag-diff v1.0.0 v1.1.0 --project FerdBur/wave gitflic commit tag-diff v1.0.0 v1.1.0 --project FerdBur/wave --ignore-collapsed # Diff между двумя тегами (tag/diff). ``` ### cherry-pick ```bash gitflic commit cherry-pick abc1234 feature/y --project FerdBur/wave gitflic commit cherry-pick abc1234 feature/y --project FerdBur/wave --new-branch hotfix/z # Применить коммит abc1234 на ветку feature/y (PUT branch/cherry-pick). # --new-branch создаёт новую ветку для cherry-pick. ``` ## blob Файлы репозитория. Принимают `--project owner/alias` либо автоопределение из git-репозитория. ### get (текст файла, raw) ```bash # Текстовый файл (вывод в stdout) gitflic blob get README.md --commit master --project FerdBur/wave gitflic blob get src/index.ts --commit abc1234 --project FerdBur/wave ``` ### download (бинарь на диск) ```bash # Бинарно-безопасное скачивание файла на диск gitflic blob download logo.png --commit master --out /tmp/logo.png --project FerdBur/wave ``` ### recursive (рекурсивный список) ```bash # Список файлов (json) от каталога вглубь до depth (макс. 10) gitflic blob recursive --commit master --project FerdBur/wave gitflic blob recursive --commit master --directory src --depth 3 --project FerdBur/wave ``` ### file-size (размер файла) ```bash # Размер файла в байтах (резолвит UUID проекта) gitflic blob file-size README.md --branch master --project FerdBur/wave ``` > 💡 Для бинарных файлов используй `blob download` — он сохраняет байты на диск без искажений. `blob get` отдаёт сырой текст в stdout. ## См. также - [Merge Requests](mr.md) - [Ветки и теги](branch-tag.md) - [Проекты](project.md) ================================================================================ # https://cli-gitflic.ru/commands/completion.html ================================================================================ # `completion` Shell completion для bash/zsh/fish. ## bash ```bash # Временно (текущая сессия) eval "$(gitflic completion bash)" # Постоянно — добавь в ~/.bashrc echo 'eval "$(gitflic completion bash)"' >> ~/.bashrc ``` ## zsh ```zsh # В fpath (рекомендуется) gitflic completion zsh > "${fpath[1]}/_gitflic" # Или source напрямую gitflic completion zsh > _gitflic.zsh echo 'source /path/to/_gitflic.zsh' >> ~/.zshrc ``` ## fish ```fish gitflic completion fish > ~/.config/fish/completions/gitflic.fish ``` ## Что комплитится - Все 21 top-level команд - Все sub-команды внутри каждого модуля - Флаги: `--project`, `--api-base`, `--token`, `--format`, `--page`, `--size`, `--all`, `--stream`, `--tui` - Для `auth` дополнительно: `--as`, `--stdin`, `--reveal`, `--all` - Для `alias` дополнительно: известные ключи (`default-project`, `api-base`, `token`) ## Проверить После установки: ```bash gitflic # покажет: auth mr branch tag release issue commit blob ... gitflic mr # покажет: list view diff create edit approve merge ... gitflic mr list -- # покажет: --project --api-base --token --format --all ... ``` ## См. также - [Установка](../install.md) - [Флаги](../flags.md) - [Все команды](/commands/) ================================================================================ # https://cli-gitflic.ru/commands/ ================================================================================ # Команды Полный справочник по всем модулям CLI. Покрытие GitFlic REST API — ~100%. Каждый модуль — отдельная страница с примерами и флагами. ## Содержание - **[`auth`](/auth/)** — login, logout, status, switch, multi-account, per-project bindings. - **[`mr`](mr.md)** — merge requests (list, view, diff, create, approve, merge, close, cancel, comments, discussions, settings). - **[`branch`](branch-tag.md#branch)** — ветки: list, get, create, delete + protection rules. - **[`tag`](branch-tag.md#tag)** — теги: list, get, create, delete. - **[`release`](release.md)** — релизы (CRUD) + upload ассетов. - **[`issue`](issue.md)** — задачи: list, view, create, edit, close, reopen, comment + relations + attachment upload. - **[`commit`](commit-blob.md#commit)** — коммиты: list, get, show (diff). - **[`blob`](commit-blob.md#blob)** — файлы и blob'ы репозитория (get, raw). - **[`project`](project.md)** — CRUD проектов, members, teams, archive, files, followers, stars, fork, mirror, import, deploy tokens. - **[`user`](user-team.md#user)** — me, search, by-id. - **[`settings`](settings.md)** — настройки аккаунта: ssh, oauth, access-token, transport-token, change-email, username, password. - **[`team`](user-team.md#team)** — команды: list, get, create, edit, delete, members. - **[`company`](user-team.md#company)** — компании: list, get. - **[`environment`](cicd-webhook.md#environment)** — environments: list, get, create, edit, delete. - **[`webhook`](cicd-webhook.md#webhook)** — вебхуки проекта: list, get, create, edit, delete. - **[`registry`](registry.md)** — реестр пакетов (scopes: project/company/instance): `registry package` (list/get/versions/files/upload/download/delete) + `registry repo` (registry-repository, Enterprise/Atlas-only). - **[`cicd`](cicd-webhook.md#cicd)** — пайплайны и джобы. - **[`runner`](cicd-webhook.md#runner)** — CI/CD runners / агенты. - **[`admin`](./admin.md)** — admin-эндпоинты (только для инстанс-админов). - **[`saml`](./saml.md)** — SAML SSO (только для инстанс-админов). - **[`cache`](./cache.md)** — локальный кеш project UUID. - **[`completion`](./completion.md)** — shell completion (bash/zsh/fish). - **[`alias`](./alias.md)** — persistent user config (default-project, api-base и т.д.). ## Глобальные флаги Почти все команды принимают: | Флаг | Что делает | Default | |---|---|---| | `--project /` | Целевой проект | авто-детект из `git remote get-url origin` или из `default-project` config | | `--api-base ` | API endpoint | `https://api.gitflic.ru` или `GITFLIC_API_BASE` | | `--token ` | Токен (per-call override) | из env / keychain / active-account | | `--format json\|pretty` | Формат вывода | pretty для list, json для single | | `--page ` | Номер страницы (1-based) | 1 | | `--size ` | Размер страницы | 20 (зависит от эндпоинта) | | `--all` | Авто-пагинация до конца | false | | `--stream` | NDJSON в stdout (для пайплайнов) | false | | `-h`, `--help` | Справка по команде | — | ## Глобальные ENV переменные См. [env.md](../env.md) — полный список. Самые важные: - `GITFLIC_TOKEN` — override токена (полезно в CI). - `GITFLIC_API_BASE` — для self-hosted. - `GITFLIC_HTTP_RETRIES` — макс. ретраев на 429/502/503/504 (default 3). - `GITFLIC_NO_RETRY=1` — отключить ретраи. - `GITFLIC_NO_CACHE=1` — отключить кеш project UUID. - `GITFLIC_NO_CONFIG=1` — отключить чтение `~/.config/gitflic-cli/config.json`. - `GITFLIC_NO_SECRET_STORE=1` — отключить хранение токенов в keychain (только env var). - `NO_COLOR=1` / `FORCE_COLOR=1` — управление цветом (по [no-color.org](https://no-color.org)). ## Выход и пайплайны ### Stable JSON Каждая команда с `--format json` (или при одиночном запросе) выдаёт стабильный JSON. Exit code = 0 при успехе, 1 при любой HTTP-ошибке. ```bash gitflic mr list --project tikhon/wave --format json | jq '._embedded.mergeRequestModelList | length' ``` ### NDJSON streaming `--stream` (или `GITFLIC_STREAM=1`) — одна JSON-запись на строку, не дожидаясь конца пагинации: ```bash gitflic mr list --project tikhon/wave --all --stream | jq -c 'select(.status.id == "OPENED") | {id: .localId, title: .title}' ``` Идеально для долгих запросов в большие репо — видишь результаты сразу, а не через минуту после полной пагинации. ### TUI mode `gitflic mr list --tui` — интерактивный браузер в TTY. Управление: `j/k` (next/prev), `g/G` (top/bottom), `Enter` (print localId в stdout, удобно для пайпа), `q/Esc` (выход). ```bash gitflic mr list --tui --project FerdBur/wave ``` Подробнее — [mr.md](mr.md#tui-mode). ## Ошибки и коды возврата | Exit code | Значение | |---|---| | 0 | Успех | | 1 | HTTP-ошибка (4xx/5xx), network error, или `die()` от любой проверки | | 2 | Usage error (не хватает аргументов, плохой формат) | В stderr — человекочитаемое объяснение с URL и HTTP status. В stdout (если `--format json`) — JSON с полями `{ message, error, ... }`. ## Конфигурация CLI хранит persistent state в: - **macOS** → `~/Library/Keychains/login.keychain-db` (зашифровано) - **Linux** → GNOME Keyring / KWallet (зашифровано) - **иначе** → `~/.config/gitflic-cli/config.json` (`chmod 0600`) Управляется через [alias](../commands/alias.md) (config-ключи) и [auth](/auth/) (токены + привязки). ## Отладка ```bash GITFLIC_HTTP_RETRIES=0 GITFLIC_NO_RETRY=1 gitflic mr list --project x/y # Без ретраев — увидишь оригинальную ошибку сразу. gitflic mr list --project x/y --format json | jq . # Сырой JSON для inspection. gitflic --help # Полный help по top-level командам. ``` ================================================================================ # https://cli-gitflic.ru/commands/issue.html ================================================================================ # Задачи (`gitflic issue ...`) Полный CRUD + комментарии + связи (relations) + работа с файлами + загрузка вложений. ## Подкоманды ```bash gitflic issue list --project FerdBur/wave # все gitflic issue list --project FerdBur/wave --status OPEN # фильтр по статусу gitflic issue list --project FerdBur/wave --all --format json # с автопагинацией gitflic issue view --project FerdBur/wave # детали ``` ### create ```bash gitflic issue create --project FerdBur/wave \ --title "Bug: login broken" \ --description "Steps to reproduce..." # С опциональными полями gitflic issue create --project FerdBur/wave \ --title "Feature: dark mode" \ --description "..." \ --assign-to \ --label \ --status OPEN # OPEN | IN_PROGRESS | CLOSED | COMPLETED ``` ### edit ```bash gitflic issue edit --project FerdBur/wave \ --title "New title" \ --description "..." \ --status IN_PROGRESS \ --assign-to \ --label ``` ### close / reopen ```bash gitflic issue close --project FerdBur/wave # shortcut: edit --status CLOSED gitflic issue reopen --project FerdBur/wave # shortcut: edit --status OPEN ``` ### delete ```bash gitflic issue delete --project FerdBur/wave ``` ### Комментарии ```bash gitflic issue comments list --project FerdBur/wave gitflic issue comments add "Comment text" --project FerdBur/wave gitflic issue comments edit "New text" --project FerdBur/wave gitflic issue comments delete --project FerdBur/wave ``` ### Связи (relations) Связи между задачами (зависимости, блокировки, «связано с» и т.п.). Поддерживается полный CRUD. ```bash gitflic issue relations list --project FerdBur/wave # Создать связь с другой задачей (по её UUID) gitflic issue relations create RELATED --project FerdBur/wave # Типы: RELATED, AFFECTS_FORWARD, DEPENDENCY_FORWARD, ... (см. документацию GitFlic) # Удалить связь gitflic issue relations delete --project FerdBur/wave ``` ### Файлы Просмотр и управление файлами, прикреплёнными к задаче. `link`/`unlink` оперируют уже загруженными в проект файлами по их UUID. ```bash gitflic issue files list --project FerdBur/wave --format json # Привязать уже загруженный файл проекта к задаче gitflic issue files link --project FerdBur/wave # Отвязать (и удалить) файл от задачи gitflic issue files unlink --project FerdBur/wave ``` ### Загрузка вложений `issue attach` — основной способ: загружает файл в проект и сразу привязывает его к задаче (upload + link одним вызовом). ```bash gitflic issue attach ./screenshot.png --project FerdBur/wave gitflic issue attach ./logs.txt --name debug-logs.txt --project FerdBur/wave ``` Команда `issue attachment upload` оставлена как legacy-вариант (одиночный best-guess endpoint); для новых сценариев используйте `issue attach`. ```bash gitflic issue attachment upload ./screenshot.png --project FerdBur/wave ``` ## Пайплайн: triage ```bash # Все открытые без assignee gitflic issue list --project FerdBur/wave --status OPEN --all --format json \ | jq -r '.[] | select(.assignee == null) | "#\(.localId) \(.title)"' ``` ## См. также - [Merge Requests](mr.md) - [Пользователи и команды](user-team.md) - [Все команды](/commands/) ================================================================================ # https://cli-gitflic.ru/commands/mr.html ================================================================================ # Merge Requests (`gitflic mr ...`) Главный модуль. Покрывает полный жизненный цикл MR: list → view → create → review → approve/merge → close. ## Подкоманды ### list ```bash gitflic mr list --project FerdBur/wave # дефолтные фильтры gitflic mr list --project FerdBur/wave --all # авто-пагинация gitflic mr list --project FerdBur/wave --stream # NDJSON gitflic mr list --project FerdBur/wave --tui # интерактивный браузер gitflic mr list --project FerdBur/wave --size 50 # 50 на страницу gitflic mr list --project FerdBur/wave --format json # JSON для jq ``` Параметры пагинации: `--page`, `--size`. Без `--all` показывает только первую страницу (default 20 элементов). ### view ```bash gitflic mr view 42 --project FerdBur/wave # Полная JSON-карточка MR: title, description, source/target branches, # author, reviewers, labels, статус, даты. ``` ### diff ```bash gitflic mr diff 42 --project FerdBur/wave # File-level diff: список файлов с добавленными/удалёнными строками. ``` ### by-commit ```bash gitflic mr by-commit abc1234 --project FerdBur/wave # Найти MR, содержащие данный commit hash. ``` ### create ```bash gitflic mr create --project FerdBur/wave \ --title "Fix login bug" \ --description "Fixes #123" \ --to main # source-ветка = текущая ветка (или --from если указана явно) ``` Флаги: - `--title ` — заголовок (обязательный) - `--description ` — описание (опционально) - `--to ` — целевая ветка (default = default branch проекта) - `--from ` — source-ветка (default = текущая) - `--squash` — squash commits при merge - `--no-remove-branch` — НЕ удалять source-ветку после merge ### edit ```bash gitflic mr edit 42 --project FerdBur/wave --title "New title" gitflic mr edit 42 --project FerdBur/wave --description "..." gitflic mr edit 42 --project FerdBur/wave --to develop # сменить target # Source-ветку менять нельзя (ограничение GitFlic API). ``` ### approve ```bash gitflic mr approve 42 --project FerdBur/wave # Toggle approve: если уже аппрувнул — снимает. ``` ### merge ```bash gitflic mr merge 42 --project FerdBur/wave gitflic mr merge 42 --project FerdBur/wave --message "Squash: fix login" gitflic mr merge 42 --project FerdBur/wave --squash-message "single commit msg" ``` ### close / cancel ```bash gitflic mr close 42 --project FerdBur/wave gitflic mr cancel 42 --project FerdBur/wave ``` ### comment ```bash # Обычный комментарий (общий к MR) gitflic mr comment 42 --project FerdBur/wave "Please rebase" # Inline-комментарий (привязан к строке в файле) gitflic mr comment 42 --project FerdBur/wave "Why this? " \ --new-path src/login.ts --new-line 42 # Diff-side (старый или новый) gitflic mr comment 42 --project FerdBur/wave "Fix this" \ --old-path src/old.ts --old-line 10 --new-path src/new.ts --new-line 12 ``` ### discuss (обсуждения / threaded comments) ```bash gitflic mr discuss list 42 --project FerdBur/wave gitflic mr discuss get 42 --project FerdBur/wave # один тред целиком gitflic mr discuss reply 42 "My reply" --project FerdBur/wave gitflic mr discuss resolve 42 --project FerdBur/wave gitflic mr discuss delete 42 --project FerdBur/wave ``` ## Настройки MR (company / team) Эти подкоманды управляют политиками MR на уровне **компании или команды** (approval-правила, конфигурация аппрувов, squash, метод merge, шаблон описания). Требуется указать scope: - напрямую: `--company ` или `--team `; - либо `--scope company|team` вместе с `--project owner/alias` (контекст проекта всё равно должен резолвиться). ### approval rule (правила аппрува) ```bash gitflic mr approval rule list --scope team --team backend --format json gitflic mr approval rule get --scope team --team backend gitflic mr approval rule create --scope team --team backend \ --name "main protection" --target-branch main \ --minimal-approvals 2 --approvers tikhon,alice gitflic mr approval rule edit --uuid --scope team --team backend \ --minimal-approvals 1 gitflic mr approval rule delete --scope team --team backend ``` ### approval configuration (общая конфигурация аппрувов) ```bash gitflic mr approval configuration get --company acme --format json gitflic mr approval configuration edit --company acme \ --minimal-approvals 2 \ --reset-approvals-on-push true \ --require-all-discussions-resolved true \ --author-can-approve false # Полный контроль над телом запроса: gitflic mr approval configuration edit --company acme --json '{"minimalApprovals":3}' ``` ### settings (squash / merge-method / template) ```bash gitflic mr settings squash --team backend # текущее значение gitflic mr settings squash-edit --team backend --enabled true gitflic mr settings method-type --company acme # текущий метод merge gitflic mr settings method-type-edit --company acme --type SQUASH gitflic mr settings template --team backend # шаблон описания MR gitflic mr settings template-edit --team backend \ --template "## Что изменилось\n\n## Как проверить" ``` Все `*-edit` подкоманды дополнительно принимают `--json ''` для полного контроля над телом запроса. ### apply-settings ```bash gitflic mr apply-settings --company acme # Применить настройки MR компании/команды ко всем её проектам. ``` ## TUI mode ```bash gitflic mr list --tui --project FerdBur/wave ``` Запускается только в TTY. Если stdin/stdout не TTY — fallback на plain list + warning. Клавиши: | Клавиша | Действие | |---|---| | `j` / `↓` | следующий MR | | `k` / `↑` | предыдущий MR | | `g` | первый | | `G` | последний | | `Enter` | напечатать `localId` в stdout (для пайпа: `gitflic mr list --tui \| xargs -I{} gitflic mr view {}`) | | `q` / `Esc` | выход | ## Примеры пайплайнов ### Список открытых MR с автором ```bash gitflic mr list --project FerdBur/wave --all --format json \ | jq -r '.["merge-request-model-list"]? // ._embedded.mergeRequestModelList? // .[] | select(.status.id == "OPENED") | "#\(.localId) [\(.author.alias // "?")] \(.title)"' ``` ### Закрыть все MR старше 30 дней ```bash gitflic mr list --project FerdBur/wave --all --format json \ | jq -r '.[] | select(.status.id == "OPENED") | select(.updatedAt < (now - 2592000 | todate)) | .localId' \ | xargs -I{} gitflic mr close {} --project FerdBur/wave ``` ### Approve все MR где я ревьюер ```bash gitflic mr list --project FerdBur/wave --all --format json \ | jq -r '.[] | select(.reviewers[]?.alias == "tikhon") | select(.approved == false) | .localId' \ | xargs -I{} gitflic mr approve {} --project FerdBur/wave ``` ## Известные ограничения - `mr merge` на свежем проекте может упасть с `MergeCheckException`, если default branch protection требует approve от не-автора. Это поведение GitFlic, не баг CLI. - Source-ветку существующего MR менять нельзя (`mr edit` принимает только `--to`, не `--from`) — ограничение GitFlic API. ## См. также - [Задачи](issue.md) - [Ветки и теги](branch-tag.md) - [Все команды](/commands/) ================================================================================ # https://cli-gitflic.ru/commands/project.html ================================================================================ # Проекты ```bash gitflic project list # все доступные gitflic project list --scope my # только мои gitflic project list --scope shared # расшаренные мне gitflic project list --scope public --q "wave" # поиск по публичным gitflic project get tikhon/gitflic-cli # детали (alias или UUID) ``` `project list` поддерживает фильтры и пагинацию: `--q `, `--q-name `, `--q-owner `, `--page N`, `--size N`, `--all` (выгрузить все страницы). ```bash # Поиск по имени и владельцу, JSON для агентов gitflic project list --scope public --q-name wave --q-owner FerdBur --format json ``` ## CRUD ```bash # create gitflic project create \ --alias my-project \ --title "My Project" \ --private \ --language "JavaScript" \ --description "..." # Создание под командой/компанией: gitflic project create --alias team-proj --title "Team Project" \ --owner-alias my-team --owner-alias-type TEAM # edit (PUT /project) gitflic project edit tikhon/my-project \ --title "New title" \ --default-branch develop \ --public # delete gitflic project delete tikhon/my-project ``` ### Настройки проекта `change-setting` обновляет настройки проекта (заголовок, описание, язык, темы) через `PUT .../setting/change-setting`: ```bash gitflic project change-setting --project tikhon/wave \ --title "Wave" \ --description "Новое описание" \ --language Go \ --topics cli,api,gitflic ``` ### Где можно создавать проекты ```bash # Список владельцев (вы + ваши команды/компании), под которыми можно создать проект gitflic project allowed-owners --format json ``` ### Размер хранилища ```bash # Разбивка по размеру (по умолчанию — текущий --project) gitflic project project-size tikhon/wave gitflic project project-size --format json ``` ## Members ```bash gitflic project member list --project tikhon/wave gitflic project member invite user-alias --project tikhon/wave --role DEVELOPER gitflic project member role user-alias --project tikhon/wave --role ADMIN gitflic project member delete user-alias --project tikhon/wave # Роли: GUEST | REPORTER | DEVELOPER | ADMIN | OWNER ``` ## Teams ```bash gitflic project team invite team-alias --project tikhon/wave --role DEVELOPER gitflic project team role team-alias --project tikhon/wave --role ADMIN gitflic project team delete team-alias --project tikhon/wave # Роли для команд: GUEST | REPORTER | DEVELOPER | ADMIN ``` ## Archive / files / attachments / social ```bash # Список файлов в дереве репозитория gitflic project files --project tikhon/wave --path src --branch master # Followers / stars / forks gitflic project followers --project tikhon/wave gitflic project stars --project tikhon/wave gitflic project forked --project tikhon/wave ``` ### Вложения (attachments) ```bash # Список прикреплённых файлов gitflic project upload-files --project tikhon/wave # Загрузить файл (multipart, до 10 МБ) gitflic project upload ./screenshot.zip --project tikhon/wave # Удалить вложение по UUID gitflic project delete-file --project tikhon/wave ``` > **Архив проекта.** `gitflic project archive [branch] [--out FILE]` реализован > (`GET .../file/getArchive`), но на публичном `api.gitflic.ru` эндпоинт возвращает > **404** — скачивание архива отключено (доступно только через веб-интерфейс). > Используйте `git clone`. ## Fork / mirror / import ```bash # Fork (POST .../create-fork) — форк под текущим юзером или другим владельцем gitflic project fork --project FerdBur/wave --new-alias my-fork gitflic project fork --project FerdBur/wave --new-alias team-fork \ --owner-alias my-team --private # Создать новый mirror-проект (без --project) gitflic project create-mirror \ --url https://github.com/foo/bar.git \ --alias my-mirror \ --type PULL \ --login my-login --token-secret \ --ref-spec "+refs/heads/*:refs/heads/*" # type: PULL | PUSH # Превратить существующий проект в PUSH-зеркало gitflic project to-push-mirror --project tikhon/wave \ --source https://github.com/foo/bar.git \ --login my-login --token-secret # Принудительно синхронизировать зеркало gitflic project manual-update --project tikhon/my-mirror # Import (импорт из external repo, без --project) gitflic project import \ --url https://github.com/foo/bar.git \ --new-alias imported \ --private ``` ## Scripts ```bash # Запустить скрипт проекта по UUID gitflic project run-script --project tikhon/wave ``` ## Deploy tokens ```bash gitflic project deploy-token create --project tikhon/wave \ --name "CI deploy" \ --scope REPOSITORY_READ \ --expires 2026-12-31T00:00:00Z # Скоупы: REPOSITORY_READ | REPOSITORY_WRITE # Для HTTPS push без пароля (вместо SSH). ``` > **HTTPS push с токеном** работает напрямую: > `git push https://oauth2:@gitflic.ru/project//.git ` ## Команды/компании как владельцы Многие операции принимают владельца через `--owner-alias` (+ `--owner-alias-type USER|TEAM|COMPANY` для `create`): ```bash gitflic project create --alias x --title "X" --owner-alias acme --owner-alias-type COMPANY gitflic project fork --project FerdBur/wave --new-alias x --owner-alias acme ``` ## Авто-детект проекта `gitflic` без `--project` пытается определить проект из `git remote get-url origin`: ```bash cd ~/code/FerdBur/wave # клонированный репо git remote -v # origin = git@gitflic.ru:FerdBur/wave.git gitflic mr list # → flags.project = "FerdBur/wave" (автоматически) ``` Если авто-детект не сработал — `default-project` config: ```bash gitflic alias set default-project tikhon/gitflic-cli cd ~/anywhere gitflic mr list # → использует tikhon/gitflic-cli как fallback ``` ## См. также - [Пользователи и команды](user-team.md) - [CI/CD, вебхуки, агенты](cicd-webhook.md) - [Все команды](/commands/) ================================================================================ # https://cli-gitflic.ru/commands/registry.html ================================================================================ # Реестр пакетов GitFlic registry поддерживает несколько форматов пакетов (Maven, NPM, PyPI, NuGet, Composer, OPM, CRAN, RubyGem, Cargo, Conda, generic). CLI покрывает полностью: список/просмотр/версии/файлы/удаление пакетов, а также upload/download артефактов для всех форматов. Команда `registry` — **глобальная**: scope задаётся явно. ## Scope ```bash # Project-scope (по умолчанию; --project обязателен) --scope project --project / # Company-scope --scope company --company # Instance-scope (пакеты: "global") --scope instance ``` ## registry package ### list Список пакетов в выбранном scope. ```bash gitflic registry package list --project tikhon/wave gitflic registry package list --scope company --company acme --type maven gitflic registry package list --scope instance --format json # Пагинация gitflic registry package list --project tikhon/wave --page 2 --size 50 ``` ### get Один пакет по UUID. ```bash gitflic registry package get --project tikhon/wave --format json ``` ### versions Список версий пакета. ```bash gitflic registry package versions --project tikhon/wave gitflic registry package versions --project tikhon/wave --page 2 ``` ### version Одна версия пакета. ```bash gitflic registry package version 1.0.0 --project tikhon/wave --format json ``` ### files Файлы пакета (опционально по версии). ```bash gitflic registry package files --project tikhon/wave gitflic registry package files --version 1.0.0 --project tikhon/wave ``` ### delete / delete-version / delete-file Удаление пакета, версии или файла (через `POST .../delete`). ```bash gitflic registry package delete --project tikhon/wave gitflic registry package delete-version 1.0.0 --project tikhon/wave gitflic registry package delete-file 1.0.0 --project tikhon/wave ``` ### upload Загрузка артефакта (raw PUT). Формат задаётся флагом `--fmt` (**не** `--format` — он зарезервирован под вывод `json|pretty`). Координаты зависят от формата. ```bash # Maven: groupId artifactId version [file] gitflic registry package upload --fmt maven --project tikhon/wave ./app-1.0.jar com.acme app 1.0 # NPM: name version [file]; scope через --npm-scope gitflic registry package upload --fmt npm --project tikhon/wave ./my-pkg-1.0.tgz my-pkg 1.0 # PyPI / generic: name version [file] gitflic registry package upload --fmt pypi --project tikhon/wave ./dist.whl mypkg 1.0 # NuGet / RubyGem / Cargo: только файл gitflic registry package upload --fmt nuget --project tikhon/wave ./pkg.1.0.0.nupkg # Свой content-type при необходимости gitflic registry package upload --fmt generic --project tikhon/wave ./blob.bin myblob 1.0 --content-type application/octet-stream ``` Координаты по форматам: `generic/npm/pypi` = `name version [file]`; `maven` = `groupId artifactId version [file]`; `composer` = `version`; `cran` = `languageVersion [file]`; `conda` = `channel [file]`; `opm` = `[file]`; `nuget/rubygem/cargo` = только файл. > GitFlic валидирует тип файла (allowlist). Архивы (`.zip` и т.п.) проходят, а `.txt`/`.png` могут вернуть HTTP 415 — это серверное ограничение, не баг CLI. ### download Скачивание артефакта (GET). Формат — через `--fmt`, путь сохранения — `--out`. ```bash gitflic registry package download --fmt npm --project tikhon/wave my-pkg my-pkg-1.0.tgz --out ./out.tgz gitflic registry package download --fmt maven --project tikhon/wave 1.0 --out ./app.jar ``` Координаты по форматам: `generic/npm/pypi/opm` = `name version file`; `maven` = `packageUuid version fileUuid`; `nuget/rubygem/cargo/composer` = `name version` (`composer` = `groupId artifactId version`); `cran` = `file languageVersion platform`; `conda` = `platform file`. ### composer-tag Собрать Composer-пакет из git-тега. ```bash gitflic registry package composer-tag --tag v1.2.0 --project tikhon/wave ``` ## registry repo (Enterprise) > Раздел реестров репозиториев (registry-repository) доступен только в Enterprise/Atlas. На публичном SaaS (`api.gitflic.ru`) команды возвращают 404 — реализованы по спецификации, но работают только в self-hosted инсталляции. ```bash # Список / получение gitflic registry repo list --scope instance gitflic registry repo get # Создание (rt: LOCAL|PROXY|LOCAL_CACHE|VIRTUAL|TRASH_CAN) gitflic registry repo create --title "npm-local" --repository-type LOCAL --package-type npm --description "internal npm" # Редактирование / удаление gitflic registry repo edit --title "npm-local-2" gitflic registry repo delete # Пакеты внутри репозитория gitflic registry repo packages --type npm gitflic registry repo package gitflic registry repo package-versions gitflic registry repo package-version 1.0.0 gitflic registry repo package-files --version 1.0.0 gitflic registry repo delete-package gitflic registry repo delete-package-version 1.0.0 # Upload/download (формат — через --format, путь узла — --node-path) gitflic registry repo upload --format maven ./app-1.0.jar com.acme app 1.0 gitflic registry repo download --format npm my-pkg my-pkg-1.0.tgz --out ./out.tgz ``` ## Устаревшие алиасы Сохранены для обратной совместимости: ```bash gitflic registry list # -> alias of 'registry package list' gitflic registry repos # -> alias of 'registry repo list --scope instance' ``` ## См. также - [Релизы](release.md) - [Известные проблемы](../known-issues.md) - [Все команды](/commands/) ================================================================================ # https://cli-gitflic.ru/commands/release.html ================================================================================ # Релизы (`gitflic release ...`) CRUD релизов + **multipart-загрузка файлов** (download / delete-file). ## Подкоманды ```bash gitflic release list --project FerdBur/wave # список релизов gitflic release list --project FerdBur/wave --all --format json # авто-пагинация gitflic release get --project FerdBur/wave # детали релиза gitflic release latest --project FerdBur/wave # последний релиз ``` ### create ```bash gitflic release create --project FerdBur/wave \ --title "v1.0.0" \ --description "Release notes here" \ --tag v1.0.0 \ --pre-release # пометить как pre-release ``` Можно также прикрепить архив прямо при создании: ```bash gitflic release create --project FerdBur/wave \ --title "v1.0.0" \ --tag v1.0.0 \ --attach-archive \ --archive-format tar.gz ``` ### edit Редактирует только метаданные релиза (файлы через этот API не редактируются — см. `upload` / `delete-file`). ```bash gitflic release edit --project FerdBur/wave \ --title "v1.0.1" \ --description "Updated notes" \ --pre-release false ``` ### delete ```bash gitflic release delete --project FerdBur/wave ``` ### upload — **multipart** Загружает файл в релиз. CLI использует `multipart/form-data` (поле `files`) через встроенный `FormData` Node (Node 18+). ```bash gitflic release upload ./bin/myapp \ --project FerdBur/wave \ --name myapp-linux-x64 # опционально, default = basename файла gitflic release upload ./dist/myapp-1.0.0.tar.gz \ --project FerdBur/wave ``` > GitFlic проверяет тип файла по allowlist. Архивы (`.zip`, `.tar.gz` и т.п.) проходят, а `.txt` / `.png` могут вернуть **HTTP 415** — это серверное ограничение GitFlic, а не баг CLI. ### download Скачивает прикреплённый файл по его UUID. Без `--out` файл сохраняется под именем ``. ```bash gitflic release download --project FerdBur/wave --out ./myapp.tar.gz ``` ### delete-file Удаляет прикреплённый файл из релиза. ```bash gitflic release delete-file --project FerdBur/wave ``` ## Пример: полный release flow ```bash # Сборка npm run build tar czf myapp-1.0.0.tar.gz dist/ # Релиз с прикреплённым архивом gitflic release create --project FerdBur/wave \ --title "v1.0.0" \ --tag v1.0.0 \ --description "$(cat CHANGELOG.md)" \ --attach-archive \ --archive-format tar.gz # Или отдельно: создать релиз, потом залить файл UUID=$(gitflic release create --project FerdBur/wave --title "v1.0.0" --tag v1.0.0 --format json | jq -r '.id') gitflic release upload $UUID ./myapp-1.0.0.tar.gz --project FerdBur/wave # Список файлов релиза и скачивание gitflic release get $UUID --project FerdBur/wave --format json | jq '.attachmentFiles' gitflic release download $UUID --project FerdBur/wave --out ./myapp-1.0.0.tar.gz ``` ## См. также - [Ветки и теги](branch-tag.md) - [Реестр пакетов](registry.md) - [Релизы и артефакты](/releases/) ================================================================================ # https://cli-gitflic.ru/commands/saml.html ================================================================================ # SAML SSO (`gitflic saml ...`) > ⚠️ Admin-only. Требуются права администратора инстанса (для обычного токена — 403/404). Code-only — не live-tested на self-hosted с настроенным SAML. Управление SAML-подключениями (Single Sign-On) через `/admin/saml`. ## `saml list` Список SAML-подключений (`GET /admin/saml`). ```bash gitflic saml list gitflic saml list --page 0 --size 50 --format json ``` ## `saml create` Создать SAML-подключение (`POST /admin/saml`). ```bash gitflic saml create \ --name "Corp IdP" \ --idp-metadata-url https://idp.example.com/metadata \ --idp-issuer https://idp.example.com/entity \ --idp-initiated-sso-url https://idp.example.com/sso \ --cert ./idp-cert.pem ``` ## `saml edit` Изменить SAML-подключение по UUID (`PUT /admin/saml/{uuid}`). ```bash gitflic saml edit --name "New name" gitflic saml edit --idp-metadata-url https://idp.example.com/metadata2 ``` ## `saml change-status` Включить/выключить подключение (`PUT /admin/saml/{uuid}change-status`). ```bash gitflic saml change-status --enabled true gitflic saml change-status --enabled false ``` ## См. также - [Админ](admin.md) - [Аутентификация](/auth/) - [Известные проблемы](../known-issues.md) ================================================================================ # https://cli-gitflic.ru/commands/settings.html ================================================================================ # Настройки пользователя (`gitflic settings ...`) Управление SSH-ключами, OAuth-приложениями, токенами и профилем. ## SSH ключи ```bash # Добавить SSH-ключ (читает файл или stdin) gitflic settings ssh add ~/.ssh/id_ed25519.pub --title "macbook" # С expires gitflic settings ssh add ~/.ssh/id_ed25519.pub --title "temp" --expires 2026-12-31 ``` > ⚠️ List и delete SSH-ключей **не доступны через REST API**. Управляется только через Web UI. ## OAuth apps ```bash # Список своих OAuth-приложений gitflic settings oauth list gitflic settings oauth list --format json # Получить одно приложение по id gitflic settings oauth get # Создать приложение gitflic settings oauth create \ --name "My App" \ --homepage https://myapp.example.com \ --callback https://myapp.example.com/callback \ --description "..." # Standalone app (без редиректа, для service-to-service) gitflic settings oauth create \ --name "CI bot" \ --homepage https://ci.example.com \ --callback https://ci.example.com/cb \ --standalone # Редактировать приложение (имя обязательно, остальное опционально) gitflic settings oauth edit \ --name "My App v2" \ --homepage https://myapp.example.com \ --callback https://myapp.example.com/callback/v2 \ --description "обновлённое описание" gitflic settings oauth delete ``` ## Transport tokens (для git push через HTTPS) ```bash gitflic settings transport-token create \ --name "CI deploy" \ --scope READ_REGISTRY gitflic settings transport-token create \ --name "CI deploy" \ --scope READ_REGISTRY --scope WRITE_REGISTRY ``` > ⚠️ GitFlic **не принимает transport-token для HTTPS git push** (как и большинство GitLab-подобных серверов). Используйте SSH-ключ для git push. Transport-token работает только для registry (Maven/NPM/etc). ## Смена профиля ```bash gitflic settings change-email --email new@example.com gitflic settings change-username --username new-alias # НЕОБРАТИМО! gitflic settings change-password \ --old-password "old" \ --password "new" \ --password-confirm "new" ``` ## Access tokens (API-токены) Создание API-токена с явным набором прав. Права задаются повторяемым флагом `--scope` (`USER_READ`, `USER_WRITE`, `PROJECT_READ`, `PROJECT_WRITE`, `PROJECT_EDIT`, `TEAM_READ`, `TEAM_WRITE`, `COMPANY_READ`, `COMPANY_WRITE`, `READ_REGISTRY`, `WRITE_REGISTRY`). ```bash gitflic settings access-token create \ --name "CI read-only" \ --scope PROJECT_READ --scope USER_READ # С датой истечения gitflic settings access-token create \ --name "temp full" \ --scope PROJECT_READ --scope PROJECT_WRITE \ --expires 2026-12-31 ``` > ⚠️ По известным проблемам этот эндпоинт может требовать **HTTP Basic auth** (логин + пароль). > Если запрос возвращает 401/403, создайте токен через Web UI в **Профиль → API-токены → Создать**. ## См. также - [Аутентификация](/auth/) - [Пользователи и команды](user-team.md) - [Известные проблемы](../known-issues.md) ================================================================================ # https://cli-gitflic.ru/commands/user-team.html ================================================================================ # Пользователи, команды, компании Все list-команды поддерживают `--page N`, `--size N`, `--all`, `--stream` и `--format json`. ## user Команды для работы с пользователями (проект не требуется). ```bash gitflic user me # текущий юзер (с email) gitflic user me --format json gitflic user search --q "tikhon" # поиск (с пагинацией) gitflic user search --q "tikhon" --page 2 --size 50 gitflic user get tikhon # по alias gitflic user projects tikhon # публичные проекты юзера gitflic user projects tikhon --page 1 --size 50 --format json gitflic user followers tikhon # кто на него подписан gitflic user following tikhon # на кого он подписан ``` ## team Команды для работы с командами. Владелец создаваемой команды по умолчанию — вы; при желании можно указать другого владельца через `--owner`/`--owner-type`. ```bash gitflic team list # публичные команды gitflic team list --q "core" --page 1 --size 50 gitflic team my # команды, в которых вы состоите gitflic team shared # команды, расшаренные вам gitflic team get backend-team # одна команда по alias # создание (owner по умолчанию — вы) gitflic team create --alias core --title "Core Team" --private gitflic team create --alias core --title "Core Team" \ --description "Ядро" --owner acme --owner-type COMPANY # передача владения (замена отсутствующего edit/delete) gitflic team transfer --team core --owner newowner ``` ### team member ```bash gitflic team member list core # участники gitflic team member list core --q "tikhon" --format json gitflic team member invite core tikhon --role DEVELOPER # пригласить gitflic team member role core tikhon --role ADMIN # сменить роль gitflic team member remove core tikhon # удалить участника ``` Роли: `GUEST`, `REPORTER`, `DEVELOPER`, `ADMIN`. ### team import Управление тем, какие настройки-шаблоны (защита веток, окружения, теги и т.п.) импортируются в дочерние проекты команды. ```bash gitflic team import get core # текущее состояние импорта gitflic team import set core --branch --environment --tag --mr-approval --pipeline-lifetime ``` > ⚠️ В GitFlic REST нет эндпоинтов `team edit` и `team delete` (PUT/DELETE → 405) — переименование/удаление только через Web UI. Для смены владельца используйте `team transfer`. ## company Команды для работы с компаниями. ```bash gitflic company list # публичные компании gitflic company list --q "acme" gitflic company my # компании активного пользователя gitflic company shared # компании, где вы участвуете gitflic company get acme # одна компания по alias gitflic company create --title "Acme" --alias acme --private --description "Acme Inc." ``` ### company member ```bash gitflic company member list acme # участники gitflic company member list acme --q "tikhon" --format json gitflic company member invite acme tikhon DEVELOPER # добавить gitflic company member role acme tikhon ADMIN # сменить роль gitflic company member remove acme tikhon # удалить участника ``` Роли: `GUEST`, `REPORTER`, `DEVELOPER`, `ADMIN`. ### company import ```bash gitflic company import get acme # состояние настроек-импорта gitflic company import run acme --branch --environment --tag --mr-approval --pipeline-lifetime ``` > ⚠️ В GitFlic REST нет эндпоинтов `company edit` и `company delete` (PUT/DELETE → 405) — изменение/удаление компаний только через Web UI. ## См. также - [Проекты](project.md) - [Настройки пользователя](settings.md) - [Все команды](/commands/) ================================================================================ # https://cli-gitflic.ru/credential-helper.html ================================================================================ # Git credential helper > ⚠️ Не реализовано. Это страница-плейсхолдер для будущей фичи. `gitflic` можно зарегистрировать как **credential helper** для git — тогда `git push` и `git pull` автоматически получат токен через CLI. ## Как это должно работать ```bash git config --global credential.helper '!gitflic credential helper' git push origin main # CLI читает action из stdin, возвращает username + token ``` ## Формат credential helper Git вызывает credential helper через stdin/stdout: ``` action=get protocol=https host=gitflic.ru ``` Helper должен ответить (на stdout): ``` protocol=https host=gitflic.ru username=oauth2 password= ``` ## Почему пока не реализовано GitFlic поддерживает HTTPS push только с **SSH-ключом или Personal Access Token**. Transport-token (который CLI умеет создавать через `settings transport-token create`) НЕ работает для git push (см. [settings.md](commands/settings.md)). Так что для git push поверх HTTPS нужно: 1. Создать Personal Access Token через Web UI (CLI не поддерживает — basic auth нужен). 2. Передать его credential helper'у. Сложность vs выгода пока не в нашей пользе — большинство пользователей используют SSH. ## Если очень нужно Открой issue: https://gitflic.ru/project/tikhon/gitflic-cli/-/issues с описанием use-case. Реализуем, если спрос есть. ## См. также - [Аутентификация](/auth/) — хранение токена и resolution chain. - [settings](commands/settings.md) — SSH-ключи, access- и transport-токены. - [Известные проблемы](known-issues.md) — HTTPS git push с токеном и через SSH-ключ. ================================================================================ # https://cli-gitflic.ru/development.html ================================================================================ # Локальная разработка ## Структура репо ``` gitflic-cli/ ├── bin/gitflic # bash-шим → node lib/gitflic.mjs ├── lib/ │ ├── gitflic.mjs # entry: dispatcher │ ├── http.mjs # fetch + retry + parseArgs + resolveToken │ ├── secret.mjs # OS keychain / libsecret / chmod 0600 │ ├── config.mjs # persistent config (chmod 0600) │ ├── cache.mjs # file-based project-UUID cache │ ├── paginate.mjs # --all auto-pagination │ ├── format.mjs # вывод + цвета │ ├── tui.mjs # интерактивный браузер MR │ └── cmd/ # один файл = один модуль ├── mcp-server/ # MCP-сервер для AI-агентов ├── docs/ # эта документация (VitePress) ├── scripts/ # утилиты (docs dev-server) ├── install.sh / install.ps1 # установщики ├── gitflic-ci.yaml # (удалён в 0.2.0 — собираем локально) ├── package.json # только devDeps (vitest) └── vitest.config.mjs ``` ## Конвенции ### Стиль кода - **ESM only**, `"type": "module"` в package.json. - **Node 18+** baseline (используем `globalThis.fetch`, `node:fs/promises`, etc). - **`node --check `** для syntax — никакого TypeScript, никакого Babel, никакого bundler. - **2-space indent**, no semicolons в конце statements… шучу, с semicolons. Single quotes для строк. - **Каждый модуль экспортирует `usage` (строка) и `handle(ctx, sub, args, flags)`** — это контракт диспетчера. ### Структура cmd-модуля ```js // lib/cmd/.mjs export const usage = ` [--flag value] One-line description. `; export async function handle(ctx, sub, args, flags) { switch (sub) { case "list": return handleList(ctx, args, flags); case "create": return handleCreate(ctx, args, flags); // ... case undefined: process.stdout.write(usage); return; default: process.stderr.write(`gitflic ${name}: unknown subcommand: ${sub}\n`); process.exit(2); } } ``` ### Добавление новой команды 1. Создай `lib/cmd/.mjs` с `usage` и `handle`. 2. Импортируй в `lib/gitflic.mjs` и добавь в `COMMANDS`. 3. Если не требует `--project`, добавь в `GLOBAL` set. 4. Напиши тесты в `lib/__tests__/.test.mjs` (vitest). 5. Если добавляешь новый sensitive параметр — обнови `isSensitiveKey()` в `lib/secret.mjs`. 6. Обнови README + `docs/commands/.md`. ### Тесты - **Vitest**, 163 теста, ~300ms на полный прогон. - Тесты лежат рядом с кодом: `lib/__tests__/.test.mjs`. - Покрытие: все публичные функции, command handlers, edge cases (env vars, file modes, secret backend fallback). - Не мокай global fetch для тестов auth.mjs — используй `vi.stubGlobal("fetch", mockFn)`. ```bash npm test # один прогон npm run test:watch # watch mode npx vitest run path/to/specific.test.mjs # один файл ``` ### Линтинг Сейчас нет линтера (только `node --check`). Если хочется eslint — отдельный PR. Минимальный sanity-check: ```bash npm run lint # или node scripts/build.mjs --no-test --no-bundle ``` ## Документация Docs лежат в `docs/` — это **VitePress** сайт (Markdown + конфиг в `docs/.vitepress/config.mjs`). ```bash npm run docs:dev # dev-server с HMR (по умолчанию :5173) npm run docs:build # статическая сборка → docs/.vitepress/dist npm run docs:preview # локальный предпросмотр собранного сайта npm run docs:publish # build + пуш собранного сайта в GitHub-зеркало (деплой) ``` - Страницы — обычный Markdown в `docs/**.md`. Навигация/сайдбар — в `docs/.vitepress/config.mjs`. - Статика (иконки, картинки) — в `docs/public/` (раздаётся из корня сайта, напр. `/_media/icon.svg`). - Тема/брендинг — `docs/.vitepress/theme/` (GitFlic-красный). Поиск — встроенный локальный. - Важно: в Markdown вне код-блоков не пиши голые `<плейсхолдеры>` — Vue-компилятор примет их за теги. Оборачивай в backticks: `` `` ``. ## Сборка и релиз `scripts/build.mjs` — полная локальная сборка: syntax-check всех .mjs, JSON-валидация, vitest, `tar.gz` portable-бандла в `dist/`. ```bash npm run build # lint + test + tar.gz npm run build -- --no-test # быстрая итерация (без тестов) npm run build -- --no-bundle # только проверки, без tar.gz ``` `scripts/release.mjs` — бампит версию в `package.json`, пересобирает, копирует tar.gz в **`docs/public/downloads/`** (раздаётся VitePress как `/downloads/` — артефакты качаются прямо с сайта, без S3), и пересобирает там же `index.html` со списком релизов. ```bash npm run release -- --version 0.3.0 # бамп + билд + ship npm run release # интерактивно спросит версию npm run docs:build # собрать VitePress перед деплоем ``` Почему так: на публичном `gitflic.ru` нет shared runners (нужна Company + self-hosted `runner.jar` — это платный VPS), и покупать S3 ради одного tar.gz тоже не хочется. Поэтому: 1. CI/CD выпилен (`gitflic-ci.yaml` удалён). 2. Документация — статический **VitePress** сайт. Исходник (`docs/`) живёт в этом репо; собранный сайт публикуется в **GitHub-зеркало** [`zhimbura/gitflic-cli-docs`](https://github.com/zhimbura/gitflic-cli-docs) (его корень = собранный сайт, без build-шага), а **Timeweb Apps** раздаёт зеркало статикой. Деплой одной командой: `npm run docs:publish` (= `docs:build` + пуш `dist` в зеркало, gh-pages style). 3. Артефакты релизов лежат в `docs/public/downloads/` → попадают в собранный сайт под тем же доменом (`/downloads/`). Workflow релиза целиком: ```bash # 1. Поправил код, прогнал тесты npm run build # 2. Бамп + ship tar.gz в docs/public/downloads/ npm run release -- --version 0.3.0 # 3. Коммит исходников (код + docs/) в основной репо git add . && git commit -m "release: v0.3.0" git push # 4. Собрать и опубликовать доку в зеркало (Timeweb подхватит) npm run docs:publish ``` ## Отладка ```bash # Verbose retry logs GITFLIC_HTTP_RETRIES=0 GITFLIC_NO_RETRY=1 GITFLIC_HTTP_RETRY_DELAY=10 gitflic ... # Без кеша GITFLIC_NO_CACHE=1 gitflic ... # Без config-файла (CI-mode) GITFLIC_NO_CONFIG=1 gitflic ... # Без secret store (только env var) GITFLIC_NO_SECRET_STORE=1 gitflic ... # Print resolved API calls DEBUG=gitflic:* gitflic ... # пока не реализовано, но легко добавить ``` ## См. также - [Установка](install.md) - [Релизы и артефакты](/releases/) - [MCP-сервер](mcp-server.md) ================================================================================ # https://cli-gitflic.ru/env.html ================================================================================ # ENV переменные Все поддерживаемые переменные окружения. ## Аутентификация и API | Переменная | Что делает | Default | |---|---|---| | `GITFLIC_TOKEN` | Токен для запросов | — | | `GITFLIC_API_BASE` | API endpoint | `https://api.gitflic.ru` | | `GITFLIC_NO_CONFIG=1` | Не читать `~/.config/gitflic-cli/config.json` | — | | `GITFLIC_NO_SECRET_STORE=1` | Не использовать keychain (только env var) | — | ## HTTP / retry | Переменная | Что делает | Default | |---|---|---| | `GITFLIC_HTTP_RETRIES` | Макс. ретраев на 429/502/503/504 | `3` | | `GITFLIC_HTTP_RETRY_DELAY` | Базовая задержка backoff (ms), реальная задержка случайная в `[0, base*2^attempt]` (jitter) | `500` | | `GITFLIC_NO_RETRY=1` | Полностью отключить ретраи | — | ## Кеш | Переменная | Что делает | Default | |---|---|---| | `GITFLIC_NO_CACHE=1` | Не использовать file-based project-UUID cache | — | ## Вывод | Переменная | Что делает | Default | |---|---|---| | `NO_COLOR=1` | Отключить ANSI-цвета (по [no-color.org](https://no-color.org)) | — | | `FORCE_COLOR=1` | Принудительно включить цвета даже без TTY | — | | `GITFLIC_STREAM=1` | Всегда выводить NDJSON (как `--stream`) | — | ## Секреты | Переменная | Что делает | Default | |---|---|---| | `XDG_CONFIG_HOME` | Базовая директория для config-файла | `$HOME/.config` | | `XDG_CACHE_HOME` | Базовая директория для кеша | `$HOME/.cache` | ## Пример: полностью headless CI ```bash export GITFLIC_TOKEN="$(cat ~/.gitflic-ci-token)" export GITFLIC_NO_CACHE=1 export GITFLIC_NO_CONFIG=1 export GITFLIC_NO_RETRY=1 # fail fast export NO_COLOR=1 # чистый вывод для grep/jq gitflic mr list --project tikhon/wave --format json | jq '.[] | .localId' ``` ## Пример: sandbox разработка ```bash export GITFLIC_API_BASE=https://gitflic-staging.example.com export GITFLIC_TOKEN="$(security find-generic-password -a tikhon-staging -s gitflic-cli -w)" export GITFLIC_HTTP_RETRIES=0 # Без ретраев — увидишь ошибки сразу, удобно при дебаге. ``` ## См. также - [Флаги](flags.md) - [Все команды](/commands/) - [MCP-сервер](mcp-server.md) ================================================================================ # https://cli-gitflic.ru/flags.html ================================================================================ # Флаги ## Глобальные (почти все команды) | Флаг | Короткая | Аргумент | Default | Описание | |---|---|---|---|---| | `--project` | `-p` | `owner/alias` | авто-детект или `default-project` | Целевой проект | | `--api-base` | | URL | `https://api.gitflic.ru` | API endpoint | | `--token` | | строка | — | Токен (per-call override) | | `--format` | `-f` | `json\|pretty` | auto | Формат вывода | | `--page` | | число | `1` | Номер страницы | | `--size` | | число | endpoint-specific | Размер страницы | | `--all` | | флаг | false | Авто-пагинация до конца | | `--stream` | | флаг | false | NDJSON output | | `--tui` | | флаг | false | Интерактивный браузер (где применимо) | | `--json` | | флаг | false | Эквивалент `--format json` | | `--pretty` | | флаг | false | Эквивалент `--format pretty` | | `--help` | `-h` | флаг | false | Справка | | `--no-remove-branch` | | флаг | false | Для `mr merge`: не удалять source-ветку | | `--no-color` | | флаг | false | Отключить цвета (per-call override `NO_COLOR`) | ## Scope-флаги (team/company/instance) Многие сущности глобальны и работают в нескольких контекстах. Контекст задаётся парой флагов: `--scope` + alias соответствующего владельца. | Флаг | Аргумент | Описание | |---|---|---| | `--scope` | `project\|company\|team\|instance` | Контекст команды (default обычно `project`) | | `--team` | `` | Alias команды (для `--scope team`) | | `--company` | `` | Alias компании (для `--scope company`) | | `--project` | `/` | Проект (для `--scope project`) | ```bash # registry в контексте компании gitflic registry package list --scope company --company acme --format json # branch-protection команды gitflic branch protection list --scope team --team backend --format json # tag-protection компании gitflic tag protection list --scope company --company acme ``` ## Специфичные для модулей ### mr - `--title ` — заголовок MR - `--description ` — описание - `--to ` — target ветка - `--from ` — source ветка (default = текущая) - `--squash` — squash при merge - `--squash-message ` — сообщение коммита при squash merge - `--message ` — merge commit message - `--new-path

` `--new-line ` — для inline-комментариев (new side) - `--old-path

` `--old-line ` — для inline-комментариев (old side) ### branch - `--from ` — базовая ветка при создании - `--base ` — база при compare - `--file-path

` `--base-hash ` `--compare-hash ` — для `compare-file` / `commits` - Branch-protection (`branch protection …`, по умолчанию scope `project`; для company/team — `--scope company|team` + `--company/--team `): - `--branch-template ` — паттерн ветки - `--allowed-to-push ` - `--allowed-to-merge ` - `--allow-force-push` - `--code-owner-approval` - `--auto-merge` ### tag - `--branch ` / `--commit ` — источник при `tag create` (branch по умолчанию `master`) - `--message ` — сообщение тега - Tag-protection (`tag protection …`, scope team/company — `--scope team|company` + `--team/--company `): - `--tag-template ` — паттерн тега - `--allow-to-create ` ```bash gitflic tag protection create --scope team --team backend \ --tag-template 'v*' --allow-to-create ADMINS ``` ### release - `--title ` — заголовок релиза - `--description ` — release notes - `--tag ` — связанный тег - `--pre-release` — пометить как pre-release (в `edit` принимает `true|false`) - `--attach-archive` — приложить архив при создании - `--archive-format ` - `--name ` — имя файла для `release upload` (default = basename) - `--out ` — путь сохранения для `release download` (default = ``) ```bash # загрузка/скачивание файлов релиза gitflic release upload ./build.zip --name build.zip gitflic release download --out ./build.zip ``` > GitFlic проверяет тип загружаемого файла по allow-list: архивы (`.zip` и т.п.) проходят, > а `.txt`/`.png` могут вернуть HTTP 415 — это ограничение сервера, не CLI. ### issue - `--title ` `--description ` - `--status ` - `--assign-to ` - `--label ` - `--name ` — имя файла для `issue attach` (default = basename) ```bash # загрузить файл в проект и привязать его к issue одной командой gitflic issue attach 42 ./report.pdf --name report.pdf ``` ### registry Registry — глобальный модуль; контекст задаётся через `--scope` + `--project/--company`. - `--scope ` — контекст (default `project`) - `--fmt ` — формат пакета для `package upload`/`package download` (`generic`, `maven`, `npm`, `pypi`, `nuget`, `composer`, `opm`, `cran`, `rubygem`, `cargo`, `conda`). **Это НЕ `--format`** — `--format` зарезервирован под вывод `json|pretty`. - `--type ` — фильтр по типу при `package list` - `--version ` — версия при `package files` - `--content-type ` — Content-Type при загрузке - `--npm-scope ` — npm-scope при загрузке npm-пакета - `--out ` — путь сохранения для `package download` - `--tag ` — git-тег для `package composer-tag` - `--node-path ` — путь узла для `registry repo upload/download` ```bash gitflic registry package list --scope company --company acme --type maven --format json gitflic registry package upload --fmt maven --project tikhon/wave ./app-1.0.jar com.acme app 1.0 gitflic registry package download --fmt npm --project tikhon/wave my-pkg my-pkg-1.0.tgz --out ./out.tgz ``` > `registry repo …` (registry-repositories) — функционал Enterprise/Atlas, на публичном > SaaS возвращает 404 (реализован по спеке, но code-only). ### team / company - `--alias ` `--title ` `--description ` — при `create` - `--private` — приватная команда/компания - `--owner ` `--owner-type ` — владелец при `team create` (default = вы) - `--owner ` `--team ` — для `team transfer` - `--role ` — для `member invite/role` - `--q ` — поиск в `list` / `member list` - import-флаги (`team import set` / `company import run`): `--branch`, `--environment`, `--tag`, `--mr-approval`, `--pipeline-lifetime` ```bash gitflic team create --alias backend --title "Backend" --private \ --owner acme --owner-type COMPANY gitflic team transfer --team backend --owner newlead ``` > У `team` и `company` нет REST-эндпоинтов `edit`/`delete` (PUT/DELETE → 405) — правка и > удаление только через web-интерфейс; для смены владельца используйте `team transfer`. ### project - `--title ` `--alias ` `--description ` `--language ` — при `create`/`edit` - `--private` / `--public` — видимость - `--default-branch ` — ветка по умолчанию при `edit` - `--topics ` — теги проекта при `change-setting` - `--owner-alias ` `--owner-alias-type ` — владелец при `create` - `--new-alias ` `--owner-alias ` — при `fork` - `--url ` `--new-alias ` — при `import` - `--out ` — путь для `project archive` ```bash gitflic project create --title "Wave" --alias wave --private \ --owner-alias acme --owner-alias-type COMPANY ``` > `project archive` (`/file/getArchive`) на публичном `api.gitflic.ru` отдаёт 404 > (скачивание архива отключено / только в web) — используйте `git clone`. ### auth - `--token ` — токен для login - `--stdin` — читать токен из stdin - `--as ` — named-аккаунт - `--api-base ` — для login-валидации - `--reveal` — показать полное значение sensitive ключа - `--all` — для logout: удалить всё ### alias - `--reveal` — для get: показать полное значение ## Boolean флаги `--key` без значения = `true`. `--no-key` = `false`. Например: ```bash gitflic mr merge 42 --squash # flags.squash = true gitflic mr merge 42 --no-remove-branch # flags.removeBranch = false ``` ## Парсинг `parseArgs` в `lib/http.mjs`: - `--key value` — два токена - `--key=value` — один токен (тоже работает) - `--key` (последний в строке) — boolean `true` - `--no-key` — boolean `false` - `-abc` — grouped short flags (`-abc` = `-a -b -c`) - Всё остальное — позиционный аргумент в `flags._`. ## Пример ```bash gitflic mr create --project FerdBur/wave \ --title "Fix login" \ --description "$(git log -1 --pretty=%B)" \ --to main \ --squash \ --no-remove-branch \ --format json ``` ## См. также - [ENV переменные](env.md) - [Все команды](/commands/) - [Аутентификация](/auth/) ================================================================================ # https://cli-gitflic.ru/ ================================================================================ ## За 30 секунд ```bash npm install -g gitflic-cli # или разово: npx gitflic-cli help gitflic auth login --token xxxx-xxxx-xxxx # валидирует через /user/me, кладёт в Keychain gitflic mr list --project tikhon/gitflic-cli # список MR gitflic mr create --title "Fix login" --to main ``` Ноль транзитивных зависимостей — чистый Node ESM (`>=18`), один бинарь `gitflic`. [Другие способы установки →](/install.html) ## Архитектура ``` gitflic-cli/ ├── bin/gitflic # bash-шим → node lib/gitflic.mjs ├── lib/ │ ├── gitflic.mjs # диспетчер команд │ ├── http.mjs # fetch + retry + parseArgs + resolveToken + httpText/httpDownload/httpUploadFile │ ├── secret.mjs # macOS Keychain / Linux libsecret / chmod 0600 │ ├── config.mjs # persistent user config (chmod 0600) │ ├── cache.mjs # file-based project-UUID cache │ ├── paginate.mjs # --all auto-pagination + NDJSON streaming │ ├── format.mjs # вывод + цвета (NO_COLOR / FORCE_COLOR) + htmlUnescape │ ├── tui.mjs # интерактивный браузер MR │ └── cmd/ # модули команд (mr, branch, release, registry, ...) ├── mcp-server/ # Model Context Protocol сервер └── docs/ # эта документация (VitePress) ``` ## Лицензия MIT. ================================================================================ # https://cli-gitflic.ru/install.html ================================================================================ # Установка ## Требования - **Node.js 18+** (используется глобальный `fetch`, нет runtime-зависимостей). ## npm (рекомендуется) ```bash npm install -g gitflic-cli gitflic help ``` У CLI нет транзитивных зависимостей — `npm i -g` ставит только сам пакет. Обновление: `npm update -g gitflic-cli`. Удаление: `npm uninstall -g gitflic-cli`. ### Без установки — npx ```bash npx gitflic-cli help npx gitflic-cli mr list --project owner/repo ``` ## Из исходников (SSH-клон + install.sh) Подходит, если хочешь хакать CLI локально. Нужен SSH-ключ в https://gitflic.ru. ```bash git clone git@gitflic.ru:tikhon/gitflic-cli.git ~/tools/gitflic-cli cd ~/tools/gitflic-cli bash install.sh ``` `install.sh` сделает: 1. Скопирует CLI в `~/.local/share/gitflic-cli/`. 2. Создаст symlink `~/.local/bin/gitflic` → `bin/gitflic`. 3. Подскажет добавить `~/.local/bin` в `PATH`, если его там ещё нет. ## Альтернативные способы ### Windows / PowerShell ```powershell git clone git@gitflic.ru:tikhon/gitflic-cli.git cd gitflic-cli powershell -ExecutionPolicy Bypass -File install.ps1 ``` ### Кастомный префикс установки ```bash bash install.sh --prefix ~/my-tools # CLI ляжет в ~/my-tools/share/gitflic-cli, symlink в ~/my-tools/bin/gitflic ``` ### Только файлы, без symlink ```bash bash install.sh --no-symlink # Полезно если PATH под контролем (XDG_BIN_HOME, mise, asdf, ...) ``` ### Dry-run (без записи на диск) ```bash bash install.sh --dry-run # Покажет что будет сделано, ничего не записывая. ``` ### HTTPS вместо SSH ```bash GITFLIC_TOKEN=xxxxxxxx bash install.sh # Использует https://gitflic.ru/tikhon/gitflic-cli.git с basic auth. ``` ### Удаление ```bash bash uninstall.sh # Linux/macOS/WSL powershell -File uninstall.ps1 # Windows ``` ## Ручная установка (без install.sh) ```bash git clone git@gitflic.ru:tikhon/gitflic-cli.git ~/tools/gitflic-cli chmod +x ~/tools/gitflic-cli/bin/gitflic ln -sf ~/tools/gitflic-cli/bin/gitflic ~/.local/bin/gitflic export PATH="$HOME/.local/bin:$PATH" # добавь в ~/.bashrc / ~/.zshrc ``` ## Что ставится на диск ``` ~/.local/share/gitflic-cli/ # сам CLI (копия репо) ~/.local/bin/gitflic # symlink на bin/gitflic ``` `install.sh` НЕ модифицирует `~/.bashrc` / `~/.zshrc` сам — он только подсказывает. Решение о добавлении в PATH — за тобой. ## Запуск из исходников (dev-режим) Если ты форкнул/клонировал и хочешь запустить без установки: ```bash cd ~/tools/gitflic-cli node lib/gitflic.mjs --help ``` Все подкоманды работают идентично, путь просто короче. ## Обновление ```bash cd ~/tools/gitflic-cli git pull bash install.sh ``` Старая копия в `~/.local/share/gitflic-cli/` будет перезаписана, symlink останется. ## См. также - [Быстрый старт](quickstart.md) — вход по токену и первые команды за пару минут. - [Все команды](/commands/) — полный справочник CLI (~100% покрытие REST API). - [Аутентификация](/auth/) — где и как хранится токен GitFlic. - [Релизы и артефакты](/releases/) — портативные `tar.gz`-сборки для скачивания. ================================================================================ # https://cli-gitflic.ru/known-issues.html ================================================================================ # Известные проблемы и обходы > CLI покрывает ~100% публичного REST API GitFlic. Перечисленные ниже ограничения — это > поведение **серверной стороны** GitFlic (а не баги CLI) либо эндпоинты, которых в публичном > REST просто нет. Команды реализованы по спецификации; ограничения снимаются на стороне сервиса. ## `tag get ` возвращает HTTP 400 для любого имени **Симптом:** ``` gitflic tag get v1.0.0 --project FerdBur/wave gitflic: HTTP 400 — ... ``` **Причина:** GitFlic отдаёт `400` на `GET /tag/{name}` для любого имени тега — это поведение API. **Обход:** используйте `tag list` + фильтрацию: ```bash gitflic tag list --project FerdBur/wave | grep v1.0.0 gitflic tag list --project FerdBur/wave --format json | jq '.[] | select(.name == "v1.0.0")' ``` --- ## `tag delete` — нет REST-эндпоинта Публичный REST GitFlic не предоставляет эндпоинт для удаления тегов. **Обход:** удаляйте тег через git: ```bash git push origin :v1.0.0 # удаление тега через push ``` --- ## `mr merge` падает с `MergeCheckException` на свежих проектах **Симптом:** ``` gitflic mr merge 1 --project myorg/new-repo gitflic: HTTP 422 — MergeCheckException ``` **Причина:** branch protection по умолчанию требует approve от пользователя, который **не является автором** MR. Это политика GitFlic по умолчанию, а не баг CLI. **Обход:** получите approve своего MR от другой учётки, либо ослабьте branch protection через Web UI / `gitflic branch protection edit`. --- ## `project archive` → HTTP 404 на публичном api.gitflic.ru **Симптом:** ``` gitflic project archive owner/alias --out repo.zip gitflic: HTTP 404 — Not Found URL: GET https://api.gitflic.ru/project/owner/alias/file/getArchive ``` **Причина:** эндпоинт `/file/getArchive` отключён на публичном SaaS (скачивание архива доступно только через Web UI). Команда реализована по спецификации. **Обход:** используйте `git clone`: ```bash git clone https://gitflic.ru/project/owner/alias.git ``` --- ## `registry repo ...` (репозитории реестра) → 404 на публичном SaaS Подкоманды управления репозиториями реестра (`registry repo ...`) относятся к **Enterprise / Atlas**-функциональности и недоступны на публичном `api.gitflic.ru` (отдаёт `404`). Реализованы по спецификации (code-only) и работают только на соответствующем инстансе. Управление пакетами (`registry package ...`) на публичном SaaS работает. --- ## `release` — загрузка ассетов проверяется по типу файла (HTTP 415) **Симптом:** ``` gitflic release upload v1.0.0 ./notes.txt --project owner/alias gitflic: HTTP 415 — Unsupported Media Type ``` **Причина:** GitFlic валидирует тип загружаемого файла по allowlist на стороне сервера. Архивы (`.zip` и т. п.) проходят; `.txt`, `.png` и ряд других типов могут отдавать `415`. Это ограничение сервера, а не CLI. **Обход:** упакуйте файл в архив: ```bash zip notes.zip notes.txt gitflic release upload v1.0.0 ./notes.zip --project owner/alias ``` --- ## `team` / `company`: edit и delete — только Web UI (HTTP 405) У GitFlic **нет** REST-эндпоинтов для редактирования и удаления команд и компаний — `PUT`/`DELETE` возвращают `405 Method Not Allowed`. Создание, просмотр и управление участниками работают через REST. **Обход:** - Редактирование/удаление — через Web UI. - Для передачи владения командой используйте `team transfer`: ```bash gitflic team transfer my-team --to newowner ``` --- ## `settings access-token create` может требовать HTTP Basic auth Создание access-token на части инстансов требует **HTTP Basic auth** (логин + пароль), а не токен. **Симптом:** `401`/`403` при `settings access-token create`. **Обход:** создавайте токен через Web UI: **Профиль → API-токены → Создать**. --- ## HTTPS git push с токеном HTTPS git push работает с access-токеном — токен передаётся в URL: ```bash git push https://oauth2:@gitflic.ru/project//.git ``` Альтернатива — SSH-ключ: ```bash gitflic settings ssh add ~/.ssh/id_ed25519.pub --title "macbook" ``` --- ## `admin`, `saml`, instance-scoped `runner` — требуют прав инстанс-админа Команды уровня инстанса реализованы по спецификации, но требуют **прав инстанс-администратора**. С обычным токеном они отдают `403`/`404`: - `gitflic admin user list` / `admin project list` — admin-эндпоинты инстанса. - `gitflic saml ...` — настройки SAML SSO (только self-hosted с включённым SAML). - `gitflic runner ...` в instance-scope — управление runner'ами на уровне инстанса. **Обход:** используйте токен инстанс-админа либо Web UI. Project/team-scoped runner'ы при этом доступны обычному токену. --- ## GitFlic отдаёт локализованные значения для некоторых полей **Симптом:** `status.title` = «Открыт», «Слит», «Закрыт» (русский) вместо английских констант. **Решение:** CLI передаёт `Accept-Language: en`, где это возможно, но не все эндпоинты это уважают. Для машинной обработки используйте `status.id` — там всегда английские константы: `OPENED`, `MERGED`, `CLOSED`, `CANCELED`, `FAILED`. --- ## `registry package` upload использует `--fmt` (не `--format`) При загрузке пакета формат пакета задаётся флагом `--fmt`, потому что `--format` зарезервирован под формат вывода (`json` | `pretty`): ```bash gitflic registry package upload ./pkg.tgz --fmt npm --format json ``` --- ## `npm install` в подпапке `mcp-server/` CLI (`gitflic`) — **zero deps**, работает только на Node stdlib. MCP-сервер (`mcp-server/`) требует `@modelcontextprotocol/sdk`. Это сознательное решение — MCP-протокол слишком сложный, чтобы реализовать руками, а SDK небольшой (~2MB). Если вы используете только CLI (не MCP), `npm install` в `mcp-server/` не нужен. --- ## Исправленные баги - **BUG-001 — `mr diff` не декодировал HTML-entities (`"`, `<`, `>`, `&`).** ✅ **Исправлено.** Добавлен `htmlUnescape()` в `lib/format.mjs`, применяется к строкам диффа и заголовкам ханков в `printChanges()` (`lib/cmd/mr.mjs`). Декодирование однопроходное (`&` обрабатывается без двойного прохода), покрыто тестами в `lib/__tests__/format.test.mjs`. ## См. также - [Все команды](/commands/) - [Покрытие API](api-coverage.md) - [MCP-сервер](mcp-server.md) ================================================================================ # https://cli-gitflic.ru/mcp-server.html ================================================================================ # MCP-сервер для AI-агентов `mcp-server/` — это [Model Context Protocol](https://modelcontextprotocol.io) сервер, оборачивающий CLI `gitflic` в **типизированные тулзы** для AI-агентов (Claude Code, Cursor и т.п.). ## Что внутри ``` mcp-server/ ├── server.mjs # MCP stdio сервер ├── tools.mjs # описания тулзов (имя, описание, JSON-схема) ├── runner.mjs # child_process-обёртка: node ├── project-resolver.mjs # авто-резолв project из git remote └── __tests__/ # vitest ``` 77 инструментов — каждый маппится 1-в-1 на подкоманду CLI. ## Установка и запуск Сервер опубликован в npm как `gitflic-cli-mcp` и запускается через `npx` — ставить ничего не нужно: ```bash GITFLIC_TOKEN="xxxx" npx -y gitflic-cli-mcp ``` `npx` сам подтянет `gitflic-cli-mcp` и его зависимости (`@modelcontextprotocol/sdk`, `zod`) и сам CLI `gitflic-cli`. Из исходников — то же самое вручную: ```bash cd mcp-server && npm install GITFLIC_TOKEN="xxxx" node server.mjs ``` ## Настройка токена MCP-сервер наследует `GITFLIC_TOKEN` от родительского процесса — так же, как CLI: ```bash export GITFLIC_TOKEN="xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx" ``` Если токен лежит в OS keychain (через `gitflic auth login`), MCP-сервер тоже его увидит — он запускает `gitflic` CLI как subprocess, а тот умеет резолвить из keychain. ## Конфигурация в Claude Code / Cursor ### Claude Code Одной командой: ```bash claude mcp add gitflic --env GITFLIC_TOKEN=xxxxxxxx -- npx -y gitflic-cli-mcp ``` Или вручную в `~/.claude.json`: ```json { "mcpServers": { "gitflic": { "command": "npx", "args": ["-y", "gitflic-cli-mcp"], "env": { "GITFLIC_TOKEN": "xxxxxxxx" } } } } ``` ### Cursor В `~/.cursor/mcp.json`: ```json { "mcpServers": { "gitflic": { "command": "npx", "args": ["-y", "gitflic-cli-mcp"], "env": { "GITFLIC_TOKEN": "xxxxxxxx" } } } } ``` > Из исходников вместо `npx -y gitflic-cli-mcp` укажи `"command": "node", "args": ["/path/to/gitflic-cli/mcp-server/server.mjs"]`. ## Ограничение набора тулзов (экономия контекста) Все 77 тулзов уходят хосту по `tools/list` ещё до первого вызова — это ~6K токенов «налога» на контекст модели. Если агенту нужны не все, набор сужается через **env-переменные** — в том же `env`-блоке конфига, где `GITFLIC_TOKEN`: | Переменная | Значение | Что делает | |---|---|---| | `GITFLIC_MCP_GROUPS` | список групп через запятую/пробел | оставить только тулзы указанных групп | | `GITFLIC_MCP_READONLY` | `1` / `true` / `yes` / `on` | оставить только read-only тулзы (без мутаций) | | `GITFLIC_MCP_NO_DESTRUCTIVE` | `1` / `true` / `yes` / `on` | убрать деструктивные (удаление) тулзы | | `GITFLIC_MCP_TOOLS` | список имён тулзов | явный allowlist (приоритет над `GROUPS`) | | `GITFLIC_MCP_EXCLUDE` | список имён тулзов | убрать конкретные тулзы (применяется последним) | Все опциональны; без них регистрируются все 77. Неизвестные имена/группы не валят старт — сервер пишет `WARN` в stderr и игнорирует их. Регистр в списках не важен. **Порядок применения:** базовый набор (`GITFLIC_MCP_TOOLS` → иначе `GITFLIC_MCP_GROUPS` → иначе все) → пересечение с read-only при `GITFLIC_MCP_READONLY` (накладывается и на allowlist, так что write-тул не «протечёт» в read-only режим) → вычитание деструктивных при `GITFLIC_MCP_NO_DESTRUCTIVE` → вычитание `GITFLIC_MCP_EXCLUDE` в конце. **`GITFLIC_MCP_NO_DESTRUCTIVE=1`** жёстко убирает (на уровне регистрации, не через approval-prompt) **только удаляющие** тулзы — 7 шт. на `_delete`: `issue_delete`, `issue_comments_delete`, `mr_discuss_delete`, `branch_delete`, `branch_protection_delete`, `release_delete`, `webhook_delete`. Остальные мутации (`*_create` / `*_edit` / `*_close` / `gitflic_mr_merge`) остаются и идут через подтверждение хоста (`destructiveHint:true`). Это надёжнее approval'а, который можно прокликать. **Допустимые значения `GITFLIC_MCP_GROUPS`** (группа = первый сегмент имени после `gitflic_`): | Группа | Тулзов | Read / Write | |---|---|---| | `auth` | 8 | 3 / 5 | | `blob` | 2 | 2 / 0 | | `branch` | 10 | 5 / 5 | | `commit` | 4 | 4 / 0 | | `issue` | 12 | 4 / 8 | | `mr` | 15 | 5 / 10 | | `project` | 7 | 4 / 3 | | `release` | 6 | 3 / 3 | | `tag` | 3 | 2 / 1 | | `user` | 5 | 5 / 0 | | `webhook` | 5 | 2 / 3 | > ⚠️ Группа `auth` содержит мутирующие тулзы (`_login` / `_logout` / `_switch` / `_bind` / `_unbind`) — они меняют локальный keychain/конфиг. Для «только проверка личности» добавь `GITFLIC_MCP_READONLY=1` или перечисли нужное через `GITFLIC_MCP_TOOLS`. ```bash # Только MR и issue (27 тулзов вместо 77) claude mcp add gitflic --env GITFLIC_TOKEN=xxxx \ --env GITFLIC_MCP_GROUPS=mr,issue -- npx -y gitflic-cli-mcp # Read-only агент для код-ревью (39 read-only тулзов) GITFLIC_MCP_READONLY=1 npx -y gitflic-cli-mcp # Может всё, кроме удаления (70 тулзов) GITFLIC_MCP_NO_DESTRUCTIVE=1 npx -y gitflic-cli-mcp ``` ```json { "mcpServers": { "gitflic": { "command": "npx", "args": ["-y", "gitflic-cli-mcp"], "env": { "GITFLIC_TOKEN": "xxxx", "GITFLIC_MCP_GROUPS": "mr,issue", "GITFLIC_MCP_READONLY": "1" } } } } ``` Полный список всех 77 тулзов с пометкой R/W — в [README MCP-сервера](https://gitflic.ru/project/tikhon/gitflic-cli/blob?file=mcp-server%2FREADME.md). Совет: можно держать два подключения — `gitflic` (полный) и `gitflic-ro` (`GITFLIC_MCP_READONLY=1`), либо класть конфиг в проектный `.mcp.json` / `.cursor/mcp.json`, чтобы в каждом репозитории грузились свои группы. ## Сжатие ответов (экономия токенов) GitFlic REST API отдаёт «сырой» JSON с кучей бесполезного для LLM шума: URL аватаров/обложек, `hexColor` лейблов, `status` из 9 полей, вложенные объекты юзеров целиком, HAL-обёртки `_embedded`/`_links`. По умолчанию (с `gitflic-cli-mcp@0.4.0`) MCP **сжимает** ответы перед отдачей модели: разворачивает list-обёртку в `{ items, total, matched, returned }`, проецирует каждую сущность до нужных полей, схлопывает мусор. На реальных данных — **≈70% меньше токенов** (на коммитах/ветках до 84%). CLI `--format json` при этом остаётся «сырым» — сжатие живёт только в MCP-слое. | Переменная / аргумент | Значения | Эффект | | --- | --- | --- | | `GITFLIC_MCP_OUTPUT` | `slim` (по умолч.) / `full` (=`raw`) | глобальный режим: `full` = старый сырой ответ один-в-один | | `GITFLIC_MCP_RAW` | `1` / `true` / `yes` / `on` | то же, что `OUTPUT=full` (булев алиас, побеждает при конфликте) | | аргумент `raw: true` | на **любом** тулзе | вернуть полный несжатый ответ для **одного** вызова | | аргумент `fields: [...]` | на read/list тулзах | вернуть только указанные поля (+ id-ключи) | **Фильтрация списков на стороне MCP.** У GitFlic почти нет серверных фильтров для списков, поэтому list-тулзы принимают аргументы фильтра/сортировки (`label`, `q`, `assignee`, `status`, `author`, `sort`, `limit`, …). При их наличии хендлер автоматически дотягивает `--all`, фильтрует и возвращает только совпадения + `matched`/`total`. Напр. «найди открытые issue с лейблом Безопасность» вернёт совпадения вместо всех задач. **Секреты вебхуков.** В slim-режиме `secret` маскируется в `secretSet: true|false` (сырой ответ его раньше **утекал** в модель). Прочитать реальное значение можно тулзом `gitflic_webhook_reveal_secret` — он помечен деструктивным, поэтому MCP-хост спросит подтверждение перед выдачей. ## Примеры использования (в Claude Code) После подключения агент получает доступ к 77 тулам. Несколько типичных сценариев: ``` > Создай MR из текущей ветки в main с описанием из последнего коммита > Найди все открытые MR в проекте FerdBur/wave, которые ждут моего approve > Закрой все issue старше 60 дней, которые в статусе OPEN и без assignee ``` Агент сам составляет правильные аргументы, валидирует результат, итерирует при ошибках. ## Авто-резолв проекта `mcp-server/project-resolver.mjs` автоматически определяет `owner/alias` из `git remote get-url origin` — агенту не нужно каждый раз передавать `--project`: ```bash cd ~/code/FerdBur/wave # Агент теперь работает с FerdBur/wave по умолчанию для всех команд. ``` ## Безопасность MCP-сервер — **тонкая прослойка**: каждая тулза маппится 1-в-1 на CLI. Всё, что CLI может сделать, может и MCP-хост. Это и фича, и риск — следите за: - Кто имеет доступ к MCP-хосту (любой промпт там может вызвать тулзы). - Scope токена (минимизируйте: `PROJECT_READ` для read-only агентов). - Не давайте токен с `ADMIN_*` scope без крайней нужды. ## Что в планах - ✅ ~~Read-only mode~~ — готово: `GITFLIC_MCP_READONLY=1` (см. [«Ограничение набора тулзов»](#ограничение-набора-тулзов-экономия-контекста)). - ❌ OAuth browser flow для токена (вместо env-var). - ❌ Audit log (кто какую тулзу вызвал). Если нужно — issue/PR. ## Annotations: деструктивные операции требуют approval Все 77 тулов помечены MCP-аннотациями ([MCP 2025-06-18 spec](https://modelcontextprotocol.io/specification/2025-06-18/server/tools#toolannotations)): ```json { "name": "gitflic_mr_close", "annotations": { "title": "MR Close", "readOnlyHint": false, "destructiveHint": true, // ← клиент запросит подтверждение "idempotentHint": true, // повторный вызов = то же состояние "openWorldHint": true // ходит в GitFlic API } } ``` | Hint | Когда `true` | Когда `false` | |---|---|---| | `readOnlyHint` | list / get / view / search / me / status | create / edit / delete / merge | | `destructiveHint` | (почти всегда — дефолт) | только чисто read-only тулзы | | `idempotentHint` | close / cancel / delete / bind / set (повтор → то же состояние) | approve (toggle), pipeline start (новый run) | | `openWorldHint` | любой тул, ходящий в GitFlic API | только локальные (auth login/logout, alias set, cache clear) | ### Что это даёт Хосты вроде **Claude Code** и **Cursor** при получении тулза с `destructiveHint: true` показывают пользователю prompt: ``` gitflic_mr_close wants to close merge request #42 on project FerdBur/wave. Approve? [y/N] ``` Это защита от runaway-агентов, которые могут снести прод случайным вызовом `mr_close` или `issue_delete`. ### Как это работает внутри Аннотации живут в `mcp-server/tools.mjs` рядом с каждым тулзом: ```js { name: "gitflic_mr_close", description: "...", inputSchema: { ... }, annotations: { title: "MR Close", readOnlyHint: false, destructiveHint: true, idempotentHint: true, openWorldHint: true, }, handler: (a) => ["mr", "close", a.localId, "--project", a.project], } ``` `server.mjs` пробрасывает annotations в `server.tool(name, desc, schema, annotations, handler)` — MCP SDK v1.x их нативно поддерживает и шлёт хосту в `tools/list` ответе. ### Re-classification after adding new tools Если добавляешь новый тул в `tools.mjs`, прогони классификатор: ```bash node scripts/annotate-mcp-tools.mjs ``` Скрипт идёт по TOOLS-массиву, классифицирует каждый по суффиксу/префиксу имени, и вставляет `annotations: {...}` если его ещё нет. Полностью идемпотентен — повторный запуск ничего не дублирует. Логика классификации — в `scripts/annotate-mcp-tools.mjs` (~150 LOC, без зависимостей). ### Caveats - `destructiveHint` **не означает "обязательно удалит"** — это hint, что *может*. Хосты используют его для UI prompt, но не для блокировки. - Если хост не поддерживает annotations (старые версии), всё работает как раньше — annotations просто игнорируются. - `idempotentHint` используется MCP-хостами для авто-retry, но в нашей реализации retry сам делает CLI (через `GITFLIC_HTTP_RETRIES`). Так что это скорее hint для пользователя. ## См. также - [Быстрый старт](quickstart.md) — установка и первые команды `gitflic`. - [Все команды](/commands/) — какие подкоманды стоят за 77 тулзами MCP. - [ENV переменные](env.md) — `GITFLIC_TOKEN`, `GITFLIC_API_BASE` и настройки поведения. - [Аутентификация](/auth/) — как MCP-сервер получает токен из keychain. ================================================================================ # https://cli-gitflic.ru/quickstart.html ================================================================================ # Быстрый старт За 2 минуты от нуля до `gitflic mr list`. ## 1. Установить ```bash npm install -g gitflic-cli # или разово, без установки: npx gitflic-cli help ``` Все способы (npx, из исходников, Windows, dry-run) — [Установка](install.md). ## 2. Получить токен Открой https://gitflic.ru → **Профиль** → **API-токены** → **Создать**. Минимально нужные скоупы: `PROJECT_READ` + `PROJECT_WRITE` (или `PROJECT_EDIT`) для работы с MR. ## 3. Сохранить токен в системное хранилище ```bash gitflic auth login --token xxxx-xxxx-xxxx ``` Что произойдёт: 1. CLI дёрнет `/user/me` с этим токеном — убедится, что токен валиден. 2. Покажет identity (alias + email). 3. Сохранит токен в: - **macOS** → Keychain (`security add-generic-password`) - **Linux** → libsecret (`secret-tool`) - **иначе** → `~/.config/gitflic-cli/config.json` с `chmod 0600` + предупреждение. Битый токен **не сохраняется** — keychain остаётся чистым. ## 4. Пользоваться ```bash gitflic project get tikhon/gitflic-cli # резолв alias → UUID gitflic mr list --project tikhon/gitflic-cli # открытые MR gitflic mr view 42 --project tikhon/gitflic-cli # детали MR #42 gitflic mr create --title "Fix login" --to main # создать MR gitflic auth status # проверить текущий аккаунт ``` CLI покрывает REST API GitFlic почти на 100% — ниже несколько примеров «посерьёзнее». ### Реестр пакетов (registry) Загрузка и скачивание артефактов. Формат указывается через `--fmt` (не `--format` — он зарезервирован под вывод): ```bash # Загрузить Maven-артефакт в реестр проекта gitflic registry package upload --fmt maven --project tikhon/wave \ ./app-1.0.jar com.acme app 1.0 # Скачать npm-пакет gitflic registry package download --fmt npm --project tikhon/wave \ my-pkg my-pkg-1.0.tgz --out ./out.tgz # Список пакетов компании в формате JSON gitflic registry package list --scope company --company acme --type maven --format json ``` ### Релизы (release) ```bash # Создать релиз с тегом gitflic release create --title "v1.2.0" --tag v1.2.0 --project tikhon/wave # Прикрепить файл к релизу (.zip/архивы проходят валидацию типа на сервере) gitflic release upload ./build.zip --name build.zip --project tikhon/wave ``` ### Задачи (issue) ```bash # Загрузить файл в проект и прикрепить его к задаче одной командой gitflic issue attach 17 ./screenshot.png --name bug.png --project tikhon/wave ``` ### Защита веток и тегов Правила защиты можно задавать на уровне проекта, команды или компании: ```bash # Запретить force-push в main на уровне проекта gitflic branch protection create --project tikhon/wave \ --branch-template main --allowed-to-push ADMINS --allowed-to-merge DEVELOPER # Защита тегов на уровне команды gitflic tag protection create --scope team --team backend \ --tag-template "v*" --allow-to-create ADMINS ``` ### CI/CD-раннеры ```bash gitflic runner list --project tikhon/wave --format json # раннеры проекта gitflic runner list --scope company --company acme # раннеры компании ``` ## Что дальше - [Аутентификация — обзор](/auth/) — multi-account, per-project bindings, threat model. - [Команды — справочник](/commands/) — все доступные модули и флаги. - [MCP-сервер](mcp-server.md) — для AI-агентов (Claude Code, Cursor). - [Известные проблемы](known-issues.md) — что может пойти не так. ================================================================================ # https://cli-gitflic.ru/releases/ ================================================================================ # Релизы и артефакты Каждый релиз `gitflic-cli` — это портативный `tar.gz`, собранный скриптом `scripts/build.mjs` и опубликованный как статический ассет сайта документации. Никакого CI, никакого S3 — собранный VitePress-сайт раздаётся целиком (страницы + артефакты под одним доменом). ## Как скачать Артефакты лежат в `/downloads/` собранного сайта (исходник — `docs/public/downloads/`): по одному `tar.gz` на каждый релиз, плюс простой список в [/downloads/](/downloads/). Прямые ссылки без редиректов, например `/downloads/gitflic-cli-0.3.0.tar.gz`. После скачивания: ```bash tar -xzf gitflic-cli-0.3.0.tar.gz cd gitflic-cli-0.3.0 bash install.sh # симлинк в ~/.local/bin/gitflic gitflic --help ``` ## Как устроена сборка Подробно — в [Локальной разработке](/development), секция «Сборка и релиз». Коротко: ```bash npm run build # lint + test + tar.gz → dist/ npm run release -- --version 0.3.0 # bump + пересборка + копия в docs/public/downloads/ git add . && git commit -m "release: v0.3.0" && git push # исходники в основной репо npm run docs:publish # build + публикация сайта в GitHub-зеркало ``` ## Деплой Дока — статический VitePress-сайт (gh-pages style). `npm run docs:publish` собирает `docs/.vitepress/dist` и публикует его в GitHub-зеркало [`zhimbura/gitflic-cli-docs`](https://github.com/zhimbura/gitflic-cli-docs), корень которого Timeweb раздаёт статикой. Артефакты релизов попадают в сборку как `docs/public/` → `/downloads/`. ## Почему не GitFlic Releases / S3 - Публичный `gitflic.ru` не даёт shared CI runners — нужен self-hosted `runner.jar`, а это платный VPS. - S3 для одного бинаря — overkill. - Один артефакт + одна дока = один деплой статики.