Initial commit
This commit is contained in:
97
skills/bugsnag/README.md
Normal file
97
skills/bugsnag/README.md
Normal file
@@ -0,0 +1,97 @@
|
||||
# Bugsnag Skill
|
||||
|
||||
Skill для интеграции с Bugsnag API, позволяющий просматривать и управлять ошибками в проекте.
|
||||
|
||||
## Возможности
|
||||
|
||||
- 🏢 **Управление организациями** - Просмотр списка доступных организаций в Bugsnag
|
||||
- 📦 **Управление проектами** - Просмотр списка доступных проектов
|
||||
- 📋 **Просмотр текущих ошибок** - Получение списка активных ошибок из Bugsnag
|
||||
- 🔍 **Детальный контекст ошибки** - Просмотр полной информации об ошибке включая stack trace
|
||||
- ✅ **Управление статусами** - Пометка ошибок как выполненные (resolved)
|
||||
- 📈 **Анализ паттернов** - Автоматический анализ повторяющихся ошибок
|
||||
- 🔐 **Безопасная авторизация** - Использование API ключей из переменных окружения
|
||||
|
||||
## Использование
|
||||
|
||||
### Быстрый доступ (Slash Commands)
|
||||
|
||||
Рекомендуется для частых операций:
|
||||
|
||||
```bash
|
||||
# Работа с ошибками
|
||||
/bugsnag:list # Список всех ошибок
|
||||
/bugsnag:list --limit 50 # С фильтрами
|
||||
/bugsnag:open # Только открытые ошибки
|
||||
/bugsnag:details ERROR_ID # Детали ошибки
|
||||
|
||||
# Комментарии
|
||||
/bugsnag:comments ERROR_ID # Просмотр комментариев
|
||||
/bugsnag:comment ERROR_ID "text" # Добавить комментарий
|
||||
|
||||
# Управление
|
||||
/bugsnag:fix ERROR_ID # Отметить ошибку как исправленную
|
||||
|
||||
# Обзор
|
||||
/bugsnag:projects # Список проектов
|
||||
/bugsnag:orgs # Список организаций
|
||||
```
|
||||
|
||||
### Естественный язык (Skill)
|
||||
|
||||
Альтернативный способ через естественный язык:
|
||||
|
||||
```
|
||||
"показать bugsnag ошибки"
|
||||
"bugsnag открытые ошибки"
|
||||
"bugsnag детали для error_123"
|
||||
"показать комментарии для bugsnag ошибки abc123"
|
||||
"добавить комментарий к bugsnag ошибке abc123: investigating"
|
||||
"список проектов bugsnag"
|
||||
"отметить ошибку ERROR_ID как исправленную"
|
||||
"проанализируй bugsnag ошибки"
|
||||
```
|
||||
|
||||
### Прямой вызов скрипта
|
||||
|
||||
Для автоматизации и скриптинга:
|
||||
|
||||
```bash
|
||||
# Обзор
|
||||
./bugsnag.rb organizations # Список организаций
|
||||
./bugsnag.rb projects # Список проектов
|
||||
|
||||
# Работа с ошибками
|
||||
./bugsnag.rb list # Список всех ошибок
|
||||
./bugsnag.rb open # Только открытые ошибки
|
||||
./bugsnag.rb details ERROR_ID # Детали конкретной ошибки
|
||||
|
||||
# Комментарии
|
||||
./bugsnag.rb comments ERROR_ID # Показать комментарии
|
||||
./bugsnag.rb comment ERROR_ID "message" # Добавить комментарий
|
||||
|
||||
# Управление
|
||||
./bugsnag.rb resolve ERROR_ID # Отметить как выполненную
|
||||
./bugsnag.rb analyze # Анализ паттернов ошибок
|
||||
```
|
||||
|
||||
### Настройка
|
||||
|
||||
#### Как получить API ключ
|
||||
|
||||
1. Перейдите в [Bugsnag Dashboard](https://app.bugsnag.com)
|
||||
2. Настройки → Organization → API Authentication
|
||||
3. Создайте Personal Access Token с правами на чтение ошибок
|
||||
4. Получите ID проекта из настроек проекта
|
||||
|
||||
#### Переменные окружения
|
||||
|
||||
```bash
|
||||
export BUGSNAG_DATA_API_KEY="your_api_key_here"
|
||||
export BUGSNAG_PROJECT_ID="your_project_id_here"
|
||||
```
|
||||
|
||||
## Подробная документация
|
||||
|
||||
Полное описание команд и примеры использования см. в [SKILL.md](SKILL.md).
|
||||
|
||||
158
skills/bugsnag/SKILL.md
Normal file
158
skills/bugsnag/SKILL.md
Normal file
@@ -0,0 +1,158 @@
|
||||
---
|
||||
name: bugsnag
|
||||
description: |
|
||||
**UNIVERSAL TRIGGER**: Use when user wants to GET/FETCH/RETRIEVE any data FROM Bugsnag.
|
||||
|
||||
Common patterns:
|
||||
- "get/show/list/display [something] from bugsnag"
|
||||
- "получить/показать/вывести [что-то] из bugsnag"
|
||||
- "bugsnag [organizations/projects/errors/details/events/comments/stats]"
|
||||
- "what [data] in bugsnag", "check bugsnag [resource]"
|
||||
|
||||
Specific data types supported:
|
||||
|
||||
📊 **Organizations & Projects**:
|
||||
- "list bugsnag organizations/orgs", "show organizations"
|
||||
- "list bugsnag projects", "available projects", "проекты bugsnag"
|
||||
|
||||
🐛 **Errors (viewing)**:
|
||||
- "show/list bugsnag errors", "что в bugsnag", "check bugsnag"
|
||||
- "open errors", "error list", "ошибки bugsnag", "открытые ошибки"
|
||||
- "errors with severity error/warning", "filter bugsnag errors"
|
||||
|
||||
🔍 **Error Details**:
|
||||
- "bugsnag details for <id>", "error details", "детали ошибки"
|
||||
- "show stack trace", "error context", "what happened in error"
|
||||
- "events for error", "error timeline", "события ошибки"
|
||||
|
||||
💬 **Comments**:
|
||||
- "show comments for error", "error comments", "комментарии ошибки"
|
||||
- "bugsnag discussion", "what comments on error"
|
||||
|
||||
📈 **Analysis**:
|
||||
- "analyze bugsnag errors", "error patterns", "анализ ошибок"
|
||||
- "bugsnag statistics", "error trends", "что происходит в bugsnag"
|
||||
|
||||
✅ **Management** (write operations):
|
||||
- "mark as fixed/resolved", "fix error", "resolve error", "close error"
|
||||
- "закрыть ошибку", "отметить как решенную", "исправить ошибку"
|
||||
- "add comment to error", "comment on bugsnag error"
|
||||
- NOTE: Fix/Resolve/Close are synonyms - all mark error as resolved in Bugsnag
|
||||
|
||||
TRIGGERS: bugsnag, получить из bugsnag, показать bugsnag, список bugsnag,
|
||||
bugsnag data, bugsnag info, check bugsnag, what in bugsnag, bugsnag status,
|
||||
error tracking, error monitoring, production errors, stack trace,
|
||||
bugsnag organizations, bugsnag projects, bugsnag errors, bugsnag details,
|
||||
bugsnag events, bugsnag comments, bugsnag analysis, ошибки в bugsnag,
|
||||
что в bugsnag, проверить bugsnag, данные bugsnag, fix error, resolve error,
|
||||
close error, закрыть ошибку, исправить ошибку, отметить как решенную
|
||||
|
||||
This skill provides complete Bugsnag API integration for viewing and managing
|
||||
error tracking data via Ruby helper scripts.
|
||||
allowed-tools: Bash, Read
|
||||
---
|
||||
|
||||
Skill для интеграции с Bugsnag API, позволяющий просматривать и управлять ошибками в проекте.
|
||||
|
||||
**⚠️ PATH RESOLUTION**: Этот skill использует Ruby скрипты из своей директории.
|
||||
НИКОГДА не вызывай `./bugsnag.rb` из текущей рабочей директории пользователя.
|
||||
|
||||
**ПРАВИЛЬНО**: `find ~ -name "bugsnag.rb" -type f | head -1 | xargs dirname` → получим путь к skill
|
||||
**НЕПРАВИЛЬНО**: `./bugsnag.rb` из текущей директории → ошибка "no such file or directory"
|
||||
|
||||
**ВАЖНО:** Используй ТОЛЬКО команды, описанные в этом файле. НЕ анализируй код bugsnag.rb - следуй документации ниже.
|
||||
|
||||
Вызывает скрипт ./bugsnag.rb находающийся в каталого этого skill с целью выполнить пользовательский запрос.
|
||||
|
||||
## Path Resolution для Claude
|
||||
|
||||
**КРИТИЧЕСКИ ВАЖНО**: При выполнении команд НЕ ИСПОЛЬЗУЙ `./bugsnag.rb` из текущей директории пользователя.
|
||||
Всегда определяй директорию где находится skill и выполняй скрипт оттуда.
|
||||
|
||||
### Проблема
|
||||
Когда пользователь говорит "покажи ошибки из bugsnag", выполнение `./bugsnag.rb` из текущей директории не работает.
|
||||
|
||||
### Решение
|
||||
1. Определи директорию skill
|
||||
2. Перейди в неё
|
||||
3. Выполни скрипт
|
||||
|
||||
**Команда для Claude**: Используй `bash -c "cd [path_to_skill] && ./bugsnag.rb [args]"`
|
||||
|
||||
Где `[path_to_skill]` - это путь к директории skill. Определи его с помощью:
|
||||
1. `find ~/.claude -name "bugsnag.rb" -type f` (если установлен)
|
||||
2. или используй `pwd` если ты уже в директории skill
|
||||
3. или попробуй стандартные пути установки плагинов
|
||||
|
||||
## Возможности
|
||||
|
||||
- 🏢 **Управление организациями** - Просмотр списка доступных организаций в Bugsnag
|
||||
- 📦 **Управление проектами** - Просмотр списка доступных проектов
|
||||
- 📋 **Просмотр текущих ошибок** - Получение списка активных ошибок из Bugsnag
|
||||
- 🔍 **Детальный контекст ошибки** - Просмотр полной информации об ошибке включая stack trace
|
||||
- ✅ **Управление статусами** - Пометка ошибок как выполненные (resolved)
|
||||
- 🔐 **Безопасная авторизация** - Использование API ключей из переменных окружения
|
||||
|
||||
## Команды bugsnag.rb
|
||||
|
||||
### Обзор
|
||||
- `organizations` / `orgs` / `организации` - Список всех организаций
|
||||
- `projects` / `проекты` - Список всех проектов
|
||||
|
||||
### Просмотр ошибок
|
||||
- `list` / `show` / `показать` - Список всех ошибок
|
||||
- `open` / `открыть` / `открытые` - Только открытые ошибки
|
||||
- `list --limit 50` - Показать до 50 ошибок
|
||||
- `list --severity error` - Только ошибки (без предупреждений)
|
||||
|
||||
### Детализация
|
||||
- `details <error_id>` / `детали <id>` - Полная информация об ошибке
|
||||
- `events <error_id> [limit]` / `события <id> [лимит]` - Показать события ошибки
|
||||
|
||||
### Управление
|
||||
- `resolve <error_id>` / `отметить <id>` - Отметить как выполненную
|
||||
|
||||
### Анализ
|
||||
- `analyze` / `анализ` - Анализ паттернов ошибок
|
||||
|
||||
### Справка
|
||||
- `help` / `помощь` / `h` - Показать справку
|
||||
|
||||
## ПРИМЕРЫ ИСПОЛЬЗОВАНИЯ
|
||||
|
||||
**FOR CLAUDE**: Используй `bash -c "cd [skill_directory] && ./bugsnag.rb [command]"`
|
||||
|
||||
```bash
|
||||
# Показать организации
|
||||
bash -c "cd [skill_dir] && ./bugsnag.rb organizations"
|
||||
|
||||
# Показать проекты
|
||||
bash -c "cd [skill_dir] && ./bugsnag.rb projects"
|
||||
|
||||
# Показать открытые ошибки
|
||||
bash -c "cd [skill_dir] && ./bugsnag.rb open --limit 20"
|
||||
|
||||
# Показать все ошибки (лимит 50)
|
||||
bash -c "cd [skill_dir] && ./bugsnag.rb list --limit 50"
|
||||
|
||||
# Детали конкретной ошибки
|
||||
bash -c "cd [skill_dir] && ./bugsnag.rb details ERROR_ID"
|
||||
|
||||
# Показать справку
|
||||
bash -c "cd [skill_dir] && ./bugsnag.rb help"
|
||||
```
|
||||
|
||||
**Примечание**: `[skill_dir]` - это путь к директории где установлен skill bugsnag.
|
||||
|
||||
## ЗАПРЕЩЕННЫЕ КОМАНДЫ
|
||||
|
||||
❌ `list-errors` - такой команды НЕ существует
|
||||
❌ `--help` - используется `help` без дефисов
|
||||
<EFBFBD>️ Использовать команды не описанные выше
|
||||
|
||||
## Безопасность
|
||||
|
||||
- API ключи хранятся только в переменных окружения
|
||||
- Все запросы выполняются через HTTPS
|
||||
- Минимальные необходимые права доступа к API
|
||||
- Логирование чувствительных данных отключено
|
||||
166
skills/bugsnag/TESTING.md
Normal file
166
skills/bugsnag/TESTING.md
Normal file
@@ -0,0 +1,166 @@
|
||||
# Bugsnag Skill - Testing Guide
|
||||
|
||||
## Auto-Activation Test Scenarios
|
||||
|
||||
This document contains test scenarios to verify the bugsnag skill activates correctly based on user input.
|
||||
|
||||
### ✅ SHOULD Activate
|
||||
|
||||
These phrases should trigger automatic skill activation:
|
||||
|
||||
1. **Direct Bugsnag mentions**:
|
||||
- "показать ошибки в bugsnag"
|
||||
- "show bugsnag errors"
|
||||
- "check bugsnag"
|
||||
- "what's in bugsnag?"
|
||||
|
||||
2. **Error details requests**:
|
||||
- "bugsnag details for ERROR_123"
|
||||
- "show error stack trace for ERROR_456"
|
||||
- "get bugsnag error context"
|
||||
- "покажи стектрейс ошибки ERROR_789"
|
||||
|
||||
3. **Error management**:
|
||||
- "resolve bugsnag error ERROR_123"
|
||||
- "mark bugsnag error as fixed"
|
||||
- "close bugsnag error ERROR_456"
|
||||
- "отметить ошибку ERROR_789 как решенную"
|
||||
|
||||
4. **Error analysis**:
|
||||
- "analyze bugsnag errors"
|
||||
- "bugsnag error patterns"
|
||||
- "проанализировать ошибки в bugsnag"
|
||||
- "what error patterns in production?"
|
||||
|
||||
5. **Generic error monitoring mentions**:
|
||||
- "check production errors"
|
||||
- "show error tracking"
|
||||
- "what's happening in error monitoring?"
|
||||
|
||||
### ❌ Should NOT Activate
|
||||
|
||||
These phrases should NOT trigger bugsnag skill:
|
||||
|
||||
1. **Code errors (not monitoring)**:
|
||||
- "найти ошибку в коде"
|
||||
- "this code has a bug"
|
||||
- "review this function for errors"
|
||||
|
||||
2. **Application logs (not Bugsnag)**:
|
||||
- "показать логи приложения"
|
||||
- "show server logs"
|
||||
- "check nginx logs"
|
||||
|
||||
3. **Generic debugging**:
|
||||
- "debug this issue"
|
||||
- "why is this not working?"
|
||||
- "help me fix this"
|
||||
|
||||
4. **Other monitoring tools**:
|
||||
- "check sentry errors"
|
||||
- "show datadog alerts"
|
||||
- "rollbar notifications"
|
||||
|
||||
## Testing Procedure
|
||||
|
||||
### 1. Install Plugin Locally
|
||||
|
||||
```bash
|
||||
# From repository root
|
||||
/plugin marketplace add /home/danil/code/claude-code-marketplace
|
||||
/plugin install dev-tools@dapi
|
||||
```
|
||||
|
||||
### 2. Verify Skill Discovery
|
||||
|
||||
```bash
|
||||
# Check skill is registered
|
||||
/skills list
|
||||
# Should show: bugsnag (dev-tools)
|
||||
```
|
||||
|
||||
### 3. Test Auto-Activation
|
||||
|
||||
Start new conversation and try phrases from "SHOULD Activate" section:
|
||||
|
||||
```
|
||||
User: "show bugsnag errors"
|
||||
Expected: Claude should mention using bugsnag skill or invoke ./bugsnag.rb
|
||||
```
|
||||
|
||||
```
|
||||
User: "bugsnag details for ERROR_123"
|
||||
Expected: Claude should invoke ./bugsnag.rb details ERROR_123
|
||||
```
|
||||
|
||||
### 4. Test Non-Activation
|
||||
|
||||
Try phrases from "Should NOT Activate" section:
|
||||
|
||||
```
|
||||
User: "найти ошибку в коде"
|
||||
Expected: Claude uses code analysis, NOT bugsnag skill
|
||||
```
|
||||
|
||||
## Environment Setup for Testing
|
||||
|
||||
Before testing, ensure environment variables are set:
|
||||
|
||||
```bash
|
||||
export BUGSNAG_DATA_API_KEY='your_actual_api_key'
|
||||
export BUGSNAG_PROJECT_ID='your_actual_project_id'
|
||||
```
|
||||
|
||||
To get these values:
|
||||
1. Visit https://app.bugsnag.com
|
||||
2. Settings → Organization → API Authentication
|
||||
3. Create Personal Access Token
|
||||
4. Get Project ID from project settings
|
||||
|
||||
## Expected Behavior
|
||||
|
||||
### Correct Activation Flow
|
||||
|
||||
1. User mentions "bugsnag errors"
|
||||
2. Claude recognizes trigger keywords
|
||||
3. Claude invokes bugsnag skill
|
||||
4. Skill executes `./bugsnag.rb <command>`
|
||||
5. Results displayed to user
|
||||
|
||||
### Correct Non-Activation Flow
|
||||
|
||||
1. User asks about code errors (no "bugsnag" mention)
|
||||
2. Claude uses native code analysis
|
||||
3. Bugsnag skill does NOT activate
|
||||
4. Standard debugging workflow proceeds
|
||||
|
||||
## Success Criteria
|
||||
|
||||
- ✅ Skill activates for all "SHOULD Activate" scenarios
|
||||
- ✅ Skill does NOT activate for "Should NOT Activate" scenarios
|
||||
- ✅ Commands execute correctly when activated
|
||||
- ✅ Environment variables validated before execution
|
||||
- ✅ Error messages are clear when API keys missing
|
||||
- ✅ Help command works: `./bugsnag.rb help`
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
### Skill Not Activating
|
||||
|
||||
1. Check skill is installed: `/skills list`
|
||||
2. Verify SKILL.md frontmatter has proper YAML
|
||||
3. Check description contains trigger keywords
|
||||
4. Restart Claude Code session
|
||||
|
||||
### Commands Not Working
|
||||
|
||||
1. Verify script is executable: `chmod +x bugsnag.rb`
|
||||
2. Check environment variables are set
|
||||
3. Test script directly: `./bugsnag.rb help`
|
||||
4. Check Ruby dependencies installed
|
||||
|
||||
### Permission Errors
|
||||
|
||||
1. Verify API key has correct permissions in Bugsnag
|
||||
2. Check project ID is correct
|
||||
3. Test API access with curl first
|
||||
175
skills/bugsnag/TRIGGER_EXAMPLES.md
Normal file
175
skills/bugsnag/TRIGGER_EXAMPLES.md
Normal file
@@ -0,0 +1,175 @@
|
||||
# Bugsnag Skill Trigger Examples
|
||||
|
||||
Примеры запросов, которые **должны активировать** bugsnag skill.
|
||||
|
||||
## ✅ Универсальные паттерны (ДОЛЖНЫ СРАБОТАТЬ)
|
||||
|
||||
### Английский
|
||||
- "get data from bugsnag"
|
||||
- "show me bugsnag information"
|
||||
- "list bugsnag resources"
|
||||
- "retrieve bugsnag data"
|
||||
- "display bugsnag status"
|
||||
- "what's in bugsnag"
|
||||
- "check bugsnag"
|
||||
- "fetch bugsnag info"
|
||||
|
||||
### Русский
|
||||
- "получить данные из bugsnag"
|
||||
- "показать информацию bugsnag"
|
||||
- "вывести список bugsnag"
|
||||
- "что в bugsnag"
|
||||
- "проверить bugsnag"
|
||||
- "данные из bugsnag"
|
||||
|
||||
---
|
||||
|
||||
## ✅ Организации и проекты (ДОЛЖНЫ СРАБОТАТЬ)
|
||||
|
||||
### Организации
|
||||
- "list bugsnag organizations"
|
||||
- "show bugsnag orgs"
|
||||
- "get organizations from bugsnag"
|
||||
- "список организаций bugsnag"
|
||||
- "организации в bugsnag"
|
||||
- "показать организации bugsnag"
|
||||
|
||||
### Проекты
|
||||
- "list bugsnag projects"
|
||||
- "show available projects in bugsnag"
|
||||
- "get bugsnag projects"
|
||||
- "выведи список доступных проектов в bugsnag" ← **твой исходный запрос**
|
||||
- "список проектов bugsnag"
|
||||
- "проекты в bugsnag"
|
||||
- "показать проекты bugsnag"
|
||||
|
||||
---
|
||||
|
||||
## ✅ Ошибки - просмотр (ДОЛЖНЫ СРАБОТАТЬ)
|
||||
|
||||
### Общий список
|
||||
- "show bugsnag errors"
|
||||
- "list errors from bugsnag"
|
||||
- "what errors in bugsnag"
|
||||
- "показать ошибки bugsnag"
|
||||
- "список ошибок bugsnag"
|
||||
- "что в bugsnag"
|
||||
- "ошибки в bugsnag"
|
||||
|
||||
### Открытые ошибки
|
||||
- "show open bugsnag errors"
|
||||
- "list open errors"
|
||||
- "открытые ошибки bugsnag"
|
||||
- "показать открытые ошибки"
|
||||
|
||||
### С фильтрацией
|
||||
- "show errors with severity error"
|
||||
- "list bugsnag warnings"
|
||||
- "filter bugsnag errors by severity"
|
||||
|
||||
---
|
||||
|
||||
## ✅ Детали ошибки (ДОЛЖНЫ СРАБОТАТЬ)
|
||||
|
||||
### Детальная информация
|
||||
- "bugsnag details for ERROR_123"
|
||||
- "show error details ERROR_123"
|
||||
- "get error information ERROR_123"
|
||||
- "детали ошибки ERROR_123"
|
||||
- "показать детали ошибки ERROR_123"
|
||||
|
||||
### Stack trace
|
||||
- "show stack trace for error ERROR_123"
|
||||
- "error context ERROR_123"
|
||||
- "what happened in error ERROR_123"
|
||||
- "stack trace ошибки ERROR_123"
|
||||
|
||||
### События
|
||||
- "show events for error ERROR_123"
|
||||
- "error timeline ERROR_123"
|
||||
- "события ошибки ERROR_123"
|
||||
- "timeline для ошибки ERROR_123"
|
||||
|
||||
---
|
||||
|
||||
## ✅ Комментарии (ДОЛЖНЫ СРАБОТАТЬ)
|
||||
|
||||
- "show comments for error ERROR_123"
|
||||
- "list bugsnag comments ERROR_123"
|
||||
- "error discussion ERROR_123"
|
||||
- "комментарии ошибки ERROR_123"
|
||||
- "показать комментарии ERROR_123"
|
||||
- "что говорят об ошибке ERROR_123"
|
||||
|
||||
---
|
||||
|
||||
## ✅ Анализ и статистика (ДОЛЖНЫ СРАБОТАТЬ)
|
||||
|
||||
- "analyze bugsnag errors"
|
||||
- "show error patterns in bugsnag"
|
||||
- "bugsnag statistics"
|
||||
- "error trends in bugsnag"
|
||||
- "what's happening in bugsnag"
|
||||
- "анализ ошибок bugsnag"
|
||||
- "паттерны ошибок в bugsnag"
|
||||
- "статистика bugsnag"
|
||||
- "что происходит в bugsnag"
|
||||
|
||||
---
|
||||
|
||||
## ✅ Управление (ДОЛЖНЫ СРАБОТАТЬ)
|
||||
|
||||
### Пометка как исправлено (fix/resolve/close - синонимы)
|
||||
- "mark bugsnag error ERROR_123 as fixed"
|
||||
- "fix error ERROR_123"
|
||||
- "resolve error ERROR_123"
|
||||
- "close bugsnag error ERROR_123"
|
||||
- "отметить ошибку ERROR_123 как решенную"
|
||||
- "закрыть ошибку ERROR_123"
|
||||
- "исправить ошибку ERROR_123"
|
||||
- NOTE: Fix, Resolve, Close - всё это одна операция в Bugsnag
|
||||
|
||||
### Добавление комментария
|
||||
- "add comment to bugsnag error ERROR_123"
|
||||
- "comment on error ERROR_123"
|
||||
- "добавить комментарий к ошибке ERROR_123"
|
||||
|
||||
---
|
||||
|
||||
## ❌ НЕ должны активировать (другие контексты)
|
||||
|
||||
- "create a bug tracking system" (создание системы, не использование bugsnag)
|
||||
- "what is bugsnag" (общий вопрос, не запрос данных)
|
||||
- "install bugsnag" (установка, не получение данных)
|
||||
- "bugsnag pricing" (коммерческий вопрос)
|
||||
- "compare bugsnag with sentry" (сравнение продуктов)
|
||||
|
||||
---
|
||||
|
||||
## 🎯 Ключевые триггерные слова
|
||||
|
||||
### Действия (verbs)
|
||||
**EN**: get, show, list, display, retrieve, fetch, check, analyze, view
|
||||
**RU**: получить, показать, вывести, список, проверить, анализ, посмотреть
|
||||
|
||||
### Типы данных (nouns)
|
||||
**EN**: organizations, orgs, projects, errors, details, events, comments, analysis, patterns, trends, statistics
|
||||
**RU**: организации, проекты, ошибки, детали, события, комментарии, анализ, паттерны, статистика
|
||||
|
||||
### Контекст
|
||||
**EN**: from bugsnag, in bugsnag, bugsnag [noun]
|
||||
**RU**: из bugsnag, в bugsnag, bugsnag [существительное]
|
||||
|
||||
---
|
||||
|
||||
## 🧪 Тестирование
|
||||
|
||||
Для проверки активации skill попробуйте:
|
||||
|
||||
1. **Минимальный запрос**: "check bugsnag"
|
||||
2. **Специфичный**: "list bugsnag projects"
|
||||
3. **Русский**: "что в bugsnag"
|
||||
4. **С ID**: "details for error 12345"
|
||||
5. **Аналитический**: "analyze error patterns in bugsnag"
|
||||
|
||||
Каждый из этих запросов **должен активировать** bugsnag skill автоматически.
|
||||
250
skills/bugsnag/bugsnag.rb
Executable file
250
skills/bugsnag/bugsnag.rb
Executable file
@@ -0,0 +1,250 @@
|
||||
#!/usr/bin/env ruby
|
||||
|
||||
require_relative 'bugsnag_helper'
|
||||
|
||||
class BugsnagCLI
|
||||
def initialize
|
||||
@helper = BugsnagHelper.new
|
||||
rescue StandardError => e
|
||||
puts "❌ Ошибка инициализации: #{e.message}"
|
||||
puts ""
|
||||
puts "Убедитесь что установлены переменные окружения:"
|
||||
puts "export BUGSNAG_DATA_API_KEY='your_api_key' # Обязательно для всех команд"
|
||||
puts "export BUGSNAG_PROJECT_ID='your_project_id' # Обязательно только для команд работы с ошибками"
|
||||
puts ""
|
||||
puts "💡 Команды 'organizations' и 'projects' работают без BUGSNAG_PROJECT_ID"
|
||||
exit 1
|
||||
end
|
||||
|
||||
def run(args = [])
|
||||
if args.empty?
|
||||
puts show_help
|
||||
return
|
||||
end
|
||||
|
||||
command = args[0].downcase
|
||||
case command
|
||||
when 'list', 'errors', 'show', 'показать', 'список'
|
||||
list_errors(args[1..-1])
|
||||
when 'open', 'открыть', 'opened', 'открытые'
|
||||
show_open_errors(args[1..-1])
|
||||
when 'details', 'error', 'детали'
|
||||
show_error_details(args[1])
|
||||
when 'resolve', 'close', 'resolve-error', 'отметить', 'решить'
|
||||
resolve_error(args[1])
|
||||
when 'events', 'события'
|
||||
show_events(args[1], args[2])
|
||||
when 'analyze', 'analysis', 'анализ', 'проанализировать'
|
||||
analyze_errors
|
||||
when 'organizations', 'orgs', 'организации'
|
||||
list_organizations
|
||||
when 'projects', 'проекты'
|
||||
list_projects
|
||||
when 'comment', 'комментарий'
|
||||
add_error_comment(args[1], args[2..-1].join(' '))
|
||||
when 'comments', 'комментарии'
|
||||
show_error_comments(args[1])
|
||||
when 'help', 'помощь', 'h'
|
||||
puts show_help
|
||||
else
|
||||
puts "❌ Неизвестная команда: #{command}"
|
||||
puts show_help
|
||||
end
|
||||
rescue StandardError => e
|
||||
puts "❌ Ошибка выполнения: #{e.message}"
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def list_errors(options = [])
|
||||
limit = extract_option('--limit', options) || 20
|
||||
status = extract_option('--status', options)
|
||||
severity = extract_option('--severity', options)
|
||||
|
||||
puts "📋 Получение списка ошибок..."
|
||||
puts ""
|
||||
result = @helper.list_errors(limit: limit.to_i, status: status, severity: severity)
|
||||
puts result
|
||||
end
|
||||
|
||||
def show_open_errors(options = [])
|
||||
limit = extract_option('--limit', options) || 20
|
||||
severity = extract_option('--severity', options)
|
||||
|
||||
puts "📋 Получение списка **открытых** ошибок..."
|
||||
puts ""
|
||||
result = @helper.list_errors(limit: limit.to_i, status: 'open', severity: severity)
|
||||
puts result
|
||||
end
|
||||
|
||||
def show_error_details(error_id)
|
||||
unless error_id
|
||||
puts "❌ Укажите ID ошибки"
|
||||
puts "Пример: bugsnag-lookuper details 5f8a9b2c"
|
||||
return
|
||||
end
|
||||
|
||||
puts "🔍 Получение деталей ошибки #{error_id}..."
|
||||
puts ""
|
||||
result = @helper.get_error_details(error_id)
|
||||
puts result
|
||||
|
||||
# Также покажем последние события
|
||||
puts ""
|
||||
puts "📊 **Последние события:**"
|
||||
events_result = @helper.get_error_events(error_id, 3)
|
||||
puts events_result
|
||||
end
|
||||
|
||||
def resolve_error(error_id)
|
||||
unless error_id
|
||||
puts "❌ Укажите ID ошибки для пометки как выполненной"
|
||||
puts "Пример: bugsnag-lookuper resolve 5f8a9b2c"
|
||||
return
|
||||
end
|
||||
|
||||
puts "🔄 Пометка ошибки #{error_id} как выполненной..."
|
||||
result = @helper.resolve_error(error_id)
|
||||
puts result
|
||||
end
|
||||
|
||||
def show_events(error_id, limit = nil)
|
||||
unless error_id
|
||||
puts "❌ Укажите ID ошибки"
|
||||
puts "Пример: bugsnag-lookuper events 5f8a9b2c 5"
|
||||
return
|
||||
end
|
||||
|
||||
event_limit = limit&.to_i || 10
|
||||
puts "📊 Получение событий ошибки #{error_id} (лимит: #{event_limit})..."
|
||||
puts ""
|
||||
result = @helper.get_error_events(error_id, limit: event_limit)
|
||||
puts result
|
||||
end
|
||||
|
||||
def analyze_errors
|
||||
puts "📈 Анализ ошибок в проекте..."
|
||||
puts ""
|
||||
result = @helper.analyze_errors
|
||||
puts result
|
||||
end
|
||||
|
||||
def list_organizations
|
||||
puts "🏢 Получение списка организаций..."
|
||||
puts ""
|
||||
result = @helper.list_organizations
|
||||
puts result
|
||||
end
|
||||
|
||||
def list_projects
|
||||
puts "📦 Получение списка проектов..."
|
||||
puts ""
|
||||
result = @helper.list_projects
|
||||
puts result
|
||||
end
|
||||
|
||||
def add_error_comment(error_id, message)
|
||||
unless error_id && !message.empty?
|
||||
puts "❌ Укажите ID ошибки и текст комментария"
|
||||
puts "Пример: bugsnag.rb comment 5f8a9b2c 'Investigating this issue'"
|
||||
return
|
||||
end
|
||||
|
||||
puts "💬 Добавление комментария к ошибке #{error_id}..."
|
||||
result = @helper.add_comment(error_id, message)
|
||||
puts result
|
||||
end
|
||||
|
||||
def show_error_comments(error_id)
|
||||
unless error_id
|
||||
puts "❌ Укажите ID ошибки"
|
||||
puts "Пример: bugsnag.rb comments 5f8a9b2c"
|
||||
return
|
||||
end
|
||||
|
||||
puts "💬 Получение комментариев для ошибки #{error_id}..."
|
||||
puts ""
|
||||
result = @helper.list_comments(error_id)
|
||||
puts result
|
||||
end
|
||||
|
||||
def show_help
|
||||
<<~HELP
|
||||
🚀 **Bugsnag** - Инструмент для работы с Bugsnag API
|
||||
|
||||
**Использование:**
|
||||
`skill: "bugsnag" "<команда> [аргументы]"`
|
||||
|
||||
**Команды:**
|
||||
|
||||
📋 **Просмотр ошибок:**
|
||||
• `list` / `show` / `показать` - Список всех ошибок
|
||||
• `open` / `открыть` / `открытые` - Только **открытые** ошибки
|
||||
• `list --limit 50` - Показать до 50 ошибок
|
||||
• `list --status open` - Только открытые ошибки
|
||||
• `list --severity error` - Только ошибки (не предупреждения)
|
||||
|
||||
🔍 **Детали ошибки:**
|
||||
• `details <error_id>` / `детали <id>` - Полная информация об ошибке
|
||||
• Пример: `details 5f8a9b2c`
|
||||
|
||||
✅ **Управление статусами:**
|
||||
• `resolve <error_id>` / `resolve-error <id>` / `отметить <id>` - Отметить как выполненную
|
||||
• Пример: `resolve 5f8a9b2c`
|
||||
|
||||
📊 **События ошибки:**
|
||||
• `events <error_id> [limit]` / `события <id> [лимит]` - Показать события
|
||||
• Пример: `events 5f8a9b2c 5`
|
||||
|
||||
📈 **Анализ:**
|
||||
• `analyze` / `analysis` / `анализ` - Анализ паттернов ошибок
|
||||
|
||||
💬 **Комментарии:**
|
||||
• `comment <error_id> "message"` / `комментарий <id> "текст"` - Добавить комментарий
|
||||
• `comments <error_id>` / `комментарии <id>` - Показать все комментарии
|
||||
|
||||
🏢 **Организации:**
|
||||
• `organizations` / `orgs` / `организации` - Список всех организаций
|
||||
|
||||
📦 **Проекты:**
|
||||
• `projects` / `проекты` - Список всех проектов
|
||||
|
||||
❓ **Справка:**
|
||||
• `help` / `помощь` / `h` - Показать эту справку
|
||||
|
||||
**Настройка:**
|
||||
```bash
|
||||
export BUGSNAG_DATA_API_KEY="your_api_key" # Обязательно для всех команд
|
||||
export BUGSNAG_PROJECT_ID="your_project_id" # Обязательно для команд работы с ошибками
|
||||
```
|
||||
|
||||
💡 **Важно:** Команды `organizations` и `projects` работают **БЕЗ** BUGSNAG_PROJECT_ID.
|
||||
Используйте их для получения списка доступных проектов и их ID.
|
||||
|
||||
HELP
|
||||
end
|
||||
|
||||
def extract_option(option_name, options)
|
||||
index = options.find_index { |opt| opt.start_with?(option_name) }
|
||||
return nil unless index
|
||||
|
||||
option = options[index]
|
||||
value = nil
|
||||
|
||||
if option.include?('=')
|
||||
value = option.split('=', 2)[1]
|
||||
options.delete_at(index)
|
||||
elsif options[index + 1] && !options[index + 1].start_with?('--')
|
||||
value = options.delete_at(index + 1)
|
||||
options.delete_at(index)
|
||||
else
|
||||
options.delete_at(index)
|
||||
end
|
||||
|
||||
value
|
||||
end
|
||||
end
|
||||
|
||||
# Handle execution through MCP or direct CLI
|
||||
cli = BugsnagCLI.new
|
||||
cli.run(ARGV)
|
||||
370
skills/bugsnag/bugsnag_api_client.rb
Normal file
370
skills/bugsnag/bugsnag_api_client.rb
Normal file
@@ -0,0 +1,370 @@
|
||||
#!/usr/bin/env ruby
|
||||
|
||||
require 'bugsnag/api'
|
||||
|
||||
class BugsnagApiClient
|
||||
def initialize
|
||||
@api_key = ENV.fetch('BUGSNAG_DATA_API_KEY')
|
||||
@project_id = ENV['BUGSNAG_PROJECT_ID'] # Optional - needed only for error-specific commands
|
||||
|
||||
validate_api_key
|
||||
configure_api
|
||||
end
|
||||
|
||||
def list_errors(limit: 20, status: nil, severity: nil)
|
||||
errors_data = fetch_errors(limit: limit, status: status, severity: severity)
|
||||
format_errors_list(errors_data)
|
||||
rescue Bugsnag::Api::Error => e
|
||||
handle_api_error(e, "получении списка ошибок")
|
||||
end
|
||||
|
||||
def get_error_details(error_id)
|
||||
require_project_id!
|
||||
|
||||
response = Bugsnag::Api.client.error(@project_id, error_id)
|
||||
format_error_details(response)
|
||||
rescue Bugsnag::Api::Error => e
|
||||
handle_api_error(e, "получении деталей ошибки")
|
||||
end
|
||||
|
||||
def resolve_error(error_id)
|
||||
require_project_id!
|
||||
|
||||
# Try to resolve via API first
|
||||
begin
|
||||
Bugsnag::Api.client.update_errors(@project_id, [error_id], "resolve")
|
||||
"✅ Ошибка `#{error_id}` успешно отмечена как выполненная!"
|
||||
rescue Bugsnag::Api::Error => e
|
||||
# Fallback to adding a resolution comment
|
||||
begin
|
||||
comment_text = "🔧 **MARKED AS RESOLVED** - Эта ошибка была помечена как выполненная через Bugsnag skill."
|
||||
Bugsnag::Api.client.create_comment(@project_id, error_id, comment_text)
|
||||
"✅ Ошибка `#{error_id}` помечена как выполненная через комментарий. Пожалуйста, закройте ошибку вручную в Bugsnag dashboard."
|
||||
rescue Bugsnag::Api::Error => comment_error
|
||||
handle_api_error(comment_error, "пометки ошибки как выполненной")
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def add_comment(error_id, message)
|
||||
require_project_id!
|
||||
|
||||
Bugsnag::Api.client.create_comment(@project_id, error_id, message)
|
||||
"✅ Комментарий успешно добавлен к ошибке `#{error_id}`"
|
||||
rescue Bugsnag::Api::Error => e
|
||||
handle_api_error(e, "добавлении комментария")
|
||||
end
|
||||
|
||||
def get_error_events(error_id, limit: 10)
|
||||
require_project_id!
|
||||
|
||||
options = {}
|
||||
options[:limit] = limit if limit
|
||||
|
||||
response = Bugsnag::Api.client.error_events(@project_id, error_id, options)
|
||||
format_events_list(response)
|
||||
rescue Bugsnag::Api::Error => e
|
||||
handle_api_error(e, "получении событий ошибки")
|
||||
end
|
||||
|
||||
def analyze_errors
|
||||
errors_data = fetch_errors(limit: 50)
|
||||
errors = normalize_errors_array(errors_data)
|
||||
analyze_error_patterns(errors)
|
||||
end
|
||||
|
||||
def list_organizations
|
||||
response = Bugsnag::Api.client.organizations
|
||||
format_organizations_list(response)
|
||||
rescue Bugsnag::Api::Error => e
|
||||
handle_api_error(e, "получении списка организаций")
|
||||
end
|
||||
|
||||
def list_projects
|
||||
# Get all organizations first
|
||||
orgs = Bugsnag::Api.client.organizations
|
||||
all_projects = []
|
||||
|
||||
# Get projects for each organization
|
||||
orgs.each do |org|
|
||||
org_projects = Bugsnag::Api.client.projects(org['id'])
|
||||
all_projects.concat(org_projects)
|
||||
rescue Bugsnag::Api::Error
|
||||
# Skip this org if error, continue with others
|
||||
next
|
||||
end
|
||||
|
||||
format_projects_list(all_projects)
|
||||
rescue Bugsnag::Api::Error => e
|
||||
handle_api_error(e, "получении списка проектов")
|
||||
end
|
||||
|
||||
def list_comments(error_id)
|
||||
require_project_id!
|
||||
|
||||
response = Bugsnag::Api.client.comments(@project_id, error_id)
|
||||
format_comments_list(response)
|
||||
rescue Bugsnag::Api::Error => e
|
||||
handle_api_error(e, "получении комментариев")
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def fetch_errors(limit: 20, status: nil, severity: nil)
|
||||
require_project_id!
|
||||
|
||||
options = {}
|
||||
options[:limit] = limit if limit
|
||||
options[:status] = status if status
|
||||
options[:severity] = severity if severity
|
||||
|
||||
Bugsnag::Api.client.errors(@project_id, nil, options)
|
||||
end
|
||||
|
||||
def normalize_errors_array(errors_data)
|
||||
errors_data.is_a?(Array) ? errors_data : errors_data['errors'] || []
|
||||
end
|
||||
|
||||
def validate_api_key
|
||||
unless @api_key
|
||||
raise "Missing required environment variable: BUGSNAG_DATA_API_KEY"
|
||||
end
|
||||
end
|
||||
|
||||
def require_project_id!
|
||||
unless @project_id
|
||||
raise "Missing required environment variable: BUGSNAG_PROJECT_ID\n\n" \
|
||||
"This command requires a project ID. Set it with:\n" \
|
||||
"export BUGSNAG_PROJECT_ID='your_project_id'\n\n" \
|
||||
"Use 'projects' command to list available project IDs."
|
||||
end
|
||||
end
|
||||
|
||||
def configure_api
|
||||
Bugsnag::Api.configure do |config|
|
||||
config.auth_token = @api_key
|
||||
end
|
||||
end
|
||||
|
||||
def handle_api_error(error, operation)
|
||||
case error
|
||||
when Bugsnag::Api::ClientError
|
||||
"❌ Ошибка при #{operation}: ошибка клиента API - #{error.message}"
|
||||
when Bugsnag::Api::ServerError
|
||||
"❌ Ошибка при #{operation}: ошибка сервера Bugsnag - #{error.message}"
|
||||
when Bugsnag::Api::InternalServerError
|
||||
"❌ Ошибка при #{operation}: внутренняя ошибка сервера Bugsnag - #{error.message}"
|
||||
else
|
||||
"❌ Ошибка при #{operation}: #{error.message}"
|
||||
end
|
||||
end
|
||||
|
||||
def format_errors_list(errors_data)
|
||||
errors = errors_data.is_a?(Array) ? errors_data : errors_data['errors'] || []
|
||||
|
||||
output = ["📋 Найдено ошибок: #{errors.length}\n"]
|
||||
|
||||
errors.each do |error|
|
||||
status_emoji = case error['status']
|
||||
when 'open' then '❌'
|
||||
when 'resolved' then '✅'
|
||||
when 'ignored' then '🚫'
|
||||
else '❓'
|
||||
end
|
||||
|
||||
output << "#{status_emoji} **#{error['error_class']}** (#{error['events']} событий)"
|
||||
output << " ID: `#{error['id']}`"
|
||||
output << " Severity: #{error['severity']}"
|
||||
output << " Первое появление: #{error['first_seen']}"
|
||||
output << " Последнее: #{error['last_seen']}"
|
||||
output << " URL: #{error['url']}" if error['url']
|
||||
output << ""
|
||||
end
|
||||
|
||||
output.join("\n")
|
||||
end
|
||||
|
||||
def format_error_details(error_data)
|
||||
error = error_data['error'] || error_data
|
||||
|
||||
output = []
|
||||
output << "🔍 **Детали ошибки:** #{error['error_class']}"
|
||||
output << ""
|
||||
output << "**Основная информация:**"
|
||||
output << "• ID: `#{error['id']}`"
|
||||
output << "• Статус: #{error['status']}"
|
||||
output << "• Критичность: #{error['severity']}"
|
||||
output << "• Событий: #{error['events']}"
|
||||
output << "• Пользователи затронуто: #{error['users']}"
|
||||
output << ""
|
||||
|
||||
if error['first_seen'] && error['last_seen']
|
||||
output << "**Временные рамки:**"
|
||||
output << "• Первое появление: #{error['first_seen']}"
|
||||
output << "• Последнее: #{error['last_seen']}"
|
||||
output << ""
|
||||
end
|
||||
|
||||
output << "**Контекст:**"
|
||||
output << "• App Version: #{error.dig('app', 'version') || 'N/A'}"
|
||||
output << "• Release Stage: #{error.dig('app', 'releaseStage') || 'N/A'}"
|
||||
output << "• Language: #{error['language'] || 'N/A'}"
|
||||
output << "• Framework: #{error['framework'] || 'N/A'}"
|
||||
output << ""
|
||||
|
||||
if error['url']
|
||||
output << "**URL:** #{error['url']}"
|
||||
output << ""
|
||||
end
|
||||
|
||||
if error['message']
|
||||
output << "**Сообщение:**"
|
||||
output << "```"
|
||||
output << error['message']
|
||||
output << "```"
|
||||
output << ""
|
||||
end
|
||||
|
||||
output
|
||||
end
|
||||
|
||||
def format_events_list(events_data)
|
||||
events = events_data['events'] || []
|
||||
|
||||
output = ["📊 События ошибки (#{events.length}):\n"]
|
||||
|
||||
events.each_with_index do |event, index|
|
||||
output << "**Событие #{index + 1}:**"
|
||||
output << "• ID: `#{event['id']}`"
|
||||
output << "• Время: #{event['receivedAt']}"
|
||||
output << "• App Version: #{event['app']['releaseStage'] || 'N/A'}"
|
||||
output << "• OS: #{event['device']['osName'] || 'N/A'} #{event['device']['osVersion'] || ''}"
|
||||
|
||||
if event['user']
|
||||
output << "• Пользователь: #{event['user']['name'] || event['user']['id'] || 'N/A'}"
|
||||
end
|
||||
|
||||
if event['message']
|
||||
output << "• Сообщение: #{event['message']}"
|
||||
end
|
||||
|
||||
output << ""
|
||||
end
|
||||
|
||||
output.join("\n")
|
||||
end
|
||||
|
||||
def analyze_error_patterns(errors)
|
||||
critical_errors = errors.select { |e| e['severity'] == 'error' && e['status'] == 'open' }
|
||||
warnings = errors.select { |e| e['severity'] == 'warning' && e['status'] == 'open' }
|
||||
|
||||
output = ["📈 **Анализ ошибок в проекте:**\n"]
|
||||
|
||||
output << "🔴 **Критичные ошибки (#{critical_errors.length}):**"
|
||||
if critical_errors.any?
|
||||
critical_errors.first(5).each do |error|
|
||||
events_count = error['events'] || error['events_count'] || 0
|
||||
output << "• #{error['error_class']} - #{events_count} событий (ID: #{error['id']})"
|
||||
end
|
||||
else
|
||||
output << "• Нет критичных ошибок!"
|
||||
end
|
||||
output << ""
|
||||
|
||||
output << "🟡 **Предупреждения (#{warnings.length}):**"
|
||||
if warnings.any?
|
||||
warnings.first(5).each do |error|
|
||||
events_count = error['events'] || error['events_count'] || 0
|
||||
output << "• #{error['error_class']} - #{events_count} событий (ID: #{error['id']})"
|
||||
end
|
||||
else
|
||||
output << "• Нет предупреждений!"
|
||||
end
|
||||
output << ""
|
||||
|
||||
# Частые паттерны ошибок
|
||||
error_classes = errors.group_by { |e| e['error_class'] }
|
||||
frequent_errors = error_classes.select { |klass, errs| errs.length > 1 }
|
||||
|
||||
if frequent_errors.any?
|
||||
output << "🔄 **Повторяющиеся паттерны:**"
|
||||
frequent_errors.each do |error_class, errors|
|
||||
total_events = errors.sum { |e| e['events'] || e['events_count'] || 0 }
|
||||
output << "• #{error_class}: #{errors.length} экземпляров, #{total_events} событий"
|
||||
end
|
||||
end
|
||||
|
||||
output.join("\n")
|
||||
end
|
||||
|
||||
def format_organizations_list(orgs_data)
|
||||
orgs = orgs_data.is_a?(Array) ? orgs_data : orgs_data['organizations'] || []
|
||||
|
||||
output = ["🏢 Доступные организации: #{orgs.length}\n"]
|
||||
|
||||
orgs.each_with_index do |org, index|
|
||||
output << "#{index + 1}. **#{org['name']}** (ID: `#{org['id']}`)"
|
||||
output << " Создана: #{org['created_at']}" if org['created_at']
|
||||
output << " Коллабораторов: #{org['collaborators_count']}" if org['collaborators_count']
|
||||
output << " Проектов: #{org['projects_count']}" if org['projects_count']
|
||||
output << " URL: #{org['url']}" if org['url']
|
||||
output << ""
|
||||
end
|
||||
|
||||
output.join("\n")
|
||||
end
|
||||
|
||||
def format_projects_list(projects_data)
|
||||
projects = projects_data.is_a?(Array) ? projects_data : projects_data['projects'] || []
|
||||
|
||||
output = ["📦 Доступные проекты: #{projects.length}\n"]
|
||||
|
||||
projects.each_with_index do |project, index|
|
||||
output << "#{index + 1}. **#{project['name']}** (ID: `#{project['id']}`)"
|
||||
output << " Тип: #{project['type']}" if project['type']
|
||||
output << " Открытых ошибок: #{project['open_error_count']}" if project['open_error_count']
|
||||
output << " Коллабораторов: #{project['collaborators_count']}" if project['collaborators_count']
|
||||
|
||||
if project['release_stages'] && project['release_stages'].any?
|
||||
output << " Стадии: #{project['release_stages'].join(', ')}"
|
||||
end
|
||||
|
||||
output << " URL: #{project['url']}" if project['url']
|
||||
output << ""
|
||||
end
|
||||
|
||||
output.join("\n")
|
||||
end
|
||||
|
||||
def format_comments_list(comments_data)
|
||||
comments = comments_data.is_a?(Array) ? comments_data : comments_data['comments'] || []
|
||||
|
||||
output = ["💬 Комментарии (#{comments.length}):\n"]
|
||||
|
||||
if comments.empty?
|
||||
output << "Нет комментариев для этой ошибки."
|
||||
return output.join("\n")
|
||||
end
|
||||
|
||||
comments.each_with_index do |comment, index|
|
||||
output << "**Комментарий #{index + 1}:**"
|
||||
output << "• ID: `#{comment['id']}`"
|
||||
|
||||
# Author info
|
||||
author = if comment['user'] && comment['user']['name']
|
||||
comment['user']['name']
|
||||
elsif comment['user'] && comment['user']['email']
|
||||
comment['user']['email']
|
||||
else
|
||||
'Unknown'
|
||||
end
|
||||
output << "• Автор: #{author}"
|
||||
|
||||
output << "• Время: #{comment['created_at']}" if comment['created_at']
|
||||
output << "• Текст: #{comment['message']}" if comment['message']
|
||||
output << ""
|
||||
end
|
||||
|
||||
output.join("\n")
|
||||
end
|
||||
end
|
||||
45
skills/bugsnag/bugsnag_helper.rb
Executable file
45
skills/bugsnag/bugsnag_helper.rb
Executable file
@@ -0,0 +1,45 @@
|
||||
#!/usr/bin/env ruby
|
||||
|
||||
require_relative 'bugsnag_api_client'
|
||||
|
||||
class BugsnagHelper
|
||||
def initialize
|
||||
@client = BugsnagApiClient.new
|
||||
end
|
||||
|
||||
def list_errors(limit: 20, status: nil, severity: nil)
|
||||
@client.list_errors(limit: limit, status: status, severity: severity)
|
||||
end
|
||||
|
||||
def get_error_details(error_id)
|
||||
@client.get_error_details(error_id)
|
||||
end
|
||||
|
||||
def resolve_error(error_id)
|
||||
@client.resolve_error(error_id)
|
||||
end
|
||||
|
||||
def get_error_events(error_id, limit: 10)
|
||||
@client.get_error_events(error_id, limit: limit)
|
||||
end
|
||||
|
||||
def analyze_errors
|
||||
@client.analyze_errors
|
||||
end
|
||||
|
||||
def list_organizations
|
||||
@client.list_organizations
|
||||
end
|
||||
|
||||
def list_projects
|
||||
@client.list_projects
|
||||
end
|
||||
|
||||
def add_comment(error_id, message)
|
||||
@client.add_comment(error_id, message)
|
||||
end
|
||||
|
||||
def list_comments(error_id)
|
||||
@client.list_comments(error_id)
|
||||
end
|
||||
end
|
||||
Reference in New Issue
Block a user