eva-agent/CLAUDE.md
Andrey Epifancev e38d21fff1 docs, e2e: хаб переименован в sdlc-hub (#5)
Пути ../sdlc-hub, sdlc-hub tokens / agent publish; scripts/e2e-hub.sh —
SDLC_HUB_HOME, CLI sdlc-hub, хаб по умолчанию из основного checkout
sdlc-hub workspace (worktree jira-hub/.wt/wiki больше нет).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-24 16:10:15 +04:00

7.1 KiB
Raw Blame History

eva-agent

Что это

Клиент модуля wiki хаба (sdlc-hub, ../sdlc-hub) для виртуалки с доступом к Eva банка. Опрашивает хаб, по командам wiki_sync (выгрузить поддерево страниц с корня) и wiki_fetch (скачать вложение) читает Eva и отдаёт данные хабу; в Eva ничего не пишет. Главный сценарий: хаб ставит wiki_sync с кодом корня, агент обходит дерево страниц, шлёт страницы пачками в стадию хаба и отчитывается списком кодов. Спека и дизайн: ../sdlc-hub/openspec/changes/wiki-module/ (hub#91, PR hub#92); решения агента — openspec/changes/eva-agent-mvp/design.md. Issue агента — aep/eva-agent#1.

Стек и ограничения

  • Python 3.9.6 (как на виртуалке), только стандартная библиотека, без venv и зависимостей.
  • Запрещено: синтаксис 3.10+ и сторонние импорты. tests/test_py39.py ловит синтаксис 3.10+ и сторонние импорты; X | Y в аннотациях функций ловит прогон на /usr/bin/python3 3.9.6.
  • agent.json содержит токены хаба и Eva — не коммитить, не отправлять в хаб, не выносить с виртуалки. Шаблон без секретов — src/agent.example.json.

Архитектура

  • src/agent.py — весь агент, один файл. Общие части скопированы из jira-agent v14 без изменения смысла (решение 1): Http/HttpError/RedirectAway/TooBig, FolderTransport (хаб через общую папку), HubClient, Journal, Updater (самообновление), Runner (claim → пауза → журнал → выполнение → отчёт), acquire_lock, CLI run|check|selftest|prune. Своё: EvaClient (клиент Eva), Executor (do_wiki_sync, do_wiki_fetch).
  • src/run.py — запускатель, дословная копия ../jira-agent/src/run.py (решение 2); agent.py не импортирует.
  • Границы: Executor знает Eva и хаб (стадия страниц wiki_pages, файл upload_file); Runner знает хаб, Eva и журнал; журнал не знает об Eva. Имена полей протокола хаба jira_calls/rate_limited общие для всех агентов: в jira_calls идёт число вызовов Eva.
  • src/agent.example.json — шаблон настроек, README.md — эксплуатация. Подробнее: ARCHITECTURE.md.

Команды

  • /usr/bin/python3 -m unittest discover -s tests -t . — весь набор тестов. Зелёным считается только весь набор.
  • /usr/bin/python3 -W error::ResourceWarning -m unittest discover -s tests -t . — то же с ошибками на незакрытые ресурсы (так проверяем перед коммитом).
  • /usr/bin/python3 src/agent.py check — доступность хаба и Eva (CmfDocument.list, 1 запись), без записи; код 0 или 3.
  • /usr/bin/python3 src/agent.py run --once — выполнить выданное и выйти при первом пустом claim.
  • bash scripts/e2e-hub.sh — сквозной прогон с тестовым хабом из основного checkout sdlc-hub workspace (временный SDLC_HUB_HOME, свободный порт, фейковая Eva); «e2e: ok». Живой хаб не трогать.
  • /usr/bin/python3 src/agent.py — основной цикл (нужен agent.json рядом с agent.py).
  • /usr/bin/python3 src/agent.py prune — очистка журнала (при работающем агенте откажет).
  • /usr/bin/python3 src/agent.py selftest — версия + check; код 0 или 3.
  • /usr/bin/python3 src/run.py — запуск через запускатель (самообновление).

Тесты

  • Тесты в tests/, запуск из корня worktree. Внешних сервисов нет: хаб и Eva заменяют фейки tests/fake_hub.py, tests/fake_relay.py (реле общей папки) и tests/fake_eva.py; scripts/fake_eva_serve.py поднимает тот же фейк отдельным процессом для e2e.
  • tests/_common.py — путь к src, SETTINGS (как их отдаёт /agent/settings), eva_cfg(), no_sleep().
  • Тесты общих частей перенесены из jira-agent: test_clients.py (HTTP), test_folder.py (папка), test_journal.py, test_runner.py (цикл и восстановление; команда-заглушка wiki_fetch), test_update.py (самообновление), test_launcher.py (запускатель + test_run_py_is_copy), test_self_update_e2e.py (run.py + настоящий agent.py).
  • Фикстуры страниц — tests/fixtures/pages/. Golden-сценариев нет: каждый тест строит сценарий в коде. Тестовый HTML — синтетический.

Первая подсистема

MVP агента: каркас с общими частями (задача 1 плана docs/superpowers/plans/), затем клиент Eva, обход дерева, wiki_sync, wiki_fetch, установка и живая проверка. Версия агента — 1. Выкатка: uv run --project ../sdlc-hub sdlc-hub agent publish --module wiki src/agent.py (из основного checkout; без --module версия уйдёт агенту jira); порог — настройка хаба wiki_min_agent_version; токен — «агент wiki».

OpenSpec и superpowers

  • Вход в любую задачу — superpowers:brainstorming. Skills openspec-propose и openspec-explore сами по себе не запускать.
  • Когда brainstorming классифицировал задачу как architectural, структуру change создать через openspec new change <id> (или /opsx:propose <id>), а содержимое proposal.md, specs/ и design.md написать по итогам brainstorming. tasks.md из OpenSpec не заполнять — задачи живут в плане superpowers.
  • /opsx:apply не использовать: исполнение идёт через writing-plans и SDD/executing-plans.
  • openspec archive <id> — после merge PR, как часть чеклиста закрытия.
  • Хук require-plan защищает любой каталог src/ на любой глубине. Если код лежит иначе — перечислить каталоги (префиксы от корня, по одному в строке) в .claude/code-paths.