← [Раздел](README.md) · [Главная](../README.md)

# Примеры hooks (ECC и Projects)

## Цель

Разобрать **реальные** конфигурации и скрипты хуков из ECC и workspace `Projects`, понять паттерны реализации на Node.js и shell.

## Предварительно

- [tipy-hooks.md](tipy-hooks.md)
- Node.js установлен (для запуска `.js` хуков локально)
- Пути: `ECC/.cursor/hooks/` и `Projects/.cursor/hooks/`

## Время

~60–90 минут.

---

## Эталон: ECC/.cursor/hooks.json

В репозитории ECC (`/Users/nazeebod/Projects/ECC`) конфигурация включает цепочку обработчиков:

### sessionStart

```json
{
  "command": "node .cursor/hooks/session-start.js",
  "event": "sessionStart",
  "description": "Load previous context and detect environment"
}
```

**Назначение:** при открытии сессии скрипт может:

- прочитать маркер прошлой сессии;
- определить стек (package.json, go.mod, Cargo.toml);
- вывести в stdout подсказки для агента (stdin/stdout протокол зависит от версии).

### beforeShellExecution — защита git hooks

```json
{
  "command": "npx block-no-verify@1.1.2",
  "event": "beforeShellExecution",
  "description": "Block git hook-bypass flag"
}
```

**Урок:** не обязательно свой скрипт — можно вызывать **npm-пакет** как hook command.

### beforeShellExecution — кастомная логика

```json
{
  "command": "node .cursor/hooks/before-shell-execution.js",
  "description": "Tmux dev server blocker, tmux reminder, git push review"
}
```

Типичные проверки внутри JS:

- блокировка `git push` без явного флага подтверждения;
- напоминание, если dev-сервер уже в tmux;
- предупреждение о push в `main`.

### afterShellExecution

```json
{
  "command": "node .cursor/hooks/after-shell-execution.js",
  "description": "PR URL logging, build analysis"
}
```

После `gh pr create` — сохранить URL; после failed build — парс stderr для агента.

### afterFileEdit

```json
{
  "command": "node .cursor/hooks/after-file-edit.js",
  "description": "Auto-format, TypeScript check, console.log warning"
}
```

**Паттерн:** получить путь файла → запустить formatter/linter только для затронутого файла → вернуть код выхода.

### beforeMCPExecution / afterMCPExecution

Аудит вызовов MCP: какой сервер, какой tool, параметры (с редактированием секретов).

---

## Workspace Projects/.cursor/hooks.json

На уровне `/Users/nazeebod/Projects/.cursor/hooks.json` часто **дублируется** ECC-набор — это monorepo/workspace политика:

- одни и те же хуки для всех подпроектов;
- единый блок `block-no-verify`;
- общие session-start/end.

**Внимание:** не копируйте слепо в маленький репозиторий — [agent-sort](../11-ecc/ustanovka-i-agent-sort.md) поможет оставить нужное.

---

## Анатомия JS-хука (упрощённо)

```javascript
// .cursor/hooks/example-after-edit.js
const { readFileSync } = require('fs');

// Псевдокод: реальный протокол читайте в соседних хуках ECC
const input = JSON.parse(readFileSync(0, 'utf-8'));
const filePath = input.filePath;

if (filePath.endsWith('.ts')) {
  // spawn sync: npx prettier --write filePath
}

process.stdout.write(JSON.stringify({ ok: true }));
process.exit(0);
```

Практика: **копируйте стиль** из `ECC/.cursor/hooks/after-file-edit.js`, не изобретайте протокол с нуля.

---

## Shell-хуки (continuous-learning-v2)

В skill `continuous-learning-v2` есть bash-наблюдатель:

```text
ECC/.cursor/skills/continuous-learning-v2/hooks/observe.sh
```

Он подключается к цепочке tool use и пишет наблюдения для «инстинктов». Это пример **hook как части skill**, а не только корневого `hooks.json`.

---

## Таблица: файл → ответственность

| Скрипт (ECC) | Событие | Эффект для разработчика |
|--------------|---------|-------------------------|
| `session-start.js` | sessionStart | Меньше «с нуля» в новой сессии |
| `session-end.js` | sessionEnd | Итоги, обучение |
| `before-shell-execution.js` | beforeShellExecution | Меньше опасных команд |
| `after-shell-execution.js` | afterShellExecution | Связь shell ↔ задачи агента |
| `after-file-edit.js` | afterFileEdit | Единый стиль кода |
| `before-mcp-execution.js` | beforeMCPExecution | Контроль MCP |
| `stop-format-typecheck.js` | stop (если есть) | Финальная проверка |

Точные имена сверяйте с актуальным деревом `ECC/.cursor/hooks/`.

---

## Минимальный учебный hook

**Задача:** при старте сессии печатать «Учебный проект — не prod».

1. Создайте `.cursor/hooks/lab-session-start.js` (скопируйте заголовок из ECC session-start).
2. Добавьте в `hooks.json` один `sessionStart`.
3. Откройте новый Agent Chat — убедитесь, что сообщение появляется.

Удалите после лабораторной — не оставляйте отладочный шум в команде.

---

## Отладка

| Проблема | Действие |
|----------|----------|
| Хук не вызывается | Валидный JSON? Путь к скрипту от корня репо? |
| Exit code ≠ 0 | Запустите `node .cursor/hooks/....js` вручную с тестовым JSON |
| Всё тормозит | Профилируйте afterFileEdit — часто виноват tsc на всём проекте |
| Дубли | Проверьте workspace + project hooks.json |

---

## Самопроверка

1. Какой пакет блокирует `--no-verify` в ECC?
2. На какое событие вешается автоформат?
3. Где лежит observe.sh для continuous-learning?
4. Почему копируют стиль протокола из существующих хуков?

---

## Дальше

→ [Hookify и автоматизация](hookify-i-avtomatizaciya.md)  
← [Типы hooks](tipy-hooks.md)
