Направьте агента на репозиторий GitHub — и получите готовую доску: каждый issue как история, в том состоянии, которого требует её история изменений, вместе с чек-листами, метками и вехами. Затем тот же агент берёт историю, назначает себя владельцем, проводит её через машину состояний и прикрепляет открытый им pull request.
Эта страница описывает весь цикл. У шага наполнения два пути: GitHub-to-EAT, открытый импортёр East Agile, делает всё одной командой (шаг 3); API импорта делает ту же работу вызов за вызовом (шаги 4 и 5), и именно им управляет агент, когда ему нужен дескриптор задачи. Всё дальнейшее идёт через API, потому что смысл в том, чтобы остальное агент делал без присмотра.
Это не отдельный «ИИ-импорт». Шаг наполнения — тот же импортёр GitHub, который вы запускаете вручную из Настройки проекта → Импорт / Экспорт, описанный в Руководство пользователя → Импорт из других трекеров. Агент вызывает тот же эндпоинт, что и вы. Эта страница добавляет всё, что вокруг: кто держит ключ, как проверить импорт до записи и что агент делает с доской, когда она уже есть.

Что вам нужно
Заголовок раздела «Что вам нужно»- Проект — и сессия либо ключ
ea_user_…, которым вы его создадите. - Ключ агента — ключ
ea_agent_…, привязанный к этому проекту. Какая роль ему нужна, зависит от того, какую часть цикла должен вести агент; см. шаг 2. См. также Руководство по API → Два вида ключей. - Персональный токен доступа GitHub — с правом чтения issues репозитория. Любой импорт проходит аутентификацию, потому что выборка идёт через GraphQL API GitHub, а GraphQL отклоняет запрос без токена. Опустить его можно только тогда, когда выборку делает Tracker от вашего имени: публичный репозиторий, на развёртывании, у которого есть общий запасной токен (у размещённого eastagiletracker.com он есть; у самостоятельной установки его нет, пока её оператор не задаст
GITHUB_IMPORT_PAT), и никогда с--engine directв GitHub-to-EAT. См. Токены и лимиты запросов. - Node.js 22+ — только для пути через GitHub-to-EAT на шаге 3. Пути через API достаточно
curl.
1. Создайте проект
Заголовок раздела «1. Создайте проект»Проект должен существовать раньше ключа агента, и создать его должен человек: ключи агентов привязываются к одному проекту при выпуске и сами проект не создают. Сделайте это в интерфейсе или своим ключом ea_user_…:
curl -X POST https://eastagiletracker.com/api/v1/projects \ -H "X-TrackerToken: $TRACKER_USER_TOKEN" \ -H "Content-Type: application/json" \ -d '{"name": "hello-world", "iteration_length_weeks": 1}'Ответ несёт project_id, который нужен каждому вызову ниже.
2. Выпустите ключ агента
Заголовок раздела «2. Выпустите ключ агента»Владелец проекта создаёт ключи агентов в Настройки проекта → Агенты. Выбранная роль решает, какую часть этой страницы агент сделает сам, и разумных ответов два:
owner— один ключ проходит весь цикл, включая импорт. Импортировать может только владелец, потому что импорт переписывает форму проекта целиком. Чтобы выпустить агента с рольюowner, вы сами должны быть владельцем проекта: роль агента никогда не превышает роль его создателя.member— минимальные права. Агент берёт истории, двигает их, комментирует и прикрепляет pull request’ы, но импортировать не может. Импорт вы запускаете сами (шаг 5) своим ключом, а затем передаёте доску агенту.
В любом случае не оставляйте значение по умолчанию. Новый ключ агента — viewer, пока вы не скажете иначе, а viewer читает доску, но не берёт и не двигает историю — то есть не делает большую часть этого цикла.
Ключи агентов важны здесь не только из-за доступа. Ключ агента выступает как именованный участник одного проекта, поэтому каждая созданная им история, каждая смена состояния и каждый комментарий приписаны в истории именно этому агенту — отличимы от вашей собственной работы, а не смешаны с ней.
export TRACKER_TOKEN="ea_agent_xxxxx"Пусть агент прочитает /meta прежде всего остального:
curl https://eastagiletracker.com/api/v1/meta \ -H "X-TrackerToken: $TRACKER_TOKEN"Это отвечает на два вопроса, которые агент иначе угадывал бы: к какому проекту привязан ключ (auth.project_id) и какие переходы состояний законны для каждого типа истории (transitions). Feature идёт unstarted → started → finished → delivered → accepted; chore — только unstarted → started → accepted. Прочитать карту лучше, чем зашить её в код.
3. Импорт через GitHub-to-EAT
Заголовок раздела «3. Импорт через GitHub-to-EAT»GitHub-to-EAT — собственный открытый импортёр East Agile: инструмент командной строки под лицензией MIT, который выполняет весь шаг наполнения — шаги 4 и 5 ниже — одной командой. Берите его, когда за терминалом сидит человек. Берите API под ним, когда управляет агент без присмотра и ему нужен дескриптор задачи для опроса.
Ему нужен Node.js 22+ и нет собственных зависимостей времени выполнения. В npm он пока не опубликован, поэтому установите его из репозитория:
git clone git@github.com:EastAgile/GitHub-to-EAT.gitcd GitHub-to-EATnpm install --global .Затем направьте его на ключ из шага 2 и проект из шага 1:
export EAT_AGENT_KEY="ea_agent_xxxxx"github-to-eat --project $PROJECT_ID --repo octocat/hello-worldСначала он печатает легенду сопоставления — как именно ляжет каждый выбранный тип — и просит подтверждения, прежде чем что-либо записать. Вне терминала, в конвейере, в CI или в агенте показать этот запрос негде, поэтому запуск, который стал бы писать, обязан передать --yes; без него инструмент завершается с кодом 2 и не пишет ничего, вместо того чтобы угадывать ваш ответ. Повторный запуск безопасен: уже импортированное пропускается, а не дублируется.
| Флаг | Что делает |
|---|---|
--dry-run | Предварительная проверка, затем печать плана, который был бы выполнен, — сколько историй он импортировал бы, сколько пропустил бы как уже существующие — и ничего не пишет. --yes не нужен. |
--include | Какие типы импортировать, через запятую: issues,prs,milestones,releases,deps. По умолчанию issues, и любой выбор обязан его содержать. Это те же опции, что и в таблице на шаге 6. |
--token | Ваш персональный токен доступа GitHub (GITHUB_TOKEN в окружении или в .env тоже считается). Ему нужен repo либо детальное право Issues: Read на этот репозиторий. Обязателен для приватного репозитория, для сервера без общего запасного токена и всегда для --engine direct. Опустите его на движке по умолчанию размещённого сервиса — и Tracker потратит собственный общий бюджет; см. Токены и лимиты запросов. |
--engine | server, значение по умолчанию, шлёт один вызов /import/json и оставляет выборку, сопоставление и запись Tracker’у. direct запускает тот же конвейер на вашей машине и пишет через публичный API — то есть читает GitHub сам и всегда требует токен, иначе завершается с кодом 2. |
--states, --milestones, --story-type, --no-comments, --no-tasks | Сужают или переопределяют сопоставление для одного запуска; ничего не сохраняется. Каждый из них подразумевает --engine direct. |
Задайте EAT_API_BASE и EAT_APP_BASE, чтобы направить его на самостоятельно размещённый или локальный Tracker; оба по умолчанию указывают на размещённый сервис. README несёт полный справочник флагов, коды выхода и разбор проблем.
Всё ниже — тот же импорт, управляемый вызов за вызовом, и именно это вам нужно, когда его запускает агент.
4. Сначала сухой прогон
Заголовок раздела «4. Сначала сухой прогон»Импорт доступен только владельцу — используйте ключ агента с ролью owner или собственный ключ, если оставили агента как member. Запустите сначала с dry_run, прежде чем разрешать запись:
curl -X POST https://eastagiletracker.com/api/v1/projects/$PROJECT_ID/import/json \ -H "X-TrackerToken: $TRACKER_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "source": "github", "owner": "octocat", "repo": "hello-world", "include_pull_requests": true, "include_milestones": true, "dry_run": true }'Сухой прогон выбирает данные из GitHub, сопоставляет и устраняет дубликаты ровно как настоящий, сообщает те же счётчики — imported, skipped, errors, unmatched — и затем откатывает всю транзакцию. Ничего не сохраняется, и ни одно событие о завершённом импорте не попадает в журнал аудита. Это самый дешёвый способ выяснить, что вы хотели включить вехи или что репозиторий больше, чем вы думали, — пока это ещё ничего не стоит.
Каждый вызов /import/json асинхронный, включая сухой прогон: эндпоинт возвращает 202 с дескриптором задачи, а не результат, и счётчики приходят на задачу, когда вы её опрашиваете (шаг 5). Задача сухого прогона достигает done, как и настоящая; разница в том, что ничего не было записано.
5. Запустите импорт
Заголовок раздела «5. Запустите импорт»Уберите dry_run и отправьте снова. Как и прежде, эндпоинт возвращает 202 с дескриптором задачи:
{ "import_id": "…", "status": "pending" }Опрашивайте задачу, пока она не достигнет конечного состояния:
curl https://eastagiletracker.com/api/v1/projects/$PROJECT_ID/imports/$IMPORT_ID \ -H "X-TrackerToken: $TRACKER_TOKEN"Статус идёт pending → fetching → writing → done | failed. Конечных только два последних: done несёт счётчики результата, failed несёт сообщение об ошибке и стабильный машинный код, по которому можно ветвиться. Пока выборка идёт постранично, progress_current и progress_total говорят, на какой она странице, — стоит показать, если смотрит человек.
Токены. Передайте "token": "github_pat_…". Опустите его — и сервер подставит общий платформенный токен, который читает только публичные репозитории и расходуется на всех вызывающих в развёртывании; Токены и лимиты запросов объясняет, чего это стоит. Какой бы токен ни использовался, он ведёт вызовы к GitHub и ничего больше: он никогда не попадает в логи, никогда в журнал аудита, никогда не сохраняется и никогда не возвращается в ответе или ошибке.
Повторный запуск безопасен. Строка, уже импортированная ранее, опознаётся по id в источнике и пропускается, а не дублируется. Второй импорт дополняет доску тем, что появилось после первого.
6. Что попадает на доску
Заголовок раздела «6. Что попадает на доску»Issues импортируются по умолчанию. Всё остальное подключается по выбору, по одному флагу на тип:
| Из GitHub | Становится | Флаг |
|---|---|---|
| Issue | История. Открытая → unstarted в Backlog. Закрытая → accepted, либо rejected, когда GitHub сообщает, что issue закрыт как not_planned или duplicate (история тогда несёт соответствующую метку). | по умолчанию |
| Чек-лист в теле issue | Задачи — каждая строка - [ ] / - [x] становится одной задачей в порядке текста, [x] приходит уже выполненной. Чек-лист остаётся и в описании. | по умолчанию |
| Метки | Метки, перенесённые как есть. | по умолчанию |
| Pull request | История с меткой pull-request. Открыт → started, влит → accepted, закрыт без влития → rejected. | include_pull_requests |
| Веха | Эпик, названный по вехе и лишённый дублей по заголовку — два issue с общей вехой попадают в один эпик. С выключенным флагом она едет как метка milestone:<заголовок>. | include_milestones |
| Релиз | История релиза. Опубликован → accepted, черновик → unstarted. | include_releases |
| Зависимость issue | Блокер на истории. Только issues, никогда pull request’ы. | include_dependencies |
Тип истории выводится, когда issue его не называет. Метка, содержащая bug, fix или defect, — либо заголовок, начинающийся с fix или bug, — делает её багом; chore, maintenance, devops или infra делают её chore; всё остальное — feature. Об этом стоит знать до импорта, потому что в East Agile Tracker points несут только features и только features питают velocity. См. Введение → Истории.

