@vibeguardai/mcp-server 0.1.0

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,2 @@
1
+
2
+ export { }
package/dist/index.mjs ADDED
@@ -0,0 +1,647 @@
1
+ #!/usr/bin/env node
2
+
3
+ // src/index.ts
4
+ import { Server } from "@modelcontextprotocol/sdk/server/index.js";
5
+ import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
6
+ import {
7
+ CallToolRequestSchema,
8
+ ListToolsRequestSchema
9
+ } from "@modelcontextprotocol/sdk/types.js";
10
+ import { z } from "zod";
11
+ var API_BASE_URL = process.env.VIBEGUARD_API_URL || "https://vibeguard.app/api";
12
+ var shipCheckSchema = z.object({
13
+ app_name: z.string().describe("The name of the app to scan (as registered in VibeGuard)"),
14
+ branch: z.string().optional().describe("Branch to scan (defaults to main)")
15
+ });
16
+ var fixIssueSchema = z.object({
17
+ issue_id: z.string().describe("The issue ID to fix (from ship_check results)")
18
+ });
19
+ var fixAllSchema = z.object({
20
+ app_name: z.string().describe("The name of the app"),
21
+ severity: z.enum(["critical", "high", "medium", "low"]).optional().describe("Minimum severity to fix (defaults to high)")
22
+ });
23
+ var getScoreSchema = z.object({
24
+ app_name: z.string().describe("The name of the app")
25
+ });
26
+ var appStatusSchema = z.object({
27
+ app_name: z.string().describe("The name of the app to get status for")
28
+ });
29
+ var diagnoseErrorSchema = z.object({
30
+ error_id: z.string().describe("The runtime error ID to diagnose")
31
+ });
32
+ var getErrorsSchema = z.object({
33
+ app_name: z.string().describe("The name of the app"),
34
+ status: z.enum(["new", "seen", "resolved", "ignored"]).optional().describe("Filter by error status (default: all)"),
35
+ limit: z.number().optional().describe("Maximum number of errors to return (default: 10)")
36
+ });
37
+ function getShipVerdict(score) {
38
+ if (score >= 80) return { emoji: "\u2705", label: "Ready to ship" };
39
+ if (score >= 60) return { emoji: "\u26A0\uFE0F", label: "Ship with caution" };
40
+ if (score >= 40) return { emoji: "\u{1F536}", label: "Fix issues first" };
41
+ return { emoji: "\u{1F6D1}", label: "Do not ship" };
42
+ }
43
+ function timeAgo(dateStr) {
44
+ const date = new Date(dateStr);
45
+ const now = /* @__PURE__ */ new Date();
46
+ const diffMs = now.getTime() - date.getTime();
47
+ const diffMins = Math.floor(diffMs / 6e4);
48
+ const diffHours = Math.floor(diffMins / 60);
49
+ const diffDays = Math.floor(diffHours / 24);
50
+ if (diffMins < 1) return "just now";
51
+ if (diffMins < 60) return `${diffMins} minutes ago`;
52
+ if (diffHours < 24) return `${diffHours} hours ago`;
53
+ return `${diffDays} days ago`;
54
+ }
55
+ async function makeApiRequest(endpoint, method, apiKey, body) {
56
+ const response = await fetch(`${API_BASE_URL}${endpoint}`, {
57
+ method,
58
+ headers: {
59
+ "Content-Type": "application/json",
60
+ Authorization: `Bearer ${apiKey}`
61
+ },
62
+ body: body ? JSON.stringify(body) : void 0
63
+ });
64
+ if (!response.ok) {
65
+ const error = await response.json().catch(() => ({ error: "Unknown error" }));
66
+ throw new Error(error.error || `API request failed: ${response.status}`);
67
+ }
68
+ return response.json();
69
+ }
70
+ async function main() {
71
+ const apiKey = process.env.VIBEGUARD_API_KEY;
72
+ if (!apiKey) {
73
+ console.error("Error: VIBEGUARD_API_KEY environment variable is required");
74
+ console.error("Get your API key at https://vibeguard.app/api-keys");
75
+ process.exit(1);
76
+ }
77
+ const server = new Server(
78
+ {
79
+ name: "vibeguard",
80
+ version: "0.1.0"
81
+ },
82
+ {
83
+ capabilities: {
84
+ tools: {}
85
+ }
86
+ }
87
+ );
88
+ server.setRequestHandler(ListToolsRequestSchema, async () => {
89
+ return {
90
+ tools: [
91
+ {
92
+ name: "ship_check",
93
+ description: "Run a full security, performance, and quality scan on your app. Returns a Ship Score (0-100) and lists any issues found with plain-English explanations.",
94
+ inputSchema: {
95
+ type: "object",
96
+ properties: {
97
+ app_name: {
98
+ type: "string",
99
+ description: "Name of the app to scan (as registered in VibeGuard)"
100
+ },
101
+ branch: {
102
+ type: "string",
103
+ description: "Branch to scan (defaults to main)"
104
+ }
105
+ },
106
+ required: ["app_name"]
107
+ }
108
+ },
109
+ {
110
+ name: "fix_issue",
111
+ description: "Generate an AI-powered fix for a specific issue and open a GitHub PR with the fix.",
112
+ inputSchema: {
113
+ type: "object",
114
+ properties: {
115
+ issue_id: {
116
+ type: "string",
117
+ description: "ID of the issue to fix (from ship_check results)"
118
+ }
119
+ },
120
+ required: ["issue_id"]
121
+ }
122
+ },
123
+ {
124
+ name: "fix_all",
125
+ description: "Fix all open issues at or above a severity level. Opens individual PRs for each fix.",
126
+ inputSchema: {
127
+ type: "object",
128
+ properties: {
129
+ app_name: {
130
+ type: "string",
131
+ description: "Name of the app"
132
+ },
133
+ severity: {
134
+ type: "string",
135
+ enum: ["critical", "high", "medium", "low"],
136
+ description: "Minimum severity to fix (default: high)"
137
+ }
138
+ },
139
+ required: ["app_name"]
140
+ }
141
+ },
142
+ {
143
+ name: "get_score",
144
+ description: "Get the current Ship Score for an app without running a new scan.",
145
+ inputSchema: {
146
+ type: "object",
147
+ properties: {
148
+ app_name: {
149
+ type: "string",
150
+ description: "Name of the app"
151
+ }
152
+ },
153
+ required: ["app_name"]
154
+ }
155
+ },
156
+ // Phase 2: Runtime monitoring tools
157
+ {
158
+ name: "app_status",
159
+ description: "Get real-time health status for an app including uptime percentage, Web Vitals, and runtime errors summary.",
160
+ inputSchema: {
161
+ type: "object",
162
+ properties: {
163
+ app_name: {
164
+ type: "string",
165
+ description: "Name of the app"
166
+ }
167
+ },
168
+ required: ["app_name"]
169
+ }
170
+ },
171
+ {
172
+ name: "diagnose_error",
173
+ description: "Get AI-powered diagnosis for a runtime error. Returns root cause analysis and suggested fix.",
174
+ inputSchema: {
175
+ type: "object",
176
+ properties: {
177
+ error_id: {
178
+ type: "string",
179
+ description: "The runtime error ID to diagnose"
180
+ }
181
+ },
182
+ required: ["error_id"]
183
+ }
184
+ },
185
+ {
186
+ name: "get_errors",
187
+ description: "List runtime errors for an app. Can filter by status (new, seen, resolved, ignored).",
188
+ inputSchema: {
189
+ type: "object",
190
+ properties: {
191
+ app_name: {
192
+ type: "string",
193
+ description: "Name of the app"
194
+ },
195
+ status: {
196
+ type: "string",
197
+ enum: ["new", "seen", "resolved", "ignored"],
198
+ description: "Filter by error status (default: all)"
199
+ },
200
+ limit: {
201
+ type: "number",
202
+ description: "Maximum number of errors to return (default: 10)"
203
+ }
204
+ },
205
+ required: ["app_name"]
206
+ }
207
+ }
208
+ ]
209
+ };
210
+ });
211
+ server.setRequestHandler(CallToolRequestSchema, async (request) => {
212
+ const { name, arguments: args } = request.params;
213
+ try {
214
+ switch (name) {
215
+ case "ship_check": {
216
+ const parsed = shipCheckSchema.parse(args);
217
+ const appsResponse = await makeApiRequest(`/apps?name=${encodeURIComponent(parsed.app_name)}`, "GET", apiKey);
218
+ const apps = appsResponse.apps || [];
219
+ const app = apps.find((a) => a.name.toLowerCase() === parsed.app_name.toLowerCase());
220
+ if (!app) {
221
+ return {
222
+ content: [
223
+ {
224
+ type: "text",
225
+ text: `App "${parsed.app_name}" not found. Connect it at https://vibeguard.app`
226
+ }
227
+ ]
228
+ };
229
+ }
230
+ const scanResponse = await makeApiRequest("/scans", "POST", apiKey, {
231
+ appId: app.id,
232
+ branch: parsed.branch
233
+ });
234
+ const scan = scanResponse.scan;
235
+ if (!scan) {
236
+ throw new Error("Failed to create scan");
237
+ }
238
+ const maxWait = 12e4;
239
+ const pollInterval = 5e3;
240
+ const startTime = Date.now();
241
+ while (Date.now() - startTime < maxWait) {
242
+ const statusResponse = await makeApiRequest(`/scans/${scan.id}`, "GET", apiKey);
243
+ const updatedScan = statusResponse.scan;
244
+ if (!updatedScan) {
245
+ throw new Error("Failed to get scan status");
246
+ }
247
+ if (updatedScan.status === "completed") {
248
+ const verdict = getShipVerdict(updatedScan.score || 0);
249
+ const issues = updatedScan.issues || [];
250
+ const criticalHighIssues = issues.filter(
251
+ (i) => ["critical", "high"].includes(i.severity)
252
+ );
253
+ let response = `${verdict.emoji} **Ship Score: ${updatedScan.score}/100** \u2014 ${verdict.label}
254
+
255
+ `;
256
+ response += `${updatedScan.summary || ""}
257
+
258
+ `;
259
+ if (criticalHighIssues.length > 0) {
260
+ response += `### Issues Found
261
+ `;
262
+ for (const issue of criticalHighIssues.slice(0, 10)) {
263
+ response += `- **${issue.severity.toUpperCase()}**: ${issue.title}
264
+ `;
265
+ if (issue.description) {
266
+ response += ` ${issue.description}
267
+ `;
268
+ }
269
+ if (issue.fix_available) {
270
+ response += ` \u2192 Fix available (use \`fix_issue\` tool with id: ${issue.id})
271
+ `;
272
+ }
273
+ }
274
+ if (criticalHighIssues.length > 10) {
275
+ response += `
276
+ ...and ${criticalHighIssues.length - 10} more issues.
277
+ `;
278
+ }
279
+ } else {
280
+ response += `No critical or high severity issues found!
281
+ `;
282
+ }
283
+ response += `
284
+ **Scan ID:** ${updatedScan.id}`;
285
+ return {
286
+ content: [{ type: "text", text: response }]
287
+ };
288
+ }
289
+ if (updatedScan.status === "failed") {
290
+ throw new Error(updatedScan.error || "Scan failed");
291
+ }
292
+ await new Promise((resolve) => setTimeout(resolve, pollInterval));
293
+ }
294
+ throw new Error("Scan timed out");
295
+ }
296
+ case "fix_issue": {
297
+ const parsed = fixIssueSchema.parse(args);
298
+ const result = await makeApiRequest("/fixes", "POST", apiKey, {
299
+ issueId: parsed.issue_id
300
+ });
301
+ if (!result.prUrl) {
302
+ throw new Error("Failed to create fix PR");
303
+ }
304
+ return {
305
+ content: [
306
+ {
307
+ type: "text",
308
+ text: `\u2705 Fix applied! PR opened: ${result.prUrl}
309
+
310
+ Review and merge the PR when ready.`
311
+ }
312
+ ]
313
+ };
314
+ }
315
+ case "fix_all": {
316
+ const parsed = fixAllSchema.parse(args);
317
+ const minSeverity = parsed.severity || "high";
318
+ const appsResponse = await makeApiRequest(`/apps?name=${encodeURIComponent(parsed.app_name)}`, "GET", apiKey);
319
+ const apps = appsResponse.apps || [];
320
+ const app = apps.find((a) => a.name.toLowerCase() === parsed.app_name.toLowerCase());
321
+ if (!app) {
322
+ return {
323
+ content: [
324
+ {
325
+ type: "text",
326
+ text: `App "${parsed.app_name}" not found.`
327
+ }
328
+ ]
329
+ };
330
+ }
331
+ const issuesResponse = await makeApiRequest(
332
+ `/apps/${app.id}/issues?status=open&min_severity=${minSeverity}`,
333
+ "GET",
334
+ apiKey
335
+ );
336
+ const issues = issuesResponse.issues || [];
337
+ if (issues.length === 0) {
338
+ return {
339
+ content: [
340
+ {
341
+ type: "text",
342
+ text: `No open ${minSeverity}+ issues found. Your app looks good! \u{1F389}`
343
+ }
344
+ ]
345
+ };
346
+ }
347
+ const fixResults = [];
348
+ const errors = [];
349
+ for (const issue of issues) {
350
+ try {
351
+ const fixResult = await makeApiRequest("/fixes", "POST", apiKey, {
352
+ issueId: issue.id
353
+ });
354
+ if (fixResult.prUrl) {
355
+ fixResults.push({ title: issue.title, prUrl: fixResult.prUrl });
356
+ }
357
+ } catch (error) {
358
+ errors.push(`Failed to fix "${issue.title}": ${error instanceof Error ? error.message : "Unknown error"}`);
359
+ }
360
+ }
361
+ let response = `\u2705 Fixed ${fixResults.length} issues:
362
+
363
+ `;
364
+ for (const fix of fixResults) {
365
+ response += `- ${fix.title} \u2192 [PR](${fix.prUrl})
366
+ `;
367
+ }
368
+ if (errors.length > 0) {
369
+ response += `
370
+ \u26A0\uFE0F ${errors.length} issues could not be fixed:
371
+ `;
372
+ for (const err of errors) {
373
+ response += `- ${err}
374
+ `;
375
+ }
376
+ }
377
+ response += `
378
+ Review and merge the PRs when ready.`;
379
+ return {
380
+ content: [{ type: "text", text: response }]
381
+ };
382
+ }
383
+ case "get_score": {
384
+ const parsed = getScoreSchema.parse(args);
385
+ const appsResponse = await makeApiRequest(`/apps?name=${encodeURIComponent(parsed.app_name)}`, "GET", apiKey);
386
+ const apps = appsResponse.apps || [];
387
+ const app = apps.find((a) => a.name.toLowerCase() === parsed.app_name.toLowerCase());
388
+ if (!app) {
389
+ return {
390
+ content: [
391
+ {
392
+ type: "text",
393
+ text: `App "${parsed.app_name}" not found.`
394
+ }
395
+ ]
396
+ };
397
+ }
398
+ if (!app.latest_score) {
399
+ return {
400
+ content: [
401
+ {
402
+ type: "text",
403
+ text: `No scan results yet for **${app.name}**. Run \`ship_check\` first.`
404
+ }
405
+ ]
406
+ };
407
+ }
408
+ const verdict = getShipVerdict(app.latest_score);
409
+ const lastScanned = app.last_scan_at ? timeAgo(app.last_scan_at) : "unknown";
410
+ return {
411
+ content: [
412
+ {
413
+ type: "text",
414
+ text: `${verdict.emoji} **${app.name}** Ship Score: **${app.latest_score}/100** \u2014 ${verdict.label}
415
+ Last scanned: ${lastScanned}`
416
+ }
417
+ ]
418
+ };
419
+ }
420
+ // Phase 2: Runtime monitoring tools
421
+ case "app_status": {
422
+ const parsed = appStatusSchema.parse(args);
423
+ const appsResponse = await makeApiRequest(`/apps?name=${encodeURIComponent(parsed.app_name)}`, "GET", apiKey);
424
+ const apps = appsResponse.apps || [];
425
+ const app = apps.find((a) => a.name.toLowerCase() === parsed.app_name.toLowerCase());
426
+ if (!app) {
427
+ return {
428
+ content: [
429
+ {
430
+ type: "text",
431
+ text: `App "${parsed.app_name}" not found.`
432
+ }
433
+ ]
434
+ };
435
+ }
436
+ const uptimeResponse = await fetch(`${API_BASE_URL}/apps/${app.id}/uptime?period=24h`, {
437
+ headers: { Authorization: `Bearer ${apiKey}` }
438
+ });
439
+ const uptimeData = uptimeResponse.ok ? await uptimeResponse.json() : null;
440
+ const perfResponse = await fetch(`${API_BASE_URL}/apps/${app.id}/performance?period=24h`, {
441
+ headers: { Authorization: `Bearer ${apiKey}` }
442
+ });
443
+ const perfData = perfResponse.ok ? await perfResponse.json() : null;
444
+ const errorsResponse = await fetch(`${API_BASE_URL}/apps/${app.id}/errors?limit=1`, {
445
+ headers: { Authorization: `Bearer ${apiKey}` }
446
+ });
447
+ const errorsData = errorsResponse.ok ? await errorsResponse.json() : null;
448
+ let response = `## ${app.name} Status
449
+
450
+ `;
451
+ const healthEmoji = {
452
+ healthy: "\u{1F7E2}",
453
+ degraded: "\u{1F7E1}",
454
+ down: "\u{1F534}",
455
+ unknown: "\u26AA"
456
+ }[app.health_status || "unknown"] || "\u26AA";
457
+ response += `**Health:** ${healthEmoji} ${app.health_status || "unknown"}
458
+ `;
459
+ if (app.deployed_url) {
460
+ response += `**URL:** ${app.deployed_url}
461
+ `;
462
+ }
463
+ if (uptimeData?.stats) {
464
+ response += `
465
+ ### Uptime (24h)
466
+ `;
467
+ response += `- **Uptime:** ${uptimeData.stats.uptimePercentage.toFixed(2)}%
468
+ `;
469
+ if (uptimeData.stats.avgResponseTime) {
470
+ response += `- **Avg Response Time:** ${Math.round(uptimeData.stats.avgResponseTime)}ms
471
+ `;
472
+ }
473
+ }
474
+ if (perfData?.coreWebVitals) {
475
+ response += `
476
+ ### Core Web Vitals (24h)
477
+ `;
478
+ const cwv = perfData.coreWebVitals;
479
+ if (cwv.lcp.p75 !== null) {
480
+ const lcpEmoji = cwv.lcp.rating === "good" ? "\u{1F7E2}" : cwv.lcp.rating === "needs-improvement" ? "\u{1F7E1}" : "\u{1F534}";
481
+ response += `- **LCP:** ${lcpEmoji} ${cwv.lcp.p75}ms
482
+ `;
483
+ }
484
+ if (cwv.inp.p75 !== null) {
485
+ const inpEmoji = cwv.inp.rating === "good" ? "\u{1F7E2}" : cwv.inp.rating === "needs-improvement" ? "\u{1F7E1}" : "\u{1F534}";
486
+ response += `- **INP:** ${inpEmoji} ${cwv.inp.p75}ms
487
+ `;
488
+ }
489
+ if (cwv.cls.p75 !== null) {
490
+ const clsEmoji = cwv.cls.rating === "good" ? "\u{1F7E2}" : cwv.cls.rating === "needs-improvement" ? "\u{1F7E1}" : "\u{1F534}";
491
+ response += `- **CLS:** ${clsEmoji} ${cwv.cls.p75}
492
+ `;
493
+ }
494
+ }
495
+ if (errorsData?.stats) {
496
+ response += `
497
+ ### Runtime Errors
498
+ `;
499
+ response += `- **New:** ${errorsData.stats.new}
500
+ `;
501
+ response += `- **Seen:** ${errorsData.stats.seen}
502
+ `;
503
+ response += `- **Resolved:** ${errorsData.stats.resolved}
504
+ `;
505
+ response += `- **Total:** ${errorsData.stats.total}
506
+ `;
507
+ if (errorsData.stats.new > 0) {
508
+ response += `
509
+ Use \`get_errors\` to see error details.`;
510
+ }
511
+ }
512
+ return {
513
+ content: [{ type: "text", text: response }]
514
+ };
515
+ }
516
+ case "diagnose_error": {
517
+ const parsed = diagnoseErrorSchema.parse(args);
518
+ const response = await fetch(`${API_BASE_URL}/errors/${parsed.error_id}/diagnose`, {
519
+ method: "POST",
520
+ headers: {
521
+ "Content-Type": "application/json",
522
+ Authorization: `Bearer ${apiKey}`
523
+ }
524
+ });
525
+ if (!response.ok) {
526
+ const error = await response.json().catch(() => ({ error: "Unknown error" }));
527
+ throw new Error(error.error || `Diagnosis failed: ${response.status}`);
528
+ }
529
+ const data = await response.json();
530
+ if (!data.diagnosis) {
531
+ throw new Error("No diagnosis returned");
532
+ }
533
+ let result = `## Error Diagnosis
534
+
535
+ ${data.diagnosis}`;
536
+ if (data.suggestedFix) {
537
+ result += `
538
+
539
+ ---
540
+ **Suggested Fix:**
541
+ ${data.suggestedFix}`;
542
+ }
543
+ return {
544
+ content: [{ type: "text", text: result }]
545
+ };
546
+ }
547
+ case "get_errors": {
548
+ const parsed = getErrorsSchema.parse(args);
549
+ const limit = parsed.limit || 10;
550
+ const appsResponse = await makeApiRequest(`/apps?name=${encodeURIComponent(parsed.app_name)}`, "GET", apiKey);
551
+ const apps = appsResponse.apps || [];
552
+ const app = apps.find((a) => a.name.toLowerCase() === parsed.app_name.toLowerCase());
553
+ if (!app) {
554
+ return {
555
+ content: [
556
+ {
557
+ type: "text",
558
+ text: `App "${parsed.app_name}" not found.`
559
+ }
560
+ ]
561
+ };
562
+ }
563
+ const params = new URLSearchParams();
564
+ params.set("limit", limit.toString());
565
+ if (parsed.status) {
566
+ params.set("status", parsed.status);
567
+ }
568
+ const errorsResponse = await fetch(`${API_BASE_URL}/apps/${app.id}/errors?${params}`, {
569
+ headers: { Authorization: `Bearer ${apiKey}` }
570
+ });
571
+ if (!errorsResponse.ok) {
572
+ throw new Error("Failed to fetch errors");
573
+ }
574
+ const data = await errorsResponse.json();
575
+ if (data.errors.length === 0) {
576
+ return {
577
+ content: [
578
+ {
579
+ type: "text",
580
+ text: `No ${parsed.status ? parsed.status + " " : ""}errors found for **${app.name}**. \u{1F389}`
581
+ }
582
+ ]
583
+ };
584
+ }
585
+ let response = `## Runtime Errors for ${app.name}
586
+
587
+ `;
588
+ response += `Showing ${data.errors.length} of ${data.stats.total} total errors
589
+
590
+ `;
591
+ for (const error of data.errors) {
592
+ const statusEmoji = {
593
+ new: "\u{1F534}",
594
+ seen: "\u{1F7E1}",
595
+ resolved: "\u2705",
596
+ ignored: "\u26AA"
597
+ }[error.status] || "\u26AA";
598
+ response += `### ${statusEmoji} ${error.message.slice(0, 60)}${error.message.length > 60 ? "..." : ""}
599
+ `;
600
+ response += `- **ID:** \`${error.id}\`
601
+ `;
602
+ response += `- **Occurrences:** ${error.occurrenceCount}
603
+ `;
604
+ response += `- **First seen:** ${timeAgo(error.firstSeenAt)}
605
+ `;
606
+ response += `- **Last seen:** ${timeAgo(error.lastSeenAt)}
607
+ `;
608
+ if (error.sourceFile) {
609
+ response += `- **Location:** ${error.sourceFile}${error.sourceLine ? `:${error.sourceLine}` : ""}
610
+ `;
611
+ }
612
+ if (error.diagnosisPlain) {
613
+ response += `- **Diagnosed:** \u2705
614
+ `;
615
+ } else {
616
+ response += `- Use \`diagnose_error\` with id \`${error.id}\` for AI analysis
617
+ `;
618
+ }
619
+ response += "\n";
620
+ }
621
+ return {
622
+ content: [{ type: "text", text: response }]
623
+ };
624
+ }
625
+ default:
626
+ throw new Error(`Unknown tool: ${name}`);
627
+ }
628
+ } catch (error) {
629
+ return {
630
+ content: [
631
+ {
632
+ type: "text",
633
+ text: `Error: ${error instanceof Error ? error.message : "Unknown error"}`
634
+ }
635
+ ],
636
+ isError: true
637
+ };
638
+ }
639
+ });
640
+ const transport = new StdioServerTransport();
641
+ await server.connect(transport);
642
+ }
643
+ main().catch((error) => {
644
+ console.error("Fatal error:", error);
645
+ process.exit(1);
646
+ });
647
+ //# sourceMappingURL=index.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/index.ts"],"sourcesContent":["import { Server } from '@modelcontextprotocol/sdk/server/index.js'\nimport { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js'\nimport {\n CallToolRequestSchema,\n ListToolsRequestSchema,\n} from '@modelcontextprotocol/sdk/types.js'\nimport { z } from 'zod'\n\nconst API_BASE_URL = process.env.VIBEGUARD_API_URL || 'https://vibeguard.app/api'\n\n// Tool schemas - aligned with architecture spec\nconst shipCheckSchema = z.object({\n app_name: z.string().describe('The name of the app to scan (as registered in VibeGuard)'),\n branch: z.string().optional().describe('Branch to scan (defaults to main)'),\n})\n\nconst fixIssueSchema = z.object({\n issue_id: z.string().describe('The issue ID to fix (from ship_check results)'),\n})\n\nconst fixAllSchema = z.object({\n app_name: z.string().describe('The name of the app'),\n severity: z\n .enum(['critical', 'high', 'medium', 'low'])\n .optional()\n .describe('Minimum severity to fix (defaults to high)'),\n})\n\nconst getScoreSchema = z.object({\n app_name: z.string().describe('The name of the app'),\n})\n\n// Phase 2: Runtime monitoring tools\nconst appStatusSchema = z.object({\n app_name: z.string().describe('The name of the app to get status for'),\n})\n\nconst diagnoseErrorSchema = z.object({\n error_id: z.string().describe('The runtime error ID to diagnose'),\n})\n\nconst getErrorsSchema = z.object({\n app_name: z.string().describe('The name of the app'),\n status: z\n .enum(['new', 'seen', 'resolved', 'ignored'])\n .optional()\n .describe('Filter by error status (default: all)'),\n limit: z.number().optional().describe('Maximum number of errors to return (default: 10)'),\n})\n\ninterface Scan {\n id: string\n status: string\n score?: number\n verdict?: string\n summary?: string\n issues?: Array<{\n id: string\n title: string\n severity: string\n description?: string\n file?: string\n line?: number\n fix_available?: boolean\n }>\n score_breakdown?: Record<string, number>\n error?: string\n}\n\ninterface App {\n id: string\n name: string\n latest_score?: number\n latest_scan_id?: string\n last_scan_at?: string\n health_status?: string\n deployed_url?: string\n monitoring_enabled?: boolean\n}\n\ninterface UptimeStats {\n period: string\n totalChecks: number\n uptimePercentage: number\n avgResponseTime: number | null\n}\n\ninterface WebVitalsMetric {\n p75: number | null\n rating: string | null\n sampleCount: number\n}\n\ninterface AppStatusResponse {\n app: App\n stats: UptimeStats\n coreWebVitals?: {\n lcp: WebVitalsMetric\n inp: WebVitalsMetric\n cls: WebVitalsMetric\n }\n errorStats?: {\n new: number\n seen: number\n resolved: number\n ignored: number\n total: number\n }\n}\n\ninterface RuntimeError {\n id: string\n fingerprint: string\n message: string\n occurrenceCount: number\n firstSeenAt: string\n lastSeenAt: string\n status: string\n sourceFile?: string\n sourceLine?: number\n diagnosisPlain?: string\n}\n\ninterface ErrorsResponse {\n errors: RuntimeError[]\n pagination: {\n page: number\n limit: number\n total: number\n totalPages: number\n }\n stats: {\n new: number\n seen: number\n resolved: number\n ignored: number\n total: number\n }\n}\n\ninterface DiagnoseResponse {\n success: boolean\n diagnosis: string\n suggestedFix?: string\n}\n\ninterface ApiResponse {\n scan?: Scan\n scans?: Scan[]\n app?: App\n apps?: App[]\n issues?: Array<{\n id: string\n title: string\n severity: string\n description?: string\n status: string\n }>\n prUrl?: string\n error?: string\n}\n\n// Get ship verdict with emoji\nfunction getShipVerdict(score: number): { emoji: string; label: string } {\n if (score >= 80) return { emoji: 'āœ…', label: 'Ready to ship' }\n if (score >= 60) return { emoji: 'āš ļø', label: 'Ship with caution' }\n if (score >= 40) return { emoji: 'šŸ”¶', label: 'Fix issues first' }\n return { emoji: 'šŸ›‘', label: 'Do not ship' }\n}\n\n// Format time ago\nfunction timeAgo(dateStr: string): string {\n const date = new Date(dateStr)\n const now = new Date()\n const diffMs = now.getTime() - date.getTime()\n const diffMins = Math.floor(diffMs / 60000)\n const diffHours = Math.floor(diffMins / 60)\n const diffDays = Math.floor(diffHours / 24)\n\n if (diffMins < 1) return 'just now'\n if (diffMins < 60) return `${diffMins} minutes ago`\n if (diffHours < 24) return `${diffHours} hours ago`\n return `${diffDays} days ago`\n}\n\nasync function makeApiRequest(\n endpoint: string,\n method: string,\n apiKey: string,\n body?: Record<string, unknown>\n): Promise<ApiResponse> {\n const response = await fetch(`${API_BASE_URL}${endpoint}`, {\n method,\n headers: {\n 'Content-Type': 'application/json',\n Authorization: `Bearer ${apiKey}`,\n },\n body: body ? JSON.stringify(body) : undefined,\n })\n\n if (!response.ok) {\n const error = (await response.json().catch(() => ({ error: 'Unknown error' }))) as { error?: string }\n throw new Error(error.error || `API request failed: ${response.status}`)\n }\n\n return response.json() as Promise<ApiResponse>\n}\n\nasync function main() {\n const apiKey = process.env.VIBEGUARD_API_KEY\n\n if (!apiKey) {\n console.error('Error: VIBEGUARD_API_KEY environment variable is required')\n console.error('Get your API key at https://vibeguard.app/api-keys')\n process.exit(1)\n }\n\n const server = new Server(\n {\n name: 'vibeguard',\n version: '0.1.0',\n },\n {\n capabilities: {\n tools: {},\n },\n }\n )\n\n // List available tools\n server.setRequestHandler(ListToolsRequestSchema, async () => {\n return {\n tools: [\n {\n name: 'ship_check',\n description:\n 'Run a full security, performance, and quality scan on your app. Returns a Ship Score (0-100) and lists any issues found with plain-English explanations.',\n inputSchema: {\n type: 'object',\n properties: {\n app_name: {\n type: 'string',\n description: 'Name of the app to scan (as registered in VibeGuard)',\n },\n branch: {\n type: 'string',\n description: 'Branch to scan (defaults to main)',\n },\n },\n required: ['app_name'],\n },\n },\n {\n name: 'fix_issue',\n description:\n 'Generate an AI-powered fix for a specific issue and open a GitHub PR with the fix.',\n inputSchema: {\n type: 'object',\n properties: {\n issue_id: {\n type: 'string',\n description: 'ID of the issue to fix (from ship_check results)',\n },\n },\n required: ['issue_id'],\n },\n },\n {\n name: 'fix_all',\n description:\n 'Fix all open issues at or above a severity level. Opens individual PRs for each fix.',\n inputSchema: {\n type: 'object',\n properties: {\n app_name: {\n type: 'string',\n description: 'Name of the app',\n },\n severity: {\n type: 'string',\n enum: ['critical', 'high', 'medium', 'low'],\n description: 'Minimum severity to fix (default: high)',\n },\n },\n required: ['app_name'],\n },\n },\n {\n name: 'get_score',\n description: 'Get the current Ship Score for an app without running a new scan.',\n inputSchema: {\n type: 'object',\n properties: {\n app_name: {\n type: 'string',\n description: 'Name of the app',\n },\n },\n required: ['app_name'],\n },\n },\n // Phase 2: Runtime monitoring tools\n {\n name: 'app_status',\n description:\n 'Get real-time health status for an app including uptime percentage, Web Vitals, and runtime errors summary.',\n inputSchema: {\n type: 'object',\n properties: {\n app_name: {\n type: 'string',\n description: 'Name of the app',\n },\n },\n required: ['app_name'],\n },\n },\n {\n name: 'diagnose_error',\n description:\n 'Get AI-powered diagnosis for a runtime error. Returns root cause analysis and suggested fix.',\n inputSchema: {\n type: 'object',\n properties: {\n error_id: {\n type: 'string',\n description: 'The runtime error ID to diagnose',\n },\n },\n required: ['error_id'],\n },\n },\n {\n name: 'get_errors',\n description:\n 'List runtime errors for an app. Can filter by status (new, seen, resolved, ignored).',\n inputSchema: {\n type: 'object',\n properties: {\n app_name: {\n type: 'string',\n description: 'Name of the app',\n },\n status: {\n type: 'string',\n enum: ['new', 'seen', 'resolved', 'ignored'],\n description: 'Filter by error status (default: all)',\n },\n limit: {\n type: 'number',\n description: 'Maximum number of errors to return (default: 10)',\n },\n },\n required: ['app_name'],\n },\n },\n ],\n }\n })\n\n // Handle tool calls\n server.setRequestHandler(CallToolRequestSchema, async (request) => {\n const { name, arguments: args } = request.params\n\n try {\n switch (name) {\n case 'ship_check': {\n const parsed = shipCheckSchema.parse(args)\n\n // Find the app by name\n const appsResponse = await makeApiRequest(`/apps?name=${encodeURIComponent(parsed.app_name)}`, 'GET', apiKey)\n const apps = appsResponse.apps || []\n const app = apps.find((a) => a.name.toLowerCase() === parsed.app_name.toLowerCase())\n\n if (!app) {\n return {\n content: [\n {\n type: 'text',\n text: `App \"${parsed.app_name}\" not found. Connect it at https://vibeguard.app`,\n },\n ],\n }\n }\n\n // Create a new scan\n const scanResponse = await makeApiRequest('/scans', 'POST', apiKey, {\n appId: app.id,\n branch: parsed.branch,\n })\n const scan = scanResponse.scan\n\n if (!scan) {\n throw new Error('Failed to create scan')\n }\n\n // Poll for completion (max 2 minutes)\n const maxWait = 120000\n const pollInterval = 5000\n const startTime = Date.now()\n\n while (Date.now() - startTime < maxWait) {\n const statusResponse = await makeApiRequest(`/scans/${scan.id}`, 'GET', apiKey)\n const updatedScan = statusResponse.scan\n\n if (!updatedScan) {\n throw new Error('Failed to get scan status')\n }\n\n if (updatedScan.status === 'completed') {\n const verdict = getShipVerdict(updatedScan.score || 0)\n const issues = updatedScan.issues || []\n const criticalHighIssues = issues.filter((i) =>\n ['critical', 'high'].includes(i.severity)\n )\n\n let response = `${verdict.emoji} **Ship Score: ${updatedScan.score}/100** — ${verdict.label}\\n\\n`\n response += `${updatedScan.summary || ''}\\n\\n`\n\n if (criticalHighIssues.length > 0) {\n response += `### Issues Found\\n`\n for (const issue of criticalHighIssues.slice(0, 10)) {\n response += `- **${issue.severity.toUpperCase()}**: ${issue.title}\\n`\n if (issue.description) {\n response += ` ${issue.description}\\n`\n }\n if (issue.fix_available) {\n response += ` → Fix available (use \\`fix_issue\\` tool with id: ${issue.id})\\n`\n }\n }\n if (criticalHighIssues.length > 10) {\n response += `\\n...and ${criticalHighIssues.length - 10} more issues.\\n`\n }\n } else {\n response += `No critical or high severity issues found!\\n`\n }\n\n response += `\\n**Scan ID:** ${updatedScan.id}`\n\n return {\n content: [{ type: 'text', text: response }],\n }\n }\n\n if (updatedScan.status === 'failed') {\n throw new Error(updatedScan.error || 'Scan failed')\n }\n\n await new Promise((resolve) => setTimeout(resolve, pollInterval))\n }\n\n throw new Error('Scan timed out')\n }\n\n case 'fix_issue': {\n const parsed = fixIssueSchema.parse(args)\n\n const result = await makeApiRequest('/fixes', 'POST', apiKey, {\n issueId: parsed.issue_id,\n })\n\n if (!result.prUrl) {\n throw new Error('Failed to create fix PR')\n }\n\n return {\n content: [\n {\n type: 'text',\n text: `āœ… Fix applied! PR opened: ${result.prUrl}\\n\\nReview and merge the PR when ready.`,\n },\n ],\n }\n }\n\n case 'fix_all': {\n const parsed = fixAllSchema.parse(args)\n const minSeverity = parsed.severity || 'high'\n\n // Find the app\n const appsResponse = await makeApiRequest(`/apps?name=${encodeURIComponent(parsed.app_name)}`, 'GET', apiKey)\n const apps = appsResponse.apps || []\n const app = apps.find((a) => a.name.toLowerCase() === parsed.app_name.toLowerCase())\n\n if (!app) {\n return {\n content: [\n {\n type: 'text',\n text: `App \"${parsed.app_name}\" not found.`,\n },\n ],\n }\n }\n\n // Get open issues at or above severity\n const issuesResponse = await makeApiRequest(\n `/apps/${app.id}/issues?status=open&min_severity=${minSeverity}`,\n 'GET',\n apiKey\n )\n const issues = issuesResponse.issues || []\n\n if (issues.length === 0) {\n return {\n content: [\n {\n type: 'text',\n text: `No open ${minSeverity}+ issues found. Your app looks good! šŸŽ‰`,\n },\n ],\n }\n }\n\n // Fix each issue and collect results\n const fixResults: Array<{ title: string; prUrl: string }> = []\n const errors: string[] = []\n\n for (const issue of issues) {\n try {\n const fixResult = await makeApiRequest('/fixes', 'POST', apiKey, {\n issueId: issue.id,\n })\n if (fixResult.prUrl) {\n fixResults.push({ title: issue.title, prUrl: fixResult.prUrl })\n }\n } catch (error) {\n errors.push(`Failed to fix \"${issue.title}\": ${error instanceof Error ? error.message : 'Unknown error'}`)\n }\n }\n\n let response = `āœ… Fixed ${fixResults.length} issues:\\n\\n`\n for (const fix of fixResults) {\n response += `- ${fix.title} → [PR](${fix.prUrl})\\n`\n }\n\n if (errors.length > 0) {\n response += `\\nāš ļø ${errors.length} issues could not be fixed:\\n`\n for (const err of errors) {\n response += `- ${err}\\n`\n }\n }\n\n response += `\\nReview and merge the PRs when ready.`\n\n return {\n content: [{ type: 'text', text: response }],\n }\n }\n\n case 'get_score': {\n const parsed = getScoreSchema.parse(args)\n\n // Find the app\n const appsResponse = await makeApiRequest(`/apps?name=${encodeURIComponent(parsed.app_name)}`, 'GET', apiKey)\n const apps = appsResponse.apps || []\n const app = apps.find((a) => a.name.toLowerCase() === parsed.app_name.toLowerCase())\n\n if (!app) {\n return {\n content: [\n {\n type: 'text',\n text: `App \"${parsed.app_name}\" not found.`,\n },\n ],\n }\n }\n\n if (!app.latest_score) {\n return {\n content: [\n {\n type: 'text',\n text: `No scan results yet for **${app.name}**. Run \\`ship_check\\` first.`,\n },\n ],\n }\n }\n\n const verdict = getShipVerdict(app.latest_score)\n const lastScanned = app.last_scan_at ? timeAgo(app.last_scan_at) : 'unknown'\n\n return {\n content: [\n {\n type: 'text',\n text: `${verdict.emoji} **${app.name}** Ship Score: **${app.latest_score}/100** — ${verdict.label}\\nLast scanned: ${lastScanned}`,\n },\n ],\n }\n }\n\n // Phase 2: Runtime monitoring tools\n case 'app_status': {\n const parsed = appStatusSchema.parse(args)\n\n // Find the app\n const appsResponse = await makeApiRequest(`/apps?name=${encodeURIComponent(parsed.app_name)}`, 'GET', apiKey)\n const apps = appsResponse.apps || []\n const app = apps.find((a) => a.name.toLowerCase() === parsed.app_name.toLowerCase())\n\n if (!app) {\n return {\n content: [\n {\n type: 'text',\n text: `App \"${parsed.app_name}\" not found.`,\n },\n ],\n }\n }\n\n // Get uptime stats\n const uptimeResponse = await fetch(`${API_BASE_URL}/apps/${app.id}/uptime?period=24h`, {\n headers: { Authorization: `Bearer ${apiKey}` },\n })\n const uptimeData = uptimeResponse.ok ? (await uptimeResponse.json()) as AppStatusResponse : null\n\n // Get performance stats\n const perfResponse = await fetch(`${API_BASE_URL}/apps/${app.id}/performance?period=24h`, {\n headers: { Authorization: `Bearer ${apiKey}` },\n })\n const perfData = perfResponse.ok ? (await perfResponse.json()) as { coreWebVitals: AppStatusResponse['coreWebVitals'] } : null\n\n // Get error stats\n const errorsResponse = await fetch(`${API_BASE_URL}/apps/${app.id}/errors?limit=1`, {\n headers: { Authorization: `Bearer ${apiKey}` },\n })\n const errorsData = errorsResponse.ok ? (await errorsResponse.json()) as ErrorsResponse : null\n\n // Build response\n let response = `## ${app.name} Status\\n\\n`\n\n // Health status\n const healthEmoji = {\n healthy: '🟢',\n degraded: '🟔',\n down: 'šŸ”“',\n unknown: '⚪',\n }[app.health_status || 'unknown'] || '⚪'\n\n response += `**Health:** ${healthEmoji} ${app.health_status || 'unknown'}\\n`\n if (app.deployed_url) {\n response += `**URL:** ${app.deployed_url}\\n`\n }\n\n // Uptime stats\n if (uptimeData?.stats) {\n response += `\\n### Uptime (24h)\\n`\n response += `- **Uptime:** ${uptimeData.stats.uptimePercentage.toFixed(2)}%\\n`\n if (uptimeData.stats.avgResponseTime) {\n response += `- **Avg Response Time:** ${Math.round(uptimeData.stats.avgResponseTime)}ms\\n`\n }\n }\n\n // Web Vitals\n if (perfData?.coreWebVitals) {\n response += `\\n### Core Web Vitals (24h)\\n`\n const cwv = perfData.coreWebVitals\n if (cwv.lcp.p75 !== null) {\n const lcpEmoji = cwv.lcp.rating === 'good' ? '🟢' : cwv.lcp.rating === 'needs-improvement' ? '🟔' : 'šŸ”“'\n response += `- **LCP:** ${lcpEmoji} ${cwv.lcp.p75}ms\\n`\n }\n if (cwv.inp.p75 !== null) {\n const inpEmoji = cwv.inp.rating === 'good' ? '🟢' : cwv.inp.rating === 'needs-improvement' ? '🟔' : 'šŸ”“'\n response += `- **INP:** ${inpEmoji} ${cwv.inp.p75}ms\\n`\n }\n if (cwv.cls.p75 !== null) {\n const clsEmoji = cwv.cls.rating === 'good' ? '🟢' : cwv.cls.rating === 'needs-improvement' ? '🟔' : 'šŸ”“'\n response += `- **CLS:** ${clsEmoji} ${cwv.cls.p75}\\n`\n }\n }\n\n // Error stats\n if (errorsData?.stats) {\n response += `\\n### Runtime Errors\\n`\n response += `- **New:** ${errorsData.stats.new}\\n`\n response += `- **Seen:** ${errorsData.stats.seen}\\n`\n response += `- **Resolved:** ${errorsData.stats.resolved}\\n`\n response += `- **Total:** ${errorsData.stats.total}\\n`\n\n if (errorsData.stats.new > 0) {\n response += `\\nUse \\`get_errors\\` to see error details.`\n }\n }\n\n return {\n content: [{ type: 'text', text: response }],\n }\n }\n\n case 'diagnose_error': {\n const parsed = diagnoseErrorSchema.parse(args)\n\n // Trigger diagnosis via API\n const response = await fetch(`${API_BASE_URL}/errors/${parsed.error_id}/diagnose`, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n Authorization: `Bearer ${apiKey}`,\n },\n })\n\n if (!response.ok) {\n const error = (await response.json().catch(() => ({ error: 'Unknown error' }))) as { error?: string }\n throw new Error(error.error || `Diagnosis failed: ${response.status}`)\n }\n\n const data = (await response.json()) as DiagnoseResponse\n\n if (!data.diagnosis) {\n throw new Error('No diagnosis returned')\n }\n\n let result = `## Error Diagnosis\\n\\n${data.diagnosis}`\n\n if (data.suggestedFix) {\n result += `\\n\\n---\\n**Suggested Fix:**\\n${data.suggestedFix}`\n }\n\n return {\n content: [{ type: 'text', text: result }],\n }\n }\n\n case 'get_errors': {\n const parsed = getErrorsSchema.parse(args)\n const limit = parsed.limit || 10\n\n // Find the app\n const appsResponse = await makeApiRequest(`/apps?name=${encodeURIComponent(parsed.app_name)}`, 'GET', apiKey)\n const apps = appsResponse.apps || []\n const app = apps.find((a) => a.name.toLowerCase() === parsed.app_name.toLowerCase())\n\n if (!app) {\n return {\n content: [\n {\n type: 'text',\n text: `App \"${parsed.app_name}\" not found.`,\n },\n ],\n }\n }\n\n // Build query params\n const params = new URLSearchParams()\n params.set('limit', limit.toString())\n if (parsed.status) {\n params.set('status', parsed.status)\n }\n\n const errorsResponse = await fetch(`${API_BASE_URL}/apps/${app.id}/errors?${params}`, {\n headers: { Authorization: `Bearer ${apiKey}` },\n })\n\n if (!errorsResponse.ok) {\n throw new Error('Failed to fetch errors')\n }\n\n const data = (await errorsResponse.json()) as ErrorsResponse\n\n if (data.errors.length === 0) {\n return {\n content: [\n {\n type: 'text',\n text: `No ${parsed.status ? parsed.status + ' ' : ''}errors found for **${app.name}**. šŸŽ‰`,\n },\n ],\n }\n }\n\n let response = `## Runtime Errors for ${app.name}\\n\\n`\n response += `Showing ${data.errors.length} of ${data.stats.total} total errors\\n\\n`\n\n for (const error of data.errors) {\n const statusEmoji = {\n new: 'šŸ”“',\n seen: '🟔',\n resolved: 'āœ…',\n ignored: '⚪',\n }[error.status] || '⚪'\n\n response += `### ${statusEmoji} ${error.message.slice(0, 60)}${error.message.length > 60 ? '...' : ''}\\n`\n response += `- **ID:** \\`${error.id}\\`\\n`\n response += `- **Occurrences:** ${error.occurrenceCount}\\n`\n response += `- **First seen:** ${timeAgo(error.firstSeenAt)}\\n`\n response += `- **Last seen:** ${timeAgo(error.lastSeenAt)}\\n`\n if (error.sourceFile) {\n response += `- **Location:** ${error.sourceFile}${error.sourceLine ? `:${error.sourceLine}` : ''}\\n`\n }\n if (error.diagnosisPlain) {\n response += `- **Diagnosed:** āœ…\\n`\n } else {\n response += `- Use \\`diagnose_error\\` with id \\`${error.id}\\` for AI analysis\\n`\n }\n response += '\\n'\n }\n\n return {\n content: [{ type: 'text', text: response }],\n }\n }\n\n default:\n throw new Error(`Unknown tool: ${name}`)\n }\n } catch (error) {\n return {\n content: [\n {\n type: 'text',\n text: `Error: ${error instanceof Error ? error.message : 'Unknown error'}`,\n },\n ],\n isError: true,\n }\n }\n })\n\n // Start the server\n const transport = new StdioServerTransport()\n await server.connect(transport)\n}\n\nmain().catch((error) => {\n console.error('Fatal error:', error)\n process.exit(1)\n})\n"],"mappings":";;;AAAA,SAAS,cAAc;AACvB,SAAS,4BAA4B;AACrC;AAAA,EACE;AAAA,EACA;AAAA,OACK;AACP,SAAS,SAAS;AAElB,IAAM,eAAe,QAAQ,IAAI,qBAAqB;AAGtD,IAAM,kBAAkB,EAAE,OAAO;AAAA,EAC/B,UAAU,EAAE,OAAO,EAAE,SAAS,0DAA0D;AAAA,EACxF,QAAQ,EAAE,OAAO,EAAE,SAAS,EAAE,SAAS,mCAAmC;AAC5E,CAAC;AAED,IAAM,iBAAiB,EAAE,OAAO;AAAA,EAC9B,UAAU,EAAE,OAAO,EAAE,SAAS,+CAA+C;AAC/E,CAAC;AAED,IAAM,eAAe,EAAE,OAAO;AAAA,EAC5B,UAAU,EAAE,OAAO,EAAE,SAAS,qBAAqB;AAAA,EACnD,UAAU,EACP,KAAK,CAAC,YAAY,QAAQ,UAAU,KAAK,CAAC,EAC1C,SAAS,EACT,SAAS,4CAA4C;AAC1D,CAAC;AAED,IAAM,iBAAiB,EAAE,OAAO;AAAA,EAC9B,UAAU,EAAE,OAAO,EAAE,SAAS,qBAAqB;AACrD,CAAC;AAGD,IAAM,kBAAkB,EAAE,OAAO;AAAA,EAC/B,UAAU,EAAE,OAAO,EAAE,SAAS,uCAAuC;AACvE,CAAC;AAED,IAAM,sBAAsB,EAAE,OAAO;AAAA,EACnC,UAAU,EAAE,OAAO,EAAE,SAAS,kCAAkC;AAClE,CAAC;AAED,IAAM,kBAAkB,EAAE,OAAO;AAAA,EAC/B,UAAU,EAAE,OAAO,EAAE,SAAS,qBAAqB;AAAA,EACnD,QAAQ,EACL,KAAK,CAAC,OAAO,QAAQ,YAAY,SAAS,CAAC,EAC3C,SAAS,EACT,SAAS,uCAAuC;AAAA,EACnD,OAAO,EAAE,OAAO,EAAE,SAAS,EAAE,SAAS,kDAAkD;AAC1F,CAAC;AAmHD,SAAS,eAAe,OAAiD;AACvE,MAAI,SAAS,GAAI,QAAO,EAAE,OAAO,UAAK,OAAO,gBAAgB;AAC7D,MAAI,SAAS,GAAI,QAAO,EAAE,OAAO,gBAAM,OAAO,oBAAoB;AAClE,MAAI,SAAS,GAAI,QAAO,EAAE,OAAO,aAAM,OAAO,mBAAmB;AACjE,SAAO,EAAE,OAAO,aAAM,OAAO,cAAc;AAC7C;AAGA,SAAS,QAAQ,SAAyB;AACxC,QAAM,OAAO,IAAI,KAAK,OAAO;AAC7B,QAAM,MAAM,oBAAI,KAAK;AACrB,QAAM,SAAS,IAAI,QAAQ,IAAI,KAAK,QAAQ;AAC5C,QAAM,WAAW,KAAK,MAAM,SAAS,GAAK;AAC1C,QAAM,YAAY,KAAK,MAAM,WAAW,EAAE;AAC1C,QAAM,WAAW,KAAK,MAAM,YAAY,EAAE;AAE1C,MAAI,WAAW,EAAG,QAAO;AACzB,MAAI,WAAW,GAAI,QAAO,GAAG,QAAQ;AACrC,MAAI,YAAY,GAAI,QAAO,GAAG,SAAS;AACvC,SAAO,GAAG,QAAQ;AACpB;AAEA,eAAe,eACb,UACA,QACA,QACA,MACsB;AACtB,QAAM,WAAW,MAAM,MAAM,GAAG,YAAY,GAAG,QAAQ,IAAI;AAAA,IACzD;AAAA,IACA,SAAS;AAAA,MACP,gBAAgB;AAAA,MAChB,eAAe,UAAU,MAAM;AAAA,IACjC;AAAA,IACA,MAAM,OAAO,KAAK,UAAU,IAAI,IAAI;AAAA,EACtC,CAAC;AAED,MAAI,CAAC,SAAS,IAAI;AAChB,UAAM,QAAS,MAAM,SAAS,KAAK,EAAE,MAAM,OAAO,EAAE,OAAO,gBAAgB,EAAE;AAC7E,UAAM,IAAI,MAAM,MAAM,SAAS,uBAAuB,SAAS,MAAM,EAAE;AAAA,EACzE;AAEA,SAAO,SAAS,KAAK;AACvB;AAEA,eAAe,OAAO;AACpB,QAAM,SAAS,QAAQ,IAAI;AAE3B,MAAI,CAAC,QAAQ;AACX,YAAQ,MAAM,2DAA2D;AACzE,YAAQ,MAAM,oDAAoD;AAClE,YAAQ,KAAK,CAAC;AAAA,EAChB;AAEA,QAAM,SAAS,IAAI;AAAA,IACjB;AAAA,MACE,MAAM;AAAA,MACN,SAAS;AAAA,IACX;AAAA,IACA;AAAA,MACE,cAAc;AAAA,QACZ,OAAO,CAAC;AAAA,MACV;AAAA,IACF;AAAA,EACF;AAGA,SAAO,kBAAkB,wBAAwB,YAAY;AAC3D,WAAO;AAAA,MACL,OAAO;AAAA,QACL;AAAA,UACE,MAAM;AAAA,UACN,aACE;AAAA,UACF,aAAa;AAAA,YACX,MAAM;AAAA,YACN,YAAY;AAAA,cACV,UAAU;AAAA,gBACR,MAAM;AAAA,gBACN,aAAa;AAAA,cACf;AAAA,cACA,QAAQ;AAAA,gBACN,MAAM;AAAA,gBACN,aAAa;AAAA,cACf;AAAA,YACF;AAAA,YACA,UAAU,CAAC,UAAU;AAAA,UACvB;AAAA,QACF;AAAA,QACA;AAAA,UACE,MAAM;AAAA,UACN,aACE;AAAA,UACF,aAAa;AAAA,YACX,MAAM;AAAA,YACN,YAAY;AAAA,cACV,UAAU;AAAA,gBACR,MAAM;AAAA,gBACN,aAAa;AAAA,cACf;AAAA,YACF;AAAA,YACA,UAAU,CAAC,UAAU;AAAA,UACvB;AAAA,QACF;AAAA,QACA;AAAA,UACE,MAAM;AAAA,UACN,aACE;AAAA,UACF,aAAa;AAAA,YACX,MAAM;AAAA,YACN,YAAY;AAAA,cACV,UAAU;AAAA,gBACR,MAAM;AAAA,gBACN,aAAa;AAAA,cACf;AAAA,cACA,UAAU;AAAA,gBACR,MAAM;AAAA,gBACN,MAAM,CAAC,YAAY,QAAQ,UAAU,KAAK;AAAA,gBAC1C,aAAa;AAAA,cACf;AAAA,YACF;AAAA,YACA,UAAU,CAAC,UAAU;AAAA,UACvB;AAAA,QACF;AAAA,QACA;AAAA,UACE,MAAM;AAAA,UACN,aAAa;AAAA,UACb,aAAa;AAAA,YACX,MAAM;AAAA,YACN,YAAY;AAAA,cACV,UAAU;AAAA,gBACR,MAAM;AAAA,gBACN,aAAa;AAAA,cACf;AAAA,YACF;AAAA,YACA,UAAU,CAAC,UAAU;AAAA,UACvB;AAAA,QACF;AAAA;AAAA,QAEA;AAAA,UACE,MAAM;AAAA,UACN,aACE;AAAA,UACF,aAAa;AAAA,YACX,MAAM;AAAA,YACN,YAAY;AAAA,cACV,UAAU;AAAA,gBACR,MAAM;AAAA,gBACN,aAAa;AAAA,cACf;AAAA,YACF;AAAA,YACA,UAAU,CAAC,UAAU;AAAA,UACvB;AAAA,QACF;AAAA,QACA;AAAA,UACE,MAAM;AAAA,UACN,aACE;AAAA,UACF,aAAa;AAAA,YACX,MAAM;AAAA,YACN,YAAY;AAAA,cACV,UAAU;AAAA,gBACR,MAAM;AAAA,gBACN,aAAa;AAAA,cACf;AAAA,YACF;AAAA,YACA,UAAU,CAAC,UAAU;AAAA,UACvB;AAAA,QACF;AAAA,QACA;AAAA,UACE,MAAM;AAAA,UACN,aACE;AAAA,UACF,aAAa;AAAA,YACX,MAAM;AAAA,YACN,YAAY;AAAA,cACV,UAAU;AAAA,gBACR,MAAM;AAAA,gBACN,aAAa;AAAA,cACf;AAAA,cACA,QAAQ;AAAA,gBACN,MAAM;AAAA,gBACN,MAAM,CAAC,OAAO,QAAQ,YAAY,SAAS;AAAA,gBAC3C,aAAa;AAAA,cACf;AAAA,cACA,OAAO;AAAA,gBACL,MAAM;AAAA,gBACN,aAAa;AAAA,cACf;AAAA,YACF;AAAA,YACA,UAAU,CAAC,UAAU;AAAA,UACvB;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAAA,EACF,CAAC;AAGD,SAAO,kBAAkB,uBAAuB,OAAO,YAAY;AACjE,UAAM,EAAE,MAAM,WAAW,KAAK,IAAI,QAAQ;AAE1C,QAAI;AACF,cAAQ,MAAM;AAAA,QACZ,KAAK,cAAc;AACjB,gBAAM,SAAS,gBAAgB,MAAM,IAAI;AAGzC,gBAAM,eAAe,MAAM,eAAe,cAAc,mBAAmB,OAAO,QAAQ,CAAC,IAAI,OAAO,MAAM;AAC5G,gBAAM,OAAO,aAAa,QAAQ,CAAC;AACnC,gBAAM,MAAM,KAAK,KAAK,CAAC,MAAM,EAAE,KAAK,YAAY,MAAM,OAAO,SAAS,YAAY,CAAC;AAEnF,cAAI,CAAC,KAAK;AACR,mBAAO;AAAA,cACL,SAAS;AAAA,gBACP;AAAA,kBACE,MAAM;AAAA,kBACN,MAAM,QAAQ,OAAO,QAAQ;AAAA,gBAC/B;AAAA,cACF;AAAA,YACF;AAAA,UACF;AAGA,gBAAM,eAAe,MAAM,eAAe,UAAU,QAAQ,QAAQ;AAAA,YAClE,OAAO,IAAI;AAAA,YACX,QAAQ,OAAO;AAAA,UACjB,CAAC;AACD,gBAAM,OAAO,aAAa;AAE1B,cAAI,CAAC,MAAM;AACT,kBAAM,IAAI,MAAM,uBAAuB;AAAA,UACzC;AAGA,gBAAM,UAAU;AAChB,gBAAM,eAAe;AACrB,gBAAM,YAAY,KAAK,IAAI;AAE3B,iBAAO,KAAK,IAAI,IAAI,YAAY,SAAS;AACvC,kBAAM,iBAAiB,MAAM,eAAe,UAAU,KAAK,EAAE,IAAI,OAAO,MAAM;AAC9E,kBAAM,cAAc,eAAe;AAEnC,gBAAI,CAAC,aAAa;AAChB,oBAAM,IAAI,MAAM,2BAA2B;AAAA,YAC7C;AAEA,gBAAI,YAAY,WAAW,aAAa;AACtC,oBAAM,UAAU,eAAe,YAAY,SAAS,CAAC;AACrD,oBAAM,SAAS,YAAY,UAAU,CAAC;AACtC,oBAAM,qBAAqB,OAAO;AAAA,gBAAO,CAAC,MACxC,CAAC,YAAY,MAAM,EAAE,SAAS,EAAE,QAAQ;AAAA,cAC1C;AAEA,kBAAI,WAAW,GAAG,QAAQ,KAAK,kBAAkB,YAAY,KAAK,iBAAY,QAAQ,KAAK;AAAA;AAAA;AAC3F,0BAAY,GAAG,YAAY,WAAW,EAAE;AAAA;AAAA;AAExC,kBAAI,mBAAmB,SAAS,GAAG;AACjC,4BAAY;AAAA;AACZ,2BAAW,SAAS,mBAAmB,MAAM,GAAG,EAAE,GAAG;AACnD,8BAAY,OAAO,MAAM,SAAS,YAAY,CAAC,OAAO,MAAM,KAAK;AAAA;AACjE,sBAAI,MAAM,aAAa;AACrB,gCAAY,KAAK,MAAM,WAAW;AAAA;AAAA,kBACpC;AACA,sBAAI,MAAM,eAAe;AACvB,gCAAY,2DAAsD,MAAM,EAAE;AAAA;AAAA,kBAC5E;AAAA,gBACF;AACA,oBAAI,mBAAmB,SAAS,IAAI;AAClC,8BAAY;AAAA,SAAY,mBAAmB,SAAS,EAAE;AAAA;AAAA,gBACxD;AAAA,cACF,OAAO;AACL,4BAAY;AAAA;AAAA,cACd;AAEA,0BAAY;AAAA,eAAkB,YAAY,EAAE;AAE5C,qBAAO;AAAA,gBACL,SAAS,CAAC,EAAE,MAAM,QAAQ,MAAM,SAAS,CAAC;AAAA,cAC5C;AAAA,YACF;AAEA,gBAAI,YAAY,WAAW,UAAU;AACnC,oBAAM,IAAI,MAAM,YAAY,SAAS,aAAa;AAAA,YACpD;AAEA,kBAAM,IAAI,QAAQ,CAAC,YAAY,WAAW,SAAS,YAAY,CAAC;AAAA,UAClE;AAEA,gBAAM,IAAI,MAAM,gBAAgB;AAAA,QAClC;AAAA,QAEA,KAAK,aAAa;AAChB,gBAAM,SAAS,eAAe,MAAM,IAAI;AAExC,gBAAM,SAAS,MAAM,eAAe,UAAU,QAAQ,QAAQ;AAAA,YAC5D,SAAS,OAAO;AAAA,UAClB,CAAC;AAED,cAAI,CAAC,OAAO,OAAO;AACjB,kBAAM,IAAI,MAAM,yBAAyB;AAAA,UAC3C;AAEA,iBAAO;AAAA,YACL,SAAS;AAAA,cACP;AAAA,gBACE,MAAM;AAAA,gBACN,MAAM,kCAA6B,OAAO,KAAK;AAAA;AAAA;AAAA,cACjD;AAAA,YACF;AAAA,UACF;AAAA,QACF;AAAA,QAEA,KAAK,WAAW;AACd,gBAAM,SAAS,aAAa,MAAM,IAAI;AACtC,gBAAM,cAAc,OAAO,YAAY;AAGvC,gBAAM,eAAe,MAAM,eAAe,cAAc,mBAAmB,OAAO,QAAQ,CAAC,IAAI,OAAO,MAAM;AAC5G,gBAAM,OAAO,aAAa,QAAQ,CAAC;AACnC,gBAAM,MAAM,KAAK,KAAK,CAAC,MAAM,EAAE,KAAK,YAAY,MAAM,OAAO,SAAS,YAAY,CAAC;AAEnF,cAAI,CAAC,KAAK;AACR,mBAAO;AAAA,cACL,SAAS;AAAA,gBACP;AAAA,kBACE,MAAM;AAAA,kBACN,MAAM,QAAQ,OAAO,QAAQ;AAAA,gBAC/B;AAAA,cACF;AAAA,YACF;AAAA,UACF;AAGA,gBAAM,iBAAiB,MAAM;AAAA,YAC3B,SAAS,IAAI,EAAE,oCAAoC,WAAW;AAAA,YAC9D;AAAA,YACA;AAAA,UACF;AACA,gBAAM,SAAS,eAAe,UAAU,CAAC;AAEzC,cAAI,OAAO,WAAW,GAAG;AACvB,mBAAO;AAAA,cACL,SAAS;AAAA,gBACP;AAAA,kBACE,MAAM;AAAA,kBACN,MAAM,WAAW,WAAW;AAAA,gBAC9B;AAAA,cACF;AAAA,YACF;AAAA,UACF;AAGA,gBAAM,aAAsD,CAAC;AAC7D,gBAAM,SAAmB,CAAC;AAE1B,qBAAW,SAAS,QAAQ;AAC1B,gBAAI;AACF,oBAAM,YAAY,MAAM,eAAe,UAAU,QAAQ,QAAQ;AAAA,gBAC/D,SAAS,MAAM;AAAA,cACjB,CAAC;AACD,kBAAI,UAAU,OAAO;AACnB,2BAAW,KAAK,EAAE,OAAO,MAAM,OAAO,OAAO,UAAU,MAAM,CAAC;AAAA,cAChE;AAAA,YACF,SAAS,OAAO;AACd,qBAAO,KAAK,kBAAkB,MAAM,KAAK,MAAM,iBAAiB,QAAQ,MAAM,UAAU,eAAe,EAAE;AAAA,YAC3G;AAAA,UACF;AAEA,cAAI,WAAW,gBAAW,WAAW,MAAM;AAAA;AAAA;AAC3C,qBAAW,OAAO,YAAY;AAC5B,wBAAY,KAAK,IAAI,KAAK,gBAAW,IAAI,KAAK;AAAA;AAAA,UAChD;AAEA,cAAI,OAAO,SAAS,GAAG;AACrB,wBAAY;AAAA,eAAQ,OAAO,MAAM;AAAA;AACjC,uBAAW,OAAO,QAAQ;AACxB,0BAAY,KAAK,GAAG;AAAA;AAAA,YACtB;AAAA,UACF;AAEA,sBAAY;AAAA;AAEZ,iBAAO;AAAA,YACL,SAAS,CAAC,EAAE,MAAM,QAAQ,MAAM,SAAS,CAAC;AAAA,UAC5C;AAAA,QACF;AAAA,QAEA,KAAK,aAAa;AAChB,gBAAM,SAAS,eAAe,MAAM,IAAI;AAGxC,gBAAM,eAAe,MAAM,eAAe,cAAc,mBAAmB,OAAO,QAAQ,CAAC,IAAI,OAAO,MAAM;AAC5G,gBAAM,OAAO,aAAa,QAAQ,CAAC;AACnC,gBAAM,MAAM,KAAK,KAAK,CAAC,MAAM,EAAE,KAAK,YAAY,MAAM,OAAO,SAAS,YAAY,CAAC;AAEnF,cAAI,CAAC,KAAK;AACR,mBAAO;AAAA,cACL,SAAS;AAAA,gBACP;AAAA,kBACE,MAAM;AAAA,kBACN,MAAM,QAAQ,OAAO,QAAQ;AAAA,gBAC/B;AAAA,cACF;AAAA,YACF;AAAA,UACF;AAEA,cAAI,CAAC,IAAI,cAAc;AACrB,mBAAO;AAAA,cACL,SAAS;AAAA,gBACP;AAAA,kBACE,MAAM;AAAA,kBACN,MAAM,6BAA6B,IAAI,IAAI;AAAA,gBAC7C;AAAA,cACF;AAAA,YACF;AAAA,UACF;AAEA,gBAAM,UAAU,eAAe,IAAI,YAAY;AAC/C,gBAAM,cAAc,IAAI,eAAe,QAAQ,IAAI,YAAY,IAAI;AAEnE,iBAAO;AAAA,YACL,SAAS;AAAA,cACP;AAAA,gBACE,MAAM;AAAA,gBACN,MAAM,GAAG,QAAQ,KAAK,MAAM,IAAI,IAAI,oBAAoB,IAAI,YAAY,iBAAY,QAAQ,KAAK;AAAA,gBAAmB,WAAW;AAAA,cACjI;AAAA,YACF;AAAA,UACF;AAAA,QACF;AAAA;AAAA,QAGA,KAAK,cAAc;AACjB,gBAAM,SAAS,gBAAgB,MAAM,IAAI;AAGzC,gBAAM,eAAe,MAAM,eAAe,cAAc,mBAAmB,OAAO,QAAQ,CAAC,IAAI,OAAO,MAAM;AAC5G,gBAAM,OAAO,aAAa,QAAQ,CAAC;AACnC,gBAAM,MAAM,KAAK,KAAK,CAAC,MAAM,EAAE,KAAK,YAAY,MAAM,OAAO,SAAS,YAAY,CAAC;AAEnF,cAAI,CAAC,KAAK;AACR,mBAAO;AAAA,cACL,SAAS;AAAA,gBACP;AAAA,kBACE,MAAM;AAAA,kBACN,MAAM,QAAQ,OAAO,QAAQ;AAAA,gBAC/B;AAAA,cACF;AAAA,YACF;AAAA,UACF;AAGA,gBAAM,iBAAiB,MAAM,MAAM,GAAG,YAAY,SAAS,IAAI,EAAE,sBAAsB;AAAA,YACrF,SAAS,EAAE,eAAe,UAAU,MAAM,GAAG;AAAA,UAC/C,CAAC;AACD,gBAAM,aAAa,eAAe,KAAM,MAAM,eAAe,KAAK,IAA0B;AAG5F,gBAAM,eAAe,MAAM,MAAM,GAAG,YAAY,SAAS,IAAI,EAAE,2BAA2B;AAAA,YACxF,SAAS,EAAE,eAAe,UAAU,MAAM,GAAG;AAAA,UAC/C,CAAC;AACD,gBAAM,WAAW,aAAa,KAAM,MAAM,aAAa,KAAK,IAA8D;AAG1H,gBAAM,iBAAiB,MAAM,MAAM,GAAG,YAAY,SAAS,IAAI,EAAE,mBAAmB;AAAA,YAClF,SAAS,EAAE,eAAe,UAAU,MAAM,GAAG;AAAA,UAC/C,CAAC;AACD,gBAAM,aAAa,eAAe,KAAM,MAAM,eAAe,KAAK,IAAuB;AAGzF,cAAI,WAAW,MAAM,IAAI,IAAI;AAAA;AAAA;AAG7B,gBAAM,cAAc;AAAA,YAClB,SAAS;AAAA,YACT,UAAU;AAAA,YACV,MAAM;AAAA,YACN,SAAS;AAAA,UACX,EAAE,IAAI,iBAAiB,SAAS,KAAK;AAErC,sBAAY,eAAe,WAAW,IAAI,IAAI,iBAAiB,SAAS;AAAA;AACxE,cAAI,IAAI,cAAc;AACpB,wBAAY,YAAY,IAAI,YAAY;AAAA;AAAA,UAC1C;AAGA,cAAI,YAAY,OAAO;AACrB,wBAAY;AAAA;AAAA;AACZ,wBAAY,iBAAiB,WAAW,MAAM,iBAAiB,QAAQ,CAAC,CAAC;AAAA;AACzE,gBAAI,WAAW,MAAM,iBAAiB;AACpC,0BAAY,4BAA4B,KAAK,MAAM,WAAW,MAAM,eAAe,CAAC;AAAA;AAAA,YACtF;AAAA,UACF;AAGA,cAAI,UAAU,eAAe;AAC3B,wBAAY;AAAA;AAAA;AACZ,kBAAM,MAAM,SAAS;AACrB,gBAAI,IAAI,IAAI,QAAQ,MAAM;AACxB,oBAAM,WAAW,IAAI,IAAI,WAAW,SAAS,cAAO,IAAI,IAAI,WAAW,sBAAsB,cAAO;AACpG,0BAAY,cAAc,QAAQ,IAAI,IAAI,IAAI,GAAG;AAAA;AAAA,YACnD;AACA,gBAAI,IAAI,IAAI,QAAQ,MAAM;AACxB,oBAAM,WAAW,IAAI,IAAI,WAAW,SAAS,cAAO,IAAI,IAAI,WAAW,sBAAsB,cAAO;AACpG,0BAAY,cAAc,QAAQ,IAAI,IAAI,IAAI,GAAG;AAAA;AAAA,YACnD;AACA,gBAAI,IAAI,IAAI,QAAQ,MAAM;AACxB,oBAAM,WAAW,IAAI,IAAI,WAAW,SAAS,cAAO,IAAI,IAAI,WAAW,sBAAsB,cAAO;AACpG,0BAAY,cAAc,QAAQ,IAAI,IAAI,IAAI,GAAG;AAAA;AAAA,YACnD;AAAA,UACF;AAGA,cAAI,YAAY,OAAO;AACrB,wBAAY;AAAA;AAAA;AACZ,wBAAY,cAAc,WAAW,MAAM,GAAG;AAAA;AAC9C,wBAAY,eAAe,WAAW,MAAM,IAAI;AAAA;AAChD,wBAAY,mBAAmB,WAAW,MAAM,QAAQ;AAAA;AACxD,wBAAY,gBAAgB,WAAW,MAAM,KAAK;AAAA;AAElD,gBAAI,WAAW,MAAM,MAAM,GAAG;AAC5B,0BAAY;AAAA;AAAA,YACd;AAAA,UACF;AAEA,iBAAO;AAAA,YACL,SAAS,CAAC,EAAE,MAAM,QAAQ,MAAM,SAAS,CAAC;AAAA,UAC5C;AAAA,QACF;AAAA,QAEA,KAAK,kBAAkB;AACrB,gBAAM,SAAS,oBAAoB,MAAM,IAAI;AAG7C,gBAAM,WAAW,MAAM,MAAM,GAAG,YAAY,WAAW,OAAO,QAAQ,aAAa;AAAA,YACjF,QAAQ;AAAA,YACR,SAAS;AAAA,cACP,gBAAgB;AAAA,cAChB,eAAe,UAAU,MAAM;AAAA,YACjC;AAAA,UACF,CAAC;AAED,cAAI,CAAC,SAAS,IAAI;AAChB,kBAAM,QAAS,MAAM,SAAS,KAAK,EAAE,MAAM,OAAO,EAAE,OAAO,gBAAgB,EAAE;AAC7E,kBAAM,IAAI,MAAM,MAAM,SAAS,qBAAqB,SAAS,MAAM,EAAE;AAAA,UACvE;AAEA,gBAAM,OAAQ,MAAM,SAAS,KAAK;AAElC,cAAI,CAAC,KAAK,WAAW;AACnB,kBAAM,IAAI,MAAM,uBAAuB;AAAA,UACzC;AAEA,cAAI,SAAS;AAAA;AAAA,EAAyB,KAAK,SAAS;AAEpD,cAAI,KAAK,cAAc;AACrB,sBAAU;AAAA;AAAA;AAAA;AAAA,EAAgC,KAAK,YAAY;AAAA,UAC7D;AAEA,iBAAO;AAAA,YACL,SAAS,CAAC,EAAE,MAAM,QAAQ,MAAM,OAAO,CAAC;AAAA,UAC1C;AAAA,QACF;AAAA,QAEA,KAAK,cAAc;AACjB,gBAAM,SAAS,gBAAgB,MAAM,IAAI;AACzC,gBAAM,QAAQ,OAAO,SAAS;AAG9B,gBAAM,eAAe,MAAM,eAAe,cAAc,mBAAmB,OAAO,QAAQ,CAAC,IAAI,OAAO,MAAM;AAC5G,gBAAM,OAAO,aAAa,QAAQ,CAAC;AACnC,gBAAM,MAAM,KAAK,KAAK,CAAC,MAAM,EAAE,KAAK,YAAY,MAAM,OAAO,SAAS,YAAY,CAAC;AAEnF,cAAI,CAAC,KAAK;AACR,mBAAO;AAAA,cACL,SAAS;AAAA,gBACP;AAAA,kBACE,MAAM;AAAA,kBACN,MAAM,QAAQ,OAAO,QAAQ;AAAA,gBAC/B;AAAA,cACF;AAAA,YACF;AAAA,UACF;AAGA,gBAAM,SAAS,IAAI,gBAAgB;AACnC,iBAAO,IAAI,SAAS,MAAM,SAAS,CAAC;AACpC,cAAI,OAAO,QAAQ;AACjB,mBAAO,IAAI,UAAU,OAAO,MAAM;AAAA,UACpC;AAEA,gBAAM,iBAAiB,MAAM,MAAM,GAAG,YAAY,SAAS,IAAI,EAAE,WAAW,MAAM,IAAI;AAAA,YACpF,SAAS,EAAE,eAAe,UAAU,MAAM,GAAG;AAAA,UAC/C,CAAC;AAED,cAAI,CAAC,eAAe,IAAI;AACtB,kBAAM,IAAI,MAAM,wBAAwB;AAAA,UAC1C;AAEA,gBAAM,OAAQ,MAAM,eAAe,KAAK;AAExC,cAAI,KAAK,OAAO,WAAW,GAAG;AAC5B,mBAAO;AAAA,cACL,SAAS;AAAA,gBACP;AAAA,kBACE,MAAM;AAAA,kBACN,MAAM,MAAM,OAAO,SAAS,OAAO,SAAS,MAAM,EAAE,sBAAsB,IAAI,IAAI;AAAA,gBACpF;AAAA,cACF;AAAA,YACF;AAAA,UACF;AAEA,cAAI,WAAW,yBAAyB,IAAI,IAAI;AAAA;AAAA;AAChD,sBAAY,WAAW,KAAK,OAAO,MAAM,OAAO,KAAK,MAAM,KAAK;AAAA;AAAA;AAEhE,qBAAW,SAAS,KAAK,QAAQ;AAC/B,kBAAM,cAAc;AAAA,cAClB,KAAK;AAAA,cACL,MAAM;AAAA,cACN,UAAU;AAAA,cACV,SAAS;AAAA,YACX,EAAE,MAAM,MAAM,KAAK;AAEnB,wBAAY,OAAO,WAAW,IAAI,MAAM,QAAQ,MAAM,GAAG,EAAE,CAAC,GAAG,MAAM,QAAQ,SAAS,KAAK,QAAQ,EAAE;AAAA;AACrG,wBAAY,eAAe,MAAM,EAAE;AAAA;AACnC,wBAAY,sBAAsB,MAAM,eAAe;AAAA;AACvD,wBAAY,qBAAqB,QAAQ,MAAM,WAAW,CAAC;AAAA;AAC3D,wBAAY,oBAAoB,QAAQ,MAAM,UAAU,CAAC;AAAA;AACzD,gBAAI,MAAM,YAAY;AACpB,0BAAY,mBAAmB,MAAM,UAAU,GAAG,MAAM,aAAa,IAAI,MAAM,UAAU,KAAK,EAAE;AAAA;AAAA,YAClG;AACA,gBAAI,MAAM,gBAAgB;AACxB,0BAAY;AAAA;AAAA,YACd,OAAO;AACL,0BAAY,sCAAsC,MAAM,EAAE;AAAA;AAAA,YAC5D;AACA,wBAAY;AAAA,UACd;AAEA,iBAAO;AAAA,YACL,SAAS,CAAC,EAAE,MAAM,QAAQ,MAAM,SAAS,CAAC;AAAA,UAC5C;AAAA,QACF;AAAA,QAEA;AACE,gBAAM,IAAI,MAAM,iBAAiB,IAAI,EAAE;AAAA,MAC3C;AAAA,IACF,SAAS,OAAO;AACd,aAAO;AAAA,QACL,SAAS;AAAA,UACP;AAAA,YACE,MAAM;AAAA,YACN,MAAM,UAAU,iBAAiB,QAAQ,MAAM,UAAU,eAAe;AAAA,UAC1E;AAAA,QACF;AAAA,QACA,SAAS;AAAA,MACX;AAAA,IACF;AAAA,EACF,CAAC;AAGD,QAAM,YAAY,IAAI,qBAAqB;AAC3C,QAAM,OAAO,QAAQ,SAAS;AAChC;AAEA,KAAK,EAAE,MAAM,CAAC,UAAU;AACtB,UAAQ,MAAM,gBAAgB,KAAK;AACnC,UAAQ,KAAK,CAAC;AAChB,CAAC;","names":[]}
package/package.json ADDED
@@ -0,0 +1,30 @@
1
+ {
2
+ "name": "@vibeguardai/mcp-server",
3
+ "version": "0.1.0",
4
+ "description": "VibeGuard MCP Server for Claude Code and Cursor integration",
5
+ "main": "./dist/index.js",
6
+ "types": "./dist/index.d.ts",
7
+ "bin": {
8
+ "vibeguard-mcp": "./dist/index.js"
9
+ },
10
+ "scripts": {
11
+ "build": "tsup",
12
+ "dev": "tsup --watch",
13
+ "typecheck": "tsc --noEmit"
14
+ },
15
+ "dependencies": {
16
+ "@modelcontextprotocol/sdk": "^1.3.0",
17
+ "zod": "^3.24.0"
18
+ },
19
+ "devDependencies": {
20
+ "@types/node": "^22.0.0",
21
+ "tsup": "^8.3.0",
22
+ "typescript": "^5.7.0"
23
+ },
24
+ "files": [
25
+ "dist"
26
+ ],
27
+ "publishConfig": {
28
+ "access": "public"
29
+ }
30
+ }