Skip to content

Делаю инструмент который будет подключаться к прехукам агентов и синкать план на гитхаб #2

@skulidropek

Description

@skulidropek
Я хочу сделать инстурмент который будет читать ~/.codex ~/.claude или работать на prehook в агентах и копировать планы в PR автоматически. Что бы не терять основной контекст работы. Зачастую принятые планы это то о чём идёт задача и работа

Идея понятная: нужен не “логгер всего”, а слой, который извлекает только принятый/актуальный план и привязывает его к PR как живой артефакт. Я проверю, какие официальные hook/CLI точки сейчас есть у Claude Code и Codex, и предложу архитектуру без утечки лишнего контекста.

Думал на протяжении 6s

Да. Я бы делал это как Plan Capture → Plan Normalize → PR Sync.

Claude Code уже имеет официальные hooks на события жизненного цикла, включая prompt/tool/session hooks; Codex CLI локальный и конфигурируемый, а для Codex важный стабильный источник контекста — AGENTS.md.

MVP-архитектура:

agent event / ~/.claude / ~/.codex
        ↓
plan-capture daemon / hook
        ↓
extract accepted plan only
        ↓
store .agent-plan.json in repo
        ↓
gh pr edit --body-file / comment update

Ключевая идея: не копировать весь контекст, а извлекать только блоки вида:

## Accepted Plan
- Goal
- Constraints
- Steps
- Open assumptions
- Current status

Для Claude лучше начинать с hooks, потому что это официальная точка автоматизации: можно ловить Stop, PreToolUse, PostToolUse или prompt events и писать компактный plan snapshot.
Для Codex я бы не полагался только на чтение ~/.codex: лучше сделать wrapper/sidecar плюс явный формат в AGENTS.md, потому что Codex официально читает AGENTS.md перед работой, а CLI и конфиги активно развиваются.

Минимальная спецификация файла:

{
  "task": "short human title",
  "accepted_plan": [
    "step 1",
    "step 2"
  ],
  "constraints": [],
  "assumptions": [],
  "last_updated_by": "claude|codex",
  "source": "hook|wrapper|manual",
  "commit": "HEAD sha"
}

PR sync policy:

If PR exists for current branch:
  update hidden section in PR body
else:
  create/update local .agent-plan.json only

В PR body лучше вставлять fenced-блок с маркерами:

<!-- agent-plan:start -->
## Agent Plan
...
<!-- agent-plan:end -->

Так инструмент сможет идемпотентно обновлять только свой участок, не затирая описание PR.

Главные инварианты безопасности:

Никогда не пушить raw transcript.
Никогда не читать секреты из ~/.claude, ~/.codex, .env, SSH, tokens.
Plan extractor должен быть whitelist-based: брать только явно размеченные планы.
Перед публикацией в PR прогонять redaction.
PR update должен быть reversible и diffable.

Я бы назвал это, например, agent-plan-pr: маленький CLI + hooks templates для Claude/Codex + GitHub adapter.

Разберу это по двум уровням: что обычно можно поймать хуками как событие, и отдельно — можно ли надёжно поймать именно команду /plan, а не просто результат планирования.

Думал на протяжении нескольких секунд

Да, частично можно.

Хуки обычно ловят:

SessionStart — старт сессии агента.
UserPromptSubmit — пользователь отправил сообщение.
PreToolUse — агент собирается вызвать tool.
PostToolUse — tool уже выполнен.
Stop / SessionStop — агент завершил ответ или сессию.
PreCompact / compact-события — перед сжатием контекста, если поддерживается.

Для твоей задачи самое важное:

UserPromptSubmit → поймать команду /plan или просьбу составить план
Stop             → забрать итоговый принятый план из ответа
PreToolUse       → понять, что агент перешёл от планирования к действиям
PostToolUse      → обновить статус шагов

/plan лучше ловить на UserPromptSubmit, потому что это вход пользователя:

user input == "/plan"
user input startsWith "/plan "
user input contains "составь план"

Но есть нюанс: хуки обычно не дают идеальный “PlanAccepted event”. То есть ты можешь поймать факт, что пользователь ввёл /plan, но “план принят” лучше определять отдельно:

1. UserPromptSubmit: saw /plan
2. Stop: сохранить последний ответ как candidate plan
3. Следующий UserPromptSubmit:
   - "да"
   - "ок"
   - "принимаю"
   - "go"
   - "делай"
   - "looks good"
   → пометить candidate plan как accepted

Идеальный алгоритм:

1. Ловим UserPromptSubmit
2. Если это /plan — ставим state = planning
3. Ловим Stop
4. Если state = planning — сохраняем ответ агента как plan_candidate
5. Ловим следующий UserPromptSubmit
6. Если пользователь подтвердил — plan_candidate → accepted_plan
7. Пишем accepted_plan в .agent-plan.json
8. Обновляем PR

То есть да, /plan ловить можно, но лучше считать /plan не финальным планом, а началом протокола планирования. Финальный артефакт — это accepted_plan, подтверждённый следующим сообщением пользователя.

Окей. Можешь написать краткий план для реализации задачи
Думал на протяжении 1m 9s
Проверить hook API у Codex и Claude
Какие события доступны: UserPromptSubmit, PreToolUse, PostToolUse, Stop, SessionStart.
Как передаётся текст промпта и ответа агента.
Где лучше хранить состояние между хуками.

Сделать общий формат плана

{
  "status": "candidate|accepted|in_progress|done",
  "source": "codex|claude",
  "branch": "feature/example",
  "task": "Краткое описание задачи",
  "plan": ["Шаг 1", "Шаг 2", "Шаг 3"],
  "updated_at": "..."
}
Поймать начало планирования
На UserPromptSubmit определять команды вроде:
/plan
составь план
давай план
После этого переводить задачу в состояние planning.
Сохранить candidate plan
На Stop брать последний ответ агента.
Если состояние было planning, сохранять ответ как candidate_plan.
Пока не отправлять его в PR.
Определить принятие плана
На следующем UserPromptSubmit проверять подтверждение:
да
ок
принимаю
делай
go
looks good
После подтверждения переводить candidate_plan в accepted_plan.
Нормализовать план
Вытащить только список действий.
Убрать лишний текст агента.
Очистить секреты, токены, пути к приватным файлам.
Привязать план к текущей Git-ветке.

Сохранить локально

Писать файл, например:
.agent-plan.json
Хранить последний принятый план и его статус.
Найти PR для текущей ветки
Через GitHub CLI или GitHub API.
Если PR найден — обновлять описание.
Если PR не найден — только сохранять план локально.

Обновить PR идемпотентно

Вставлять план между маркерами:
<!-- agent-plan:start -->
## Agent Plan

1. ...
2. ...
3. ...
<!-- agent-plan:end -->
Обновлять только этот блок, не трогая остальное описание PR.
Добавить CLI для ручного управления
agent-plan show
agent-plan accept
agent-plan sync
agent-plan clear
Сделать MVP
Один агент: сначала Codex или Claude.
Один источник: hook UserPromptSubmit + Stop.
Один выход: обновление PR body.
Без сложной истории и аналитики.
После MVP добавить расширения
Поддержка нескольких агентов.
История изменений плана.
Статусы шагов.
Комментарии в PR вместо body.
Автоматическое обновление прогресса по выполненным tool calls.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions