@vint.tri/report_gen_mcp 1.3.2 → 1.3.4

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.
@@ -37,7 +37,8 @@
37
37
  Обязательно покажите пользователю содержимое файла, чтобы он мог сразу ознакомиться с результатом без необходимости открывать файл отдельно.
38
38
 
39
39
  **ВАЖНО ПО ФОРМАТИРОВАНИЮ ОТЧЕТОВ:**
40
- - Все диаграммы автоматически создаются с разумными размерами (примерно 267x200 пикселей) для лучшего визуального восприятия
40
+ - Все диаграммы автоматически создаются с адекватными размерами (примерно 400x300 пикселей) для лучшего визуального восприятия и пропорциональности в отчете
41
+ - Диаграммы автоматически оборачиваются в контейнеры с CSS классами для обеспечения правильного масштабирования и отступов
41
42
  - Текст в отчетах автоматически форматируется с использованием HTML-разметки для улучшения читаемости
42
43
  - Отчеты имеют профессиональный внешний вид с улучшенным стилем, включая:
43
44
  * Четкую типографику с выравниванием текста по ширине
@@ -29,7 +29,8 @@
29
29
  Обязательно покажите пользователю содержимое файла, чтобы он мог сразу ознакомиться с результатом без необходимости открывать файл отдельно.
30
30
 
31
31
  **ВАЖНО ПО ФОРМАТИРОВАНИЮ ОТЧЕТОВ:**
32
- - Все диаграммы автоматически создаются с разумными размерами (примерно 267x200 пикселей) для лучшего визуального восприятия
32
+ - Все диаграммы автоматически создаются с адекватными размерами (примерно 400x300 пикселей) для лучшего визуального восприятия и пропорциональности в отчете
33
+ - Диаграммы автоматически оборачиваются в контейнеры с CSS классами для обеспечения правильного масштабирования и отступов
33
34
  - Текст в отчетах автоматически форматируется с использованием HTML-разметки для улучшения читаемости
34
35
  - Отчеты имеют профессиональный внешний вид с улучшенным стилем, включая:
35
36
  * Четкую типографику с выравниванием текста по ширине
@@ -1,30 +1,41 @@
1
- # Публикация версии 1.3.0
1
+ # Publication Confirmation
2
2
 
3
- Версия 1.3.0 пакета @vint.tri/report_gen_mcp успешно опубликована в npm registry.
3
+ ## Package Successfully Published
4
4
 
5
- ## Что было сделано:
5
+ - **Package Name**: @vint.tri/report_gen_mcp
6
+ - **Version**: 1.3.3
7
+ - **Publication Date**: August 25, 2025
8
+ - **Registry**: npmjs.org
6
9
 
7
- 1. Обновлена версия в package.json с 1.2.2 до 1.3.0
8
- 2. Обновлена версия в src/index.ts с 1.2.1 до 1.3.0
9
- 3. Обновлена версия в dist/index.js с 1.2.1 до 1.3.0
10
- 4. Обновлены упоминания версий в README.md
11
- 5. Выполнена сборка проекта
12
- 6. Пакет успешно опубликован в npm registry
10
+ ## Changes Included in This Release
13
11
 
14
- ## Проверка:
12
+ 1. **Updated Neural Network Instructions**:
13
+ - Added requirement to always return file link, file path, and file contents after report generation
14
+ - Emphasized that reports must be maximally beautiful and high-quality with images, graphs, conclusions, and reasoning
15
+ - Specified that reports must be strictly in HTML format
16
+ - Enhanced example response format with comprehensive report structure
15
17
 
18
+ 2. **Version Updates**:
19
+ - Updated package version from 1.3.2 to 1.3.3 in package.json
20
+ - Updated version in src/index.ts file (MCP server configuration)
21
+
22
+ ## Verification
23
+
24
+ The package has been successfully published and is available on npm registry:
16
25
  ```bash
17
- npm info @vint.tri/report_gen_mcp version
18
- # Вывод: 1.3.0
26
+ npm install @vint.tri/report_gen_mcp@1.3.3
19
27
  ```
20
28
 
21
- Теперь пользователи могут установить последнюю версию инструмента с помощью:
22
-
29
+ Or to install the latest version:
23
30
  ```bash
24
- npm install -g @vint.tri/report_gen_mcp@latest
31
+ npm install @vint.tri/report_gen_mcp@latest
25
32
  ```