7. Агент работает над историей
Заголовок раздела «7. Агент работает над историей»Теперь у доски есть история изменений, а у агента — ключ. Дальше цикл укладывается в четыре вызова.
Найдите историю или напишите её. Отфильтруйте доску, чтобы найти, что взять:
curl "https://eastagiletracker.com/api/v1/projects/$PROJECT_ID/stories?state=unstarted" \ -H "X-TrackerToken: $TRACKER_TOKEN"import_source=github сужает выборку до того, что принёс импорт. Если агент нашёл работу, которую репозиторий никогда не фиксировал, он создаёт историю сам — см. Руководство по API → Создание истории.
Возьмите её себе. Агент добавляет себя владельцем, отправив пустое тело:
curl -X POST https://eastagiletracker.com/api/v1/projects/$PROJECT_ID/stories/$STORY_ID/owners \ -H "X-TrackerToken: $TRACKER_TOKEN" \ -H "Content-Type: application/json" \ -d '{}'Пустое тело означает вызывающего, поэтому агенту не нужно знать собственный id. Доска теперь показывает агента владельцем, и по этому наблюдающий человек понимает, что работа занята.
Начните её.
curl -X POST https://eastagiletracker.com/api/v1/projects/$PROJECT_ID/stories/$STORY_ID/transitions \ -H "X-TrackerToken: $TRACKER_TOKEN" \ -H "Content-Type: application/json" \ -d '{"to": "started"}'Дальше агент идёт и делает работу — читает репозиторий, пишет код, открывает pull request. Эта часть происходит в вашем инструменте разработки, не здесь.
Прикрепите pull request.
curl -X POST https://eastagiletracker.com/api/v1/projects/$PROJECT_ID/stories/$STORY_ID/links \ -H "X-TrackerToken: $TRACKER_TOKEN" \ -H "Content-Type: application/json" \ -d '{"url": "https://github.com/octocat/hello-world/pull/42"}'URL pull request’а на GitHub распознаётся сам — говорить об этом не нужно. История и закрывающий её код теперь в одном клике друг от друга, в обе стороны.
Завершите её. Переведите в finished и остановитесь. У feature впереди ещё delivered и accepted, и это ворота проверки: что работа сделана верно, решает кто-то, кроме агента. У chore таких ворот нет — started → accepted и есть весь её оставшийся путь.

