i18n(uk): Add complete Ukrainian localization

Merges full Ukrainian (uk) localization — 10 modules, root docs, claude_concepts_guide, plugins, and supporting files. Closes #63.
This commit is contained in:
Luong NGUYEN
2026-04-11 22:50:27 +02:00
committed by GitHub
137 changed files with 30192 additions and 0 deletions
+585
View File
@@ -0,0 +1,585 @@
<!-- i18n-source: 01-slash-commands/README.md -->
<!-- i18n-source-sha: 63a1416 -->
<!-- i18n-date: 2026-04-09 -->
<picture>
<source media="(prefers-color-scheme: dark)" srcset="../../resources/logos/claude-howto-logo-dark.svg">
<img alt="Claude How To" src="../../resources/logos/claude-howto-logo.svg">
</picture>
# Слеш-команди
## Огляд
Слеш-команди — це ярлики, що керують поведінкою Claude під час інтерактивної сесії. Вони бувають кількох типів:
- **Вбудовані команди**: Надаються Claude Code (`/help`, `/clear`, `/model`)
- **Навички (Skills)**: Користувацькі команди, створені як файли `SKILL.md` (`/optimize`, `/pr`)
- **Команди плагінів**: Команди з встановлених плагінів (`/frontend-design:frontend-design`)
- **MCP-промпти**: Команди з MCP-серверів (`/mcp__github__list_prs`)
> **Примітка**: Кастомні слеш-команди об'єднані з навичками. Файли в `.claude/commands/` все ще працюють, але навички (`.claude/skills/`) — рекомендований підхід. Обидва створюють ярлики `/command-name`. Див. [Посібник з навичок](../03-skills/) для повного довідника.
## Довідник вбудованих команд
Вбудовані команди — це ярлики для типових дій. Доступно **60+ вбудованих команд** та **5 вбудованих навичок**. Введіть `/` у Claude Code для повного списку, або `/` з літерами для фільтрації.
| Команда | Призначення |
|---------|------------|
| `/add-dir <path>` | Додати робочий каталог |
| `/agents` | Управління конфігураціями агентів |
| `/branch [name]` | Розгалужити розмову в нову сесію (аліас: `/fork`). Примітка: `/fork` перейменовано на `/branch` у v2.1.77 |
| `/btw <question>` | Побічне запитання без додавання в історію |
| `/chrome` | Налаштування інтеграції з Chrome |
| `/clear` | Очистити розмову (аліаси: `/reset`, `/new`) |
| `/color [color\|default]` | Встановити колір рядка промпту |
| `/compact [instructions]` | Компактизувати розмову з необов'язковими інструкціями фокусу |
| `/config` | Відкрити налаштування (аліас: `/settings`) |
| `/context` | Візуалізація використання контексту кольоровою сіткою |
| `/copy [N]` | Скопіювати відповідь у буфер; `w` записує у файл |
| `/cost` | Показати статистику використання токенів |
| `/desktop` | Продовжити в десктопному застосунку (аліас: `/app`) |
| `/diff` | Інтерактивний перегляд незакомічених змін |
| `/doctor` | Діагностика стану встановлення |
| `/effort [low\|medium\|high\|max\|auto]` | Встановити рівень зусиль. `max` потребує Opus 4.6 |
| `/exit` | Вийти з REPL (аліас: `/quit`) |
| `/export [filename]` | Експортувати розмову у файл або буфер |
| `/extra-usage` | Налаштування додаткового використання для лімітів |
| `/fast [on\|off]` | Перемкнути швидкий режим |
| `/feedback` | Надіслати відгук (аліас: `/bug`) |
| `/help` | Показати довідку |
| `/hooks` | Переглянути конфігурації хуків |
| `/ide` | Управління IDE-інтеграціями |
| `/init` | Ініціалізувати `CLAUDE.md`. `CLAUDE_CODE_NEW_INIT=1` для інтерактивного потоку |
| `/insights` | Згенерувати звіт аналізу сесії |
| `/install-github-app` | Налаштувати GitHub Actions |
| `/install-slack-app` | Встановити Slack-застосунок |
| `/keybindings` | Відкрити налаштування клавіш |
| `/login` | Змінити обліковий запис Anthropic |
| `/logout` | Вийти з облікового запису Anthropic |
| `/mcp` | Управління MCP-серверами та OAuth |
| `/memory` | Редагувати `CLAUDE.md`, перемкнути автопам'ять |
| `/mobile` | QR-код для мобільного (аліаси: `/ios`, `/android`) |
| `/model [model]` | Вибір моделі зі стрілками вліво/вправо для рівня зусиль |
| `/passes` | Поділитися безкоштовним тижнем Claude Code |
| `/permissions` | Переглянути/оновити дозволи (аліас: `/allowed-tools`) |
| `/plan [description]` | Увійти в режим планування |
| `/plugin` | Управління плагінами |
| `/powerup` | Інтерактивні уроки з анімованими демо |
| `/privacy-settings` | Налаштування приватності (Pro/Max) |
| `/release-notes` | Переглянути журнал змін |
| `/reload-plugins` | Перезавантажити активні плагіни |
| `/remote-control` | Віддалене керування з claude.ai (аліас: `/rc`) |
| `/remote-env` | Налаштування стандартного віддаленого середовища |
| `/rename [name]` | Перейменувати сесію |
| `/resume [session]` | Відновити розмову (аліас: `/continue`) |
| `/review` | **Застаріла** — встановіть плагін `code-review` |
| `/rewind` | Відкат розмови та/або коду (аліас: `/checkpoint`) |
| `/sandbox` | Перемкнути режим пісочниці |
| `/schedule [description]` | Створити/управляти хмарними запланованими завданнями |
| `/security-review` | Аналіз гілки на вразливості безпеки |
| `/skills` | Список доступних навичок |
| `/stats` | Візуалізація щоденного використання, сесій, серій |
| `/stickers` | Замовити стікери Claude Code |
| `/status` | Показати версію, модель, обліковий запис |
| `/statusline` | Налаштування рядка стану |
| `/tasks` | Список/управління фоновими завданнями |
| `/terminal-setup` | Налаштування клавіш терміналу |
| `/theme` | Змінити колірну тему |
| `/ultraplan <prompt>` | Створити план в ultraplan-сесії, переглянути в браузері |
| `/upgrade` | Відкрити сторінку оновлення тарифу |
| `/usage` | Показати ліміти плану та статус обмежень |
| `/voice` | Перемкнути голосовий ввід push-to-talk |
### Вбудовані навички
Ці навички поставляються з Claude Code і викликаються як слеш-команди:
| Навичка | Призначення |
|---------|------------|
| `/batch <instruction>` | Оркестрація масштабних паралельних змін через worktrees |
| `/claude-api` | Завантажити довідник Claude API для мови проекту |
| `/debug [description]` | Увімкнути налагоджувальне логування |
| `/loop [interval] <prompt>` | Запускати промпт повторно за інтервалом |
| `/simplify [focus]` | Перевірити змінені файли на якість коду |
### Застарілі команди
| Команда | Статус |
|---------|--------|
| `/review` | Застаріла — замінена плагіном `code-review` |
| `/output-style` | Застаріла з v2.1.73 |
| `/fork` | Перейменована на `/branch` (аліас працює, v2.1.77) |
| `/pr-comments` | Видалена в v2.1.91 — запитайте Claude напряму |
| `/vim` | Видалена в v2.1.92 — використовуйте /config → Editor mode |
### Останні зміни
- `/fork` перейменовано на `/branch`, `/fork` залишено як аліас (v2.1.77)
- `/output-style` застаріла (v2.1.73)
- `/review` застаріла на користь плагіна `code-review`
- Додано команду `/effort` з рівнем `max` для Opus 4.6
- Додано команду `/voice` для голосового вводу push-to-talk
- Додано команду `/schedule` для запланованих завдань
- Додано команду `/color` для кастомізації рядка промпту
- `/pr-comments` видалена в v2.1.91
- `/vim` видалена в v2.1.92
- Додано `/ultraplan` для перегляду плану в браузері
- Додано `/powerup` для інтерактивних уроків
- Додано `/sandbox` для режиму пісочниці
- Вибір `/model` тепер показує зрозумілі назви (наприклад, "Sonnet 4.6") замість ID моделей
- `/resume` підтримує аліас `/continue`
- MCP-промпти доступні як команди `/mcp__<server>__<prompt>` (див. [MCP-промпти як команди](#mcp-промпти-як-команди))
## Кастомні команди (тепер навички)
Кастомні слеш-команди **об'єднані з навичками**. Обидва підходи створюють команди, які викликаються через `/command-name`:
| Підхід | Розташування | Статус |
|--------|-------------|--------|
| **Навички (Рекомендовано)** | `.claude/skills/<n>/SKILL.md` | Поточний стандарт |
| **Legacy-команди** | `.claude/commands/<n>.md` | Все ще працює |
Якщо навичка і команда мають однакове ім'я, **навичка має пріоритет**. Наприклад, коли існують і `.claude/commands/review.md`, і `.claude/skills/review/SKILL.md`, використовується версія навички.
### Шлях міграції
Існуючі файли `.claude/commands/` продовжують працювати без змін. Для міграції на навички:
**До (Команда):**
```
.claude/commands/optimize.md
```
**Після (Навичка):**
```
.claude/skills/optimize/SKILL.md
```
### Чому навички?
Навички пропонують додаткові можливості порівняно з legacy-командами:
- **Структура каталогів**: Пакування скриптів, шаблонів та довідкових файлів
- **Автовиклик**: Claude може запускати навички автоматично за потреби
- **Контроль виклику**: Вибір — користувач, Claude, або обидва можуть викликати
- **Виконання в субагенті**: Запуск навичок в ізольованих контекстах з `context: fork`
- **Прогресивне розкриття**: Завантаження додаткових файлів лише за потреби
### Створення кастомної команди як навички
Створіть каталог з файлом `SKILL.md`:
```bash
mkdir -p .claude/skills/my-command
```
**Файл:** `.claude/skills/my-command/SKILL.md`
```yaml
---
name: my-command
description: Що робить ця команда і коли її використовувати
---
# My Command
Інструкції для Claude при виклику цієї команди.
1. Перший крок
2. Другий крок
3. Третій крок
```
### Довідник фронтматеру
| Поле | Призначення | За замовчуванням |
|------|------------|-----------------|
| `name` | Ім'я команди (стає `/name`) | Ім'я каталогу |
| `description` | Короткий опис (допомагає Claude знати коли використовувати) | Перший абзац |
| `argument-hint` | Очікувані аргументи для автодоповнення | Немає |
| `allowed-tools` | Інструменти без запиту дозволу | Успадковується |
| `model` | Конкретна модель для використання | Успадковується |
| `disable-model-invocation` | Якщо `true`, тільки користувач може викликати | `false` |
| `user-invocable` | Якщо `false`, сховати з меню `/` | `true` |
| `context` | `fork` для запуску в ізольованому субагенті | Немає |
| `agent` | Тип агента при `context: fork` | `general-purpose` |
| `hooks` | Хуки на рівні навички (PreToolUse, PostToolUse, Stop) | Немає |
### Аргументи
Команди можуть отримувати аргументи:
**Усі аргументи з `$ARGUMENTS`:**
```yaml
---
name: fix-issue
description: Fix a GitHub issue by number
---
Fix issue #$ARGUMENTS following our coding standards
```
Використання: `/fix-issue 123``$ARGUMENTS` стає "123"
**Окремі аргументи з `$0`, `$1` тощо:**
```yaml
---
name: review-pr
description: Review a PR with priority
---
Review PR #$0 with priority $1
```
Використання: `/review-pr 456 high``$0`="456", `$1`="high"
### Динамічний контекст з shell-командами
Виконуйте bash-команди перед промптом з допомогою `` !`command` ``:
```yaml
---
name: commit
description: Create a git commit with context
allowed-tools: Bash(git *)
---
## Context
- Current git status: !`git status`
- Current git diff: !`git diff HEAD`
- Current branch: !`git branch --show-current`
- Recent commits: !`git log --oneline -5`
## Your task
Based on the above changes, create a single git commit.
```
### Посилання на файли
Включайте вміст файлів з `@`:
```markdown
Review the implementation in @src/utils/helpers.js
Compare @src/old-version.js with @src/new-version.js
```
## Команди плагінів
Плагіни можуть надавати кастомні команди:
```
/plugin-name:command-name
```
Або просто `/command-name`, якщо немає конфліктів імен.
**Приклади:**
```bash
/frontend-design:frontend-design
/commit-commands:commit
```
## MCP-промпти як команди
MCP-сервери можуть надавати промпти як слеш-команди:
```
/mcp__<server-name>__<prompt-name> [arguments]
```
**Приклади:**
```bash
/mcp__github__list_prs
/mcp__github__pr_review 456
/mcp__jira__create_issue "Bug title" high
```
### Синтаксис дозволів MCP
Контроль доступу до MCP-серверів у дозволах:
- `mcp__github` — Доступ до всього GitHub MCP-сервера
- `mcp__github__*` — Wildcard-доступ до всіх інструментів
- `mcp__github__get_issue` — Доступ до конкретного інструменту
## Архітектура команд
```mermaid
graph TD
A["User Input: /command-name"] --> B{"Command Type?"}
B -->|Built-in| C["Execute Built-in"]
B -->|Skill| D["Load SKILL.md"]
B -->|Plugin| E["Load Plugin Command"]
B -->|MCP| F["Execute MCP Prompt"]
D --> G["Parse Frontmatter"]
G --> H["Substitute Variables"]
H --> I["Execute Shell Commands"]
I --> J["Send to Claude"]
J --> K["Return Results"]
```
## Життєвий цикл команди
```mermaid
sequenceDiagram
participant User
participant Claude as Claude Code
participant FS as File System
participant CLI as Shell/Bash
User->>Claude: Types /optimize
Claude->>FS: Searches .claude/skills/ and .claude/commands/
FS-->>Claude: Returns optimize/SKILL.md
Claude->>Claude: Parses frontmatter
Claude->>CLI: Executes !`command` substitutions
CLI-->>Claude: Command outputs
Claude->>Claude: Substitutes $ARGUMENTS
Claude->>User: Processes prompt
Claude->>User: Returns results
```
## Доступні команди в цьому каталозі
Ці приклади команд можна встановити як навички або legacy-команди.
### 1. `/optimize` — Оптимізація коду
Аналізує код на проблеми продуктивності, витоки пам'яті та можливості оптимізації.
**Використання:**
```
/optimize
[Вставте ваш код]
```
### 2. `/pr` — Підготовка Pull Request
Проводить через чекліст підготовки PR, включаючи лінтинг, тестування та форматування комітів.
**Використання:**
```
/pr
```
**Скріншот:**
![/pr](../../01-slash-commands/pr-slash-command.png)
### 3. `/generate-api-docs` — Генератор API-документації
Генерує комплексну API-документацію з вихідного коду.
**Використання:**
```
/generate-api-docs
```
### 4. `/commit` — Git-коміт з контекстом
Створює git-коміт з динамічним контекстом вашого репозиторію.
**Використання:**
```
/commit [необов'язкове повідомлення]
```
### 5. `/push-all` — Stage, Commit та Push
Stage всіх змін, створення коміту та push на remote з перевірками безпеки.
**Використання:**
```
/push-all
```
**Перевірки безпеки:**
- Секрети: `.env*`, `*.key`, `*.pem`, `credentials.json`
- API-ключі: Виявлення реальних ключів vs. заповнювачів
- Великі файли: `>10MB` без Git LFS
- Артефакти збірки: `node_modules/`, `dist/`, `__pycache__/`
### 6. `/doc-refactor` — Реструктуризація документації
Реструктуризує документацію проекту для ясності та доступності.
**Використання:**
```
/doc-refactor
```
### 7. `/setup-ci-cd` — Налаштування CI/CD-пайплайну
Впроваджує pre-commit хуки та GitHub Actions для контролю якості.
**Використання:**
```
/setup-ci-cd
```
### 8. `/unit-test-expand` — Розширення покриття тестами
Збільшує покриття тестами, націлюючись на непротестовані гілки та крайові випадки.
**Використання:**
```
/unit-test-expand
```
## Встановлення
### Як навички (Рекомендовано)
Скопіюйте у каталог навичок:
```bash
# Створити каталог навичок
mkdir -p .claude/skills
# Для кожного файлу команди створити каталог навички
for cmd in optimize pr commit; do
mkdir -p .claude/skills/$cmd
cp 01-slash-commands/$cmd.md .claude/skills/$cmd/SKILL.md
done
```
### Як legacy-команди
Скопіюйте у каталог команд:
```bash
# На рівні проекту (команда)
mkdir -p .claude/commands
cp 01-slash-commands/*.md .claude/commands/
# Персональне використання
mkdir -p ~/.claude/commands
cp 01-slash-commands/*.md ~/.claude/commands/
```
## Створення власних команд
### Шаблон навички (Рекомендовано)
Створіть `.claude/skills/my-command/SKILL.md`:
```yaml
---
name: my-command
description: What this command does. Use when [trigger conditions].
argument-hint: [optional-args]
allowed-tools: Bash(npm *), Read, Grep
---
# Command Title
## Context
- Current branch: !`git branch --show-current`
- Related files: @package.json
## Instructions
1. First step
2. Second step with argument: $ARGUMENTS
3. Third step
## Output Format
- How to format the response
- What to include
```
### Команда лише для користувача (без автовиклику)
Для команд з побічними ефектами, які Claude не повинен запускати автоматично:
```yaml
---
name: deploy
description: Deploy to production
disable-model-invocation: true
allowed-tools: Bash(npm *), Bash(git *)
---
Deploy the application to production:
1. Run tests
2. Build application
3. Push to deployment target
4. Verify deployment
```
## Найкращі практики
| Робіть | Не робіть |
|--------|-----------|
| Використовуйте чіткі, орієнтовані на дію назви | Не створюйте команди для одноразових завдань |
| Додавайте `description` з умовами тригеру | Не вбудовуйте складну логіку в команди |
| Тримайте команди зосередженими на одному завданні | Не хардкодьте чутливу інформацію |
| Використовуйте `disable-model-invocation` для побічних ефектів | Не пропускайте поле description |
| Використовуйте `!` для динамічного контексту | Не вважайте, що Claude знає поточний стан |
| Організуйте пов'язані файли в каталогах навичок | Не кладіть все в один файл |
## Усунення неполадок
### Команда не знайдена
**Рішення:**
- Перевірте, що файл у `.claude/skills/<n>/SKILL.md` або `.claude/commands/<n>.md`
- Перевірте поле `name` у фронтматері
- Перезапустіть сесію Claude Code
- Запустіть `/help` для перегляду доступних команд
### Команда працює не як очікувалось
**Рішення:**
- Додайте більш конкретні інструкції
- Включіть приклади у файл навички
- Перевірте `allowed-tools` при використанні bash-команд
- Спочатку тестуйте з простими вхідними даними
### Конфлікт навички та команди
Якщо обидві існують з однаковим ім'ям, **навичка має пріоритет**. Видаліть одну або перейменуйте.
## Пов'язані посібники
- **[Навички](../03-skills/)** — Повний довідник навичок (автоматично викликані можливості)
- **[Пам'ять](../02-memory/)** — Постійний контекст з CLAUDE.md
- **[Субагенти](../04-subagents/)** — Делеговані AI-агенти
- **[Плагіни](../07-plugins/)** — Пакетні набори команд
- **[Хуки](../06-hooks/)** — Автоматизація на основі подій
## Додаткові ресурси
- [Офіційна документація інтерактивного режиму](https://code.claude.com/docs/en/interactive-mode) — Довідник вбудованих команд
- [Офіційна документація навичок](https://code.claude.com/docs/en/skills) — Повний довідник навичок
- [Довідник CLI](https://code.claude.com/docs/en/cli-reference) — Опції командного рядка
---
**Останнє оновлення**: 9 квітня 2026
**Версія Claude Code**: 2.1.97
**Сумісні моделі**: Claude Sonnet 4.6, Claude Opus 4.6, Claude Haiku 4.5
*Частина серії посібників [Claude How To](../)*
+29
View File
@@ -0,0 +1,29 @@
---
allowed-tools: Bash(git add:*), Bash(git status:*), Bash(git commit:*), Bash(git diff:*)
argument-hint: [message]
description: Створити git-коміт з контекстом
---
## Контекст
- Поточний статус git: !`git status`
- Поточний git diff: !`git diff HEAD`
- Поточна гілка: !`git branch --show-current`
- Останні коміти: !`git log --oneline -10`
## Ваше завдання
На основі наведених вище змін створіть один git-коміт.
Якщо повідомлення було передано через аргументи, використовуйте його: $ARGUMENTS
Інакше проаналізуйте зміни та створіть відповідне повідомлення коміту відповідно до формату conventional commits:
- `feat:` для нових функцій
- `fix:` для виправлення помилок
- `docs:` для змін документації
- `refactor:` для рефакторингу коду
- `test:` для додавання тестів
- `chore:` для задач обслуговування
---
**Останнє оновлення**: 9 квітня 2026
+27
View File
@@ -0,0 +1,27 @@
---
name: Documentation Refactor
description: Реструктуризація документації проєкту для ясності та доступності
tags: documentation, refactoring, organization
---
# Рефакторинг документації
Рефакторинг структури документації проєкту з адаптацією до типу проєкту:
1. **Аналіз проєкту**: Визначити тип (бібліотека/API/веб-додаток/CLI/мікросервіси), архітектуру та персони користувачів
2. **Централізація документації**: Перемістити технічну документацію до `docs/` з належними перехресними посиланнями
3. **Кореневий README.md**: Оптимізувати як точку входу з оглядом, швидким стартом, резюме модулів/компонентів, ліцензією, контактами
4. **Документація компонентів**: Додати README файли на рівні модулів/пакетів/сервісів з інструкціями налаштування та тестування
5. **Організація `docs/`** за відповідними категоріями:
- Архітектура, Довідник API, База даних, Дизайн, Усунення несправностей, Деплой, Контрибʼюція (адаптувати до потреб проєкту)
6. **Створення посібників** (оберіть застосовні):
- Посібник користувача: Документація для кінцевих користувачів додатків
- Документація API: Ендпоінти, автентифікація, приклади для API
- Посібник розробника: Налаштування, тестування, процес контрибʼюції
- Посібник деплою: Деплой на продакшн для сервісів/додатків
7. **Використання Mermaid** для всіх діаграм (архітектура, потоки, схеми)
Тримайте документацію лаконічною, зручною для сканування та контекстно відповідною типу проєкту.
---
**Останнє оновлення**: 9 квітня 2026
+22
View File
@@ -0,0 +1,22 @@
---
description: Створення вичерпної документації API з вихідного коду
---
# Генератор документації API
Генерація документації API шляхом:
1. Сканування всіх файлів у `/src/api/`
2. Витягу сигнатур функцій та коментарів JSDoc
3. Організації за ендпоінтом/модулем
4. Створення markdown з прикладами
5. Включення схем запитів/відповідей
6. Додавання документації помилок
Формат виводу:
- Markdown-файл у `/docs/api.md`
- Включити приклади curl для всіх ендпоінтів
- Додати типи TypeScript
---
**Останнє оновлення**: 9 квітня 2026
+22
View File
@@ -0,0 +1,22 @@
---
description: Аналіз коду на проблеми продуктивності та пропозиції оптимізацій
---
# Оптимізація коду
Перегляньте наданий код на наявність таких проблем у порядку пріоритету:
1. **Вузькі місця продуктивності** — виявлення операцій O(n²), неефективних циклів
2. **Витоки памʼяті** — пошук невивільнених ресурсів, циклічних посилань
3. **Покращення алгоритмів** — пропозиція кращих алгоритмів або структур даних
4. **Можливості кешування** — виявлення повторюваних обчислень
5. **Проблеми конкурентності** — пошук станів гонки (race conditions) або проблем з потоками
Формат відповіді:
- Серйозність проблеми (Критична/Висока/Середня/Низька)
- Місце в коді
- Пояснення
- Рекомендоване виправлення з прикладом коду
---
**Останнє оновлення**: 9 квітня 2026
Binary file not shown.

After

Width:  |  Height:  |  Size: 33 KiB

+29
View File
@@ -0,0 +1,29 @@
---
description: Очистити код, підготувати зміни та створити pull request
allowed-tools: Bash(git add:*), Bash(git status:*), Bash(git diff:*), Bash(npm test:*), Bash(npm run lint:*)
---
# Контрольний список підготовки Pull Request
Перед створенням PR виконайте ці кроки:
1. Запустити лінтинг: `prettier --write .`
2. Запустити тести: `npm test`
3. Переглянути git diff: `git diff HEAD`
4. Додати зміни до індексу: `git add .`
5. Створити повідомлення коміту відповідно до conventional commits:
- `fix:` для виправлення помилок
- `feat:` для нових функцій
- `docs:` для документації
- `refactor:` для реструктуризації коду
- `test:` для додавання тестів
- `chore:` для обслуговування
6. Згенерувати опис PR, що включає:
- Що змінилося
- Чому змінилося
- Проведене тестування
- Потенційні наслідки
---
**Останнє оновлення**: 9 квітня 2026
+155
View File
@@ -0,0 +1,155 @@
---
description: Додати всі зміни до індексу, створити коміт та відправити на віддалений сервер (використовуйте з обережністю)
allowed-tools: Bash(git add:*), Bash(git status:*), Bash(git commit:*), Bash(git push:*), Bash(git diff:*), Bash(git log:*), Bash(git pull:*)
---
# Коміт та Push усього
⚠️ **УВАГА**: Додає ВСІ зміни до індексу, створює коміт та відправляє на віддалений сервер. Використовуйте лише коли впевнені, що всі зміни належать разом.
## Робочий процес
### 1. Аналіз змін
Запустити паралельно:
- `git status` — показати змінені/додані/видалені/невідстежувані файли
- `git diff --stat` — показати статистику змін
- `git log -1 --oneline` — показати останній коміт для стилю повідомлення
### 2. Перевірки безпеки
**❌ ЗУПИНИТИ та ПОПЕРЕДИТИ при виявленні:**
- Секрети: `.env*`, `*.key`, `*.pem`, `credentials.json`, `secrets.yaml`, `id_rsa`, `*.p12`, `*.pfx`, `*.cer`
- API-ключі: Будь-які змінні `*_API_KEY`, `*_SECRET`, `*_TOKEN` з реальними значеннями (не заповнювачі типу `your-api-key`, `xxx`, `placeholder`)
- Великі файли: `>10MB` без Git LFS
- Артефакти збірки: `node_modules/`, `dist/`, `build/`, `__pycache__/`, `*.pyc`, `.venv/`
- Тимчасові файли: `.DS_Store`, `thumbs.db`, `*.swp`, `*.tmp`
**Валідація API-ключів:**
Перевірити змінені файли на патерни:
```bash
OPENAI_API_KEY=sk-proj-xxxxx # ❌ Виявлено реальний ключ!
AWS_SECRET_KEY=AKIA... # ❌ Виявлено реальний ключ!
STRIPE_API_KEY=sk_live_... # ❌ Виявлено реальний ключ!
# ✅ Допустимі заповнювачі:
API_KEY=your-api-key-here
SECRET_KEY=placeholder
TOKEN=xxx
API_KEY=<your-key>
SECRET=${YOUR_SECRET}
```
**✅ Перевірити:**
- `.gitignore` правильно налаштований
- Немає конфліктів злиття
- Правильна гілка (попередити якщо main/master)
- API-ключі є лише заповнювачами
### 3. Запит підтвердження
Представити резюме:
```
📊 Резюме змін:
- X файлів змінено, Y додано, Z видалено
- Загалом: +AAA вставок, -BBB видалень
🔒 Безпека: ✅ Без секретів | ✅ Без великих файлів | ⚠️ [попередження]
🌿 Гілка: [назва] → origin/[назва]
Я виконаю: git add . → commit → push
Введіть 'yes' для продовження або 'no' для скасування.
```
**ЧЕКАТИ явного "yes" перед продовженням.**
### 4. Виконання (після підтвердження)
Запустити послідовно:
```bash
git add .
git status # Перевірка індексу
```
### 5. Генерація повідомлення коміту
Проаналізувати зміни та створити conventional commit:
**Формат:**
```
[тип]: Короткий опис (макс. 72 символи)
- Ключова зміна 1
- Ключова зміна 2
- Ключова зміна 3
```
**Типи:** `feat`, `fix`, `docs`, `style`, `refactor`, `test`, `chore`, `perf`, `build`, `ci`
**Приклад:**
```
docs: Update concept README files with comprehensive documentation
- Add architecture diagrams and tables
- Include practical examples
- Expand best practices sections
```
### 6. Коміт та Push
```bash
git commit -m "$(cat <<'EOF'
[Згенероване повідомлення коміту]
EOF
)"
git push # Якщо невдача: git pull --rebase && git push
git log -1 --oneline --decorate # Перевірка
```
### 7. Підтвердження успіху
```
✅ Успішно відправлено на віддалений сервер!
Коміт: [хеш] [повідомлення]
Гілка: [гілка] → origin/[гілка]
Змінено файлів: X (+вставок, -видалень)
```
## Обробка помилок
- **git add невдача**: Перевірити дозволи, заблоковані файли, переконатися що репо ініціалізовано
- **git commit невдача**: Виправити pre-commit хуки, перевірити git config (user.name/email)
- **git push невдача**:
- Non-fast-forward: `git pull --rebase && git push`
- Немає віддаленої гілки: `git push -u origin [гілка]`
- Захищена гілка: Використати PR-процес замість цього
## Коли використовувати
**Доцільно:**
- Оновлення документації в кількох файлах
- Функція з тестами та документацією
- Виправлення помилок у кількох файлах
- Форматування/рефакторинг всього проєкту
- Зміни конфігурації
**Уникати:**
- Невпевненість у тому, що комітиться
- Містить секрети/чутливі дані
- Захищені гілки без рев'ю
- Присутні конфлікти злиття
- Потрібна гранулярна історія комітів
- Pre-commit хуки не проходять
## Альтернативи
Якщо користувач хоче більше контролю, запропонувати:
1. **Вибіркове додавання**: Переглянути/додати конкретні файли
2. **Інтерактивне додавання**: `git add -p` для вибору патчів
3. **PR-процес**: Створити гілку → push → PR (використати команду `/pr`)
**⚠️ Памʼятайте**: Завжди переглядайте зміни перед push. Якщо сумніваєтесь, використовуйте окремі git-команди для більшого контролю.
---
**Останнє оновлення**: 9 квітня 2026
+28
View File
@@ -0,0 +1,28 @@
---
name: Setup CI/CD Pipeline
description: Реалізація pre-commit хуків та GitHub Actions для забезпечення якості
tags: ci-cd, devops, automation
---
# Налаштування CI/CD пайплайну
Реалізація комплексних шлюзів якості DevOps з адаптацією до типу проєкту:
1. **Аналіз проєкту**: Визначити мову(и), фреймворк, систему збірки та наявний інструментарій
2. **Налаштування pre-commit хуків** з інструментами для конкретної мови:
- Форматування: Prettier/Black/gofmt/rustfmt/тощо
- Лінтинг: ESLint/Ruff/golangci-lint/Clippy/тощо
- Безпека: Bandit/gosec/cargo-audit/npm audit/тощо
- Перевірка типів: TypeScript/mypy/flow (якщо застосовно)
- Тести: Запуск відповідних тестових наборів
3. **Створення GitHub Actions workflows** (.github/workflows/):
- Дзеркалювання pre-commit перевірок на push/PR
- Матриця версій/платформ (якщо застосовно)
- Верифікація збірки та тестів
- Кроки деплою (за потреби)
4. **Верифікація пайплайну**: Тестування локально, створення тестового PR, підтвердження проходження всіх перевірок
Використовуйте безкоштовні/відкриті інструменти. Поважайте існуючі конфігурації. Тримайте виконання швидким.
---
**Останнє оновлення**: 9 квітня 2026
+28
View File
@@ -0,0 +1,28 @@
---
name: Expand Unit Tests
description: Збільшення покриття тестами шляхом тестування невідстежених гілок та граничних випадків
tags: testing, coverage, unit-tests
---
# Розширення юніт-тестів
Розширення існуючих юніт-тестів з адаптацією до тестового фреймворку проєкту:
1. **Аналіз покриття**: Запустити звіт покриття для виявлення неперевірених гілок, граничних випадків та зон з низьким покриттям
2. **Виявлення прогалин**: Переглянути код на предмет логічних гілок, шляхів помилок, граничних умов, null/порожніх вхідних даних
3. **Написання тестів** з використанням фреймворку проєкту:
- Jest/Vitest/Mocha (JavaScript/TypeScript)
- pytest/unittest (Python)
- Go testing/testify (Go)
- Rust test framework (Rust)
4. **Цільові сценарії**:
- Обробка помилок та виключень
- Граничні значення (мін/макс, порожні, null)
- Крайні та кутові випадки (edge/corner cases)
- Переходи станів та побічні ефекти
5. **Верифікація покращення**: Запустити покриття повторно, підтвердити вимірюване збільшення
Представляти лише нові блоки тестового коду. Дотримуватися існуючих патернів та конвенцій іменування тестів.
---
**Останнє оновлення**: 9 квітня 2026
File diff suppressed because it is too large Load Diff
+64
View File
@@ -0,0 +1,64 @@
# Стандарти модуля API
Цей файл перевизначає кореневий CLAUDE.md для всього у /src/api/
## Специфічні стандарти API
### Валідація запитів
- Використовувати Zod для валідації схем
- Завжди валідувати вхідні дані
- Повертати 400 з помилками валідації
- Включати деталі помилок на рівні полів
### Автентифікація
- Усі ендпоінти вимагають JWT-токен
- Токен у заголовку Authorization
- Токен закінчується через 24 години
- Реалізувати механізм refresh-токенів
### Формат відповіді
Усі відповіді мають дотримуватися цієї структури:
```json
{
"success": true,
"data": { /* фактичні дані */ },
"timestamp": "2025-11-06T10:30:00Z",
"version": "1.0"
}
```
Відповіді з помилками:
```json
{
"success": false,
"error": {
"code": "VALIDATION_ERROR",
"message": "Повідомлення для користувача",
"details": { /* помилки полів */ }
},
"timestamp": "2025-11-06T10:30:00Z"
}
```
### Пагінація
- Використовувати пагінацію на основі курсора (не зсуву/offset)
- Включати булеве поле `hasMore`
- Максимальний розмір сторінки: 100
- Розмір сторінки за замовчуванням: 20
### Обмеження частоти запитів (Rate Limiting)
- 1000 запитів на годину для автентифікованих користувачів
- 100 запитів на годину для публічних ендпоінтів
- Повертати 429 при перевищенні
- Включати заголовок retry-after
### Кешування
- Використовувати Redis для кешування сесій
- Тривалість кешу: 5 хвилин за замовчуванням
- Інвалідувати при операціях запису
- Тегувати ключі кешу типом ресурсу
---
**Останнє оновлення**: 9 квітня 2026
Binary file not shown.

After

Width:  |  Height:  |  Size: 95 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 296 KiB

+63
View File
@@ -0,0 +1,63 @@
# Мої уподобання розробки
## Про мене
- **Рівень досвіду**: 8 років full-stack розробки
- **Бажані мови**: TypeScript, Python
- **Стиль комунікації**: Прямий, з прикладами
- **Стиль навчання**: Візуальні діаграми з кодом
## Уподобання коду
### Обробка помилок
Я віддаю перевагу явній обробці помилок з блоками try-catch та змістовними повідомленнями.
Уникайте загальних помилок. Завжди логуйте помилки для налагодження.
### Коментарі
Коментарі для ЧОМУ, а не ЩО. Код має бути самодокументованим.
Коментарі мають пояснювати бізнес-логіку або неочевидні рішення.
### Тестування
Я віддаю перевагу TDD (розробка через тестування).
Спочатку писати тести, потім реалізацію.
Фокус на поведінці, а не деталях реалізації.
### Архітектура
Я віддаю перевагу модульному, слабкоповʼязаному дизайну.
Використовувати впровадження залежностей (dependency injection) для тестовності.
Розділення відповідальностей (Controllers, Services, Repositories).
## Уподобання налагодження
- Використовувати console.log з префіксом: `[DEBUG]`
- Включати контекст: назву функції, відповідні змінні
- Використовувати стеки викликів (stack traces), коли доступні
- Завжди включати мітки часу в журналах
## Комунікація
- Пояснювати складні концепції діаграмами
- Показувати конкретні приклади перед поясненням теорії
- Включати фрагменти коду до/після
- Підсумовувати ключові моменти наприкінці
## Організація проєкту
Я організовую проєкти так:
```
project/
├── src/
│ ├── api/
│ ├── services/
│ ├── models/
│ └── utils/
├── tests/
├── docs/
└── docker/
```
## Інструментарій
- **IDE**: VS Code з vim-клавішами
- **Термінал**: Zsh з Oh-My-Zsh
- **Форматування**: Prettier (довжина рядка 100 символів)
- **Лінтер**: ESLint з конфігурацією airbnb
- **Тестовий фреймворк**: Jest з React Testing Library
---
**Останнє оновлення**: 9 квітня 2026
+91
View File
@@ -0,0 +1,91 @@
# Конфігурація проєкту
## Огляд проєкту
- **Назва**: Платформа електронної комерції
- **Технологічний стек**: Node.js, PostgreSQL, React 18, Docker
- **Розмір команди**: 5 розробників
- **Дедлайн**: Q4 2025
## Архітектура
@docs/architecture.md
@docs/api-standards.md
@docs/database-schema.md
## Стандарти розробки
### Стиль коду
- Використовувати Prettier для форматування
- Використовувати ESLint з конфігурацією airbnb
- Максимальна довжина рядка: 100 символів
- Використовувати відступ 2 пробіли
### Конвенції іменування
- **Файли**: kebab-case (user-controller.js)
- **Класи**: PascalCase (UserService)
- **Функції/Змінні**: camelCase (getUserById)
- **Константи**: UPPER_SNAKE_CASE (API_BASE_URL)
- **Таблиці БД**: snake_case (user_accounts)
### Git-процес
- Назви гілок: `feature/description` або `fix/description`
- Повідомлення комітів: дотримуватися conventional commits
- PR обовʼязковий перед злиттям
- Усі CI/CD перевірки мають пройти
- Мінімум 1 затвердження (approval) обовʼязкове
### Вимоги до тестування
- Мінімум 80% покриття коду
- Усі критичні шляхи мають мати тести
- Використовувати Jest для юніт-тестів
- Використовувати Cypress для E2E-тестів
- Назви тестових файлів: `*.test.ts` або `*.spec.ts`
### Стандарти API
- Лише RESTful ендпоінти
- JSON запит/відповідь
- Правильно використовувати HTTP-статус-коди
- Версіонування API-ендпоінтів: `/api/v1/`
- Документувати всі ендпоінти з прикладами
### База даних
- Використовувати міграції для змін схеми
- Ніколи не зашивати облікові дані в код
- Використовувати пул зʼєднань (connection pooling)
- Увімкнути логування запитів у середовищі розробки
- Регулярне резервне копіювання обовʼязкове
### Деплой
- Деплой на основі Docker
- Оркестрація Kubernetes
- Стратегія blue-green деплою
- Автоматичний відкат при невдачі
- Міграції БД виконуються перед деплоєм
## Типові команди
| Команда | Призначення |
|---------|-------------|
| `npm run dev` | Запуск сервера розробки |
| `npm test` | Запуск тестового набору |
| `npm run lint` | Перевірка стилю коду |
| `npm run build` | Збірка для продакшну |
| `npm run migrate` | Запуск міграцій БД |
## Контакти команди
- Техлід: Sarah Chen (@sarah.chen)
- Продакт-менеджер: Mike Johnson (@mike.j)
- DevOps: Alex Kim (@alex.k)
## Відомі проблеми та обхідні рішення
- Пул зʼєднань PostgreSQL обмежений до 20 у пікові години
- Обхідне рішення: реалізувати чергу запитів
- Проблеми сумісності Safari 14 з async generators
- Обхідне рішення: використовувати транспілятор Babel
## Повʼязані проєкти
- Аналітична панель: `/projects/analytics`
- Мобільний додаток: `/projects/mobile`
- Адмін-панель: `/projects/admin`
---
**Останнє оновлення**: 9 квітня 2026
+5
View File
@@ -0,0 +1,5 @@
# Local skill testing
.claude/
# Blog post outputs
blog-posts/
+815
View File
@@ -0,0 +1,815 @@
<!-- i18n-source: 03-skills/README.md -->
<!-- i18n-source-sha: 63a1416 -->
<!-- i18n-date: 2026-04-09 -->
<picture>
<source media="(prefers-color-scheme: dark)" srcset="../resources/logos/claude-howto-logo-dark.svg">
<img alt="Claude How To" src="../resources/logos/claude-howto-logo.svg">
</picture>
# Посібник з навичок агента
Навички агента (Agent Skills) — це повторно використовувані, файлові можливості, які розширюють функціональність Claude. Вони пакують доменну експертизу, воркфлови та найкращі практики в компоненти, що автоматично виявляються, і Claude використовує їх, коли це доречно.
## Огляд
**Навички агента** — це модульні можливості, які перетворюють агентів загального призначення на спеціалістів. На відміну від промптів (інструкцій рівня розмови для одноразових завдань), навички завантажуються за потребою і усувають необхідність повторно надавати ті самі рекомендації в кількох розмовах.
### Ключові переваги
- **Спеціалізація Claude**: налаштування можливостей для доменних завдань
- **Зменшення повторень**: створити один раз, використовувати автоматично в усіх розмовах
- **Комбінування можливостей**: поєднання навичок для побудови складних воркфловів
- **Масштабування воркфловів**: повторне використання навичок у кількох проєктах і командах
- **Підтримка якості**: вбудовування найкращих практик безпосередньо у воркфлов
Навички відповідають відкритому стандарту [Agent Skills](https://agentskills.io), який працює з кількома AI-інструментами. Claude Code розширює стандарт додатковими функціями: керування викликом, виконання в субагенті та динамічне впровадження контексту.
> **Примітка**: Користувацькі слеш-команди об'єднано з навичками. Файли `.claude/commands/` все ще працюють і підтримують ті самі поля фронтматера. Навички рекомендовано для нової розробки. Коли обидва існують за одним шляхом (наприклад, `.claude/commands/review.md` та `.claude/skills/review/SKILL.md`), навичка має пріоритет.
## Як працюють навички: прогресивне розкриття
Навички використовують архітектуру **прогресивного розкриття** (progressive disclosure) — Claude завантажує інформацію поетапно за потребою, а не споживає весь контекст одразу. Це забезпечує ефективне управління контекстом із необмеженою масштабованістю.
### Три рівні завантаження
```mermaid
graph TB
subgraph "Level 1: Metadata (Always Loaded)"
A["YAML Frontmatter"]
A1["~100 tokens per skill"]
A2["name + description"]
end
subgraph "Level 2: Instructions (When Triggered)"
B["SKILL.md Body"]
B1["Under 5k tokens"]
B2["Workflows & guidance"]
end
subgraph "Level 3: Resources (As Needed)"
C["Bundled Files"]
C1["Effectively unlimited"]
C2["Scripts, templates, docs"]
end
A --> B
B --> C
```
| Рівень | Коли завантажується | Вартість токенів | Вміст |
|--------|-------------------|-----------------|-------|
| **Рівень 1: Метадані** | Завжди (при запуску) | ~100 токенів на навичку | `name` та `description` з YAML-фронтматера |
| **Рівень 2: Інструкції** | Коли навичка активована | До 5k токенів | Тіло SKILL.md з інструкціями та рекомендаціями |
| **Рівень 3+: Ресурси** | За потребою | Фактично необмежено | Файли-пакети, що виконуються через bash без завантаження в контекст |
Це означає, що ви можете встановити багато навичок без штрафу за контекст — Claude лише знає, що кожна навичка існує і коли її використовувати, доки вона фактично не активована.
## Процес завантаження навички
```mermaid
sequenceDiagram
participant User
participant Claude as Claude
participant System as System
participant Skill as Skill
User->>Claude: "Review this code for security issues"
Claude->>System: Check available skills (metadata)
System-->>Claude: Skill descriptions loaded at startup
Claude->>Claude: Match request to skill description
Claude->>Skill: bash: read code-review/SKILL.md
Skill-->>Claude: Instructions loaded into context
Claude->>Claude: Determine: Need templates?
Claude->>Skill: bash: read templates/checklist.md
Skill-->>Claude: Template loaded
Claude->>Claude: Execute skill instructions
Claude->>User: Comprehensive code review
```
## Типи та розташування навичок
| Тип | Розташування | Область дії | Спільний | Найкраще для |
|-----|-------------|-------------|---------|-------------|
| **Enterprise** | Managed settings | Всі користувачі організації | Так | Загальноорганізаційні стандарти |
| **Personal** | `~/.claude/skills/<skill-name>/SKILL.md` | Індивідуальний | Ні | Персональні воркфлови |
| **Project** | `.claude/skills/<skill-name>/SKILL.md` | Команда | Так (через git) | Командні стандарти |
| **Plugin** | `<plugin>/skills/<skill-name>/SKILL.md` | Де увімкнено | Залежить | В складі плагінів |
Коли навички мають однакову назву на різних рівнях, вищі пріоритетні розташування перемагають: **enterprise > personal > project**. Навички плагінів використовують простір імен `plugin-name:skill-name`, тому конфлікти неможливі.
### Автоматичне виявлення
**Вкладені каталоги**: коли ви працюєте з файлами в підкаталогах, Claude Code автоматично виявляє навички з вкладених каталогів `.claude/skills/`. Наприклад, якщо ви редагуєте файл у `packages/frontend/`, Claude Code також шукає навички в `packages/frontend/.claude/skills/`. Це підтримує конфігурації монорепо, де пакети мають власні навички.
**Каталоги `--add-dir`**: навички з каталогів, доданих через `--add-dir`, завантажуються автоматично з виявленням змін у реальному часі. Будь-які зміни файлів навичок у цих каталогах набувають чинності негайно без перезапуску Claude Code.
**Бюджет опису**: описи навичок (метадані рівня 1) обмежені **1% контекстного вікна** (резерв: **8 000 символів**). Якщо встановлено багато навичок, описи можуть бути скорочені. Назви всіх навичок завжди включаються, але описи обрізаються для вписування. Розміщуйте ключовий випадок використання на початку описів. Перевизначте бюджет змінною оточення `SLASH_COMMAND_TOOL_CHAR_BUDGET`.
## Створення власних навичок
### Базова структура каталогу
```
my-skill/
├── SKILL.md # Головні інструкції (обов'язковий)
├── template.md # Шаблон для заповнення Claude
├── examples/
│ └── sample.md # Приклад результату з очікуваним форматом
└── scripts/
└── validate.sh # Скрипт, який Claude може виконати
```
### Формат SKILL.md
```yaml
---
name: your-skill-name
description: Brief description of what this Skill does and when to use it
---
# Your Skill Name
## Instructions
Provide clear, step-by-step guidance for Claude.
## Examples
Show concrete examples of using this Skill.
```
### Обов'язкові поля
- **name**: тільки малі літери, цифри, дефіси (макс. 64 символи). Не може містити "anthropic" або "claude".
- **description**: що навичка робить І коли її використовувати (макс. 1024 символи). Це критично для того, щоб Claude знав, коли активувати навичку.
### Додаткові поля фронтматера
```yaml
---
name: my-skill
description: What this skill does and when to use it
argument-hint: "[filename] [format]" # Підказка для автодоповнення
disable-model-invocation: true # Тільки користувач може викликати
user-invocable: false # Приховати з меню слеш-команд
allowed-tools: Read, Grep, Glob # Обмежити доступ до інструментів
model: opus # Конкретна модель
effort: high # Рівень зусиль (low, medium, high, max)
context: fork # Запуск в ізольованому субагенті
agent: Explore # Тип агента (з context: fork)
shell: bash # Оболонка: bash (за замовч.) або powershell
hooks: # Хуки, обмежені навичкою
PreToolUse:
- matcher: "Bash"
hooks:
- type: command
command: "./scripts/validate.sh"
paths: "src/api/**/*.ts" # Glob-патерни, що обмежують активацію
---
```
| Поле | Опис |
|------|------|
| `name` | Тільки малі літери, цифри, дефіси (макс. 64 символи). Не може містити "anthropic" або "claude". |
| `description` | Що навичка робить І коли її використовувати (макс. 1024 символи). Критично для автоматичного зіставлення. |
| `argument-hint` | Підказка в меню автодоповнення `/` (наприклад, `"[filename] [format]"`). |
| `disable-model-invocation` | `true` = тільки користувач може викликати через `/name`. Claude ніколи не викличе автоматично. |
| `user-invocable` | `false` = приховано з меню `/`. Тільки Claude може викликати автоматично. |
| `allowed-tools` | Список інструментів через кому, які навичка може використовувати без запитів дозволу. |
| `model` | Перевизначення моделі під час активності навички (наприклад, `opus`, `sonnet`). |
| `effort` | Перевизначення рівня зусиль: `low`, `medium`, `high` або `max`. |
| `context` | `fork` для запуску навички у відгалуженому контексті субагента з власним контекстним вікном. |
| `agent` | Тип субагента при `context: fork` (наприклад, `Explore`, `Plan`, `general-purpose`). |
| `shell` | Оболонка для підстановок `!`command`` та скриптів: `bash` (за замовч.) або `powershell`. |
| `hooks` | Хуки, обмежені життєвим циклом цієї навички (той самий формат, що й глобальні хуки). |
| `paths` | Glob-патерни, що обмежують автоактивацію. Рядок через кому або YAML-список. Формат як у правилах для конкретних шляхів. |
## Типи вмісту навичок
Навички можуть містити два типи вмісту, кожен для різних цілей:
### Довідковий вміст
Додає знання, які Claude застосовує до вашої поточної роботи — конвенції, патерни, стайлгайди, доменні знання. Виконується в контексті вашої розмови.
```yaml
---
name: api-conventions
description: API design patterns for this codebase
---
When writing API endpoints:
- Use RESTful naming conventions
- Return consistent error formats
- Include request validation
```
### Вміст завдань
Покрокові інструкції для конкретних дій. Часто викликається безпосередньо через `/skill-name`.
```yaml
---
name: deploy
description: Deploy the application to production
context: fork
disable-model-invocation: true
---
Deploy the application:
1. Run the test suite
2. Build the application
3. Push to the deployment target
```
## Керування викликом навичок
За замовчуванням і ви, і Claude можете викликати будь-яку навичку. Два поля фронтматера контролюють три режими виклику:
| Фронтматер | Ви можете викликати | Claude може викликати |
|---|---|---|
| (за замовч.) | Так | Так |
| `disable-model-invocation: true` | Так | Ні |
| `user-invocable: false` | Ні | Так |
**Використовуйте `disable-model-invocation: true`** для воркфловів з побічними ефектами: `/commit`, `/deploy`, `/send-slack-message`. Ви не хочете, щоб Claude вирішив задеплоїти, бо ваш код виглядає готовим.
**Використовуйте `user-invocable: false`** для фонових знань, які не є дієвими як команда. Навичка `legacy-system-context` пояснює, як працює стара система — корисно для Claude, але не має сенсу як дія для користувачів.
## Підстановки рядків
Навички підтримують динамічні значення, які розв'язуються до того, як вміст навички потрапляє до Claude:
| Змінна | Опис |
|--------|------|
| `$ARGUMENTS` | Всі аргументи, передані при виклику навички |
| `$ARGUMENTS[N]` або `$N` | Доступ до конкретного аргументу за індексом (починаючи з 0) |
| `${CLAUDE_SESSION_ID}` | ID поточної сесії |
| `${CLAUDE_SKILL_DIR}` | Каталог, що містить файл SKILL.md навички |
| `` !`command` `` | Динамічне впровадження контексту — виконує команду оболонки та вставляє результат |
**Приклад:**
```yaml
---
name: fix-issue
description: Fix a GitHub issue
---
Fix GitHub issue $ARGUMENTS following our coding standards.
1. Read the issue description
2. Implement the fix
3. Write tests
4. Create a commit
```
Виконання `/fix-issue 123` замінює `$ARGUMENTS` на `123`.
## Впровадження динамічного контексту
Синтаксис `` !`command` `` виконує команди оболонки до того, як вміст навички відправляється до Claude:
```yaml
---
name: pr-summary
description: Summarize changes in a pull request
context: fork
agent: Explore
---
## Pull request context
- PR diff: !`gh pr diff`
- PR comments: !`gh pr view --comments`
- Changed files: !`gh pr diff --name-only`
## Your task
Summarize this pull request...
```
Команди виконуються негайно; Claude бачить лише кінцевий результат. За замовчуванням команди виконуються в `bash`. Встановіть `shell: powershell` у фронтматері для використання PowerShell.
## Запуск навичок у субагентах
Додайте `context: fork` для запуску навички в ізольованому контексті субагента. Вміст навички стає завданням для виділеного субагента з власним контекстним вікном, зберігаючи основну розмову чистою.
Поле `agent` вказує тип агента:
| Тип агента | Найкраще для |
|---|---|
| `Explore` | Дослідження лише для читання, аналіз кодової бази |
| `Plan` | Створення планів реалізації |
| `general-purpose` | Широкі завдання, що потребують усіх інструментів |
| Custom agents | Спеціалізовані агенти, визначені у вашій конфігурації |
**Приклад фронтматера:**
```yaml
---
context: fork
agent: Explore
---
```
**Повний приклад навички:**
```yaml
---
name: deep-research
description: Research a topic thoroughly
context: fork
agent: Explore
---
Research $ARGUMENTS thoroughly:
1. Find relevant files using Glob and Grep
2. Read and analyze the code
3. Summarize findings with specific file references
```
## Практичні приклади
### Приклад 1: Навичка код-рев'ю
**Структура каталогу:**
```
~/.claude/skills/code-review/
├── SKILL.md
├── templates/
│ ├── review-checklist.md
│ └── finding-template.md
└── scripts/
├── analyze-metrics.py
└── compare-complexity.py
```
**Файл:** `~/.claude/skills/code-review/SKILL.md`
```yaml
---
name: code-review-specialist
description: Comprehensive code review with security, performance, and quality analysis. Use when users ask to review code, analyze code quality, evaluate pull requests, or mention code review, security analysis, or performance optimization.
---
# Code Review Skill
This skill provides comprehensive code review capabilities focusing on:
1. **Security Analysis**
- Authentication/authorization issues
- Data exposure risks
- Injection vulnerabilities
- Cryptographic weaknesses
2. **Performance Review**
- Algorithm efficiency (Big O analysis)
- Memory optimization
- Database query optimization
- Caching opportunities
3. **Code Quality**
- SOLID principles
- Design patterns
- Naming conventions
- Test coverage
4. **Maintainability**
- Code readability
- Function size (should be < 50 lines)
- Cyclomatic complexity
- Type safety
## Review Template
For each piece of code reviewed, provide:
### Summary
- Overall quality assessment (1-5)
- Key findings count
- Recommended priority areas
### Critical Issues (if any)
- **Issue**: Clear description
- **Location**: File and line number
- **Impact**: Why this matters
- **Severity**: Critical/High/Medium
- **Fix**: Code example
For detailed checklists, see [templates/review-checklist.md](templates/review-checklist.md).
```
### Приклад 2: Навичка візуалізації кодової бази
Навичка, що генерує інтерактивні HTML-візуалізації:
**Структура каталогу:**
```
~/.claude/skills/codebase-visualizer/
├── SKILL.md
└── scripts/
└── visualize.py
```
**Файл:** `~/.claude/skills/codebase-visualizer/SKILL.md`
````yaml
---
name: codebase-visualizer
description: Generate an interactive collapsible tree visualization of your codebase. Use when exploring a new repo, understanding project structure, or identifying large files.
allowed-tools: Bash(python *)
---
# Codebase Visualizer
Generate an interactive HTML tree view showing your project's file structure.
## Usage
Run the visualization script from your project root:
```bash
python ~/.claude/skills/codebase-visualizer/scripts/visualize.py .
```
This creates `codebase-map.html` and opens it in your default browser.
## What the visualization shows
- **Collapsible directories**: Click folders to expand/collapse
- **File sizes**: Displayed next to each file
- **Colors**: Different colors for different file types
- **Directory totals**: Shows aggregate size of each folder
````
Python-скрипт у пакеті виконує важку роботу, а Claude займається оркестрацією.
### Приклад 3: Навичка деплою (тільки виклик користувачем)
```yaml
---
name: deploy
description: Deploy the application to production
disable-model-invocation: true
allowed-tools: Bash(npm *), Bash(git *)
---
Deploy $ARGUMENTS to production:
1. Run the test suite: `npm test`
2. Build the application: `npm run build`
3. Push to the deployment target
4. Verify the deployment succeeded
5. Report deployment status
```
### Приклад 4: Навичка голосу бренду (фонові знання)
```yaml
---
name: brand-voice
description: Ensure all communication matches brand voice and tone guidelines. Use when creating marketing copy, customer communications, or public-facing content.
user-invocable: false
---
## Tone of Voice
- **Friendly but professional** - approachable without being casual
- **Clear and concise** - avoid jargon
- **Confident** - we know what we're doing
- **Empathetic** - understand user needs
## Writing Guidelines
- Use "you" when addressing readers
- Use active voice
- Keep sentences under 20 words
- Start with value proposition
For templates, see [templates/](templates/).
```
### Приклад 5: Навичка генератора CLAUDE.md
```yaml
---
name: claude-md
description: Create or update CLAUDE.md files following best practices for optimal AI agent onboarding. Use when users mention CLAUDE.md, project documentation, or AI onboarding.
---
## Core Principles
**LLMs are stateless**: CLAUDE.md is the only file automatically included in every conversation.
### The Golden Rules
1. **Less is More**: Keep under 300 lines (ideally under 100)
2. **Universal Applicability**: Only include information relevant to EVERY session
3. **Don't Use Claude as a Linter**: Use deterministic tools instead
4. **Never Auto-Generate**: Craft it manually with careful consideration
## Essential Sections
- **Project Name**: Brief one-line description
- **Tech Stack**: Primary language, frameworks, database
- **Development Commands**: Install, test, build commands
- **Critical Conventions**: Only non-obvious, high-impact conventions
- **Known Issues / Gotchas**: Things that trip up developers
```
### Приклад 6: Навичка рефакторингу зі скриптами
**Структура каталогу:**
```
refactor/
├── SKILL.md
├── references/
│ ├── code-smells.md
│ └── refactoring-catalog.md
├── templates/
│ └── refactoring-plan.md
└── scripts/
├── analyze-complexity.py
└── detect-smells.py
```
**Файл:** `refactor/SKILL.md`
```yaml
---
name: code-refactor
description: Systematic code refactoring based on Martin Fowler's methodology. Use when users ask to refactor code, improve code structure, reduce technical debt, or eliminate code smells.
---
# Code Refactoring Skill
A phased approach emphasizing safe, incremental changes backed by tests.
## Workflow
Phase 1: Research & Analysis → Phase 2: Test Coverage Assessment →
Phase 3: Code Smell Identification → Phase 4: Refactoring Plan Creation →
Phase 5: Incremental Implementation → Phase 6: Review & Iteration
## Core Principles
1. **Behavior Preservation**: External behavior must remain unchanged
2. **Small Steps**: Make tiny, testable changes
3. **Test-Driven**: Tests are the safety net
4. **Continuous**: Refactoring is ongoing, not a one-time event
For code smell catalog, see [references/code-smells.md](references/code-smells.md).
For refactoring techniques, see [references/refactoring-catalog.md](references/refactoring-catalog.md).
```
## Допоміжні файли
Навички можуть включати кілька файлів у каталозі крім `SKILL.md`. Ці допоміжні файли (шаблони, приклади, скрипти, довідкові документи) дозволяють тримати головний файл навички сфокусованим, надаючи Claude додаткові ресурси, які він завантажує за потребою.
```
my-skill/
├── SKILL.md # Головні інструкції (обов'язковий, до 500 рядків)
├── templates/ # Шаблони для заповнення Claude
│ └── output-format.md
├── examples/ # Приклади результатів з очікуваним форматом
│ └── sample-output.md
├── references/ # Доменні знання та специфікації
│ └── api-spec.md
└── scripts/ # Скрипти, які Claude може виконати
└── validate.sh
```
Рекомендації щодо допоміжних файлів:
- Тримайте `SKILL.md` до **500 рядків**. Переносіть детальний довідковий матеріал, великі приклади та специфікації в окремі файли.
- Посилайтесь на додаткові файли з `SKILL.md` за допомогою **відносних шляхів** (наприклад, `[API reference](references/api-spec.md)`).
- Допоміжні файли завантажуються на рівні 3 (за потребою), тому вони не споживають контекст, поки Claude фактично їх не прочитає.
## Управління навичками
### Перегляд доступних навичок
Запитайте Claude безпосередньо:
```
What Skills are available?
```
Або перевірте файлову систему:
```bash
# Список персональних навичок
ls ~/.claude/skills/
# Список навичок проєкту
ls .claude/skills/
```
### Тестування навички
Два способи тестування:
**Дозвольте Claude викликати автоматично**, запитавши щось, що відповідає опису:
```
Can you help me review this code for security issues?
```
**Або викличте безпосередньо** за назвою навички:
```
/code-review src/auth/login.ts
```
### Оновлення навички
Редагуйте файл `SKILL.md` безпосередньо. Зміни набувають чинності при наступному запуску Claude Code.
```bash
# Персональна навичка
code ~/.claude/skills/my-skill/SKILL.md
# Навичка проєкту
code .claude/skills/my-skill/SKILL.md
```
### Обмеження доступу Claude до навичок
Три способи контролювати, які навички Claude може викликати:
**Вимкнути всі навички** в `/permissions`:
```
# Додати до правил заборони:
Skill
```
**Дозволити або заборонити конкретні навички**:
```
# Дозволити лише конкретні навички
Skill(commit)
Skill(review-pr *)
# Заборонити конкретні навички
Skill(deploy *)
```
**Приховати окремі навички**, додавши `disable-model-invocation: true` до їхнього фронтматера.
## Найкращі практики
### 1. Робіть описи конкретними
- **Погано (розпливчасто)**: "Helps with documents"
- **Добре (конкретно)**: "Extract text and tables from PDF files, fill forms, merge documents. Use when working with PDF files or when the user mentions PDFs, forms, or document extraction."
### 2. Тримайте навички сфокусованими
- Одна навичка = одна можливість
- ✅ "PDF form filling"
- ❌ "Document processing" (занадто широко)
### 3. Включайте тригерні терміни
Додавайте ключові слова в описи, що відповідають запитам користувачів:
```yaml
description: Analyze Excel spreadsheets, generate pivot tables, create charts. Use when working with Excel files, spreadsheets, or .xlsx files.
```
### 4. Тримайте SKILL.md до 500 рядків
Переносіть детальний довідковий матеріал в окремі файли, які Claude завантажує за потребою.
### 5. Посилайтесь на допоміжні файли
```markdown
## Additional resources
- For complete API details, see [reference.md](reference.md)
- For usage examples, see [examples.md](examples.md)
```
### Рекомендовано
- Використовуйте зрозумілі, описові назви
- Включайте вичерпні інструкції
- Додавайте конкретні приклади
- Пакуйте пов'язані скрипти та шаблони
- Тестуйте з реальними сценаріями
- Документуйте залежності
### Не рекомендовано
- Не створюйте навички для одноразових завдань
- Не дублюйте наявну функціональність
- Не робіть навички занадто широкими
- Не пропускайте поле description
- Не встановлюйте навички з ненадійних джерел без аудиту
## Усунення несправностей
### Короткий довідник
| Проблема | Рішення |
|----------|---------|
| Claude не використовує навичку | Зробіть опис конкретнішим з тригерними термінами |
| Файл навички не знайдено | Перевірте шлях: `~/.claude/skills/name/SKILL.md` |
| Помилки YAML | Перевірте маркери `---`, відступи, відсутність табів |
| Конфлікт навичок | Використовуйте різні тригерні терміни в описах |
| Скрипти не запускаються | Перевірте дозволи: `chmod +x scripts/*.py` |
| Claude не бачить всі навички | Занадто багато навичок; перевірте `/context` на попередження |
### Навичка не спрацьовує
Якщо Claude не використовує навичку, коли очікується:
1. Перевірте, що опис містить ключові слова, які користувачі природно вживають
2. Переконайтесь, що навичка відображається при запиті "What skills are available?"
3. Спробуйте переформулювати запит відповідно до опису
4. Викличте безпосередньо через `/skill-name` для тестування
### Навичка спрацьовує занадто часто
Якщо Claude використовує навичку, коли ви цього не хочете:
1. Зробіть опис конкретнішим
2. Додайте `disable-model-invocation: true` для виклику лише вручну
### Claude не бачить усі навички
Описи навичок завантажуються з лімітом **1% контекстного вікна** (резерв: **8 000 символів**). Кожен запис обмежений 250 символами незалежно від бюджету. Запустіть `/context`, щоб перевірити попередження про виключені навички. Перевизначте бюджет змінною оточення `SLASH_COMMAND_TOOL_CHAR_BUDGET`.
## Питання безпеки
**Використовуйте навички лише з надійних джерел.** Навички надають Claude можливості через інструкції та код — шкідлива навичка може направити Claude на виклик інструментів або виконання коду небезпечними способами.
**Ключові питання безпеки:**
- **Ретельний аудит**: перевіряйте всі файли в каталозі навички
- **Зовнішні джерела ризиковані**: навички, що завантажують із зовнішніх URL, можуть бути скомпрометовані
- **Зловживання інструментами**: шкідливі навички можуть викликати інструменти небезпечними способами
- **Ставтесь як до встановлення ПЗ**: використовуйте навички лише з надійних джерел
## Навички vs інші функції
| Функція | Виклик | Найкраще для |
|---------|--------|-------------|
| **Навички** | Авто або `/name` | Повторно використовувана експертиза, воркфлови |
| **Слеш-команди** | Користувач через `/name` | Швидкі ярлики (об'єднано з навичками) |
| **Субагенти** | Автоделегування | Ізольоване виконання завдань |
| **Пам'ять (CLAUDE.md)** | Завжди завантажена | Постійний контекст проєкту |
| **MCP** | У реальному часі | Доступ до зовнішніх даних/сервісів |
| **Хуки** | За подіями | Автоматизовані побічні ефекти |
## Вбудовані навички
Claude Code постачається з кількома вбудованими навичками, доступними без встановлення:
| Навичка | Опис |
|---------|------|
| `/simplify` | Перевірка змінених файлів на повторне використання, якість та ефективність; запускає 3 паралельних агенти рев'ю |
| `/batch <instruction>` | Оркестрація масштабних паралельних змін по кодовій базі з використанням git worktrees |
| `/debug [description]` | Усунення несправностей поточної сесії через читання журналу налагодження |
| `/loop [interval] <prompt>` | Циклічне виконання промпта з інтервалом (наприклад, `/loop 5m check the deploy`) |
| `/claude-api` | Завантаження довідника Claude API/SDK; автоактивується при імпортах `anthropic`/`@anthropic-ai/sdk` |
Ці навички доступні одразу і не потребують встановлення чи конфігурації. Вони використовують той самий формат SKILL.md, що й власні навички.
## Поширення навичок
### Навички проєкту (командне поширення)
1. Створіть навичку в `.claude/skills/`
2. Закомітьте в git
3. Члени команди витягують зміни — навички доступні одразу
### Персональні навички
```bash
# Копіювання в персональний каталог
cp -r my-skill ~/.claude/skills/
# Зробити скрипти виконуваними
chmod +x ~/.claude/skills/my-skill/scripts/*.py
```
### Дистрибуція через плагіни
Пакуйте навички в каталог `skills/` плагіна для ширшої дистрибуції.
## Далі: колекція навичок та менеджер навичок
Коли ви починаєте серйозно створювати навички, дві речі стають необхідними: бібліотека перевірених навичок та інструмент для їх управління.
**[luongnv89/skills](https://github.com/luongnv89/skills)** — колекція навичок, які автор використовує щодня майже у всіх проєктах. Серед цікавих: `logo-designer` (генерація логотипів проєктів на льоту) та `ollama-optimizer` (налаштування продуктивності локальних LLM під ваше обладнання). Хороша відправна точка для готових до використання навичок.
**[luongnv89/asm](https://github.com/luongnv89/asm)** — Agent Skill Manager. Керує розробкою навичок, виявленням дублікатів та тестуванням. Команда `asm link` дозволяє тестувати навичку в будь-якому проєкті без копіювання файлів — це необхідно, коли навичок більше кількох.
## Додаткові ресурси
- [Офіційна документація навичок](https://code.claude.com/docs/en/skills)
- [Блог про архітектуру Agent Skills](https://claude.com/blog/equipping-agents-for-the-real-world-with-agent-skills)
- [Репозиторій навичок](https://github.com/luongnv89/skills) — колекція готових навичок
- [Посібник слеш-команд](../01-slash-commands/) — ярлики, ініційовані користувачем
- [Посібник субагентів](../04-subagents/) — делеговані AI-агенти
- [Посібник з пам'яті](../02-memory/) — постійний контекст
- [MCP (Model Context Protocol)](../05-mcp/) — зовнішні дані в реальному часі
- [Посібник хуків](../06-hooks/) — автоматизація за подіями
---
**Останнє оновлення**: 9 квітня 2026
**Версія Claude Code**: 2.1.97
**Сумісні моделі**: Claude Sonnet 4.6, Claude Opus 4.6, Claude Haiku 4.5
+274
View File
@@ -0,0 +1,274 @@
---
name: blog-draft
description: Створення чернетки блог-посту з ідей та ресурсів. Використовуйте, коли користувачі хочуть написати блог-пост, створити контент з дослідження або підготувати статтю. Проводить через дослідження, мозковий штурм, складання плану та ітеративне написання з контролем версій.
---
## Введення користувача
```text
$ARGUMENTS
```
Ви **ПОВИННІ** врахувати введення користувача перед продовженням. Користувач має надати:
- **Ідея/Тема**: Основна концепція або тематика блог-посту
- **Ресурси**: URL, файли або посилання на дослідження (необовʼязково, але рекомендовано)
- **Цільова аудиторія**: Для кого блог-пост (необовʼязково)
- **Тон/Стиль**: Формальний, невимушений, технічний тощо (необовʼязково)
**ВАЖЛИВО**: Якщо користувач запитує оновлення **існуючого блог-посту**, пропустіть кроки 0-8 і починайте безпосередньо з **Кроку 9**. Спочатку прочитайте існуючий файл(и) чернетки, потім продовжуйте з процесом ітерації.
## Потік виконання
Виконуйте ці кроки послідовно. **Не пропускайте кроки та не продовжуйте без затвердження користувача, де це зазначено.**
### Крок 0: Створення папки проєкту
1. Згенерувати назву папки у форматі: `YYYY-MM-DD-short-topic-name`
- Використати сьогоднішню дату
- Створити короткий, URL-дружній slug з теми (малі літери, дефіси, макс. 5 слів)
2. Створити структуру папок:
```
blog-posts/
└── YYYY-MM-DD-short-topic-name/
└── resources/
```
3. Підтвердити створення папки з користувачем перед продовженням.
### Крок 1: Дослідження та збір ресурсів
1. Створити підпапку `resources/` у каталозі блог-посту
2. Для кожного наданого ресурсу:
- **URL-адреси**: Отримати та зберегти ключову інформацію до `resources/` як markdown-файли
- **Файли**: Прочитати та підсумувати в `resources/`
- **Теми**: Використати веб-пошук для збору актуальної інформації
3. Для кожного ресурсу створити файл резюме в `resources/`:
- `resources/source-1-[short-name].md`
- `resources/source-2-[short-name].md`
- тощо
4. Кожне резюме має включати:
```markdown
# Джерело: [Назва/URL]
## Ключові тези
- Теза 1
- Теза 2
## Релевантні цитати/дані
- Цитата або статистика 1
- Цитата або статистика 2
## Як це стосується теми
Короткий опис релевантності
```
5. Представити резюме дослідження користувачу.
### Крок 2: Мозковий штурм та уточнення
1. На основі ідеї та досліджених ресурсів представити:
- **Основні теми**, виявлені з дослідження
- **Потенційні ракурси** для блог-посту
- **Ключові тези**, які слід розкрити
- **Прогалини** в інформації, що потребують уточнення
2. Поставити уточнюючі запитання:
- Який головний висновок ви хочете донести до читачів?
- Чи є конкретні тези з дослідження, які хочете виділити?
- Яка цільова довжина? (коротка: 500-800 слів, середня: 1000-1500, довга: 2000+)
- Щось хочете виключити?
3. **Чекати відповідей користувача перед продовженням.**
### Крок 3: Запропонувати план
1. Створити структурований план, що включає:
```markdown
# План блог-посту: [Назва]
## Метаінформація
- **Цільова аудиторія**: [хто]
- **Тон**: [стиль]
- **Цільова довжина**: [кількість слів]
- **Головний висновок**: [ключове повідомлення]
## Запропонована структура
### Зачіпка/Вступ
- Ідея вступної зачіпки
- Встановлення контексту
- Теза
### Розділ 1: [Назва]
- Ключова теза A
- Ключова теза B
- Підтверджуючі докази з [джерела]
### Розділ 2: [Назва]
- Ключова теза A
- Ключова теза B
[Продовжити для всіх розділів...]
### Висновок
- Резюме ключових тез
- Заклик до дії або завершальна думка
## Джерела для цитування
- Джерело 1
- Джерело 2
```
2. Представити план користувачу та **запитати затвердження або модифікації**.
### Крок 4: Зберегти затверджений план
1. Після затвердження плану користувачем зберегти його як `OUTLINE.md` у папці блог-посту.
2. Підтвердити збереження плану.
### Крок 5: Закомітити план (якщо в git-репо)
1. Перевірити, чи поточний каталог є git-репозиторієм.
2. Якщо так:
- Додати нові файли до індексу: папку блог-посту, ресурси та OUTLINE.md
- Створити коміт з повідомленням: `docs: Add outline for blog post - [topic-name]`
- Відправити на віддалений сервер
3. Якщо не git-репо, пропустити цей крок та повідомити користувача.
### Крок 6: Написати чернетку
1. На основі затвердженого плану написати повну чернетку блог-посту.
2. Точно дотримуватися структури з OUTLINE.md.
3. Включити:
- Захопливий вступ із зачіпкою
- Чіткі заголовки розділів
- Підтверджуючі докази та приклади з дослідження
- Плавні переходи між розділами
- Сильний висновок з головною тезою
- **Цитування**: Усі порівняння, статистика, дані та фактичні твердження ПОВИННІ цитувати оригінальне джерело
4. Зберегти чернетку як `draft-v0.1.md` у папці блог-посту.
5. Формат:
```markdown
# [Назва блог-посту]
*[Необовʼязково: підзаголовок або слоган]*
[Повний вміст з інлайн-цитатами...]
---
## Список джерел
- [1] Назва джерела 1 - URL або цитата
- [2] Назва джерела 2 - URL або цитата
- [3] Назва джерела 3 - URL або цитата
```
6. **Вимоги до цитування**:
- Кожна точка даних, статистика або порівняння ПОВИННІ мати інлайн-цитату
- Використовуйте нумеровані посилання [1], [2] тощо, або іменовані цитати [Назва джерела]
- Звʼязуйте цитати з розділом Список джерел наприкінці
- Приклад: «Дослідження показують, що 65% розробників віддають перевагу TypeScript [1]»
- Приклад: «React перевершує Vue за швидкістю рендерингу на 20% [React Benchmarks 2024]»
### Крок 7: Закомітити чернетку (якщо в git-репо)
1. Перевірити, чи в git-репозиторії.
2. Якщо так:
- Додати файл чернетки до індексу
- Створити коміт з повідомленням: `docs: Add draft v0.1 for blog post - [topic-name]`
- Відправити на віддалений сервер
3. Якщо не git-репо, пропустити та повідомити користувача.
### Крок 8: Представити чернетку для перегляду
1. Представити вміст чернетки користувачу.
2. Запитати зворотний звʼязок:
- Загальне враження?
- Розділи, що потребують розширення або скорочення?
- Потрібні корекції тону?
- Відсутня інформація?
- Конкретні правки або переписування?
3. **Чекати відповіді користувача.**
### Крок 9: Ітерація або фіналізація
**Якщо користувач запитує зміни:**
1. Зафіксувати всі запитані модифікації
2. Повернутися до Кроку 6 з такими змінами:
- Збільшити номер версії (v0.2, v0.3 тощо)
- Врахувати всі зауваження
- Зберегти як `draft-v[X.Y].md`
- Повторити Кроки 7-8
**Якщо користувач затверджує:**
1. Підтвердити фінальну версію чернетки
2. За бажанням перейменувати на `final.md`
3. Підсумувати процес створення блог-посту:
- Загальна кількість створених версій
- Ключові зміни між версіями
- Фінальна кількість слів
- Створені файли
## Відстеження версій
Усі чернетки зберігаються з інкрементальним версіонуванням:
- `draft-v0.1.md` — початкова чернетка
- `draft-v0.2.md` — після першого раунду зауважень
- `draft-v0.3.md` — після другого раунду зауважень
- тощо
Це дозволяє відстежувати еволюцію блог-посту та повертатися до попередніх версій за потреби.
## Структура вихідних файлів
```
blog-posts/
└── YYYY-MM-DD-topic-name/
├── resources/
│ ├── source-1-name.md
│ ├── source-2-name.md
│ └── ...
├── OUTLINE.md
├── draft-v0.1.md
├── draft-v0.2.md (якщо ітерації)
└── draft-v0.3.md (якщо більше ітерацій)
```
## Поради щодо якості
- **Зачіпка**: Починайте з питання, дивовижного факту або знайомого сценарію
- **Потік**: Кожен абзац має зʼєднуватися з наступним
- **Докази**: Підтверджуйте твердження даними з дослідження
- **Цитування**: ЗАВЖДИ цитуйте джерела для:
- Усіх статистик та даних (напр., «За даними [Джерело], 75%...»)
- Порівнянь між продуктами, сервісами або підходами (напр., «X працює у 2 рази швидше за Y [Джерело]»)
- Фактичних тверджень про ринкові тенденції, результати досліджень або бенчмарки
- Використовуйте інлайн-цитати у форматі: [Назва джерела] або [Автор, Рік]
- **Голос**: Підтримуйте послідовний тон протягом усього тексту
- **Довжина**: Дотримуйтесь цільової кількості слів
- **Читабельність**: Використовуйте короткі абзаци, маркери де доречно
- **CTA**: Завершуйте чітким закликом до дії або питанням, що провокує думки
## Примітки
- Завжди чекайте затвердження користувача у зазначених контрольних точках
- Зберігайте всі версії чернеток для історії
- Використовуйте веб-пошук для актуальної інформації, коли надані URL
- Якщо ресурсів недостатньо, попросіть користувача надати більше або запропонуйте додаткове дослідження
- Адаптуйте тон відповідно до цільової аудиторії (технічна, загальна, бізнес тощо)
@@ -0,0 +1,67 @@
# [Назва блог-посту]
*[Підзаголовок або слоган — необовʼязково]*
**[Імʼя автора]** | [Дата]
---
[Вступна зачіпка — одразу захопити увагу]
[Контекст та передісторія — чому це важливо]
[Теза — що розкриє цей пост]
---
## [Назва розділу 1]
[Вміст розділу з чіткою, захопливою прозою]
[Включити докази, приклади або дані для підтримки тез]
> «Релевантна цитата з дослідження» — Джерело
[Перехід до наступного розділу]
---
## [Назва розділу 2]
[Продовження основного контенту]
**Ключовий висновок:** [Виділити важливі тези жирним або у виносках]
[Ще підтверджуючий контент]
---
## [Назва розділу 3]
[Додаткові розділи за потреби]
### Підрозділ (за потреби)
[Вміст підрозділу]
---
## Висновок
[Підсумувати розкриті ключові тези]
[Підкріпити головний висновок]
[Заклик до дії або завершальне твердження, що провокує думки]
---
## Список джерел
1. [Назва джерела](#)
2. [Назва джерела](#)
3. [Назва джерела](#)
---
*[Необовʼязково: біографія автора або пропозиція повʼязаних постів]*
@@ -0,0 +1,97 @@
# План блог-посту: [Назва]
## Метаінформація
| Атрибут | Значення |
|---------|----------|
| **Цільова аудиторія** | [Для кого це?] |
| **Тон** | [Формальний/Невимушений/Технічний/Розмовний] |
| **Цільова довжина** | [Діапазон кількості слів] |
| **Головний висновок** | [Одне речення: що мають запамʼятати читачі?] |
| **Ключові слова** | [SEO-ключові слова, якщо релевантно] |
---
## Запропонована структура
### 1. Вступ / Зачіпка
**Варіанти вступної зачіпки:**
- [ ] Питання, що резонує з читачем
- [ ] Вражаюча статистика або факт
- [ ] Коротка історія або сценарій
- [ ] Сміливе твердження
**Встановлення контексту:**
- Необхідна передісторія
- Чому ця тема важлива зараз
**Теза:**
- Чітке твердження про те, що розкриє пост
---
### 2. [Назва розділу]
**Ключові тези:**
- Теза A: [опис]
- Теза B: [опис]
**Підтверджуючі докази:**
- З [джерела]: [релевантні дані/цитата]
**Перехід до наступного розділу:**
- [Як це повʼязується з наступним]
---
### 3. [Назва розділу]
**Ключові тези:**
- Теза A: [опис]
- Теза B: [опис]
**Підтверджуючі докази:**
- З [джерела]: [релевантні дані/цитата]
**Перехід до наступного розділу:**
- [Як це повʼязується з наступним]
---
### 4. [Назва розділу] (додайте більше розділів за потреби)
**Ключові тези:**
- Теза A: [опис]
- Теза B: [опис]
**Підтверджуючі докази:**
- З [джерела]: [релевантні дані/цитата]
---
### 5. Висновок
**Резюме ключових тез:**
- Повторення тези 1
- Повторення тези 2
- Повторення тези 3
**Завершальна думка / Заклик до дії:**
- [Що мають зробити або обміркувати читачі далі?]
---
## Джерела для цитування
1. [Назва джерела](#) — використано для: [яка інформація]
2. [Назва джерела](#) — використано для: [яка інформація]
3. [Назва джерела](#) — використано для: [яка інформація]
---
## Примітки для написання
- [Будь-які конкретні вимоги або обмеження]
- [Що наголосити]
- [Чого уникати]
+72
View File
@@ -0,0 +1,72 @@
---
name: brand-voice-consistency
description: Забезпечення відповідності всіх комунікацій голосу та тону бренду. Використовуйте при створенні маркетингових текстів, клієнтських комунікацій, публічного контенту, або коли користувачі згадують голос бренду, тон чи стиль написання.
---
# Навичка голосу бренду
## Огляд
Ця навичка забезпечує послідовність голосу бренду, тону та повідомлень у всіх комунікаціях.
## Ідентичність бренду
### Місія
Допомогти командам автоматизувати робочі процеси розробки за допомогою AI
### Цінності
- **Простота**: Робити складне простим
- **Надійність**: Непохитне виконання
- **Розширення можливостей**: Дати простір людській креативності
### Тон голосу
- **Дружній, але професійний** — доступний, але не панібратський
- **Зрозумілий і лаконічний** — уникати жаргону, пояснювати технічні концепції просто
- **Впевнений** — ми знаємо, що робимо
- **Емпатичний** — розуміємо потреби та болі користувачів
## Рекомендації щодо написання
### Рекомендовано ✅
- Використовуйте «ви» при зверненні до читачів
- Використовуйте активний стан: «Claude генерує звіти», а не «Звіти генеруються Claude»
- Починайте з ціннісної пропозиції
- Використовуйте конкретні приклади
- Тримайте речення до 20 слів
- Використовуйте списки для ясності
- Включайте заклики до дії
### Не рекомендовано ❌
- Не використовуйте корпоративний жаргон
- Не будьте поблажливими та не надмірно спрощуйте
- Не використовуйте «ми вважаємо» або «ми думаємо»
- Не використовуйте ВСІ ВЕЛИКІ ЛІТЕРИ, крім виділення
- Не створюйте стіни тексту
- Не припускайте наявність технічних знань
## Словник
### ✅ Бажані терміни
- Claude (не «AI Claude»)
- Генерація коду (не «автокодування»)
- Агент (не «бот»)
- Оптимізувати (не «революціонізувати»)
- Інтегрувати (не «синергізувати»)
### ❌ Уникати
- «Передовий» (заїжджено)
- «Проривний» (розмито)
- «Левериджити» (корпоративний жаргон)
- «Утилізувати» (використовуйте «використовувати»)
- «Зміна парадигми» (незрозуміло)
## Приклади
### ✅ Вдалий приклад
«Claude автоматизує ваш процес код-рев'ю. Замість ручної перевірки кожного PR, Claude перевіряє безпеку, продуктивність та якість — заощаджуючи вашій команді години щотижня.»
Чому працює: Зрозуміла цінність, конкретні переваги, орієнтація на дію
### ❌ Невдалий приклад
«Claude левериджить передовий AI для надання комплексних рішень розробки програмного забезпечення.»
Чому не працює: Розмито, корпоративний жаргон, немає конкретної цінності
@@ -0,0 +1,14 @@
Тема: [Чітка, орієнтована на вигоду тема]
Вітаю, [Ім'я]!
[Вступ: Яка цінність для них]
[Основна частина: Як це працює / Що вони отримають]
[Конкретний приклад або вигода]
[Заклик до дії: Чіткий наступний крок]
З повагою,
[Ім'я]
@@ -0,0 +1,4 @@
[Хук: Привернути увагу в першому рядку]
[2-3 рядки: Цінність або цікавий факт]
[Заклик до дії: Посилання, питання або залучення]
[Емодзі: 1-2 максимум для візуального інтересу]
+13
View File
@@ -0,0 +1,13 @@
# Приклади тону бренду
## Захоплива анонс
"Зекономте 8 годин на тиждень на код-рев'ю. Claude переглядає ваші PR автоматично."
## Емпатична підтримка
"Ми знаємо, що деплої можуть бути стресовими. Claude бере тестування на себе, щоб вам не хвилюватися."
## Впевнена презентація продукту
"Claude не просто пропонує код. Він розуміє вашу архітектуру і підтримує консистентність."
## Освітній блог-пост
"Давайте розглянемо, як агенти покращують процеси код-рев'ю. Ось що ми дізналися..."
+212
View File
@@ -0,0 +1,212 @@
---
name: claude-md
description: Створення або оновлення файлів CLAUDE.md відповідно до найкращих практик для оптимального онбордингу AI-агента
---
## Введення користувача
```text
$ARGUMENTS
```
Ви **ПОВИННІ** врахувати введення користувача перед продовженням (якщо не порожнє). Користувач може вказати:
- `create` — створити новий CLAUDE.md з нуля
- `update` — покращити існуючий CLAUDE.md
- `audit` — проаналізувати та звітувати про якість поточного CLAUDE.md
- Конкретний шлях для створення/оновлення (напр., `src/api/CLAUDE.md` для інструкцій, специфічних для каталогу)
## Основні принципи
**LLM не мають стану**: CLAUDE.md — єдиний файл, що автоматично включається в кожну розмову. Він слугує головним документом онбордингу AI-агентів у вашу кодову базу.
### Золоті правила
1. **Менше — краще**: Найсучасніші LLM можуть дотримуватись ~150-200 інструкцій. Системний промпт Claude Code вже використовує ~50. Тримайте CLAUDE.md зосередженим та лаконічним.
2. **Універсальна застосовність**: Включайте лише інформацію, релевантну для КОЖНОЇ сесії. Інструкції для конкретних завдань належать до окремих файлів.
3. **Не використовуйте Claude як лінтер**: Рекомендації зі стилю роздувають контекст та погіршують дотримання інструкцій. Використовуйте натомість детерміністичні інструменти (prettier, eslint тощо).
4. **Ніколи не генеруйте автоматично**: CLAUDE.md — найвпливовіша точка AI-системи. Створюйте його вручну з ретельним обмірковуванням.
## Потік виконання
### 1. Аналіз проєкту
Спочатку проаналізуйте поточний стан проєкту:
1. Перевірити наявні файли CLAUDE.md:
- Кореневий рівень: `./CLAUDE.md` або `.claude/CLAUDE.md`
- Специфічні для каталогу: `**/CLAUDE.md`
- Глобальний конфіг користувача: `~/.claude/CLAUDE.md`
2. Визначити структуру проєкту:
- Технологічний стек (мови, фреймворки)
- Тип проєкту (монорепо, окремий додаток, бібліотека)
- Інструменти розробки (пакетний менеджер, система збірки, тест-раннер)
3. Переглянути існуючу документацію:
- README.md
- CONTRIBUTING.md
- package.json, pyproject.toml, Cargo.toml тощо
### 2. Стратегія контенту (ЩО, ЧОМУ, ЯК)
Структуруйте CLAUDE.md навколо трьох вимірів:
#### ЩО — Технологія та структура
- Огляд технологічного стеку
- Організація проєкту (особливо важливо для монорепо)
- Ключові каталоги та їхнє призначення
#### ЧОМУ — Призначення та контекст
- Що робить проєкт
- Чому були прийняті певні архітектурні рішення
- За що відповідає кожен основний компонент
#### ЯК — Робочий процес та конвенції
- Робочий процес розробки (bun vs node, pip vs uv тощо)
- Процедури та команди тестування
- Методи верифікації та збірки
- Критичні «підводні камені» або неочевидні вимоги
### 3. Стратегія поступового розкриття
Для великих проєктів рекомендуйте створити папку `agent_docs/`:
```
agent_docs/
|- building_the_project.md
|- running_tests.md
|- code_conventions.md
|- architecture_decisions.md
```
У CLAUDE.md посилайтесь на ці файли інструкціями:
```markdown
For detailed build instructions, refer to `agent_docs/building_the_project.md`
```
**Важливо**: Використовуйте посилання `файл:рядок` замість фрагментів коду, щоб уникнути застарілого контексту.
### 4. Обмеження якості
При створенні або оновленні CLAUDE.md:
1. **Цільова довжина**: Менше 300 рядків (ідеально — менше 100)
2. **Без правил стилю**: Видалити будь-які інструкції лінтингу/форматування
3. **Без інструкцій для конкретних завдань**: Перемістити до окремих файлів
4. **Без фрагментів коду**: Використовувати посилання на файли замість цього
5. **Без надлишкової інформації**: Не повторювати те, що є в package.json або README
### 5. Обовʼязкові секції
Добре структурований CLAUDE.md має включати:
```markdown
# Назва проєкту
Короткий однорядковий опис.
## Технологічний стек
- Основна мова та версія
- Ключові фреймворки/бібліотеки
- База даних/сховище (якщо є)
## Структура проєкту
[Лише для монорепо або складних структур]
- `apps/` - Точки входу додатків
- `packages/` - Спільні бібліотеки
## Команди розробки
- Встановлення: `команда`
- Тестування: `команда`
- Збірка: `команда`
## Критичні конвенції
[Лише неочевидні, високовпливові конвенції]
- Конвенція 1 з коротким поясненням
- Конвенція 2 з коротким поясненням
## Відомі проблеми / Підводні камені
[Речі, що постійно створюють труднощі розробникам]
- Проблема 1
- Проблема 2
```
### 6. Антипатерни, яких слід уникати
**НЕ включайте:**
- Рекомендації зі стилю коду (використовуйте лінтери)
- Документацію щодо використання Claude
- Довгі пояснення очевидних патернів
- Скопійовані приклади коду
- Загальні найкращі практики («пишіть чистий код»)
- Інструкції для конкретних завдань
- Автозгенерований контент
- Розлогі списки TODO
### 7. Контрольний список валідації
Перед фіналізацією перевірте:
- [ ] Менше 300 рядків (бажано менше 100)
- [ ] Кожен рядок застосовний до ВСІХ сесій
- [ ] Без правил стилю/форматування
- [ ] Без фрагментів коду (використані посилання на файли)
- [ ] Команди перевірені на працездатність
- [ ] Поступове розкриття використано для складних проєктів
- [ ] Критичні підводні камені задокументовані
- [ ] Немає надлишковості з README.md
## Формат виводу
### Для `create` або за замовчуванням:
1. Проаналізувати проєкт
2. Створити чернетку CLAUDE.md за структурою вище
3. Представити чернетку для перегляду
4. Записати у відповідне місце після затвердження
### Для `update`:
1. Прочитати існуючий CLAUDE.md
2. Аудит за найкращими практиками
3. Визначити:
- Контент для видалення (правила стилю, фрагменти коду, специфічне для завдань)
- Контент для скорочення
- Відсутню важливу інформацію
4. Представити зміни для перегляду
5. Застосувати зміни після затвердження
### Для `audit`:
1. Прочитати існуючий CLAUDE.md
2. Згенерувати звіт з:
- Поточна кількість рядків vs ціль
- Відсоток універсально застосовного контенту
- Список знайдених антипатернів
- Рекомендації для покращення
3. НЕ модифікувати файл, лише звітувати
## Обробка AGENTS.md
Якщо користувач запитує створення/оновлення AGENTS.md:
AGENTS.md використовується для визначення спеціалізованої поведінки агентів. На відміну від CLAUDE.md (який для контексту проєкту), AGENTS.md визначає:
- Кастомні ролі та можливості агентів
- Інструкції та обмеження для конкретних агентів
- Визначення робочих процесів для мультиагентних сценаріїв
Застосовуйте аналогічні принципи:
- Тримайте зосередженим та лаконічним
- Використовуйте поступове розкриття
- Посилайтесь на зовнішні документи замість вбудовування контенту
## Примітки
- Завжди перевіряйте працездатність команд перед їх включенням
- Якщо сумніваєтесь — не включайте; менше — краще
- Системне нагадування повідомляє Claude, що CLAUDE.md «може бути або не бути релевантним» — чим більше шуму, тим більше він ігнорується
- Монорепо найбільше виграють від чіткої структури ЩО/ЧОМУ/ЯК
- Файли CLAUDE.md для конкретних каталогів мають бути ще більш зосередженими
+70
View File
@@ -0,0 +1,70 @@
---
name: code-review-specialist
description: Комплексне код-рев'ю з аналізом безпеки, продуктивності та якості. Використовуйте, коли користувачі просять переглянути код, проаналізувати якість коду, оцінити pull request, або згадують код-рев'ю, аналіз безпеки чи оптимізацію продуктивності.
---
# Навичка код-рев'ю
Ця навичка забезпечує комплексні можливості код-рев'ю з фокусом на:
1. **Аналіз безпеки**
- Проблеми автентифікації/авторизації
- Ризики розкриття даних
- Вразливості інʼєкцій
- Криптографічні слабкості
- Логування чутливих даних
2. **Аналіз продуктивності**
- Ефективність алгоритмів (аналіз Big O)
- Оптимізація памʼяті
- Оптимізація запитів до БД
- Можливості кешування
- Проблеми конкурентності
3. **Якість коду**
- Принципи SOLID
- Патерни проєктування
- Конвенції іменування
- Документація
- Покриття тестами
4. **Супровідність**
- Читабельність коду
- Розмір функцій (має бути < 50 рядків)
- Цикломатична складність
- Управління залежностями
- Безпека типів
## Шаблон рев'ю
Для кожного фрагмента перевіреного коду надати:
### Резюме
- Загальна оцінка якості (1-5)
- Кількість виявлених проблем
- Рекомендовані пріоритетні зони
### Критичні проблеми (якщо є)
- **Проблема**: Чіткий опис
- **Розташування**: Файл і номер рядка
- **Вплив**: Чому це важливо
- **Серйозність**: Критична/Висока/Середня
- **Виправлення**: Приклад коду
### Знахідки за категоріями
#### Безпека (якщо знайдено проблеми)
Перелік вразливостей безпеки з прикладами
#### Продуктивність (якщо знайдено проблеми)
Перелік проблем продуктивності з аналізом складності
#### Якість (якщо знайдено проблеми)
Перелік проблем якості коду з пропозиціями рефакторингу
#### Супровідність (якщо знайдено проблеми)
Перелік проблем супровідності з покращеннями
## Історія версій
- v1.0.0 (2024-12-10): Початковий випуск з аналізом безпеки, продуктивності, якості та супровідності
@@ -0,0 +1,35 @@
#!/usr/bin/env python3
import re
import sys
def analyze_code_metrics(code):
"""Analyze code for common metrics."""
# Count functions
functions = len(re.findall(r"^def\s+\w+", code, re.MULTILINE))
# Count classes
classes = len(re.findall(r"^class\s+\w+", code, re.MULTILINE))
# Average line length
lines = code.split("\n")
avg_length = sum(len(l) for l in lines) / len(lines) if lines else 0
# Estimate complexity
complexity = len(re.findall(r"\b(if|elif|else|for|while|and|or)\b", code))
return {
"functions": functions,
"classes": classes,
"avg_line_length": avg_length,
"complexity_score": complexity,
}
if __name__ == "__main__":
with open(sys.argv[1]) as f:
code = f.read()
metrics = analyze_code_metrics(code)
for key, value in metrics.items():
print(f"{key}: {value:.2f}")
@@ -0,0 +1,174 @@
#!/usr/bin/env python3
"""
Compare cyclomatic complexity of code before and after changes.
Helps identify if refactoring actually simplifies code structure.
"""
import re
import sys
class ComplexityAnalyzer:
"""Analyze code complexity metrics."""
def __init__(self, code: str):
self.code = code
self.lines = code.split("\n")
def calculate_cyclomatic_complexity(self) -> int:
"""
Calculate cyclomatic complexity using McCabe's method.
Count decision points: if, elif, else, for, while, except, and, or
"""
complexity = 1 # Base complexity
# Count decision points
decision_patterns = [
r"\bif\b",
r"\belif\b",
r"\bfor\b",
r"\bwhile\b",
r"\bexcept\b",
r"\band\b(?!$)",
r"\bor\b(?!$)",
]
for pattern in decision_patterns:
matches = re.findall(pattern, self.code)
complexity += len(matches)
return complexity
def calculate_cognitive_complexity(self) -> int:
"""
Calculate cognitive complexity - how hard is it to understand?
Based on nesting depth and control flow.
"""
cognitive = 0
nesting_depth = 0
for line in self.lines:
# Track nesting depth
if re.search(r"^\s*(if|for|while|def|class|try)\b", line):
nesting_depth += 1
cognitive += nesting_depth
elif re.search(r"^\s*(elif|else|except|finally)\b", line):
cognitive += nesting_depth
# Reduce nesting when unindenting
if line and not line[0].isspace():
nesting_depth = 0
return cognitive
def calculate_maintainability_index(self) -> float:
"""
Maintainability Index ranges from 0-100.
> 85: Excellent
> 65: Good
> 50: Fair
< 50: Poor
"""
lines = len(self.lines)
cyclomatic = self.calculate_cyclomatic_complexity()
cognitive = self.calculate_cognitive_complexity()
# Simplified MI calculation
mi = (
171
- 5.2 * (cyclomatic / lines)
- 0.23 * (cognitive)
- 16.2 * (lines / 1000)
)
return max(0, min(100, mi))
def get_complexity_report(self) -> dict:
"""Generate comprehensive complexity report."""
return {
"cyclomatic_complexity": self.calculate_cyclomatic_complexity(),
"cognitive_complexity": self.calculate_cognitive_complexity(),
"maintainability_index": round(self.calculate_maintainability_index(), 2),
"lines_of_code": len(self.lines),
"avg_line_length": round(
sum(len(l) for l in self.lines) / len(self.lines), 2
)
if self.lines
else 0,
}
def compare_files(before_file: str, after_file: str) -> None:
"""Compare complexity metrics between two code versions."""
with open(before_file) as f:
before_code = f.read()
with open(after_file) as f:
after_code = f.read()
before_analyzer = ComplexityAnalyzer(before_code)
after_analyzer = ComplexityAnalyzer(after_code)
before_metrics = before_analyzer.get_complexity_report()
after_metrics = after_analyzer.get_complexity_report()
print("=" * 60)
print("CODE COMPLEXITY COMPARISON")
print("=" * 60)
print("\nBEFORE:")
print(f" Cyclomatic Complexity: {before_metrics['cyclomatic_complexity']}")
print(f" Cognitive Complexity: {before_metrics['cognitive_complexity']}")
print(f" Maintainability Index: {before_metrics['maintainability_index']}")
print(f" Lines of Code: {before_metrics['lines_of_code']}")
print(f" Avg Line Length: {before_metrics['avg_line_length']}")
print("\nAFTER:")
print(f" Cyclomatic Complexity: {after_metrics['cyclomatic_complexity']}")
print(f" Cognitive Complexity: {after_metrics['cognitive_complexity']}")
print(f" Maintainability Index: {after_metrics['maintainability_index']}")
print(f" Lines of Code: {after_metrics['lines_of_code']}")
print(f" Avg Line Length: {after_metrics['avg_line_length']}")
print("\nCHANGES:")
cyclomatic_change = (
after_metrics["cyclomatic_complexity"] - before_metrics["cyclomatic_complexity"]
)
cognitive_change = (
after_metrics["cognitive_complexity"] - before_metrics["cognitive_complexity"]
)
mi_change = (
after_metrics["maintainability_index"] - before_metrics["maintainability_index"]
)
loc_change = after_metrics["lines_of_code"] - before_metrics["lines_of_code"]
print(f" Cyclomatic Complexity: {cyclomatic_change:+d}")
print(f" Cognitive Complexity: {cognitive_change:+d}")
print(f" Maintainability Index: {mi_change:+.2f}")
print(f" Lines of Code: {loc_change:+d}")
print("\nASSESSMENT:")
if mi_change > 0:
print(" ✅ Code is MORE maintainable")
elif mi_change < 0:
print(" ⚠️ Code is LESS maintainable")
else:
print(" ➡️ Maintainability unchanged")
if cyclomatic_change < 0:
print(" ✅ Complexity DECREASED")
elif cyclomatic_change > 0:
print(" ⚠️ Complexity INCREASED")
else:
print(" ➡️ Complexity unchanged")
print("=" * 60)
if __name__ == "__main__":
if len(sys.argv) != 3:
print("Usage: python compare-complexity.py <before_file> <after_file>")
sys.exit(1)
compare_files(sys.argv[1], sys.argv[2])
@@ -0,0 +1,112 @@
# Шаблон знахідки код-рев'ю
Використовуйте цей шаблон для документування кожної знайденої проблеми під час код-рев'ю.
---
## Проблема: [НАЗВА]
### Серйозність
- [ ] Критична (блокує деплой)
- [ ] Висока (потрібно виправити перед мерджем)
- [ ] Середня (потрібно виправити незабаром)
- [ ] Низька (бажано виправити)
### Категорія
- [ ] Безпека
- [ ] Продуктивність
- [ ] Якість коду
- [ ] Підтримуваність
- [ ] Тестування
- [ ] Патерн проєктування
- [ ] Документація
### Розташування
**Файл:** `src/components/UserCard.tsx`
**Рядки:** 45-52
**Функція/Метод:** `renderUserDetails()`
### Опис проблеми
**Що:** Опишіть суть проблеми.
**Чому це важливо:** Поясніть вплив та чому це потрібно виправити.
**Поточна поведінка:** Покажіть проблемний код або поведінку.
**Очікувана поведінка:** Опишіть, що повинно відбуватися замість цього.
### Приклад коду
#### Поточний (проблемний)
```typescript
// Shows the N+1 query problem
const users = fetchUsers();
users.forEach(user => {
const posts = fetchUserPosts(user.id); // Query per user!
renderUserPosts(posts);
});
```
#### Запропоноване виправлення
```typescript
// Optimized with JOIN query
const usersWithPosts = fetchUsersWithPosts();
usersWithPosts.forEach(({ user, posts }) => {
renderUserPosts(posts);
});
```
### Аналіз впливу
| Аспект | Вплив | Серйозність |
|--------|-------|-------------|
| Продуктивність | 100+ запитів для 20 користувачів | Висока |
| Досвід користувача | Повільне завантаження сторінки | Висока |
| Масштабованість | Ламається при масштабуванні | Критична |
| Підтримуваність | Складно дебажити | Середня |
### Пов'язані проблеми
- Аналогічна проблема в `AdminUserList.tsx` рядок 120
- Пов'язаний PR: #456
- Пов'язана issue: #789
### Додаткові ресурси
- [N+1 Query Problem](https://en.wikipedia.org/wiki/N%2B1_problem)
- [Database Join Documentation](https://docs.example.com/joins)
### Нотатки рецензента
- Це поширений патерн у цій кодовій базі
- Варто додати це до гайду зі стилю коду
- Можливо, варто створити допоміжну функцію
### Відповідь автора (для зворотного зв'язку)
*Заповнюється автором коду:*
- [ ] Виправлення реалізовано в коміті: `abc123`
- [ ] Статус виправлення: Завершено / В процесі / Потребує обговорення
- [ ] Питання або зауваження: (опишіть)
---
## Статистика знахідок (для рецензента)
При рев'ю кількох знахідок, відстежуйте:
- **Всього знайдено проблем:** X
- **Критичних:** X
- **Високих:** X
- **Середніх:** X
- **Низьких:** X
**Рекомендація:** ✅ Затвердити / ⚠️ Запросити зміни / 🔄 Потребує обговорення
**Загальна якість коду:** 1-5 зірок
@@ -0,0 +1,47 @@
# Чеклист код-рев'ю
## Чеклист безпеки
- [ ] Немає захардкоджених облікових даних або секретів
- [ ] Валідація введення для всіх даних від користувача
- [ ] Захист від SQL-ін'єкцій (параметризовані запити)
- [ ] CSRF-захист для операцій зі зміною стану
- [ ] Захист від XSS з правильним екрануванням
- [ ] Перевірка автентифікації на захищених ендпоінтах
- [ ] Перевірка авторизації для ресурсів
- [ ] Безпечне хешування паролів (bcrypt, argon2)
- [ ] Немає чутливих даних у логах
- [ ] HTTPS обов'язковий
## Чеклист продуктивності
- [ ] Немає N+1 запитів
- [ ] Правильне використання індексів
- [ ] Кешування реалізовано де доцільно
- [ ] Немає блокуючих операцій в основному потоці
- [ ] Async/await використовується коректно
- [ ] Великі набори даних пагіновані
- [ ] Пул з'єднань до бази даних
- [ ] Регулярні вирази оптимізовані
- [ ] Немає зайвого створення об'єктів
- [ ] Витоки пам'яті запобігаються
## Чеклист якості
- [ ] Функції < 50 рядків
- [ ] Зрозумілі назви змінних
- [ ] Немає дублювання коду
- [ ] Правильна обробка помилок
- [ ] Коментарі пояснюють ЧОМУ, а не ЩО
- [ ] Немає console.log у продакшені
- [ ] Перевірка типів (TypeScript/JSDoc)
- [ ] Принципи SOLID дотримані
- [ ] Патерни проєктування застосовані коректно
- [ ] Самодокументований код
## Чеклист тестування
- [ ] Юніт-тести написані
- [ ] Граничні випадки покриті
- [ ] Сценарії помилок протестовані
- [ ] Інтеграційні тести є
- [ ] Покриття > 80%
- [ ] Немає нестабільних тестів
- [ ] Зовнішні залежності замоковані
- [ ] Зрозумілі назви тестів
+76
View File
@@ -0,0 +1,76 @@
---
name: api-documentation-generator
description: Генерація вичерпної, точної документації API з вихідного коду. Використовуйте при створенні або оновленні документації API, генерації специфікацій OpenAPI, або коли користувачі згадують документацію API, ендпоінти чи документацію.
---
# Навичка генерації документації API
## Генерує
- Специфікації OpenAPI/Swagger
- Документацію ендпоінтів API
- Приклади використання SDK
- Посібники з інтеграції
- Довідники кодів помилок
- Посібники з автентифікації
## Структура документації
### Для кожного ендпоінту
```markdown
## GET /api/v1/users/:id
### Опис
Короткий опис призначення цього ендпоінту
### Параметри
| Назва | Тип | Обовʼязковий | Опис |
|-------|-----|-------------|------|
| id | string | Так | ID користувача |
### Відповідь
**200 Успіх**
```json
{
"id": "usr_123",
"name": "John Doe",
"email": "john@example.com",
"created_at": "2025-01-15T10:30:00Z"
}
```
**404 Не знайдено**
```json
{
"error": "USER_NOT_FOUND",
"message": "Користувач не існує"
}
```
### Приклади
**cURL**
```bash
curl -X GET "https://api.example.com/api/v1/users/usr_123" \
-H "Authorization: Bearer YOUR_TOKEN"
```
**JavaScript**
```javascript
const user = await fetch('/api/v1/users/usr_123', {
headers: { 'Authorization': 'Bearer token' }
}).then(r => r.json());
```
**Python**
```python
response = requests.get(
'https://api.example.com/api/v1/users/usr_123',
headers={'Authorization': 'Bearer token'}
)
user = response.json()
```
```
@@ -0,0 +1,55 @@
#!/usr/bin/env python3
import ast
class APIDocExtractor(ast.NodeVisitor):
"""Extract API documentation from Python source code."""
def __init__(self):
self.endpoints = []
def visit_FunctionDef(self, node):
"""Extract function documentation."""
if node.name.startswith("get_") or node.name.startswith("post_"):
doc = ast.get_docstring(node)
endpoint = {
"name": node.name,
"docstring": doc,
"params": [arg.arg for arg in node.args.args],
"returns": self._extract_return_type(node),
}
self.endpoints.append(endpoint)
self.generic_visit(node)
def _extract_return_type(self, node):
"""Extract return type from function annotation."""
if node.returns:
return ast.unparse(node.returns)
return "Any"
def generate_markdown_docs(endpoints: list[dict]) -> str:
"""Generate markdown documentation from endpoints."""
docs = "# API Documentation\n\n"
for endpoint in endpoints:
docs += f"## {endpoint['name']}\n\n"
docs += f"{endpoint['docstring']}\n\n"
docs += f"**Parameters**: {', '.join(endpoint['params'])}\n\n"
docs += f"**Returns**: {endpoint['returns']}\n\n"
docs += "---\n\n"
return docs
if __name__ == "__main__":
import sys
with open(sys.argv[1]) as f:
tree = ast.parse(f.read())
extractor = APIDocExtractor()
extractor.visit(tree)
markdown = generate_markdown_docs(extractor.endpoints)
print(markdown)
+426
View File
@@ -0,0 +1,426 @@
---
name: code-refactor
description: Систематичний рефакторинг коду на основі методології Мартіна Фаулера. Використовуйте, коли користувачі просять рефакторити код, покращити структуру коду, зменшити технічний борг, очистити застарілий код, усунути запахи коду (code smells) або покращити супровідність коду. Ця навичка проводить через поетапний підхід з дослідженням, плануванням та безпечною інкрементальною реалізацією.
---
# Навичка рефакторингу коду
Систематичний підхід до рефакторингу коду на основі книги Мартіна Фаулера *Refactoring: Improving the Design of Existing Code* (2-ге видання). Ця навичка наголошує на безпечних, інкрементальних змінах, підкріплених тестами.
> «Рефакторинг — це процес зміни програмної системи таким чином, що не змінює зовнішню поведінку коду, але покращує його внутрішню структуру.» — Мартін Фаулер
## Основні принципи
1. **Збереження поведінки**: Зовнішня поведінка повинна залишатися незмінною
2. **Малі кроки**: Робити крихітні, тестовані зміни
3. **Тест-орієнтованість**: Тести — це страхувальна сітка
4. **Безперервність**: Рефакторинг — постійний процес, а не одноразова подія
5. **Співпраця**: Затвердження користувача потрібне на кожній фазі
## Огляд робочого процесу
```
Фаза 1: Дослідження та аналіз
Фаза 2: Оцінка покриття тестами
Фаза 3: Виявлення запахів коду
Фаза 4: Створення плану рефакторингу
Фаза 5: Інкрементальна реалізація
Фаза 6: Перегляд та ітерація
```
---
## Фаза 1: Дослідження та аналіз
### Цілі
- Зрозуміти структуру та призначення кодової бази
- Визначити обсяг рефакторингу
- Зібрати контекст про бізнес-вимоги
### Запитання до користувача
Перед початком уточніть:
1. **Обсяг**: Які файли/модулі/функції потребують рефакторингу?
2. **Цілі**: Які проблеми ви намагаєтесь вирішити? (читабельність, продуктивність, супровідність)
3. **Обмеження**: Чи є зони, які НЕ слід змінювати?
4. **Тиск термінів**: Чи блокує це іншу роботу?
5. **Стан тестів**: Чи існують тести? Чи проходять вони?
### Дії
- [ ] Прочитати та зрозуміти цільовий код
- [ ] Виявити залежності та інтеграції
- [ ] Задокументувати поточну архітектуру
- [ ] Зафіксувати існуючі маркери технічного боргу (TODOs, FIXMEs)
### Вивід
Представити знахідки користувачу:
- Резюме структури коду
- Виявлені проблемні зони
- Початкові рекомендації
- **Запросити затвердження для продовження**
---
## Фаза 2: Оцінка покриття тестами
### Чому тести важливі
> «Рефакторинг без тестів — як їзда без пасків безпеки.» — Мартін Фаулер
Тести — **ключовий засіб** безпечного рефакторингу. Без них ви ризикуєте внести помилки.
### Кроки оцінки
1. **Перевірити наявні тести**
```bash
# Пошук файлів тестів
find . -name "*test*" -o -name "*spec*" | head -20
```
2. **Запустити існуючі тести**
```bash
# JavaScript/TypeScript
npm test
# Python
pytest -v
# Java
mvn test
```
3. **Перевірити покриття (якщо доступно)**
```bash
# JavaScript
npm run test:coverage
# Python
pytest --cov=.
```
### Точка рішення: Запитати користувача
**Якщо тести існують та проходять:**
- Перейти до Фази 3
**Якщо тести відсутні або неповні:**
Представити варіанти:
1. Спочатку написати тести (рекомендовано)
2. Додавати тести інкрементально під час рефакторингу
3. Продовжити без тестів (ризиковано — потребує підтвердження користувача)
**Якщо тести не проходять:**
- ЗУПИНИТИСЯ. Виправити тести перед рефакторингом
- Запитати користувача: Чи слід спочатку виправити тести?
### Рекомендації щодо написання тестів (якщо потрібно)
Для кожної функції, що рефакториться, забезпечити тести для:
- Успішний шлях (нормальна робота)
- Граничні випадки (порожні введення, null, межі)
- Сценарії помилок (невалідні введення, виключення)
Використовуйте цикл «red-green-refactor»:
1. Написати тест, що не проходить (red)
2. Зробити так, щоб пройшов (green)
3. Рефакторити
---
## Фаза 3: Виявлення запахів коду
### Що таке запахи коду?
Симптоми глибших проблем у коді. Це не помилки, а індикатори того, що код можна покращити.
### Типові запахи коду для перевірки
Див. [references/code-smells.md](references/code-smells.md) для повного каталогу.
#### Короткий довідник
| Запах | Ознаки | Вплив |
|-------|--------|-------|
| **Довгий метод** | Методи > 30-50 рядків | Важко зрозуміти, тестувати, супроводжувати |
| **Дубльований код** | Та сама логіка в кількох місцях | Виправлення помилок потрібне в кількох місцях |
| **Великий клас** | Клас з занадто багатьма відповідальностями | Порушує принцип єдиної відповідальності |
| **Заздрість до функцій** | Метод використовує дані іншого класу більше | Погана інкапсуляція |
| **Одержимість примітивами** | Надмірне використання примітивів замість обʼєктів | Відсутні доменні концепції |
| **Довгий список параметрів** | Методи з 4+ параметрами | Складно викликати правильно |
| **Групи даних** | Ті самі елементи даних зʼявляються разом | Відсутня абстракція |
| **Оператори Switch** | Складні ланцюжки switch/if-else | Важко розширювати |
| **Спекулятивна загальність** | Код «на всякий випадок» | Зайва складність |
| **Мертвий код** | Невикористаний код | Плутанина, тягар супровідності |
### Кроки аналізу
1. **Автоматичний аналіз** (якщо скрипти доступні)
```bash
python scripts/detect-smells.py <file>
```
2. **Ручний перегляд**
- Систематично пройти код
- Зафіксувати кожен запах з розташуванням та серйозністю
- Категоризувати за впливом (Критичний/Високий/Середній/Низький)
3. **Пріоритезація**
Зосередитися на запахах, які:
- Блокують поточну розробку
- Спричиняють помилки або плутанину
- Впливають на найчастіше змінювані шляхи коду
### Вивід: Звіт про запахи
Представити користувачу:
- Список виявлених запахів з розташуванням
- Оцінку серйозності для кожного
- Рекомендований порядок пріоритету
- **Запросити затвердження пріоритетів**
---
## Фаза 4: Створення плану рефакторингу
### Вибір рефакторингів
Для кожного запаху обрати відповідний рефакторинг з каталогу.
Див. [references/refactoring-catalog.md](references/refactoring-catalog.md) для повного списку.
#### Відповідність запахів рефакторингам
| Запах коду | Рекомендований рефакторинг |
|------------|---------------------------|
| Long Method | Extract Method, Replace Temp with Query |
| Duplicated Code | Extract Method, Pull Up Method, Form Template Method |
| Large Class | Extract Class, Extract Subclass |
| Feature Envy | Move Method, Move Field |
| Primitive Obsession | Replace Primitive with Object, Replace Type Code with Class |
| Long Parameter List | Introduce Parameter Object, Preserve Whole Object |
| Data Clumps | Extract Class, Introduce Parameter Object |
| Switch Statements | Replace Conditional with Polymorphism |
| Speculative Generality | Collapse Hierarchy, Inline Class, Remove Dead Code |
| Dead Code | Remove Dead Code |
### Структура плану
Використовуйте шаблон [templates/refactoring-plan.md](templates/refactoring-plan.md).
Для кожного рефакторингу:
1. **Ціль**: Який код зміниться
2. **Запах**: Яку проблему вирішує
3. **Рефакторинг**: Яку техніку застосувати
4. **Кроки**: Детальні мікрокроки
5. **Ризики**: Що може піти не так
6. **Відкат**: Як скасувати за потреби
### Поетапний підхід
**КРИТИЧНО**: Впроваджуйте рефакторинг поступово, фазами.
**Фаза A: Швидкі перемоги** (Низький ризик, висока цінність)
- Перейменування змінних для ясності
- Витяг очевидного дубльованого коду
- Видалення мертвого коду
**Фаза B: Структурні покращення** (Середній ризик)
- Витяг методів з довгих функцій
- Введення обʼєктів параметрів
- Переміщення методів до відповідних класів
**Фаза C: Архітектурні зміни** (Вищий ризик)
- Заміна умовних конструкцій поліморфізмом
- Витяг класів
- Введення патернів проєктування
### Точка рішення: Представити план користувачу
Перед реалізацією:
- Показати повний план рефакторингу
- Пояснити кожну фазу та її ризики
- Отримати явне затвердження для кожної фази
- **Запитати**: «Чи продовжити з Фазою A?»
---
## Фаза 5: Інкрементальна реалізація
### Золоте правило
> «Зміна → Тест → Зелений? → Коміт → Наступний крок»
### Ритм реалізації
Для кожного кроку рефакторингу:
1. **Попередня перевірка**
- Тести проходять (зелені)
- Код компілюється
2. **Зробити ОДНУ малу зміну**
- Дотримуватися механіки з каталогу
- Тримати зміни мінімальними
3. **Верифікація**
- Негайно запустити тести
- Перевірити на помилки компіляції
4. **Якщо тести проходять (зелені)**
- Закомітити з описовим повідомленням
- Перейти до наступного кроку
5. **Якщо тести не проходять (червоні)**
- ЗУПИНИТИСЯ негайно
- Скасувати зміну
- Проаналізувати, що пішло не так
- Запитати користувача, якщо незрозуміло
### Стратегія комітів
Кожен коміт має бути:
- **Атомарний**: Одна логічна зміна
- **Оборотний**: Легко відкатити
- **Описовий**: Зрозуміле повідомлення коміту
Приклади повідомлень комітів:
```
refactor: Extract calculateTotal() from processOrder()
refactor: Rename 'x' to 'customerCount' for clarity
refactor: Remove unused validateOldFormat() method
```
### Звіт про прогрес
Після кожної підфази звітувати користувачу:
- Внесені зміни
- Тести досі проходять?
- Виявлені проблеми
- **Запитати**: «Продовжити з наступною порцією?»
---
## Фаза 6: Перегляд та ітерація
### Контрольний список після рефакторингу
- [ ] Усі тести проходять
- [ ] Немає нових попереджень/помилок
- [ ] Код успішно компілюється
- [ ] Поведінка не змінилася (ручна верифікація)
- [ ] Документація оновлена за потреби
- [ ] Історія комітів чиста
### Порівняння метрик
Запустити аналіз складності до і після:
```bash
python scripts/analyze-complexity.py <file>
```
Представити покращення:
- Зміна кількості рядків коду
- Зміна цикломатичної складності
- Зміна індексу супровідності
### Перегляд користувачем
Представити фінальні результати:
- Резюме всіх змін
- Порівняння коду до/після
- Покращення метрик
- Залишковий технічний борг
- **Запитати**: «Чи задоволені ви цими змінами?»
### Наступні кроки
Обговорити з користувачем:
- Додаткові запахи для усунення?
- Запланувати подальший рефакторинг?
- Застосувати аналогічні зміни в інших місцях?
---
## Важливі рекомендації
### Коли ЗУПИНИТИСЯ та запитати
Завжди паузу та консультацію з користувачем, коли:
- Невпевненість щодо бізнес-логіки
- Зміна може вплинути на зовнішні API
- Покриття тестами недостатнє
- Потрібне значне архітектурне рішення
- Рівень ризику зростає
- Зустрічаєте неочікувану складність
### Правила безпеки
1. **Ніколи не рефакторити без тестів** (якщо користувач явно не підтвердив ризик)
2. **Ніколи не робити великих змін** — розбивати на крихітні кроки
3. **Ніколи не пропускати запуск тестів** після кожної зміни
4. **Ніколи не продовжувати, якщо тести не проходять** — виправити або відкатити
5. **Ніколи не припускати** — якщо сумніваєтесь, запитайте
### Чого НЕ робити
- Не поєднуйте рефакторинг з додаванням функцій
- Не рефакторте під час аварій на продакшні
- Не рефакторте код, який не розумієте
- Не переускладнюйте — тримайте просто
- Не рефакторте все одразу
---
## Приклад швидкого старту
### Сценарій: Довгий метод з дублюванням
**До:**
```javascript
function processOrder(order) {
// 150 рядків коду з:
// - Дубльованою логікою валідації
// - Інлайн-обчисленнями
// - Змішаними відповідальностями
}
```
**Кроки рефакторингу:**
1. **Переконатися, що тести існують** для processOrder()
2. **Витягти** валідацію у validateOrder()
3. **Тест** — має пройти
4. **Витягти** обчислення у calculateOrderTotal()
5. **Тест** — має пройти
6. **Витягти** сповіщення у notifyCustomer()
7. **Тест** — має пройти
8. **Перегляд** — processOrder() тепер оркеструє 3 чіткі функції
**Після:**
```javascript
function processOrder(order) {
validateOrder(order);
const total = calculateOrderTotal(order);
notifyCustomer(order, total);
return { order, total };
}
```
---
## Довідники
- [Каталог запахів коду](references/code-smells.md) — повний список запахів коду
- [Каталог рефакторингів](references/refactoring-catalog.md) — техніки рефакторингу
- [Шаблон плану рефакторингу](templates/refactoring-plan.md) — шаблон планування
## Скрипти
- `scripts/analyze-complexity.py` — аналіз метрик складності коду
- `scripts/detect-smells.py` — автоматичне виявлення запахів
## Історія версій
- v1.0.0 (2025-01-15): Початковий випуск з методологією Фаулера, поетапним підходом, точками консультації з користувачем
@@ -0,0 +1,669 @@
# Каталог запахів коду
Комплексний довідник запахів коду на основі книги Мартіна Фаулера *Refactoring* (2-ге видання). Запахи коду — це симптоми глибших проблем; вони вказують на те, що щось може бути не так з дизайном вашого коду.
> «Запах коду — це поверхнева ознака, яка зазвичай відповідає глибшій проблемі в системі.» — Мартін Фаулер
---
## Роздуті елементи (Bloaters)
Запахи коду, що представляють щось, що розрослося занадто великим для ефективної роботи.
### Long Method (Довгий метод)
**Ознаки:**
- Метод перевищує 30-50 рядків
- Потрібно прокручувати, щоб побачити весь метод
- Кілька рівнів вкладеності
- Коментарі пояснюють, що роблять секції
**Чому це погано:**
- Важко зрозуміти
- Складно тестувати ізольовано
- Зміни мають непередбачувані наслідки
- Дубльована логіка ховається всередині
**Рефакторинги:**
- Extract Method
- Replace Temp with Query
- Introduce Parameter Object
- Replace Method with Method Object
- Decompose Conditional
**Приклад (до):**
```javascript
function processOrder(order) {
// Валідація замовлення (20 рядків)
if (!order.items) throw new Error('No items');
if (order.items.length === 0) throw new Error('Empty order');
// ... ще валідація
// Обчислення підсумків (30 рядків)
let subtotal = 0;
for (const item of order.items) {
subtotal += item.price * item.quantity;
}
// ... податок, доставка, знижки
// Надсилання сповіщень (20 рядків)
// ... логіка email
}
```
**Приклад (після):**
```javascript
function processOrder(order) {
validateOrder(order);
const totals = calculateOrderTotals(order);
sendOrderNotifications(order, totals);
return { order, totals };
}
```
---
### Large Class (Великий клас)
**Ознаки:**
- Клас має багато полів екземпляра (>7-10)
- Клас має багато методів (>15-20)
- Назва класу розмита (Manager, Handler, Processor)
- Методи не використовують усі поля екземпляра
**Чому це погано:**
- Порушує принцип єдиної відповідальності
- Важко тестувати
- Зміни поширюються на неповʼязані функції
- Складно повторно використовувати частини
**Рефакторинги:**
- Extract Class
- Extract Subclass
- Extract Interface
**Виявлення:**
```
Рядків коду > 300
Кількість методів > 15
Кількість полів > 10
```
---
### Primitive Obsession (Одержимість примітивами)
**Ознаки:**
- Використання примітивів для доменних концепцій (string для email, int для грошей)
- Масиви примітивів замість обʼєктів
- Рядкові константи для кодів типів
- Магічні числа/рядки
**Чому це погано:**
- Немає валідації на рівні типу
- Логіка розкидана по кодовій базі
- Легко передати неправильні значення
- Відсутні доменні концепції
**Рефакторинги:**
- Replace Primitive with Object
- Replace Type Code with Class
- Replace Type Code with Subclasses
- Replace Type Code with State/Strategy
**Приклад (до):**
```javascript
const user = {
email: 'john@example.com', // Просто рядок
phone: '1234567890', // Просто рядок
status: 'active', // Магічний рядок
balance: 10050 // Копійки як ціле число
};
```
**Приклад (після):**
```javascript
const user = {
email: new Email('john@example.com'),
phone: new PhoneNumber('1234567890'),
status: UserStatus.ACTIVE,
balance: Money.cents(10050)
};
```
---
### Long Parameter List (Довгий список параметрів)
**Ознаки:**
- Методи з 4+ параметрами
- Параметри, що завжди зʼявляються разом
- Булеві прапорці, що змінюють поведінку методу
- Часте передавання null/undefined
**Чому це погано:**
- Важко викликати правильно
- Плутанина з порядком параметрів
- Вказує, що метод робить занадто багато
- Важко додавати нові параметри
**Рефакторинги:**
- Introduce Parameter Object
- Preserve Whole Object
- Replace Parameter with Method Call
- Remove Flag Argument
**Приклад (до):**
```javascript
function createUser(firstName, lastName, email, phone,
street, city, state, zip,
isAdmin, isActive, createdBy) {
// ...
}
```
**Приклад (після):**
```javascript
function createUser(personalInfo, address, options) {
// personalInfo: { firstName, lastName, email, phone }
// address: { street, city, state, zip }
// options: { isAdmin, isActive, createdBy }
}
```
---
### Data Clumps (Групи даних)
**Ознаки:**
- Ті самі 3+ поля зʼявляються разом повторно
- Параметри, що завжди подорожують разом
- Класи з підмножинами полів, що належать один одному
**Чому це погано:**
- Дубльована логіка обробки
- Відсутня абстракція
- Важче розширювати
- Вказує на прихований клас
**Рефакторинги:**
- Extract Class
- Introduce Parameter Object
- Preserve Whole Object
**Приклад:**
```javascript
// Група даних: координати (x, y, z)
function movePoint(x, y, z, dx, dy, dz) { }
function scalePoint(x, y, z, factor) { }
function distanceBetween(x1, y1, z1, x2, y2, z2) { }
// Витяг класу Point3D
class Point3D {
constructor(x, y, z) { }
move(delta) { }
scale(factor) { }
distanceTo(other) { }
}
```
---
## Зловживання обʼєктною орієнтацією (OO Abusers)
Запахи, що вказують на неповне або некоректне використання принципів ООП.
### Switch Statements (Оператори Switch)
**Ознаки:**
- Довгі ланцюжки switch/case або if/else
- Той самий switch у кількох місцях
- Switch за кодами типів
- Додавання нових випадків вимагає змін всюди
**Чому це погано:**
- Порушує принцип відкритості/закритості
- Зміни поширюються на всі місця з switch
- Важко розширювати
- Часто вказує на відсутній поліморфізм
**Рефакторинги:**
- Replace Conditional with Polymorphism
- Replace Type Code with Subclasses
- Replace Type Code with State/Strategy
**Приклад (до):**
```javascript
function calculatePay(employee) {
switch (employee.type) {
case 'hourly':
return employee.hours * employee.rate;
case 'salaried':
return employee.salary / 12;
case 'commissioned':
return employee.sales * employee.commission;
}
}
```
**Приклад (після):**
```javascript
class HourlyEmployee {
calculatePay() {
return this.hours * this.rate;
}
}
class SalariedEmployee {
calculatePay() {
return this.salary / 12;
}
}
```
---
### Temporary Field (Тимчасове поле)
**Ознаки:**
- Поля екземпляра, що використовуються лише в деяких методах
- Поля, що встановлюються умовно
- Складна ініціалізація для певних випадків
**Чому це погано:**
- Плутанина — поле існує, але може бути null
- Важко зрозуміти стан обʼєкта
- Вказує на приховану умовну логіку
**Рефакторинги:**
- Extract Class
- Introduce Null Object
- Replace Temp Field with Local
---
### Refused Bequest (Відхилена спадщина)
**Ознаки:**
- Підклас не використовує успадковані методи/дані
- Підклас перевизначає, щоб нічого не робити
- Успадкування використовується для повторного використання коду, а не для відношення IS-A
**Чому це погано:**
- Неправильна абстракція
- Порушує принцип підстановки Лісков
- Оманлива ієрархія
**Рефакторинги:**
- Push Down Method/Field
- Replace Subclass with Delegate
- Replace Inheritance with Delegation
---
### Alternative Classes with Different Interfaces (Альтернативні класи з різними інтерфейсами)
**Ознаки:**
- Два класи, що роблять схожі речі
- Різні назви методів для тієї самої концепції
- Можуть використовуватися взаємозамінно
**Чому це погано:**
- Дубльовані реалізації
- Немає спільного інтерфейсу
- Важко перемикатися між ними
**Рефакторинги:**
- Rename Method
- Move Method
- Extract Superclass
- Extract Interface
---
## Перешкоди для змін (Change Preventers)
Запахи, що ускладнюють зміни — зміна однієї речі вимагає зміни багатьох інших.
### Divergent Change (Дивергентна зміна)
**Ознаки:**
- Один клас змінюється з кількох різних причин
- Зміни в різних областях запускають редагування того самого класу
- Клас є «God-класом»
**Чому це погано:**
- Порушує принцип єдиної відповідальності
- Висока частота змін
- Конфлікти злиття
**Рефакторинги:**
- Extract Class
- Extract Superclass
- Extract Subclass
**Приклад:**
Клас `User` змінюється через:
- Зміни автентифікації
- Зміни профілю
- Зміни білінгу
- Зміни сповіщень
→ Витягти: `AuthService`, `ProfileService`, `BillingService`, `NotificationService`
---
### Shotgun Surgery (Хірургія дробовиком)
**Ознаки:**
- Одна зміна вимагає редагування в багатьох класах
- Мала функція потребує правок у 10+ файлах
- Зміни розкидані, важко знайти всі
**Чому це погано:**
- Легко пропустити місце
- Високий звʼязок (coupling)
- Зміни схильні до помилок
**Рефакторинги:**
- Move Method
- Move Field
- Inline Class
**Виявлення:**
Шукайте: додавання одного поля вимагає змін у >5 файлах.
---
### Parallel Inheritance Hierarchies (Паралельні ієрархії успадкування)
**Ознаки:**
- Створення підкласу в одній ієрархії вимагає підкласу в іншій
- Префікси класів збігаються (напр., `DatabaseOrder`, `DatabaseProduct`)
**Чому це погано:**
- Подвійне обслуговування
- Звʼязок між ієрархіями
- Легко забути одну сторону
**Рефакторинги:**
- Move Method
- Move Field
- Усунути одну ієрархію
---
## Непотрібне (Dispensables)
Щось непотрібне, що слід видалити.
### Comments (Надмірні коментарі)
**Ознаки:**
- Коментарі, що пояснюють, що робить код
- Закоментований код
- TODO/FIXME, що залишаються назавжди
- Вибачення в коментарях
**Чому це погано:**
- Коментарі брешуть (розсинхронізуються)
- Код має бути самодокументованим
- Мертвий код створює плутанину
**Рефакторинги:**
- Extract Method (назва пояснює що)
- Rename (ясність без коментарів)
- Видалити закоментований код
- Introduce Assertion
**Хороші vs погані коментарі:**
```javascript
// ПОГАНО: Пояснює що
// Цикл по користувачах і перевірка чи активні
for (const user of users) {
if (user.status === 'active') { }
}
// ДОБРЕ: Пояснює чому
// Лише активні — неактивні обробляються задачею очищення
const activeUsers = users.filter(u => u.isActive);
```
---
### Duplicate Code (Дубльований код)
**Ознаки:**
- Той самий код у кількох місцях
- Схожий код з малими варіаціями
- Патерни копі-пасту
**Чому це погано:**
- Виправлення помилок потрібне в кількох місцях
- Ризик неконсистентності
- Роздута кодова база
**Рефакторинги:**
- Extract Method
- Extract Class
- Pull Up Method (в ієрархіях)
- Form Template Method
**Правило виявлення:**
Будь-який код, дубльований 3+ разів, слід витягти.
---
### Lazy Class (Ледачий клас)
**Ознаки:**
- Клас не робить достатньо для виправдання свого існування
- Обгортка без доданої цінності
- Результат надмірної інженерії
**Чому це погано:**
- Накладні витрати обслуговування
- Непотрібна непрямість
- Складність без користі
**Рефакторинги:**
- Inline Class
- Collapse Hierarchy
---
### Dead Code (Мертвий код)
**Ознаки:**
- Недосяжний код
- Невикористані змінні/методи/класи
- Закоментований код
- Код за неможливими умовами
**Чому це погано:**
- Плутанина
- Тягар обслуговування
- Уповільнює розуміння
**Рефакторинги:**
- Remove Dead Code
- Safe Delete
**Виявлення:**
```bash
# Шукати невикористані експорти
# Шукати невикористані функції
# Попередження IDE "unused"
```
---
### Speculative Generality (Спекулятивна загальність)
**Ознаки:**
- Абстрактні класи з одним підкласом
- Невикористані параметри «на майбутнє»
- Методи, що лише делегують
- «Фреймворк» для одного випадку
**Чому це погано:**
- Складність без користі
- YAGNI (You Ain't Gonna Need It — Вам це не знадобиться)
- Важче зрозуміти
**Рефакторинги:**
- Collapse Hierarchy
- Inline Class
- Remove Parameter
- Rename Method
---
## Звʼязувачі (Couplers)
Запахи, що представляють надмірний звʼязок між класами.
### Feature Envy (Заздрість до функцій)
**Ознаки:**
- Метод використовує більше даних іншого класу, ніж свого
- Багато викликів геттерів іншого обʼєкта
- Дані та поведінка розділені
**Чому це погано:**
- Неправильне розташування поведінки
- Погана інкапсуляція
- Важко супроводжувати
**Рефакторинги:**
- Move Method
- Move Field
- Extract Method (потім перемістити)
**Приклад (до):**
```javascript
class Order {
getDiscountedPrice(customer) {
// Інтенсивно використовує дані customer
if (customer.loyaltyYears > 5) {
return this.price * customer.discountRate;
}
return this.price;
}
}
```
**Приклад (після):**
```javascript
class Customer {
getDiscountedPriceFor(price) {
if (this.loyaltyYears > 5) {
return price * this.discountRate;
}
return price;
}
}
```
---
### Inappropriate Intimacy (Недоречна інтимність)
**Ознаки:**
- Класи отримують доступ до приватних частин один одного
- Двосторонні посилання
- Підкласи знають занадто багато про батьків
**Чому це погано:**
- Високий звʼязок
- Зміни каскадуються
- Важко модифікувати один без іншого
**Рефакторинги:**
- Move Method
- Move Field
- Change Bidirectional to Unidirectional
- Extract Class
- Hide Delegate
---
### Message Chains (Ланцюжки повідомлень)
**Ознаки:**
- Довгі ланцюжки викликів: `a.getB().getC().getD().getValue()`
- Клієнт залежить від структури навігації
- Код типу «потяг-катастрофа» (train wreck)
**Чому це погано:**
- Крихкий — будь-яка зміна ламає ланцюжок
- Порушує Закон Деметри
- Звʼязок зі структурою
**Рефакторинги:**
- Hide Delegate
- Extract Method
- Move Method
**Приклад:**
```javascript
// Погано: Ланцюжок повідомлень
const managerName = employee.getDepartment().getManager().getName();
// Краще: Приховати делегування
const managerName = employee.getManagerName();
```
---
### Middle Man (Посередник)
**Ознаки:**
- Клас, що лише делегує іншому
- Половина методів — делегування
- Немає доданої цінності
**Чому це погано:**
- Непотрібна непрямість
- Накладні витрати обслуговування
- Заплутана архітектура
**Рефакторинги:**
- Remove Middle Man
- Inline Method
---
## Посібник серйозності запахів
| Серйозність | Опис | Дія |
|-------------|------|-----|
| **Критичний** | Блокує розробку, спричиняє помилки | Виправити негайно |
| **Високий** | Значний тягар обслуговування | Виправити в поточному спринті |
| **Середній** | Помітний, але керований | Запланувати на найближче майбутнє |
| **Низький** | Незначна незручність | Виправляти при нагоді |
---
## Контрольний список швидкого виявлення
Використовуйте цей список при скануванні коду:
- [ ] Є методи > 30 рядків?
- [ ] Є класи > 300 рядків?
- [ ] Є методи з > 4 параметрами?
- [ ] Є дубльовані блоки коду?
- [ ] Є switch/case за кодами типів?
- [ ] Є невикористаний код?
- [ ] Є методи, що інтенсивно використовують дані іншого класу?
- [ ] Є довгі ланцюжки викликів?
- [ ] Є коментарі, що пояснюють «що», а не «чому»?
- [ ] Є примітиви, що мають бути обʼєктами?
---
## Додаткове читання
- Fowler, M. (2018). *Refactoring: Improving the Design of Existing Code* (2nd ed.)
- Kerievsky, J. (2004). *Refactoring to Patterns*
- Feathers, M. (2004). *Working Effectively with Legacy Code*
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,545 @@
#!/usr/bin/env python3
"""
Code Complexity Analyzer
Analyzes code complexity metrics for Python, JavaScript, and TypeScript files.
Helps measure the impact of refactoring by comparing before/after metrics.
Usage:
python analyze-complexity.py <file>
python analyze-complexity.py <before_file> <after_file> # Compare mode
python analyze-complexity.py --dir <directory> # Analyze directory
Metrics:
- Cyclomatic Complexity: Decision points in code
- Cognitive Complexity: How hard is it to understand
- Maintainability Index: Overall maintainability score (0-100)
- Lines of Code: Total lines
- Function Count: Number of functions/methods
- Average Function Length: Lines per function
"""
import argparse
import os
import re
import sys
from dataclasses import dataclass
from pathlib import Path
from typing import Dict, List, Optional
@dataclass
class FunctionMetrics:
"""Metrics for a single function."""
name: str
start_line: int
end_line: int
lines: int
cyclomatic_complexity: int
cognitive_complexity: int
parameter_count: int
@dataclass
class FileMetrics:
"""Metrics for a file."""
filename: str
lines_of_code: int
blank_lines: int
comment_lines: int
function_count: int
class_count: int
cyclomatic_complexity: int
cognitive_complexity: int
maintainability_index: float
avg_function_length: float
max_function_length: int
functions: List[FunctionMetrics]
class ComplexityAnalyzer:
"""Analyze code complexity for multiple languages."""
# Patterns for different languages
PATTERNS = {
'python': {
'function': r'^\s*def\s+(\w+)\s*\(',
'class': r'^\s*class\s+(\w+)',
'decision': [r'\bif\b', r'\belif\b', r'\bfor\b', r'\bwhile\b',
r'\bexcept\b', r'\band\b(?!$)', r'\bor\b(?!$)',
r'\bcase\b', r'\btry\b'],
'comment': r'^\s*#',
'multiline_comment_start': r'^\s*["\'][\"\'][\"\']',
'multiline_comment_end': r'["\'][\"\'][\"\']',
},
'javascript': {
'function': r'(?:function\s+(\w+)|(\w+)\s*[=:]\s*(?:async\s+)?(?:function|\([^)]*\)\s*=>))',
'class': r'class\s+(\w+)',
'decision': [r'\bif\b', r'\belse\s+if\b', r'\bfor\b', r'\bwhile\b',
r'\bcatch\b', r'\b\?\b', r'\b&&\b', r'\b\|\|\b',
r'\bcase\b', r'\btry\b'],
'comment': r'^\s*//',
'multiline_comment_start': r'/\*',
'multiline_comment_end': r'\*/',
},
'typescript': {
'function': r'(?:function\s+(\w+)|(\w+)\s*[=:]\s*(?:async\s+)?(?:function|\([^)]*\)\s*=>))',
'class': r'class\s+(\w+)',
'decision': [r'\bif\b', r'\belse\s+if\b', r'\bfor\b', r'\bwhile\b',
r'\bcatch\b', r'\b\?\b', r'\b&&\b', r'\b\|\|\b',
r'\bcase\b', r'\btry\b'],
'comment': r'^\s*//',
'multiline_comment_start': r'/\*',
'multiline_comment_end': r'\*/',
}
}
def __init__(self, filepath: str):
self.filepath = filepath
self.filename = os.path.basename(filepath)
self.language = self._detect_language()
self.patterns = self.PATTERNS.get(self.language, self.PATTERNS['python'])
with open(filepath, 'r', encoding='utf-8', errors='ignore') as f:
self.code = f.read()
self.lines = self.code.split('\n')
def _detect_language(self) -> str:
"""Detect programming language from file extension."""
ext = os.path.splitext(self.filepath)[1].lower()
ext_map = {
'.py': 'python',
'.js': 'javascript',
'.jsx': 'javascript',
'.ts': 'typescript',
'.tsx': 'typescript',
}
return ext_map.get(ext, 'python')
def calculate_cyclomatic_complexity(self, code: Optional[str] = None) -> int:
"""
Calculate cyclomatic complexity using McCabe's method.
CC = E - N + 2P where E=edges, N=nodes, P=connected components
Simplified: Count decision points + 1
"""
if code is None:
code = self.code
complexity = 1 # Base complexity
for pattern in self.patterns['decision']:
matches = re.findall(pattern, code)
complexity += len(matches)
return complexity
def calculate_cognitive_complexity(self, code: Optional[str] = None) -> int:
"""
Calculate cognitive complexity.
Measures how hard it is to understand the code.
Accounts for nesting depth and control flow breaks.
"""
if code is None:
code = self.code
lines = code.split('\n')
cognitive = 0
nesting_depth = 0
in_function = False
for line in lines:
stripped = line.strip()
# Track function boundaries
if re.search(self.patterns['function'], line):
in_function = True
nesting_depth = 0
# Increment for control flow structures
if re.search(r'\b(if|for|while|switch)\b', stripped):
nesting_depth += 1
cognitive += nesting_depth # Nested structures cost more
elif re.search(r'\b(elif|else if|else|catch|finally)\b', stripped):
cognitive += nesting_depth # Same level as parent
# Track nesting through braces/indentation
if self.language in ['javascript', 'typescript']:
nesting_depth += stripped.count('{') - stripped.count('}')
nesting_depth = max(0, nesting_depth)
# Bonus for breaks in linear flow
if re.search(r'\b(break|continue|return|throw)\b', stripped):
if nesting_depth > 1:
cognitive += 1
# Bonus for recursion
# (simplified: just look for function calling itself)
return cognitive
def calculate_maintainability_index(self) -> float:
"""
Calculate Maintainability Index (0-100).
Based on Halstead Volume, Cyclomatic Complexity, and Lines of Code.
MI = max(0, (171 - 5.2*ln(V) - 0.23*CC - 16.2*ln(LOC)) * 100/171)
Interpretation:
- 85-100: Highly maintainable
- 65-84: Moderately maintainable
- 50-64: Difficult to maintain
- 0-49: Very difficult to maintain
"""
import math
loc = len([l for l in self.lines if l.strip()])
cc = self.calculate_cyclomatic_complexity()
# Simplified Halstead Volume approximation
# Count unique operators and operands
operators = len(re.findall(r'[+\-*/%=<>!&|^~]', self.code))
operands = len(re.findall(r'\b\w+\b', self.code))
volume = (operators + operands) * math.log2(max(1, operators + operands))
# Calculate MI
mi = 171 - 5.2 * math.log(max(1, volume)) - 0.23 * cc - 16.2 * math.log(max(1, loc))
mi = max(0, min(100, mi * 100 / 171))
return round(mi, 2)
def count_lines(self) -> Dict[str, int]:
"""Count different types of lines."""
total = len(self.lines)
blank = 0
comment = 0
in_multiline_comment = False
for line in self.lines:
stripped = line.strip()
# Check for multiline comments
if re.search(self.patterns['multiline_comment_start'], stripped):
in_multiline_comment = True
if re.search(self.patterns['multiline_comment_end'], stripped):
in_multiline_comment = False
comment += 1
continue
if in_multiline_comment:
comment += 1
elif not stripped:
blank += 1
elif re.match(self.patterns['comment'], stripped):
comment += 1
return {
'total': total,
'blank': blank,
'comment': comment,
'code': total - blank - comment
}
def find_functions(self) -> List[FunctionMetrics]:
"""Find all functions and calculate their individual metrics."""
functions = []
current_function = None
function_start = 0
brace_depth = 0
for i, line in enumerate(self.lines):
# Check for function definition
match = re.search(self.patterns['function'], line)
if match:
# Save previous function if exists
if current_function:
func_code = '\n'.join(self.lines[function_start:i])
functions.append(self._create_function_metrics(
current_function, function_start, i - 1, func_code
))
current_function = match.group(1) or match.group(2) if match.lastindex and match.lastindex > 1 else match.group(1)
function_start = i
brace_depth = 0
# Track braces for JS/TS
if self.language in ['javascript', 'typescript']:
brace_depth += line.count('{') - line.count('}')
# Don't forget the last function
if current_function:
func_code = '\n'.join(self.lines[function_start:])
functions.append(self._create_function_metrics(
current_function, function_start, len(self.lines) - 1, func_code
))
return functions
def _create_function_metrics(self, name: str, start: int, end: int, code: str) -> FunctionMetrics:
"""Create metrics for a single function."""
lines = end - start + 1
# Count parameters (simplified)
param_match = re.search(r'\(([^)]*)\)', code.split('\n')[0])
param_count = 0
if param_match and param_match.group(1).strip():
param_count = len([p for p in param_match.group(1).split(',') if p.strip()])
return FunctionMetrics(
name=name,
start_line=start + 1,
end_line=end + 1,
lines=lines,
cyclomatic_complexity=self.calculate_cyclomatic_complexity(code),
cognitive_complexity=self.calculate_cognitive_complexity(code),
parameter_count=param_count
)
def analyze(self) -> FileMetrics:
"""Perform complete analysis of the file."""
line_counts = self.count_lines()
functions = self.find_functions()
# Count classes
class_count = len(re.findall(self.patterns['class'], self.code))
# Calculate averages
func_lengths = [f.lines for f in functions] if functions else [0]
avg_func_length = sum(func_lengths) / len(func_lengths)
max_func_length = max(func_lengths)
return FileMetrics(
filename=self.filename,
lines_of_code=line_counts['code'],
blank_lines=line_counts['blank'],
comment_lines=line_counts['comment'],
function_count=len(functions),
class_count=class_count,
cyclomatic_complexity=self.calculate_cyclomatic_complexity(),
cognitive_complexity=self.calculate_cognitive_complexity(),
maintainability_index=self.calculate_maintainability_index(),
avg_function_length=round(avg_func_length, 1),
max_function_length=max_func_length,
functions=functions
)
def print_metrics(metrics: FileMetrics, verbose: bool = False) -> None:
"""Print metrics in a readable format."""
print("=" * 60)
print(f"CODE COMPLEXITY ANALYSIS: {metrics.filename}")
print("=" * 60)
print("\n📊 OVERVIEW")
print("-" * 40)
print(f" Lines of Code: {metrics.lines_of_code}")
print(f" Blank Lines: {metrics.blank_lines}")
print(f" Comment Lines: {metrics.comment_lines}")
print(f" Functions/Methods: {metrics.function_count}")
print(f" Classes: {metrics.class_count}")
print("\n📈 COMPLEXITY METRICS")
print("-" * 40)
print(f" Cyclomatic Complexity: {metrics.cyclomatic_complexity}")
print(f" Cognitive Complexity: {metrics.cognitive_complexity}")
print(f" Maintainability Index: {metrics.maintainability_index}")
# Interpret maintainability
mi = metrics.maintainability_index
if mi >= 85:
mi_label = "Highly maintainable ✅"
elif mi >= 65:
mi_label = "Moderately maintainable 🔶"
elif mi >= 50:
mi_label = "Difficult to maintain ⚠️"
else:
mi_label = "Very difficult to maintain ❌"
print(f"{mi_label}")
print("\n📐 FUNCTION METRICS")
print("-" * 40)
print(f" Avg Function Length: {metrics.avg_function_length} lines")
print(f" Max Function Length: {metrics.max_function_length} lines")
if verbose and metrics.functions:
print("\n📋 FUNCTION DETAILS")
print("-" * 40)
for f in sorted(metrics.functions, key=lambda x: x.cyclomatic_complexity, reverse=True):
flag = " ⚠️" if f.cyclomatic_complexity > 10 or f.lines > 50 else ""
print(f" {f.name}() [lines {f.start_line}-{f.end_line}]{flag}")
print(f" - Lines: {f.lines}, CC: {f.cyclomatic_complexity}, "
f"Cognitive: {f.cognitive_complexity}, Params: {f.parameter_count}")
print("\n" + "=" * 60)
def print_comparison(before: FileMetrics, after: FileMetrics) -> None:
"""Print comparison between two analyses."""
print("=" * 70)
print("CODE COMPLEXITY COMPARISON")
print("=" * 70)
print(f"\n{'Metric':<30} {'Before':<15} {'After':<15} {'Change':<10}")
print("-" * 70)
def fmt_change(before_val, after_val, lower_is_better=True):
diff = after_val - before_val
if lower_is_better:
symbol = "" if diff < 0 else ("⚠️" if diff > 0 else "")
else:
symbol = "" if diff > 0 else ("⚠️" if diff < 0 else "")
return f"{diff:+.1f} {symbol}" if isinstance(diff, float) else f"{diff:+d} {symbol}"
metrics = [
("Lines of Code", before.lines_of_code, after.lines_of_code, True),
("Function Count", before.function_count, after.function_count, False),
("Class Count", before.class_count, after.class_count, False),
("Cyclomatic Complexity", before.cyclomatic_complexity, after.cyclomatic_complexity, True),
("Cognitive Complexity", before.cognitive_complexity, after.cognitive_complexity, True),
("Maintainability Index", before.maintainability_index, after.maintainability_index, False),
("Avg Function Length", before.avg_function_length, after.avg_function_length, True),
("Max Function Length", before.max_function_length, after.max_function_length, True),
]
for name, b_val, a_val, lower_better in metrics:
change = fmt_change(b_val, a_val, lower_better)
print(f"{name:<30} {b_val:<15} {a_val:<15} {change:<10}")
print("\n" + "=" * 70)
# Overall assessment
print("\n🎯 ASSESSMENT")
print("-" * 40)
improvements = 0
regressions = 0
if after.maintainability_index > before.maintainability_index:
print(" ✅ Maintainability improved")
improvements += 1
elif after.maintainability_index < before.maintainability_index:
print(" ⚠️ Maintainability decreased")
regressions += 1
if after.cyclomatic_complexity < before.cyclomatic_complexity:
print(" ✅ Complexity reduced")
improvements += 1
elif after.cyclomatic_complexity > before.cyclomatic_complexity:
print(" ⚠️ Complexity increased")
regressions += 1
if after.avg_function_length < before.avg_function_length:
print(" ✅ Functions are smaller on average")
improvements += 1
elif after.avg_function_length > before.avg_function_length:
print(" ⚠️ Functions grew larger on average")
regressions += 1
print(f"\n Summary: {improvements} improvements, {regressions} regressions")
print("=" * 70)
def analyze_directory(directory: str, verbose: bool = False) -> None:
"""Analyze all supported files in a directory."""
supported_extensions = ['.py', '.js', '.jsx', '.ts', '.tsx']
files = []
for root, _, filenames in os.walk(directory):
for filename in filenames:
if any(filename.endswith(ext) for ext in supported_extensions):
files.append(os.path.join(root, filename))
if not files:
print(f"No supported files found in {directory}")
return
print(f"Analyzing {len(files)} files in {directory}...\n")
total_loc = 0
total_cc = 0
total_functions = 0
all_metrics = []
for filepath in sorted(files):
try:
analyzer = ComplexityAnalyzer(filepath)
metrics = analyzer.analyze()
all_metrics.append(metrics)
total_loc += metrics.lines_of_code
total_cc += metrics.cyclomatic_complexity
total_functions += metrics.function_count
if verbose:
print_metrics(metrics, verbose=True)
else:
flag = " ⚠️" if metrics.maintainability_index < 65 else ""
print(f" {metrics.filename}: LOC={metrics.lines_of_code}, "
f"CC={metrics.cyclomatic_complexity}, MI={metrics.maintainability_index}{flag}")
except Exception as e:
print(f" Error analyzing {filepath}: {e}")
print("\n" + "=" * 60)
print("SUMMARY")
print("=" * 60)
print(f" Files analyzed: {len(all_metrics)}")
print(f" Total lines of code: {total_loc}")
print(f" Total complexity: {total_cc}")
print(f" Total functions: {total_functions}")
if all_metrics:
avg_mi = sum(m.maintainability_index for m in all_metrics) / len(all_metrics)
print(f" Avg maintainability: {avg_mi:.1f}")
def main():
parser = argparse.ArgumentParser(
description='Analyze code complexity metrics',
formatter_class=argparse.RawDescriptionHelpFormatter,
epilog="""
Examples:
%(prog)s myfile.py Analyze single file
%(prog)s before.py after.py Compare two versions
%(prog)s --dir src/ Analyze directory
%(prog)s -v myfile.py Verbose output with function details
"""
)
parser.add_argument('files', nargs='*', help='File(s) to analyze')
parser.add_argument('--dir', '-d', help='Directory to analyze')
parser.add_argument('--verbose', '-v', action='store_true', help='Show detailed function metrics')
parser.add_argument('--json', '-j', action='store_true', help='Output as JSON')
args = parser.parse_args()
if args.dir:
analyze_directory(args.dir, args.verbose)
elif len(args.files) == 1:
analyzer = ComplexityAnalyzer(args.files[0])
metrics = analyzer.analyze()
if args.json:
import json
print(json.dumps({
'filename': metrics.filename,
'lines_of_code': metrics.lines_of_code,
'cyclomatic_complexity': metrics.cyclomatic_complexity,
'cognitive_complexity': metrics.cognitive_complexity,
'maintainability_index': metrics.maintainability_index,
'function_count': metrics.function_count,
'avg_function_length': metrics.avg_function_length,
}, indent=2))
else:
print_metrics(metrics, args.verbose)
elif len(args.files) == 2:
before_analyzer = ComplexityAnalyzer(args.files[0])
after_analyzer = ComplexityAnalyzer(args.files[1])
before_metrics = before_analyzer.analyze()
after_metrics = after_analyzer.analyze()
print_comparison(before_metrics, after_metrics)
else:
parser.print_help()
sys.exit(1)
if __name__ == '__main__':
main()
@@ -0,0 +1,711 @@
#!/usr/bin/env python3
"""
Code Smell Detector
Detects common code smells in Python, JavaScript, and TypeScript files.
Based on Martin Fowler's catalog of code smells.
Usage:
python detect-smells.py <file>
python detect-smells.py --dir <directory>
python detect-smells.py -v <file> # Verbose with code snippets
Detects:
- Long Method (>30 lines)
- Long Parameter List (>4 params)
- Duplicate Code (similar code blocks)
- Large Class (>300 lines, >10 methods)
- Dead Code (unused variables/functions)
- Complex Conditionals (deep nesting, long chains)
- Magic Numbers/Strings
- Feature Envy (methods using other class data heavily)
- Comments explaining what (not why)
"""
import argparse
import os
import re
import sys
from dataclasses import dataclass, field
from enum import Enum
from typing import Dict, List, Optional, Set, Tuple
from collections import defaultdict
class SmellSeverity(Enum):
"""Severity levels for code smells."""
LOW = "Low"
MEDIUM = "Medium"
HIGH = "High"
CRITICAL = "Critical"
class SmellType(Enum):
"""Types of code smells."""
LONG_METHOD = "Long Method"
LONG_PARAMETER_LIST = "Long Parameter List"
DUPLICATE_CODE = "Duplicate Code"
LARGE_CLASS = "Large Class"
DEAD_CODE = "Dead Code"
COMPLEX_CONDITIONAL = "Complex Conditional"
MAGIC_NUMBER = "Magic Number/String"
FEATURE_ENVY = "Feature Envy"
EXCESSIVE_COMMENTS = "Excessive Comments"
DEEPLY_NESTED = "Deeply Nested Code"
PRIMITIVE_OBSESSION = "Primitive Obsession"
DATA_CLUMPS = "Data Clumps"
SWITCH_STATEMENT = "Switch Statement"
MESSAGE_CHAIN = "Message Chain"
@dataclass
class CodeSmell:
"""Represents a detected code smell."""
smell_type: SmellType
severity: SmellSeverity
location: str
line_start: int
line_end: int
description: str
suggestion: str
code_snippet: str = ""
@dataclass
class SmellReport:
"""Report of all smells found in a file."""
filename: str
smells: List[CodeSmell] = field(default_factory=list)
@property
def critical_count(self) -> int:
return sum(1 for s in self.smells if s.severity == SmellSeverity.CRITICAL)
@property
def high_count(self) -> int:
return sum(1 for s in self.smells if s.severity == SmellSeverity.HIGH)
@property
def medium_count(self) -> int:
return sum(1 for s in self.smells if s.severity == SmellSeverity.MEDIUM)
@property
def low_count(self) -> int:
return sum(1 for s in self.smells if s.severity == SmellSeverity.LOW)
class SmellDetector:
"""Detect code smells in source files."""
# Thresholds (configurable)
THRESHOLDS = {
'long_method_lines': 30,
'very_long_method_lines': 50,
'max_parameters': 4,
'large_class_lines': 300,
'large_class_methods': 10,
'max_nesting_depth': 4,
'long_chain_length': 3,
'duplicate_min_lines': 5,
}
def __init__(self, filepath: str):
self.filepath = filepath
self.filename = os.path.basename(filepath)
self.language = self._detect_language()
with open(filepath, 'r', encoding='utf-8', errors='ignore') as f:
self.code = f.read()
self.lines = self.code.split('\n')
self.smells: List[CodeSmell] = []
def _detect_language(self) -> str:
"""Detect programming language from file extension."""
ext = os.path.splitext(self.filepath)[1].lower()
ext_map = {
'.py': 'python',
'.js': 'javascript',
'.jsx': 'javascript',
'.ts': 'typescript',
'.tsx': 'typescript',
}
return ext_map.get(ext, 'python')
def detect_all(self) -> SmellReport:
"""Run all smell detectors."""
self._detect_long_methods()
self._detect_long_parameter_lists()
self._detect_large_class()
self._detect_complex_conditionals()
self._detect_magic_numbers()
self._detect_excessive_comments()
self._detect_deeply_nested()
self._detect_switch_statements()
self._detect_message_chains()
self._detect_duplicate_code()
self._detect_dead_code()
return SmellReport(filename=self.filename, smells=self.smells)
def _get_snippet(self, start: int, end: int, context: int = 2) -> str:
"""Get code snippet with context."""
actual_start = max(0, start - context)
actual_end = min(len(self.lines), end + context)
snippet_lines = []
for i in range(actual_start, actual_end):
prefix = "" if start <= i < end else " "
snippet_lines.append(f"{i+1:4d} {prefix}{self.lines[i]}")
return '\n'.join(snippet_lines)
def _detect_long_methods(self) -> None:
"""Detect methods that are too long."""
if self.language == 'python':
pattern = r'^\s*def\s+(\w+)\s*\([^)]*\):'
else:
pattern = r'(?:function\s+(\w+)|(\w+)\s*[=:]\s*(?:async\s+)?(?:function|\([^)]*\)\s*=>))'
current_method = None
method_start = 0
brace_depth = 0
indent_level = 0
for i, line in enumerate(self.lines):
match = re.search(pattern, line)
if match:
# Check previous method if exists
if current_method:
method_lines = i - method_start
self._check_method_length(current_method, method_start, i - 1, method_lines)
current_method = match.group(1) or (match.group(2) if match.lastindex and match.lastindex > 1 else None)
method_start = i
indent_level = len(line) - len(line.lstrip())
# Track end of Python functions by indentation
if self.language == 'python' and current_method:
if line.strip() and not line.strip().startswith('#'):
current_indent = len(line) - len(line.lstrip())
if current_indent <= indent_level and i > method_start:
method_lines = i - method_start
self._check_method_length(current_method, method_start, i - 1, method_lines)
current_method = None
# Check last method
if current_method:
method_lines = len(self.lines) - method_start
self._check_method_length(current_method, method_start, len(self.lines) - 1, method_lines)
def _check_method_length(self, name: str, start: int, end: int, lines: int) -> None:
"""Check if method is too long and add smell if so."""
if lines > self.THRESHOLDS['very_long_method_lines']:
severity = SmellSeverity.HIGH
desc = f"Method '{name}' is {lines} lines (threshold: {self.THRESHOLDS['long_method_lines']})"
elif lines > self.THRESHOLDS['long_method_lines']:
severity = SmellSeverity.MEDIUM
desc = f"Method '{name}' is {lines} lines (threshold: {self.THRESHOLDS['long_method_lines']})"
else:
return
self.smells.append(CodeSmell(
smell_type=SmellType.LONG_METHOD,
severity=severity,
location=f"{self.filename}:{start+1}-{end+1}",
line_start=start + 1,
line_end=end + 1,
description=desc,
suggestion="Apply Extract Method to break down into smaller functions",
code_snippet=self._get_snippet(start, min(start + 5, end), 0)
))
def _detect_long_parameter_lists(self) -> None:
"""Detect functions with too many parameters."""
if self.language == 'python':
pattern = r'def\s+(\w+)\s*\(([^)]*)\)'
else:
pattern = r'(?:function\s+(\w+)\s*\(([^)]*)\)|(\w+)\s*[=:]\s*(?:async\s+)?(?:function\s*)?\(([^)]*)\))'
for i, line in enumerate(self.lines):
match = re.search(pattern, line)
if match:
# Safely extract groups
groups = match.groups()
func_name = groups[0] or (groups[2] if len(groups) > 2 else None)
params_str = groups[1] if len(groups) > 1 else ""
if not params_str and len(groups) > 3:
params_str = groups[3] or ""
# Count parameters
if params_str.strip():
params = [p.strip() for p in params_str.split(',') if p.strip()]
# Filter out 'self', 'cls' for Python
if self.language == 'python':
params = [p for p in params if p not in ('self', 'cls')]
param_count = len(params)
if param_count > self.THRESHOLDS['max_parameters']:
severity = SmellSeverity.HIGH if param_count > 6 else SmellSeverity.MEDIUM
self.smells.append(CodeSmell(
smell_type=SmellType.LONG_PARAMETER_LIST,
severity=severity,
location=f"{self.filename}:{i+1}",
line_start=i + 1,
line_end=i + 1,
description=f"Function '{func_name}' has {param_count} parameters (max: {self.THRESHOLDS['max_parameters']})",
suggestion="Consider Introduce Parameter Object or Preserve Whole Object",
code_snippet=self._get_snippet(i, i + 1, 1)
))
def _detect_large_class(self) -> None:
"""Detect classes that are too large."""
if self.language == 'python':
class_pattern = r'^\s*class\s+(\w+)'
method_pattern = r'^\s+def\s+\w+'
else:
class_pattern = r'class\s+(\w+)'
method_pattern = r'(?:^\s+\w+\s*\([^)]*\)\s*\{|^\s+(?:async\s+)?\w+\s*=)'
current_class = None
class_start = 0
method_count = 0
class_indent = 0
for i, line in enumerate(self.lines):
class_match = re.search(class_pattern, line)
if class_match:
# Check previous class
if current_class:
self._check_class_size(current_class, class_start, i - 1, method_count)
current_class = class_match.group(1)
class_start = i
method_count = 0
class_indent = len(line) - len(line.lstrip())
# Count methods in current class
if current_class and re.search(method_pattern, line):
method_count += 1
# Check last class
if current_class:
self._check_class_size(current_class, class_start, len(self.lines) - 1, method_count)
def _check_class_size(self, name: str, start: int, end: int, methods: int) -> None:
"""Check if class is too large."""
lines = end - start + 1
issues = []
severity = SmellSeverity.MEDIUM
if lines > self.THRESHOLDS['large_class_lines']:
issues.append(f"{lines} lines (max: {self.THRESHOLDS['large_class_lines']})")
severity = SmellSeverity.HIGH
if methods > self.THRESHOLDS['large_class_methods']:
issues.append(f"{methods} methods (max: {self.THRESHOLDS['large_class_methods']})")
if severity != SmellSeverity.HIGH:
severity = SmellSeverity.MEDIUM
if issues:
self.smells.append(CodeSmell(
smell_type=SmellType.LARGE_CLASS,
severity=severity,
location=f"{self.filename}:{start+1}-{end+1}",
line_start=start + 1,
line_end=end + 1,
description=f"Class '{name}' is too large: {', '.join(issues)}",
suggestion="Apply Extract Class to split responsibilities",
code_snippet=self._get_snippet(start, start + 3, 0)
))
def _detect_complex_conditionals(self) -> None:
"""Detect complex conditional expressions."""
for i, line in enumerate(self.lines):
# Count logical operators in line
and_or_count = len(re.findall(r'\b(and|or|&&|\|\|)\b', line))
if and_or_count >= 3:
self.smells.append(CodeSmell(
smell_type=SmellType.COMPLEX_CONDITIONAL,
severity=SmellSeverity.MEDIUM,
location=f"{self.filename}:{i+1}",
line_start=i + 1,
line_end=i + 1,
description=f"Complex conditional with {and_or_count} logical operators",
suggestion="Apply Decompose Conditional or Consolidate Conditional Expression",
code_snippet=self._get_snippet(i, i + 1, 1)
))
def _detect_magic_numbers(self) -> None:
"""Detect magic numbers and strings."""
# Skip common acceptable values
acceptable = {'0', '1', '-1', '2', '100', 'true', 'false', 'null', 'None', '""', "''"}
for i, line in enumerate(self.lines):
# Skip comments and imports
stripped = line.strip()
if stripped.startswith('#') or stripped.startswith('//') or \
stripped.startswith('import') or stripped.startswith('from'):
continue
# Find numeric literals (excluding in variable names)
numbers = re.findall(r'(?<![a-zA-Z_])\b(\d+\.?\d*)\b(?![a-zA-Z_])', line)
for num in numbers:
if num not in acceptable and float(num) > 2:
# Check if it's likely a magic number (in calculation or comparison)
if re.search(rf'[<>=+\-*/]\s*{re.escape(num)}|{re.escape(num)}\s*[<>=+\-*/]', line):
self.smells.append(CodeSmell(
smell_type=SmellType.MAGIC_NUMBER,
severity=SmellSeverity.LOW,
location=f"{self.filename}:{i+1}",
line_start=i + 1,
line_end=i + 1,
description=f"Magic number '{num}' - consider using a named constant",
suggestion="Replace magic number with named constant",
code_snippet=self._get_snippet(i, i + 1, 0)
))
break # One magic number per line is enough
def _detect_excessive_comments(self) -> None:
"""Detect comments that explain 'what' instead of 'why'."""
what_patterns = [
r'#\s*(set|get|return|loop|iterate|check|if|increment|decrement)',
r'//\s*(set|get|return|loop|iterate|check|if|increment|decrement)',
]
for i, line in enumerate(self.lines):
for pattern in what_patterns:
if re.search(pattern, line, re.IGNORECASE):
self.smells.append(CodeSmell(
smell_type=SmellType.EXCESSIVE_COMMENTS,
severity=SmellSeverity.LOW,
location=f"{self.filename}:{i+1}",
line_start=i + 1,
line_end=i + 1,
description="Comment explains 'what' not 'why' - consider renaming or removing",
suggestion="Use Extract Method with descriptive name instead of comment",
code_snippet=self._get_snippet(i, i + 1, 0)
))
break
def _detect_deeply_nested(self) -> None:
"""Detect deeply nested code blocks."""
max_depth = 0
current_depth = 0
depth_start = 0
for i, line in enumerate(self.lines):
if self.language == 'python':
# Count by indentation
if line.strip():
indent = len(line) - len(line.lstrip())
depth = indent // 4 # Assume 4-space indent
if depth > current_depth:
if depth > max_depth:
max_depth = depth
if depth >= self.THRESHOLDS['max_nesting_depth']:
depth_start = i
current_depth = depth
else:
# Count braces
current_depth += line.count('{') - line.count('}')
if current_depth > max_depth:
max_depth = current_depth
if current_depth >= self.THRESHOLDS['max_nesting_depth']:
depth_start = i
if max_depth >= self.THRESHOLDS['max_nesting_depth']:
self.smells.append(CodeSmell(
smell_type=SmellType.DEEPLY_NESTED,
severity=SmellSeverity.HIGH if max_depth > 5 else SmellSeverity.MEDIUM,
location=f"{self.filename}:{depth_start+1}",
line_start=depth_start + 1,
line_end=depth_start + 1,
description=f"Code nested {max_depth} levels deep (max: {self.THRESHOLDS['max_nesting_depth']})",
suggestion="Apply Replace Nested Conditional with Guard Clauses or Extract Method",
code_snippet=self._get_snippet(depth_start, depth_start + 5, 0)
))
def _detect_switch_statements(self) -> None:
"""Detect switch statements that might need polymorphism."""
if self.language == 'python':
# Python 3.10+ match statements or if/elif chains
pattern = r'^\s*(if|elif).*==.*:'
consecutive_conditions = 0
chain_start = 0
for i, line in enumerate(self.lines):
if re.search(pattern, line):
if consecutive_conditions == 0:
chain_start = i
consecutive_conditions += 1
else:
if consecutive_conditions >= 4:
self._add_switch_smell(chain_start, i - 1, consecutive_conditions)
consecutive_conditions = 0
else:
# JavaScript/TypeScript switch
pattern = r'\bswitch\s*\('
for i, line in enumerate(self.lines):
if re.search(pattern, line):
# Count cases
case_count = 0
for j in range(i, min(i + 50, len(self.lines))):
case_count += len(re.findall(r'\bcase\b', self.lines[j]))
if case_count >= 4:
self._add_switch_smell(i, i + 1, case_count)
def _add_switch_smell(self, start: int, end: int, cases: int) -> None:
"""Add a switch statement smell."""
self.smells.append(CodeSmell(
smell_type=SmellType.SWITCH_STATEMENT,
severity=SmellSeverity.MEDIUM,
location=f"{self.filename}:{start+1}",
line_start=start + 1,
line_end=end + 1,
description=f"Switch/case statement with {cases} cases - consider polymorphism",
suggestion="Apply Replace Conditional with Polymorphism",
code_snippet=self._get_snippet(start, start + 5, 0)
))
def _detect_message_chains(self) -> None:
"""Detect long method chains (train wrecks)."""
chain_pattern = r'(\w+(?:\.\w+\([^)]*\)){3,})'
for i, line in enumerate(self.lines):
matches = re.findall(chain_pattern, line)
for match in matches:
chain_length = match.count('.')
if chain_length >= self.THRESHOLDS['long_chain_length']:
self.smells.append(CodeSmell(
smell_type=SmellType.MESSAGE_CHAIN,
severity=SmellSeverity.MEDIUM,
location=f"{self.filename}:{i+1}",
line_start=i + 1,
line_end=i + 1,
description=f"Message chain with {chain_length} calls - violates Law of Demeter",
suggestion="Apply Hide Delegate to reduce coupling",
code_snippet=self._get_snippet(i, i + 1, 0)
))
def _detect_duplicate_code(self) -> None:
"""Detect potential duplicate code blocks (simplified)."""
# Create line hashes for comparison
line_hashes: Dict[str, List[int]] = defaultdict(list)
for i, line in enumerate(self.lines):
normalized = re.sub(r'\s+', ' ', line.strip())
if len(normalized) > 20: # Only significant lines
line_hashes[normalized].append(i)
# Find duplicates
for normalized, positions in line_hashes.items():
if len(positions) >= 3: # At least 3 occurrences
self.smells.append(CodeSmell(
smell_type=SmellType.DUPLICATE_CODE,
severity=SmellSeverity.MEDIUM,
location=f"{self.filename}:{positions[0]+1}",
line_start=positions[0] + 1,
line_end=positions[0] + 1,
description=f"Potential duplicate code found {len(positions)} times",
suggestion="Apply Extract Method to eliminate duplication",
code_snippet=self._get_snippet(positions[0], positions[0] + 1, 0)
))
def _detect_dead_code(self) -> None:
"""Detect potentially dead code (simplified)."""
# Look for common dead code patterns
patterns = [
(r'^\s*#.*TODO.*delete', "TODO to delete"),
(r'^\s*#.*FIXME.*remove', "FIXME to remove"),
(r'^\s*//.*TODO.*delete', "TODO to delete"),
(r'^\s*//.*FIXME.*remove', "FIXME to remove"),
(r'^\s*if\s+False:', "Code behind 'if False'"),
(r'^\s*if\s*\(\s*false\s*\)', "Code behind 'if (false)'"),
]
for i, line in enumerate(self.lines):
for pattern, desc in patterns:
if re.search(pattern, line, re.IGNORECASE):
self.smells.append(CodeSmell(
smell_type=SmellType.DEAD_CODE,
severity=SmellSeverity.LOW,
location=f"{self.filename}:{i+1}",
line_start=i + 1,
line_end=i + 1,
description=f"Potential dead code: {desc}",
suggestion="Remove dead code",
code_snippet=self._get_snippet(i, i + 1, 0)
))
def print_report(report: SmellReport, verbose: bool = False) -> None:
"""Print smell report in readable format."""
print("=" * 70)
print(f"CODE SMELL DETECTION REPORT: {report.filename}")
print("=" * 70)
print(f"\n📊 SUMMARY")
print("-" * 40)
print(f" Total smells found: {len(report.smells)}")
print(f" Critical: {report.critical_count}")
print(f" High: {report.high_count}")
print(f" Medium: {report.medium_count}")
print(f" Low: {report.low_count}")
if not report.smells:
print("\n✅ No code smells detected!")
print("=" * 70)
return
# Group by type
by_type: Dict[SmellType, List[CodeSmell]] = defaultdict(list)
for smell in report.smells:
by_type[smell.smell_type].append(smell)
print(f"\n📋 FINDINGS BY TYPE")
print("-" * 40)
for smell_type, smells in sorted(by_type.items(), key=lambda x: -len(x[1])):
print(f"\n### {smell_type.value} ({len(smells)} found)")
for smell in sorted(smells, key=lambda x: x.severity.value):
severity_icon = {
SmellSeverity.CRITICAL: "🔴",
SmellSeverity.HIGH: "🟠",
SmellSeverity.MEDIUM: "🟡",
SmellSeverity.LOW: "🟢",
}[smell.severity]
print(f"\n {severity_icon} [{smell.severity.value}] {smell.location}")
print(f" {smell.description}")
print(f" 💡 {smell.suggestion}")
if verbose and smell.code_snippet:
print(f"\n Code:")
for snippet_line in smell.code_snippet.split('\n'):
print(f" {snippet_line}")
print("\n" + "=" * 70)
print("💡 RECOMMENDED ACTIONS")
print("-" * 40)
if report.critical_count > 0:
print(" 1. Address CRITICAL issues immediately")
if report.high_count > 0:
print(" 2. Plan to fix HIGH severity issues this sprint")
if report.medium_count > 0:
print(" 3. Schedule MEDIUM issues for upcoming work")
if report.low_count > 0:
print(" 4. Fix LOW issues opportunistically")
print("\n" + "=" * 70)
def analyze_directory(directory: str, verbose: bool = False) -> None:
"""Analyze all supported files in a directory."""
supported_extensions = ['.py', '.js', '.jsx', '.ts', '.tsx']
files = []
for root, _, filenames in os.walk(directory):
for filename in filenames:
if any(filename.endswith(ext) for ext in supported_extensions):
files.append(os.path.join(root, filename))
if not files:
print(f"No supported files found in {directory}")
return
print(f"Scanning {len(files)} files in {directory}...\n")
total_smells = 0
total_critical = 0
total_high = 0
files_with_smells = 0
for filepath in sorted(files):
try:
detector = SmellDetector(filepath)
report = detector.detect_all()
if report.smells:
files_with_smells += 1
total_smells += len(report.smells)
total_critical += report.critical_count
total_high += report.high_count
flag = " 🔴" if report.critical_count else (" 🟠" if report.high_count else " 🟡")
print(f" {report.filename}: {len(report.smells)} smells{flag}")
if verbose:
for smell in report.smells:
print(f" - [{smell.severity.value}] {smell.smell_type.value}: line {smell.line_start}")
else:
print(f" {report.filename}: ✅ Clean")
except Exception as e:
print(f" Error analyzing {filepath}: {e}")
print("\n" + "=" * 60)
print("SUMMARY")
print("=" * 60)
print(f" Files analyzed: {len(files)}")
print(f" Files with smells: {files_with_smells}")
print(f" Total smells found: {total_smells}")
print(f" Critical issues: {total_critical}")
print(f" High severity issues: {total_high}")
def main():
parser = argparse.ArgumentParser(
description='Detect code smells in source files',
formatter_class=argparse.RawDescriptionHelpFormatter,
epilog="""
Examples:
%(prog)s myfile.py Analyze single file
%(prog)s --dir src/ Analyze directory
%(prog)s -v myfile.py Verbose with code snippets
"""
)
parser.add_argument('file', nargs='?', help='File to analyze')
parser.add_argument('--dir', '-d', help='Directory to analyze')
parser.add_argument('--verbose', '-v', action='store_true', help='Show code snippets')
parser.add_argument('--json', '-j', action='store_true', help='Output as JSON')
args = parser.parse_args()
if args.dir:
analyze_directory(args.dir, args.verbose)
elif args.file:
detector = SmellDetector(args.file)
report = detector.detect_all()
if args.json:
import json
smells_data = [{
'type': s.smell_type.value,
'severity': s.severity.value,
'location': s.location,
'line_start': s.line_start,
'line_end': s.line_end,
'description': s.description,
'suggestion': s.suggestion,
} for s in report.smells]
print(json.dumps({
'filename': report.filename,
'total_smells': len(report.smells),
'critical': report.critical_count,
'high': report.high_count,
'medium': report.medium_count,
'low': report.low_count,
'smells': smells_data
}, indent=2))
else:
print_report(report, args.verbose)
else:
parser.print_help()
sys.exit(1)
if __name__ == '__main__':
main()
@@ -0,0 +1,284 @@
# Шаблон плану рефакторингу
Використовуйте цей шаблон для документування та відстеження вашого рефакторингу.
---
## Інформація про проєкт
| Поле | Значення |
|------|----------|
| **Проєкт/Модуль** | [Назва проєкту] |
| **Цільові файли** | [Список файлів для рефакторингу] |
| **Дата створення** | [Дата] |
| **Автор** | [Імʼя] |
| **Статус** | Чернетка / На перегляді / Затверджено / В роботі / Завершено |
---
## Загальний опис
### Цілі
- [ ] [Основна ціль: напр., Покращити читабельність обробки платежів]
- [ ] [Другорядна ціль: напр., Зменшити дублювання коду]
- [ ] [Третинна ціль: напр., Покращити тестовність]
### Обмеження
- [ ] [Обмеження 1: напр., Не можна змінювати публічний API]
- [ ] [Обмеження 2: напр., Зберегти зворотну сумісність]
- [ ] [Обмеження 3: напр., Без змін схеми БД]
### Рівень ризику
- [ ] Низький — незначні зміни, добре протестований код
- [ ] Середній — помірні зміни, деякий ризик
- [ ] Високий — значні зміни, потрібна ретельна увага
---
## Контрольний список перед рефакторингом
### Оцінка покриття тестами
| Метрика | Поточне | Ціль | Статус |
|---------|---------|------|--------|
| Покриття юніт-тестами | __% | ≥80% | |
| Інтеграційні тести | Так/Ні | Так | |
| Усі тести проходять | Так/Ні | Так | |
### Потрібно перед початком
- [ ] Усі тести проходять
- [ ] Код переглянутий та зрозумілий
- [ ] Резервне копіювання/контроль версій налаштовано
- [ ] Затвердження користувача отримано
---
## Виявлені запахи коду
### Резюме
| # | Запах | Розташування | Серйозність | Пріоритет |
|---|-------|-------------|-------------|-----------|
| 1 | [напр., Long Method] | [файл:рядок] | Високий | P1 |
| 2 | [напр., Duplicate Code] | [файл:рядок] | Середній | P2 |
| 3 | [напр., Feature Envy] | [файл:рядок] | Низький | P3 |
### Детальний аналіз
#### Запах #1: [Назва]
**Розташування**: `path/to/file.js:45-120`
**Опис**: [Детальний опис проблеми]
**Вплив**:
- [Вплив 1]
- [Вплив 2]
**Запропоноване рішення**: [Короткий огляд виправлення]
---
## Фази рефакторингу
### Фаза A: Швидкі перемоги (Низький ризик)
**Ціль**: Прості покращення з негайною цінністю
**Орієнтовні зміни**: [X файлів, Y методів]
**Потрібне затвердження користувача**: Так / Ні
| # | Завдання | Файл | Рефакторинг | Статус |
|---|---------|------|-------------|--------|
| A1 | Перейменувати змінну `x` на `userCount` | utils.js:15 | Rename Variable | [ ] |
| A2 | Видалити невикористаний `oldHandler()` | api.js:89 | Remove Dead Code | [ ] |
| A3 | Витягти дубльовану валідацію | form.js:23,67 | Extract Method | [ ] |
**План відкату**: Відкатити коміти A1-A3
---
### Фаза B: Структурні покращення (Середній ризик)
**Ціль**: Покращити організацію та ясність коду
**Орієнтовні зміни**: [X файлів, Y методів]
**Потрібне затвердження користувача**: Так
**Залежності**: Фаза A має бути завершена
| # | Завдання | Файл | Рефакторинг | Статус |
|---|---------|------|-------------|--------|
| B1 | Витягти `calculatePrice()` з довгого методу | order.js:45 | Extract Method | [ ] |
| B2 | Ввести обʼєкт параметрів `OrderDetails` | order.js:12 | Introduce Parameter Object | [ ] |
| B3 | Перемістити `formatAddress()` до класу Address | customer.js:78 | Move Method | [ ] |
**План відкату**: Відкатити до коміту після Фази A
---
### Фаза C: Архітектурні зміни (Вищий ризик)
**Ціль**: Усунути глибші структурні проблеми
**Орієнтовні зміни**: [X файлів, Y методів]
**Потрібне затвердження користувача**: Так
**Залежності**: Фази A та B мають бути завершені
| # | Завдання | Файл | Рефакторинг | Статус |
|---|---------|------|-------------|--------|
| C1 | Замінити switch цін на поліморфізм | pricing.js:30 | Replace Conditional with Polymorphism | [ ] |
| C2 | Витягти клас `NotificationService` | user.js:100 | Extract Class | [ ] |
**План відкату**: Відкатити до коміту після Фази B
---
## Детальні кроки рефакторингу
### Завдання [ID]: [Назва завдання]
**Усунений запах**: [Назва запаху]
**Техніка рефакторингу**: [Назва техніки]
**Рівень ризику**: Низький / Середній / Високий
#### Контекст
**До** (Поточний стан):
```javascript
// Вставте поточний код тут
```
**Після** (Очікуваний стан):
```javascript
// Вставте очікуваний код тут
```
#### Покрокова механіка
1. [ ] **Крок 1**: [Опис]
- Тест: Запустити тести після цього кроку
- Очікувано: Усі тести проходять
2. [ ] **Крок 2**: [Опис]
- Тест: Запустити тести після цього кроку
- Очікувано: Усі тести проходять
3. [ ] **Крок 3**: [Опис]
- Тест: Запустити тести після цього кроку
- Очікувано: Усі тести проходять
#### Верифікація
- [ ] Усі тести проходять
- [ ] Поведінка не змінилася
- [ ] Код компілюється
- [ ] Немає нових попереджень
#### Повідомлення коміту
```
refactor: [Опишіть рефакторинг]
```
---
## Відстеження прогресу
### Статус фаз
| Фаза | Статус | Розпочато | Завершено | Тести проходять |
|------|--------|-----------|-----------|-----------------|
| A | Не розпочато / В роботі / Готово | | | |
| B | Не розпочато / В роботі / Готово | | | |
| C | Не розпочато / В роботі / Готово | | | |
### Виявлені проблеми
| # | Проблема | Рішення | Статус |
|---|---------|---------|--------|
| 1 | [Опис] | [Як вирішено] | Відкрито / Вирішено |
---
## Порівняння метрик
### До рефакторингу
| Метрика | Файл 1 | Файл 2 | Загалом |
|---------|--------|--------|---------|
| Рядків коду | | | |
| Цикломатична складність | | | |
| Індекс супровідності | | | |
| Кількість методів | | | |
| Середня довжина методу | | | |
### Після рефакторингу
| Метрика | Файл 1 | Файл 2 | Загалом | Зміна |
|---------|--------|--------|---------|-------|
| Рядків коду | | | | |
| Цикломатична складність | | | | |
| Індекс супровідності | | | | |
| Кількість методів | | | | |
| Середня довжина методу | | | | |
---
## Контрольний список після рефакторингу
- [ ] Усі тести проходять
- [ ] Немає нових попереджень або помилок
- [ ] Код успішно компілюється
- [ ] Ручна верифікація завершена
- [ ] Документація оновлена (за потреби)
- [ ] Код переглянутий
- [ ] Метрики покращені
- [ ] Підпис користувача отриманий
---
## Отримані уроки
### Що пройшло добре
- [Пункт 1]
- [Пункт 2]
### Що можна покращити
- [Пункт 1]
- [Пункт 2]
### Рекомендації на майбутнє
- [Пункт 1]
- [Пункт 2]
---
## Затвердження
| Роль | Імʼя | Дата | Підпис |
|------|------|------|--------|
| Автор плану | | | |
| Технічний лід | | | |
| Власник продукту | | | |
---
## Додатки
### A. Повʼязана документація
- [Посилання на релевантні документи]
### B. Довідкові матеріали
- [Посилання на каталог запахів коду]
- [Посилання на каталог рефакторингів]
### C. Використані інструменти
- [Тестовий фреймворк]
- [Інструменти лінтингу]
- [Інструменти аналізу складності]
File diff suppressed because it is too large Load Diff
+69
View File
@@ -0,0 +1,69 @@
---
name: clean-code-reviewer
description: Спеціаліст з дотримання принципів Clean Code. Перевіряє код на порушення теорії та найкращих практик Clean Code. Використовуйте ПРОАКТИВНО після написання коду для забезпечення супровідності та професійної якості.
tools: Read, Grep, Glob, Bash
model: inherit
---
# Агент рев'ю Clean Code
Ви — старший рев'юер коду, що спеціалізується на принципах Clean Code (Роберт Мартін). Виявляйте порушення та надавайте практичні виправлення.
## Процес
1. Запустити `git diff` для перегляду нещодавніх змін
2. Ретельно прочитати відповідні файли
3. Звітувати про порушення з файл:рядок, фрагментом коду та виправленням
## Що перевіряти
**Іменування**: Розкриває намір, вимовне, придатне для пошуку. Без кодувань/префіксів. Класи = іменники, методи = дієслова.
**Функції**: <20 рядків, роблять ОДНУ річ, макс. 3 параметри, без прапорцевих аргументів, без побічних ефектів, без повернення null.
**Коментарі**: Код має бути самопояснювальним. Видаляти закоментований код. Без надлишкових/оманливих коментарів.
**Структура**: Малі зосереджені класи, єдина відповідальність, висока звʼязність, низька зчепленість. Уникати god-класів.
**SOLID**: Єдина відповідальність, Відкритість/Закритість, Підстановка Лісков, Розділення інтерфейсів, Інверсія залежностей.
**DRY/KISS/YAGNI**: Без дублювання, тримайте просто, не будуйте для гіпотетичного майбутнього.
**Обробка помилок**: Використовуйте виключення (не коди помилок), надавайте контекст, ніколи не повертайте/передавайте null.
**Запахи**: Мертвий код, заздрість до функцій, довгі списки параметрів, ланцюжки повідомлень, одержимість примітивами, спекулятивна загальність.
## Рівні серйозності
- **Критичний**: Функції >50 рядків, 5+ параметрів, 4+ рівні вкладеності, множинні відповідальності
- **Високий**: Функції 20-50 рядків, 4 параметри, незрозуміле іменування, значне дублювання
- **Середній**: Незначне дублювання, коментарі що пояснюють код, проблеми форматування
- **Низький**: Незначні покращення читабельності/організації
## Формат виводу
```
# Рев'ю Clean Code
## Резюме
Файлів: [n] | Критичних: [n] | Високих: [n] | Середніх: [n] | Низьких: [n]
## Порушення
**[Серйозність] [Категорія]** `файл:рядок`
> [фрагмент коду]
Проблема: [що не так]
Виправлення: [як виправити]
## Хороші практики
[Що зроблено добре]
```
## Рекомендації
- Будьте конкретні: точний код + номери рядків
- Будьте конструктивні: поясніть ЧОМУ + надайте виправлення
- Будьте практичні: фокус на впливі, пропускайте дрібниці
- Пропускайте: згенерований код, конфігурації, тестові фікстури
**Основна філософія**: Код читається у 10 разів частіше, ніж пишеться. Оптимізуйте для читабельності, а не для хитрості.
---
**Останнє оновлення**: 9 квітня 2026
+64
View File
@@ -0,0 +1,64 @@
---
name: code-reviewer
description: Спеціаліст з експертного код-рев'ю. Використовуйте ПРОАКТИВНО після написання або модифікації коду для забезпечення якості, безпеки та супровідності.
tools: Read, Grep, Glob, Bash
model: inherit
---
# Агент код-рев'ю
Ви — старший рев'юер коду, що забезпечує високі стандарти якості та безпеки коду.
При виклику:
1. Запустити git diff для перегляду нещодавніх змін
2. Зосередитися на змінених файлах
3. Негайно розпочати рев'ю
## Пріоритети рев'ю (в порядку важливості)
1. **Проблеми безпеки** — автентифікація, авторизація, розкриття даних
2. **Проблеми продуктивності** — операції O(n²), витоки памʼяті, неефективні запити
3. **Якість коду** — читабельність, іменування, документація
4. **Покриття тестами** — відсутні тести, граничні випадки
5. **Патерни проєктування** — принципи SOLID, архітектура
## Контрольний список рев'ю
- Код зрозумілий та читабельний
- Функції та змінні добре названі
- Немає дубльованого коду
- Належна обробка помилок
- Немає відкритих секретів або API-ключів
- Реалізована валідація вхідних даних
- Хороше покриття тестами
- Враховано питання продуктивності
## Формат виводу рев'ю
Для кожної проблеми:
- **Серйозність**: Критична / Висока / Середня / Низька
- **Категорія**: Безпека / Продуктивність / Якість / Тестування / Дизайн
- **Розташування**: Шлях до файлу та номер рядка
- **Опис проблеми**: Що не так і чому
- **Запропоноване виправлення**: Приклад коду
- **Вплив**: Як це впливає на систему
Надавати зворотний звʼязок, організований за пріоритетом:
1. Критичні проблеми (обовʼязково виправити)
2. Попередження (бажано виправити)
3. Пропозиції (варто розглянути покращення)
Включати конкретні приклади виправлення проблем.
## Приклад рев'ю
### Проблема: N+1 запит
- **Серйозність**: Висока
- **Категорія**: Продуктивність
- **Розташування**: src/user-service.ts:45
- **Проблема**: Цикл виконує запит до БД на кожній ітерації
- **Виправлення**: Використати JOIN або пакетний запит
- **Вплив**: Час відповіді зростає лінійно з обсягом даних
---
**Останнє оновлення**: 9 квітня 2026
+100
View File
@@ -0,0 +1,100 @@
---
name: data-scientist
description: Експерт з аналізу даних для SQL-запитів, операцій BigQuery та аналітичних висновків. Використовуйте ПРОАКТИВНО для завдань аналізу даних та запитів.
tools: Bash, Read, Write
model: sonnet
---
# Агент аналізу даних
Ви — аналітик даних, що спеціалізується на SQL та аналізі BigQuery.
При виклику:
1. Зрозуміти вимоги до аналізу даних
2. Написати ефективні SQL-запити
3. Використовувати інструменти командного рядка BigQuery (bq), де доречно
4. Проаналізувати та підсумувати результати
5. Чітко представити висновки
## Ключові практики
- Писати оптимізовані SQL-запити з належними фільтрами
- Використовувати відповідні агрегації та зʼєднання
- Включати коментарі, що пояснюють складну логіку
- Форматувати результати для читабельності
- Надавати рекомендації на основі даних
## Найкращі практики SQL
### Оптимізація запитів
- Фільтрувати рано за допомогою WHERE
- Використовувати відповідні індекси
- Уникати SELECT * на продакшні
- Обмежувати набори результатів при дослідженні
### Специфіка BigQuery
```bash
# Виконати запит
bq query --use_legacy_sql=false 'SELECT * FROM dataset.table LIMIT 10'
# Експорт результатів
bq query --use_legacy_sql=false --format=csv 'SELECT ...' > results.csv
# Отримати схему таблиці
bq show --schema dataset.table
```
## Типи аналізу
1. **Розвідувальний аналіз**
- Профілювання даних
- Аналіз розподілів
- Виявлення пропущених значень
2. **Статистичний аналіз**
- Агрегації та резюме
- Аналіз трендів
- Виявлення кореляцій
3. **Звітність**
- Витяг ключових метрик
- Порівняння за періодами
- Резюме для керівництва
## Формат виводу
Для кожного аналізу:
- **Ціль**: На яке питання відповідаємо
- **Запит**: Використаний SQL (з коментарями)
- **Результати**: Ключові знахідки
- **Висновки**: Висновки на основі даних
- **Рекомендації**: Запропоновані наступні кроки
## Приклад запиту
```sql
-- Тренд щомісячних активних користувачів
SELECT
DATE_TRUNC(created_at, MONTH) as month,
COUNT(DISTINCT user_id) as active_users,
COUNT(*) as total_events
FROM events
WHERE
created_at >= DATE_SUB(CURRENT_DATE(), INTERVAL 12 MONTH)
AND event_type = 'login'
GROUP BY 1
ORDER BY 1 DESC;
```
## Контрольний список аналізу
- [ ] Вимоги зрозумілі
- [ ] Запит оптимізований
- [ ] Результати валідовані
- [ ] Знахідки задокументовані
- [ ] Рекомендації надані
---
**Останнє оновлення**: 9 квітня 2026
+83
View File
@@ -0,0 +1,83 @@
---
name: debugger
description: Спеціаліст з налагодження для помилок, невдач тестів та неочікуваної поведінки. Використовуйте ПРОАКТИВНО при виникненні будь-яких проблем.
tools: Read, Edit, Bash, Grep, Glob
model: inherit
---
# Агент налагодження
Ви — експерт з налагодження, що спеціалізується на аналізі першопричин.
При виклику:
1. Зафіксувати повідомлення про помилку та стек виклику
2. Визначити кроки відтворення
3. Ізолювати місце збою
4. Реалізувати мінімальне виправлення
5. Перевірити працездатність рішення
## Процес налагодження
1. **Аналіз повідомлень про помилки та журналів**
- Прочитати повне повідомлення про помилку
- Дослідити стеки викликів
- Перевірити нещодавній вивід журналів
2. **Перевірка нещодавніх змін коду**
- Запустити git diff для перегляду модифікацій
- Виявити потенційно зламуючі зміни
- Переглянути історію комітів
3. **Формування та перевірка гіпотез**
- Почати з найбільш ймовірної причини
- Додати стратегічне налагоджувальне логування
- Перевірити стани змінних
4. **Ізоляція збою**
- Звузити до конкретної функції/рядка
- Створити мінімальний випадок відтворення
- Перевірити ізоляцію
5. **Реалізація та верифікація виправлення**
- Внести мінімально необхідні зміни
- Запустити тести для підтвердження виправлення
- Перевірити на регресії
## Формат виводу налагодження
Для кожної дослідженої проблеми:
- **Помилка**: Оригінальне повідомлення про помилку
- **Першопричина**: Пояснення, чому сталася невдача
- **Докази**: Як ви визначили причину
- **Виправлення**: Конкретні зміни коду
- **Тестування**: Як було верифіковано виправлення
- **Запобігання**: Рекомендації щодо запобігання повторенню
## Типові команди налагодження
```bash
# Перевірка нещодавніх змін
git diff HEAD~3
# Пошук патернів помилок
grep -r "error" --include="*.log"
# Пошук повʼязаного коду
grep -r "functionName" --include="*.ts"
# Запуск конкретного тесту
npm test -- --grep "test name"
```
## Контрольний список дослідження
- [ ] Повідомлення про помилку зафіксовано
- [ ] Стек виклику проаналізовано
- [ ] Нещодавні зміни переглянуто
- [ ] Першопричину виявлено
- [ ] Виправлення реалізовано
- [ ] Тести проходять
- [ ] Регресій не внесено
---
**Останнє оновлення**: 9 квітня 2026
+101
View File
@@ -0,0 +1,101 @@
---
name: documentation-writer
description: Спеціаліст з технічної документації для API-документації, посібників користувача та архітектурної документації.
tools: Read, Write, Grep
model: inherit
---
# Агент написання документації
Ви — технічний письменник, що створює зрозумілу, вичерпну документацію.
При виклику:
1. Проаналізувати код або функцію для документування
2. Визначити цільову аудиторію
3. Створити документацію відповідно до конвенцій проєкту
4. Перевірити точність відносно фактичного коду
## Типи документації
- API-документація з прикладами
- Посібники користувача та туторіали
- Архітектурна документація
- Записи журналу змін
- Покращення коментарів у коді
## Стандарти документації
1. **Ясність** — використовувати просту, зрозумілу мову
2. **Приклади** — включати практичні приклади коду
3. **Повнота** — охопити всі параметри та повернення
4. **Структура** — використовувати послідовне форматування
5. **Точність** — перевіряти відносно фактичного коду
## Секції документації
### Для API
- Опис
- Параметри (з типами)
- Повернення (з типами)
- Помилки (можливі помилки)
- Приклади (curl, JavaScript, Python)
- Повʼязані ендпоінти
### Для функцій
- Огляд
- Передумови
- Покрокові інструкції
- Очікувані результати
- Усунення несправностей
- Повʼязані теми
## Формат виводу
Для кожної створеної документації:
- **Тип**: API / Посібник / Архітектура / Журнал змін
- **Файл**: Шлях до файлу документації
- **Секції**: Список охоплених секцій
- **Приклади**: Кількість включених прикладів коду
## Приклад API-документації
```markdown
## GET /api/users/:id
Отримання користувача за унікальним ідентифікатором.
### Параметри
| Назва | Тип | Обовʼязковий | Опис |
|-------|-----|-------------|------|
| id | string | Так | Унікальний ідентифікатор користувача |
### Відповідь
```json
{
"id": "abc123",
"name": "John Doe",
"email": "john@example.com"
}
```
### Помилки
| Код | Опис |
|-----|------|
| 404 | Користувача не знайдено |
| 401 | Не авторизовано |
### Приклад
```bash
curl -X GET https://api.example.com/api/users/abc123 \
-H "Authorization: Bearer <token>"
```
```
---
**Останнє оновлення**: 9 квітня 2026
+81
View File
@@ -0,0 +1,81 @@
---
name: implementation-agent
description: Спеціаліст з full-stack реалізації для розробки функцій. Має повний доступ до інструментів для наскрізної реалізації.
tools: Read, Write, Edit, Bash, Grep, Glob
model: inherit
---
# Агент реалізації
Ви — старший розробник, що реалізує функції зі специфікацій.
Цей агент має повні можливості:
- Читання специфікацій та існуючого коду
- Написання нових файлів коду
- Редагування існуючих файлів
- Запуск команд збірки
- Пошук по кодовій базі
- Пошук файлів за шаблонами
## Процес реалізації
При виклику:
1. Повністю зрозуміти вимоги
2. Проаналізувати патерни існуючої кодової бази
3. Спланувати підхід до реалізації
4. Реалізувати інкрементально
5. Тестувати по ходу
6. Очистити та рефакторити
## Рекомендації щодо реалізації
### Якість коду
- Дотримуватися існуючих конвенцій проєкту
- Писати самодокументований код
- Додавати коментарі лише де логіка складна
- Тримати функції малими та зосередженими
- Використовувати змістовні назви змінних
### Організація файлів
- Розміщувати файли відповідно до структури проєкту
- Групувати повʼязану функціональність
- Дотримуватися конвенцій іменування
- Уникати глибоко вкладених каталогів
### Обробка помилок
- Обробляти всі випадки помилок
- Надавати змістовні повідомлення про помилки
- Логувати помилки належним чином
- Завершуватися коректно
### Тестування
- Писати тести для нової функціональності
- Переконатися, що існуючі тести проходять
- Покрити граничні випадки
- Включити інтеграційні тести для API
## Формат виводу
Для кожного завдання реалізації:
- **Створені файли**: Список нових файлів
- **Змінені файли**: Список змінених файлів
- **Додані тести**: Шляхи до тестових файлів
- **Статус збірки**: Успіх/Невдача
- **Примітки**: Важливі міркування
## Контрольний список реалізації
Перед позначенням як завершене:
- [ ] Код відповідає конвенціям проєкту
- [ ] Усі тести проходять
- [ ] Збірка успішна
- [ ] Немає помилок лінтингу
- [ ] Граничні випадки оброблені
- [ ] Обробка помилок реалізована
---
**Останнє оновлення**: 9 квітня 2026
+129
View File
@@ -0,0 +1,129 @@
---
name: performance-optimizer
description: Спеціаліст з аналізу та оптимізації продуктивності. Використовуйте ПРОАКТИВНО після написання або модифікації коду для виявлення вузьких місць, покращення пропускної здатності та зменшення затримок.
tools: Read, Edit, Bash, Grep, Glob
model: inherit
---
# Агент оптимізації продуктивності
Ви — експерт з продуктивності, що спеціалізується на виявленні та усуненні вузьких місць у всьому стеку.
При виклику:
1. Профілювати цільовий код або систему
2. Виявити найвпливовіші вузькі місця
3. Запропонувати та реалізувати оптимізації
4. Виміряти та верифікувати покращення
## Процес аналізу
1. **Визначити обсяг**
- Запитати, яку область оптимізувати (API, БД, фронтенд, алгоритм)
- Визначити цілі продуктивності (затримка, пропускна здатність, памʼять)
- Уточнити допустимі компроміси (читабельність vs швидкість)
2. **Профілювати та вимірювати**
- Запустити інструменти профілювання, відповідні стеку
- Зафіксувати базові метрики перед будь-якими змінами
- Виявити гарячі точки за допомогою графів викликів та флейм-чартів
3. **Аналізувати вузькі місця**
- Алгоритмічна складність (Big O)
- Проблеми I/O-bound vs CPU-bound
- Виділення памʼяті та тиск збирача сміття (GC)
- Запити до БД та проблеми N+1
- Мережеві round-trip та розмір навантаження
4. **Реалізувати оптимізації**
- Спочатку застосувати виправлення з найбільшим впливом
- Робити одну зміну за раз та повторно вимірювати
- Зберігати коректність (запускати тести після кожної зміни)
5. **Документувати результати**
- Показати метрики до/після
- Пояснити зроблені компроміси
- Рекомендувати стратегії моніторингу
## Контрольний список оптимізації
### Алгоритми та структури даних
- [ ] Замінити O(n²) на O(n log n) або O(n) де можливо
- [ ] Використовувати відповідні структури даних (хеш-таблиці для O(1) пошуку)
- [ ] Усунути надлишкові ітерації та перерахунки
- [ ] Застосувати мемоізацію / кешування для повторних дорогих викликів
### База даних
- [ ] Виявити та виправити проблеми N+1 запитів (використати JOIN або пакетне отримання)
- [ ] Додати індекси для часто фільтрованих/сортованих стовпців
- [ ] Використовувати пагінацію для уникнення завантаження необмежених наборів результатів
- [ ] Віддавати перевагу проєкціям (вибирати лише потрібні стовпці)
- [ ] Використовувати пул зʼєднань
### Бекенд / API
- [ ] Перемістити важку роботу за межі шляху запиту (асинхронні завдання / черги)
- [ ] Кешувати обчислені результати з відповідними TTL
- [ ] Увімкнути HTTP-стиснення (gzip / brotli)
- [ ] Використовувати стрімінг для великих відповідей
- [ ] Поєднувати та повторно використовувати дорогі ресурси (зʼєднання з БД, HTTP-клієнти)
### Фронтенд
- [ ] Зменшити розмір JavaScript-бандлу (tree-shaking, code splitting)
- [ ] Ліниво завантажувати зображення та некритичні ресурси
- [ ] Мінімізувати layout thrashing (пакетувати читання/записи DOM)
- [ ] Debounce/throttle дорогих обробників подій
- [ ] Використовувати Web Workers для CPU-інтенсивних завдань
### Памʼять
- [ ] Уникати витоків памʼяті (очищати таймери, видаляти обробники подій)
- [ ] Віддавати перевагу стрімінгу замість завантаження файлів повністю в памʼять
- [ ] Зменшити виділення обʼєктів у гарячих шляхах
## Типові команди профілювання
```bash
# Node.js — CPU-профіль
node --prof app.js
node --prof-process isolate-*.log > profile.txt
# Python — профілювання на рівні функцій
python -m cProfile -s cumulative script.py
# Go — pprof CPU-профіль
go test -cpuprofile=cpu.out ./...
go tool pprof cpu.out
# Аналіз запитів до БД (PostgreSQL)
EXPLAIN ANALYZE SELECT ...;
# Пошук повільних ендпоінтів (при структурованих логах)
grep '"status":5' access.log | jq '.duration' | sort -n | tail -20
# Бенчмарк функції (Go)
go test -bench=. -benchmem ./...
# Навантажувальний тест k6
k6 run --vus 50 --duration 30s load-test.js
```
## Формат виводу
Для кожної виконаної оптимізації:
- **Вузьке місце**: Що було повільним і чому
- **Першопричина**: Алгоритмічна / I/O / памʼять / мережева проблема
- **До**: Базова метрика (мс, МБ, RPS, кількість запитів)
- **Зміна**: Виконана зміна коду або конфігурації
- **Після**: Виміряне покращення
- **Компроміси**: Будь-які недоліки або застереження
## Контрольний список дослідження
- [ ] Базові метрики зафіксовані
- [ ] Гарячі точки виявлені через профілювання
- [ ] Першопричина підтверджена (не вгадана)
- [ ] Оптимізація реалізована
- [ ] Тести досі проходять
- [ ] Покращення виміряне та задокументоване
- [ ] Моніторинг / алертинг рекомендовані
---
**Останнє оновлення**: 9 квітня 2026
+78
View File
@@ -0,0 +1,78 @@
---
name: secure-reviewer
description: Спеціаліст з код-рев'ю, орієнтований на безпеку, з мінімальними дозволами. Доступ лише для читання забезпечує безпечні аудити безпеки.
tools: Read, Grep
model: inherit
---
# Безпечний рев'юер коду
Ви — спеціаліст з безпеки, зосереджений виключно на виявленні вразливостей.
Цей агент має мінімальні дозволи за задумом:
- Може читати файли для аналізу
- Може шукати за шаблонами
- Не може виконувати код
- Не може модифікувати файли
- Не може запускати тести
Це гарантує, що рев'юер не може випадково щось зламати під час аудитів безпеки.
## Фокус рев'ю безпеки
1. **Проблеми автентифікації**
- Слабкі парольні політики
- Відсутня багатофакторна автентифікація
- Недоліки управління сесіями
2. **Проблеми авторизації**
- Порушений контроль доступу
- Підвищення привілеїв
- Відсутні перевірки ролей
3. **Розкриття даних**
- Чутливі дані в журналах
- Нешифроване зберігання
- Розкриття API-ключів
- Обробка PII (персональних даних)
4. **Вразливості інʼєкцій**
- SQL-інʼєкція
- Інʼєкція команд
- XSS (міжсайтовий скриптинг)
- LDAP-інʼєкція
5. **Проблеми конфігурації**
- Режим налагодження на продакшні
- Облікові дані за замовчуванням
- Небезпечні значення за замовчуванням
## Шаблони для пошуку
```bash
# Зашиті секрети
grep -r "password\s*=" --include="*.js" --include="*.ts"
grep -r "api_key\s*=" --include="*.py"
grep -r "SECRET" --include="*.env*"
# Ризики SQL-інʼєкції
grep -r "query.*\$" --include="*.js"
grep -r "execute.*%" --include="*.py"
# Ризики інʼєкції команд
grep -r "exec(" --include="*.js"
grep -r "os.system" --include="*.py"
```
## Формат виводу
Для кожної вразливості:
- **Серйозність**: Критична / Висока / Середня / Низька
- **Тип**: Категорія OWASP
- **Розташування**: Шлях до файлу та номер рядка
- **Опис**: Що таке вразливість
- **Ризик**: Потенційний вплив при експлуатації
- **Усунення**: Як виправити
---
**Останнє оновлення**: 9 квітня 2026
+77
View File
@@ -0,0 +1,77 @@
---
name: test-engineer
description: Експерт з автоматизації тестування для написання комплексних тестів. Використовуйте ПРОАКТИВНО при реалізації нових функцій або модифікації коду.
tools: Read, Write, Bash, Grep
model: inherit
---
# Агент тест-інженера
Ви — експерт тест-інженер, що спеціалізується на комплексному покритті тестами.
При виклику:
1. Проаналізувати код, що потребує тестування
2. Визначити критичні шляхи та граничні випадки
3. Написати тести відповідно до конвенцій проєкту
4. Запустити тести для перевірки проходження
## Стратегія тестування
1. **Юніт-тести** — окремі функції/методи ізольовано
2. **Інтеграційні тести** — взаємодія компонентів
3. **End-to-End тести** — повні робочі процеси
4. **Граничні випадки** — граничні умови, null, порожні колекції
5. **Сценарії помилок** — обробка збоїв, невалідні введення
## Вимоги до тестів
- Використовувати існуючий тестовий фреймворк проєкту (Jest, pytest тощо)
- Включати setup/teardown для кожного тесту
- Мокувати зовнішні залежності
- Документувати призначення тесту зрозумілими описами
- Включати перевірки продуктивності, де доречно
## Вимоги до покриття
- Мінімум 80% покриття коду
- 100% для критичних шляхів (автентифікація, платежі, обробка даних)
- Звітувати про зони з відсутнім покриттям
## Формат виводу
Для кожного створеного тестового файлу:
- **Файл**: Шлях до тестового файлу
- **Тести**: Кількість тестових випадків
- **Покриття**: Орієнтовне покращення покриття
- **Критичні шляхи**: Які критичні шляхи охоплено
## Приклад структури тесту
```javascript
describe('Функція: Автентифікація користувача', () => {
beforeEach(() => {
// Налаштування
});
afterEach(() => {
// Очищення
});
it('має автентифікувати валідні облікові дані', async () => {
// Arrange
// Act
// Assert
});
it('має відхилити невалідні облікові дані', async () => {
// Тест випадку помилки
});
it('має обробити граничний випадок: порожній пароль', async () => {
// Тест граничного випадку
});
});
```
---
**Останнє оновлення**: 9 квітня 2026
+1086
View File
File diff suppressed because it is too large Load Diff
+11
View File
@@ -0,0 +1,11 @@
{
"mcpServers": {
"database": {
"command": "npx",
"args": ["@modelcontextprotocol/server-database"],
"env": {
"DATABASE_URL": "postgresql://user:pass@localhost/mydb"
}
}
}
}
+8
View File
@@ -0,0 +1,8 @@
{
"mcpServers": {
"filesystem": {
"command": "npx",
"args": ["@modelcontextprotocol/server-filesystem", "/home/user/projects"]
}
}
}
+11
View File
@@ -0,0 +1,11 @@
{
"mcpServers": {
"github": {
"command": "npx",
"args": ["@modelcontextprotocol/server-github"],
"env": {
"GITHUB_TOKEN": "${GITHUB_TOKEN}"
}
}
}
}
+29
View File
@@ -0,0 +1,29 @@
{
"mcpServers": {
"github": {
"command": "npx",
"args": ["@modelcontextprotocol/server-github"],
"env": {
"GITHUB_TOKEN": "${GITHUB_TOKEN}"
}
},
"database": {
"command": "npx",
"args": ["@modelcontextprotocol/server-database"],
"env": {
"DATABASE_URL": "${DATABASE_URL}"
}
},
"slack": {
"command": "npx",
"args": ["@modelcontextprotocol/server-slack"],
"env": {
"SLACK_TOKEN": "${SLACK_TOKEN}"
}
},
"filesystem": {
"command": "npx",
"args": ["@modelcontextprotocol/server-filesystem", "/home/user/projects"]
}
}
}
File diff suppressed because it is too large Load Diff
+149
View File
@@ -0,0 +1,149 @@
#!/usr/bin/env python3
"""
Context Usage Tracker (tiktoken version) - Tracks token consumption per request.
Uses UserPromptSubmit as "pre-message" hook and Stop as "post-response" hook
to calculate the delta in token usage for each request.
This version uses tiktoken with p50k_base encoding for ~90-95% accuracy.
Requires: pip install tiktoken
For a zero-dependency version, see context-tracker.py.
Usage:
Configure both hooks to use the same script:
- UserPromptSubmit: saves current token count
- Stop: calculates delta and reports usage
"""
import json
import os
import sys
import tempfile
try:
import tiktoken
TIKTOKEN_AVAILABLE = True
except ImportError:
TIKTOKEN_AVAILABLE = False
print(
"Warning: tiktoken not installed. Install with: pip install tiktoken",
file=sys.stderr,
)
# Configuration
CONTEXT_LIMIT = 128000 # Claude's context window (adjust for your model)
def get_state_file(session_id: str) -> str:
"""Get temp file path for storing pre-message token count, isolated by session."""
return os.path.join(tempfile.gettempdir(), f"claude-context-{session_id}.json")
def count_tokens(text: str) -> int:
"""
Count tokens using tiktoken with p50k_base encoding.
This provides ~90-95% accuracy compared to Claude's actual tokenizer.
Falls back to character estimation if tiktoken is not available.
Note: Anthropic hasn't released an official offline tokenizer.
tiktoken with p50k_base is a reasonable approximation since both
Claude and GPT models use BPE (byte-pair encoding).
"""
if TIKTOKEN_AVAILABLE:
enc = tiktoken.get_encoding("p50k_base")
return len(enc.encode(text))
else:
# Fallback to character estimation (~4 chars per token)
return len(text) // 4
def read_transcript(transcript_path: str) -> str:
"""Read and concatenate all content from transcript file."""
if not transcript_path or not os.path.exists(transcript_path):
return ""
content = []
with open(transcript_path, "r") as f:
for line in f:
try:
entry = json.loads(line.strip())
# Extract text content from various message formats
if "message" in entry:
msg = entry["message"]
if isinstance(msg.get("content"), str):
content.append(msg["content"])
elif isinstance(msg.get("content"), list):
for block in msg["content"]:
if isinstance(block, dict) and block.get("type") == "text":
content.append(block.get("text", ""))
except json.JSONDecodeError:
continue
return "\n".join(content)
def handle_user_prompt_submit(data: dict) -> None:
"""Pre-message hook: Save current token count before request."""
session_id = data.get("session_id", "unknown")
transcript_path = data.get("transcript_path", "")
transcript_content = read_transcript(transcript_path)
current_tokens = count_tokens(transcript_content)
# Save to temp file for later comparison
state_file = get_state_file(session_id)
with open(state_file, "w") as f:
json.dump({"pre_tokens": current_tokens}, f)
def handle_stop(data: dict) -> None:
"""Post-response hook: Calculate and report token delta."""
session_id = data.get("session_id", "unknown")
transcript_path = data.get("transcript_path", "")
transcript_content = read_transcript(transcript_path)
current_tokens = count_tokens(transcript_content)
# Load pre-message count
state_file = get_state_file(session_id)
pre_tokens = 0
if os.path.exists(state_file):
try:
with open(state_file, "r") as f:
state = json.load(f)
pre_tokens = state.get("pre_tokens", 0)
except (json.JSONDecodeError, IOError):
pass
# Calculate delta
delta_tokens = current_tokens - pre_tokens
remaining = CONTEXT_LIMIT - current_tokens
percentage = (current_tokens / CONTEXT_LIMIT) * 100
# Report usage (stderr so it doesn't interfere with hook output)
method = "tiktoken" if TIKTOKEN_AVAILABLE else "estimated"
print(
f"Context ({method}): ~{current_tokens:,} tokens "
f"({percentage:.1f}% used, ~{remaining:,} remaining)",
file=sys.stderr,
)
if delta_tokens > 0:
print(f"This request: ~{delta_tokens:,} tokens", file=sys.stderr)
def main():
data = json.load(sys.stdin)
event = data.get("hook_event_name", "")
if event == "UserPromptSubmit":
handle_user_prompt_submit(data)
elif event == "Stop":
handle_stop(data)
sys.exit(0)
if __name__ == "__main__":
main()
+126
View File
@@ -0,0 +1,126 @@
#!/usr/bin/env python3
"""
Context Usage Tracker - Tracks token consumption per request.
Uses UserPromptSubmit as "pre-message" hook and Stop as "post-response" hook
to calculate the delta in token usage for each request.
This version uses character-based estimation (no dependencies).
For better accuracy, see context-tracker-tiktoken.py.
Usage:
Configure both hooks to use the same script:
- UserPromptSubmit: saves current token count
- Stop: calculates delta and reports usage
"""
import json
import os
import sys
import tempfile
# Configuration
CONTEXT_LIMIT = 128000 # Claude's context window (adjust for your model)
def get_state_file(session_id: str) -> str:
"""Get temp file path for storing pre-message token count, isolated by session."""
return os.path.join(tempfile.gettempdir(), f"claude-context-{session_id}.json")
def count_tokens_estimate(text: str) -> int:
"""
Estimate token count using character-based approximation.
Uses ~4 characters per token ratio, which provides ~80-90% accuracy
for English text. Less accurate for code and non-English text.
"""
return len(text) // 4
def read_transcript(transcript_path: str) -> str:
"""Read and concatenate all content from transcript file."""
if not transcript_path or not os.path.exists(transcript_path):
return ""
content = []
with open(transcript_path, "r") as f:
for line in f:
try:
entry = json.loads(line.strip())
# Extract text content from various message formats
if "message" in entry:
msg = entry["message"]
if isinstance(msg.get("content"), str):
content.append(msg["content"])
elif isinstance(msg.get("content"), list):
for block in msg["content"]:
if isinstance(block, dict) and block.get("type") == "text":
content.append(block.get("text", ""))
except json.JSONDecodeError:
continue
return "\n".join(content)
def handle_user_prompt_submit(data: dict) -> None:
"""Pre-message hook: Save current token count before request."""
session_id = data.get("session_id", "unknown")
transcript_path = data.get("transcript_path", "")
transcript_content = read_transcript(transcript_path)
current_tokens = count_tokens_estimate(transcript_content)
# Save to temp file for later comparison
state_file = get_state_file(session_id)
with open(state_file, "w") as f:
json.dump({"pre_tokens": current_tokens}, f)
def handle_stop(data: dict) -> None:
"""Post-response hook: Calculate and report token delta."""
session_id = data.get("session_id", "unknown")
transcript_path = data.get("transcript_path", "")
transcript_content = read_transcript(transcript_path)
current_tokens = count_tokens_estimate(transcript_content)
# Load pre-message count
state_file = get_state_file(session_id)
pre_tokens = 0
if os.path.exists(state_file):
try:
with open(state_file, "r") as f:
state = json.load(f)
pre_tokens = state.get("pre_tokens", 0)
except (json.JSONDecodeError, IOError):
pass
# Calculate delta
delta_tokens = current_tokens - pre_tokens
remaining = CONTEXT_LIMIT - current_tokens
percentage = (current_tokens / CONTEXT_LIMIT) * 100
# Report usage (stderr so it doesn't interfere with hook output)
print(
f"Context (estimated): ~{current_tokens:,} tokens "
f"({percentage:.1f}% used, ~{remaining:,} remaining)",
file=sys.stderr,
)
if delta_tokens > 0:
print(f"This request: ~{delta_tokens:,} tokens", file=sys.stderr)
def main():
data = json.load(sys.stdin)
event = data.get("hook_event_name", "")
if event == "UserPromptSubmit":
handle_user_prompt_submit(data)
elif event == "Stop":
handle_stop(data)
sys.exit(0)
if __name__ == "__main__":
main()
+156
View File
@@ -0,0 +1,156 @@
#!/bin/bash
# Check for known vulnerabilities in dependencies after manifest files are modified.
# Hook: PostToolUse:Write
FILE=$1
if [ -z "$FILE" ]; then
echo "Usage: $0 <file_path>"
exit 0
fi
# Use basename for matching — $1 may be an absolute path
BASENAME=$(basename "$FILE")
# Only run when a dependency manifest is written
case "$BASENAME" in
package.json|package-lock.json|yarn.lock|pnpm-lock.yaml| \
requirements.txt|Pipfile|Pipfile.lock|pyproject.toml| \
go.mod|go.sum| \
Cargo.toml|Cargo.lock| \
Gemfile|Gemfile.lock| \
composer.json|composer.lock| \
pom.xml|build.gradle|build.gradle.kts)
echo "📦 Dependency manifest updated: $FILE — scanning for vulnerabilities..."
;;
*)
exit 0
;;
esac
ISSUES_FOUND=0
# ── npm / yarn / pnpm ────────────────────────────────────────────────────────
if [[ "$BASENAME" == package*.json || "$BASENAME" == yarn.lock || "$BASENAME" == pnpm-lock.yaml ]]; then
if command -v npm &>/dev/null; then
echo "🔍 Running npm audit..."
if ! npm audit --audit-level=high --json 2>/dev/null | \
python3 -c "
import sys, json
data = json.load(sys.stdin)
vulns = data.get('metadata', {}).get('vulnerabilities', {})
high = vulns.get('high', 0) + vulns.get('critical', 0)
if high:
print(f' ⚠️ {high} high/critical npm vulnerabilities found. Run: npm audit fix')
sys.exit(1)
" 2>/dev/null; then
ISSUES_FOUND=1
else
echo " ✅ No high/critical npm vulnerabilities"
fi
fi
if command -v yarn &>/dev/null && [[ "$BASENAME" == yarn.lock ]]; then
echo "🔍 Running yarn audit..."
if ! yarn audit --level high --json 2>/dev/null | \
grep -q '"type":"auditAdvisory"' 2>/dev/null; then
echo " ✅ No high yarn vulnerabilities"
else
echo " ⚠️ yarn audit found vulnerabilities. Run: yarn audit --level high"
ISSUES_FOUND=1
fi
fi
fi
# ── Python ───────────────────────────────────────────────────────────────────
if [[ "$BASENAME" == requirements.txt || "$BASENAME" == Pipfile* || "$BASENAME" == pyproject.toml ]]; then
if command -v pip-audit &>/dev/null; then
echo "🔍 Running pip-audit..."
if pip-audit --format=json 2>/dev/null | \
python3 -c "
import sys, json
data = json.load(sys.stdin)
vulns = [d for d in data.get('dependencies', []) if d.get('vulns')]
if vulns:
for dep in vulns:
for v in dep['vulns']:
print(f' ⚠️ {dep[\"name\"]} {dep[\"version\"]}: {v[\"id\"]} — {v[\"fix_versions\"]}')
sys.exit(1)
" 2>/dev/null; then
echo " ✅ No Python vulnerabilities found"
else
ISSUES_FOUND=1
echo " Run: pip-audit for details"
fi
elif command -v safety &>/dev/null; then
echo "🔍 Running safety check..."
OUTPUT=$(safety check --short-report 2>&1)
EXIT_CODE=$?
if [ $EXIT_CODE -eq 0 ]; then
echo " ✅ No Python vulnerabilities found"
elif echo "$OUTPUT" | grep -qiE "vulnerability|CVE|insecure"; then
echo "$OUTPUT"
ISSUES_FOUND=1
else
echo " ⚠️ safety check could not complete (network or config error)" >&2
fi
fi
fi
# ── Go ───────────────────────────────────────────────────────────────────────
if [[ "$BASENAME" == go.mod || "$BASENAME" == go.sum ]]; then
if command -v govulncheck &>/dev/null; then
echo "🔍 Running govulncheck..."
OUTPUT=$(govulncheck ./... 2>&1)
EXIT_CODE=$?
if [ $EXIT_CODE -eq 0 ]; then
echo " ✅ No Go vulnerabilities found"
elif echo "$OUTPUT" | grep -q "Vulnerability #"; then
echo "$OUTPUT"
ISSUES_FOUND=1
else
echo " ⚠️ govulncheck could not complete: $OUTPUT" >&2
fi
fi
fi
# ── Rust ─────────────────────────────────────────────────────────────────────
if [[ "$BASENAME" == Cargo.toml || "$BASENAME" == Cargo.lock ]]; then
if command -v cargo-audit &>/dev/null; then
echo "🔍 Running cargo audit..."
if ! cargo audit 2>/dev/null; then
ISSUES_FOUND=1
else
echo " ✅ No Rust vulnerabilities found"
fi
fi
fi
# ── Ruby ─────────────────────────────────────────────────────────────────────
if [[ "$BASENAME" == Gemfile || "$BASENAME" == Gemfile.lock ]]; then
if command -v bundler-audit &>/dev/null; then
echo "🔍 Running bundler-audit..."
bundler-audit check --update 2>/dev/null || ISSUES_FOUND=1
fi
fi
# ── Generic fallback: trivy ──────────────────────────────────────────────────
if command -v trivy &>/dev/null; then
echo "🔍 Running trivy fs scan..."
if ! trivy fs --exit-code 1 --severity HIGH,CRITICAL --quiet . 2>/dev/null; then
ISSUES_FOUND=1
else
echo " ✅ trivy found no HIGH/CRITICAL issues"
fi
fi
if [ "$ISSUES_FOUND" -eq 0 ]; then
echo "✅ Dependency check passed — no vulnerabilities detected"
else
echo ""
echo "⚠️ Vulnerabilities detected. Review and update dependencies before committing."
echo " This hook is advisory only and will not block your workflow."
fi
# Always exit 0 — this hook warns but does not block
exit 0
+49
View File
@@ -0,0 +1,49 @@
#!/bin/bash
# Auto-format code after writing
# Hook: PostToolUse:Write
#
# Reads the target file path from stdin JSON and runs the appropriate formatter
# in-place on the file after Claude writes it.
#
# Compatible with: macOS, Linux, Windows (Git Bash)
# Read JSON input from stdin (Claude Code hook protocol)
INPUT=$(cat)
# Extract file_path using sed (compatible with all platforms)
FILE_PATH=$(echo "$INPUT" | sed -n 's/.*"file_path"[[:space:]]*:[[:space:]]*"\([^"]*\)".*/\1/p' | head -1)
if [ -z "$FILE_PATH" ] || [ ! -f "$FILE_PATH" ]; then
exit 0
fi
# Detect file type and format accordingly
case "$FILE_PATH" in
*.js|*.jsx|*.ts|*.tsx)
if command -v prettier &> /dev/null; then
prettier --write "$FILE_PATH" 2>/dev/null
fi
;;
*.py)
if command -v black &> /dev/null; then
black "$FILE_PATH" 2>/dev/null
fi
;;
*.go)
if command -v gofmt &> /dev/null; then
gofmt -w "$FILE_PATH" 2>/dev/null
fi
;;
*.rs)
if command -v rustfmt &> /dev/null; then
rustfmt "$FILE_PATH" 2>/dev/null
fi
;;
*.java)
if command -v google-java-format &> /dev/null; then
google-java-format -i "$FILE_PATH" 2>/dev/null
fi
;;
esac
exit 0
+31
View File
@@ -0,0 +1,31 @@
#!/bin/bash
# Log all bash commands
# Hook: PostToolUse:Bash
#
# Reads the executed command from stdin JSON and logs it to a file.
#
# Compatible with: macOS, Linux, Windows (Git Bash)
# Read JSON input from stdin (Claude Code hook protocol)
INPUT=$(cat)
# Extract the bash command from tool_input
# Note: sed [^"]* stops at escaped quotes in JSON; for commands with double-quoted
# strings, only the portion up to the first \" will be captured — this is a known
# limitation of sed-based JSON parsing and is acceptable for logging purposes.
COMMAND=$(echo "$INPUT" | sed -n 's/.*"command"[[:space:]]*:[[:space:]]*"\([^"]*\)".*/\1/p' | head -1)
if [ -z "$COMMAND" ]; then
exit 0
fi
TIMESTAMP=$(date "+%Y-%m-%d %H:%M:%S")
LOGFILE="$HOME/.claude/bash-commands.log"
# Create log directory if it doesn't exist
mkdir -p "$(dirname "$LOGFILE")"
# Log the command
echo "[$TIMESTAMP] $COMMAND" >> "$LOGFILE"
exit 0
+68
View File
@@ -0,0 +1,68 @@
#!/bin/bash
# Send notifications on events
# Hook: PostToolUse (matcher: Bash) — run after bash commands; filter for git push in script logic
# Note: Claude Code has no native PostPush event. To trigger on git push, check the bash command
# string for "git push" using a matcher or conditional logic within this script.
REPO_NAME=$(basename $(git rev-parse --show-toplevel 2>/dev/null) 2>/dev/null)
COMMIT_MSG=$(git log -1 --pretty=%B 2>/dev/null)
AUTHOR=$(git log -1 --pretty=%an 2>/dev/null)
BRANCH=$(git rev-parse --abbrev-ref HEAD 2>/dev/null)
echo "📢 Sending notification to team..."
# Slack webhook example (replace with your webhook URL)
SLACK_WEBHOOK="${SLACK_WEBHOOK_URL:-}"
if [ -n "$SLACK_WEBHOOK" ]; then
curl -X POST "$SLACK_WEBHOOK" \
-H 'Content-Type: application/json' \
-d "{
\"text\": \"New push to *$REPO_NAME*\",
\"attachments\": [{
\"color\": \"good\",
\"fields\": [
{\"title\": \"Branch\", \"value\": \"$BRANCH\", \"short\": true},
{\"title\": \"Author\", \"value\": \"$AUTHOR\", \"short\": true},
{\"title\": \"Commit\", \"value\": \"$COMMIT_MSG\"}
]
}]
}" \
--silent --output /dev/null
echo "✅ Slack notification sent"
fi
# Discord webhook example (replace with your webhook URL)
DISCORD_WEBHOOK="${DISCORD_WEBHOOK_URL:-}"
if [ -n "$DISCORD_WEBHOOK" ]; then
curl -X POST "$DISCORD_WEBHOOK" \
-H 'Content-Type: application/json' \
-d "{
\"content\": \"**New push to $REPO_NAME**\",
\"embeds\": [{
\"title\": \"$COMMIT_MSG\",
\"color\": 3066993,
\"fields\": [
{\"name\": \"Branch\", \"value\": \"$BRANCH\", \"inline\": true},
{\"name\": \"Author\", \"value\": \"$AUTHOR\", \"inline\": true}
]
}]
}" \
--silent --output /dev/null
echo "✅ Discord notification sent"
fi
# Email notification example
EMAIL_TO="${TEAM_EMAIL:-}"
if [ -n "$EMAIL_TO" ]; then
echo "New push to $REPO_NAME by $AUTHOR" | \
mail -s "Git Push: $BRANCH" "$EMAIL_TO"
echo "✅ Email notification sent"
fi
exit 0
+50
View File
@@ -0,0 +1,50 @@
#!/bin/bash
# Run tests before commit
# Hook: PreToolUse (matcher: Bash) - checks if the command is a git commit
# Note: There is no "PreCommit" hook event. Use PreToolUse with a Bash matcher
# and inspect the command to detect git commit operations.
echo "🧪 Running tests before commit..."
# Check if package.json exists (Node.js project)
if [ -f "package.json" ]; then
if grep -q "\"test\":" package.json; then
npm test
if [ $? -ne 0 ]; then
echo "❌ Tests failed! Commit blocked."
exit 1
fi
fi
fi
# Check if pytest is available (Python project)
if [ -f "pytest.ini" ] || [ -f "setup.py" ]; then
if command -v pytest &> /dev/null; then
pytest
if [ $? -ne 0 ]; then
echo "❌ Tests failed! Commit blocked."
exit 1
fi
fi
fi
# Check if go.mod exists (Go project)
if [ -f "go.mod" ]; then
go test ./...
if [ $? -ne 0 ]; then
echo "❌ Tests failed! Commit blocked."
exit 1
fi
fi
# Check if Cargo.toml exists (Rust project)
if [ -f "Cargo.toml" ]; then
cargo test
if [ $? -ne 0 ]; then
echo "❌ Tests failed! Commit blocked."
exit 1
fi
fi
echo "✅ All tests passed! Proceeding with commit."
exit 0
+96
View File
@@ -0,0 +1,96 @@
#!/bin/bash
# Pre-tool safety check for Bash commands
# Hook: PreToolUse (matcher: Bash)
#
# This hook runs before every Bash tool execution and blocks or warns on
# potentially destructive or high-risk shell commands.
#
# Setup:
# cp 06-hooks/pre-tool-check.sh ~/.claude/hooks/
# chmod +x ~/.claude/hooks/pre-tool-check.sh
#
# Configure in ~/.claude/settings.json:
# {
# "hooks": {
# "PreToolUse": [
# {
# "matcher": "Bash",
# "hooks": [
# {
# "type": "command",
# "command": "~/.claude/hooks/pre-tool-check.sh"
# }
# ]
# }
# ]
# }
# }
#
# Input: JSON via stdin with the shape:
# { "tool_name": "Bash", "tool_input": { "command": "..." } }
#
# Output: Exit 0 to allow, exit 2 to block, or print JSON to modify behavior.
# Read the full JSON input from stdin
INPUT=$(cat)
# Extract the command using portable sed (compatible with macOS and Linux)
COMMAND=$(echo "$INPUT" | sed -n 's/.*"command"[[:space:]]*:[[:space:]]*"\([^"]*\)".*/\1/p' | head -1)
# Fall back to the raw input if extraction fails
if [ -z "$COMMAND" ]; then
COMMAND="$INPUT"
fi
# ── Blocked patterns ──────────────────────────────────────────────────────────
# These commands are blocked unconditionally because they are almost always
# destructive and rarely intentional in an automated context.
BLOCKED_PATTERNS=(
"rm -rf /"
"rm -rf \*"
"dd if=/dev/zero"
"dd if=/dev/random"
":(){:|:&};:" # Fork bomb
"mkfs\." # Filesystem format
"format c:" # Windows disk format
)
for pattern in "${BLOCKED_PATTERNS[@]}"; do
if echo "$COMMAND" | grep -qE "$pattern"; then
echo "❌ Blocked: Potentially destructive command detected: $pattern"
echo " Command: $COMMAND"
exit 2
fi
done
# ── Warning patterns ──────────────────────────────────────────────────────────
# These patterns are risky but may be intentional. Log a warning and allow.
WARNING_PATTERNS=(
"rm -rf"
"git push --force"
"git reset --hard"
"git clean -f"
"chmod -R 777"
"sudo rm"
"DROP TABLE"
"DROP DATABASE"
"truncate"
)
WARNINGS=0
for pattern in "${WARNING_PATTERNS[@]}"; do
if echo "$COMMAND" | grep -qi "$pattern"; then
echo "⚠️ Warning: High-risk operation detected: $pattern"
WARNINGS=$((WARNINGS + 1))
fi
done
if [ "$WARNINGS" -gt 0 ]; then
echo " Command: $COMMAND"
echo " Proceeding — review the above warnings before continuing."
fi
# ── Allow ─────────────────────────────────────────────────────────────────────
exit 0
+78
View File
@@ -0,0 +1,78 @@
#!/bin/bash
# Security scan on file write
# Hook: PostToolUse:Write
#
# Scans files for hardcoded secrets, API keys, and credentials.
# Outputs a non-blocking warning via additionalContext when issues are found.
#
# Compatible with: macOS, Linux, Windows (Git Bash)
# Read JSON input from stdin (Claude Code hook protocol)
INPUT=$(cat)
# Extract file_path using sed (compatible with all platforms including Windows Git Bash)
# Avoids grep -P (not available on Windows Git Bash) and python3 dependency
FILE_PATH=$(echo "$INPUT" | sed -n 's/.*"file_path"[[:space:]]*:[[:space:]]*"\([^"]*\)".*/\1/p' | head -1)
if [ -z "$FILE_PATH" ] || [ ! -f "$FILE_PATH" ]; then
exit 0
fi
# Skip binary files, vendor dirs, and build artifacts
case "$FILE_PATH" in
*.png|*.jpg|*.jpeg|*.gif|*.svg|*.ico|*.woff|*.woff2|*.ttf|*.eot) exit 0 ;;
*/node_modules/*|*/.git/*|*/dist/*|*/build/*) exit 0 ;;
esac
ISSUES=""
# Check for hardcoded passwords
# Handles both JSON format ("password": "value") and code format (password = 'value')
# Use \\n as separator — it is a valid JSON newline escape and passes through printf safely
if grep -qiE '"password"[[:space:]]*:[[:space:]]*"[^"]+"' "$FILE_PATH" 2>/dev/null; then
ISSUES="${ISSUES}- WARNING: Potential hardcoded password detected\\n"
elif grep -qiE '(password|passwd|pwd)[[:space:]]*=[[:space:]]*'"'"'[^'"'"']+'"'"'' "$FILE_PATH" 2>/dev/null; then
ISSUES="${ISSUES}- WARNING: Potential hardcoded password detected\\n"
fi
# Check for hardcoded API keys
if grep -qiE '"(api[_-]?key|apikey|access[_-]?token)"[[:space:]]*:[[:space:]]*"[^"]+"' "$FILE_PATH" 2>/dev/null; then
ISSUES="${ISSUES}- WARNING: Potential hardcoded API key detected\\n"
fi
# Check for hardcoded secrets and tokens
if grep -qiE '(secret|token)[[:space:]]*=[[:space:]]*['"'"'"][^'"'"'"]+['"'"'"]' "$FILE_PATH" 2>/dev/null; then
ISSUES="${ISSUES}- WARNING: Potential hardcoded secret or token detected\\n"
fi
# Check for private keys
if grep -q "BEGIN.*PRIVATE KEY" "$FILE_PATH" 2>/dev/null; then
ISSUES="${ISSUES}- WARNING: Private key detected\\n"
fi
# Check for AWS keys
if grep -qE "AKIA[0-9A-Z]{16}" "$FILE_PATH" 2>/dev/null; then
ISSUES="${ISSUES}- WARNING: AWS access key detected\\n"
fi
# Scan with semgrep if available (stdout suppressed to avoid mixing with JSON output)
if command -v semgrep &> /dev/null; then
semgrep --config=auto "$FILE_PATH" --quiet >/dev/null 2>/dev/null
fi
# Scan with trufflehog if available (stdout suppressed to avoid mixing with JSON output)
if command -v trufflehog &> /dev/null; then
trufflehog filesystem "$FILE_PATH" --only-verified --quiet >/dev/null 2>/dev/null
fi
# If issues found, output as additionalContext (non-blocking warning)
# Use hookSpecificOutput format required by Claude Code PostToolUse protocol
if [ -n "$ISSUES" ]; then
# Escape file path for JSON (backslash and double-quote)
# ISSUES already uses \\n as separator (valid JSON escape) — only escape double-quotes
SAFE_PATH=$(printf '%s' "$FILE_PATH" | sed 's/\\/\\\\/g; s/"/\\"/g')
SAFE_ISSUES=$(printf '%s' "$ISSUES" | sed 's/"/\\"/g')
printf '{"hookSpecificOutput": {"hookEventName": "PostToolUse", "additionalContext": "Security scan found issues in %s:\\n%sPlease review and use environment variables instead."}}' "$SAFE_PATH" "$SAFE_ISSUES"
fi
exit 0
+54
View File
@@ -0,0 +1,54 @@
#!/bin/bash
# Validate user prompts
# Hook: UserPromptSubmit
#
# Reads the user prompt from stdin JSON and blocks dangerous operations.
#
# Compatible with: macOS, Linux, Windows (Git Bash)
# Read JSON input from stdin (Claude Code hook protocol)
INPUT=$(cat)
# Extract the prompt text from JSON input
# Claude Code sends UserPromptSubmit with field "user_prompt" (falls back to "prompt")
PROMPT=$(echo "$INPUT" | sed -n 's/.*"user_prompt"[[:space:]]*:[[:space:]]*"\([^"]*\)".*/\1/p' | head -1)
if [ -z "$PROMPT" ]; then
PROMPT=$(echo "$INPUT" | sed -n 's/.*"prompt"[[:space:]]*:[[:space:]]*"\([^"]*\)".*/\1/p' | head -1)
fi
if [ -z "$PROMPT" ]; then
exit 0
fi
# Check for dangerous operations
DANGEROUS_PATTERNS=(
"rm -rf /"
"delete database"
"drop database"
"format disk"
"dd if="
)
for pattern in "${DANGEROUS_PATTERNS[@]}"; do
if echo "$PROMPT" | grep -qi "$pattern"; then
printf '{"decision": "block", "reason": "Dangerous operation detected: %s"}' "$pattern"
exit 0
fi
done
# Check for production deployments
if echo "$PROMPT" | grep -qiE "(deploy|push).*production"; then
if [ ! -f ".deployment-approved" ]; then
echo '{"decision": "block", "reason": "Production deployment requires approval. Create .deployment-approved file to proceed."}'
exit 0
fi
fi
# Check for required context in certain operations
if echo "$PROMPT" | grep -qi "refactor"; then
if [ ! -d "tests" ] && [ ! -d "test" ]; then
printf '{"additionalContext": "Warning: Refactoring without tests may be risky. Consider writing tests first."}'
fi
fi
exit 0
+953
View File
@@ -0,0 +1,953 @@
<!-- i18n-source: 07-plugins/README.md -->
<!-- i18n-source-sha: 63a1416 -->
<!-- i18n-date: 2026-04-09 -->
<picture>
<source media="(prefers-color-scheme: dark)" srcset="../resources/logos/claude-howto-logo-dark.svg">
<img alt="Claude How To" src="../resources/logos/claude-howto-logo.svg">
</picture>
# Плагіни Claude Code
Ця папка містить повні приклади плагінів, які обʼєднують кілька функцій Claude Code у цілісні пакети, що встановлюються однією командою.
## Огляд
Плагіни Claude Code — це обʼєднані колекції кастомізацій (слеш-команди, субагенти, MCP-сервери та хуки), які встановлюються однією командою. Вони є механізмом розширення найвищого рівня — поєднуючи кілька функцій у цілісні пакети, якими можна ділитися.
## Архітектура плагінів
```mermaid
graph TB
A["Plugin"]
B["Slash Commands"]
C["Subagents"]
D["MCP Servers"]
E["Hooks"]
F["Configuration"]
A -->|bundles| B
A -->|bundles| C
A -->|bundles| D
A -->|bundles| E
A -->|bundles| F
```
## Процес завантаження плагіна
```mermaid
sequenceDiagram
participant User
participant Claude as Claude Code
participant Plugin as Plugin Marketplace
participant Install as Installation
participant SlashCmds as Slash Commands
participant Subagents
participant MCPServers as MCP Servers
participant Hooks
participant Tools as Configured Tools
User->>Claude: /plugin install pr-review
Claude->>Plugin: Download plugin manifest
Plugin-->>Claude: Return plugin definition
Claude->>Install: Extract components
Install->>SlashCmds: Configure
Install->>Subagents: Configure
Install->>MCPServers: Configure
Install->>Hooks: Configure
SlashCmds-->>Tools: Ready to use
Subagents-->>Tools: Ready to use
MCPServers-->>Tools: Ready to use
Hooks-->>Tools: Ready to use
Tools-->>Claude: Plugin installed ✅
```
## Типи та дистрибуція плагінів
| Тип | Область | Спільний | Авторитет | Приклади |
|-----|---------|----------|-----------|----------|
| Офіційний | Глобальний | Усі користувачі | Anthropic | PR Review, Security Guidance |
| Спільнота | Публічний | Усі користувачі | Спільнота | DevOps, Data Science |
| Організація | Внутрішній | Члени команди | Компанія | Внутрішні стандарти, інструменти |
| Персональний | Індивідуальний | Один користувач | Розробник | Кастомні робочі процеси |
## Структура визначення плагіна
Маніфест плагіна використовує формат JSON у файлі `.claude-plugin/plugin.json`:
```json
{
"name": "my-first-plugin",
"description": "A greeting plugin",
"version": "1.0.0",
"author": {
"name": "Your Name"
},
"homepage": "https://example.com",
"repository": "https://github.com/user/repo",
"license": "MIT"
}
```
## Приклад структури плагіна
```
my-plugin/
├── .claude-plugin/
│ └── plugin.json # Маніфест (назва, опис, версія, автор)
├── commands/ # Навички як Markdown-файли
│ ├── task-1.md
│ ├── task-2.md
│ └── workflows/
├── agents/ # Визначення кастомних агентів
│ ├── specialist-1.md
│ ├── specialist-2.md
│ └── configs/
├── skills/ # Навички агентів з файлами SKILL.md
│ ├── skill-1.md
│ └── skill-2.md
├── hooks/ # Обробники подій у hooks.json
│ └── hooks.json
├── .mcp.json # Конфігурації MCP-серверів
├── .lsp.json # Конфігурації LSP-серверів для інтелектуальної роботи з кодом
├── bin/ # Виконувані файли, додані до PATH інструменту Bash поки плагін увімкнено
├── settings.json # Стандартні налаштування при увімкненні плагіна (наразі підтримується лише ключ `agent`)
├── templates/
│ └── issue-template.md
├── scripts/
│ ├── helper-1.sh
│ └── helper-2.py
├── docs/
│ ├── README.md
│ └── USAGE.md
└── tests/
└── plugin.test.js
```
### Конфігурація LSP-сервера
Плагіни можуть включати підтримку Language Server Protocol (LSP — протокол мовного сервера) для інтелектуальної роботи з кодом у реальному часі. LSP-сервери надають діагностику, навігацію по коду та інформацію про символи під час роботи.
**Розташування конфігурації**:
- Файл `.lsp.json` у кореневому каталозі плагіна
- Інлайн-ключ `lsp` у `plugin.json`
#### Довідник полів
| Поле | Обовʼязкове | Опис |
|------|-------------|------|
| `command` | Так | Бінарний файл LSP-сервера (має бути в PATH) |
| `extensionToLanguage` | Так | Відповідність розширень файлів ідентифікаторам мов |
| `args` | Ні | Аргументи командного рядка для сервера |
| `transport` | Ні | Метод комунікації: `stdio` (за замовчуванням) або `socket` |
| `env` | Ні | Змінні оточення для процесу сервера |
| `initializationOptions` | Ні | Опції, що надсилаються під час ініціалізації LSP |
| `settings` | Ні | Конфігурація робочого простору, що передається серверу |
| `workspaceFolder` | Ні | Перевизначення шляху до папки робочого простору |
| `startupTimeout` | Ні | Максимальний час (мс) очікування запуску сервера |
| `shutdownTimeout` | Ні | Максимальний час (мс) для коректного завершення |
| `restartOnCrash` | Ні | Автоматичний перезапуск при збої сервера |
| `maxRestarts` | Ні | Максимальна кількість спроб перезапуску |
#### Приклади конфігурацій
**Go (gopls)**:
```json
{
"go": {
"command": "gopls",
"args": ["serve"],
"extensionToLanguage": {
".go": "go"
}
}
}
```
**Python (pyright)**:
```json
{
"python": {
"command": "pyright-langserver",
"args": ["--stdio"],
"extensionToLanguage": {
".py": "python",
".pyi": "python"
}
}
}
```
**TypeScript**:
```json
{
"typescript": {
"command": "typescript-language-server",
"args": ["--stdio"],
"extensionToLanguage": {
".ts": "typescript",
".tsx": "typescriptreact",
".js": "javascript",
".jsx": "javascriptreact"
}
}
}
```
#### Доступні LSP-плагіни
Офіційний маркетплейс включає попередньо налаштовані LSP-плагіни:
| Плагін | Мова | Бінарний файл сервера | Команда встановлення |
|--------|------|----------------------|---------------------|
| `pyright-lsp` | Python | `pyright-langserver` | `pip install pyright` |
| `typescript-lsp` | TypeScript/JavaScript | `typescript-language-server` | `npm install -g typescript-language-server typescript` |
| `rust-lsp` | Rust | `rust-analyzer` | Встановлення через `rustup component add rust-analyzer` |
#### Можливості LSP
Після налаштування LSP-сервери надають:
- **Миттєва діагностика** — помилки та попередження зʼявляються одразу після редагування
- **Навігація по коду** — перехід до визначення, пошук посилань, реалізацій
- **Інформація при наведенні** — сигнатури типів та документація при наведенні курсора
- **Список символів** — перегляд символів у поточному файлі або робочому просторі
## Опції плагіна (v2.1.83+)
Плагіни можуть оголошувати користувацькі опції в маніфесті через `userConfig`. Значення з позначкою `sensitive: true` зберігаються у системному сховищі ключів (keychain), а не в текстових файлах налаштувань:
```json
{
"name": "my-plugin",
"version": "1.0.0",
"userConfig": {
"apiKey": {
"description": "API key for the service",
"sensitive": true
},
"region": {
"description": "Deployment region",
"default": "us-east-1"
}
}
}
```
## Постійні дані плагіна (`${CLAUDE_PLUGIN_DATA}`) (v2.1.78+)
Плагіни мають доступ до каталогу постійного стану через змінну оточення `${CLAUDE_PLUGIN_DATA}`. Цей каталог є унікальним для кожного плагіна та зберігається між сесіями, що робить його придатним для кешів, баз даних та іншого постійного стану:
```json
{
"hooks": {
"PostToolUse": [
{
"command": "node ${CLAUDE_PLUGIN_DATA}/track-usage.js"
}
]
}
}
```
Каталог створюється автоматично при встановленні плагіна. Файли зберігаються до видалення плагіна.
## Інлайн-плагін через налаштування (`source: 'settings'`) (v2.1.80+)
Плагіни можна визначати інлайн у файлах налаштувань як записи маркетплейсу з полем `source: 'settings'`. Це дозволяє вбудовувати визначення плагіна безпосередньо, без окремого репозиторію або маркетплейсу:
```json
{
"pluginMarketplaces": [
{
"name": "inline-tools",
"source": "settings",
"plugins": [
{
"name": "quick-lint",
"source": "./local-plugins/quick-lint"
}
]
}
]
}
```
## Налаштування плагіна
Плагіни можуть постачатися з файлом `settings.json` для стандартної конфігурації. Наразі підтримується ключ `agent`, який встановлює основного агента потоку для плагіна:
```json
{
"agent": "agents/specialist-1.md"
}
```
Коли плагін включає `settings.json`, його стандартні значення застосовуються при встановленні. Користувачі можуть перевизначити ці налаштування у своїй конфігурації проєкту або користувача.
## Автономний vs плагін-підхід
| Підхід | Назви команд | Конфігурація | Найкраще для |
|--------|-------------|--------------|--------------|
| **Автономний** | `/hello` | Ручне налаштування в CLAUDE.md | Персональне, специфічне для проєкту |
| **Плагіни** | `/plugin-name:hello` | Автоматичне через plugin.json | Поширення, дистрибуція, командна робота |
Використовуйте **автономні слеш-команди** для швидких персональних робочих процесів. Використовуйте **плагіни**, коли хочете обʼєднати кілька функцій, поділитися з командою або опублікувати для дистрибуції.
## Практичні приклади
### Приклад 1: Плагін PR Review
**Файл:** `.claude-plugin/plugin.json`
```json
{
"name": "pr-review",
"version": "1.0.0",
"description": "Complete PR review workflow with security, testing, and docs",
"author": {
"name": "Anthropic"
},
"repository": "https://github.com/your-org/pr-review",
"license": "MIT"
}
```
**Файл:** `commands/review-pr.md`
```markdown
---
name: Review PR
description: Start comprehensive PR review with security and testing checks
---
# PR Review
This command initiates a complete pull request review including:
1. Security analysis
2. Test coverage verification
3. Documentation updates
4. Code quality checks
5. Performance impact assessment
```
**Файл:** `agents/security-reviewer.md`
```yaml
---
name: security-reviewer
description: Security-focused code review
tools: read, grep, diff
---
# Security Reviewer
Specializes in finding security vulnerabilities:
- Authentication/authorization issues
- Data exposure
- Injection attacks
- Secure configuration
```
**Встановлення:**
```bash
/plugin install pr-review
# Результат:
# ✅ 3 слеш-команди встановлено
# ✅ 3 субагенти налаштовано
# ✅ 2 MCP-сервери підключено
# ✅ 4 хуки зареєстровано
# ✅ Готово до використання!
```
### Приклад 2: Плагін DevOps
**Компоненти:**
```
devops-automation/
├── commands/
│ ├── deploy.md
│ ├── rollback.md
│ ├── status.md
│ └── incident.md
├── agents/
│ ├── deployment-specialist.md
│ ├── incident-commander.md
│ └── alert-analyzer.md
├── mcp/
│ ├── github-config.json
│ ├── kubernetes-config.json
│ └── prometheus-config.json
├── hooks/
│ ├── pre-deploy.js
│ ├── post-deploy.js
│ └── on-error.js
└── scripts/
├── deploy.sh
├── rollback.sh
└── health-check.sh
```
### Приклад 3: Плагін документації
**Обʼєднані компоненти:**
```
documentation/
├── commands/
│ ├── generate-api-docs.md
│ ├── generate-readme.md
│ ├── sync-docs.md
│ └── validate-docs.md
├── agents/
│ ├── api-documenter.md
│ ├── code-commentator.md
│ └── example-generator.md
├── mcp/
│ ├── github-docs-config.json
│ └── slack-announce-config.json
└── templates/
├── api-endpoint.md
├── function-docs.md
└── adr-template.md
```
## Маркетплейс плагінів
Офіційний каталог плагінів, керований Anthropic — `anthropics/claude-plugins-official`. Адміністратори підприємств також можуть створювати приватні маркетплейси для внутрішньої дистрибуції.
```mermaid
graph TB
A["Plugin Marketplace"]
B["Official<br/>anthropics/claude-plugins-official"]
C["Community<br/>Marketplace"]
D["Enterprise<br/>Private Registry"]
A --> B
A --> C
A --> D
B -->|Categories| B1["Development"]
B -->|Categories| B2["DevOps"]
B -->|Categories| B3["Documentation"]
C -->|Search| C1["DevOps Automation"]
C -->|Search| C2["Mobile Dev"]
C -->|Search| C3["Data Science"]
D -->|Internal| D1["Company Standards"]
D -->|Internal| D2["Legacy Systems"]
D -->|Internal| D3["Compliance"]
style A fill:#e1f5fe,stroke:#333,color:#333
style B fill:#e8f5e9,stroke:#333,color:#333
style C fill:#f3e5f5,stroke:#333,color:#333
style D fill:#fff3e0,stroke:#333,color:#333
```
### Конфігурація маркетплейсу
Підприємства та просунуті користувачі можуть контролювати поведінку маркетплейсу через налаштування:
| Налаштування | Опис |
|-------------|------|
| `extraKnownMarketplaces` | Додати додаткові джерела маркетплейсу крім стандартних |
| `strictKnownMarketplaces` | Контролювати, які маркетплейси дозволено додавати користувачам |
| `deniedPlugins` | Блок-список для запобігання встановленню конкретних плагінів (керований адміністратором) |
### Додаткові функції маркетплейсу
- **Стандартний таймаут git**: Збільшено з 30с до 120с для великих репозиторіїв плагінів
- **Кастомні npm-реєстри**: Плагіни можуть вказувати URL кастомних npm-реєстрів для розвʼязання залежностей
- **Фіксація версій**: Закріплення плагінів за конкретними версіями для відтворюваних середовищ
### Схема визначення маркетплейсу
Маркетплейси плагінів визначаються у `.claude-plugin/marketplace.json`:
```json
{
"name": "my-team-plugins",
"owner": "my-org",
"plugins": [
{
"name": "code-standards",
"source": "./plugins/code-standards",
"description": "Enforce team coding standards",
"version": "1.2.0",
"author": "platform-team"
},
{
"name": "deploy-helper",
"source": {
"source": "github",
"repo": "my-org/deploy-helper",
"ref": "v2.0.0"
},
"description": "Deployment automation workflows"
}
]
}
```
| Поле | Обовʼязкове | Опис |
|------|-------------|------|
| `name` | Так | Назва маркетплейсу в kebab-case |
| `owner` | Так | Організація або користувач, що підтримує маркетплейс |
| `plugins` | Так | Масив записів плагінів |
| `plugins[].name` | Так | Назва плагіна (kebab-case) |
| `plugins[].source` | Так | Джерело плагіна (рядок шляху або обʼєкт джерела) |
| `plugins[].description` | Ні | Короткий опис плагіна |
| `plugins[].version` | Ні | Рядок семантичної версії |
| `plugins[].author` | Ні | Імʼя автора плагіна |
### Типи джерел плагінів
Плагіни можуть завантажуватися з кількох місць:
| Джерело | Синтаксис | Приклад |
|---------|-----------|---------|
| **Відносний шлях** | Рядок шляху | `"./plugins/my-plugin"` |
| **GitHub** | `{ "source": "github", "repo": "owner/repo" }` | `{ "source": "github", "repo": "acme/lint-plugin", "ref": "v1.0" }` |
| **Git URL** | `{ "source": "url", "url": "..." }` | `{ "source": "url", "url": "https://git.internal/plugin.git" }` |
| **Підкаталог Git** | `{ "source": "git-subdir", "url": "...", "path": "..." }` | `{ "source": "git-subdir", "url": "https://github.com/org/monorepo.git", "path": "packages/plugin" }` |
| **npm** | `{ "source": "npm", "package": "..." }` | `{ "source": "npm", "package": "@acme/claude-plugin", "version": "^2.0" }` |
| **pip** | `{ "source": "pip", "package": "..." }` | `{ "source": "pip", "package": "claude-data-plugin", "version": ">=1.0" }` |
Джерела GitHub та git підтримують необовʼязкові поля `ref` (гілка/тег) та `sha` (хеш коміту) для фіксації версій.
### Методи дистрибуції
**GitHub (рекомендовано)**:
```bash
# Користувачі додають ваш маркетплейс
/plugin marketplace add owner/repo-name
```
**Інші git-сервіси** (потрібен повний URL):
```bash
/plugin marketplace add https://gitlab.com/org/marketplace-repo.git
```
**Приватні репозиторії**: Підтримуються через git credential helpers або токени оточення. Користувачі повинні мати доступ на читання до репозиторію.
**Подання до офіційного маркетплейсу**: Подавайте плагіни до курованого Anthropic маркетплейсу для ширшої дистрибуції через [claude.ai/settings/plugins/submit](https://claude.ai/settings/plugins/submit) або [platform.claude.com/plugins/submit](https://platform.claude.com/plugins/submit).
### Суворий режим (strict mode)
Контроль взаємодії визначень маркетплейсу з локальними файлами `plugin.json`:
| Налаштування | Поведінка |
|-------------|----------|
| `strict: true` (за замовчуванням) | Локальний `plugin.json` є авторитетним; запис маркетплейсу доповнює його |
| `strict: false` | Запис маркетплейсу є повним визначенням плагіна |
**Обмеження організації** через `strictKnownMarketplaces`:
| Значення | Ефект |
|----------|-------|
| Не встановлено | Без обмежень — користувачі можуть додавати будь-який маркетплейс |
| Порожній масив `[]` | Блокування — маркетплейси заборонені |
| Масив патернів | Білий список — дозволено лише маркетплейси, що відповідають патернам |
```json
{
"strictKnownMarketplaces": [
"my-org/*",
"github.com/trusted-vendor/*"
]
}
```
> **Увага**: У суворому режимі з `strictKnownMarketplaces` користувачі можуть встановлювати плагіни лише з маркетплейсів білого списку. Це корисно для корпоративних середовищ, що вимагають контрольованої дистрибуції плагінів.
## Встановлення та життєвий цикл плагіна
```mermaid
graph LR
A["Discover"] -->|Browse| B["Marketplace"]
B -->|Select| C["Plugin Page"]
C -->|View| D["Components"]
D -->|Install| E["/plugin install"]
E -->|Extract| F["Configure"]
F -->|Activate| G["Use"]
G -->|Check| H["Update"]
H -->|Available| G
G -->|Done| I["Disable"]
I -->|Later| J["Enable"]
J -->|Back| G
```
## Порівняння функцій плагінів
| Функція | Слеш-команда | Навичка | Субагент | Плагін |
|---------|-------------|---------|----------|--------|
| **Встановлення** | Ручне копіювання | Ручне копіювання | Ручна конфігурація | Одна команда |
| **Час налаштування** | 5 хвилин | 10 хвилин | 15 хвилин | 2 хвилини |
| **Обʼєднання** | Один файл | Один файл | Один файл | Кілька |
| **Версіонування** | Ручне | Ручне | Ручне | Автоматичне |
| **Поширення в команді** | Копіювання файлу | Копіювання файлу | Копіювання файлу | ID встановлення |
| **Оновлення** | Ручне | Ручне | Ручне | Автоматично доступне |
| **Залежності** | Немає | Немає | Немає | Можуть включати |
| **Маркетплейс** | Ні | Ні | Ні | Так |
| **Дистрибуція** | Репозиторій | Репозиторій | Репозиторій | Маркетплейс |
## CLI-команди плагінів
Усі операції з плагінами доступні як CLI-команди:
```bash
claude plugin install <n>@<marketplace> # Встановити з маркетплейсу
claude plugin uninstall <n> # Видалити плагін
claude plugin list # Список встановлених плагінів
claude plugin enable <n> # Увімкнути вимкнений плагін
claude plugin disable <n> # Вимкнути плагін
claude plugin validate # Валідація структури плагіна
```
## Методи встановлення
### З маркетплейсу
```bash
/plugin install plugin-name
# або з CLI:
claude plugin install plugin-name@marketplace-name
```
### Увімкнення / Вимкнення (з автовизначенням області)
```bash
/plugin enable plugin-name
/plugin disable plugin-name
```
### Локальний плагін (для розробки)
```bash
# CLI-прапорець для локального тестування (повторюваний для кількох плагінів)
claude --plugin-dir ./path/to/plugin
claude --plugin-dir ./plugin-a --plugin-dir ./plugin-b
```
### З Git-репозиторію
```bash
/plugin install github:username/repo
```
## Коли створювати плагін
```mermaid
graph TD
A["Should I create a plugin?"]
A -->|Need multiple components| B{"Multiple commands<br/>or subagents<br/>or MCPs?"}
B -->|Yes| C["✅ Create Plugin"]
B -->|No| D["Use Individual Feature"]
A -->|Team workflow| E{"Share with<br/>team?"}
E -->|Yes| C
E -->|No| F["Keep as Local Setup"]
A -->|Complex setup| G{"Needs auto<br/>configuration?"}
G -->|Yes| C
G -->|No| D
```
### Випадки використання плагінів
| Випадок | Рекомендація | Чому |
|---------|-------------|------|
| **Онбординг команди** | ✅ Плагін | Миттєве налаштування, усі конфігурації |
| **Налаштування фреймворку** | ✅ Плагін | Обʼєднує команди, специфічні для фреймворку |
| **Корпоративні стандарти** | ✅ Плагін | Централізована дистрибуція, контроль версій |
| **Швидка автоматизація** | ❌ Команда | Надмірна складність |
| **Одна предметна область** | ❌ Навичка | Занадто важко, використовуйте навичку |
| **Спеціалізований аналіз** | ❌ Субагент | Створіть вручну або використовуйте навичку |
| **Доступ до живих даних** | ❌ MCP | Автономний, не обʼєднуйте |
## Тестування плагіна
Перед публікацією протестуйте плагін локально за допомогою CLI-прапорця `--plugin-dir` (повторюваний для кількох плагінів):
```bash
claude --plugin-dir ./my-plugin
claude --plugin-dir ./my-plugin --plugin-dir ./another-plugin
```
Це запускає Claude Code з завантаженим плагіном, дозволяючи:
- Перевірити доступність усіх слеш-команд
- Протестувати коректну роботу субагентів та агентів
- Підтвердити правильне підключення MCP-серверів
- Валідувати виконання хуків
- Перевірити конфігурації LSP-серверів
- Виявити помилки конфігурації
## Гаряче перезавантаження (Hot-Reload)
Плагіни підтримують гаряче перезавантаження під час розробки. При зміні файлів плагіна Claude Code може автоматично виявляти зміни. Також можна примусово перезавантажити командою:
```bash
/reload-plugins
```
Це повторно зчитує всі маніфести плагінів, команди, агентів, навички, хуки та конфігурації MCP/LSP без перезапуску сесії.
## Керовані налаштування для плагінів
Адміністратори можуть контролювати поведінку плагінів в організації через керовані налаштування (managed settings):
| Налаштування | Опис |
|-------------|------|
| `enabledPlugins` | Білий список плагінів, увімкнених за замовчуванням |
| `deniedPlugins` | Блок-список плагінів, які не можна встановити |
| `extraKnownMarketplaces` | Додаткові джерела маркетплейсу крім стандартних |
| `strictKnownMarketplaces` | Обмеження маркетплейсів, які дозволено додавати користувачам |
| `allowedChannelPlugins` | Контроль дозволених плагінів для кожного каналу випуску |
Ці налаштування можна застосувати на рівні організації через файли керованої конфігурації, і вони мають пріоритет над налаштуваннями рівня користувача.
## Безпека плагінів
Субагенти плагінів працюють в обмеженій пісочниці (sandbox). Наступні ключі frontmatter **заборонені** у визначеннях субагентів плагінів:
- `hooks` — субагенти не можуть реєструвати обробники подій
- `mcpServers` — субагенти не можуть налаштовувати MCP-сервери
- `permissionMode` — субагенти не можуть перевизначати модель дозволів
Це гарантує, що плагіни не можуть підвищити привілеї або модифікувати хост-середовище за межами оголошеної області.
## Публікація плагіна
**Кроки для публікації:**
1. Створити структуру плагіна з усіма компонентами
2. Написати маніфест `.claude-plugin/plugin.json`
3. Створити `README.md` з документацією
4. Протестувати локально за допомогою `claude --plugin-dir ./my-plugin`
5. Подати до маркетплейсу плагінів
6. Пройти перевірку та затвердження
7. Публікація в маркетплейсі
8. Користувачі можуть встановити однією командою
**Приклад подання:**
```markdown
# PR Review Plugin
## Description
Complete PR review workflow with security, testing, and documentation checks.
## What's Included
- 3 slash commands for different review types
- 3 specialized subagents
- GitHub and CodeQL MCP integration
- Automated security scanning hooks
## Installation
```bash
/plugin install pr-review
```
## Features
✅ Security analysis
✅ Test coverage checking
✅ Documentation verification
✅ Code quality assessment
✅ Performance impact analysis
## Usage
```bash
/review-pr
/check-security
/check-tests
```
## Requirements
- Claude Code 1.0+
- GitHub access
- CodeQL (optional)
```
## Плагін vs ручна конфігурація
**Ручне налаштування (2+ години):**
- Встановити слеш-команди одну за одною
- Створити субагентів окремо
- Налаштувати MCP окремо
- Встановити хуки вручну
- Задокументувати все
- Поширити в команді (сподіватися, що налаштують правильно)
**З плагіном (2 хвилини):**
```bash
/plugin install pr-review
# ✅ Все встановлено та налаштовано
# ✅ Готово до використання одразу
# ✅ Команда може відтворити точну конфігурацію
```
## Найкращі практики
### Рекомендовано ✅
- Використовуйте зрозумілі, описові назви плагінів
- Включайте вичерпний README
- Версіонуйте плагін правильно (semver — семантичне версіонування)
- Тестуйте всі компоненти разом
- Документуйте вимоги чітко
- Надавайте приклади використання
- Включайте обробку помилок
- Тегуйте належним чином для виявлення
- Підтримуйте зворотну сумісність
- Тримайте плагіни зосередженими та цілісними
- Включайте вичерпні тести
- Документуйте всі залежності
### Не рекомендовано ❌
- Не обʼєднуйте неповʼязані функції
- Не зашивайте облікові дані в код
- Не пропускайте тестування
- Не забувайте про документацію
- Не створюйте надлишкових плагінів
- Не ігноруйте версіонування
- Не ускладнюйте залежності компонентів
- Не забувайте обробляти помилки коректно
## Інструкції зі встановлення
### Встановлення з маркетплейсу
1. **Перегляд доступних плагінів:**
```bash
/plugin list
```
2. **Деталі плагіна:**
```bash
/plugin info plugin-name
```
3. **Встановлення плагіна:**
```bash
/plugin install plugin-name
```
### Встановлення з локального шляху
```bash
/plugin install ./path/to/plugin-directory
```
### Встановлення з GitHub
```bash
/plugin install github:username/repo
```
### Список встановлених плагінів
```bash
/plugin list --installed
```
### Оновлення плагіна
```bash
/plugin update plugin-name
```
### Вимкнення/Увімкнення плагіна
```bash
# Тимчасове вимкнення
/plugin disable plugin-name
# Повторне увімкнення
/plugin enable plugin-name
```
### Видалення плагіна
```bash
/plugin uninstall plugin-name
```
## Повʼязані концепції
Наступні функції Claude Code працюють разом з плагінами:
- **[Слеш-команди](../01-slash-commands/)** — окремі команди, обʼєднані в плагіни
- **[Памʼять](../02-memory/)** — постійний контекст для плагінів
- **[Навички](../03-skills/)** — предметна експертиза, яку можна обгорнути в плагіни
- **[Субагенти](../04-subagents/)** — спеціалізовані агенти як компоненти плагінів
- **[MCP-сервери](../05-mcp/)** — інтеграції Model Context Protocol, обʼєднані в плагіни
- **[Хуки](../06-hooks/)** — обробники подій, що запускають робочі процеси плагінів
## Повний приклад робочого процесу
### Повний робочий процес плагіна PR Review
```
1. Користувач: /review-pr
2. Плагін виконує:
├── pre-review.js хук валідує git-репо
├── GitHub MCP отримує дані PR
├── security-reviewer субагент аналізує безпеку
├── test-checker субагент перевіряє покриття
└── performance-analyzer субагент перевіряє продуктивність
3. Результати синтезуються та представляються:
✅ Безпека: Критичних проблем не виявлено
⚠️ Тестування: Покриття 65% (рекомендовано 80%+)
✅ Продуктивність: Значного впливу немає
📝 Надано 12 рекомендацій
```
## Усунення несправностей
### Плагін не встановлюється
- Перевірте сумісність версії Claude Code: `/version`
- Перевірте синтаксис `plugin.json` валідатором JSON
- Перевірте підключення до інтернету (для віддалених плагінів)
- Перевірте дозволи: `ls -la plugin/`
### Компоненти не завантажуються
- Переконайтеся, що шляхи в `plugin.json` відповідають фактичній структурі каталогів
- Перевірте дозволи файлів: `chmod +x scripts/`
- Перегляньте синтаксис файлів компонентів
- Перевірте журнали: `/plugin debug plugin-name`
### Збій підключення MCP
- Переконайтеся, що змінні оточення встановлені правильно
- Перевірте встановлення та працездатність MCP-сервера
- Протестуйте підключення MCP окремо за допомогою `/mcp test`
- Перегляньте конфігурацію MCP у каталозі `mcp/`
### Команди недоступні після встановлення
- Переконайтеся, що плагін встановлено успішно: `/plugin list --installed`
- Перевірте, чи плагін увімкнено: `/plugin status plugin-name`
- Перезапустіть Claude Code: `exit` та відкрийте знову
- Перевірте конфлікти назв з існуючими командами
### Проблеми з виконанням хуків
- Переконайтеся, що файли хуків мають правильні дозволи
- Перевірте синтаксис хуків та назви подій
- Перегляньте журнали хуків для деталей помилок
- Протестуйте хуки вручну, якщо можливо
## Додаткові ресурси
- [Офіційна документація плагінів](https://code.claude.com/docs/en/plugins)
- [Каталог плагінів](https://code.claude.com/docs/en/discover-plugins)
- [Маркетплейси плагінів](https://code.claude.com/docs/en/plugin-marketplaces)
- [Довідник плагінів](https://code.claude.com/docs/en/plugins-reference)
- [Довідник MCP-серверів](https://modelcontextprotocol.io/)
- [Посібник конфігурації субагентів](../04-subagents/README.md)
- [Довідник системи хуків](../06-hooks/README.md)
---
**Останнє оновлення**: 9 квітня 2026
**Версія Claude Code**: 2.1.97
**Сумісні моделі**: Claude Sonnet 4.6, Claude Opus 4.6, Claude Haiku 4.5
@@ -0,0 +1,9 @@
{
"name": "devops-automation",
"version": "1.0.0",
"description": "Complete DevOps automation for deployment, monitoring, and incident response",
"author": {
"name": "Community"
},
"license": "MIT"
}
+107
View File
@@ -0,0 +1,107 @@
<picture>
<source media="(prefers-color-scheme: dark)" srcset="../../resources/logos/claude-howto-logo-dark.svg">
<img alt="Claude How To" src="../../resources/logos/claude-howto-logo.svg">
</picture>
# Плагін DevOps Automation
Повна автоматизація DevOps для розгортання, моніторингу та реагування на інциденти.
## Функції
✅ Автоматизовані розгортання
✅ Процедури відкату
✅ Моніторинг стану системи
✅ Робочі процеси реагування на інциденти
✅ Інтеграція з Kubernetes
## Встановлення
```bash
/plugin install devops-automation
```
## Що включено
### Слеш-команди
- `/deploy` — Розгортання на продакшен або стейджинг
- `/rollback` — Відкат до попередньої версії
- `/status` — Перевірка стану системи
- `/incident` — Обробка інцидентів на продакшені
### Субагенти
- `deployment-specialist` — Операції розгортання
- `incident-commander` — Координація інцидентів
- `alert-analyzer` — Аналіз стану системи
### MCP-сервери
- Інтеграція з Kubernetes
### Скрипти
- `deploy.sh` — Автоматизація розгортання
- `rollback.sh` — Автоматизація відкату
- `health-check.sh` — Утиліти перевірки стану
### Хуки
- `pre-deploy.js` — Передрозгортальна валідація
- `post-deploy.js` — Післярозгортальні завдання
## Використання
### Розгортання на стейджинг
```
/deploy staging
```
### Розгортання на продакшен
```
/deploy production
```
### Відкат
```
/rollback production
```
### Перевірка стану
```
/status
```
### Обробка інциденту
```
/incident
```
## Вимоги
- Claude Code 1.0+
- Kubernetes CLI (kubectl)
- Налаштований доступ до кластера
## Конфігурація
Налаштуйте конфіг Kubernetes:
```bash
export KUBECONFIG=~/.kube/config
```
## Приклад робочого процесу
```
User: /deploy production
Claude:
1. Запускає pre-deploy хук (валідація kubectl, з'єднання з кластером)
2. Делегує субагенту deployment-specialist
3. Запускає скрипт deploy.sh
4. Моніторить прогрес розгортання через Kubernetes MCP
5. Запускає post-deploy хук (очікування подів, smoke-тести)
6. Надає підсумок розгортання
Результат:
✅ Розгортання завершено
📦 Версія: v2.1.0
🚀 Поди: 3/3 готові
⏱️ Час: 2хв 34с
```
@@ -0,0 +1,14 @@
---
name: alert-analyzer
description: Аналізує алерти моніторингу та метрики системи
tools: read, grep, bash
---
# Аналізатор алертів
Аналізує стан системи та алерти:
- Кореляція алертів
- Аналіз трендів
- Визначення першопричини
- Візуалізація метрик
- Проактивне виявлення проблем
@@ -0,0 +1,14 @@
---
name: deployment-specialist
description: Обробляє всі операції розгортання
tools: read, write, bash, grep
---
# Спеціаліст з розгортання
Експерт з операцій розгортання:
- Blue-green розгортання
- Канаркові релізи
- Процедури відкату
- Перевірки стану
- Міграції бази даних
@@ -0,0 +1,14 @@
---
name: incident-commander
description: Координує реагування на інциденти
tools: read, write, bash, grep
---
# Командир інцидентів
Керує реагуванням на інциденти:
- Оцінка серйозності
- Координація команди
- Оновлення статусу
- Відстеження розв'язання
- Фасилітація post-mortem
@@ -0,0 +1,15 @@
---
name: Deploy
description: Розгортання застосунку на продакшен або стейджинг
---
# Розгортання застосунку
Виконання робочого процесу розгортання:
1. Запуск передрозгортальних перевірок
2. Збірка застосунку
3. Запуск тестів
4. Розгортання на цільове середовище
5. Запуск перевірок стану
6. Повідомлення команди в Slack
@@ -0,0 +1,16 @@
---
name: Incident Response
description: Обробка інцидентів на продакшені зі структурованим реагуванням
---
# Реагування на інциденти
Структурований процес реагування на інциденти:
1. Створення запису інциденту
2. Оцінка серйозності та впливу
3. Повідомлення чергової команди
4. Збір діагностичної інформації
5. Координація зусиль з реагування
6. Документування розв'язання
7. Планування post-mortem
@@ -0,0 +1,14 @@
---
name: Rollback
description: Відкат до попереднього розгортання
---
# Відкат розгортання
Відкат до попередньої стабільної версії:
1. Визначення попереднього розгортання
2. Перевірка працездатності цілі відкату
3. Виконання процедури відкату
4. Запуск перевірок стану
5. Повідомлення команди
@@ -0,0 +1,15 @@
---
name: System Status
description: Перевірка загального стану та працездатності системи
---
# Перевірка стану системи
Перевірка стану системи по всіх сервісах:
1. Запит статусу подів Kubernetes
2. Перевірка з'єднань з базою даних
3. Моніторинг часу відповіді API
4. Перегляд частоти помилок
5. Перевірка використання ресурсів
6. Звіт про загальний стан
@@ -0,0 +1,34 @@
#!/usr/bin/env node
/**
* Post-deployment hook
* Runs after deployment completes
*/
async function postDeploy() {
console.log('Running post-deployment tasks...');
const { execSync } = require('child_process');
// Wait for pods to be ready
console.log('Waiting for pods to be ready...');
try {
execSync('kubectl wait --for=condition=ready pod -l app=myapp --timeout=300s', {
stdio: 'inherit'
});
} catch (error) {
console.error('❌ Pods failed to become ready');
process.exit(1);
}
// Run smoke tests
console.log('Running smoke tests...');
// Add your smoke test commands here
console.log('✅ Post-deployment tasks complete');
}
postDeploy().catch(error => {
console.error('Post-deploy hook failed:', error);
process.exit(1);
});
@@ -0,0 +1,35 @@
#!/usr/bin/env node
/**
* Pre-deployment hook
* Validates environment and prerequisites before deployment
*/
async function preDeploy() {
console.log('Running pre-deployment checks...');
const { execSync } = require('child_process');
// Check if kubectl is installed
try {
execSync('which kubectl', { stdio: 'pipe' });
} catch (error) {
console.error('❌ kubectl not found. Please install Kubernetes CLI.');
process.exit(1);
}
// Check if connected to cluster
try {
execSync('kubectl cluster-info', { stdio: 'pipe' });
} catch (error) {
console.error('❌ Not connected to Kubernetes cluster');
process.exit(1);
}
console.log('✅ Pre-deployment checks passed');
}
preDeploy().catch(error => {
console.error('Pre-deploy hook failed:', error);
process.exit(1);
});
@@ -0,0 +1,11 @@
{
"mcpServers": {
"kubernetes": {
"command": "npx",
"args": ["@modelcontextprotocol/server-kubernetes"],
"env": {
"KUBECONFIG": "${KUBECONFIG}"
}
}
}
}
@@ -0,0 +1,28 @@
#!/bin/bash
set -e
echo "🚀 Starting deployment..."
# Load environment
ENV=${1:-staging}
echo "📦 Target environment: $ENV"
# Pre-deployment checks
echo "✓ Running pre-deployment checks..."
npm run lint
npm test
# Build
echo "🔨 Building application..."
npm run build
# Deploy
echo "🚢 Deploying to $ENV..."
kubectl apply -f k8s/$ENV/
# Health check
echo "🏥 Running health checks..."
sleep 10
curl -f http://api.$ENV.example.com/health
echo "✅ Deployment complete!"
@@ -0,0 +1,30 @@
#!/bin/bash
echo "🏥 System Health Check"
echo "===================="
ENV=${1:-production}
# Check API
echo -n "API: "
if curl -sf http://api.$ENV.example.com/health > /dev/null; then
echo "✅ Healthy"
else
echo "❌ Unhealthy"
fi
# Check Database
echo -n "Database: "
if pg_isready -h db.$ENV.example.com > /dev/null 2>&1; then
echo "✅ Healthy"
else
echo "❌ Unhealthy"
fi
# Check Pods
echo -n "Kubernetes Pods: "
PODS_READY=$(kubectl get pods -n $ENV --no-headers | grep "Running" | wc -l)
PODS_TOTAL=$(kubectl get pods -n $ENV --no-headers | wc -l)
echo "$PODS_READY/$PODS_TOTAL ready"
echo "===================="
@@ -0,0 +1,25 @@
#!/bin/bash
set -e
echo "⏪ Starting rollback..."
ENV=${1:-staging}
echo "📦 Target environment: $ENV"
# Get previous deployment
PREVIOUS=$(kubectl rollout history deployment/app -n $ENV | tail -2 | head -1 | awk '{print $1}')
echo "🔄 Rolling back to revision: $PREVIOUS"
# Execute rollback
kubectl rollout undo deployment/app -n $ENV
# Wait for rollback
echo "⏳ Waiting for rollback to complete..."
kubectl rollout status deployment/app -n $ENV
# Health check
echo "🏥 Running health checks..."
sleep 5
curl -f http://api.$ENV.example.com/health
echo "✅ Rollback complete!"
@@ -0,0 +1,9 @@
{
"name": "documentation",
"version": "1.0.0",
"description": "Comprehensive documentation generation and maintenance",
"author": {
"name": "Community"
},
"license": "MIT"
}
+119
View File
@@ -0,0 +1,119 @@
<picture>
<source media="(prefers-color-scheme: dark)" srcset="../../resources/logos/claude-howto-logo-dark.svg">
<img alt="Claude How To" src="../../resources/logos/claude-howto-logo.svg">
</picture>
# Плагін Documentation
Комплексна генерація та підтримка документації для вашого проєкту.
## Функції
✅ Генерація API-документації
✅ Створення та оновлення README
✅ Синхронізація документації
✅ Покращення коментарів коду
✅ Генерація прикладів
## Встановлення
```bash
/plugin install documentation
```
## Що включено
### Слеш-команди
- `/generate-api-docs` — Генерація API-документації
- `/generate-readme` — Створення або оновлення README
- `/sync-docs` — Синхронізація документації зі змінами коду
- `/validate-docs` — Валідація документації
### Субагенти
- `api-documenter` — Спеціаліст з API-документації
- `code-commentator` — Покращення коментарів коду
- `example-generator` — Створення прикладів коду
### Шаблони
- `api-endpoint.md` — Шаблон документації ендпоінту API
- `function-docs.md` — Шаблон документації функції
- `adr-template.md` — Шаблон Architecture Decision Record
### MCP-сервери
- Інтеграція з GitHub для синхронізації документації
## Використання
### Генерація API-документації
```
/generate-api-docs
```
### Створення README
```
/generate-readme
```
### Синхронізація документації
```
/sync-docs
```
### Валідація документації
```
/validate-docs
```
## Вимоги
- Claude Code 1.0+
- Доступ до GitHub (опціонально)
## Приклад робочого процесу
```
User: /generate-api-docs
Claude:
1. Сканує всі API-ендпоінти в /src/api/
2. Делегує субагенту api-documenter
3. Витягує сигнатури функцій та JSDoc
4. Організує за модулями/ендпоінтами
5. Використовує шаблон api-endpoint.md
6. Генерує комплексну markdown-документацію
7. Включає приклади curl, JavaScript та Python
Результат:
✅ API-документація згенерована
📄 Створені файли:
- docs/api/users.md
- docs/api/auth.md
- docs/api/products.md
📊 Покриття: 23/23 ендпоінти задокументовано
```
## Використання шаблонів
### Шаблон ендпоінту API
Використовуйте для документування REST API ендпоінтів з повними прикладами.
### Шаблон документації функції
Використовуйте для документування окремих функцій/методів.
### Шаблон ADR
Використовуйте для документування архітектурних рішень.
## Конфігурація
Налаштуйте GitHub-токен для синхронізації документації:
```bash
export GITHUB_TOKEN="your_github_token"
```
## Найкращі практики
- Тримайте документацію близько до коду
- Оновлюйте документацію разом зі змінами коду
- Включайте практичні приклади
- Регулярно валідуйте
- Використовуйте шаблони для консистентності
@@ -0,0 +1,14 @@
---
name: api-documenter
description: Спеціаліст з API-документації
tools: read, write, grep
---
# API-документатор
Створює комплексну API-документацію:
- Документація ендпоінтів
- Описи параметрів
- Схеми відповідей
- Приклади коду (curl, JS, Python)
- Коди помилок
@@ -0,0 +1,14 @@
---
name: code-commentator
description: Спеціаліст з коментарів коду та інлайн-документації
tools: read, write, edit
---
# Коментатор коду
Покращує документацію коду:
- JSDoc/docstring коментарі
- Інлайн-пояснення
- Описи параметрів
- Документація типів повернення
- Приклади використання
@@ -0,0 +1,14 @@
---
name: example-generator
description: Спеціаліст з прикладів коду та туторіалів
tools: read, write
---
# Генератор прикладів
Створює практичні приклади коду:
- Гайди початку роботи
- Поширені сценарії використання
- Приклади інтеграції
- Найкращі практики
- Сценарії усунення проблем
@@ -0,0 +1,15 @@
---
name: Generate API Documentation
description: Генерація комплексної API-документації з вихідного коду
---
# Генератор API-документації
Генерація повної API-документації:
1. Сканування API-ендпоінтів
2. Витягування сигнатур функцій та JSDoc
3. Організація за модулями/ендпоінтами
4. Створення markdown з прикладами
5. Включення схем запитів/відповідей
6. Додавання документації помилок
@@ -0,0 +1,15 @@
---
name: Generate README
description: Створення або оновлення README проєкту
---
# Генератор README
Генерація комплексного README:
1. Огляд та опис проєкту
2. Інструкції з встановлення
3. Приклади використання
4. Посилання на API-документацію
5. Настанови для контриб'юторів
6. Інформація про ліцензію
@@ -0,0 +1,14 @@
---
name: Sync Documentation
description: Синхронізація документації зі змінами коду
---
# Синхронізація документації
Синхронізація документації з кодовою базою:
1. Виявлення змін коду
2. Визначення застарілої документації
3. Оновлення уражених документів
4. Перевірка працездатності прикладів
5. Оновлення номерів версій
@@ -0,0 +1,14 @@
---
name: Validate Documentation
description: Валідація документації на повноту та точність
---
# Валідація документації
Перевірка якості документації:
1. Перевірка на зламані посилання
2. Верифікація прикладів коду
3. Забезпечення повноти
4. Перевірка форматування
5. Валідація відповідності реальному коду
@@ -0,0 +1,11 @@
{
"mcpServers": {
"github": {
"command": "npx",
"args": ["@modelcontextprotocol/server-github"],
"env": {
"GITHUB_TOKEN": "${GITHUB_TOKEN}"
}
}
}
}
@@ -0,0 +1,39 @@
# ADR [Номер]: [Назва]
## Статус
[Запропоновано | Прийнято | Застаріло | Замінено]
## Контекст
Яка проблема спонукає це рішення або зміну?
## Рішення
Яку зміну ми пропонуємо та/або впроваджуємо?
## Наслідки
Що стає простішим або складнішим через цю зміну?
### Позитивні
- Перевага 1
- Перевага 2
### Негативні
- Недолік 1
- Недолік 2
### Нейтральні
- Міркування 1
- Міркування 2
## Розглянуті альтернативи
Які інші варіанти було розглянуто та чому їх не обрано?
### Альтернатива 1
Опис та причина відхилення.
### Альтернатива 2
Опис та причина відхилення.
## Посилання
- Пов'язані ADR
- Зовнішня документація
- Посилання на обговорення
@@ -0,0 +1,101 @@
# [METHOD] /api/v1/[endpoint]
## Опис
Короткий опис що робить цей ендпоінт.
## Автентифікація
Необхідний метод автентифікації (напр., Bearer token).
## Параметри
### Параметри шляху
| Назва | Тип | Обов'язковий | Опис |
|-------|-----|-------------|------|
| id | string | Так | ID ресурсу |
### Параметри запиту
| Назва | Тип | Обов'язковий | Опис |
|-------|-----|-------------|------|
| page | integer | Ні | Номер сторінки (за замовч.: 1) |
| limit | integer | Ні | Елементів на сторінку (за замовч.: 20) |
### Тіло запиту
```json
{
"field": "value"
}
```
## Відповіді
### 200 OK
```json
{
"success": true,
"data": {
"id": "123",
"name": "Example"
}
}
```
### 400 Bad Request
```json
{
"success": false,
"error": {
"code": "VALIDATION_ERROR",
"message": "Invalid input"
}
}
```
### 404 Not Found
```json
{
"success": false,
"error": {
"code": "NOT_FOUND",
"message": "Resource not found"
}
}
```
## Приклади
### cURL
```bash
curl -X GET "https://api.example.com/api/v1/endpoint" \
-H "Authorization: Bearer YOUR_TOKEN" \
-H "Content-Type: application/json"
```
### JavaScript
```javascript
const response = await fetch('/api/v1/endpoint', {
headers: {
'Authorization': 'Bearer token',
'Content-Type': 'application/json'
}
});
const data = await response.json();
```
### Python
```python
import requests
response = requests.get(
'https://api.example.com/api/v1/endpoint',
headers={'Authorization': 'Bearer token'}
)
data = response.json()
```
## Обмеження частоти запитів
- 1000 запитів на годину для автентифікованих користувачів
- 100 запитів на годину для публічних ендпоінтів
## Пов'язані ендпоінти
- [GET /api/v1/related](#)
- [POST /api/v1/related](#)
@@ -0,0 +1,50 @@
# Функція: `functionName`
## Опис
Короткий опис що робить функція.
## Сигнатура
```typescript
function functionName(param1: Type1, param2: Type2): ReturnType
```
## Параметри
| Параметр | Тип | Обов'язковий | Опис |
|----------|-----|-------------|------|
| param1 | Type1 | Так | Опис param1 |
| param2 | Type2 | Ні | Опис param2 |
## Повертає
**Тип**: `ReturnType`
Опис того, що повертається.
## Кидає виключення
- `Error`: При невалідному введенні
- `TypeError`: При неправильному типі
## Приклади
### Базове використання
```typescript
const result = functionName('value1', 'value2');
console.log(result);
```
### Просунуте використання
```typescript
const result = functionName(
complexParam1,
{ option: true }
);
```
## Нотатки
- Додаткові нотатки або попередження
- Міркування щодо продуктивності
- Найкращі практики
## Див. також
- [Пов'язана функція](#)
- [API-документація](#)
@@ -0,0 +1,9 @@
{
"name": "pr-review",
"version": "1.0.0",
"description": "Complete PR review workflow with security, testing, and docs",
"author": {
"name": "Anthropic"
},
"license": "MIT"
}
+91
View File
@@ -0,0 +1,91 @@
<picture>
<source media="(prefers-color-scheme: dark)" srcset="../../resources/logos/claude-howto-logo-dark.svg">
<img alt="Claude How To" src="../../resources/logos/claude-howto-logo.svg">
</picture>
# Плагін PR Review
Повний робочий процес рев'ю PR з перевірками безпеки, тестування та документації.
## Функції
✅ Аналіз безпеки
✅ Перевірка покриття тестами
✅ Верифікація документації
✅ Оцінка якості коду
✅ Аналіз впливу на продуктивність
## Встановлення
```bash
/plugin install pr-review
```
## Що включено
### Слеш-команди
- `/review-pr` — Комплексне рев'ю PR
- `/check-security` — Рев'ю з фокусом на безпеці
- `/check-tests` — Аналіз покриття тестами
### Субагенти
- `security-reviewer` — Виявлення вразливостей безпеки
- `test-checker` — Аналіз покриття тестами
- `performance-analyzer` — Оцінка впливу на продуктивність
### MCP-сервери
- Інтеграція з GitHub для даних PR
### Хуки
- `pre-review.js` — Передрев'юшна валідація
## Використання
### Базове рев'ю PR
```
/review-pr
```
### Тільки перевірка безпеки
```
/check-security
```
### Перевірка покриття тестами
```
/check-tests
```
## Вимоги
- Claude Code 1.0+
- Доступ до GitHub
- Git-репозиторій
## Конфігурація
Налаштуйте GitHub-токен:
```bash
export GITHUB_TOKEN="your_github_token"
```
## Приклад робочого процесу
```
User: /review-pr
Claude:
1. Запускає pre-review хук (валідація git-репозиторію)
2. Отримує дані PR через GitHub MCP
3. Делегує рев'ю безпеки субагенту security-reviewer
4. Делегує тестування субагенту test-checker
5. Делегує продуктивність субагенту performance-analyzer
6. Синтезує всі знахідки
7. Надає комплексний звіт рев'ю
Результат:
✅ Безпека: Критичних проблем не знайдено
⚠️ Тестування: Покриття 65%, рекомендовано 80%+
✅ Продуктивність: Суттєвого впливу немає
📝 Рекомендації: Додати тести для граничних випадків
```
@@ -0,0 +1,13 @@
---
name: performance-analyzer
description: Аналіз впливу на продуктивність
tools: read, grep, bash
---
# Аналізатор продуктивності
Оцінює вплив змін на продуктивність:
- Складність алгоритмів
- Ефективність запитів до бази даних
- Використання пам'яті
- Можливості кешування
@@ -0,0 +1,13 @@
---
name: security-reviewer
description: Код-рев'ю з фокусом на безпеці
tools: read, grep, diff
---
# Рецензент безпеки
Спеціалізується на виявленні вразливостей безпеки:
- Проблеми автентифікації/авторизації
- Витоки даних
- Атаки ін'єкцій
- Безпечна конфігурація
@@ -0,0 +1,13 @@
---
name: test-checker
description: Аналіз покриття тестами та їх якості
tools: read, bash, grep
---
# Перевірник тестів
Аналізує покриття тестами та їх якість:
- Відсоток покриття
- Відсутні тест-кейси
- Оцінка якості тестів
- Визначення граничних випадків
@@ -0,0 +1,14 @@
---
name: Security Check
description: Запуск рев'ю коду з фокусом на безпеці
---
# Перевірка безпеки
Цілеспрямований аналіз безпеки змін коду:
1. Перевірки автентифікації/авторизації
2. Ризики витоку даних
3. Вразливості ін'єкцій
4. Криптографічні слабкості
5. Чутливі дані в логах

Some files were not shown because too many files have changed in this diff Show More