eva-agent/CLAUDE.md
Andrey Epifancev cf7c7bde8c Документация и решения 36–43: выкатка --module wiki, base_url, launchd (I-3, T6.1, T6.4, M-2, M-6, #1)
- CLAUDE.md: `jira-hub agent publish --module wiki src/agent.py`, порог `wiki_min_agent_version`.
- README: `wiki_min_agent_version` вместо `min_agent_version`; `eva.base_url` — только origin; агент только для macOS
  (fcntl), пример launchd `ru.aepif.eva-agent`; строка про проверку SSO на первой живой синхронизации (M-5).
- ARCHITECTURE: строки Eva и Executor по реализованному, строки ссылок (`_LinkParser`, `classify_links`) и дерева
  (`build_children`, `walk`).
- design.md: решения 36–43, в том числе почему M-5 отложен до живой проверки.

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

62 lines
7.1 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# eva-agent
## Что это
Клиент модуля wiki хаба (sdlc-hub, `../jira-hub`) для виртуалки с доступом к Eva банка. Опрашивает хаб, по командам
`wiki_sync` (выгрузить поддерево страниц с корня) и `wiki_fetch` (скачать вложение) читает Eva и отдаёт данные хабу;
в Eva ничего не пишет. Главный сценарий: хаб ставит `wiki_sync` с кодом корня, агент обходит дерево страниц, шлёт
страницы пачками в стадию хаба и отчитывается списком кодов.
Спека и дизайн: `../jira-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` — сквозной прогон с тестовым хабом из `../../../jira-hub/.wt/wiki` (временный `JIRA_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 ../jira-hub
jira-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`.