Токены и лимиты запросов
Заголовок раздела «Токены и лимиты запросов»Любой импорт проходит аутентификацию. Выборка issues, комментариев и pull request’ов идёт через GraphQL API GitHub, а GraphQL отклоняет запрос без токена — анонимного уровня нет ни для публичного репозитория, ни для приватного. Вопрос не в том, дойдёт ли токен до GitHub, а только чей.
Ваш собственный токен
Заголовок раздела «Ваш собственный токен»Передайте token в вызове импорта или --token в GitHub-to-EAT. Достаточно детального персонального токена доступа с правом чтения issues репозитория. Он ведёт вызовы к GitHub и ничего больше: никогда не попадает в логи, никогда в журнал аудита, никогда не сохраняется и никогда не возвращается в ответе или ошибке.
Для всего серьёзнее демонстрации приносите свой. Тогда вы тратите бюджет, которого никто больше не касается, и никакая предварительная проверка не откажет вам из-за чужого импорта.
--engine direct не оставляет выбора. Этот движок читает GitHub с вашей машины, а не через Tracker, поэтому токен сервера недоступен; запуск без токена завершается с кодом 2 и ошибкой использования до того, как что-либо выберет или запишет. GITHUB_TOKEN в вашем окружении или в .env считается так же, как --token.
Токен требует обход issues, а не весь движок. direct читает issues, комментарии и pull request’ы через GraphQL, у которого нет анонимного режима; REST он трогает только ради списка releases и бесплатной пробы /rate_limit. Инструмент до сих пор поставляет более старый анонимный REST-загрузчик, который проводил импорт публичного репозитория в рамках лимита 60 в час, но ни один путь CLI до него уже не доходит и его собираются удалить — поэтому считайте --token обязательным для direct.
Общий токен развёртывания
Заголовок раздела «Общий токен развёртывания»Не отправляйте token — и сервер подставит платформенный токен, настроенный его оператором (GITHUB_IMPORT_PAT). С ним идут три ограничения:
- Это необязательная настройка. Размещённый eastagiletracker.com предоставляет такой токен, поэтому импорт публичного репозитория без токена там работает. У самостоятельной установки — скачанного бинарника — его нет, пока её оператор не задаст
GITHUB_IMPORT_PATв окружении, и до тех пор она отклоняет каждый импорт без токена ошибкой400import_github_no_token. - Он читает только публичные репозитории. Размещённый сервис выпускает его только на чтение публичных репозиториев, поэтому приватному репозиторию всегда нужен ваш собственный токен.
- Все вызывающие в развёртывании делят один бюджет. Прежде чем запустить импорт без токена, сервер читает остаток очков GraphQL общего токена и отклоняет запрос с
400import_github_shared_quota_lowниже 500. Бюджет, кончившийся посреди импорта, роняет задачу сimport_github_rate_limited_platform. Оба сообщения называют одно и то же решение: дать свой токен.
Что даёт токен
Заголовок раздела «Что даёт токен»GitHub считает свои два API раздельно, и потолок без аутентификации на два порядка ниже.
| API GitHub | Используется для | С токеном | Без токена |
|---|---|---|---|
| GraphQL | Issues, комментарии, pull request’ы, вложенные issues, зависимости | 5000 очков в час, начисляемых по узлам, которые возвращает запрос | Отказ — у GraphQL нет анонимного уровня |
| REST | Релизы (include_releases) и предварительная проверка /rate_limit | 5000 запросов в час | 60 запросов в час, считаемых на IP-адрес и делимых со всеми за ним |
Импорт никогда не скатывается на этот уровень в 60 в час: раз отправлять нечего, запрос отклоняется заранее, а не повторяется анонимно. Число важно для того, что вы делаете вокруг импорта — скрипт, читающий GitHub напрямую, или оболочка в одной сети с другими клиентами исчерпывает 60 запросов за секунды.
Читайте остаток бюджета когда угодно; GET /rate_limit освобождён от обоих лимитов, поэтому проверка ничего не стоит:
curl -H "Authorization: Bearer $GITHUB_TOKEN" https://api.github.com/rate_limitОчки GraphQL — не запросы. GitHub оценивает запрос по узлам, которые он возвращает, поэтому одна страница из 100 issues вместе с их комментариями и назначенными стоит много очков, а большой репозиторий тратит часовой бюджет за куда меньшее число вызовов, чем подсказывают цифры эпохи REST. --dry-run (шаг 3) и dry_run (шаг 4) стоят каждый столько же очков, сколько настоящая выборка — именно это делает их счётчики надёжными — поэтому закладывайте два прохода, когда готовите большой импорт.
Куда двигаться дальше
Заголовок раздела «Куда двигаться дальше»- Руководство по API — грамматика поиска, поток событий, массовые переходы, идемпотентные записи и остальная поверхность.
- Руководство пользователя — те же операции из интерфейса и остальные десять импортёров.
- Введение — почему машина состояний и четыре типа историй устроены именно так.
- GitHub-to-EAT — собственный репозиторий импортёра: каждый флаг, оба движка и как в него внести вклад.