📁 Пример 1: Поиск и редактирование файлов
Сценарий: Замена console.log на logger
📝 Исходный файл: src/utils/helper.js
// Файл: src/utils/helper.js
function processData(data) {
console.log('Начало обработки данных');
if (!data) {
console.error('Данные не предоставлены');
return null;
}
console.log('Данные получены:', data);
const result = data.map(item => {
console.log('Обработка элемента:', item.id);
return {
...item,
processed: true,
timestamp: Date.now()
};
});
console.log('Обработка завершена, результат:', result);
return result;
}
function validateInput(input) {
console.log('Валидация входных данных');
if (typeof input !== 'object') {
console.error('Неверный тип данных');
return false;
}
console.log('Валидация пройдена');
return true;
}
module.exports = { processData, validateInput };
🔍 Шаг 1: Поиск всех console.log через grep_search
{
"tool": "grep_search",
"params": {
"pattern": "console\\.(log|error|warn|info|debug)",
"glob": "**/*.js",
"path": "/home/project/src"
}
}
src/utils/helper.js:4: console.log('Начало обработки данных')
src/utils/helper.js:7: console.error('Данные не предоставлены')
src/utils/helper.js:12: console.log('Данные получены:', data)
src/utils/helper.js:15: console.log('Обработка элемента:', item.id)
src/utils/helper.js:23: console.log('Обработка завершена, результат:', result)
src/utils/helper.js:28: console.log('Валидация входных данных')
src/utils/helper.js:31: console.error('Неверный тип данных')
src/utils/helper.js:35: console.log('Валидация пройдена')
src/api/handler.js:10: console.log('Request received')
src/api/handler.js:25: console.error('Database connection failed')
✏️ Шаг 2: Редактирование с помощью edit
{
"tool": "edit",
"params": {
"file_path": "/home/project/src/utils/helper.js",
"old_string": "// Файл: src/utils/helper.js\n\nfunction processData(data) {\n console.log('Начало обработки данных');\n \n if (!data) {\n console.error('Данные не предоставлены');\n return null;\n }",
"new_string": "// Файл: src/utils/helper.js\nconst logger = require('../logger');\n\nfunction processData(data) {\n logger.info('Начало обработки данных');\n \n if (!data) {\n logger.error('Данные не предоставлены');\n return null;\n }",
"replace_all": false
}
}
✅ Результат после редактирования
// Файл: src/utils/helper.js
const logger = require('../logger');
function processData(data) {
logger.info('Начало обработки данных');
if (!data) {
logger.error('Данные не предоставлены');
return null;
}
logger.info('Данные получены:', data);
const result = data.map(item => {
logger.debug('Обработка элемента:', item.id);
return {
...item,
processed: true,
timestamp: Date.now()
};
});
logger.info('Обработка завершена, результат:', result);
return result;
}
function validateInput(input) {
logger.info('Валидация входных данных');
if (typeof input !== 'object') {
logger.error('Неверный тип данных');
return false;
}
logger.info('Валидация пройдена');
return true;
}
module.exports = { processData, validateInput };
🔍 Пример 2: RAG - Анализ архитектуры проекта
Сценарий: Понимание структуры Express.js приложения
📁 Структура проекта (list_directory)
{
"tool": "list_directory",
"params": {
"path": "/home/project/my-express-app"
}
}
my-express-app/
├── src/
│ ├── index.js
│ ├── app.js
│ ├── config/
│ │ ├── database.js
│ │ └── app.config.js
│ ├── controllers/
│ │ ├── user.controller.js
│ │ └── auth.controller.js
│ ├── models/
│ │ ├── User.js
│ │ └── Session.js
│ ├── middleware/
│ │ ├── auth.js
│ │ └── validator.js
│ ├── routes/
│ │ ├── users.js
│ │ └── auth.js
│ └── services/
│ ├── email.service.js
│ └── token.service.js
├── tests/
├── package.json
└── .env
📄 Чтение основного файла приложения
const express = require('express');
const cors = require('cors');
const helmet = require('helmet');
const rateLimit = require('express-rate-limit');
const userRoutes = require('./routes/users');
const authRoutes = require('./routes/auth');
const { errorHandler } = require('./middleware/errorHandler');
const logger = require('./middleware/logger');
const app = express();
// Middleware
app.use(helmet());
app.use(cors({ origin: process.env.ALLOWED_ORIGINS }));
app.use(rateLimit({ windowMs: 15 * 60 * 1000, max: 100 }));
app.use(express.json());
app.use(logger);
// Routes
app.use('/api/auth', authRoutes);
app.use('/api/users', userRoutes);
// Error handling
app.use(errorHandler);
module.exports = app;
🔎 Поиск всех контроллеров через glob + read_file
{
"tool": "glob",
"params": {
"pattern": "**/*.controller.js",
"path": "/home/project/my-express-app/src"
}
}
- /home/project/my-express-app/src/controllers/user.controller.js
- /home/project/my-express-app/src/controllers/auth.controller.js
{
"tool": "read_file",
"params": {
"absolute_path": "/home/project/my-express-app/src/controllers/user.controller.js"
}
}
📊 Итоговый отчет об архитектуре
## Архитектура Express.js приложения
### Паттерн: Controller-Service-Repository
**Основные компоненты:**
1. **Controllers** (src/controllers/)
- user.controller.js - CRUD операции с пользователями
- auth.controller.js - регистрация, логин, logout
2. **Models** (src/models/)
- User.js - модель пользователя (Mongoose schema)
- Session.js - модель сессии для JWT refresh tokens
3. **Services** (src/services/)
- email.service.js - отправка email уведомлений
- token.service.js - генерация/валидация JWT токенов
4. **Middleware** (src/middleware/)
- auth.js - проверка JWT токена
- validator.js - валидация запросов через Joi
5. **Routes** (src/routes/)
- /api/auth/* - endpoints аутентификации
- /api/users/* - endpoints пользователей
### Поток запроса:
Client → Middleware (auth, validator) → Controller → Service → Model → Database
🤖 Пример 3: Использование субагента task
Сценарий: Поиск всех уязвимостей безопасности
"Найди все потенциальные уязвимости безопасности в проекте"
{
"tool": "task",
"params": {
"description": "Аудит безопасности кодовой базы",
"subagent_type": "general-purpose",
"prompt": """
Проведи полный аудит безопасности проекта:
1. Найди все места где используется:
- eval() или new Function()
- SQL запросы без параметризации
- XSS уязвимости (innerHTML, dangerouslySetInnerHTML)
- Жестко закодированные секреты (пароли, API ключи)
- Неправильная обработка ошибок с утечкой данных
2. Для каждой найденной проблемы укажи:
- Путь к файлу и номер строки
- Тип уязвимости
- Уровень критичности (Critical/High/Medium/Low)
- Рекомендацию по исправлению
3. Используй grep_search для поиска паттернов:
- eval\\(|new Function\\(
- \\`SELECT.*\\+|\\`.*\\+
- innerHTML|dangerouslySetInnerHTML
- password.*=.*['"]|api_key.*=.*['"]
- console\\.log.*error|throw.*error
Верни структурированный отчет в формате Markdown.
"""
}
}
## Отчет об аудите безопасности
### 🔴 Critical
**Файл:** src/utils/eval.js:15
**Проблема:** Использование eval() с пользовательским вводом
```javascript
// Уязвимый код
function executeCode(userCode) {
return eval(userCode); // ❌ XSS/Code Injection
}
```
**Рекомендация:** Использовать sandboxed execution или whitelist функций
### 🟠 High
**Файл:** src/models/user.js:42
**Проблема:** SQL инъекция через конкатенацию
```javascript
// Уязвимый код
const query = `SELECT * FROM users WHERE email = '${email}'`;
```
**Рекомендация:** Использовать параметризованные запросы
```javascript
const query = 'SELECT * FROM users WHERE email = ?';
```
### 🟡 Medium
**Файл:** src/config/database.js:5
**Проблема:** Жестко закодированный пароль
```javascript
const DB_PASSWORD = 'super_secret_123'; // ❌
```
**Рекомендация:** Использовать process.env.DB_PASSWORD
🧪 Пример 4: Создание функции с тестами
Сценарий: Добавление утилиты форматирования даты
"Создай функцию formatDate для форматирования дат в русском формате"
{
"tool": "write_file",
"params": {
"file_path": "/home/project/src/utils/formatDate.js",
"content": "/**\n * Форматирует дату в русский формат\n * @param {Date|string|number} date - Дата для форматирования\n * @param {string} format - Формат вывода (default|short|long|iso)\n * @returns {string} Отформатированная дата\n * \n * @example\n * formatDate(new Date()) // \"17 марта 2026, 14:30\"\n * formatDate('2026-03-17', 'short') // \"17.03.2026\"\n * formatDate(Date.now(), 'iso') // \"2026-03-17T14:30:00.000Z\"\n */\nfunction formatDate(date, format = 'default') {\n // Конвертация в объект Date\n const d = new Date(date);\n \n if (isNaN(d.getTime())) {\n throw new Error('Invalid date: ' + date);\n }\n \n const day = d.getDate();\n const month = d.getMonth() + 1;\n const year = d.getFullYear();\n const hours = d.getHours().toString().padStart(2, '0');\n const minutes = d.getMinutes().toString().padStart(2, '0');\n \n // Русские названия месяцев\n const monthNames = [\n 'января', 'февраля', 'марта', 'апреля', 'мая', 'июня',\n 'июля', 'августа', 'сентября', 'октября', 'ноября', 'декабря'\n ];\n \n switch (format) {\n case 'short':\n return `${day.toString().padStart(2, '0')}.${month.toString().padStart(2, '0')}.${year}`;\n \n case 'long':\n return `${day} ${monthNames[month - 1]} ${year} года, ${hours}:${minutes}`;\n \n case 'iso':\n return d.toISOString();\n \n default:\n return `${day} ${monthNames[month - 1]} ${year}, ${hours}:${minutes}`;\n }\n}\n\n/**\n * Форматирует относительное время (\"5 минут назад\")\n * @param {Date|string|number} date - Дата\n * @returns {string} Относительное время\n */\nfunction formatRelative(date) {\n const d = new Date(date);\n const now = new Date();\n const diffMs = now - d;\n const diffSec = Math.round(diffMs / 1000);\n const diffMin = Math.round(diffSec / 60);\n const diffHour = Math.round(diffMin / 60);\n const diffDay = Math.round(diffHour / 24);\n \n if (diffSec < 60) {\n return 'только что';\n } else if (diffMin < 60) {\n return `${diffMin} ${declension(diffMin, ['минуту', 'минуты', 'минут'])} назад`;\n } else if (diffHour < 24) {\n return `${diffHour} ${declension(diffHour, ['час', 'часа', 'часов'])} назад`;\n } else if (diffDay < 7) {\n return `${diffDay} ${declension(diffDay, ['день', 'дня', 'дней'])} назад`;\n } else {\n return formatDate(date, 'short');\n }\n}\n\n/**\n * Склонение слов по числительному\n */\nfunction declension(number, words) {\n const cases = [2, 0, 1, 1, 1, 2];\n return words[(number % 100 > 4 && number % 100 < 20) ? 2 : cases[(number % 10 < 5) ? number % 10 : 5]];\n}\n\nmodule.exports = { formatDate, formatRelative };"
}
}
📝 Создание тестов
{
"tool": "write_file",
"params": {
"file_path": "/home/project/tests/formatDate.test.js",
"content": "const { formatDate, formatRelative } = require('../src/utils/formatDate');\n\ndescribe('formatDate', () => {\n test('форматирует дату по умолчанию', () => {\n const date = new Date('2026-03-17T14:30:00');\n expect(formatDate(date)).toBe('17 марта 2026, 14:30');\n });\n \n test('форматирует в коротком формате', () => {\n const date = new Date('2026-03-17T14:30:00');\n expect(formatDate(date, 'short')).toBe('17.03.2026');\n });\n \n test('форматирует в длинном формате', () => {\n const date = new Date('2026-03-17T14:30:00');\n expect(formatDate(date, 'long')).toBe('17 марта 2026 года, 14:30');\n });\n \n test('форматирует в ISO', () => {\n const date = new Date('2026-03-17T14:30:00.000Z');\n expect(formatDate(date, 'iso')).toBe('2026-03-17T14:30:00.000Z');\n });\n \n test('принимает строку как дату', () => {\n expect(formatDate('2026-03-17', 'short')).toBe('17.03.2026');\n });\n \n test('принимает timestamp', () => {\n const timestamp = new Date('2026-03-17').getTime();\n expect(formatDate(timestamp, 'short')).toBe('17.03.2026');\n });\n \n test('бросает ошибку для невалидной даты', () => {\n expect(() => formatDate('invalid')).toThrow('Invalid date');\n });\n});\n\ndescribe('formatRelative', () => {\n test('возвращает \"только что\" для недавних дат', () => {\n const now = new Date();\n const past = new Date(now.getTime() - 30 * 1000); // 30 секунд назад\n expect(formatRelative(past)).toBe('только что');\n });\n \n test('форматирует минуты назад', () => {\n const now = new Date();\n const past = new Date(now.getTime() - 5 * 60 * 1000); // 5 минут назад\n expect(formatRelative(past)).toBe('5 минут назад');\n });\n \n test('форматирует часы назад', () => {\n const now = new Date();\n const past = new Date(now.getTime() - 3 * 60 * 60 * 1000); // 3 часа назад\n expect(formatRelative(past)).toBe('3 часа назад');\n });\n \n test('форматирует дни назад', () => {\n const now = new Date();\n const past = new Date(now.getTime() - 2 * 24 * 60 * 60 * 1000); // 2 дня назад\n expect(formatRelative(past)).toBe('2 дня назад');\n });\n});"
}
}
✅ Запуск тестов
{
"tool": "run_shell_command",
"params": {
"command": "npm test -- formatDate.test.js",
"description": "Запуск тестов для formatDate",
"is_background": false
}
}
PASS tests/formatDate.test.js
formatDate
✓ форматирует дату по умолчанию (3 ms)
✓ форматирует в коротком формате (1 ms)
✓ форматирует в длинном формате
✓ форматирует в ISO
✓ принимает строку как дату
✓ принимает timestamp
✓ бросает ошибку для невалидной даты (12 ms)
formatRelative
✓ возвращает "только что" для недавних дат (1 ms)
✓ форматирует минуты назад
✓ форматирует часы назад
✓ форматирует дни назад (1 ms)
Test Suites: 1 passed, 1 total
Tests: 11 passed, 11 total
🔄 Пример 5: Параллельное выполнение задач
Сценарий: Одновременный поиск по нескольким паттернам
{
"tool": "grep_search",
"params": {
"pattern": "(app\\.(get|post|put|delete|patch)|router\\.(get|post|put|delete|patch))\\(['\"]",
"glob": "**/*.js",
"path": "/home/project/src"
}
}
{
"tool": "glob",
"params": {
"pattern": "**/routes/**/*.js"
}
}
{
"tool": "grep_search",
"params": {
"pattern": "@(Get|Post|Put|Delete|Patch)\\(",
"glob": "**/*.ts"
}
}
{
"tool": "read_file",
"params": {
"absolute_path": "/home/project/src/routes/users.js",
"offset": 0,
"limit": 50
}
}
📋 Пример 6: Управление задачами через todo_write
{
"tool": "todo_write",
"params": {
"todos": [
{
"id": "1",
"content": "Создать CSS переменные для темной темы",
"status": "pending"
},
{
"id": "2",
"content": "Добавить переключатель темы в UI",
"status": "pending"
},
{
"id": "3",
"content": "Реализовать логику переключения в JavaScript",
"status": "pending"
},
{
"id": "4",
"content": "Сохранять выбор темы в localStorage",
"status": "pending"
},
{
"id": "5",
"content": "Протестировать переключение темы",
"status": "pending"
}
]
}
}
{
"tool": "todo_write",
"params": {
"todos": [
{"id": "1", "content": "Создать CSS переменные для темной темы", "status": "completed"},
{"id": "2", "content": "Добавить переключатель темы в UI", "status": "in_progress"},
{"id": "3", "content": "Реализовать логику переключения в JavaScript", "status": "pending"},
{"id": "4", "content": "Сохранять выбор темы в localStorage", "status": "pending"},
{"id": "5", "content": "Протестировать переключение темы", "status": "pending"}
]
}
}
🌐 Пример 7: Web инструменты
Сценарий: Получение актуальной документации
{
"tool": "web_search",
"params": {
"query": "Node.js 21 fetch API documentation 2024",
"provider": "google"
}
}
1. https://nodejs.org/api/globals.html#fetch
2. https://github.com/nodejs/undici
3. https://www.npmjs.com/package/node-fetch
{
"tool": "web_fetch",
"params": {
"url": "https://nodejs.org/api/globals.html#fetch",
"prompt": "Извлеки примеры использования fetch API и основные методы"
}
}
## Fetch API в Node.js 21
### Базовое использование:
```javascript
// GET запрос
const response = await fetch('https://api.example.com/data');
const data = await response.json();
// POST запрос
const response = await fetch('https://api.example.com/data', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ key: 'value' })
});
// Обработка ошибок
try {
const response = await fetch(url);
if (!response.ok) throw new Error(`HTTP ${response.status}`);
const data = await response.json();
} catch (error) {
console.error('Fetch failed:', error);
}
```