@vint.tri/report_gen_mcp 1.5.38 → 1.5.40

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.
@@ -8,10 +8,10 @@ export declare const generatedImageSchema: z.ZodObject<{
8
8
  nologo: z.ZodDefault<z.ZodOptional<z.ZodBoolean>>;
9
9
  enhance: z.ZodDefault<z.ZodOptional<z.ZodBoolean>>;
10
10
  }, "strip", z.ZodTypeAny, {
11
+ prompt: string;
11
12
  model: string;
12
13
  width: number;
13
14
  height: number;
14
- prompt: string;
15
15
  nologo: boolean;
16
16
  enhance: boolean;
17
17
  seed?: number | undefined;
@@ -7,18 +7,18 @@ export declare const urlImageSchema: z.ZodObject<{
7
7
  embed: z.ZodDefault<z.ZodOptional<z.ZodBoolean>>;
8
8
  outputPath: z.ZodOptional<z.ZodString>;
9
9
  }, "strip", z.ZodTypeAny, {
10
- url: string;
11
10
  embed: boolean;
11
+ url: string;
12
12
  width?: number | undefined;
13
13
  height?: number | undefined;
14
14
  alt?: string | undefined;
15
15
  outputPath?: string | undefined;
16
16
  }, {
17
17
  url: string;
18
+ embed?: boolean | undefined;
18
19
  width?: number | undefined;
19
20
  height?: number | undefined;
20
21
  alt?: string | undefined;
21
- embed?: boolean | undefined;
22
22
  outputPath?: string | undefined;
23
23
  }>;
24
24
  export declare function renderUrlImage(params: z.infer<typeof urlImageSchema>): Promise<string>;
package/dist/index.js CHANGED
@@ -109,7 +109,7 @@ if (process.argv.length === 2) {
109
109
  // No command specified, run in stdio mode using MCP SDK
110
110
  const mcpServer = new McpServer({
111
111
  name: "report_gen_mcp",
112
- version: "1.5.38"
112
+ version: "1.5.40"
113
113
  }, {
114
114
  // Disable health check to prevent automatic calls
115
115
  capabilities: {
@@ -7,7 +7,7 @@ export declare const createReportFromTextTool: {
7
7
  outputFile: z.ZodOptional<z.ZodString>;
8
8
  };
9
9
  action: (params: any) => Promise<{
10
- success: boolean;
10
+ success: true;
11
11
  filePath: string;
12
12
  }>;
13
13
  };
@@ -1,5 +1,5 @@
1
1
  export declare function generateReport(htmlDocument: string, outputFile: string): Promise<{
2
- success: boolean;
2
+ success: true;
3
3
  filePath: string;
4
4
  }>;
5
5
  //# sourceMappingURL=reportGenerator.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"reportGenerator.d.ts","sourceRoot":"","sources":["../../src/utils/reportGenerator.ts"],"names":[],"mappings":"AAGA,wBAAsB,cAAc,CAClC,YAAY,EAAE,MAAM,EACpB,UAAU,EAAE,MAAM;;;GAwEnB"}
1
+ {"version":3,"file":"reportGenerator.d.ts","sourceRoot":"","sources":["../../src/utils/reportGenerator.ts"],"names":[],"mappings":"AAIA,wBAAsB,cAAc,CAClC,YAAY,EAAE,MAAM,EACpB,UAAU,EAAE,MAAM,GACjB,OAAO,CAAC;IAAE,OAAO,EAAE,IAAI,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAA;CAAE,CAAC,CA+E9C"}
@@ -1,70 +1,71 @@
1
1
  import fs from 'fs-extra';
2
2
  import path from 'path';
3
+ import { JSDOM } from 'jsdom';
3
4
  export async function generateReport(htmlDocument, outputFile) {
4
- let fixedHtml = htmlDocument;
5
- // Add a proper HTML structure if it's missing
6
- if (!fixedHtml.includes('<html')) {
7
- fixedHtml = `
8
- <!DOCTYPE html>
9
- <html lang="ru">
10
- <head>
11
- <meta charset="UTF-8">
12
- <title>Отчет</title>
13
- <style>
14
- body { font-family: Arial, sans-serif; padding: 20px; }
15
- h1, h2 { color: #1a5276; }
16
- .content-container { width: 600px; margin: 30px auto; }
17
- .description { line-height: 1.6; max-width: 800px; margin: 20px auto; }
18
- img { max-width: 100%; height: auto; margin-top: 20px; }
19
- </style>
20
- </head>
21
- <body>
22
- ${fixedHtml}
23
- </body>
24
- </html>
25
- `;
5
+ const dom = new JSDOM(htmlDocument);
6
+ const { document } = dom.window;
7
+ // 1. Ensure a valid HTML structure
8
+ let head = document.querySelector('head');
9
+ if (!head) {
10
+ head = document.createElement('head');
11
+ document.documentElement.prepend(head);
12
+ head.innerHTML = '<meta charset="UTF-8"><title>Report</title>';
13
+ }
14
+ // 2. Inject Chart.js and basic styles if not already present
15
+ if (!head.querySelector('script[src="https://cdn.jsdelivr.net/npm/chart.js"]')) {
16
+ const chartScript = document.createElement('script');
17
+ chartScript.src = 'https://cdn.jsdelivr.net/npm/chart.js';
18
+ head.appendChild(chartScript);
26
19
  }
27
- // Inject Chart.js if it's missing
28
- if (!fixedHtml.includes('<script src="https://cdn.jsdelivr.net/npm/chart.js"></script>')) {
29
- fixedHtml = fixedHtml.replace('</head>', '<script src="https://cdn.jsdelivr.net/npm/chart.js"></script></head>');
20
+ if (!head.querySelector('style')) {
21
+ const style = document.createElement('style');
22
+ style.textContent = `
23
+ body { font-family: Arial, sans-serif; padding: 20px; }
24
+ h1, h2 { color: #1a5276; }
25
+ .chart-container { width: 80%; max-width: 600px; margin: 30px auto; }
26
+ img { max-width: 100%; height: auto; display: block; margin: 20px auto; }
27
+ `;
28
+ head.appendChild(style);
30
29
  }
31
- // Inject the chart rendering script
32
- const chartScript = `
33
- <script>
34
- document.addEventListener('DOMContentLoaded', () => {
35
- // Handle canvas-based charts
36
- const canvasElements = document.querySelectorAll('canvas');
37
- canvasElements.forEach((canvas, index) => {
38
- const chartDataScript = canvas.nextElementSibling;
39
- if (chartDataScript && chartDataScript.tagName === 'SCRIPT') {
40
- try {
41
- // Execute the script to get the chart configuration
42
- const getChartConfig = new Function(chartDataScript.textContent);
43
- const chartConfig = getChartConfig();
44
-
45
- // Ensure the canvas has a unique ID
46
- const canvasId = canvas.id || \`chart-\${index}\`;
47
- canvas.id = canvasId;
48
-
49
- const ctx = canvas.getContext('2d');
50
- new Chart(ctx, chartConfig);
51
- } catch (e) {
52
- console.error('Error rendering chart:', e);
53
- }
54
- }
55
- });
30
+ // 3. Process all canvas elements to render charts
31
+ const canvases = document.querySelectorAll('canvas');
32
+ canvases.forEach((canvas, index) => {
33
+ // Ensure each canvas has a unique ID for the script
34
+ if (!canvas.id) {
35
+ canvas.id = `chart-canvas-${index}`;
36
+ }
37
+ const scriptTag = canvas.nextElementSibling;
38
+ if (scriptTag && scriptTag.tagName === 'SCRIPT') {
39
+ // The chart data is in a script tag right after the canvas.
40
+ // We will move this logic to a single script at the end of the body.
41
+ const chartScriptContent = scriptTag.innerHTML;
42
+ // We'll attach the data to the canvas element itself to be picked up later
43
+ canvas.setAttribute('data-chart-script', chartScriptContent);
44
+ // Remove the original inline script
45
+ scriptTag.remove();
46
+ }
47
+ });
48
+ // 4. Inject a single, robust chart-rendering script at the end of the body
49
+ const finalChartScript = document.createElement('script');
50
+ finalChartScript.textContent = `
51
+ document.addEventListener('DOMContentLoaded', () => {
52
+ document.querySelectorAll('canvas[data-chart-script]').forEach(canvas => {
53
+ try {
54
+ const scriptContent = canvas.getAttribute('data-chart-script');
55
+ // Important: Replace 'var ctx' with 'const ctx' and use the canvas's own ID
56
+ const revisedScript = scriptContent.replace(/var ctx = document.getElementById\\('.+?'\\)/, \`const ctx = document.getElementById('\${canvas.id}')\`);
57
+ new Function(revisedScript)();
58
+ } catch (e) {
59
+ console.error('Failed to render chart for canvas #' + canvas.id, e);
60
+ }
56
61
  });
57
- </script>
62
+ });
58
63
  `;
59
- if (fixedHtml.includes('</body>')) {
60
- fixedHtml = fixedHtml.replace('</body>', chartScript + '</body>');
61
- }
62
- else {
63
- fixedHtml += chartScript;
64
- }
64
+ document.body.appendChild(finalChartScript);
65
+ const finalHtml = dom.serialize();
65
66
  const outputDirPath = path.dirname(outputFile);
66
67
  await fs.ensureDir(outputDirPath);
67
- await fs.writeFile(outputFile, fixedHtml);
68
- console.log(`Report successfully generated at: ${outputFile}`);
68
+ await fs.writeFile(outputFile, finalHtml);
69
+ console.log('Report successfully generated and fixed at: ${outputFile}');
69
70
  return { success: true, filePath: outputFile };
70
71
  }
File without changes
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vint.tri/report_gen_mcp",
3
- "version": "1.5.38",
3
+ "version": "1.5.40",
4
4
  "description": "CLI tool for generating HTML reports with embedded charts and images",
5
5
  "main": "dist/index.js",
6
6
  "bin": {