From 76e6b293c8603df08cebdb02e6093309efe2fe91 Mon Sep 17 00:00:00 2001 From: Dmitrii Date: Fri, 3 Apr 2026 12:26:46 +0300 Subject: [PATCH] =?UTF-8?q?refactor(skills):=20=D0=BE=D0=BF=D1=82=D0=B8?= =?UTF-8?q?=D0=BC=D0=B8=D0=B7=D0=B8=D1=80=D0=BE=D0=B2=D0=B0=D0=BD=20codex-?= =?UTF-8?q?review=20=D0=B4=D0=BB=D1=8F=20Plan=20Mode=20=D0=B8=20resume?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Зачем: - в Plan Mode ревью плана вызывало ~5 permission prompts (git, Write, rm), хотя для плана git не нужен, а план уже является файлом. - Что: - добавлен fast path: явный `plan` или Plan Mode пропускают git-проверки - base branch определяется лениво (только для code/code-vs-plan) - resume упрощён через `2>/dev/null` (stderr → /dev/null, stdout = чистое ревью) - cleanup пропускается в Plan Mode, best-effort вне его - удалены deprecated permissions claude-diff-* из settings.local.json - Проверка: - `/codex-review plan` в Plan Mode — 0 permission prompts - `/codex-review code` вне Plan Mode — работает как раньше Co-Authored-By: Claude Opus 4.6 (1M context) --- TODO.md | 7 +++ agents/.agents/skills/codex-review/SKILL.md | 53 +++++++++++++-------- claude/.claude/settings.local.json | 2 - 3 files changed, 41 insertions(+), 21 deletions(-) diff --git a/TODO.md b/TODO.md index 088dbc5..bf16b63 100644 --- a/TODO.md +++ b/TODO.md @@ -30,11 +30,18 @@ Также разобраться с поведением `codex exec resume` — переключается на `workspace-write` sandbox и `xhigh` reasoning вместо запрошенных `read-only` / `high`. +## ~~codex-review: plan mode без git~~ DONE + +Реализовано: fast path для режима `plan` — при явном аргументе `plan` или +в Claude Code Plan Mode git-проверки и определение base branch пропускаются. +Resume упрощён через `2>/dev/null` (stderr → /dev/null, stdout = чистое ревью). + ## codex-review: pipe в определении base branch Команда `git symbolic-ref ... | sed` содержит pipe `|`, который может триггерить permission prompt в Claude Code. Пока не триггерит, но если начнёт — заменить на два отдельных вызова или определять branch иначе. +Актуально только для режимов `code` и `code-vs-plan` — в `plan` git не вызывается. ## codex-review: отдельный репозиторий + статья на Хабр diff --git a/agents/.agents/skills/codex-review/SKILL.md b/agents/.agents/skills/codex-review/SKILL.md index 94aba63..3b82ca6 100644 --- a/agents/.agents/skills/codex-review/SKILL.md +++ b/agents/.agents/skills/codex-review/SKILL.md @@ -25,9 +25,14 @@ user_invocable: true ### Шаг 1: Определить режим ревью -Определи, что ревьюить, по контексту и аргументам: +Определи, что ревьюить. Проверяй в порядке приоритета: -**Автодетект (без явного аргумента):** +**1. Явный аргумент** (`plan`, `code`, путь к файлу) → использовать его. + - Для `plan` → пропустить все git-проверки, перейти к шагу 2 (только REVIEW_ID). + +**2. Claude Code Plan Mode** — если в контексте есть системное сообщение "Plan mode is active" → режим = `plan`, пропустить git. В Plan Mode код не редактируется, поэтому code/code-vs-plan невозможны. + +**3. Автодетект** (без явного аргумента, вне Plan Mode): 1. Проверь наличие изменений кода (любой непустой — значит есть): - `git diff --name-only` — unstaged @@ -42,14 +47,16 @@ user_invocable: true | Да | Нет | **code** — ревью изменений кода | | Нет | Нет | Спросить пользователя, что ревьюить | -**Явные аргументы** имеют приоритет над автодетектом: `plan`, `code` или путь к файлу. - -### Шаг 2: Сгенерировать Session ID +### Шаг 2: Сгенерировать Session ID и определить base branch Сгенерируй уникальный `REVIEW_ID` самостоятельно, формат: `{unix_timestamp}-{случайное_4значное_число}`. Пример: `1711872000-4821`. **НЕ используй bash** — подставляй значение напрямую в команды следующих шагов. -Определи base branch репозитория: +**Определение base branch (только для режимов `code` и `code-vs-plan`):** + +Для режима `plan` — пропустить определение base branch, перейти к шагу 3. + +Для остальных режимов определи base branch репозитория: ```bash git symbolic-ref refs/remotes/origin/HEAD 2>/dev/null | sed 's|refs/remotes/origin/||' @@ -67,8 +74,8 @@ git rev-parse --verify main 2>/dev/null && echo main || echo master **Ревью плана:** -- Если план уже существует как файл (в `project/`, memory или где-то в репо) — использовать путь напрямую. НЕ копировать. -- Если план только в контексте разговора — записать через **Write tool** в `/tmp/claude-plan-${REVIEW_ID}.md`. +- Если план уже существует как файл (в `project/`, plan file от Plan Mode, memory или где-то в репо) — использовать путь напрямую. НЕ копировать. В Claude Code Plan Mode план всегда является файлом. +- Если план только в контексте разговора (вне Plan Mode) — записать через **Write tool** в `/tmp/claude-plan-${REVIEW_ID}.md`. - **Обязательно вывести путь к файлу плана пользователю**, чтобы он мог открыть его в IDE: `📄 План для ревью: <путь-к-файлу>` @@ -247,9 +254,9 @@ If changes are needed, end with exactly: VERDICT: REVISE" ### Шаг 7: Переотправить в Codex (Раунды 2-5) -**Предпочтительно: `resume`** — экономит токены, сохраняет контекст сессии: +**Resume — основной путь.** Экономит токены и сохраняет контекст сессии Codex. Свежий `codex exec` без resume — **аварийный fallback**, расходует значительно больше токенов. Использовать только при ошибке resume. -1. Запусти (без перенаправлений): +1. Запусти resume с подавлением stderr (`2>/dev/null`): ```bash timeout 600 codex exec resume ${CODEX_SESSION_ID} \ @@ -258,20 +265,19 @@ timeout 600 codex exec resume ${CODEX_SESSION_ID} \ Here's what I changed: [Список правок] -Please re-review. End with VERDICT: APPROVED or VERDICT: REVISE" +Please re-review. End with VERDICT: APPROVED or VERDICT: REVISE" 2>/dev/null ``` Используй `timeout: 620000` в параметрах Bash tool. -2. Bash tool захватывает и stdout, и stderr. Проверь результат по exit code: - - **exit 0** — успех. Сохрани stdout через **Write tool** в `/tmp/codex-review-${REVIEW_ID}.md`. - **Проверка полноты:** убедись что **последняя непустая строка** stdout — это ровно `VERDICT: APPROVED` или `VERDICT: REVISE`. Если вердикт отсутствует или не на последней строке — вывод мог быть обрезан; перейди к Fallback (свежий `codex exec -o`, который пишет напрямую в файл без риска truncation). - - **exit 124** — таймаут. Сообщи пользователю: "Codex не ответил за 10 минут" и предложи повторить (аналогично шагу 4). - - **другой exit code** — покажи пользователю stderr/stdout для диагностики, затем перейди к Fallback. +**Почему `2>/dev/null`:** `codex exec` по дизайну разделяет потоки — progress/metadata → stderr, финальный ответ модели → stdout. Подавление stderr даёт чистый вывод без CLI-шума. Результат Bash tool = только ревью. -**Примечание:** `resume` не поддерживает `-o`, поэтому вывод идёт в stdout Bash tool. Затем читай файл как обычно (Шаг 5). +2. Проверь результат по exit code: + - **exit 0** — успех. stdout содержит чистое ревью. Показать пользователю напрямую (Write в файл и Read **не нужны**). Проверить VERDICT: последняя непустая строка stdout = `VERDICT: APPROVED` или `VERDICT: REVISE`. Если вердикт отсутствует → вывод мог быть обрезан, перейти к Fallback. Далее применить обработку вердикта из Шага 5 (APPROVED → Шаг 8, REVISE → Шаг 6). + - **exit 124** — таймаут. Сообщи пользователю: "Codex не ответил за 10 минут" и предложи повторить. + - **другой exit code** — сообщи пользователю: "Resume не удался (exit code N)". Перейди к Fallback. Диагностика без stderr недоступна — не пытайся парсить stdout как ошибку. -**Fallback** — если `resume` не сработал (сессия истекла, session ID не захвачен): +**Fallback** — если `resume` не сработал (сессия истекла, session ID не захвачен, ошибка): 1. Собрать список изменённых файлов (аналогично Шагу 3). 2. Запустить свежий `codex exec -o` с описанием предыдущих раундов в промпте. @@ -307,16 +313,25 @@ Please re-review. End with VERDICT: APPROVED or VERDICT: REVISE" ### Шаг 9: Очистка +**В Claude Code Plan Mode:** пропустить любой cleanup (включая deferred). rm вызовет permission prompt. Файлы подчистятся при следующем вызове вне Plan Mode. + +**Вне Plan Mode:** + ```bash rm -f /tmp/claude-plan-${REVIEW_ID}.md /tmp/codex-review-${REVIEW_ID}.md ``` -НЕ удалять файлы планов, которые существовали до ревью (только temp-файлы, созданные этим скиллом). +Если пользователь отклонил rm — продолжить без ошибки. + +НЕ удалять файлы планов, которые существовали до ревью (только temp-файлы, созданные этим скиллом). Старые temp-файлы от предыдущих сессий безвредны в /tmp и очистятся ОС при перезагрузке. ## Правила - Claude **активно правит** по замечаниям Codex — это НЕ просто передача сообщений - Автодетект режима ревью по контексту; аргументы пользователя имеют приоритет +- При явном аргументе `plan` или в Claude Code Plan Mode: пропускать git-проверки и определение base branch +- Resume — основной путь для повторных раундов. Свежий exec — аварийный fallback (дорогой по токенам) +- Cleanup — best-effort: в Plan Mode пропускать, при отказе продолжать без ошибки - Предпочитать существующие файлы, не создавать лишние копии - Всегда read-only sandbox — Codex никогда не пишет файлы - Максимум 5 раундов для защиты от бесконечных циклов diff --git a/claude/.claude/settings.local.json b/claude/.claude/settings.local.json index b25c965..cd8f45b 100644 --- a/claude/.claude/settings.local.json +++ b/claude/.claude/settings.local.json @@ -105,13 +105,11 @@ "Bash(gh repo:*)", "Bash(codex *)", "Bash(timeout 600 codex exec *)", - "Bash(rm -f /tmp/claude-diff-*)", "Bash(rm -f /tmp/claude-plan-*)", "Bash(rm -f /tmp/codex-review-*)", "WebSearch", "mcp__claude_ai_Context7__resolve-library-id", "Write(/tmp/claude-plan-*)", - "Write(/tmp/claude-diff-*)", "Write(/tmp/codex-review-*)" ] },