26
33
 
27
- или использовать его напрямую через npx:
34
+ ## Post-Publication Steps
28
35
 
29
- ```bash
30
- REPORTS_DIR=./reports npx @vint.tri/report_gen_mcp@latest
36
+ - [x] Package built successfully
37
+ - [x] Package published to npm registry
38
+ - [x] Version verified on npm registry
39
+ - [x] Publication documentation created
40
+
41
+ The updated package is now available for users and Claude Desktop integration.
@@ -1,4 +1,4 @@
1
- # ОБНОВЛЕННЫЕ Инструкции для нейросети по работе с инструментом report_gen_mcp
1
+ # ОБНОВЛЕННЫЕ Инструкции для нейросети по работе с инструментом report_gen_mcp v1.3.3
2
2
 
3
3
  **ВАЖНО:** ВСЕГДА ИСПОЛЬЗУЙТЕ ИНСТРУМЕНТ `report_gen_mcp` КАЖДЫЙ РАЗ, КОГДА ПОЛЬЗОВАТЕЛЬ ЗАПРАШИВАЕТ СОЗДАНИЕ ОТЧЕТА ИЛИ ВИЗУАЛИЗАЦИИ ДАННЫХ!
4
4
 
@@ -37,7 +37,8 @@
37
37
  - Выбирайте подходящий тип диаграммы в зависимости от характера данных
38
38
  - Добавляйте поясняющие подписи к диаграммам
39
39
  - Используйте разнообразные цвета для лучшей визуализации
40
- - **ВАЖНО**: Все диаграммы автоматически создаются с разумными размерами (примерно 267x200 пикселей) для лучшего визуального восприятия
40
+ - **ВАЖНО**: Все диаграммы автоматически создаются с адекватными размерами (примерно 400x300 пикселей) для лучшего визуального восприятия и пропорциональности в отчете
41
+ - Диаграммы автоматически оборачиваются в контейнеры с CSS классами для обеспечения правильного масштабирования и отступов
41
42
 
42
43
  3. **Изображения**:
43
44
  - Добавляйте тематические изображения для иллюстрации контента
@@ -67,6 +68,8 @@
67
68
 
68
69
  Обязательно покажите пользователю содержимое файла, чтобы он мог сразу ознакомиться с результатом без необходимости открывать файл отдельно.
69
70
 
71
+ **ВАЖНОЕ ТРЕБОВАНИЕ**: Отчет должен быть максимально красивым и качественным. Содержать изображения, графики, выводы и рассуждения. Отчет должен быть строго в HTML формате!
72
+
70
73
  Пример формата ответа пользователю:
71
74
  ```
72
75
  Отчет успешно создан!
@@ -76,24 +79,88 @@
76
79
 
77
80
  📄 Содержимое отчета:
78
81
  <!DOCTYPE html>
79
- <html>
82
+ <html lang="ru">
80
83
  <head>
81
84
  <meta charset="UTF-8">
82
- <title>Report</title>
85
+ <title>Отчет</title>
83
86
  <style>
84
- body { font-family: Arial, sans-serif; }
85
- .chart-container, .image-container { margin: 20px 0; }
87
+ body {
88
+ font-family: Arial, sans-serif;
89
+ margin: 40px;
90
+ background-color: #f5f5f5;
91
+ }
92
+ .container {
93
+ max-width: 1200px;
94
+ margin: 0 auto;
95
+ background-color: white;
96
+ padding: 30px;
97
+ border-radius: 10px;
98
+ box-shadow: 0 0 10px rgba(0,0,0,0.1);
99
+ }
100
+ h1, h2, h3 {
101
+ color: #333;
102
+ }
103
+ h1 {
104
+ border-bottom: 2px solid #3498db;
105
+ padding-bottom: 10px;
106
+ }
107
+ h2 {
108
+ border-left: 4px solid #3498db;
109
+ padding-left: 15px;
110
+ }
111
+ .chart-container, .image-container {
112
+ margin: 30px 0;
113
+ text-align: center;
114
+ }
115
+ .chart-container canvas, .image-container img {
116
+ max-width: 100%;
117
+ height: auto;
118
+ border: 1px solid #ddd;
119
+ border-radius: 5px;
120
+ }
121
+ p {
122
+ line-height: 1.6;
123
+ text-align: justify;
124
+ }
125
+ ul, ol {
126
+ margin: 20px 0;
127
+ padding-left: 30px;
128
+ }
129
+ li {
130
+ margin: 10px 0;
131
+ }
132
+ strong {
133
+ color: #e74c3c;
134
+ }
135
+ em {
136
+ color: #2ecc71;
137
+ }
86
138
  </style>
