165 lines
11 KiB
Markdown
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-сессий одним сабагентом (одна сессия = один
|
|
сабагент; параллельность — спавном нескольких сабагентов).
|