@vint.tri/report_gen_mcp 1.5.26 → 1.5.28

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.
@@ -0,0 +1,19 @@
1
+ import { z } from 'zod';
2
+ export declare const localImageSchema: z.ZodObject<{
3
+ src: z.ZodString;
4
+ alt: z.ZodOptional<z.ZodString>;
5
+ width: z.ZodOptional<z.ZodNumber>;
6
+ height: z.ZodOptional<z.ZodNumber>;
7
+ }, "strip", z.ZodTypeAny, {
8
+ src: string;
9
+ alt?: string | undefined;
10
+ width?: number | undefined;
11
+ height?: number | undefined;
12
+ }, {
13
+ src: string;
14
+ alt?: string | undefined;
15
+ width?: number | undefined;
16
+ height?: number | undefined;
17
+ }>;
18
+ export declare function renderLocalImage(params: z.infer<typeof localImageSchema>): Promise<string>;
19
+ //# sourceMappingURL=localImages.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"localImages.d.ts","sourceRoot":"","sources":["../../src/images/localImages.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAKxB,eAAO,MAAM,gBAAgB;;;;;;;;;;;;;;;EAK3B,CAAC;AAqBH,wBAAsB,gBAAgB,CAAC,MAAM,EAAE,CAAC,CAAC,KAAK,CAAC,OAAO,gBAAgB,CAAC,GAAG,OAAO,CAAC,MAAM,CAAC,CA0BhG"}
@@ -0,0 +1,52 @@
1
+ import { z } from 'zod';
2
+ import fs from 'fs-extra';
3
+ import path from 'path';
4
+ // Schema for validating local image parameters
5
+ export const localImageSchema = z.object({
6
+ src: z.string().describe("Путь к локальному изображению"),
7
+ alt: z.string().optional().describe("Альтернативный текст для изображения"),
8
+ width: z.number().optional().describe("Ширина изображения в пикселях"),
9
+ height: z.number().optional().describe("Высота изображения в пикселях"),
10
+ });
11
+ // Function to determine MIME type from buffer
12
+ function getMimeTypeFromBuffer(buffer) {
13
+ // Check JPEG
14
+ if (buffer[0] === 0xFF && buffer[1] === 0xD8) {
15
+ return 'image/jpeg';
16
+ }
17
+ // Check PNG
18
+ if (buffer[0] === 0x89 && buffer[1] === 0x50 && buffer[2] === 0x4E && buffer[3] === 0x47) {
19
+ return 'image/png';
20
+ }
21
+ // Check GIF
22
+ if (buffer[0] === 0x47 && buffer[1] === 0x49 && buffer[2] === 0x46) {
23
+ return 'image/gif';
24
+ }
25
+ // Default to JPEG if unknown
26
+ return 'image/jpeg';
27
+ }
28
+ // Function to render local image to HTML
29
+ export async function renderLocalImage(params) {
30
+ const validatedParams = localImageSchema.parse(params);
31
+ const imagePath = path.resolve(process.cwd(), validatedParams.src);
32
+ let imageSrc;
33
+ try {
34
+ const imageBuffer = await fs.readFile(imagePath);
35
+ const mimeType = getMimeTypeFromBuffer(imageBuffer);
36
+ imageSrc = `data:${mimeType};base64,${imageBuffer.toString('base64')}`;
37
+ }
38
+ catch (error) {
39
+ console.error(`Error reading local image file: ${imagePath}`, error);
40
+ // Fallback to original path if reading fails
41
+ imageSrc = validatedParams.src;
42
+ }
43
+ const widthStyle = validatedParams.width ? `width: ${validatedParams.width}px;` : '';
44
+ const heightStyle = validatedParams.height ? `height: ${validatedParams.height}px;` : '';
45
+ const altText = validatedParams.alt || '';
46
+ return `
47
+ <div class="image-container" style="margin: 20px 0; text-align: center;">
48
+ <img src="${imageSrc}" alt="${altText}" style="max-width: 100%; height: auto; border-radius: 8px; box-shadow: 0 4px 8px rgba(0,0,0,0.1); ${widthStyle} ${heightStyle}">
49
+ ${altText ? `<p style="margin-top: 10px; font-size: 14px; color: #666;">${altText}</p>` : ''}
50
+ </div>
51
+ `;
52
+ }
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.26"
112
+ version: "1.5.28"
113
113
  }, {
114
114
  // Disable health check to prevent automatic calls
115
115
  capabilities: {
@@ -1,4 +1,5 @@
1
- export declare function generateReport(document: string, outputFile: string): Promise<{
1
+ export declare function generateReport(markdownDocument: string, // Renamed 'document' to 'markdownDocument' for clarity
2
+ outputFile: string): Promise<{
2
3
  success: boolean;
3
4
  filePath: string;
4
5
  }>;
@@ -1 +1 @@
1
- {"version":3,"file":"reportGenerator.d.ts","sourceRoot":"","sources":["../../src/utils/reportGenerator.ts"],"names":[],"mappings":"AAuHA,wBAAsB,cAAc,CAClC,QAAQ,EAAE,MAAM,EAChB,UAAU,EAAE,MAAM;;;GA4InB"}
1
+ {"version":3,"file":"reportGenerator.d.ts","sourceRoot":"","sources":["../../src/utils/reportGenerator.ts"],"names":[],"mappings":"AAuIA,wBAAsB,cAAc,CAClC,gBAAgB,EAAE,MAAM,EAAE,uDAAuD;AACjF,UAAU,EAAE,MAAM;;;GA4InB"}
@@ -9,6 +9,7 @@ import { doughnutSchema, renderDoughnutChart } from '../charts/doughnut.js';
9
9
  import { radarSchema, renderRadarChart } from '../charts/radar.js';
10
10
  import { polarAreaSchema, renderPolarAreaChart } from '../charts/polarArea.js';
11
11
  import { urlImageSchema, renderUrlImage } from '../images/urlImages.js';
12
+ import { localImageSchema, renderLocalImage } from '../images/localImages.js'; // Added this line
12
13
  async function extractElementsFromMarkdown(markdown) {
13
14
  console.log("Starting extractElementsFromMarkdown...");
14
15
  const elements = {};
@@ -40,13 +41,21 @@ async function extractElementsFromMarkdown(markdown) {
40
41
  const src = imageMatch[1];
41
42
  const alt = imageMatch[2] || '';
42
43
  const id = `image-${elementCount++}`;
43
- elements[id] = { type: 'url', config: { url: src, alt: alt } };
44
- console.log(`Extracted image: ${id}, src: ${src}`);
44
+ // Determine if it's a URL or local image
45
+ const isUrl = src.startsWith('http://') || src.startsWith('https://');
46
+ const imageType = isUrl ? 'url' : 'local';
47
+ if (isUrl) {
48
+ elements[id] = { type: imageType, config: { url: src, alt: alt } };
49
+ }
50
+ else {
51
+ elements[id] = { type: imageType, config: { src: src, alt: alt } };
52
+ }
53
+ console.log(`Extracted image: ${id}, type: ${imageType}, src: ${src}`);
45
54
  // Replace the original img tag with a placeholder
46
55
  markdown = markdown.replace(imageMatch[0], `[[image:${id}]]`);
47
56
  }
48
57
  console.log("Finished extractElementsFromMarkdown. Extracted elements:", Object.keys(elements));
49
- return elements;
58
+ return { updatedMarkdown: markdown, elements: elements };
50
59
  }
51
60
  const chartRenderers = {
52
61
  bar: { schema: barSchema, renderer: renderBarChart },
@@ -58,7 +67,7 @@ const chartRenderers = {
58
67
  };
59
68
  const imageRenderers = {
60
69
  url: { schema: urlImageSchema, renderer: renderUrlImage },
61
- image: { schema: urlImageSchema, renderer: renderUrlImage },
70
+ local: { schema: localImageSchema, renderer: renderLocalImage }, // Added this line
62
71
  };
63
72
  // Utility function to normalize chart configuration data
64
73
  // Converts string values to arrays where the schema expects arrays
@@ -86,10 +95,11 @@ function normalizeChartConfig(config) {
86
95
  }
87
96
  return normalizedConfig;
88
97
  }
89
- export async function generateReport(document, outputFile) {
98
+ export async function generateReport(markdownDocument, // Renamed 'document' to 'markdownDocument' for clarity
99
+ outputFile) {
90
100
  console.log("Starting generateReport...");
91
- const extractedElements = await extractElementsFromMarkdown(document);
92
- const elements = extractedElements; // Use the extracted elements
101
+ // Extract elements and get the updated markdown
102
+ const { updatedMarkdown, elements } = await extractElementsFromMarkdown(markdownDocument); // Modified this line
93
103
  console.log("Elements after extraction:", Object.keys(elements));
94
104
  // Validate elements
95
105
  for (const [id, element] of Object.entries(elements)) {
@@ -140,13 +150,13 @@ export async function generateReport(document, outputFile) {
140
150
  }
141
151
  }
142
152
  // Replace placeholders in Markdown, e.g., [[chart:id]] or [[image:id]]
143
- let mdWithElements = document;
153
+ let mdWithElements = updatedMarkdown; // Corrected this line
144
154
  for (const [id, htmlElement] of Object.entries(renderedElements)) {
145
155
  // Поддерживаем оба формата: [[chart:id]] и [[image:id]] для обратной совместимости
146
156
  mdWithElements = mdWithElements.replace(new RegExp(`\\[\\[(chart|image):${id}\\]\\]`, 'g'), htmlElement);
147
157
  }
148
158
  // Convert Markdown to HTML
149
- const htmlContent = await marked(mdWithElements);
159
+ const htmlContent = await marked(mdWithElements); // Modified this line to use mdWithElements
150
160
  // Wrap in full HTML template with Chart.js library
151
161
  const template = `
152
162
  <!DOCTYPE html>
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vint.tri/report_gen_mcp",
3
- "version": "1.5.26",
3
+ "version": "1.5.28",
4
4
  "description": "CLI tool for generating HTML reports with embedded charts and images",
5
5
  "main": "dist/index.js",
6
6
  "bin": {
@@ -11,6 +11,7 @@
11
11
  "build": "tsc",
12
12
  "start": "node dist/index.js",
13
13
  "test": "echo \"No tests yet\"",
14
+ "generate-test-report": "ts-node src/test_utils/generate_test_report.ts",
14
15
  "install-python-deps": "pip install -r src/python/requirements.txt",
15
16
  "setup-python": "python -m venv venv && source venv/bin/activate && pip install -r src/python/requirements.txt"
16
17
  },
@@ -22,10 +23,11 @@
22
23
  "ejs": "^3.1.10",
23
24
  "express": "^4.19.2",
24
25
  "fs-extra": "^11.2.0",
26
+ "get-port": "^7.1.0",
27
+ "http-server": "^14.1.1",
25
28
  "jsdom": "^26.1.0",
26
29
  "marked": "^14.1.2",
27
- "zod": "^3.23.8",
28
- "get-port": "^7.1.0"
30
+ "zod": "^3.23.8"
29
31
  },
30
32
  "devDependencies": {
31
33
  "@types/ejs": "^3.1.5",
@@ -33,6 +35,7 @@
33
35
  "@types/fs-extra": "^11.0.4",
34
36
  "@types/jsdom": "^21.1.7",
35
37
  "@types/node": "^22.5.0",
38
+ "ts-node": "^10.9.2",
36
39
  "typescript": "^5.5.4"
37
40
  },
38
41
  "license": "MIT",
package/test_report.md ADDED
@@ -0,0 +1,15 @@
1
+ # Sample Report with Local Image and Chart
2
+
3
+ This is a sample report to test the image and chart rendering functionality.
4
+
5
+ ## Local Image Test
6
+
7
+ Here's a local image:
8
+
9
+ <img src="dollar.png" alt="A dollar bill" width="200">
10
+
11
+ ## Bar Chart Test
12
+
13
+ Here's a sample bar chart:
14
+
15
+ <canvas data-chart='{"type":"bar","data":{"labels":["Red","Blue","Yellow","Green","Purple","Orange"],"datasets":[{"label":"# of Votes","data":[12,19,3,5,2,3],"backgroundColor":["rgba(255, 99, 132, 0.2)","rgba(54, 162, 235, 0.2)","rgba(255, 206, 86, 0.2)","rgba(75, 192, 192, 0.2)","rgba(153, 102, 255, 0.2)","rgba(255, 159, 64, 0.2)"],"borderColor":["rgba(255,99,132,1)","rgba(54, 162, 235, 1)","rgba(255, 206, 86, 1)","rgba(75, 192, 192, 1)","rgba(153, 102, 255, 1)","rgba(255, 159, 64, 1)"],"borderWidth":1}]},"options":{"scales":{"y":{"beginAtZero":true}}}}'></canvas>