@s1rne/agentkit
v0.9.0
Published
A team of AI agents, project memory and engineering process — deployed into any repository with one command. Claude Code, Cursor, AGENTS.md.
Maintainers
Readme
agentkit
Русский · English
Команда ИИ-агентов, память проекта и инженерные процессы — разворачиваются в любом проекте одной командой.
npx @s1rne/agentkit initРаботает в Claude Code, Cursor и любом инструменте, читающем AGENTS.md (Codex и совместимые).
Всё содержимое набора — роли, протоколы, промпты, шаблоны памяти — по умолчанию английское: меньше токенов на сессию и лучше понимание моделью. Русский включается флагом:
npx @s1rne/agentkit init --lang ruЯзык записывается в config.json, остальные команды подхватывают его без повторения флага.
Зачем
Три вещи ломаются в разработке с ИИ-агентами чаще всего. Kit решает их не советами, а конструкцией.
Контекст теряется. Новая сессия не знает, что уже сделано, что отменено и почему. → Память живёт в файлах, а не в контексте. Процедура холодного старта поднимает проект с нуля.
Агент проверяет сам себя. Написал код и написал же тест — проверил своё понимание задачи, а не задачу. → Тесты на доменные расчёты пишет другая роль. Ревью адверсариальное: критик ищет дефект, а не одобряет.
Некому управлять. Агенты пишут код, но никто не решает, кто что делает и в каком порядке. → Главная сессия работает техническим лидом: считает состав, следит за ходом, защищает человека от шума.
Что разворачивается
.agentkit/
PROJECT.md ← пишет человек: что за проект, для кого, словарь
HOUSE-RULES.md ← пишет человек: как работать в этом проекте
INBOX.md ← пишет человек: мысли в свободной форме
QUESTIONS.md ← вопросы команды человеку и ответы
roles/ 13 ролей
skills/ 11 протоколов
commands/ 8 команд
blocks/ тексты управляемых блоков для CLAUDE.md / AGENTS.md
state/ память: BOOT · NOW · JOURNAL · DECISIONS · TEAM · RUNS
config.json
tasks/ эпики → фичи → задачи
docs/adr/ записи об архитектурных решениях
.claude/ · .cursor/ · AGENTS.md ← генерируются, править не нужноИнтерфейс человека
Четыре файла, через которые человек управляет командой, не читая её вывод.
PROJECT.md — то, чего агенты не узнают из кода: что за продукт, кто пользователь, ограничения, словарь предметных терминов.
HOUSE-RULES.md — главный. Здесь человек пишет обычными словами, как работать:
## Инструменты
- Задачи ведём в Trello, доска «Разработка».
## Границы
- Не трогать legacy/ — там своя команда.
- Схему БД правит только человек.
## Коммуникация
- Не писать о промежуточных шагах, только развилки и результаты.Лид перестраивает систему под эти правила сам. Сказано «задачи в Trello» — он определит, что это внешний инструмент, заведёт роль синхронизации, добавит вызов в протокол задач, спросит недостающие доступы в QUESTIONS.md и сообщит одной строкой. Разрешения на каждый шаг не спрашивает.
Правило человека противоречит правилу системы — побеждает человек, но лид один раз назовёт последствие. Правило небезопасно — откажется и предложит альтернативу.
INBOX.md — мысли и замечания в свободной форме, лид разбирает в задачи.
QUESTIONS.md — команда спрашивает, человек отвечает прямо в файле. Работает правило: придуманное правило дороже отсутствующего — не знаешь, спроси и заблокируй задачу.
Команда
| | |
|---|---|
| Планирование | planner · architect · domain-analyst |
| Реализация | backend-dev · frontend-dev · mobile-dev · data-engineer · reports-dev · integrations-dev |
| Качество | qa-engineer · critic · security-auditor |
| Память | scribe |
Роль — должность, а не человек. Один backend-dev работает в трёх экземплярах над тремя задачами. Сколько — лид считает алгоритмом, а не на глаз: берёт пул todo, изымает рискованные и миграции, группирует по владельцу, внутри роли режет по непересекающимся touches, ограничивает потолком роли и общим потолком 5.
Штат меняется динамически. Признак найма новой роли один: одна и та же работа встречается в 3+ задачах и не ложится на существующие. Определения ролей никогда не удаляются — меняется статус, файл остаётся.
Жизненный цикл задачи
planner → задача с проверяемыми критериями todo
исполнитель → берёт, реализует, сдаёт отчёт in_progress → review
qa-engineer → тесты (доменные — всегда он)
critic → адверсариальное ревью
[risk: high] → человек
scribe → журнал, NOW, доска doneПропуск критика не допускается. Ревью без замечаний законно — отсутствие ревью нет.
Команды
| | |
|---|---|
| /boot | холодный старт: поднять контекст с нуля и доложить, где мы |
| /plan | разложить работу на фичи и задачи |
| /task | провести задачу через полный цикл |
| /team | запустить несколько агентов параллельно |
| /roster | штат команды и рассчитанный наряд |
| /review | адверсариальное ревью |
| /wrap | записать состояние для следующей сессии |
| /standup | сводка без изменений |
CLI
npx @s1rne/agentkit init --pack web-product --adapters claude-code,cursor --lang ru
npx @s1rne/agentkit sync # перегенерировать конфиги из .agentkit/
npx @s1rne/agentkit doctor # проверить целостность
npx @s1rne/agentkit status # штат и текущее состояние
npx @s1rne/agentkit role cap backend-dev 4Паки: base (6 ролей) · web-product (10) · full (13). Языки: en (по умолчанию) · ru.
Правь .agentkit/, а не сгенерированные .claude/ и .cursor/ — их затрёт sync.
Переносимость
| | Claude Code | Cursor | AGENTS.md | |---|---|---|---| | Память, задачи, протоколы | ✓ | ✓ | ✓ | | Роли | субагенты, изолированный контекст | вызываемые шаблоны | вызываемые шаблоны | | Параллельный запуск | ✓ | — | — | | Слэш-команды | ✓ | частично | — |
Память намеренно живёт в .agentkit/state/, а не внутри папки инструмента: переход с Claude Code на Cursor не теряет историю проекта. По той же причине наблюдаемость сделана протоколом (RUNS.md), а не хуками — хуки не переносятся, файлы переносятся.
Как запускаются агенты
Агенты работают только через подписочные CLI вендоров — claude и cursor-agent. Никогда через платный API-ключ: он тарифицируется отдельно и по токенам. Оркестратор вычищает ANTHROPIC_API_KEY, CURSOR_API_KEY и подобные из окружения каждого дочернего процесса, а doctor падает, если такая переменная выставлена в шелле. Два аккаунта одного вендора разделяются через CLAUDE_CONFIG_DIR / CURSOR_CONFIG_DIR, а не ключами.
Роль просит возможность, а не провайдера — code, bulk, images, big-context, plan-mode, worktree, parallel. Маршрутизатор выбирает среди тех, кто реально авторизован.
agentkit providers # кто доступен и что добавляет
agentkit run T-0042 --role backend-dev --writers 2
agentkit context # насколько заполнена сессия · сколько агентов позволяет машина
agentkit usage # расход токенов за скользящее окно
agentkit box list # открытые боксы, ветки, незакоммиченноеВсё работает на одном Claude Code. Cursor только добавляет возможности. Возможность, которой нет ни у кого, блокирует одну задачу — с записанной командой, которая это чинит, — и никогда не останавливает волну.
Вести всю очередь
agentkit wave # берёт готовые задачи и ведёт каждую до конца
agentkit wave --conc 2 --max 8На задачу: исполнитель → критик → для risk: high второй ревьюер с другой задачей (security-auditor) → слияние → проверки проекта на основной ветке. Слияние, после которого основная ветка краснеет, откатывается сразу: разобрать одно дешевле, чем десять.
Останавливается ради человека только там, где машина честно не может решить: конфликт замысла в коде (историю задачи и лок-файл она разрешает сама), ревью, не сошедшееся за три захода, красная основная ветка. Всё прочее — работа запускателя, а не твоя.
Чем проверять после слияния — задаёшь ты, в .agentkit/providers.json:
"wave": { "verify": ["pnpm -s typecheck", "pnpm -s lint", "pnpm -s test"], "outputBudget": 4000000 }Наблюдать со стороны
Волна пишет по одному JSON-объекту на строку в .agentkit/state/runs/wave-<время>.jsonl — тот же ход работ, что идёт в терминал, только в виде, который читает программа:
{"at":"…","task":"T-12","stage":"impl","event":"started","role":"backend-dev","attempt":1}
{"at":"…","task":"T-12","stage":"impl","event":"finished","ok":true,"account":"claude-1","tokens":184000}
{"at":"…","task":"T-12","stage":"critic","event":"verdict","accepted":false,"attempt":1}
{"at":"…","task":"T-12","stage":"merge","event":"conflict","files":["src/api.ts"],"needsIntegrator":true}Стадии — refresh, impl, critic, audit, merge, verify; события — started, finished, verdict, deferred, conflict, reverted. --events <файл> уводит их в другое место.
Из своего кода: carry() принимает колбэк onEvent, и туда приходят те же объекты. Опрос файлов задач это не заменяет — он отстаёт и не видит середины: задача полчаса в in_progress не говорит, исполнитель ещё пишет, критик уже смотрит или всё повисло.
Видеть, что делает команда
agentkit team # один экран: кто работает, над чем и почём
agentkit team --watch # то же, с обновлением каждые 3 секунды
agentkit team T-0019 # один агент подробно: время, память, токены, последний вердиктЧитает только то, что уже лежит на диске — реестр активных запусков, записи о законченных, frontmatter задач. Опрашивать можно сколько угодно: ничего не запускается.
Один флаг для программы
status, providers, team, box, context и usage принимают --json и печатают то, что и так посчитано, — без цвета, выравнивания и формулировок:
$ agentkit providers --json
{"probedAt":"…","riskyEnv":[],"providers":{…},"accounts":[{"id":"claude-1","state":"ready","windowTokens":184000,…}]}
$ agentkit box --json
[{"taskId":"T-12","mode":"worktree","branch":"ak/T-12","sizeMB":240,"dirty":true,"ahead":3}]Дашборд, разбирающий человеческий вывод, ломается от смены формулировки, от --lang, от подросшей колонки — и превращает читаемый вывод в интерфейс, который больше нельзя улучшать. У волны свой поток: .agentkit/state/runs/wave-<время>.jsonl.
Из своего кода
CLI — один из вызывающих библиотеку, а не единственный вход. Сервис, ведущий несколько репозиториев, импортирует нужное:
import { run } from "@s1rne/agentkit/orchestrator";
import { carry, ready, eventLog } from "@s1rne/agentkit/wave";
import { pick, summary } from "@s1rne/agentkit/accounts";
import { probeAll, route } from "@s1rne/agentkit/providers";
import { gather } from "@s1rne/agentkit/team";
const report = await run(root, cfg, { task: "T-12", wait: true });Подпути: /orchestrator, /wave, /accounts, /providers, /boxes, /resources, /team, /usage. Корень пакета отдаёт их же пространствами имён, плюс run, carry и ready напрямую. Всё, чего в этом списке нет, — закрытое и меняется без предупреждения.
Ничего из перечисленного не лезет в глобальное состояние и не бросает исключение на ожидаемое: run() принимает корень и настройки аргументами, отказ возвращается статусом с причиной, probeAll() не бросает вовсе.
Приём проекта, где агенты уже есть
init пишет шаблоны набора поверх .claude/. Проект, который уже собрал свою команду — свои роли, на своём языке, со своими предметными правилами, — их бы потерял. adopt работает наоборот:
npx @s1rne/agentkit adopt --lang ruОн делает нетронутую копию .claude/, превращает существующие роли, навыки, команды и память в источник в .agentkit/, добавляет только то, чего в проекте не было, и заново генерирует из этого .claude/. Существующие определения проходят побайтово.
Два аккаунта одного вендора
Две подписки — это два логина, а не два API-ключа. Добавить:
agentkit account add cursor work
# выведет точную команду логина для этого аккаунта, дальше:
agentkit account listЧем именно разделяются логины — зависит от вендора, и это проверено, а не предположено:
| Вендор | Разделяется через | Чем подтверждено |
|---|---|---|
| Claude Code | CLAUDE_CONFIG_DIR | пустой каталог конфига даёт loggedIn: false |
| Cursor | HOME | пустой CURSOR_CONFIG_DIR показывает того же пользователя — токен лежит в связке ключей системы, а она находится через HOME |
account add заводит то разделение, которое реально работает. Проверь результат через account list: две строки с одинаковым адресом означают, что изоляции не произошло — набор помечает их как один логин, а не делает вид, что аккаунта два.
Работа уходит тому логину, который меньше потратил в текущем окне подписки, а не по кругу: одна задача может стоить в десять раз больше другой. Прогон, вернувшийся с упором в лимит или потерей авторизации, кладёт этот логин отдыхать до конца окна и один раз повторяется на другом — не в цикле.
Вход без браузера
В одну и ту же подписку Claude ведут два пути, и оба читаются как подписка:
| Путь | Что показывает claude auth status | Когда |
|---|---|---|
| вход через браузер | authMethod: claude.ai, плюс адрес и тариф | на своей машине |
| CLAUDE_CODE_OAUTH_TOKEN | authMethod: oauth_token, без адреса и без тарифа | в контейнере, на сервере, в CI |
Токен выдаёт claude setup-token; он требует Pro/Max/Team/Enterprise и умеет только запросы к модели, поэтому метерным быть не может и из окружения дочернего процесса не вырезается. Это единственный способ поднять агента там, где браузер открыть некому.
Одна оговорка, проверенная: claude auth status не сверяет токен с сервером — просроченный или набранный с ошибкой всё равно даёт loggedIn: true. Это вскрывается на первом же прогоне, и учёт аккаунтов убирает такой логин из ротации на окно.
Токен лежит в окружении, общем для всех конфигурационных каталогов, поэтому двух логинов на нём не построить: аккаунты, смотрящие в один токен, помечаются как один логин — ровно как две строки с одинаковым адресом.
Где агенты работают
У каждой задачи есть бокс, его выбирает лид и записывает в файл задачи:
| Режим | Когда |
|---|---|
| readonly | читающие роли — инструментов записи нет вообще |
| shared | ровно один писатель, обычная задача: ни ветки, ни слияния |
| worktree | два и более одновременных писателя, risk: high или миграция — своя ветка ak/<task> |
| sandbox | проект не под git либо операция разрушительная |
Два одновременных писателя в одной папке дерутся за индекс git, за сборку и за прогон тестов — а не только за строки в файлах. Поэтому порог — «два писателя», а не «пересекающиеся файлы».
Боксы лежат снаружи репозитория, в ~/.agentkit/boxes/<repo>/<task>. Бокс принадлежит задаче, а не агенту: подкоманда наследует бокс родителя, вложенность ограничена глубиной 2. Слияние — отдельная задача роли integrator, никогда не побочный эффект done и никогда до прохождения критика.
Чтобы не убить машину
Флот не должен делать компьютер непригодным для работы. Перед каждым запуском — проверка допуска: запас RAM, запас диска, нагрузка на ядро, потолок параллельности. Отказ возвращается с внятной причиной, а не молчаливой очередью. Во время работы сторож опрашивает дерево процессов и убивает всё, что вышло за потолок RSS или за отведённое время.
По умолчанию человеку резервируется 6 ГБ RAM и 20 ГБ диска, параллельность ограничена числом производительных ядер минус два (не больше 8), на агента закладывается 1.2 ГБ — цифра из реального прогона с пиком 1.4 ГБ, а не из простоя, каждому агенту даётся 3 ГБ RSS и 20 минут. Всё настраивается в .agentkit/providers.json.
Контекст как бюджет
Длинные сессии деградируют. Набор считает это измеримой величиной, а не ощущением: размер контекста сессии — это input + cache_read + cache_creation последнего запроса, и agentkit context его показывает.
- Лид никогда не читает транскрипт исполнителя — только отчёт. Транскрипт уходит в
.agentkit/state/runs/. - Одна задача обязана влезать в один свежий контекст. Не влезает — нарезано неправильно.
- Состояние пишется в момент, когда узнали, а не в конце сессии.
- Лид ротирует сессию на ~60% окна через wrap → boot, а не ждёт, пока начнёт тупить.
- Стабильность важнее краткости: правка всегда загружаемых файлов инвалидирует кэш промпта, и каждый следующий запуск платит полную цену.
Сам набор стоит около 2 000 токенов на старте сессии; остальные ~15 000 подгружаются только по требованию.
Принципы
- Состояние живёт в файлах, а не в контексте сессии.
- Агенты общаются через файлы задач и журнал, а не через чат: асинхронная передача переживает перезапуск.
- Критик обязателен.
- Автор кода не пишет тесты на свои доменные расчёты.
- Придуманное предметное правило дороже отсутствующего.
- Главная сессия — лид, а не исполнитель.
- Сессия заканчивается записью состояния. Не записанное для следующей сессии не существует.
- Работа не помечается как сделанная ИИ — ни в коммитах, ни в файлах, ни в метаданных.
Дорожная карта
- Проверенный разбор потока Cursor: сейчас его схема читается защитно — никто ещё не входил под ним, чтобы её подтвердить.
- Генерировать
TEAM.mdизconfig.json, а не вести руками. - Больше языков: содержимое полностью параметризовано, язык — это каталог в
template/. - Проверить ядро на реальном проекте и выкинуть то, что окажется церемонией.
Статус
0.9.0 — ранняя версия. Конструкция целая и покрыта тестами, очередь доводит рядовую задачу от начала до конца, но ядро ещё не проверено выпуском реального продукта. Протоколы, скорее всего, ужмутся при встрече с настоящей работой.
Лицензия
MIT