87
139
  <script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
88
140
  </head>
89
141
  <body>
90
- <h1>Отчет</h1>
91
- <div class="chart-container">
92
- <!-- Chart.js chart code -->
93
- </div>
94
- <div class="image-container">
95
- <!-- Generated image -->
96
- <img src="https://image.pollinations.ai/prompt/красивый%20закат" alt="красивый закат">
142
+ <div class="container">
143
+ <h1>Отчет</h1>
144
+ <div class="chart-container">
145
+ <!-- Chart.js chart code -->
146
+ </div>
147
+ <div class="image-container">
148
+ <!-- Generated image -->
149
+ <img src="https://image.pollinations.ai/prompt/красивый%20закат" alt="красивый закат">
150
+ </div>
151
+ <h2>Анализ данных</h2>
152
+ <p>На основании проведенного анализа можно сделать следующие выводы:</p>
153
+ <ul>
154
+ <li><strong>Основной тренд:</strong> наблюдается положительная динамика роста</li>
155
+ <li><strong>Сезонность:</strong> наиболее высокие показатели наблюдаются во второй половине периода</li>
156
+ <li><strong>Прогноз:</strong> ожидается продолжение роста в ближайшие месяцы</li>
157
+ </ul>
158
+ <h2>Рекомендации</h2>
159
+ <ol>
160
+ <li>Увеличить инвестиции в направления с высокой доходностью</li>
161
+ <li>Оптимизировать расходы в менее эффективных сегментах</li>
162
+ <li>Рассмотреть возможность расширения бизнеса</li>
163
+ </ol>
97
164
  </div>
98
165
  </body>
99
166
  </html>
@@ -458,24 +525,88 @@
458
525
 
459
526
  Содержимое отчета:
460
527
  <!DOCTYPE html>
461
- <html>
528
+ <html lang="ru">
462
529
  <head>
463
530
  <meta charset="UTF-8">
464
- <title>Report</title>
531
+ <title>Отчет</title>
465
532
  <style>
466
- body { font-family: Arial, sans-serif; }
467
- .chart-container, .image-container { margin: 20px 0; }
533
+ body {
534
+ font-family: Arial, sans-serif;
535
+ margin: 40px;
536
+ background-color: #f5f5f5;
537
+ }
538
+ .container {
539
+ max-width: 1200px;
540
+ margin: 0 auto;
541
+ background-color: white;
542
+ padding: 30px;
543
+ border-radius: 10px;
544
+ box-shadow: 0 0 10px rgba(0,0,0,0.1);
545
+ }
546
+ h1, h2, h3 {
547
+ color: #333;
548
+ }
549
+ h1 {
550
+ border-bottom: 2px solid #3498db;
551
+ padding-bottom: 10px;
552
+ }
553
+ h2 {
554
+ border-left: 4px solid #3498db;
555
+ padding-left: 15px;
556
+ }
557
+ .chart-container, .image-container {
558
+ margin: 30px 0;
559
+ text-align: center;
560
+ }
561
+ .chart-container canvas, .image-container img {
562
+ max-width: 100%;
563
+ height: auto;
564
+ border: 1px solid #ddd;
565
+ border-radius: 5px;
566
+ }
567
+ p {
568
+ line-height: 1.6;
569
+ text-align: justify;
570
+ }
571
+ ul, ol {
572
+ margin: 20px 0;
573
+ padding-left: 30px;
574
+ }
575
+ li {
576
+ margin: 10px 0;
577
+ }
578
+ strong {
579
+ color: #e74c3c;
580
+ }
581
+ em {
582
+ color: #2ecc71;
583
+ }
468
584
  </style>
469
585
  <script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
470
586
  </head>
471
587
  <body>
