@tocharianou/mcp-server-kibana 0.6.1

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.
Files changed (48) hide show
  1. package/LICENSE +201 -0
  2. package/README.md +530 -0
  3. package/dist/index.d.ts +4 -0
  4. package/dist/index.js +417 -0
  5. package/dist/index.js.map +1 -0
  6. package/dist/kibana-openapi-source.yaml +52597 -0
  7. package/dist/src/analysis-tools.d.ts +6 -0
  8. package/dist/src/analysis-tools.js +134 -0
  9. package/dist/src/analysis-tools.js.map +1 -0
  10. package/dist/src/base-tools.d.ts +2 -0
  11. package/dist/src/base-tools.js +349 -0
  12. package/dist/src/base-tools.js.map +1 -0
  13. package/dist/src/dependency-analyzer.d.ts +65 -0
  14. package/dist/src/dependency-analyzer.js +233 -0
  15. package/dist/src/dependency-analyzer.js.map +1 -0
  16. package/dist/src/health-analyzer.d.ts +60 -0
  17. package/dist/src/health-analyzer.js +301 -0
  18. package/dist/src/health-analyzer.js.map +1 -0
  19. package/dist/src/kibana-openapi-source.yaml +52597 -0
  20. package/dist/src/openapi-simplifier.d.ts +33 -0
  21. package/dist/src/openapi-simplifier.js +122 -0
  22. package/dist/src/openapi-simplifier.js.map +1 -0
  23. package/dist/src/prompts.d.ts +2 -0
  24. package/dist/src/prompts.js +91 -0
  25. package/dist/src/prompts.js.map +1 -0
  26. package/dist/src/resources.d.ts +2 -0
  27. package/dist/src/resources.js +125 -0
  28. package/dist/src/resources.js.map +1 -0
  29. package/dist/src/types.d.ts +150 -0
  30. package/dist/src/types.js +38 -0
  31. package/dist/src/types.js.map +1 -0
  32. package/dist/src/vl_create_tools.d.ts +5 -0
  33. package/dist/src/vl_create_tools.js +264 -0
  34. package/dist/src/vl_create_tools.js.map +1 -0
  35. package/dist/src/vl_delete_tools.d.ts +5 -0
  36. package/dist/src/vl_delete_tools.js +158 -0
  37. package/dist/src/vl_delete_tools.js.map +1 -0
  38. package/dist/src/vl_get_tools.d.ts +5 -0
  39. package/dist/src/vl_get_tools.js +201 -0
  40. package/dist/src/vl_get_tools.js.map +1 -0
  41. package/dist/src/vl_search_tools.d.ts +9 -0
  42. package/dist/src/vl_search_tools.js +290 -0
  43. package/dist/src/vl_search_tools.js.map +1 -0
  44. package/dist/src/vl_update_tools.d.ts +5 -0
  45. package/dist/src/vl_update_tools.js +372 -0
  46. package/dist/src/vl_update_tools.js.map +1 -0
  47. package/kibana-openapi-source.yaml +52597 -0
  48. package/package.json +95 -0
