Files
codex-crew/docs/design.md
T

165 lines
11 KiB
Markdown

# codex-crew — дизайн
Одноразовая спека. Удалить после реализации.
## Цель
Плагин Claude Code: Codex как полноценный сабагент-исполнитель без сандбоксов и
ограничений. Оркестратор общается с ним как с обычным Claude-сабагентом:
даёт задание, получает ответ, шлёт follow-up через SendMessage. Заменяет
плагин `openai-codex` (его выключаем).
Ключевые свойства:
- Никаких `-s`/`--dangerously-*` флагов: голый `codex exec` наследует
`~/.codex/config.toml` юзера (danger-full-access, approval never, все MCP,
gpt-5.5 high).
- Асинхронность: сабагент не блокируется на codex, всегда отвечает оркестратору.
- Надёжная детекция завершения/зависания/ошибки — детерминированным скриптом,
не LLM-угадыванием по выводу.
## Структура
```
codex-crew/
.claude-plugin/plugin.json
agents/codex.md # сабагент-транспорт
skills/
codex-do/SKILL.md # делегировать исполнение
codex-review/SKILL.md # ревью ветки/коммита/файлов
codex-consult/SKILL.md # второе мнение, итерации до консенсуса
scripts/codex-run.sh # watchdog-запускалка
docs/design.md # эта спека
```
Установка: локальная marketplace (`/plugin marketplace add ~/Projects/codex-crew`),
как caveman/ponytail. Плагин `openai-codex` отключить.
## scripts/codex-run.sh
Детерминированная обвязка вокруг `codex exec`. Интерфейс:
```
codex-run.sh <job_dir> exec [codex-флаги...] <prompt>
codex-run.sh <job_dir> resume <thread_id> [codex-флаги...] <prompt>
codex-run.sh <job_dir> review [--base X | --commit Y | --uncommitted] [codex-флаги...] [instructions]
```
Codex-флаги (модель, sandbox, effort и т.д. — см. «Переопределяемые
параметры») пробрасываются в `codex exec` без интерпретации.
Поведение:
- Запускает `codex exec --json -o <job_dir>/last.md ... > <job_dir>/events.jsonl 2> <job_dir>/err.log`.
- Парсит `thread_id` из события `thread.started` → пишет `<job_dir>/thread_id`.
- Watchdog: цикл ~30 c; если процесс жив, а mtime `events.jsonl` старше
`$CODEX_STALL_TIMEOUT` (default 600 c) → kill. Сессия codex персистентна,
kill безопасен — продолжается через `resume`.
- На выходе пишет `<job_dir>/status`:
- `ok` — codex завершил turn нормально (есть turn.completed / exit 0)
- `stalled` — убит watchdog'ом по стагнации
- `error: <короткая причина>` — ненулевой exit, ошибка API и т.п.
- Exit code скрипта: 0 только при `ok`.
Всё наблюдаемое состояние — файлы в `job_dir`. Никакого tmux: `codex exec`
не интерактивен, «nudge» = kill + `resume <thread_id>`.
## agents/codex.md
Frontmatter: `model: sonnet` (не Fable — правило юзера), `tools: Bash, Read`.
Протокол (тело агента):
1. Получил задание → создать `job_dir` в scratchpad, запустить
`codex-run.sh <job_dir> exec ...` через Bash `run_in_background`.
2. Проснулся по завершении фоновой таски → читать `status`:
- `ok` → вернуть оркестратору содержимое `last.md` + строку
`thread_id: <uuid>` (для последующих resume).
- `stalled`/`error` → до 3 попыток `codex-run.sh <job_dir> resume <thread_id>
"You were interrupted. Continue the task."`; не помогло — честный отчёт
об ошибке с хвостом `err.log`.
3. SendMessage от оркестратора (follow-up, ответ на вопрос codex, новая
реплика консультации) → `codex-run.sh <job_dir> resume <thread_id> <текст>`
→ вернуть ответ.
4. SendMessage «статус?» пока codex работает → прочитать хвост `events.jsonl`,
ответить, чем codex занят, не прерывая его.
5. Вопрос/блокер от codex приходит как обычный финальный текст turn'а —
вернуть оркестратору как есть (оркестратор ответит через SendMessage).
Путь к скрипту — через `${CLAUDE_PLUGIN_ROOT}/scripts/codex-run.sh`.
Транспортная преамбула: сабагент префиксует первое задание codex'у коротким
блоком (зашит в agents/codex.md): «Работаешь неинтерактивно как исполнитель
для другого агента. Блокер или нужно решение — заверши turn чётким вопросом,
диалог продолжится через resume. Финальное сообщение = отчёт: что сделано,
какие файлы тронуты, как проверено.» Особенности exec-режима — знание
транспорта, оркестратор про них не думает.
## Переопределяемые параметры codex
Дефолт — без флагов: наследуется `~/.codex/config.toml` (yolo: danger-full-access,
approval never, gpt-5.5, reasoning high, все MCP). Любой параметр
переопределяется на запуск. Механизм сквозной: оркестратор передаёт сабагенту
опциональную строку `codex options: <флаги>`, сабагент пробрасывает её в
`codex-run.sh`, тот — в `codex exec` как есть.
Таблица частых переопределений (войдёт в agents/codex.md и скиллы):
| Что | Флаг |
|---|---|
| Модель | `-m <model>` (например `-m o3`) |
| Reasoning effort | `-c model_reasoning_effort="minimal\|low\|medium\|high\|xhigh"` |
| Права/sandbox | `-s read-only` / `-s workspace-write` / `-s danger-full-access` (default) |
| Рабочая директория | `-C <dir>` |
| Доп. write-директории | `--add-dir <dir>` |
| Картинки в промпт | `-i <file>` (повторяемый) |
| Структурированный ответ | `--output-schema <schema.json>` |
| Профиль конфига | `-p <profile>` ($CODEX_HOME/<name>.config.toml) |
| Фичи вкл/выкл | `--enable <feature>` / `--disable <feature>` |
| Любой конфиг-ключ | `-c key=value` (dotted path, TOML-значение) |
Запрещён `--ephemeral` — ломает resume. Точные допустимые значения effort
сверить при имплементации.
## Скиллы (тонкие, для оркестратора)
Все три: «спавни агента `codex`, промпт формируй так». Общее: передавать cwd
проекта, нужные файлы/пути, критерии готовности; thread_id из ответа
использовать для follow-up через SendMessage.
Каждый скилл содержит скелет промпта — не жёсткую форму, а список «что обязано
быть» + пример:
- codex-do: задание, cwd, релевантные файлы, критерии приёмки, что вернуть.
- codex-review: скоуп, формат находок `file:line — severity — проблема — фикс`,
без похвал и пересказа.
- codex-consult: роль «второе мнение, не исполнитель — не переписывай
артефакт, дай находки и рекомендации», требования юзера, сам артефакт.
- **codex-do** — делегировать задачу (код, фикс, исследование). Триггеры:
«отдай кодексу», «пусть codex сделает/напишет/починит». После завершения —
оркестратор проверяет результат (diff, тесты).
- **codex-review** — ревью. Триггеры: «ревью у кодекса», «пусть codex
посмотрит ветку/коммит/файл». Скоуп: `--base` / `--commit` /
`--uncommitted` / произвольные файлы обычным exec-промптом. Выход — список
находок.
- **codex-consult** — второе мнение (спека, план, любой артефакт). Передать
артефакт + требования юзера; итерировать через SendMessage до консенсуса,
лимит ~5 итераций; финал — резюме: что согласовано, что осталось спорным.
Это же — точка входа для superpowers-циклов (спека/план), без жёсткой
привязки к ним.
## Проверить при имплементации
- Доставляется ли результат сабагента родителю автоматически при re-invoke
фоновой таской. Если нет — fallback: скиллы велят оркестратору пинговать
SendMessage'ем; сабагент отвечает по файлам `job_dir`.
- `codex exec review`: есть ли `--json`/`-o` и thread_id. Если нет — забирать
stdout целиком; ревью-итерации через `resume --last` или обычный exec.
## Вне скоупа
Глубокая интеграция с superpowers (кастомные ветки их воркфлоу), поддержка
нескольких параллельных codex-сессий одним сабагентом (одна сессия = один
сабагент; параллельность — спавном нескольких сабагентов).