472
- <h1>Отчет</h1>
473
- <div class="chart-container">
474
- <!-- Chart.js chart code -->
475
- </div>
476
- <div class="image-container">
477
- <!-- Generated image -->
478
- <img src="https://image.pollinations.ai/prompt/beautiful%20landscape%20with%20mountains" alt="beautiful landscape with mountains">
588
+ <div class="container">
589
+ <h1>Отчет</h1>
590
+ <div class="chart-container">
591
+ <!-- Chart.js chart code -->
592
+ </div>
593
+ <div class="image-container">
594
+ <!-- Generated image -->
595
+ <img src="https://image.pollinations.ai/prompt/beautiful%20landscape%20with%20mountains" alt="beautiful landscape with mountains">
596
+ </div>
597
+ <h2>Анализ данных</h2>
598
+ <p>На основании проведенного анализа можно сделать следующие выводы:</p>
599
+ <ul>
600
+ <li><strong>Основной тренд:</strong> наблюдается положительная динамика роста</li>
601
+ <li><strong>Сезонность:</strong> наиболее высокие показатели наблюдаются во второй половине периода</li>
602
+ <li><strong>Прогноз:</strong> ожидается продолжение роста в ближайшие месяцы</li>
603
+ </ul>
604
+ <h2>Рекомендации</h2>
605
+ <ol>
606
+ <li>Увеличить инвестиции в направления с высокой доходностью</li>
607
+ <li>Оптимизировать расходы в менее эффективных сегментах</li>
608
+ <li>Рассмотреть возможность расширения бизнеса</li>
609
+ </ol>
479
610
  </div>
480
611
  </body>
481
612
  </html>
@@ -487,19 +618,19 @@
487
618
 
488
619
  1. **Ошибка формата параметров**: Передача `elements` как строки вместо объекта
489
620
  - ❌ Неправильно: `"elements": "{\"mychart\":{...}}"`
490
- - ✅ Правильно: `"elements": {"mychart":{...}}`
621
+ - ✅ Правильно: `"elements": {"mychart":{...}}"
491
622
 
492
623
  2. **Ошибка формата цвета**: Передача `borderColor` или `backgroundColor` как строк вместо массивов
493
624
  - ❌ Неправильно: `"borderColor": "red"`
494
- - ✅ Правильно: `"borderColor": ["red"]`
625
+ - ✅ Правильно: `"borderColor": ["red"]"
495
626
 
496
627
  3. **Ошибка формата данных**: Передача числовых данных как отдельных значений вместо массивов
497
- - ❌ Неправильно: `"data": 10`
628
+ - ❌ Неправильно: `"data": 10
498
629
  - ✅ Правильно: `"data": [10]`
499
630
 
500
631
  4. **Ошибка формата меток**: Передача меток как отдельных значений вместо массивов
501
- - ❌ Неправильно: `"labels": "Январь"`
502
- - ✅ Правильно: `"labels": ["Январь"]`
632
+ - ❌ Неправильно: `"labels": "Январь"
633
+ - ✅ Правильно: `"labels": ["Январь"]"
503
634
 
504
635
  ## Дополнительные рекомендации
505
636
 
@@ -509,5 +640,8 @@
509
640
  4. При работе с Claude Desktop используйте параметр `tempDirectory` при генерации отчетов для избежания проблем с правами доступа
510
641
  5. Создавайте отчеты с красивым оформлением, используя заголовки, списки и другие элементы форматирования
511
642
  6. Добавляйте в отчеты диаграммы и изображения для лучшей визуализации данных
643
+ 7. Всегда после генерации отчета возвращайте пользователю ссылку на файл отчета, путь к файлу отчета и содержимое файла
644
+ 8. Отчет должен быть максимально красивым и качественным, содержать изображения, графики, выводы и рассуждения
645
+ 9. Отчет должен быть строго в HTML формате
512
646
 
513
647
  Следование этим инструкциям обеспечит качественное и полное взаимодействие с пользователем при работе с инструментом генерации отчетов.
@@ -30,10 +30,10 @@ export async function renderBarChart(config) {
30
30
  } : undefined
31
31
  }
32
32
  };
33
- // Return interactive Chart.js HTML
33
+ // Return interactive Chart.js HTML with proper container
34
34
  return `
