fix(skills): убраны permission prompts из codex-review
- Зачем:
- каждый раунд ревью требовал 3-5 ручных подтверждений из-за $(), > и 2>&1 в bash-командах.
- Что:
- шаг 2: Session ID генерируется Claude без bash, вместо $(date).
- шаг 3: git diff → stdout + Write tool вместо > redirect; добавлен preflight через --shortstat.
- шаг 7: resume stdout + Write tool вместо > 2>&1; дифференцированная обработка exit code.
- добавлено пояснение о плейсхолдерах ${REVIEW_ID}/${CODEX_SESSION_ID}.
- TODO.md: задача отмечена как выполненная.
- Проверка:
- /codex-review code на текущем diff — 0 permission prompts за 3 раунда.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
1 parent
a05830c4f4
commit
c7e981604e
2 files changed
+40
-31
No files matched your search
@@ -11,15 +11,7 @@
|
|||||||
|
|
||||||
Связанный PR: [anomalyco/opencode#16525](https://github.com/anomalyco/opencode/pull/16525)
|
Связанный PR: [anomalyco/opencode#16525](https://github.com/anomalyco/opencode/pull/16525)
|
||||||
|
|
||||||
## codex-review: убрать permission prompts
|
## ~~codex-review: убрать permission prompts~~ DONE
|
||||||
|
|
||||||
Скилл `codex-review` (`agents/.agents/skills/codex-review/SKILL.md`) вызывает
|
Реализовано: шаги 2, 3, 7 переписаны на встроенные инструменты (Write tool, stdout capture).
|
||||||
safety warnings Claude Code на `$()` и `>` в bash-командах. Allow-list не помогает —
|
См. коммит с `fix(skills): убраны permission prompts из codex-review`.
|
||||||
это отдельный слой проверок.
|
|
||||||
|
|
||||||
**Решение:** переписать шаги скилла, заменив bash-паттерны на встроенные инструменты:
|
|
||||||
|
|
||||||
- **Шаг 2 (Session ID):** Claude генерирует ID сам, без `$(date)` в bash.
|
|
||||||
- **Шаг 3 (Diff):** `git diff` → результат через Write tool вместо `>` redirect.
|
|
||||||
- **Шаг 7 (Resume):** stdout tool result вместо `> file 2>&1`.
|
|
||||||
- Шаги 4 и 9 — без изменений (`-o` и `rm -f` работают).
|
|
||||||
@@ -21,6 +21,8 @@ user_invocable: true
|
|||||||
|
|
||||||
## Инструкции
|
## Инструкции
|
||||||
|
|
||||||
|
> **Плейсхолдеры:** `${REVIEW_ID}` и `${CODEX_SESSION_ID}` в шагах ниже — это шаблонные плейсхолдеры, НЕ shell-переменные. Подставляй литеральные значения напрямую в каждый tool call.
|
||||||
|
|
||||||
### Шаг 1: Определить режим ревью
|
### Шаг 1: Определить режим ревью
|
||||||
|
|
||||||
Определи, что ревьюить, по контексту и аргументам:
|
Определи, что ревьюить, по контексту и аргументам:
|
||||||
@@ -41,39 +43,44 @@ user_invocable: true
|
|||||||
|
|
||||||
### Шаг 2: Сгенерировать Session ID
|
### Шаг 2: Сгенерировать Session ID
|
||||||
|
|
||||||
```bash
|
Сгенерируй уникальный `REVIEW_ID` самостоятельно, формат: `{unix_timestamp}-{случайное_4значное_число}`.
|
||||||
REVIEW_ID="$(date +%s)-${RANDOM}"
|
Пример: `1711872000-4821`. **НЕ используй bash** — подставляй значение напрямую в команды следующих шагов.
|
||||||
```
|
|
||||||
|
|
||||||
### Шаг 3: Подготовить материал для ревью
|
### Шаг 3: Подготовить материал для ревью
|
||||||
|
|
||||||
**Ревью плана:**
|
**Ревью плана:**
|
||||||
|
|
||||||
- Если план уже существует как файл (в `project/`, memory или где-то в репо) — использовать путь напрямую. НЕ копировать.
|
- Если план уже существует как файл (в `project/`, memory или где-то в репо) — использовать путь напрямую. НЕ копировать.
|
||||||
- Если план только в контексте разговора — записать в `/tmp/claude-plan-${REVIEW_ID}.md`.
|
- Если план только в контексте разговора — записать через **Write tool** в `/tmp/claude-plan-${REVIEW_ID}.md`.
|
||||||
- **Обязательно вывести путь к файлу плана пользователю**, чтобы он мог открыть его в IDE:
|
- **Обязательно вывести путь к файлу плана пользователю**, чтобы он мог открыть его в IDE:
|
||||||
`📄 План для ревью: <путь-к-файлу>`
|
`📄 План для ревью: <путь-к-файлу>`
|
||||||
|
|
||||||
**Ревью кода:**
|
**Ревью кода:**
|
||||||
|
|
||||||
Собрать diff в порядке приоритета (использовать первый непустой):
|
Собрать diff — выполняй по одной команде, используй первый непустой результат:
|
||||||
|
|
||||||
```bash
|
1. `git diff` — unstaged changes
|
||||||
# 1. Unstaged changes
|
2. Если stdout пуст — `git diff --cached` — staged changes
|
||||||
git diff > /tmp/claude-diff-${REVIEW_ID}.diff
|
3. Если пуст — `git diff main...HEAD` — все коммиты ветки
|
||||||
|
|
||||||
# 2. Если пусто — staged changes
|
Каждую команду запускай отдельным Bash tool call (без перенаправлений).
|
||||||
if [ ! -s /tmp/claude-diff-${REVIEW_ID}.diff ]; then
|
Результат (stdout первой непустой команды) сохрани через **Write tool** в `/tmp/claude-diff-${REVIEW_ID}.diff`.
|
||||||
git diff --cached > /tmp/claude-diff-${REVIEW_ID}.diff
|
|
||||||
fi
|
|
||||||
|
|
||||||
# 3. Если пусто — все коммиты ветки относительно main
|
Если все три пусты — нет изменений для ревью, сообщи пользователю.
|
||||||
if [ ! -s /tmp/claude-diff-${REVIEW_ID}.diff ]; then
|
|
||||||
git diff main...HEAD > /tmp/claude-diff-${REVIEW_ID}.diff
|
|
||||||
fi
|
|
||||||
```
|
|
||||||
|
|
||||||
Если diff всё равно пуст — нет изменений для ревью, сообщить пользователю.
|
**Большие diff-ы (best-effort preflight):** перед захватом полного diff проверь размер
|
||||||
|
через `--shortstat` в том же порядке приоритета, что и основной diff:
|
||||||
|
|
||||||
|
1. `git diff --shortstat` — если непусто, оценивай по нему
|
||||||
|
2. Если пусто — `git diff --cached --shortstat`
|
||||||
|
3. Если пусто — `git diff main...HEAD --shortstat`
|
||||||
|
|
||||||
|
Вывод вида `3 files changed, 4200 insertions(+), 100 deletions(-)`.
|
||||||
|
Если insertions + deletions > 1500 — **останови сбор diff**, сообщи пользователю
|
||||||
|
что полный diff может быть обрезан Bash tool, и потребуй использовать `/codex-review <путь>` для конкретных файлов.
|
||||||
|
**НЕ продолжай** с потенциально неполным diff — частичное ревью хуже, чем отсутствие ревью.
|
||||||
|
Это best-effort проверка: `--shortstat` считает строки, а не байты. Diff с малым числом
|
||||||
|
очень длинных строк (минифицированный JSON, lockfile) может пройти порог, но быть огромным по размеру.
|
||||||
|
|
||||||
**Ревью кода против плана:** подготовить и путь к плану, И diff.
|
**Ревью кода против плана:** подготовить и путь к плану, И diff.
|
||||||
|
|
||||||
@@ -205,6 +212,8 @@ If changes are needed, end with exactly: VERDICT: REVISE"
|
|||||||
|
|
||||||
**Предпочтительно: `resume`** — экономит токены, сохраняет контекст сессии:
|
**Предпочтительно: `resume`** — экономит токены, сохраняет контекст сессии:
|
||||||
|
|
||||||
|
1. Запусти (без перенаправлений):
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
timeout 600 codex exec resume ${CODEX_SESSION_ID} \
|
timeout 600 codex exec resume ${CODEX_SESSION_ID} \
|
||||||
"I've revised based on your feedback.
|
"I've revised based on your feedback.
|
||||||
@@ -212,10 +221,18 @@ timeout 600 codex exec resume ${CODEX_SESSION_ID} \
|
|||||||
Here's what I changed:
|
Here's what I changed:
|
||||||
[Список правок]
|
[Список правок]
|
||||||
|
|
||||||
Please re-review. End with VERDICT: APPROVED or VERDICT: REVISE" > /tmp/codex-review-${REVIEW_ID}.md 2>&1
|
Please re-review. End with VERDICT: APPROVED or VERDICT: REVISE"
|
||||||
```
|
```
|
||||||
|
|
||||||
**Примечание:** `resume` не поддерживает `-o`. Вывод перенаправляется в файл через `>`. Затем читай файл как обычно (Шаг 5).
|
Используй `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.
|
||||||
|
|
||||||
|
**Примечание:** `resume` не поддерживает `-o`, поэтому вывод идёт в stdout Bash tool. Затем читай файл как обычно (Шаг 5).
|
||||||
|
|
||||||
**Fallback** — если `resume` не сработал (сессия истекла, session ID не захвачен):
|
**Fallback** — если `resume` не сработал (сессия истекла, session ID не захвачен):
|
||||||
|
|
||||||
|
|||||||
Reference in new issue
Block a user