@vint.tri/report_gen_mcp 1.2.0 → 1.2.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CORRECT_CHART_EXAMPLES.md +155 -0
- package/NEURAL_NETWORK_INSTRUCTIONS.md +344 -0
- package/README.md +6 -0
- package/dist/charts/bar.js +2 -2
- package/dist/charts/doughnut.js +2 -2
- package/dist/charts/line.js +1 -1
- package/dist/charts/pie.js +2 -2
- package/dist/charts/polarArea.js +2 -2
- package/dist/charts/radar.js +2 -2
- package/dist/index.js +55 -3
- package/dist/utils/reportGenerator.js +31 -1
- package/package.json +1 -1
- package/test_chart_format.js +146 -0
|
@@ -0,0 +1,155 @@
|
|
|
1
|
+
# Примеры правильных конфигураций для всех типов графиков
|
|
2
|
+
|
|
3
|
+
Этот документ содержит корректные примеры конфигураций для всех поддерживаемых типов графиков в инструменте report_gen_mcp. Все примеры соответствуют требованиям схем валидации и могут быть использованы нейросетью без ошибок.
|
|
4
|
+
|
|
5
|
+
## Линейный график (line)
|
|
6
|
+
|
|
7
|
+
```json
|
|
8
|
+
{
|
|
9
|
+
"type": "line",
|
|
10
|
+
"config": {
|
|
11
|
+
"labels": ["Январь", "Февраль", "Март", "Апрель", "Май"],
|
|
12
|
+
"datasets": [
|
|
13
|
+
{
|
|
14
|
+
"label": "Продажи (USD)",
|
|
15
|
+
"data": [12000, 19000, 15000, 18000, 22000],
|
|
16
|
+
"borderColor": ["rgba(54, 162, 235, 1)"],
|
|
17
|
+
"fill": false
|
|
18
|
+
},
|
|
19
|
+
{
|
|
20
|
+
"label": "Затраты (USD)",
|
|
21
|
+
"data": [8000, 11000, 9000, 12000, 15000],
|
|
22
|
+
"borderColor": ["rgba(255, 99, 132, 1)"],
|
|
23
|
+
"fill": false
|
|
24
|
+
}
|
|
25
|
+
],
|
|
26
|
+
"options": {
|
|
27
|
+
"title": "Ежемесячные продажи и затраты"
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
## Столбчатая диаграмма (bar)
|
|
34
|
+
|
|
35
|
+
```json
|
|
36
|
+
{
|
|
37
|
+
"type": "bar",
|
|
38
|
+
"config": {
|
|
39
|
+
"labels": ["Январь", "Февраль", "Март", "Апрель", "Май"],
|
|
40
|
+
"datasets": [
|
|
41
|
+
{
|
|
42
|
+
"label": "Продажи (USD)",
|
|
43
|
+
"data": [12000, 19000, 15000, 18000, 22000],
|
|
44
|
+
"backgroundColor": ["#FF6384", "#36A2EB", "#FFCE56", "#4BC0C0", "#9966FF"],
|
|
45
|
+
"borderColor": ["#FF6384", "#36A2EB", "#FFCE56", "#4BC0C0", "#9966FF"]
|
|
46
|
+
}
|
|
47
|
+
],
|
|
48
|
+
"options": {
|
|
49
|
+
"title": "Ежемесячные продажи"
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
## Круговая диаграмма (pie)
|
|
56
|
+
|
|
57
|
+
```json
|
|
58
|
+
{
|
|
59
|
+
"type": "pie",
|
|
60
|
+
"config": {
|
|
61
|
+
"labels": ["Красный", "Синий", "Желтый", "Зеленый", "Фиолетовый"],
|
|
62
|
+
"datasets": [
|
|
63
|
+
{
|
|
64
|
+
"data": [12, 19, 3, 5, 2],
|
|
65
|
+
"backgroundColor": ["#FF6384", "#36A2EB", "#FFCE56", "#4BC0C0", "#9966FF"],
|
|
66
|
+
"borderColor": ["#FF6384", "#36A2EB", "#FFCE56", "#4BC0C0", "#9966FF"]
|
|
67
|
+
}
|
|
68
|
+
],
|
|
69
|
+
"options": {
|
|
70
|
+
"title": "Распределение по категориям"
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
## Кольцевая диаграмма (doughnut)
|
|
77
|
+
|
|
78
|
+
```json
|
|
79
|
+
{
|
|
80
|
+
"type": "doughnut",
|
|
81
|
+
"config": {
|
|
82
|
+
"labels": ["Красный", "Синий", "Желтый", "Зеленый", "Фиолетовый"],
|
|
83
|
+
"datasets": [
|
|
84
|
+
{
|
|
85
|
+
"data": [12, 19, 3, 5, 2],
|
|
86
|
+
"backgroundColor": ["#FF6384", "#36A2EB", "#FFCE56", "#4BC0C0", "#9966FF"],
|
|
87
|
+
"borderColor": ["#FF6384", "#36A2EB", "#FFCE56", "#4BC0C0", "#9966FF"]
|
|
88
|
+
}
|
|
89
|
+
],
|
|
90
|
+
"options": {
|
|
91
|
+
"title": "Распределение по категориям"
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
## Радарная диаграмма (radar)
|
|
98
|
+
|
|
99
|
+
```json
|
|
100
|
+
{
|
|
101
|
+
"type": "radar",
|
|
102
|
+
"config": {
|
|
103
|
+
"labels": ["Eating", "Drinking", "Sleeping", "Designing", "Coding", "Cycling", "Running"],
|
|
104
|
+
"datasets": [
|
|
105
|
+
{
|
|
106
|
+
"label": "Person 1",
|
|
107
|
+
"data": [65, 59, 90, 81, 56, 55, 40],
|
|
108
|
+
"backgroundColor": ["rgba(255, 99, 132, 0.2)"],
|
|
109
|
+
"borderColor": ["rgba(255, 99, 132, 1)"]
|
|
110
|
+
},
|
|
111
|
+
{
|
|
112
|
+
"label": "Person 2",
|
|
113
|
+
"data": [28, 48, 40, 19, 96, 27, 100],
|
|
114
|
+
"backgroundColor": ["rgba(54, 162, 235, 0.2)"],
|
|
115
|
+
"borderColor": ["rgba(54, 162, 235, 1)"]
|
|
116
|
+
}
|
|
117
|
+
],
|
|
118
|
+
"options": {
|
|
119
|
+
"title": "Радарная диаграмма"
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
## Полярная диаграмма (polarArea)
|
|
126
|
+
|
|
127
|
+
```json
|
|
128
|
+
{
|
|
129
|
+
"type": "polarArea",
|
|
130
|
+
"config": {
|
|
131
|
+
"labels": ["Red", "Green", "Yellow", "Grey", "Blue"],
|
|
132
|
+
"datasets": [
|
|
133
|
+
{
|
|
134
|
+
"data": [11, 16, 7, 3, 14],
|
|
135
|
+
"backgroundColor": ["#FF6384", "#4BC0C0", "#FFCE56", "#E7E9ED", "#36A2EB"],
|
|
136
|
+
"borderColor": ["#FF6384", "#4BC0C0", "#FFCE56", "#E7E9ED", "#36A2EB"]
|
|
137
|
+
}
|
|
138
|
+
],
|
|
139
|
+
"options": {
|
|
140
|
+
"title": "Полярная диаграмма"
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
```
|
|
145
|
+
|
|
146
|
+
## Важные замечания
|
|
147
|
+
|
|
148
|
+
1. Все цветовые значения (`backgroundColor`, `borderColor`) представлены в виде массивов строк, даже если используется только один цвет.
|
|
149
|
+
2. Все числовые данные (`data`) представлены в виде массивов чисел.
|
|
150
|
+
3. Все текстовые метки (`labels`) представлены в виде массивов строк.
|
|
151
|
+
4. Для линейных графиков свойство `borderColor` обязательно должно быть массивом.
|
|
152
|
+
5. Для столбчатых, круговых, кольцевых и полярных диаграмм свойства `backgroundColor` и `borderColor` обязательны и должны быть массивами.
|
|
153
|
+
6. Для радарных диаграмм свойства `backgroundColor` и `borderColor` также обязательны и должны быть массивами.
|
|
154
|
+
|
|
155
|
+
Следование этим примерам поможет избежать ошибок при генерации отчетов.
|
|
@@ -0,0 +1,344 @@
|
|
|
1
|
+
# Инструкции для нейросети по работе с инструментом report_gen_mcp
|
|
2
|
+
|
|
3
|
+
Этот документ содержит специальные инструкции для нейросети при работе с инструментом `report_gen_mcp`, чтобы обеспечить правильное взаимодействие с пользователем после генерации отчетов.
|
|
4
|
+
|
|
5
|
+
## Общие принципы работы
|
|
6
|
+
|
|
7
|
+
При использовании инструмента `report_gen_mcp` для генерации отчетов, нейросеть должна следовать определенному протоколу взаимодействия с пользователем, чтобы обеспечить полную и удобную работу с созданными отчетами.
|
|
8
|
+
|
|
9
|
+
## Поддерживаемые элементы отчета
|
|
10
|
+
|
|
11
|
+
Инструмент поддерживает вставку в отчеты следующих элементов:
|
|
12
|
+
1. **Диаграммы** (charts) - различные типы графиков (bar, line, pie, doughnut, radar, polarArea)
|
|
13
|
+
2. **Изображения** (images) - два типа:
|
|
14
|
+
- Сгенерированные сервисом pollinations.ai по текстовому описанию
|
|
15
|
+
- По URL из интернета
|
|
16
|
+
|
|
17
|
+
## После генерации отчета
|
|
18
|
+
|
|
19
|
+
После успешной генерации отчета с помощью метода `generate-report`, нейросеть получает всю необходимую информацию напрямую в ответе от метода. Необходимо предоставить пользователю следующую информацию:
|
|
20
|
+
|
|
21
|
+
### 1. Предоставление информации пользователю
|
|
22
|
+
|
|
23
|
+
Из ответа метода `generate-report` извлеките следующую информацию и предоставьте пользователю:
|
|
24
|
+
|
|
25
|
+
1. **Путь к файлу**: Абсолютный путь к созданному отчету
|
|
26
|
+
2. **Ссылка на файл**: Кликабельная file:// ссылка для открытия отчета в браузере
|
|
27
|
+
3. **Содержимое файла**: Полный текст HTML содержимого отчета
|
|
28
|
+
|
|
29
|
+
Обязательно покажите пользователю содержимое файла, чтобы он мог сразу ознакомиться с результатом без необходимости открывать файл отдельно.
|
|
30
|
+
|
|
31
|
+
Пример формата ответа пользователю:
|
|
32
|
+
```
|
|
33
|
+
Отчет успешно создан!
|
|
34
|
+
|
|
35
|
+
📁 Путь к файлу: /полный/путь/к/отчету.html
|
|
36
|
+
🌐 Ссылка для открытия в браузере: file:///полный/путь/к/отчету.html
|
|
37
|
+
|
|
38
|
+
📄 Содержимое отчета:
|
|
39
|
+
<!DOCTYPE html>
|
|
40
|
+
<html>
|
|
41
|
+
<head>
|
|
42
|
+
<meta charset="UTF-8">
|
|
43
|
+
<title>Report</title>
|
|
44
|
+
<style>
|
|
45
|
+
body { font-family: Arial, sans-serif; }
|
|
46
|
+
.chart-container, .image-container { margin: 20px 0; }
|
|
47
|
+
</style>
|
|
48
|
+
<script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
|
|
49
|
+
</head>
|
|
50
|
+
<body>
|
|
51
|
+
<h1>Отчет</h1>
|
|
52
|
+
<div class="chart-container">
|
|
53
|
+
<!-- Chart.js chart code -->
|
|
54
|
+
</div>
|
|
55
|
+
<div class="image-container">
|
|
56
|
+
<!-- Generated image -->
|
|
57
|
+
<img src="https://image.pollinations.ai/prompt/красивый%20закат" alt="красивый закат">
|
|
58
|
+
</div>
|
|
59
|
+
</body>
|
|
60
|
+
</html>
|
|
61
|
+
|
|
62
|
+
Вы можете открыть отчет, кликнув на ссылку выше или скопировав путь к файлу.
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
### 2. Альтернативный подход (при необходимости)
|
|
66
|
+
|
|
67
|
+
Если по какой-то причине информация не была получена напрямую из метода `generate-report`, можно использовать дополнительные инструменты:
|
|
68
|
+
|
|
69
|
+
#### Получение информации о файле
|
|
70
|
+
|
|
71
|
+
Используйте инструмент `get-report-url` для получения полной информации о созданном отчете:
|
|
72
|
+
|
|
73
|
+
```json
|
|
74
|
+
{
|
|
75
|
+
"method": "tools/call",
|
|
76
|
+
"params": {
|
|
77
|
+
"name": "get-report-url",
|
|
78
|
+
"arguments": {
|
|
79
|
+
"filePath": "/путь/к/созданному/отчету.html"
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
#### Прикрепление содержимого файла
|
|
86
|
+
|
|
87
|
+
Для того чтобы пользователь мог сразу просмотреть содержимое отчета без необходимости открывать файл, используйте инструмент `get-report-file`:
|
|
88
|
+
|
|
89
|
+
```json
|
|
90
|
+
{
|
|
91
|
+
"method": "tools/call",
|
|
92
|
+
"params": {
|
|
93
|
+
"name": "get-report-file",
|
|
94
|
+
"arguments": {
|
|
95
|
+
"filePath": "/путь/к/созданному/отчету.html"
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
## Формат данных для диаграмм (графиков)
|
|
102
|
+
|
|
103
|
+
Очень важно правильно формировать данные для диаграмм, чтобы избежать ошибок. Ниже приведены точные требования к формату данных для каждого типа диаграмм.
|
|
104
|
+
|
|
105
|
+
### Общие правила для всех типов диаграмм
|
|
106
|
+
|
|
107
|
+
1. Все цветовые значения (`backgroundColor`, `borderColor`) должны быть представлены в виде **массивов строк**, даже если это один цвет.
|
|
108
|
+
2. Все числовые данные (`data`) должны быть представлены в виде массивов чисел.
|
|
109
|
+
3. Все текстовые метки (`labels`) должны быть представлены в виде массивов строк.
|
|
110
|
+
|
|
111
|
+
### Линейные диаграммы (line)
|
|
112
|
+
|
|
113
|
+
```json
|
|
114
|
+
{
|
|
115
|
+
"type": "line",
|
|
116
|
+
"config": {
|
|
117
|
+
"labels": ["Январь", "Февраль", "Март", "Апрель", "Май"],
|
|
118
|
+
"datasets": [
|
|
119
|
+
{
|
|
120
|
+
"label": "Продажи (USD)",
|
|
121
|
+
"data": [12000, 19000, 15000, 18000, 22000],
|
|
122
|
+
"borderColor": ["rgba(54, 162, 235, 1)"], // ВАЖНО: массив, даже для одного цвета!
|
|
123
|
+
"fill": false
|
|
124
|
+
}
|
|
125
|
+
],
|
|
126
|
+
"options": {
|
|
127
|
+
"title": "Ежемесячные продажи"
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
**Важно**: `borderColor` должен быть массивом строк, даже если используется только один цвет.
|
|
134
|
+
|
|
135
|
+
### Столбчатые диаграммы (bar)
|
|
136
|
+
|
|
137
|
+
```json
|
|
138
|
+
{
|
|
139
|
+
"type": "bar",
|
|
140
|
+
"config": {
|
|
141
|
+
"labels": ["Январь", "Февраль", "Март", "Апрель", "Май"],
|
|
142
|
+
"datasets": [
|
|
143
|
+
{
|
|
144
|
+
"label": "Продажи (USD)",
|
|
145
|
+
"data": [12000, 19000, 15000, 18000, 22000],
|
|
146
|
+
"backgroundColor": ["#FF6384", "#36A2EB", "#FFCE56", "#4BC0C0", "#9966FF"], // Массив цветов
|
|
147
|
+
"borderColor": ["#FF6384", "#36A2EB", "#FFCE56", "#4BC0C0", "#9966FF"] // Массив цветов
|
|
148
|
+
}
|
|
149
|
+
],
|
|
150
|
+
"options": {
|
|
151
|
+
"title": "Ежемесячные продажи"
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
```
|
|
156
|
+
|
|
157
|
+
**Важно**: `backgroundColor` и `borderColor` должны быть массивами строк, даже если используется только один цвет.
|
|
158
|
+
|
|
159
|
+
### Круговые диаграммы (pie)
|
|
160
|
+
|
|
161
|
+
```json
|
|
162
|
+
{
|
|
163
|
+
"type": "pie",
|
|
164
|
+
"config": {
|
|
165
|
+
"labels": ["Красный", "Синий", "Желтый", "Зеленый", "Фиолетовый"],
|
|
166
|
+
"datasets": [
|
|
167
|
+
{
|
|
168
|
+
"data": [12, 19, 3, 5, 2],
|
|
169
|
+
"backgroundColor": ["#FF6384", "#36A2EB", "#FFCE56", "#4BC0C0", "#9966FF"], // Массив цветов
|
|
170
|
+
"borderColor": ["#FF6384", "#36A2EB", "#FFCE56", "#4BC0C0", "#9966FF"] // Массив цветов
|
|
171
|
+
}
|
|
172
|
+
],
|
|
173
|
+
"options": {
|
|
174
|
+
"title": "Распределение по категориям"
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
```
|
|
179
|
+
|
|
180
|
+
**Важно**: `backgroundColor` и `borderColor` должны быть массивами строк, даже если используется только один цвет.
|
|
181
|
+
|
|
182
|
+
### Кольцевые диаграммы (doughnut)
|
|
183
|
+
|
|
184
|
+
```json
|
|
185
|
+
{
|
|
186
|
+
"type": "doughnut",
|
|
187
|
+
"config": {
|
|
188
|
+
"labels": ["Красный", "Синий", "Желтый", "Зеленый", "Фиолетовый"],
|
|
189
|
+
"datasets": [
|
|
190
|
+
{
|
|
191
|
+
"data": [12, 19, 3, 5, 2],
|
|
192
|
+
"backgroundColor": ["#FF6384", "#36A2EB", "#FFCE56", "#4BC0C0", "#9966FF"], // Массив цветов
|
|
193
|
+
"borderColor": ["#FF6384", "#36A2EB", "#FFCE56", "#4BC0C0", "#9966FF"] // Массив цветов
|
|
194
|
+
}
|
|
195
|
+
],
|
|
196
|
+
"options": {
|
|
197
|
+
"title": "Распределение по категориям"
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
```
|
|
202
|
+
|
|
203
|
+
**Важно**: `backgroundColor` и `borderColor` должны быть массивами строк, даже если используется только один цвет.
|
|
204
|
+
|
|
205
|
+
### Радарные диаграммы (radar)
|
|
206
|
+
|
|
207
|
+
```json
|
|
208
|
+
{
|
|
209
|
+
"type": "radar",
|
|
210
|
+
"config": {
|
|
211
|
+
"labels": ["Eating", "Drinking", "Sleeping", "Designing", "Coding", "Cycling", "Running"],
|
|
212
|
+
"datasets": [
|
|
213
|
+
{
|
|
214
|
+
"label": "Person 1",
|
|
215
|
+
"data": [65, 59, 90, 81, 56, 55, 40],
|
|
216
|
+
"backgroundColor": ["rgba(255, 99, 132, 0.2)"], // Массив цветов
|
|
217
|
+
"borderColor": ["rgba(255, 99, 132, 1)"] // Массив цветов
|
|
218
|
+
}
|
|
219
|
+
],
|
|
220
|
+
"options": {
|
|
221
|
+
"title": "Радарная диаграмма"
|
|
222
|
+
}
|
|
223
|
+
}
|
|
224
|
+
}
|
|
225
|
+
```
|
|
226
|
+
|
|
227
|
+
**Важно**: `backgroundColor` и `borderColor` должны быть массивами строк, даже если используется только один цвет.
|
|
228
|
+
|
|
229
|
+
### Полярные диаграммы (polarArea)
|
|
230
|
+
|
|
231
|
+
```json
|
|
232
|
+
{
|
|
233
|
+
"type": "polarArea",
|
|
234
|
+
"config": {
|
|
235
|
+
"labels": ["Red", "Green", "Yellow", "Grey", "Blue"],
|
|
236
|
+
"datasets": [
|
|
237
|
+
{
|
|
238
|
+
"data": [11, 16, 7, 3, 14],
|
|
239
|
+
"backgroundColor": ["#FF6384", "#4BC0C0", "#FFCE56", "#E7E9ED", "#36A2EB"], // Массив цветов
|
|
240
|
+
"borderColor": ["#FF6384", "#4BC0C0", "#FFCE56", "#E7E9ED", "#36A2EB"] // Массив цветов
|
|
241
|
+
}
|
|
242
|
+
],
|
|
243
|
+
"options": {
|
|
244
|
+
"title": "Полярная диаграмма"
|
|
245
|
+
}
|
|
246
|
+
}
|
|
247
|
+
}
|
|
248
|
+
```
|
|
249
|
+
|
|
250
|
+
**Важно**: `backgroundColor` и `borderColor` должны быть массивами строк.
|
|
251
|
+
|
|
252
|
+
## Пример полного взаимодействия
|
|
253
|
+
|
|
254
|
+
Вот пример того, как должно выглядеть полное взаимодействие с пользователем после генерации отчета:
|
|
255
|
+
|
|
256
|
+
1. Генерация отчета:
|
|
257
|
+
```json
|
|
258
|
+
{
|
|
259
|
+
"method": "generate-report",
|
|
260
|
+
"params": {
|
|
261
|
+
"document": "# Отчет\n\n[[chart:mychart]]",
|
|
262
|
+
"charts": {
|
|
263
|
+
"mychart": {
|
|
264
|
+
"type": "bar",
|
|
265
|
+
"config": {
|
|
266
|
+
"labels": ["A", "B", "C"],
|
|
267
|
+
"datasets": [{
|
|
268
|
+
"label": "Data",
|
|
269
|
+
"data": [1, 2, 3],
|
|
270
|
+
"backgroundColor": ["red", "green", "blue"], // Массив цветов
|
|
271
|
+
"borderColor": ["red", "green", "blue"] // Массив цветов
|
|
272
|
+
}]
|
|
273
|
+
}
|
|
274
|
+
}
|
|
275
|
+
},
|
|
276
|
+
"outputFile": "report.html"
|
|
277
|
+
}
|
|
278
|
+
}
|
|
279
|
+
```
|
|
280
|
+
|
|
281
|
+
2. Ответ от метода `generate-report` уже содержит всю необходимую информацию:
|
|
282
|
+
```json
|
|
283
|
+
{
|
|
284
|
+
"content": [
|
|
285
|
+
{
|
|
286
|
+
"type": "text",
|
|
287
|
+
"text": "Report generated successfully.\n\nFOR THE NEURAL NETWORK: Please present the following information to the user:\n1. Path to file: /path/to/report.html\n2. Web browser link: file:///path/to/report.html\n3. File content:\n<!DOCTYPE html>\n<html>...</html>"
|
|
288
|
+
}
|
|
289
|
+
]
|
|
290
|
+
}
|
|
291
|
+
```
|
|
292
|
+
|
|
293
|
+
3. Ответ пользователю (на основе информации из ответа метода):
|
|
294
|
+
```
|
|
295
|
+
Отчет успешно создан!
|
|
296
|
+
|
|
297
|
+
📁 Путь к файлу: /path/to/report.html
|
|
298
|
+
🌐 Ссылка для открытия в браузере: file:///path/to/report.html
|
|
299
|
+
|
|
300
|
+
Содержимое отчета:
|
|
301
|
+
<!DOCTYPE html>
|
|
302
|
+
<html>
|
|
303
|
+
<head>
|
|
304
|
+
<meta charset="UTF-8">
|
|
305
|
+
<title>Report</title>
|
|
306
|
+
<style>
|
|
307
|
+
body { font-family: Arial, sans-serif; }
|
|
308
|
+
.chart-container { margin: 20px 0; }
|
|
309
|
+
</style>
|
|
310
|
+
<script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
|
|
311
|
+
</head>
|
|
312
|
+
<body>
|
|
313
|
+
<h1>Отчет</h1>
|
|
314
|
+
<div class="chart-container">
|
|
315
|
+
<!-- Chart.js chart code -->
|
|
316
|
+
</div>
|
|
317
|
+
</body>
|
|
318
|
+
</html>
|
|
319
|
+
|
|
320
|
+
Вы можете открыть отчет, кликнув на ссылку выше или скопировав путь к файлу.
|
|
321
|
+
```
|
|
322
|
+
|
|
323
|
+
## Частые ошибки и как их избежать
|
|
324
|
+
|
|
325
|
+
1. **Ошибка формата цвета**: Передача `borderColor` или `backgroundColor` как строки вместо массивов
|
|
326
|
+
- ❌ Неправильно: `"borderColor": "red"`
|
|
327
|
+
- ✅ Правильно: `"borderColor": ["red"]`
|
|
328
|
+
|
|
329
|
+
2. **Ошибка формата данных**: Передача числовых данных как отдельных значений вместо массивов
|
|
330
|
+
- ❌ Неправильно: `"data": 10`
|
|
331
|
+
- ✅ Правильно: `"data": [10]`
|
|
332
|
+
|
|
333
|
+
3. **Ошибка формата меток**: Передача меток как отдельных значений вместо массивов
|
|
334
|
+
- ❌ Неправильно: `"labels": "Январь"`
|
|
335
|
+
- ✅ Правильно: `"labels": ["Январь"]`
|
|
336
|
+
|
|
337
|
+
## Дополнительные рекомендации
|
|
338
|
+
|
|
339
|
+
1. Всегда проверяйте успешность выполнения каждой операции перед переходом к следующему шагу
|
|
340
|
+
2. Если какой-либо шаг завершается ошибкой, сообщите пользователю об этом и предложите решение
|
|
341
|
+
3. Убедитесь, что все пути к файлам корректны и файлы действительно существуют
|
|
342
|
+
4. При работе с Claude Desktop используйте параметр `tempDirectory` при генерации отчетов для избежания проблем с правами доступа
|
|
343
|
+
|
|
344
|
+
Следование этим инструкциям обеспечит качественное и полное взаимодействие с пользователем при работе с инструментом генерации отчетов.
|
package/README.md
CHANGED
|
@@ -6,6 +6,7 @@ A powerful CLI tool for generating HTML reports with embedded interactive charts
|
|
|
6
6
|
|
|
7
7
|
- Generate professional HTML reports from Markdown documents
|
|
8
8
|
- Embed customizable interactive charts (bar, line, pie, doughnut, radar, polarArea) directly in reports
|
|
9
|
+
- Embed images from URLs or generated by pollinations.ai service
|
|
9
10
|
- Dual operation modes:
|
|
10
11
|
- Command-line interface for direct usage
|
|
11
12
|
- Stdio mode for Claude Desktop integration
|
|
@@ -340,6 +341,11 @@ Required structure:
|
|
|
340
341
|
- Pie charts: `data` (required)
|
|
341
342
|
4. All numerical data must be provided as arrays of numbers
|
|
342
343
|
5. Color values (when provided) must be valid CSS color strings
|
|
344
|
+
6. **IMPORTANT for Neural Networks**: All color properties (`backgroundColor`, `borderColor`) must be provided as arrays of strings, even if there is only one color. This is a common source of errors.
|
|
345
|
+
|
|
346
|
+
For detailed examples of correct chart configurations for all supported chart types, please see [CORRECT_CHART_EXAMPLES.md](CORRECT_CHART_EXAMPLES.md).
|
|
347
|
+
|
|
348
|
+
For special instructions for neural networks on how to properly interact with users after generating reports, please see [NEURAL_NETWORK_INSTRUCTIONS.md](NEURAL_NETWORK_INSTRUCTIONS.md).
|
|
343
349
|
|
|
344
350
|
### Health Check
|
|
345
351
|
|
package/dist/charts/bar.js
CHANGED
|
@@ -4,8 +4,8 @@ export const barSchema = z.object({
|
|
|
4
4
|
datasets: z.array(z.object({
|
|
5
5
|
label: z.string(),
|
|
6
6
|
data: z.array(z.number()),
|
|
7
|
-
backgroundColor: z.array(z.string()).optional(),
|
|
8
|
-
borderColor: z.array(z.string()).optional(),
|
|
7
|
+
backgroundColor: z.union([z.string(), z.array(z.string())]).optional(),
|
|
8
|
+
borderColor: z.union([z.string(), z.array(z.string())]).optional(),
|
|
9
9
|
})),
|
|
10
10
|
options: z.object({
|
|
11
11
|
title: z.string().optional(),
|
package/dist/charts/doughnut.js
CHANGED
|
@@ -3,8 +3,8 @@ export const doughnutSchema = z.object({
|
|
|
3
3
|
labels: z.array(z.string()),
|
|
4
4
|
datasets: z.array(z.object({
|
|
5
5
|
data: z.array(z.number()),
|
|
6
|
-
backgroundColor: z.array(z.string()).optional(),
|
|
7
|
-
borderColor: z.array(z.string()).optional(),
|
|
6
|
+
backgroundColor: z.union([z.string(), z.array(z.string())]).optional(),
|
|
7
|
+
borderColor: z.union([z.string(), z.array(z.string())]).optional(),
|
|
8
8
|
})),
|
|
9
9
|
options: z.object({
|
|
10
10
|
title: z.string().optional(),
|
package/dist/charts/line.js
CHANGED
|
@@ -4,7 +4,7 @@ export const lineSchema = z.object({
|
|
|
4
4
|
datasets: z.array(z.object({
|
|
5
5
|
label: z.string(),
|
|
6
6
|
data: z.array(z.number()),
|
|
7
|
-
borderColor: z.array(z.string()).optional(),
|
|
7
|
+
borderColor: z.union([z.string(), z.array(z.string())]).optional(),
|
|
8
8
|
fill: z.boolean().optional(),
|
|
9
9
|
})),
|
|
10
10
|
options: z.object({
|
package/dist/charts/pie.js
CHANGED
|
@@ -3,8 +3,8 @@ export const pieSchema = z.object({
|
|
|
3
3
|
labels: z.array(z.string()),
|
|
4
4
|
datasets: z.array(z.object({
|
|
5
5
|
data: z.array(z.number()),
|
|
6
|
-
backgroundColor: z.array(z.string()).optional(),
|
|
7
|
-
borderColor: z.array(z.string()).optional(),
|
|
6
|
+
backgroundColor: z.union([z.string(), z.array(z.string())]).optional(),
|
|
7
|
+
borderColor: z.union([z.string(), z.array(z.string())]).optional(),
|
|
8
8
|
})),
|
|
9
9
|
options: z.object({
|
|
10
10
|
title: z.string().optional(),
|
package/dist/charts/polarArea.js
CHANGED
|
@@ -3,8 +3,8 @@ export const polarAreaSchema = z.object({
|
|
|
3
3
|
labels: z.array(z.string()),
|
|
4
4
|
datasets: z.array(z.object({
|
|
5
5
|
data: z.array(z.number()),
|
|
6
|
-
backgroundColor: z.array(z.string()).optional(),
|
|
7
|
-
borderColor: z.array(z.string()).optional(),
|
|
6
|
+
backgroundColor: z.union([z.string(), z.array(z.string())]).optional(),
|
|
7
|
+
borderColor: z.union([z.string(), z.array(z.string())]).optional(),
|
|
8
8
|
})),
|
|
9
9
|
options: z.object({
|
|
10
10
|
title: z.string().optional(),
|
package/dist/charts/radar.js
CHANGED
|
@@ -4,8 +4,8 @@ export const radarSchema = z.object({
|
|
|
4
4
|
datasets: z.array(z.object({
|
|
5
5
|
label: z.string(),
|
|
6
6
|
data: z.array(z.number()),
|
|
7
|
-
backgroundColor: z.array(z.string()).optional(),
|
|
8
|
-
borderColor: z.array(z.string()).optional(),
|
|
7
|
+
backgroundColor: z.union([z.string(), z.array(z.string())]).optional(),
|
|
8
|
+
borderColor: z.union([z.string(), z.array(z.string())]).optional(),
|
|
9
9
|
})),
|
|
10
10
|
options: z.object({
|
|
11
11
|
title: z.string().optional(),
|
package/dist/index.js
CHANGED
|
@@ -102,13 +102,58 @@ if (process.argv.length === 2) {
|
|
|
102
102
|
// No command specified, run in stdio mode using MCP SDK
|
|
103
103
|
const mcpServer = new McpServer({
|
|
104
104
|
name: "report_gen_mcp",
|
|
105
|
-
version: "1.1
|
|
105
|
+
version: "1.2.1",
|
|
106
106
|
}, {
|
|
107
107
|
// Disable health check to prevent automatic calls
|
|
108
108
|
capabilities: {
|
|
109
109
|
tools: {}
|
|
110
110
|
}
|
|
111
111
|
});
|
|
112
|
+
// Utility function to normalize chart configuration data for MCP tool
|
|
113
|
+
// Converts string values to arrays where the schema expects arrays
|
|
114
|
+
function normalizeChartConfigForMCP(config) {
|
|
115
|
+
if (!config || typeof config !== 'object') {
|
|
116
|
+
return config;
|
|
117
|
+
}
|
|
118
|
+
const normalizedConfig = { ...config };
|
|
119
|
+
// Normalize datasets
|
|
120
|
+
if (normalizedConfig.datasets && Array.isArray(normalizedConfig.datasets)) {
|
|
121
|
+
normalizedConfig.datasets = normalizedConfig.datasets.map((dataset) => {
|
|
122
|
+
if (!dataset || typeof dataset !== 'object') {
|
|
123
|
+
return dataset;
|
|
124
|
+
}
|
|
125
|
+
const normalizedDataset = { ...dataset };
|
|
126
|
+
// Convert string values to arrays for color properties
|
|
127
|
+
const colorProperties = ['backgroundColor', 'borderColor'];
|
|
128
|
+
for (const prop of colorProperties) {
|
|
129
|
+
if (normalizedDataset[prop] && typeof normalizedDataset[prop] === 'string') {
|
|
130
|
+
normalizedDataset[prop] = [normalizedDataset[prop]];
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
return normalizedDataset;
|
|
134
|
+
});
|
|
135
|
+
}
|
|
136
|
+
return normalizedConfig;
|
|
137
|
+
}
|
|
138
|
+
// Utility function to normalize elements before MCP schema validation
|
|
139
|
+
function normalizeElementsForMCP(elements) {
|
|
140
|
+
if (!elements || typeof elements !== 'object') {
|
|
141
|
+
return elements;
|
|
142
|
+
}
|
|
143
|
+
const normalizedElements = { ...elements };
|
|
144
|
+
for (const [id, element] of Object.entries(normalizedElements)) {
|
|
145
|
+
if (element && typeof element === 'object' && element.type) {
|
|
146
|
+
const elementType = element.type;
|
|
147
|
+
// Only normalize chart elements, not image elements
|
|
148
|
+
if (['bar', 'line', 'pie', 'doughnut', 'radar', 'polarArea'].includes(elementType)) {
|
|
149
|
+
if (element.config) {
|
|
150
|
+
element.config = normalizeChartConfigForMCP(element.config);
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
return normalizedElements;
|
|
156
|
+
}
|
|
112
157
|
// Register the generate-report tool
|
|
113
158
|
mcpServer.registerTool("generate-report", {
|
|
114
159
|
description: "Generate an HTML report with embedded charts",
|
|
@@ -122,8 +167,8 @@ if (process.argv.length === 2) {
|
|
|
122
167
|
datasets: z.array(z.object({
|
|
123
168
|
label: z.string().optional(),
|
|
124
169
|
data: z.array(z.number()),
|
|
125
|
-
backgroundColor: z.array(z.string()).optional(),
|
|
126
|
-
borderColor: z.array(z.string()).optional(),
|
|
170
|
+
backgroundColor: z.union([z.string(), z.array(z.string())]).optional(),
|
|
171
|
+
borderColor: z.union([z.string(), z.array(z.string())]).optional(),
|
|
127
172
|
fill: z.boolean().optional(),
|
|
128
173
|
})),
|
|
129
174
|
options: z.object({
|
|
@@ -170,6 +215,13 @@ if (process.argv.length === 2) {
|
|
|
170
215
|
else if (params.arguments && typeof params.arguments === 'object') {
|
|
171
216
|
processedParams = params.arguments;
|
|
172
217
|
}
|
|
218
|
+
// Normalize elements before extracting them to fix string/array issues
|
|
219
|
+
if (processedParams.elements) {
|
|
220
|
+
processedParams.elements = normalizeElementsForMCP(processedParams.elements);
|
|
221
|
+
}
|
|
222
|
+
if (processedParams.charts) {
|
|
223
|
+
processedParams.charts = normalizeElementsForMCP(processedParams.charts);
|
|
224
|
+
}
|
|
173
225
|
// Extract parameters correctly, ensuring outputFile is not nested within elements
|
|
174
226
|
const { document, elements, charts, outputFile = 'report.html', tempDirectory } = processedParams;
|
|
175
227
|
// Поддержка обратной совместимости: если переданы charts, используем их как elements
|
|
@@ -20,6 +20,32 @@ const imageRenderers = {
|
|
|
20
20
|
pollinations: { schema: pollinationsImageSchema, renderer: renderPollinationsImage },
|
|
21
21
|
url: { schema: urlImageSchema, renderer: renderUrlImage },
|
|
22
22
|
};
|
|
23
|
+
// Utility function to normalize chart configuration data
|
|
24
|
+
// Converts string values to arrays where the schema expects arrays
|
|
25
|
+
function normalizeChartConfig(config) {
|
|
26
|
+
if (!config || typeof config !== 'object') {
|
|
27
|
+
return config;
|
|
28
|
+
}
|
|
29
|
+
const normalizedConfig = { ...config };
|
|
30
|
+
// Normalize datasets
|
|
31
|
+
if (normalizedConfig.datasets && Array.isArray(normalizedConfig.datasets)) {
|
|
32
|
+
normalizedConfig.datasets = normalizedConfig.datasets.map((dataset) => {
|
|
33
|
+
if (!dataset || typeof dataset !== 'object') {
|
|
34
|
+
return dataset;
|
|
35
|
+
}
|
|
36
|
+
const normalizedDataset = { ...dataset };
|
|
37
|
+
// Convert string values to arrays for color properties
|
|
38
|
+
const colorProperties = ['backgroundColor', 'borderColor'];
|
|
39
|
+
for (const prop of colorProperties) {
|
|
40
|
+
if (normalizedDataset[prop] && typeof normalizedDataset[prop] === 'string') {
|
|
41
|
+
normalizedDataset[prop] = [normalizedDataset[prop]];
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
return normalizedDataset;
|
|
45
|
+
});
|
|
46
|
+
}
|
|
47
|
+
return normalizedConfig;
|
|
48
|
+
}
|
|
23
49
|
export async function generateReport(document, elements, outputFile) {
|
|
24
50
|
// Validate elements
|
|
25
51
|
for (const [id, element] of Object.entries(elements)) {
|
|
@@ -29,7 +55,11 @@ export async function generateReport(document, elements, outputFile) {
|
|
|
29
55
|
const { schema } = chartRenderers[chartElement.type];
|
|
30
56
|
if (!schema)
|
|
31
57
|
throw new Error(`Unsupported chart type: ${chartElement.type}`);
|
|
32
|
-
|
|
58
|
+
// Normalize the chart configuration before validation
|
|
59
|
+
const normalizedConfig = normalizeChartConfig(chartElement.config);
|
|
60
|
+
schema.parse(normalizedConfig);
|
|
61
|
+
// Update the element with normalized config for rendering
|
|
62
|
+
element.config = normalizedConfig;
|
|
33
63
|
}
|
|
34
64
|
else if (element.type in imageRenderers) {
|
|
35
65
|
// Это изображение
|
package/package.json
CHANGED
|
@@ -0,0 +1,146 @@
|
|
|
1
|
+
import { spawn } from 'child_process';
|
|
2
|
+
import fs from 'fs';
|
|
3
|
+
|
|
4
|
+
// Тестовая конфигурация с правильным форматом данных
|
|
5
|
+
const config = {
|
|
6
|
+
document: "# Тестовый отчет\n\nЭтот отчет демонстрирует правильный формат данных для всех типов графиков.\n\n## Линейный график\n\n[[chart:lineChart]]\n\n## Столбчатая диаграмма\n\n[[chart:barChart]]\n\n## Круговая диаграмма\n\n[[chart:pieChart]]\n\n## Кольцевая диаграмма\n\n[[chart:doughnutChart]]\n\n## Радарная диаграмма\n\n[[chart:radarChart]]\n\n## Полярная диаграмма\n\n[[chart:polarAreaChart]]",
|
|
7
|
+
charts: {
|
|
8
|
+
lineChart: {
|
|
9
|
+
type: "line",
|
|
10
|
+
config: {
|
|
11
|
+
labels: ["Январь", "Февраль", "Март", "Апрель", "Май"],
|
|
12
|
+
datasets: [
|
|
13
|
+
{
|
|
14
|
+
label: "Продажи (USD)",
|
|
15
|
+
data: [12000, 19000, 15000, 18000, 22000],
|
|
16
|
+
borderColor: ["rgba(54, 162, 235, 1)"],
|
|
17
|
+
fill: false
|
|
18
|
+
}
|
|
19
|
+
],
|
|
20
|
+
options: {
|
|
21
|
+
title: "Линейный график продаж"
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
},
|
|
25
|
+
barChart: {
|
|
26
|
+
type: "bar",
|
|
27
|
+
config: {
|
|
28
|
+
labels: ["Январь", "Февраль", "Март", "Апрель", "Май"],
|
|
29
|
+
datasets: [
|
|
30
|
+
{
|
|
31
|
+
label: "Продажи (USD)",
|
|
32
|
+
data: [12000, 19000, 15000, 18000, 22000],
|
|
33
|
+
backgroundColor: ["#FF6384", "#36A2EB", "#FFCE56", "#4BC0C0", "#9966FF"],
|
|
34
|
+
borderColor: ["#FF6384", "#36A2EB", "#FFCE56", "#4BC0C0", "#9966FF"]
|
|
35
|
+
}
|
|
36
|
+
],
|
|
37
|
+
options: {
|
|
38
|
+
title: "Столбчатая диаграмма продаж"
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
},
|
|
42
|
+
pieChart: {
|
|
43
|
+
type: "pie",
|
|
44
|
+
config: {
|
|
45
|
+
labels: ["Красный", "Синий", "Желтый", "Зеленый", "Фиолетовый"],
|
|
46
|
+
datasets: [
|
|
47
|
+
{
|
|
48
|
+
data: [12, 19, 3, 5, 2],
|
|
49
|
+
backgroundColor: ["#FF6384", "#36A2EB", "#FFCE56", "#4BC0C0", "#9966FF"],
|
|
50
|
+
borderColor: ["#FF6384", "#36A2EB", "#FFCE56", "#4BC0C0", "#9966FF"]
|
|
51
|
+
}
|
|
52
|
+
],
|
|
53
|
+
options: {
|
|
54
|
+
title: "Круговая диаграмма категорий"
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
},
|
|
58
|
+
doughnutChart: {
|
|
59
|
+
type: "doughnut",
|
|
60
|
+
config: {
|
|
61
|
+
labels: ["Красный", "Синий", "Желтый", "Зеленый", "Фиолетовый"],
|
|
62
|
+
datasets: [
|
|
63
|
+
{
|
|
64
|
+
data: [12, 19, 3, 5, 2],
|
|
65
|
+
backgroundColor: ["#FF6384", "#36A2EB", "#FFCE56", "#4BC0C0", "#9966FF"],
|
|
66
|
+
borderColor: ["#FF6384", "#36A2EB", "#FFCE56", "#4BC0C0", "#9966FF"]
|
|
67
|
+
}
|
|
68
|
+
],
|
|
69
|
+
options: {
|
|
70
|
+
title: "Кольцевая диаграмма категорий"
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
},
|
|
74
|
+
radarChart: {
|
|
75
|
+
type: "radar",
|
|
76
|
+
config: {
|
|
77
|
+
labels: ["Eating", "Drinking", "Sleeping", "Designing", "Coding", "Cycling", "Running"],
|
|
78
|
+
datasets: [
|
|
79
|
+
{
|
|
80
|
+
label: "Person 1",
|
|
81
|
+
data: [65, 59, 90, 81, 56, 55, 40],
|
|
82
|
+
backgroundColor: ["rgba(255, 99, 132, 0.2)"],
|
|
83
|
+
borderColor: ["rgba(255, 99, 132, 1)"]
|
|
84
|
+
}
|
|
85
|
+
],
|
|
86
|
+
options: {
|
|
87
|
+
title: "Радарная диаграмма"
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
},
|
|
91
|
+
polarAreaChart: {
|
|
92
|
+
type: "polarArea",
|
|
93
|
+
config: {
|
|
94
|
+
labels: ["Red", "Green", "Yellow", "Grey", "Blue"],
|
|
95
|
+
datasets: [
|
|
96
|
+
{
|
|
97
|
+
data: [11, 16, 7, 3, 14],
|
|
98
|
+
backgroundColor: ["#FF6384", "#4BC0C0", "#FFCE56", "#E7E9ED", "#36A2EB"],
|
|
99
|
+
borderColor: ["#FF6384", "#4BC0C0", "#FFCE56", "#E7E9ED", "#36A2EB"]
|
|
100
|
+
}
|
|
101
|
+
],
|
|
102
|
+
options: {
|
|
103
|
+
title: "Полярная диаграмма"
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
},
|
|
108
|
+
outputFile: "test_chart_format_report.html"
|
|
109
|
+
};
|
|
110
|
+
|
|
111
|
+
// Установим переменную окружения REPORTS_DIR
|
|
112
|
+
process.env.REPORTS_DIR = './test_reports';
|
|
113
|
+
|
|
114
|
+
// Создадим директорию для отчетов, если она не существует
|
|
115
|
+
if (!fs.existsSync('./test_reports')) {
|
|
116
|
+
fs.mkdirSync('./test_reports');
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
// Запустим генератор отчетов
|
|
120
|
+
const child = spawn('node', ['dist/index.js', 'generate', '--document', config.document, '--charts', JSON.stringify(config.charts), '--output', config.outputFile]);
|
|
121
|
+
|
|
122
|
+
// Слушаем вывод от дочернего процесса
|
|
123
|
+
child.stdout.on('data', (data) => {
|
|
124
|
+
console.log(`stdout: ${data}`);
|
|
125
|
+
});
|
|
126
|
+
|
|
127
|
+
child.stderr.on('data', (data) => {
|
|
128
|
+
console.error(`stderr: ${data}`);
|
|
129
|
+
});
|
|
130
|
+
|
|
131
|
+
child.on('close', (code) => {
|
|
132
|
+
console.log(`Дочерний процесс завершился с кодом ${code}`);
|
|
133
|
+
|
|
134
|
+
// Проверим, был ли создан файл отчета
|
|
135
|
+
const reportPath = `./test_reports/${config.outputFile}`;
|
|
136
|
+
if (fs.existsSync(reportPath)) {
|
|
137
|
+
console.log(`✅ Отчет успешно создан: ${reportPath}`);
|
|
138
|
+
|
|
139
|
+
// Прочитаем содержимое файла
|
|
140
|
+
const reportContent = fs.readFileSync(reportPath, 'utf8');
|
|
141
|
+
console.log(`📄 Содержимое отчета:`);
|
|
142
|
+
console.log(reportContent);
|
|
143
|
+
} else {
|
|
144
|
+
console.log(`❌ Отчет не был создан`);
|
|
145
|
+
}
|
|
146
|
+
});
|