@@ -0,0 +1,233 @@
1
+ /**
2
+ * Saved Object Dependency Analyzer
3
+ * Analyzes reference relationships between Kibana objects (Dashboard, Visualization, Index Pattern, etc.)
4
+ */
5
+ /**
6
+ * Build dependency tree
7
+ */
8
+ export async function buildDependencyTree(kibanaClient, rootId, rootType, space, maxDepth = 5) {
9
+ const allNodes = new Map();
10
+ const visited = new Set();
11
+ // Recursively traverse dependencies
12
+ async function traverse(id, type, depth) {
13
+ const key = `${type}:${id}`;
14
+ if (visited.has(key) || depth > maxDepth) {
15
+ return allNodes.get(key) || { id, type, referencedBy: [], references: [], depth };
16
+ }
17
+ visited.add(key);
18
+ try {
19
+ // Get object details
20
+ const obj = await kibanaClient.get(`/api/saved_objects/${type}/${id}`, { space });
21
+ const node = {
22
+ id,
23
+ type,
24
+ title: obj.attributes?.title || obj.attributes?.name,
25
+ referencedBy: [],
26
+ references: obj.references || [],
27
+ depth
28
+ };
29
+ allNodes.set(key, node);
30
+ // Recursively process referenced objects
31
+ if (obj.references && obj.references.length > 0) {
32
+ for (const ref of obj.references) {
33
+ const childNode = await traverse(ref.id, ref.type, depth + 1);
34
+ // Record reverse reference
35
+ const childKey = `${ref.type}:${ref.id}`;
36
+ const existingChild = allNodes.get(childKey);
37
+ if (existingChild) {
38
+ existingChild.referencedBy.push({ id, type, name: node.title || id });
39
+ }
40
+ }
41
+ }
42
+ return node;
43
+ }
44
+ catch (error) {
45
+ console.error(`Failed to fetch ${type}:${id}`, error);
46
+ return { id, type, referencedBy: [], references: [], depth };
47
+ }
48
+ }
49
+ const root = await traverse(rootId, rootType, 0);
50
+ // Calculate statistics
51
+ let maxDepthFound = 0;
52
+ const referenceCounts = new Map();
53
+ const orphans = [];
54
+ for (const [key, node] of allNodes.entries()) {
55
+ maxDepthFound = Math.max(maxDepthFound, node.depth);
56
+ const refCount = node.referencedBy.length;
57
+ referenceCounts.set(key, refCount);
58
+ if (refCount === 0 && key !== `${rootType}:${rootId}`) {
59
+ orphans.push({ id: node.id, type: node.type, title: node.title });
60
+ }
61
+ }
62
+ const topReferenced = Array.from(referenceCounts.entries())
63
+ .sort((a, b) => b[1] - a[1])
64
+ .slice(0, 10)
65
+ .map(([key, count]) => {
66
+ const node = allNodes.get(key);
67
+ return { id: node.id, type: node.type, title: node.title, count };
68
+ });
69
+ return {
70
+ root,
71
+ allNodes,
72
+ summary: {
73
+ total_objects: allNodes.size,
74
+ max_depth: maxDepthFound,
75
+ top_referenced: topReferenced,
76
+ orphans: orphans.slice(0, 5)
77
+ }
78
+ };
79
+ }
80
+ /**
81
+ * Analyze impact scope of deleting/modifying an object
82
+ */
83
+ export async function analyzeImpact(kibanaClient, targetId, targetType, space) {
84
+ // Reverse search: find all objects that reference this object
85
+ try {
86
+ const searchResult = await kibanaClient.post('/api/saved_objects/_find', {
87
+ type: ['dashboard', 'visualization', 'lens', 'search', 'map'],
88
+ hasReference: { type: targetType, id: targetId },
89
+ perPage: 100
90
+ }, { space });
91
+ const directDeps = searchResult.saved_objects || [];
92
+ const affectedDashboards = directDeps
93
+ .filter((obj) => obj.type === 'dashboard')
94
+ .map((obj) => ({
95
+ id: obj.id,
96
+ type: obj.type,
97
+ name: obj.attributes?.title || obj.id
98
+ }));
99
+ // Recursively find indirect dependencies (what references the dependent objects)
100
+ let indirectCount = 0;
101
+ for (const dep of directDeps) {
102
+ if (dep.type !== 'dashboard') {
103
+ const secondLevel = await kibanaClient.post('/api/saved_objects/_find', {
104
+ type: ['dashboard'],
105
+ hasReference: { type: dep.type, id: dep.id },
106
+ perPage: 100
107
+ }, { space });
108
+ indirectCount += (secondLevel.saved_objects || []).length;
109
+ }
110
+ }
111
+ // Risk assessment
112
+ let riskLevel = 'Low';
113
+ if (affectedDashboards.length > 10)
114
+ riskLevel = 'Critical';
115
+ else if (affectedDashboards.length > 5)
116
+ riskLevel = 'High';
117
+ else if (affectedDashboards.length > 0)
118
+ riskLevel = 'Medium';
119
+ let recommendation = '';
120
+ if (riskLevel === 'Critical') {
121
+ recommendation = 'âš ī¸ Warning: Object is heavily referenced by Dashboards. Deletion/modification may cause severe impact. Recommend testing in test space first.';
122
+ }
123
+ else if (riskLevel === 'High') {
124
+ recommendation = 'âš ī¸ Notice: Object is used by multiple Dashboards. Recommend notifying relevant users.';
125
+ }
126
+ else if (riskLevel === 'Medium') {
127
+ recommendation = '📌 Note: Object has some dependencies. Confirm if referencing parties need synchronous updates.';
128
+ }
129
+ else {
130
+ recommendation = '✅ Safe: Object is not referenced by other objects, can be safely deleted/modified.';
131
+ }
132
+ // Get target object info
133
+ const targetObj = await kibanaClient.get(`/api/saved_objects/${targetType}/${targetId}`, { space });
134
+ return {
135
+ target: {
136
+ id: targetId,
137
+ type: targetType,
138
+ title: targetObj.attributes?.title || targetObj.attributes?.name
139
+ },
140
+ direct_dependencies: directDeps.length,
141
+ indirect_dependencies: indirectCount,
142
+ affected_dashboards: affectedDashboards,
143
+ risk_level: riskLevel,
144
+ recommendation
145
+ };
146
+ }
147
+ catch (error) {
148
+ throw new Error(`Impact analysis failed: ${error instanceof Error ? error.message : String(error)}`);
149
+ }
150
+ }
151
+ /**
152
+ * Format dependency tree to Markdown
153
+ */
154
+ export function formatDependencyTreeToMarkdown(tree) {
155
+ let md = `# Dependency Analysis\n\n`;
156
+ md += `## 📊 Statistics Summary\n`;
157
+ md += `- Total Objects: ${tree.summary.total_objects}\n`;
158
+ md += `- Max Dependency Depth: ${tree.summary.max_depth}\n`;
159
+ md += `- Orphan Objects: ${tree.summary.orphans.length}\n\n`;
160
+ if (tree.summary.top_referenced.length > 0) {
161
+ md += `## đŸ”Ĩ Most Referenced Objects\n`;
162
+ tree.summary.top_referenced.forEach((item, index) => {
163
+ md += `${index + 1}. **${item.title || item.id}** (${item.type}) - Referenced ${item.count} times\n`;
164
+ });
165
+ md += '\n';
166
+ }
167
+ if (tree.summary.orphans.length > 0) {
168
+ md += `## 🔍 Orphan Objects (Not Referenced)\n`;
169
+ tree.summary.orphans.forEach(item => {
170
+ md += `- ${item.title || item.id} (${item.type})\n`;
171
+ });
172
+ md += '\n';
173
+ }
174
+ // Tree diagram
175
+ md += `## đŸŒŗ Dependency Tree\n`;
176
+ md += formatNodeTree(tree.root, tree.allNodes, '', new Set());
177
+ return md;
178
+ }
179
+ function formatNodeTree(node, allNodes, prefix, visited) {
180
+ const key = `${node.type}:${node.id}`;
181
+ let result = `${prefix}đŸ“Ļ **${node.title || node.id}** (${node.type})\n`;
182
+ if (visited.has(key)) {
183
+ result += `${prefix} â†ģ (Circular Reference)\n`;
184
+ return result;
185
+ }
186
+ visited.add(key);
187
+ if (node.references.length > 0) {
188
+ node.references.forEach((ref, index) => {
189
+ const isLast = index === node.references.length - 1;
190
+ const childKey = `${ref.type}:${ref.id}`;
191
+ const childNode = allNodes.get(childKey);
192
+ if (childNode) {
193
+ const childPrefix = prefix + (isLast ? ' └─ ' : ' ├─ ');
194
+ const nextPrefix = prefix + (isLast ? ' ' : ' │ ');
195
+ result += formatNodeTree(childNode, allNodes, childPrefix, new Set(visited));
196
+ }
197
+ else {
198
+ result += `${prefix}${isLast ? ' └─ ' : ' ├─ '}📄 ${ref.name || ref.id} (${ref.type})\n`;
199
+ }
200
+ });
201
+ }
202
+ return result;
203
+ }
204
+ /**
205
+ * Format impact analysis to Markdown
206
+ */
207
+ export function formatImpactAnalysisToMarkdown(analysis) {
208
+ let md = `# Impact Analysis\n\n`;
209
+ md += `## đŸŽ¯ Target Object\n`;
210
+ md += `- **Name**: ${analysis.target.title || analysis.target.id}\n`;
211
+ md += `- **Type**: ${analysis.target.type}\n`;
212
+ md += `- **ID**: ${analysis.target.id}\n\n`;
213
+ md += `## 📈 Dependency Statistics\n`;
214
+ md += `- Direct Dependencies: ${analysis.direct_dependencies} objects\n`;
215
+ md += `- Indirect Dependencies: ${analysis.indirect_dependencies} objects\n`;
216
+ md += `- Affected Dashboards: ${analysis.affected_dashboards.length}\n\n`;
217
+ const riskEmoji = {
218
+ 'Low': '✅',
219
+ 'Medium': 'âš ī¸',
220
+ 'High': 'đŸ”Ĩ',
221
+ 'Critical': '🚨'
222
+ };
223
+ md += `## ${riskEmoji[analysis.risk_level]} Risk Assessment: ${analysis.risk_level}\n`;
224
+ md += `${analysis.recommendation}\n\n`;
225
+ if (analysis.affected_dashboards.length > 0) {
226
+ md += `## 📊 Affected Dashboard List\n`;
227
+ analysis.affected_dashboards.forEach((dash, index) => {
228
+ md += `${index + 1}. ${dash.name} (ID: ${dash.id})\n`;
229
+ });
230
+ }
231
+ return md;
232
+ }
233
+ //# sourceMappingURL=dependency-analyzer.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dependency-analyzer.js","sourceRoot":"","sources":["../../src/dependency-analyzer.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,60 @@
1
+ /**
2
+ * Dashboard Health Analyzer
3
+ * Detects potential issues in Dashboards (broken references, performance issues, etc.)
4
+ */
5
+ import type { KibanaClient } from "./types";
6
+ export interface HealthIssue {
7
+ severity: 'info' | 'warning' | 'error' | 'critical';
8
+ category: 'broken_reference' | 'performance' | 'configuration' | 'data_quality';
9
+ message: string;
10
+ details?: any;
11
+ suggestion?: string;
12
+ }
13
+ export interface PanelHealth {
14
+ panel_id: string;
15
+ panel_type: string;
16
+ title?: string;
17
+ issues: HealthIssue[];
18
+ status: 'healthy' | 'warning' | 'unhealthy';
19
+ }
20
+ export interface DashboardHealth {
21
+ id: string;
22
+ title: string;
23
+ overall_status: 'healthy' | 'warning' | 'unhealthy';
24
+ overall_score: number;
25
+ panel_count: number;
26
+ panels: PanelHealth[];
27
+ global_issues: HealthIssue[];
28
+ summary: {
29
+ healthy_panels: number;
30
+ warning_panels: number;
31
+ unhealthy_panels: number;
32
+ total_issues: number;
33
+ };
34
+ }
35
+ export interface BatchHealthReport {
36
+ dashboards: DashboardHealth[];
37
+ summary: {
38
+ total_dashboards: number;
39
+ healthy: number;
40
+ warning: number;
41
+ unhealthy: number;
42
+ critical_issues: number;
43
+ };
44
+ }
45
+ /**
46
+ * Analyze health status of a single Dashboard
47
+ */
48
+ export declare function analyzeDashboardHealth(kibanaClient: KibanaClient, dashboardId: string, space?: string, checkESIndices?: boolean): Promise<DashboardHealth>;
49
+ /**
50
+ * Batch analyze health of multiple Dashboards
51
+ */
52
+ export declare function batchAnalyzeDashboards(kibanaClient: KibanaClient, space?: string, maxDashboards?: number): Promise<BatchHealthReport>;
53
+ /**
54
+ * Format health report to Markdown
55
+ */
56
+ export declare function formatHealthReportToMarkdown(health: DashboardHealth): string;
57
+ /**
58
+ * Format batch health report to Markdown
59
+ */
60
+ export declare function formatBatchHealthReportToMarkdown(report: BatchHealthReport): string;
@@ -0,0 +1,301 @@
1
+ /**
2
+ * Dashboard Health Analyzer
3
+ * Detects potential issues in Dashboards (broken references, performance issues, etc.)
4
+ */
5
+ /**
6
+ * Analyze health status of a single Dashboard
7
+ */
8
+ export async function analyzeDashboardHealth(kibanaClient, dashboardId, space, checkESIndices = false) {
9
+ try {
10
+ // Get Dashboard details
11
+ const dashboard = await kibanaClient.get(`/api/saved_objects/dashboard/${dashboardId}`, { space });
12
+ const title = dashboard.attributes?.title || dashboardId;
13
+ const panelsJSON = dashboard.attributes?.panelsJSON;
14
+ if (!panelsJSON) {
15
+ return {
16
+ id: dashboardId,
17
+ title,
18
+ overall_status: 'unhealthy',
19
+ overall_score: 0,
20
+ panel_count: 0,
21
+ panels: [],
22
+ global_issues: [{
23
+ severity: 'error',
24
+ category: 'configuration',
25
+ message: 'Dashboard has no panels configured',
26
+ suggestion: 'Add at least one visualization panel'
27
+ }],
28
+ summary: {
29
+ healthy_panels: 0,
30
+ warning_panels: 0,
31
+ unhealthy_panels: 0,
32
+ total_issues: 1
33
+ }
34
+ };
35
+ }
36
+ const panels = JSON.parse(panelsJSON);
37
+ const references = dashboard.references || [];
38
+ const panelHealths = [];
39
+ const globalIssues = [];
40
+ // Check each Panel
41
+ for (const panel of panels) {
42
+ const panelIssues = [];
43
+ // 1. Check if Panel reference exists
44
+ const panelRefId = panel.panelRefName || panel.id;
45
+ const reference = references.find((ref) => ref.name === panelRefId);
46
+ if (!reference) {
47
+ panelIssues.push({
48
+ severity: 'error',
49
+ category: 'broken_reference',
50
+ message: `Panel missing reference definition`,
51
+ details: { panelId: panel.id },
52
+ suggestion: 'This Panel may have been deleted, recommend removing it from Dashboard'
53
+ });
54
+ }
55
+ else {
56
+ // 2. Check if referenced object exists
57
+ try {
58
+ await kibanaClient.get(`/api/saved_objects/${reference.type}/${reference.id}`, { space });
59
+ }
60
+ catch (error) {
61
+ if (error.response?.status === 404) {
62
+ panelIssues.push({
63
+ severity: 'critical',
64
+ category: 'broken_reference',
65
+ message: `Referenced ${reference.type} object does not exist`,
66
+ details: { referenceId: reference.id, referenceType: reference.type },
67
+ suggestion: `Restore deleted object or remove this Panel from Dashboard`
68
+ });
69
+ }
70
+ }
71
+ }
72
+ // 3. Performance check (Panel size)
73
+ const gridData = panel.gridData || {};
74
+ const panelArea = (gridData.w || 0) * (gridData.h || 0);
75
+ if (panelArea > 48) {
76
+ panelIssues.push({
77
+ severity: 'warning',
78
+ category: 'performance',
79
+ message: 'Panel size too large may affect performance',
80
+ details: { width: gridData.w, height: gridData.h },
81
+ suggestion: 'Consider splitting into multiple smaller Panels'
82
+ });
83
+ }
84
+ // 4. Check Panel type
85
+ const panelType = panel.type;
86
+ if (!panelType) {
87
+ panelIssues.push({
88
+ severity: 'error',
89
+ category: 'configuration',
90
+ message: 'Panel missing type definition',
91
+ suggestion: 'Reconfigure Panel'
92
+ });
93
+ }
94
+ const panelStatus = panelIssues.some(i => i.severity === 'error' || i.severity === 'critical')
95
+ ? 'unhealthy'
96
+ : panelIssues.length > 0
97
+ ? 'warning'
98
+ : 'healthy';
99
+ panelHealths.push({
100
+ panel_id: panel.id,
101
+ panel_type: panelType || 'unknown',
102
+ title: panel.title,
103
+ issues: panelIssues,
104
+ status: panelStatus
105
+ });
106
+ }
107
+ // Global checks
108
+ // 1. Check if Dashboard is too complex
109
+ if (panels.length > 20) {
110
+ globalIssues.push({
111
+ severity: 'warning',
112
+ category: 'performance',
113
+ message: `Dashboard contains ${panels.length} Panels, may cause slow loading`,
114
+ suggestion: 'Consider splitting into multiple themed Dashboards'
115
+ });
116
+ }
117
+ // 2. Check index pattern references
118
+ if (checkESIndices) {
119
+ const indexPatternRefs = references.filter((ref) => ref.type === 'index-pattern');
120
+ for (const indexPatternRef of indexPatternRefs) {
121
+ try {
122
+ const indexPattern = await kibanaClient.get(`/api/saved_objects/index-pattern/${indexPatternRef.id}`, { space });
123
+ // Could further call ES API to check if index exists
124
+ // Skipped for now as it requires ES Client
125
+ }
126
+ catch (error) {
127
+ if (error.response?.status === 404) {
128
+ globalIssues.push({
129
+ severity: 'critical',
130
+ category: 'broken_reference',
131
+ message: `Referenced index pattern does not exist: ${indexPatternRef.id}`,
132
+ suggestion: 'Recreate index pattern or update Dashboard reference'
133
+ });
134
+ }
135
+ }
136
+ }
137
+ }
138
+ // Calculate overall health
139
+ const healthyCount = panelHealths.filter(p => p.status === 'healthy').length;
140
+ const warningCount = panelHealths.filter(p => p.status === 'warning').length;
141
+ const unhealthyCount = panelHealths.filter(p => p.status === 'unhealthy').length;
142
+ const totalIssues = panelHealths.reduce((sum, p) => sum + p.issues.length, 0) + globalIssues.length;
143
+ // Health scoring algorithm
144
+ const healthScore = Math.max(0, Math.min(100, 100 - (unhealthyCount * 20) - (warningCount * 5) - (globalIssues.length * 10)));
145
+ let overallStatus = 'healthy';
146
+ if (unhealthyCount > 0 || globalIssues.some(i => i.severity === 'critical')) {
147
+ overallStatus = 'unhealthy';
148
+ }
149
+ else if (warningCount > 0 || globalIssues.length > 0) {
150
+ overallStatus = 'warning';
151
+ }
152
+ return {
153
+ id: dashboardId,
154
+ title,
155
+ overall_status: overallStatus,
156
+ overall_score: healthScore,
157
+ panel_count: panels.length,
158
+ panels: panelHealths,
159
+ global_issues: globalIssues,
160
+ summary: {
161
+ healthy_panels: healthyCount,
162
+ warning_panels: warningCount,
163
+ unhealthy_panels: unhealthyCount,
164
+ total_issues: totalIssues
165
+ }
166
+ };
167
+ }
168
+ catch (error) {
169
+ throw new Error(`Health analysis failed: ${error instanceof Error ? error.message : String(error)}`);
170
+ }
171
+ }
172
+ /**
173
+ * Batch analyze health of multiple Dashboards
174
+ */
175
+ export async function batchAnalyzeDashboards(kibanaClient, space, maxDashboards = 50) {
176
+ try {
177
+ // Search all Dashboards
178
+ const searchResult = await kibanaClient.post('/api/saved_objects/_find', {
179
+ type: 'dashboard',
180
+ perPage: maxDashboards,
181
+ fields: ['title']
182
+ }, { space });
183
+ const dashboards = searchResult.saved_objects || [];
184
+ const healthReports = [];
185
+ for (const dashboard of dashboards) {
186
+ try {
187
+ const health = await analyzeDashboardHealth(kibanaClient, dashboard.id, space, false);
188
+ healthReports.push(health);
189
+ }
190
+ catch (error) {
191
+ console.error(`Failed to analyze dashboard ${dashboard.id}:`, error);
192
+ // Continue analyzing other Dashboards
193
+ }
194
+ }
195
+ const summary = {
196
+ total_dashboards: healthReports.length,
197
+ healthy: healthReports.filter(h => h.overall_status === 'healthy').length,
198
+ warning: healthReports.filter(h => h.overall_status === 'warning').length,
199
+ unhealthy: healthReports.filter(h => h.overall_status === 'unhealthy').length,
200
+ critical_issues: healthReports.reduce((sum, h) => sum + h.global_issues.filter(i => i.severity === 'critical').length +
201
+ h.panels.reduce((pSum, p) => pSum + p.issues.filter(i => i.severity === 'critical').length, 0), 0)
202
+ };
203
+ return {
204
+ dashboards: healthReports,
205
+ summary
206
+ };
207
+ }
208
+ catch (error) {
209
+ throw new Error(`Batch health analysis failed: ${error instanceof Error ? error.message : String(error)}`);
210
+ }
211
+ }
212
+ /**
213
+ * Format health report to Markdown
214
+ */
215
+ export function formatHealthReportToMarkdown(health) {
216
+ const statusEmoji = {
217
+ 'healthy': '✅',
218
+ 'warning': 'âš ī¸',
219
+ 'unhealthy': '🔴'
220
+ };
221
+ let md = `# Dashboard Health Report\n\n`;
222
+ md += `## ${statusEmoji[health.overall_status]} Overall Status: ${health.overall_status.toUpperCase()}\n`;
223
+ md += `- **Dashboard**: ${health.title}\n`;
224
+ md += `- **Health Score**: ${health.overall_score}/100\n`;
225
+ md += `- **Total Panels**: ${health.panel_count}\n\n`;
226
+ md += `## 📊 Panel Statistics\n`;
227
+ md += `- ✅ Healthy: ${health.summary.healthy_panels}\n`;
228
+ md += `- âš ī¸ Warning: ${health.summary.warning_panels}\n`;
229
+ md += `- 🔴 Unhealthy: ${health.summary.unhealthy_panels}\n`;
230
+ md += `- 🐛 Total Issues: ${health.summary.total_issues}\n\n`;
231
+ if (health.global_issues.length > 0) {
232
+ md += `## 🚨 Global Issues\n`;
233
+ health.global_issues.forEach((issue, index) => {
234
+ const severityEmoji = { info: 'â„šī¸', warning: 'âš ī¸', error: '❌', critical: '🚨' };
235
+ md += `${index + 1}. ${severityEmoji[issue.severity]} **[${issue.severity.toUpperCase()}]** ${issue.message}\n`;
236
+ if (issue.suggestion) {
237
+ md += ` 💡 ${issue.suggestion}\n`;
238
+ }
239
+ });
240
+ md += '\n';
241
+ }
242
+ const unhealthyPanels = health.panels.filter(p => p.status === 'unhealthy');
243
+ if (unhealthyPanels.length > 0) {
244
+ md += `## 🔴 Unhealthy Panel Details\n`;
245
+ unhealthyPanels.forEach(panel => {
246
+ md += `### Panel: ${panel.title || panel.panel_id} (${panel.panel_type})\n`;
247
+ panel.issues.forEach(issue => {
248
+ md += `- ❌ ${issue.message}\n`;
249
+ if (issue.suggestion) {
250
+ md += ` 💡 ${issue.suggestion}\n`;
251
+ }
252
+ });
253
+ md += '\n';
254
+ });
255
+ }
256
+ const warningPanels = health.panels.filter(p => p.status === 'warning');
257
+ if (warningPanels.length > 0) {
258
+ md += `## âš ī¸ Warning Panels (top 5)\n`;
259
+ warningPanels.slice(0, 5).forEach(panel => {
260
+ md += `- **${panel.title || panel.panel_id}**: ${panel.issues[0]?.message}\n`;
261
+ });
262
+ }
263
+ return md;
264
+ }
265
+ /**
266
+ * Format batch health report to Markdown
267
+ */
268
+ export function formatBatchHealthReportToMarkdown(report) {
269
+ let md = `# Dashboard Batch Health Report\n\n`;
270
+ md += `## 📊 Overall Summary\n`;
271
+ md += `- Total Dashboards: ${report.summary.total_dashboards}\n`;
272
+ md += `- ✅ Healthy: ${report.summary.healthy} (${Math.round(report.summary.healthy / report.summary.total_dashboards * 100)}%)\n`;
273
+ md += `- âš ī¸ Warning: ${report.summary.warning} (${Math.round(report.summary.warning / report.summary.total_dashboards * 100)}%)\n`;
274
+ md += `- 🔴 Unhealthy: ${report.summary.unhealthy} (${Math.round(report.summary.unhealthy / report.summary.total_dashboards * 100)}%)\n`;
275
+ md += `- 🚨 Critical Issues: ${report.summary.critical_issues}\n\n`;
276
+ // Sort by health score, show most problematic first
277
+ const sortedDashboards = [...report.dashboards].sort((a, b) => a.overall_score - b.overall_score);
278
+ if (report.summary.unhealthy > 0) {
279
+ md += `## 🔴 Dashboards Requiring Urgent Fix\n`;
280
+ sortedDashboards
281
+ .filter(d => d.overall_status === 'unhealthy')
282
+ .slice(0, 10)
283
+ .forEach((dashboard, index) => {
284
+ md += `${index + 1}. **${dashboard.title}** (Score: ${dashboard.overall_score}/100)\n`;
285
+ md += ` - Unhealthy Panels: ${dashboard.summary.unhealthy_panels}/${dashboard.panel_count}\n`;
286
+ md += ` - Total Issues: ${dashboard.summary.total_issues}\n`;
287
+ });
288
+ md += '\n';
289
+ }
290
+ if (report.summary.warning > 0) {
291
+ md += `## âš ī¸ Dashboards Recommended for Optimization (top 5)\n`;
292
+ sortedDashboards
293
+ .filter(d => d.overall_status === 'warning')
294
+ .slice(0, 5)
295
+ .forEach((dashboard, index) => {
296
+ md += `${index + 1}. **${dashboard.title}** (Score: ${dashboard.overall_score}/100)\n`;
297
+ });
298
+ }
299
+ return md;
300
+ }
301
+ //# sourceMappingURL=health-analyzer.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"health-analyzer.js","sourceRoot":"","sources":["../../src/health-analyzer.ts"],"names":[],"mappings":"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"}