35
- <div>
36
- <canvas id="${chartId}" width="267" height="200"></canvas>
35
+ <div class="chart-container">
36
+ <canvas id="${chartId}" width="400" height="300"></canvas>
37
37
  <script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
38
38
  <script>
39
39
  document.addEventListener('DOMContentLoaded', function() {
@@ -29,10 +29,10 @@ export async function renderDoughnutChart(config) {
29
29
  } : undefined
30
30
  }
31
31
  };
32
- // Return interactive Chart.js HTML
32
+ // Return interactive Chart.js HTML with proper container
33
33
  return `
34
- <div>
35
- <canvas id="${chartId}" width="267" height="200"></canvas>
34
+ <div class="chart-container">
35
+ <canvas id="${chartId}" width="400" height="300"></canvas>
36
36
  <script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
37
37
  <script>
38
38
  document.addEventListener('DOMContentLoaded', function() {
@@ -30,10 +30,10 @@ export async function renderLineChart(config) {
30
30
  } : undefined
31
31
  }
32
32
  };
33
- // Return interactive Chart.js HTML
33
+ // Return interactive Chart.js HTML with proper container
34
34
  return `
35
- <div>
36
- <canvas id="${chartId}" width="267" height="200"></canvas>
35
+ <div class="chart-container">
36
+ <canvas id="${chartId}" width="400" height="300"></canvas>
37
37
  <script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
38
38
  <script>
39
39
  document.addEventListener('DOMContentLoaded', function() {
@@ -29,10 +29,10 @@ export async function renderPieChart(config) {
29
29
  } : undefined
30
30
  }
31
31
  };
32
- // Return interactive Chart.js HTML
32
+ // Return interactive Chart.js HTML with proper container
33
33
  return `
34
- <div>
35
- <canvas id="${chartId}" width="267" height="200"></canvas>
34
+ <div class="chart-container">
35
+ <canvas id="${chartId}" width="400" height="300"></canvas>
36
36
  <script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
37
37
  <script>
38
38
  document.addEventListener('DOMContentLoaded', function() {
@@ -29,10 +29,10 @@ export async function renderPolarAreaChart(config) {
29
29
  } : undefined
30
30
  }
31
31
  };
32
- // Return interactive Chart.js HTML
32
+ // Return interactive Chart.js HTML with proper container
33
33
  return `
34
- <div>
35
- <canvas id="${chartId}" width="267" height="200"></canvas>
34
+ <div class="chart-container">
35
+ <canvas id="${chartId}" width="400" height="300"></canvas>
36
36
  <script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
37
37
  <script>
38
38
  document.addEventListener('DOMContentLoaded', function() {
@@ -30,10 +30,10 @@ export async function renderRadarChart(config) {
30
30
  } : undefined
31
31
  }
32
32
  };
33
- // Return interactive Chart.js HTML
33
+ // Return interactive Chart.js HTML with proper container
34
34
  return `
35
- <div>
36
- <canvas id="${chartId}" width="267" height="200"></canvas>
35
+ <div class="chart-container">
36
+ <canvas id="${chartId}" width="400" height="300"></canvas>
37
37
  <script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
38
38
  <script>
39
39
  document.addEventListener('DOMContentLoaded', function() {
package/dist/index.js CHANGED
@@ -9,6 +9,7 @@ import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
9
9
  import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
10
10
  import { z } from 'zod';
11
11
  import { pathToFileURL } from 'url';
12
+ import { JSDOM } from 'jsdom';
12
13
  // Check if we're running in stdio mode (no command-line arguments)
13
14
  const isStdioMode = process.argv.length === 2;
14
15
  // For CLI and HTTP API modes, check for mandatory REPORTS_DIR environment variable
@@ -102,7 +103,7 @@ if (process.argv.length === 2) {
102
103
  // No command specified, run in stdio mode using MCP SDK
103
104
  const mcpServer = new McpServer({
104
105
  name: "report_gen_mcp",
105
- version: "1.3.2",
106
+ version: "1.3.4",
106
107
  }, {
107
108
  // Disable health check to prevent automatic calls
108
109
  capabilities: {
@@ -322,28 +323,29 @@ ${fileContent}`
322
323
  if (!contentToAdd || !selector || !position) {
323
324
  throw new Error("contentToAdd, selector, and position are required for 'add' operation");
324
325
  }
