From 32051ae3f08d0c0b421c4809406b14028b1847cc Mon Sep 17 00:00:00 2001 From: Dmitry Dementev Date: Tue, 21 Jul 2026 16:38:02 -0400 Subject: [PATCH] =?UTF-8?q?docs(gitverse):=20=D0=B4=D0=BE=D0=B1=D0=B0?= =?UTF-8?q?=D0=B2=D0=BB=D0=B5=D0=BD=D0=BE=20=D0=B8=D1=81=D1=81=D0=BB=D0=B5?= =?UTF-8?q?=D0=B4=D0=BE=D0=B2=D0=B0=D0=BD=D0=B8=D0=B5=20API=20=D0=B7=D0=B0?= =?UTF-8?q?=D0=B4=D0=B0=D1=87?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Зачем: - нужно понять, подходит ли GitVerse для управления задачами проекта. - Что: - описаны Public API, совместимость с GitHub и GitLab и доступные операции. - сохранены результаты живых проверок и отличие внутреннего API. - добавлены безопасные команды повторной проверки и решение для dotfiles. - Проверка: - git diff --cached --check. --- docs/research/2026-07-21-gitverse-api.md | 212 +++++++++++++++++++++++ 1 file changed, 212 insertions(+) create mode 100644 docs/research/2026-07-21-gitverse-api.md diff --git a/docs/research/2026-07-21-gitverse-api.md b/docs/research/2026-07-21-gitverse-api.md new file mode 100644 index 0000000..30ca1e2 --- /dev/null +++ b/docs/research/2026-07-21-gitverse-api.md @@ -0,0 +1,212 @@ +# API GitVerse для задач + +Проверено 21 июля 2026 года по официальной документации, спецификации OpenAPI, +ответам действующего сервера и коду веб-интерфейса. + +## Зачем проверяли + +Мы хотели понять, можно ли управлять задачами проекта `dotfiles` +программно и со временем перенести туда часть локального процесса из +`.scratch`. Для этого нужно было ответить на два вопроса: + +1. Совместим ли GitVerse с API GitHub или GitLab либо использует свой API? +2. Можно ли через этот API создавать, менять и закрывать задачи? + +## Ответ + +GitVerse предоставляет **собственный REST API** на `https://api.gitverse.ru`. +Он похож на GitHub REST API по маршрутам и структуре части ответов, но полной +совместимости GitVerse не заявляет. С GitLab API он несовместим уже на уровне +маршрутов: GitLab использует `/api/v4/projects/:id/issues`, а GitVerse +использует `/repos/{owner}/{repo}/issues`. + +Поддержка задач сейчас неполная: публичный API поддерживает получение списка и +отдельной задачи, чтение временной шкалы и меток, а также создание и изменение +комментариев и реакций. В опубликованном контракте нет создания, изменения, +закрытия или удаления самой задачи. Поэтому заменить им полноценное управление +задачами пока нельзя. + +Веб-интерфейс умеет создавать задачи, но использует для этого отдельный +внутренний API и браузерную сессию. Токен Public API этот внутренний сервер не +принимает. + +## Почему комментарии есть, а создания задачи нет + +GitVerse использует общую модель обсуждений для задач и запросов на слияние. +Поэтому `GET /repos/{owner}/{repo}/issues/{index}` возвращает любой из этих +объектов, а комментарии к обоим создаются через +`POST /repos/{owner}/{repo}/issues/{index}/comments`. + +Жизненный цикл запросов на слияние вынесен в `/pulls`: там есть создание и +изменение запроса. Для обычной задачи симметричных `POST /issues` и +`PATCH /issues/{index}` в Public API нет. Наличие `POST` для комментария не +означает, что через тот же API можно создать саму задачу. + +## Как проверяли + +1. В официальных спецификациях OpenAPI 1.0-1.7 у `/issues` и + `/issues/{index}` найден только `GET`. Для комментариев опубликованы методы + записи, а для запросов на слияние есть отдельные методы `/pulls`. +2. `OPTIONS` для коллекции задач и `/issues/1` вернул `405` с `Allow: GET`. + Запрос списка без токена вернул `401 Unauthorized` и заголовок + `GitVerse-Api-Version: 1`. +3. Токен `work-usa` с правом «Репозитории: Запись» успешно прочитал репозиторий + через Bearer-аутентификацию: `GET /repos/ddementiev/dotfiles` вернул `200`. + `GET /user` с тем же токеном вернул `403`, поэтому этот маршрут не подходит + для проверки токена с ограниченными правами. Basic-аутентификация вернула + `401`. Токен создан 20 июля 2026 года и действует до 31 декабря 2026 года. +4. Настоящий `POST /repos/ddementiev/dotfiles/issues` проверен с двумя телами: + GitHub-подобным и тем, которое отправляет веб-интерфейс. Оба запроса вернули + `400` и пустую JSON-строку. Такой же ответ получен для заведомо + несуществующего пути. Ни одна тестовая задача не создалась. +5. В рабочих JavaScript-модулях GitVerse найден отдельный внутренний API + веб-интерфейса и точное тело запроса создания задачи. Это наблюдение за + реализацией сайта, а не публичный контракт. +6. Безопасный `GET` к внутреннему API с тем же Public API-токеном вернул `401` + и `{"message":"Wrong auth info"}`. Внутренний клиент использует cookie + браузерной сессии. + +## Контракт Public API + +- Базовый адрес: `https://api.gitverse.ru`. Опубликован собственный контракт + [GitVerse Public API](https://gitverse.ru/docs/developers/public-api/) и + [официальный OpenAPI 2.0](https://gitverse.ru/gitverse/rest-api-description/content/master/v1/openapi-1.7.json) + версии 1.7.0. +- Обязательны заголовки + `Authorization: Bearer ` и + `Accept: application/vnd.gitverse.object+json;version=1`. + Токен создается в профиле: «Настройки» → «Управление токенами»; + [инструкция по токенам](https://gitverse.ru/docs/collaborative/authentification/tokens/) + предлагает включить доступ к репозиториям. +- Лимит составляет 2000 запросов в час на идентификатор авторизованного + пользователя. + При превышении сервер отвечает `429` и передает остаток, время сброса и + `Retry-After`; см. [официальное описание ограничений](https://gitverse.ru/docs/developers/public-api/using-public-api/rate-limits). +- Для списков используются `page`, `per_page` и заголовок ответа `Link`. + Верхняя граница `per_page` в открытом контракте не указана. + +### Опубликованные операции с задачами + +| Метод | Маршрут | Назначение | +|---|---|---| +| `GET` | `/repos/{owner}/{repo}/issues` | Список задач и запросов на слияние; фильтры `state`, `q`, `labels`, `milestones`, `created_by`, `assigned_by`, `mentioned_by`, `type`, `since`, `before`, `page`, `per_page` | +| `GET` | `/repos/{owner}/{repo}/issues/{index}` | Одна задача или запрос на слияние | +| `GET` | `/repos/{owner}/{repo}/issues/{index}/timeline` | Комментарии и события задачи | +| `GET` | `/repos/{owner}/{repo}/issues/{index}/labels` | Метки задачи | +| `GET`, `POST` | `/repos/{owner}/{repo}/issues/{index}/comments` | Список и создание комментариев | +| `GET` | `/repos/{owner}/{repo}/issues/comments/{id}` | Один комментарий | +| `PATCH`, `DELETE` | `/repos/{owner}/{repo}/issues/{index}/comments/{comment_id}` | Изменение и удаление комментария | +| `POST` | `/repos/{owner}/{repo}/issues/{index}/comments/{comment_id}/reactions` | Добавление реакции | +| `DELETE` | `/repos/{owner}/{repo}/issues/{index}/comments/{comment_id}/reactions/{reaction_id}` | Удаление реакции | + +Источник таблицы: раздел `paths` официальной +[спецификации OpenAPI 1.7](https://gitverse.ru/gitverse/rest-api-description/content/master/v1/openapi-1.7.json). + +### Подробности проверки создания + +Токен взят из локального хранилища Git. Его значение не печаталось и не +сохранялось в документе. + +- `GET https://api.gitverse.ru/repos/ddementiev/dotfiles` с Bearer-токеном + вернул `200`. Это подтверждает, что Public API принимает токен и видит + репозиторий. +- `POST https://api.gitverse.ru/repos/ddementiev/dotfiles/issues` с + GitHub-подобным телом `title` и `body` вернул `400` и пустую JSON-строку. +- Повторный `POST` с точным форматом веб-интерфейса (`title`, `content`, + `issue_type`, `assignees`, `labels` и `attachments`) вернул тот же ответ. +- Такой же `400` сервер возвращает для `POST` на заведомо несуществующий путь. + Поэтому этот ответ выглядит как общая обработка незарегистрированного метода, + а не как ошибка полей задачи. +- Ни одна тестовая задача не была создана. + +Код [веб-интерфейса задач](https://gitverse.ru/ddementiev/dotfiles/issues) +показывает другую точку входа: + +```text +https://gitverse.ru/sc/sbt/api/v1/repos/{owner}/{repo}/issues +``` + +Форма отправляет туда `POST` с телом следующего вида: + +```json +{ + "title": "...", + "content": "...", + "issue_type": 1, + "assignees": [], + "labels": [], + "attachments": [] +} +``` + +Внутренний клиент передает cookie браузерной сессии. Проверочный `GET` к этому +адресу с токеном `work-usa` вернул `401` и +`{"message":"Wrong auth info"}`. Эта проверка не запускала внутренний `POST` и +не могла создать задачу. Она показала, что токен Public API не подходит для +клиента веб-интерфейса. + +## Как повторить безопасные проверки + +Токен должен находиться в переменной `GITVERSE_TOKEN`. Команды ниже только +читают данные и не создают задач. + +```bash +curl -sS -o /dev/null -w '%{http_code}\n' \ + -H "Authorization: Bearer $GITVERSE_TOKEN" \ + -H 'Accept: application/vnd.gitverse.object+json;version=1' \ + https://api.gitverse.ru/repos/ddementiev/dotfiles + +curl -sS -X OPTIONS -D - -o /dev/null \ + -H "Authorization: Bearer $GITVERSE_TOKEN" \ + -H 'Accept: application/vnd.gitverse.object+json;version=1' \ + https://api.gitverse.ru/repos/ddementiev/dotfiles/issues +``` + +Ожидаются `200` для первого запроса и `405` с `Allow: GET` для второго. +Повторять `POST` в основном репозитории не следует: если GitVerse добавит метод, +проверка создаст настоящую задачу. Для новой проверки нужен временный +репозиторий. + +## Совместимость + +- Это не GitLab API. У GitLab базовый путь начинается с `/api/v4`, а создание + задачи выполняется через `POST /projects/:id/issues`; см. + [GitLab REST API](https://docs.gitlab.com/api/rest/) и + [Issues API](https://docs.gitlab.com/api/issues/). +- Это не совместимая замена GitHub API. Совпадают некоторые маршруты и поля, + но отличаются хост, MIME-тип, версия и полнота операций. Например, GitHub + документирует `POST /repos/{owner}/{repo}/issues` и изменение задачи, а + GitVerse для этого маршрута публикует только `GET`; см. + [GitHub Issues API](https://docs.github.com/en/rest/issues/issues). +- Сходство с GitHub намеренное и частичное: в документации GitVerse некоторые + дубли полей ответа прямо объясняются + [совместимостью с GitHub API](https://gitverse.ru/docs/developers/public-api/repositories/api-post-orgs-repos). + Это не обещание полной совместимости клиента или контракта. + +## Решение для dotfiles + +- Оставить `.scratch` главным хранилищем задач текущей ветки. +- Public API можно использовать для чтения задач. Операции с комментариями + опубликованы, но перед постоянным использованием их стоит отдельно проверить + на тестовой задаче. +- Не строить интеграцию на внутреннем `/sc/sbt/api/v1`. Он требует браузерную + сессию, не документирован и может измениться без предупреждения. +- Вернуться к переносу `.scratch` в GitVerse после появления официальных + методов создания и изменения задач. + +## Неизвестно и требует уточнения у GitVerse + +- Есть ли закрытая бета или планируемый публичный `POST/PATCH` для задач. +- Какие права будут нужны для создания задач, если метод появится. Токен с + правом «Репозитории: Запись» успешно читает репозиторий, но проверить еще не + опубликованную операцию невозможно. +- Поддержит ли GitVerse обычные GitHub-клиенты при замене базового адреса. + Официального заявления об этом не найдено, а различия контракта уже исключают + надежную совместимость. +- [GitVerse MCP](https://gitverse.ru/docs/ai/mcp/) использует тот же токен и + собственный адрес `https://mcp.gitverse.ru`, но официальный список его + сущностей на 21 июля 2026 года не включает задачи. По документации это не + обход отсутствующих операций REST API. + +Следующий шаг: запросить у поддержки GitVerse сроки появления публичных +операций создания и изменения задач, а также нужные права токена.