325
- // Insert content at the specified position relative to the selected element
326
- const addRegex = new RegExp(`(<${selector}[^>]*>)|(<\\/[^>]*${selector}>)`, 'i');
327
- const addMatch = fileContent.match(addRegex);
328
- if (addMatch) {
329
- const matchIndex = addMatch.index;
330
- const matchLength = addMatch[0].length;
326
+ // Use a more robust approach for finding elements with CSS selectors
327
+ const dom = new JSDOM(fileContent);
328
+ const document = dom.window.document;
329
+ // Find the element using querySelector
330
+ const element = document.querySelector(selector);
331
+ if (element) {
332
+ // Insert content at the specified position relative to the selected element
331
333
  switch (position) {
332
334
  case "beforebegin":
333
- fileContent = fileContent.slice(0, matchIndex) + contentToAdd + fileContent.slice(matchIndex);
335
+ element.insertAdjacentHTML('beforebegin', contentToAdd);
334
336
  break;
335
337
  case "afterbegin":
336
- fileContent = fileContent.slice(0, matchIndex + matchLength) + contentToAdd + fileContent.slice(matchIndex + matchLength);
338
+ element.insertAdjacentHTML('afterbegin', contentToAdd);
337
339
  break;
338
340
  case "beforeend":
339
- const closingTagIndex = fileContent.indexOf('</', matchIndex);
340
- fileContent = fileContent.slice(0, closingTagIndex) + contentToAdd + fileContent.slice(closingTagIndex);
341
+ element.insertAdjacentHTML('beforeend', contentToAdd);
341
342
  break;
342
343
  case "afterend":
343
- const endTagIndex = fileContent.indexOf('>', matchIndex) + 1;
344
- fileContent = fileContent.slice(0, endTagIndex) + contentToAdd + fileContent.slice(endTagIndex);
344
+ element.insertAdjacentHTML('afterend', contentToAdd);
345
345
  break;
346
346
  }
347
+ // Serialize the modified DOM back to HTML
348
+ fileContent = dom.serialize();
347
349
  }
348
350
  else {
349
351
  throw new Error(`Element with selector '${selector}' not found`);
@@ -353,17 +355,29 @@ ${fileContent}`
353
355
  if (!selector) {
354
356
  throw new Error("selector is required for 'remove' operation");
355
357
  }
356
- // Remove the element with the specified selector
357
- const removeRegex = new RegExp(`<${selector}[^>]*>[^]*?<\\/[^>]*${selector}[^>]*>|<${selector}[^>]*/?>`, 'gi');
358
- fileContent = fileContent.replace(removeRegex, '');
358
+ // Use a more robust approach for finding and removing elements
359
+ const domRemove = new JSDOM(fileContent);
360
+ const documentRemove = domRemove.window.document;
361
+ // Find and remove all elements matching the selector
362
+ const elementsToRemove = documentRemove.querySelectorAll(selector);
363
+ elementsToRemove.forEach((el) => el.remove());
364
+ // Serialize the modified DOM back to HTML
365
+ fileContent = domRemove.serialize();
359
366
  break;
360
367
  case "replace":
361
368
  if (!selector || !contentToReplace) {
362
369
  throw new Error("selector and contentToReplace are required for 'replace' operation");
363
370
  }
364
- // Replace the element with the specified selector
365
- const replaceRegex = new RegExp(`<${selector}[^>]*>[^]*?<\\/[^>]*${selector}[^>]*>|<${selector}[^>]*/?>`, 'gi');
366
- fileContent = fileContent.replace(replaceRegex, contentToReplace);
371
+ // Use a more robust approach for finding and replacing elements
372
+ const domReplace = new JSDOM(fileContent);
373
+ const documentReplace = domReplace.window.document;
374
+ // Find and replace all elements matching the selector
375
+ const elementsToReplace = documentReplace.querySelectorAll(selector);
376
+ elementsToReplace.forEach((el) => {
377
+ el.outerHTML = contentToReplace;
378
+ });
379
+ // Serialize the modified DOM back to HTML
380
+ fileContent = domReplace.serialize();
367
381
  break;
368
382
  default:
369
383
  throw new Error(`Unsupported operation: ${operation}`);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vint.tri/report_gen_mcp",
3
- "version": "1.3.2",
3
+ "version": "1.3.4",
4
4
  "description": "CLI tool for generating HTML reports with embedded charts",
5
5
  "main": "dist/index.js",
6
6
  "bin": {
@@ -19,6 +19,7 @@
19
19
  "ejs": "^3.1.10",
20
20
  "express": "^4.19.2",
21
21
  "fs-extra": "^11.2.0",
22
+ "jsdom": "^26.1.0",
22
23
  "marked": "^14.1.2",
23
24
  "zod": "^3.23.8"
24
25
  },
@@ -26,6 +27,7 @@
26
27
  "@types/ejs": "^3.1.5",
27
28
  "@types/express": "^4.17.21",
28
29
  "@types/fs-extra": "^11.0.4",
30
+ "@types/jsdom": "^21.1.7",
29
31
  "@types/node": "^22.5.0",
30
32
  "typescript": "^5.5.4"
31
33
  },
@@ -0,0 +1,75 @@
1
+ import { generateReport } from './dist/utils/reportGenerator.js';
2
+
3
+ async function testChartFix() {
4
+ const document = `
5
+ # Тестовый отчет с диаграммами
6
+
7
+ ## Введение
8
+ Этот отчет демонстрирует исправленные диаграммы с адекватными размерами.
9
+
10
+ ## Данные продаж
11
+ [[chart:sales]]
12
+
13
+ ## Распределение по категориям
14
+ [[chart:categories]]
15
+
16
+ ## Динамика роста
17
+ [[chart:growth]]
18
+ `;
19
+
20
+ const elements = {
21
+ sales: {
22
+ type: 'bar',
23
+ config: {
24
+ labels: ['Январь', 'Февраль', 'Март', 'Апрель', 'Май'],
25
+ datasets: [{
26
+ label: 'Продажи (тыс. руб.)',
27
+ data: [120, 190, 150, 180, 220],
28
+ backgroundColor: ['#FF6384', '#36A2EB', '#FFCE56', '#4BC0C0', '#9966FF'],
29
+ borderColor: ['#FF6384', '#36A2EB', '#FFCE56', '#4BC0C0', '#9966FF']
30
+ }],
31
+ options: {
32
+ title: 'Ежемесячные продажи'
33
+ }
34
+ }
35
+ },
36
+ categories: {
37
+ type: 'pie',
38
+ config: {
39
+ labels: ['Электроника', 'Одежда', 'Продукты', 'Мебель', 'Книги'],
40
+ datasets: [{
41
+ data: [30, 25, 20, 15, 10],
42
+ backgroundColor: ['#FF6384', '#36A2EB', '#FFCE56', '#4BC0C0', '#9966FF'],
43
+ borderColor: ['#FF6384', '#36A2EB', '#FFCE56', '#4BC0C0', '#9966FF']
44
+ }],
45
+ options: {
46
+ title: 'Распределение продаж по категориям'
47
+ }
48
+ }
49
+ },
50
+ growth: {
51
+ type: 'line',
52
+ config: {
53
+ labels: ['Январь', 'Февраль', 'Март', 'Апрель', 'Май'],
54
+ datasets: [{
55
+ label: 'Рост продаж (%)',
56
+ data: [5, 10, 15, 12, 18],
57
+ borderColor: ['#36A2EB'],
58
+ fill: false
59
+ }],
60
+ options: {
61
+ title: 'Динамика роста продаж'
62
+ }
63
+ }
64
+ }
65
+ };
66
+
67
+ try {
68
+ const result = await generateReport(document, elements, 'test_chart_fix_report.html');
69
+ console.log('Отчет успешно создан:', result.filePath);
70
+ } catch (error) {
71
+ console.error('Ошибка при создании отчета:', error);
72
+ }
73
+ }
74
+
75
+ testChartFix();
@@ -0,0 +1,32 @@
1
+ import { JSDOM } from 'jsdom';
2
+ import fs from 'fs/promises';
3
+
4
+ // Read the test file
5
+ const fileContent = await fs.readFile('test_tesla_report.html', 'utf8');
6
+
7
+ // Use JSDOM to parse and manipulate the HTML
8
+ const dom = new JSDOM(fileContent);
9
+ const document = dom.window.document;
10
+
11
+ // Test the CSS selector that was failing before
12
+ const element = document.querySelector('h2:nth-of-type(3)');
13
+
14
+ if (element) {
15
+ console.log('✓ Successfully found element with CSS selector "h2:nth-of-type(3)"');
16
+ console.log('Element text:', element.textContent);
17
+
18
+ // Test inserting content before the element
19
+ const contentToAdd = "<h2>Акции Apple</h2><p>Акции Apple (AAPL) в текущем месяце показали умеренный рост, поддерживаемый стабильными финансовыми результатами и планами по расширению продуктовой линейки.</p><ul><li><strong>Цена на начало месяца:</strong> 189.34 $</li><li><strong>Цена на конец месяца:</strong> 195.78 $</li><li><strong>Изменение за месяц:</strong> +3.4%</li></ul><p>Основные факторы роста связаны с успешными продажами iPhone 15 и ожиданием выхода новых продуктов, таких как Vision Pro и обновленные чипы M3.</p>";
20
+
21
+ element.insertAdjacentHTML('beforebegin', contentToAdd);
22
+
23
+ // Serialize the modified DOM back to HTML
24
+ const modifiedContent = dom.serialize();
25
+
26
+ // Write the modified content back to the file
27
+ await fs.writeFile('test_tesla_report.html', modifiedContent, 'utf8');
28
+
29
+ console.log('✓ Successfully modified the file with Apple stock information');
30
+ } else {
31
+ console.log('✗ Failed to find element with CSS selector "h2:nth-of-type(3)"');
32
+ }
@@ -0,0 +1,66 @@
1
+ import { spawn } from 'child_process';
2
+ import fs from 'fs';
3
+
4
+ // Start the report_gen_mcp server in stdio mode
5
+ const child = spawn('node', ['dist/index.js']);
6
+
7
+ let initialized = false;
8
+
9
+ child.stdout.on('data', (data) => {
10
+ console.log('STDOUT:', data.toString());
11
+
12
+ if (!initialized) {
13
+ // Send initialize message
14
+ const initializeMessage = {
15
+ jsonrpc: "2.0",
16
+ id: 1,
17
+ method: "initialize",
18
+ params: {
19
+ protocolVersion: "2024-07-01",
20
+ capabilities: {},
21
+ clientInfo: {
22
+ name: "test-client",
23
+ version: "1.0.0"
24
+ }
25
+ }
26
+ };
27
+
28
+ child.stdin.write(JSON.stringify(initializeMessage) + '\n');
29
+ initialized = true;
30
+ }
31
+ });
32
+
33
+ child.stderr.on('data', (data) => {
34
+ console.error('STDERR:', data.toString());
35
+ });
36
+
37
+ child.on('close', (code) => {
38
+ console.log(`Child process exited with code ${code}`);
39
+ });
40
+
41
+ // Wait a bit for the server to start, then send the edit-report request
42
+ setTimeout(() => {
43
+ const editReportRequest = {
44
+ jsonrpc: "2.0",
45
+ id: 2,
46
+ method: "tools/call",
47
+ params: {
48
+ name: "edit-report",
49
+ arguments: {
50
+ filePath: "test_tesla_report.html",
51
+ operation: "add",
52
+ contentToAdd: "<h2>Акции Apple</h2><p>Акции Apple (AAPL) в текущем месяце показали умеренный рост, поддерживаемый стабильными финансовыми результатами и планами по расширению продуктовой линейки.</p><ul><li><strong>Цена на начало месяца:</strong> 189.34 $</li><li><strong>Цена на конец месяца:</strong> 195.78 $</li><li><strong>Изменение за месяц:</strong> +3.4%</li></ul><p>Основные факторы роста связаны с успешными продажами iPhone 15 и ожиданием выхода новых продуктов, таких как Vision Pro и обновленные чипы M3.</p>",
53
+ selector: "h2:nth-of-type(3)",
54
+ position: "beforebegin"
55
+ }
56
+ }
57
+ };
58
+
59
+ console.log('Sending edit-report request...');
60
+ child.stdin.write(JSON.stringify(editReportRequest) + '\n');
61
+
62
+ // Give some time for the response, then exit
63
+ setTimeout(() => {
64
+ child.kill();
65
+ }, 2000);
66
+ }, 1000);