@muggleai/mcp 1.0.4 → 1.0.6
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.
- package/dist/cli/index.d.ts.map +1 -1
- package/dist/cli.js +177 -14
- package/dist/cli.js.map +1 -1
- package/package.json +2 -2
- package/scripts/postinstall.mjs +1 -1
package/dist/cli/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/cli/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/cli/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAiIH;;GAEG;AACH,wBAAsB,MAAM,IAAI,OAAO,CAAC,IAAI,CAAC,CAe5C"}
|
package/dist/cli.js
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
import { getLogger, getConfig, getQaTools, registerTools, getLocalQaTools, createUnifiedMcpServer, startStdioServer, getElectronAppVersion, getDownloadBaseUrl, getElectronAppDir, isElectronAppInstalled, getElectronAppChecksums, performLogin, performLogout, getAuthStatus, getDataDir, getBundledElectronAppVersion, getElectronAppVersionSource, getCredentialsFilePath, __require } from './chunk-DX2A2FVG.js';
|
|
3
3
|
import * as fs from 'fs';
|
|
4
4
|
import { readFileSync, existsSync, rmSync, mkdirSync, createWriteStream, readdirSync, writeFileSync, statSync } from 'fs';
|
|
5
|
-
import * as
|
|
5
|
+
import * as path3 from 'path';
|
|
6
6
|
import { dirname, resolve } from 'path';
|
|
7
7
|
import { fileURLToPath } from 'url';
|
|
8
8
|
import { Command } from 'commander';
|
|
@@ -14,14 +14,14 @@ import * as crypto from 'crypto';
|
|
|
14
14
|
var logger = getLogger();
|
|
15
15
|
var ELECTRON_APP_DIR = "electron-app";
|
|
16
16
|
function getElectronAppBaseDir() {
|
|
17
|
-
return
|
|
17
|
+
return path3.join(getDataDir(), ELECTRON_APP_DIR);
|
|
18
18
|
}
|
|
19
19
|
function getDirectorySize(dirPath) {
|
|
20
20
|
let totalSize = 0;
|
|
21
21
|
try {
|
|
22
22
|
const entries = readdirSync(dirPath, { withFileTypes: true });
|
|
23
23
|
for (const entry of entries) {
|
|
24
|
-
const fullPath =
|
|
24
|
+
const fullPath = path3.join(dirPath, entry.name);
|
|
25
25
|
if (entry.isDirectory()) {
|
|
26
26
|
totalSize += getDirectorySize(fullPath);
|
|
27
27
|
} else if (entry.isFile()) {
|
|
@@ -74,7 +74,7 @@ function listInstalledVersions() {
|
|
|
74
74
|
if (!/^\d+\.\d+\.\d+$/.test(entry.name)) {
|
|
75
75
|
continue;
|
|
76
76
|
}
|
|
77
|
-
const versionPath =
|
|
77
|
+
const versionPath = path3.join(baseDir, entry.name);
|
|
78
78
|
const sizeBytes = getDirectorySize(versionPath);
|
|
79
79
|
versions.push({
|
|
80
80
|
version: entry.name,
|
|
@@ -301,6 +301,158 @@ async function doctorCommand() {
|
|
|
301
301
|
});
|
|
302
302
|
}
|
|
303
303
|
|
|
304
|
+
// src/cli/help.ts
|
|
305
|
+
var COLORS = {
|
|
306
|
+
reset: "\x1B[0m",
|
|
307
|
+
bold: "\x1B[1m",
|
|
308
|
+
dim: "\x1B[2m",
|
|
309
|
+
cyan: "\x1B[36m",
|
|
310
|
+
green: "\x1B[32m",
|
|
311
|
+
yellow: "\x1B[33m",
|
|
312
|
+
blue: "\x1B[34m"};
|
|
313
|
+
function colorize(text, color) {
|
|
314
|
+
if (process.env.NO_COLOR) {
|
|
315
|
+
return text;
|
|
316
|
+
}
|
|
317
|
+
return `${color}${text}${COLORS.reset}`;
|
|
318
|
+
}
|
|
319
|
+
function header(title) {
|
|
320
|
+
return colorize(`
|
|
321
|
+
${title}`, COLORS.bold + COLORS.cyan);
|
|
322
|
+
}
|
|
323
|
+
function cmd(cmd2) {
|
|
324
|
+
return colorize(cmd2, COLORS.green);
|
|
325
|
+
}
|
|
326
|
+
function path2(path5) {
|
|
327
|
+
return colorize(path5, COLORS.yellow);
|
|
328
|
+
}
|
|
329
|
+
function getHelpGuidance() {
|
|
330
|
+
const lines = [
|
|
331
|
+
"",
|
|
332
|
+
colorize("=".repeat(70), COLORS.cyan),
|
|
333
|
+
colorize(" Muggle AI MCP - Comprehensive How-To Guide", COLORS.bold + COLORS.green),
|
|
334
|
+
colorize("=".repeat(70), COLORS.cyan),
|
|
335
|
+
"",
|
|
336
|
+
header("What is Muggle AI MCP?"),
|
|
337
|
+
"",
|
|
338
|
+
" Muggle AI MCP is a Model Context Protocol server that provides AI",
|
|
339
|
+
" assistants with tools to perform automated QA testing of web applications.",
|
|
340
|
+
"",
|
|
341
|
+
" It supports both:",
|
|
342
|
+
` ${colorize("\u2022", COLORS.green)} Cloud QA - Test remote production/staging sites`,
|
|
343
|
+
` ${colorize("\u2022", COLORS.green)} Local QA - Test localhost development servers`,
|
|
344
|
+
"",
|
|
345
|
+
header("Setup Instructions"),
|
|
346
|
+
"",
|
|
347
|
+
` ${colorize("Step 1:", COLORS.bold)} Configure your MCP client`,
|
|
348
|
+
"",
|
|
349
|
+
` For ${colorize("Cursor", COLORS.bold)}, edit ${path2("~/.cursor/mcp.json")}:`,
|
|
350
|
+
"",
|
|
351
|
+
` ${colorize("{", COLORS.dim)}`,
|
|
352
|
+
` ${colorize('"mcpServers"', COLORS.yellow)}: {`,
|
|
353
|
+
` ${colorize('"muggle"', COLORS.yellow)}: {`,
|
|
354
|
+
` ${colorize('"command"', COLORS.yellow)}: ${colorize('"muggle-mcp"', COLORS.green)},`,
|
|
355
|
+
` ${colorize('"args"', COLORS.yellow)}: [${colorize('"serve"', COLORS.green)}]`,
|
|
356
|
+
` }`,
|
|
357
|
+
` }`,
|
|
358
|
+
` ${colorize("}", COLORS.dim)}`,
|
|
359
|
+
"",
|
|
360
|
+
` ${colorize("Step 2:", COLORS.bold)} Restart your MCP client`,
|
|
361
|
+
"",
|
|
362
|
+
` ${colorize("Step 3:", COLORS.bold)} Start testing! Ask your AI assistant:`,
|
|
363
|
+
` ${colorize('"Test the login flow on my app at http://localhost:3000"', COLORS.dim)}`,
|
|
364
|
+
"",
|
|
365
|
+
header("CLI Commands"),
|
|
366
|
+
"",
|
|
367
|
+
` ${colorize("Server Commands:", COLORS.bold)}`,
|
|
368
|
+
` ${cmd("muggle-mcp")} Start MCP server (default)`,
|
|
369
|
+
` ${cmd("muggle-mcp serve")} Start MCP server with all tools`,
|
|
370
|
+
` ${cmd("muggle-mcp serve --qa")} Start with Cloud QA tools only`,
|
|
371
|
+
` ${cmd("muggle-mcp serve --local")} Start with Local QA tools only`,
|
|
372
|
+
"",
|
|
373
|
+
` ${colorize("Setup & Diagnostics:", COLORS.bold)}`,
|
|
374
|
+
` ${cmd("muggle-mcp setup")} Download/update Electron app`,
|
|
375
|
+
` ${cmd("muggle-mcp setup --force")} Force re-download`,
|
|
376
|
+
` ${cmd("muggle-mcp doctor")} Diagnose installation issues`,
|
|
377
|
+
` ${cmd("muggle-mcp upgrade")} Check for updates`,
|
|
378
|
+
` ${cmd("muggle-mcp upgrade --check")} Check updates without installing`,
|
|
379
|
+
"",
|
|
380
|
+
` ${colorize("Authentication:", COLORS.bold)}`,
|
|
381
|
+
` ${cmd("muggle-mcp login")} Login to Muggle AI`,
|
|
382
|
+
` ${cmd("muggle-mcp logout")} Clear stored credentials`,
|
|
383
|
+
` ${cmd("muggle-mcp status")} Show authentication status`,
|
|
384
|
+
"",
|
|
385
|
+
` ${colorize("Maintenance:", COLORS.bold)}`,
|
|
386
|
+
` ${cmd("muggle-mcp versions")} List installed Electron app versions`,
|
|
387
|
+
` ${cmd("muggle-mcp cleanup")} Remove old Electron app versions`,
|
|
388
|
+
` ${cmd("muggle-mcp cleanup --all")} Remove all old versions`,
|
|
389
|
+
"",
|
|
390
|
+
` ${colorize("Help:", COLORS.bold)}`,
|
|
391
|
+
` ${cmd("muggle-mcp help")} Show this guide`,
|
|
392
|
+
` ${cmd("muggle-mcp --help")} Show command synopsis`,
|
|
393
|
+
` ${cmd("muggle-mcp --version")} Show version`,
|
|
394
|
+
"",
|
|
395
|
+
header("Authentication Flow"),
|
|
396
|
+
"",
|
|
397
|
+
" Authentication happens automatically when you first use a tool that",
|
|
398
|
+
" requires it:",
|
|
399
|
+
"",
|
|
400
|
+
` 1. ${colorize("A browser window opens", COLORS.bold)} with a verification code`,
|
|
401
|
+
` 2. ${colorize("Log in", COLORS.bold)} with your Muggle AI account`,
|
|
402
|
+
` 3. ${colorize("The tool call continues", COLORS.bold)} with your credentials`,
|
|
403
|
+
"",
|
|
404
|
+
` Credentials are stored in ${path2("~/.muggle-ai/credentials.json")}`,
|
|
405
|
+
"",
|
|
406
|
+
header("Available MCP Tools"),
|
|
407
|
+
"",
|
|
408
|
+
` ${colorize("Cloud QA Tools:", COLORS.bold)} (prefix: qa_)`,
|
|
409
|
+
" qa_project_create, qa_project_list, qa_use_case_create_from_prompts,",
|
|
410
|
+
" qa_test_case_generate_from_prompt, qa_workflow_start_*, etc.",
|
|
411
|
+
"",
|
|
412
|
+
` ${colorize("Local QA Tools:", COLORS.bold)} (prefix: muggle_)`,
|
|
413
|
+
" muggle_project_create, muggle_test_case_save,",
|
|
414
|
+
" muggle_execute_test_generation, muggle_execute_replay,",
|
|
415
|
+
" muggle_cloud_pull_project, muggle_publish_project, etc.",
|
|
416
|
+
"",
|
|
417
|
+
header("Data Directory"),
|
|
418
|
+
"",
|
|
419
|
+
` All data is stored in ${path2("~/.muggle-ai/")}:`,
|
|
420
|
+
"",
|
|
421
|
+
` ${path2("credentials.json")} Auth credentials (auto-generated)`,
|
|
422
|
+
` ${path2("projects/")} Local test projects`,
|
|
423
|
+
` ${path2("sessions/")} Test execution sessions`,
|
|
424
|
+
` ${path2("electron-app/")} Downloaded Electron app binaries`,
|
|
425
|
+
"",
|
|
426
|
+
header("Troubleshooting"),
|
|
427
|
+
"",
|
|
428
|
+
` ${colorize("Installation issues:", COLORS.bold)}`,
|
|
429
|
+
` Run ${cmd("muggle-mcp doctor")} to diagnose problems`,
|
|
430
|
+
"",
|
|
431
|
+
` ${colorize("Electron app not found:", COLORS.bold)}`,
|
|
432
|
+
` Run ${cmd("muggle-mcp setup --force")} to re-download`,
|
|
433
|
+
"",
|
|
434
|
+
` ${colorize("Authentication issues:", COLORS.bold)}`,
|
|
435
|
+
` Run ${cmd("muggle-mcp logout")} then ${cmd("muggle-mcp login")}`,
|
|
436
|
+
"",
|
|
437
|
+
` ${colorize("MCP not working in client:", COLORS.bold)}`,
|
|
438
|
+
" 1. Verify mcp.json configuration",
|
|
439
|
+
" 2. Restart your MCP client",
|
|
440
|
+
` 3. Check ${cmd("muggle-mcp doctor")} output`,
|
|
441
|
+
"",
|
|
442
|
+
header("Documentation & Support"),
|
|
443
|
+
"",
|
|
444
|
+
` Docs: ${colorize("https://www.muggle-ai.com/muggleTestV0/docs/mcp/mcp-overview", COLORS.blue)}`,
|
|
445
|
+
` GitHub: ${colorize("https://github.com/multiplex-ai/muggle-ai-mcp", COLORS.blue)}`,
|
|
446
|
+
"",
|
|
447
|
+
colorize("=".repeat(70), COLORS.cyan),
|
|
448
|
+
""
|
|
449
|
+
];
|
|
450
|
+
return lines.join("\n");
|
|
451
|
+
}
|
|
452
|
+
function helpCommand() {
|
|
453
|
+
console.log(getHelpGuidance());
|
|
454
|
+
}
|
|
455
|
+
|
|
304
456
|
// src/cli/login.ts
|
|
305
457
|
var logger3 = getLogger();
|
|
306
458
|
async function loginCommand(options) {
|
|
@@ -431,7 +583,7 @@ async function calculateFileChecksum(filePath) {
|
|
|
431
583
|
async function verifyFileChecksum(filePath, expectedChecksum) {
|
|
432
584
|
if (!expectedChecksum || expectedChecksum.trim() === "") {
|
|
433
585
|
logger5.warn("Checksum verification skipped - no checksum provided", {
|
|
434
|
-
file:
|
|
586
|
+
file: path3.basename(filePath)
|
|
435
587
|
});
|
|
436
588
|
return {
|
|
437
589
|
valid: true,
|
|
@@ -447,13 +599,13 @@ async function verifyFileChecksum(filePath, expectedChecksum) {
|
|
|
447
599
|
const valid = normalizedExpected === normalizedActual;
|
|
448
600
|
if (!valid) {
|
|
449
601
|
logger5.error("Checksum verification failed", {
|
|
450
|
-
file:
|
|
602
|
+
file: path3.basename(filePath),
|
|
451
603
|
expected: normalizedExpected,
|
|
452
604
|
actual: normalizedActual
|
|
453
605
|
});
|
|
454
606
|
} else {
|
|
455
607
|
logger5.info("Checksum verified successfully", {
|
|
456
|
-
file:
|
|
608
|
+
file: path3.basename(filePath),
|
|
457
609
|
checksum: normalizedActual
|
|
458
610
|
});
|
|
459
611
|
}
|
|
@@ -466,7 +618,7 @@ async function verifyFileChecksum(filePath, expectedChecksum) {
|
|
|
466
618
|
} catch (error) {
|
|
467
619
|
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
468
620
|
logger5.error("Checksum calculation failed", {
|
|
469
|
-
file:
|
|
621
|
+
file: path3.basename(filePath),
|
|
470
622
|
error: errorMessage
|
|
471
623
|
});
|
|
472
624
|
return {
|
|
@@ -505,8 +657,8 @@ function getBinaryName() {
|
|
|
505
657
|
}
|
|
506
658
|
async function extractZip(zipPath, destDir) {
|
|
507
659
|
return new Promise((resolve2, reject) => {
|
|
508
|
-
const
|
|
509
|
-
exec(
|
|
660
|
+
const cmd2 = platform() === "win32" ? `powershell -command "Expand-Archive -Path '${zipPath}' -DestinationPath '${destDir}' -Force"` : `unzip -o "${zipPath}" -d "${destDir}"`;
|
|
661
|
+
exec(cmd2, (error) => {
|
|
510
662
|
if (error) {
|
|
511
663
|
reject(error);
|
|
512
664
|
} else {
|
|
@@ -610,7 +762,7 @@ function extractVersionFromTag(tag) {
|
|
|
610
762
|
return match ? match[1] : null;
|
|
611
763
|
}
|
|
612
764
|
function getVersionOverridePath() {
|
|
613
|
-
return
|
|
765
|
+
return path3.join(getDataDir(), VERSION_OVERRIDE_FILE);
|
|
614
766
|
}
|
|
615
767
|
function getEffectiveElectronAppVersion() {
|
|
616
768
|
const overridePath = getVersionOverridePath();
|
|
@@ -694,8 +846,8 @@ function compareVersions2(a, b) {
|
|
|
694
846
|
}
|
|
695
847
|
async function extractZip2(zipPath, destDir) {
|
|
696
848
|
return new Promise((resolve2, reject) => {
|
|
697
|
-
const
|
|
698
|
-
exec(
|
|
849
|
+
const cmd2 = platform() === "win32" ? `powershell -command "Expand-Archive -Path '${zipPath}' -DestinationPath '${destDir}' -Force"` : `unzip -o "${zipPath}" -d "${destDir}"`;
|
|
850
|
+
exec(cmd2, (error) => {
|
|
699
851
|
if (error) {
|
|
700
852
|
reject(error);
|
|
701
853
|
} else {
|
|
@@ -774,7 +926,7 @@ async function downloadAndInstall(version, downloadUrl, checksum) {
|
|
|
774
926
|
if (!response.ok) {
|
|
775
927
|
throw new Error(`Download failed: ${response.status} ${response.statusText}`);
|
|
776
928
|
}
|
|
777
|
-
const tempFile =
|
|
929
|
+
const tempFile = path3.join(versionDir, binaryName);
|
|
778
930
|
const fileStream = createWriteStream(tempFile);
|
|
779
931
|
if (!response.body) {
|
|
780
932
|
throw new Error("No response body");
|
|
@@ -886,8 +1038,19 @@ function createProgram() {
|
|
|
886
1038
|
});
|
|
887
1039
|
return program;
|
|
888
1040
|
}
|
|
1041
|
+
function handleHelpCommand() {
|
|
1042
|
+
const args = process.argv.slice(2);
|
|
1043
|
+
if (args.length === 1 && args[0] === "help") {
|
|
1044
|
+
helpCommand();
|
|
1045
|
+
return true;
|
|
1046
|
+
}
|
|
1047
|
+
return false;
|
|
1048
|
+
}
|
|
889
1049
|
async function runCli() {
|
|
890
1050
|
try {
|
|
1051
|
+
if (handleHelpCommand()) {
|
|
1052
|
+
return;
|
|
1053
|
+
}
|
|
891
1054
|
const program = createProgram();
|
|
892
1055
|
await program.parseAsync(process.argv);
|
|
893
1056
|
} catch (error) {
|
package/dist/cli.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/cli/cleanup.ts","../src/cli/doctor.ts","../src/cli/login.ts","../src/cli/serve.ts","../src/shared/checksum.ts","../src/cli/setup.ts","../src/cli/upgrade.ts","../src/cli/index.ts","../src/cli/main.ts"],"names":["path","logger","existsSync","arch","resolve","platform","rmSync","getBinaryName","path3","mkdirSync","compareVersions","extractZip","exec","extractTarGz","createWriteStream","pipeline","cleanupResult","__dirname"],"mappings":"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","file":"cli.js","sourcesContent":["/**\n * Cleanup command - removes old electron-app versions to free disk space.\n */\n\nimport { existsSync, readdirSync, rmSync, statSync } from \"fs\";\nimport * as path from \"path\";\n\nimport { getDataDir, getElectronAppVersion } from \"../shared/config.js\";\nimport { getLogger } from \"../shared/logger.js\";\n\nconst logger = getLogger();\n\n/** Subdirectory name for electron-app versions. */\nconst ELECTRON_APP_DIR = \"electron-app\";\n\n/**\n * Options for the cleanup command.\n */\nexport interface ICleanupOptions {\n /** Remove all versions except current (default: keep current + 1 previous). */\n all?: boolean;\n /** Dry run - show what would be deleted without deleting. */\n dryRun?: boolean;\n}\n\n/**\n * Installed version info.\n */\nexport interface IInstalledVersion {\n /** Version string. */\n version: string;\n /** Full path to version directory. */\n path: string;\n /** Size in bytes. */\n sizeBytes: number;\n /** Whether this is the current active version. */\n isCurrent: boolean;\n}\n\n/**\n * Get the electron-app base directory.\n * @returns Path to ~/.muggle-ai/electron-app\n */\nfunction getElectronAppBaseDir(): string {\n return path.join(getDataDir(), ELECTRON_APP_DIR);\n}\n\n/**\n * Calculate directory size recursively.\n * @param dirPath - Path to directory.\n * @returns Size in bytes.\n */\nfunction getDirectorySize(dirPath: string): number {\n let totalSize = 0;\n\n try {\n const entries = readdirSync(dirPath, { withFileTypes: true });\n\n for (const entry of entries) {\n const fullPath = path.join(dirPath, entry.name);\n\n if (entry.isDirectory()) {\n totalSize += getDirectorySize(fullPath);\n } else if (entry.isFile()) {\n try {\n const stats = statSync(fullPath);\n totalSize += stats.size;\n } catch {\n // Skip files we can't stat\n }\n }\n }\n } catch {\n // Return 0 if we can't read the directory\n }\n\n return totalSize;\n}\n\n/**\n * Format bytes as human-readable string.\n * @param bytes - Size in bytes.\n * @returns Formatted string (e.g., \"150 MB\").\n */\nexport function formatBytes(bytes: number): string {\n if (bytes === 0) {\n return \"0 B\";\n }\n\n const units = [\"B\", \"KB\", \"MB\", \"GB\"];\n const k = 1024;\n const i = Math.floor(Math.log(bytes) / Math.log(k));\n const size = bytes / Math.pow(k, i);\n\n return `${size.toFixed(1)} ${units[i]}`;\n}\n\n/**\n * Compare semver versions.\n * @param a - First version.\n * @param b - Second version.\n * @returns Negative if a < b, positive if a > b, 0 if equal.\n */\nfunction compareVersions(a: string, b: string): number {\n const partsA = a.split(\".\").map(Number);\n const partsB = b.split(\".\").map(Number);\n\n for (let i = 0; i < 3; i++) {\n const partA = partsA[i] || 0;\n const partB = partsB[i] || 0;\n\n if (partA !== partB) {\n return partA - partB;\n }\n }\n\n return 0;\n}\n\n/**\n * List all installed electron-app versions.\n * @returns Array of installed version info, sorted by version descending.\n */\nexport function listInstalledVersions(): IInstalledVersion[] {\n const baseDir = getElectronAppBaseDir();\n const currentVersion = getElectronAppVersion();\n const versions: IInstalledVersion[] = [];\n\n if (!existsSync(baseDir)) {\n return versions;\n }\n\n try {\n const entries = readdirSync(baseDir, { withFileTypes: true });\n\n for (const entry of entries) {\n if (!entry.isDirectory()) {\n continue;\n }\n\n // Check if directory name looks like a version (e.g., \"1.0.1\")\n if (!/^\\d+\\.\\d+\\.\\d+$/.test(entry.name)) {\n continue;\n }\n\n const versionPath = path.join(baseDir, entry.name);\n const sizeBytes = getDirectorySize(versionPath);\n\n versions.push({\n version: entry.name,\n path: versionPath,\n sizeBytes: sizeBytes,\n isCurrent: entry.name === currentVersion,\n });\n }\n } catch (error) {\n const errorMessage = error instanceof Error ? error.message : String(error);\n logger.warn(\"Failed to list installed versions\", { error: errorMessage });\n }\n\n // Sort by version descending (newest first)\n versions.sort((a, b) => compareVersions(b.version, a.version));\n\n return versions;\n}\n\n/**\n * Remove old electron-app versions.\n * @param options - Cleanup options.\n * @returns Object with removed versions and freed bytes.\n */\nexport function cleanupOldVersions(options: ICleanupOptions = {}): {\n removed: IInstalledVersion[];\n freedBytes: number;\n} {\n const { all = false, dryRun = false } = options;\n const versions = listInstalledVersions();\n const removed: IInstalledVersion[] = [];\n let freedBytes = 0;\n\n // Determine which versions to keep\n // - Always keep current version\n // - By default, also keep one previous version (for rollback)\n // - With --all, only keep current\n\n const versionsToKeep = all ? 1 : 2;\n let keptCount = 0;\n\n for (const version of versions) {\n if (version.isCurrent) {\n keptCount++;\n continue;\n }\n\n if (keptCount < versionsToKeep) {\n keptCount++;\n continue;\n }\n\n // This version should be removed\n if (!dryRun) {\n try {\n rmSync(version.path, { recursive: true, force: true });\n logger.info(\"Removed old version\", {\n version: version.version,\n freedBytes: version.sizeBytes,\n });\n } catch (error) {\n const errorMessage = error instanceof Error ? error.message : String(error);\n logger.error(\"Failed to remove version\", {\n version: version.version,\n error: errorMessage,\n });\n continue;\n }\n }\n\n removed.push(version);\n freedBytes += version.sizeBytes;\n }\n\n return { removed: removed, freedBytes: freedBytes };\n}\n\n/**\n * Execute the versions command - list installed versions.\n */\nexport async function versionsCommand(): Promise<void> {\n console.log(\"\\nInstalled Electron App Versions\");\n console.log(\"================================\\n\");\n\n const versions = listInstalledVersions();\n\n if (versions.length === 0) {\n console.log(\"No versions installed.\");\n console.log(\"Run 'muggle-mcp setup' to download the Electron app.\\n\");\n return;\n }\n\n let totalSize = 0;\n\n for (const version of versions) {\n const marker = version.isCurrent ? \" (current)\" : \"\";\n const size = formatBytes(version.sizeBytes);\n console.log(` v${version.version}${marker} - ${size}`);\n totalSize += version.sizeBytes;\n }\n\n console.log(\"\");\n console.log(`Total: ${versions.length} version(s), ${formatBytes(totalSize)}`);\n console.log(\"\");\n}\n\n/**\n * Execute the cleanup command.\n * @param options - Command options.\n */\nexport async function cleanupCommand(options: ICleanupOptions): Promise<void> {\n console.log(\"\\nElectron App Cleanup\");\n console.log(\"====================\\n\");\n\n const versions = listInstalledVersions();\n\n if (versions.length === 0) {\n console.log(\"No versions installed. Nothing to clean up.\\n\");\n return;\n }\n\n if (versions.length === 1) {\n console.log(\"Only the current version is installed. Nothing to clean up.\\n\");\n return;\n }\n\n const currentVersion = versions.find((v) => v.isCurrent);\n const oldVersions = versions.filter((v) => !v.isCurrent);\n\n console.log(`Current version: v${currentVersion?.version || \"unknown\"}`);\n console.log(`Old versions: ${oldVersions.length}`);\n console.log(\"\");\n\n if (options.dryRun) {\n console.log(\"Dry run - showing what would be deleted:\\n\");\n }\n\n const result = cleanupOldVersions(options);\n\n if (result.removed.length === 0) {\n if (options.all) {\n console.log(\"No old versions to remove.\\n\");\n } else {\n console.log(\"Keeping one previous version for rollback.\");\n console.log(\"Use --all to remove all old versions.\\n\");\n }\n return;\n }\n\n console.log(options.dryRun ? \"Would remove:\" : \"Removed:\");\n\n for (const version of result.removed) {\n console.log(` v${version.version} (${formatBytes(version.sizeBytes)})`);\n }\n\n console.log(\"\");\n console.log(\n `${options.dryRun ? \"Would free\" : \"Freed\"}: ${formatBytes(result.freedBytes)}`,\n );\n console.log(\"\");\n\n if (options.dryRun) {\n console.log(\"Run without --dry-run to actually delete.\\n\");\n }\n\n logger.info(\"Cleanup completed\", {\n removed: result.removed.length,\n freedBytes: result.freedBytes,\n dryRun: options.dryRun,\n });\n}\n","/**\n * Doctor command - diagnoses installation and configuration issues.\n */\n\nimport { existsSync } from \"fs\";\n\nimport {\n getBundledElectronAppVersion,\n getConfig,\n getDataDir,\n getElectronAppVersion,\n getElectronAppVersionSource,\n isElectronAppInstalled,\n} from \"../shared/config.js\";\nimport { getAuthStatus, getCredentialsFilePath } from \"../shared/credentials.js\";\nimport { getLogger } from \"../shared/logger.js\";\n\nconst logger = getLogger();\n\n/**\n * Check result with status indicator.\n */\ninterface ICheckResult {\n /** Check name. */\n name: string;\n /** Whether check passed. */\n passed: boolean;\n /** Description of the result. */\n description: string;\n /** Suggestion to fix (if failed). */\n suggestion?: string;\n}\n\n/**\n * Run all diagnostic checks.\n * @returns Array of check results.\n */\nfunction runDiagnostics(): ICheckResult[] {\n const results: ICheckResult[] = [];\n const config = getConfig();\n\n // Check 1: Data directory exists\n const dataDir = getDataDir();\n results.push({\n name: \"Data Directory\",\n passed: existsSync(dataDir),\n description: existsSync(dataDir) ? `Found at ${dataDir}` : `Not found at ${dataDir}`,\n suggestion: \"Run 'muggle-mcp login' to create the data directory\",\n });\n\n // Check 2: Electron app installed\n const electronInstalled = isElectronAppInstalled();\n const electronVersion = getElectronAppVersion();\n const bundledVersion = getBundledElectronAppVersion();\n const versionSource = getElectronAppVersionSource();\n\n let electronDescription: string;\n if (electronInstalled) {\n electronDescription = `Installed (v${electronVersion})`;\n switch (versionSource) {\n case \"env\":\n electronDescription += ` [from ELECTRON_APP_VERSION env]`;\n break;\n case \"override\":\n electronDescription += ` [upgraded from bundled v${bundledVersion}]`;\n break;\n default:\n break;\n }\n } else {\n electronDescription = `Not installed (expected v${electronVersion})`;\n }\n\n results.push({\n name: \"Electron App\",\n passed: electronInstalled,\n description: electronDescription,\n suggestion: \"Run 'muggle-mcp setup' to download the Electron app\",\n });\n\n // Check 2b: Upgrade available hint\n if (electronInstalled) {\n results.push({\n name: \"Electron App Updates\",\n passed: true,\n description: \"Run 'muggle-mcp upgrade --check' to check for updates\",\n });\n }\n\n // Check 3: Authentication status\n const authStatus = getAuthStatus();\n results.push({\n name: \"Authentication\",\n passed: authStatus.authenticated,\n description: authStatus.authenticated\n ? `Authenticated as ${authStatus.email || \"unknown\"}`\n : \"Not authenticated\",\n suggestion: \"Run 'muggle-mcp login' to authenticate\",\n });\n\n // Check 4: API key available\n results.push({\n name: \"API Key\",\n passed: authStatus.hasApiKey,\n description: authStatus.hasApiKey ? \"API key stored\" : \"No API key stored\",\n suggestion: \"Run 'muggle-mcp login' to generate an API key\",\n });\n\n // Check 5: Credentials file\n const credentialsPath = getCredentialsFilePath();\n results.push({\n name: \"Credentials File\",\n passed: existsSync(credentialsPath),\n description: existsSync(credentialsPath)\n ? `Found at ${credentialsPath}`\n : `Not found at ${credentialsPath}`,\n suggestion: \"Run 'muggle-mcp login' to create credentials\",\n });\n\n // Check 6: Prompt service URL\n results.push({\n name: \"Prompt Service URL\",\n passed: !!config.qa.promptServiceBaseUrl,\n description: config.qa.promptServiceBaseUrl,\n });\n\n // Check 7: Web service URL (for local testing)\n results.push({\n name: \"Web Service URL\",\n passed: !!config.localQa.webServiceUrl,\n description: config.localQa.webServiceUrl,\n });\n\n return results;\n}\n\n/**\n * Format a check result for display.\n * @param result - Check result.\n * @returns Formatted string.\n */\nfunction formatCheckResult(result: ICheckResult): string {\n const icon = result.passed ? \"✓\" : \"✗\";\n const color = result.passed ? \"\\x1b[32m\" : \"\\x1b[31m\"; // Green or Red\n const reset = \"\\x1b[0m\";\n\n let output = `${color}${icon}${reset} ${result.name}: ${result.description}`;\n\n if (!result.passed && result.suggestion) {\n output += `\\n └─ ${result.suggestion}`;\n }\n\n return output;\n}\n\n/**\n * Execute the doctor command.\n */\nexport async function doctorCommand(): Promise<void> {\n console.log(\"\\nMuggle MCP Doctor\");\n console.log(\"=================\\n\");\n\n const results = runDiagnostics();\n\n for (const result of results) {\n console.log(formatCheckResult(result));\n }\n\n console.log(\"\");\n\n const failedCount = results.filter((r) => !r.passed).length;\n\n if (failedCount === 0) {\n console.log(\"All checks passed! Your installation is ready.\");\n } else {\n console.log(`${failedCount} issue(s) found. See suggestions above.`);\n }\n\n logger.info(\"Doctor command completed\", {\n totalChecks: results.length,\n passed: results.length - failedCount,\n failed: failedCount,\n });\n}\n","/**\n * Login/logout/status commands for authentication.\n */\n\nimport { performLogin, performLogout } from \"../shared/auth.js\";\nimport { getAuthStatus } from \"../shared/credentials.js\";\nimport { getLogger } from \"../shared/logger.js\";\n\nconst logger = getLogger();\n\n/**\n * Options for the login command.\n */\nexport interface ILoginOptions {\n /** Name for the API key. */\n keyName?: string;\n /** API key expiry: 30d, 90d, 1y, never. */\n keyExpiry?: string;\n}\n\n/**\n * Execute the login command.\n * @param options - Command options.\n */\nexport async function loginCommand(options: ILoginOptions): Promise<void> {\n console.log(\"\\nMuggle AI Login\");\n console.log(\"===============\\n\");\n\n const expiry = (options.keyExpiry || \"90d\") as \"30d\" | \"90d\" | \"1y\" | \"never\";\n\n console.log(\"Starting device code authentication...\");\n console.log(\"A browser window will open for you to complete login.\\n\");\n\n const result = await performLogin(options.keyName, expiry);\n\n if (result.success) {\n console.log(\"✓ Login successful!\");\n\n if (result.credentials?.email) {\n console.log(` Logged in as: ${result.credentials.email}`);\n }\n\n if (result.credentials?.apiKey) {\n console.log(\" API key created and stored for future use.\");\n }\n\n console.log(\"\\nYou can now use Muggle AI MCP tools.\");\n } else {\n console.error(\"✗ Login failed\");\n\n if (result.error) {\n console.error(` Error: ${result.error}`);\n }\n\n if (result.deviceCodeResponse) {\n console.log(\"\\nIf browser didn't open, visit:\");\n console.log(` ${result.deviceCodeResponse.verificationUriComplete}`);\n console.log(` Code: ${result.deviceCodeResponse.userCode}`);\n }\n\n process.exit(1);\n }\n}\n\n/**\n * Execute the logout command.\n */\nexport async function logoutCommand(): Promise<void> {\n console.log(\"\\nLogging out...\");\n\n performLogout();\n\n console.log(\"✓ Credentials cleared successfully.\");\n logger.info(\"Logout completed\");\n}\n\n/**\n * Execute the status command.\n */\nexport async function statusCommand(): Promise<void> {\n console.log(\"\\nAuthentication Status\");\n console.log(\"=====================\\n\");\n\n const status = getAuthStatus();\n\n if (status.authenticated) {\n console.log(\"✓ Authenticated\");\n\n if (status.email) {\n console.log(` Email: ${status.email}`);\n }\n\n if (status.userId) {\n console.log(` User ID: ${status.userId}`);\n }\n\n if (status.expiresAt) {\n const expiresDate = new Date(status.expiresAt);\n console.log(` Token expires: ${expiresDate.toLocaleString()}`);\n }\n\n console.log(` API Key: ${status.hasApiKey ? \"Yes\" : \"No\"}`);\n } else {\n console.log(\"✗ Not authenticated\");\n console.log(\"\\nRun 'muggle-mcp login' to authenticate.\");\n }\n}\n","/**\n * Serve command - starts the MCP server.\n */\n\nimport { getLocalQaTools } from \"../local-qa/index.js\";\nimport { getQaTools } from \"../qa/index.js\";\nimport { getConfig } from \"../shared/config.js\";\nimport { getLogger } from \"../shared/logger.js\";\nimport { createUnifiedMcpServer, registerTools, startStdioServer } from \"../server/index.js\";\n\nconst logger = getLogger();\n\n/**\n * Options for the serve command.\n */\nexport interface IServeOptions {\n /** Only enable Cloud QA tools. */\n qa?: boolean;\n /** Only enable Local QA tools. */\n local?: boolean;\n /** Use stdio transport. */\n stdio?: boolean;\n}\n\n/**\n * Execute the serve command.\n * @param options - Command options.\n */\nexport async function serveCommand(options: IServeOptions): Promise<void> {\n const config = getConfig();\n\n // Determine which tool sets to enable\n const enableQa = options.local ? false : true;\n const enableLocal = options.qa ? false : true;\n\n logger.info(\"Starting Muggle MCP Server\", {\n version: config.serverVersion,\n enableQa: enableQa,\n enableLocal: enableLocal,\n transport: \"stdio\",\n });\n\n try {\n // Register tools based on options\n if (enableQa) {\n const qaTools = getQaTools();\n registerTools(qaTools);\n logger.info(\"Registered QA tools\", { count: qaTools.length });\n }\n\n if (enableLocal) {\n const localTools = getLocalQaTools();\n registerTools(localTools);\n logger.info(\"Registered Local QA tools\", { count: localTools.length });\n }\n\n // Create unified MCP server\n const mcpServer = createUnifiedMcpServer({\n enableQaTools: enableQa,\n enableLocalTools: enableLocal,\n });\n\n // Start stdio server (MCP clients communicate via stdin/stdout)\n await startStdioServer(mcpServer);\n\n logger.info(\"MCP server started successfully\");\n } catch (error) {\n logger.error(\"Failed to start MCP server\", {\n error: error instanceof Error ? error.message : String(error),\n stack: error instanceof Error ? error.stack : undefined,\n });\n process.exit(1);\n }\n}\n","/**\n * Checksum verification utilities for downloaded binaries.\n * Uses SHA256 for integrity verification.\n */\n\nimport * as crypto from \"crypto\";\nimport * as fs from \"fs\";\nimport * as path from \"path\";\nimport { platform } from \"os\";\n\nimport { getLogger } from \"./logger.js\";\n\nconst logger = getLogger();\n\n/**\n * Platform key for checksum lookup.\n */\nexport type PlatformKey = \"darwin-arm64\" | \"darwin-x64\" | \"win32-x64\" | \"linux-x64\";\n\n/**\n * Checksums map from package.json muggleConfig.\n */\nexport interface IChecksums {\n /** macOS ARM64 (Apple Silicon) checksum. */\n \"darwin-arm64\"?: string;\n /** macOS x64 (Intel) checksum. */\n \"darwin-x64\"?: string;\n /** Windows x64 checksum. */\n \"win32-x64\"?: string;\n /** Linux x64 checksum. */\n \"linux-x64\"?: string;\n}\n\n/**\n * Result of checksum verification.\n */\nexport interface IChecksumResult {\n /** Whether verification passed. */\n valid: boolean;\n /** Expected checksum (from config or release). */\n expected: string;\n /** Actual checksum of downloaded file. */\n actual: string;\n /** Error message if verification failed. */\n error?: string;\n}\n\n/**\n * Get the platform key for the current system.\n * @returns The platform key for checksum lookup.\n */\nexport function getPlatformKey(): PlatformKey {\n const os = platform();\n const arch = process.arch;\n\n switch (os) {\n case \"darwin\":\n return arch === \"arm64\" ? \"darwin-arm64\" : \"darwin-x64\";\n case \"win32\":\n return \"win32-x64\";\n case \"linux\":\n return \"linux-x64\";\n default:\n throw new Error(`Unsupported platform: ${os}`);\n }\n}\n\n/**\n * Calculate SHA256 checksum of a file.\n * @param filePath - Path to the file.\n * @returns The SHA256 checksum as a hex string.\n */\nexport async function calculateFileChecksum(filePath: string): Promise<string> {\n return new Promise((resolve, reject) => {\n const hash = crypto.createHash(\"sha256\");\n const stream = fs.createReadStream(filePath);\n\n stream.on(\"data\", (data) => {\n hash.update(data);\n });\n\n stream.on(\"end\", () => {\n resolve(hash.digest(\"hex\"));\n });\n\n stream.on(\"error\", (error) => {\n reject(error);\n });\n });\n}\n\n/**\n * Verify file checksum against expected value.\n * @param filePath - Path to the file to verify.\n * @param expectedChecksum - Expected SHA256 checksum.\n * @returns Verification result.\n */\nexport async function verifyFileChecksum(\n filePath: string,\n expectedChecksum: string,\n): Promise<IChecksumResult> {\n if (!expectedChecksum || expectedChecksum.trim() === \"\") {\n logger.warn(\"Checksum verification skipped - no checksum provided\", {\n file: path.basename(filePath),\n });\n return {\n valid: true,\n expected: \"\",\n actual: \"\",\n error: \"Checksum verification skipped - no checksum configured\",\n };\n }\n\n try {\n const actualChecksum = await calculateFileChecksum(filePath);\n const normalizedExpected = expectedChecksum.toLowerCase().trim();\n const normalizedActual = actualChecksum.toLowerCase();\n\n const valid = normalizedExpected === normalizedActual;\n\n if (!valid) {\n logger.error(\"Checksum verification failed\", {\n file: path.basename(filePath),\n expected: normalizedExpected,\n actual: normalizedActual,\n });\n } else {\n logger.info(\"Checksum verified successfully\", {\n file: path.basename(filePath),\n checksum: normalizedActual,\n });\n }\n\n return {\n valid: valid,\n expected: normalizedExpected,\n actual: normalizedActual,\n error: valid ? undefined : \"Checksum mismatch - file may be corrupted or tampered with\",\n };\n } catch (error) {\n const errorMessage = error instanceof Error ? error.message : String(error);\n logger.error(\"Checksum calculation failed\", {\n file: path.basename(filePath),\n error: errorMessage,\n });\n\n return {\n valid: false,\n expected: expectedChecksum,\n actual: \"\",\n error: `Failed to calculate checksum: ${errorMessage}`,\n };\n }\n}\n\n/**\n * Get checksum for current platform from checksums map.\n * @param checksums - Checksums map from config.\n * @returns Checksum for current platform, or empty string if not found.\n */\nexport function getChecksumForPlatform(checksums: IChecksums | undefined): string {\n if (!checksums) {\n return \"\";\n }\n\n const platformKey = getPlatformKey();\n return checksums[platformKey] || \"\";\n}\n","/**\n * Setup command - downloads/updates the Electron app.\n */\n\nimport { exec } from \"child_process\";\nimport { createWriteStream, existsSync, mkdirSync, rmSync } from \"fs\";\nimport { arch, platform } from \"os\";\nimport { pipeline } from \"stream/promises\";\n\nimport {\n getDownloadBaseUrl,\n getElectronAppChecksums,\n getElectronAppDir,\n getElectronAppVersion,\n isElectronAppInstalled,\n} from \"../shared/config.js\";\nimport { getChecksumForPlatform, verifyFileChecksum } from \"../shared/checksum.js\";\nimport { getLogger } from \"../shared/logger.js\";\n\nconst logger = getLogger();\n\n/**\n * Options for the setup command.\n */\nexport interface ISetupOptions {\n /** Force re-download even if already installed. */\n force?: boolean;\n}\n\n/**\n * Get platform-specific binary name.\n * @returns Binary filename.\n */\nfunction getBinaryName(): string {\n const os = platform();\n const architecture = arch();\n\n switch (os) {\n case \"darwin\": {\n const darwinArch = architecture === \"arm64\" ? \"arm64\" : \"x64\";\n return `MuggleAI-darwin-${darwinArch}.zip`;\n }\n case \"win32\":\n return \"MuggleAI-win32-x64.zip\";\n case \"linux\":\n return \"MuggleAI-linux-x64.zip\";\n default:\n throw new Error(`Unsupported platform: ${os}`);\n }\n}\n\n/**\n * Extract a zip file.\n * @param zipPath - Path to zip file.\n * @param destDir - Destination directory.\n */\nasync function extractZip(zipPath: string, destDir: string): Promise<void> {\n return new Promise((resolve, reject) => {\n const cmd =\n platform() === \"win32\"\n ? `powershell -command \"Expand-Archive -Path '${zipPath}' -DestinationPath '${destDir}' -Force\"`\n : `unzip -o \"${zipPath}\" -d \"${destDir}\"`;\n\n exec(cmd, (error) => {\n if (error) {\n reject(error);\n } else {\n resolve();\n }\n });\n });\n}\n\n/**\n * Extract a tar.gz file.\n * @param tarPath - Path to tar.gz file.\n * @param destDir - Destination directory.\n */\nasync function extractTarGz(tarPath: string, destDir: string): Promise<void> {\n return new Promise((resolve, reject) => {\n exec(`tar -xzf \"${tarPath}\" -C \"${destDir}\"`, (error) => {\n if (error) {\n reject(error);\n } else {\n resolve();\n }\n });\n });\n}\n\n/**\n * Execute the setup command.\n * @param options - Command options.\n */\nexport async function setupCommand(options: ISetupOptions): Promise<void> {\n const version = getElectronAppVersion();\n const baseUrl = getDownloadBaseUrl();\n const versionDir = getElectronAppDir(version);\n\n // Check if already installed\n if (!options.force && isElectronAppInstalled()) {\n console.log(`Electron app v${version} is already installed at ${versionDir}`);\n console.log(\"Use --force to re-download.\");\n return;\n }\n\n const binaryName = getBinaryName();\n const downloadUrl = `${baseUrl}/v${version}/${binaryName}`;\n\n console.log(`Downloading Muggle Test Electron app v${version}...`);\n console.log(`URL: ${downloadUrl}`);\n\n try {\n // Create directory\n if (existsSync(versionDir)) {\n rmSync(versionDir, { recursive: true, force: true });\n }\n mkdirSync(versionDir, { recursive: true });\n\n // Download\n const response = await fetch(downloadUrl);\n if (!response.ok) {\n throw new Error(`Download failed: ${response.status} ${response.statusText}`);\n }\n\n const tempFile = `${versionDir}/${binaryName}`;\n const fileStream = createWriteStream(tempFile);\n\n if (!response.body) {\n throw new Error(\"No response body\");\n }\n\n await pipeline(response.body as unknown as NodeJS.ReadableStream, fileStream);\n\n console.log(\"Download complete, verifying checksum...\");\n\n // Verify checksum\n const checksums = getElectronAppChecksums();\n const expectedChecksum = getChecksumForPlatform(checksums);\n const checksumResult = await verifyFileChecksum(tempFile, expectedChecksum);\n\n if (!checksumResult.valid && expectedChecksum) {\n rmSync(versionDir, { recursive: true, force: true });\n throw new Error(\n `Checksum verification failed!\\n` +\n `Expected: ${checksumResult.expected}\\n` +\n `Actual: ${checksumResult.actual}\\n` +\n `The downloaded file may be corrupted or tampered with.`,\n );\n }\n\n if (expectedChecksum) {\n console.log(\"Checksum verified successfully.\");\n } else {\n console.log(\"Warning: No checksum configured, skipping verification.\");\n }\n\n console.log(\"Extracting...\");\n\n // Extract based on file type\n if (binaryName.endsWith(\".zip\")) {\n await extractZip(tempFile, versionDir);\n } else if (binaryName.endsWith(\".tar.gz\")) {\n await extractTarGz(tempFile, versionDir);\n }\n\n // Clean up temp file\n rmSync(tempFile, { force: true });\n\n console.log(`Electron app installed to ${versionDir}`);\n logger.info(\"Setup complete\", { version: version, path: versionDir });\n } catch (error) {\n const errorMessage = error instanceof Error ? error.message : String(error);\n console.error(`Failed to download Electron app: ${errorMessage}`);\n logger.error(\"Setup failed\", { error: errorMessage });\n process.exit(1);\n }\n}\n","/**\n * Upgrade command - checks for and downloads the latest electron-app version.\n * Allows users to get newer electron-app versions independently of MCP updates.\n */\n\nimport { exec } from \"child_process\";\nimport { createWriteStream, existsSync, mkdirSync, rmSync, writeFileSync } from \"fs\";\nimport { platform } from \"os\";\nimport * as path from \"path\";\nimport { pipeline } from \"stream/promises\";\n\nimport {\n getDataDir,\n getDownloadBaseUrl,\n getElectronAppDir,\n getElectronAppVersion,\n} from \"../shared/config.js\";\nimport { getPlatformKey, verifyFileChecksum } from \"../shared/checksum.js\";\nimport { getLogger } from \"../shared/logger.js\";\nimport { cleanupOldVersions, formatBytes } from \"./cleanup.js\";\n\nconst logger = getLogger();\n\n/** GitHub API URL for releases. */\nconst GITHUB_RELEASES_API = \"https://api.github.com/repos/multiplex-ai/muggle-ai-mcp/releases\";\n\n/** Filename for storing the overridden electron-app version. */\nconst VERSION_OVERRIDE_FILE = \"electron-app-version-override.json\";\n\n/**\n * Options for the upgrade command.\n */\nexport interface IUpgradeOptions {\n /** Force re-download even if already on latest. */\n force?: boolean;\n /** Check for updates only, don't download. */\n check?: boolean;\n /** Specific version to download (e.g., \"1.0.2\"). */\n version?: string;\n}\n\n/**\n * Result of checking for updates.\n */\ninterface IUpdateCheckResult {\n /** Currently installed version. */\n currentVersion: string;\n /** Latest available version. */\n latestVersion: string;\n /** Whether an update is available. */\n updateAvailable: boolean;\n /** Download URL for the latest version. */\n downloadUrl?: string;\n}\n\n/**\n * Get platform-specific binary name.\n * @returns Binary filename.\n */\nfunction getBinaryName(): string {\n const os = platform();\n const arch = process.arch;\n\n switch (os) {\n case \"darwin\":\n return arch === \"arm64\"\n ? \"MuggleAI-darwin-arm64.zip\"\n : \"MuggleAI-darwin-x64.zip\";\n case \"win32\":\n return \"MuggleAI-win32-x64.zip\";\n case \"linux\":\n return \"MuggleAI-linux-x64.zip\";\n default:\n throw new Error(`Unsupported platform: ${os}`);\n }\n}\n\n/**\n * Extract version from release tag.\n * @param tag - Release tag (e.g., \"electron-app-v1.0.2\").\n * @returns Version string (e.g., \"1.0.2\") or null.\n */\nfunction extractVersionFromTag(tag: string): string | null {\n const match = tag.match(/^electron-app-v(\\d+\\.\\d+\\.\\d+)$/);\n return match ? match[1] : null;\n}\n\n/**\n * Get the path to the version override file.\n * @returns Path to the override file.\n */\nfunction getVersionOverridePath(): string {\n return path.join(getDataDir(), VERSION_OVERRIDE_FILE);\n}\n\n/**\n * Get the effective electron-app version (override or default).\n * @returns The version to use.\n */\nexport function getEffectiveElectronAppVersion(): string {\n const overridePath = getVersionOverridePath();\n\n if (existsSync(overridePath)) {\n try {\n const content = JSON.parse(require(\"fs\").readFileSync(overridePath, \"utf-8\"));\n if (content.version) {\n return content.version;\n }\n } catch {\n // Fall through to default\n }\n }\n\n return getElectronAppVersion();\n}\n\n/**\n * Save the version override.\n * @param version - Version to save.\n */\nfunction saveVersionOverride(version: string): void {\n const overridePath = getVersionOverridePath();\n const dataDir = getDataDir();\n\n if (!existsSync(dataDir)) {\n mkdirSync(dataDir, { recursive: true });\n }\n\n writeFileSync(overridePath, JSON.stringify({\n version: version,\n updatedAt: new Date().toISOString(),\n }, null, 2), \"utf-8\");\n}\n\n/**\n * Check for the latest electron-app version from GitHub releases.\n * @returns Update check result.\n */\nasync function checkForUpdates(): Promise<IUpdateCheckResult> {\n const currentVersion = getEffectiveElectronAppVersion();\n\n try {\n const response = await fetch(GITHUB_RELEASES_API, {\n headers: {\n \"Accept\": \"application/vnd.github.v3+json\",\n \"User-Agent\": \"muggle-mcp\",\n },\n });\n\n if (!response.ok) {\n throw new Error(`GitHub API error: ${response.status} ${response.statusText}`);\n }\n\n const releases = await response.json() as Array<{\n tag_name: string;\n prerelease: boolean;\n draft: boolean;\n }>;\n\n // Find latest electron-app release (non-prerelease, non-draft)\n for (const release of releases) {\n if (release.prerelease || release.draft) {\n continue;\n }\n\n const version = extractVersionFromTag(release.tag_name);\n if (version) {\n const updateAvailable = compareVersions(version, currentVersion) > 0;\n const baseUrl = getDownloadBaseUrl();\n const binaryName = getBinaryName();\n\n return {\n currentVersion: currentVersion,\n latestVersion: version,\n updateAvailable: updateAvailable,\n downloadUrl: `${baseUrl}/electron-app-v${version}/${binaryName}`,\n };\n }\n }\n\n // No electron-app releases found\n return {\n currentVersion: currentVersion,\n latestVersion: currentVersion,\n updateAvailable: false,\n };\n } catch (error) {\n const errorMessage = error instanceof Error ? error.message : String(error);\n logger.warn(\"Failed to check for updates\", { error: errorMessage });\n throw new Error(`Failed to check for updates: ${errorMessage}`);\n }\n}\n\n/**\n * Compare two semver versions.\n * @param a - First version.\n * @param b - Second version.\n * @returns 1 if a > b, -1 if a < b, 0 if equal.\n */\nfunction compareVersions(a: string, b: string): number {\n const partsA = a.split(\".\").map(Number);\n const partsB = b.split(\".\").map(Number);\n\n for (let i = 0; i < 3; i++) {\n const partA = partsA[i] || 0;\n const partB = partsB[i] || 0;\n\n if (partA > partB) {\n return 1;\n }\n if (partA < partB) {\n return -1;\n }\n }\n\n return 0;\n}\n\n/**\n * Extract a zip file.\n * @param zipPath - Path to zip file.\n * @param destDir - Destination directory.\n */\nasync function extractZip(zipPath: string, destDir: string): Promise<void> {\n return new Promise((resolve, reject) => {\n const cmd =\n platform() === \"win32\"\n ? `powershell -command \"Expand-Archive -Path '${zipPath}' -DestinationPath '${destDir}' -Force\"`\n : `unzip -o \"${zipPath}\" -d \"${destDir}\"`;\n\n exec(cmd, (error) => {\n if (error) {\n reject(error);\n } else {\n resolve();\n }\n });\n });\n}\n\n/**\n * Extract a tar.gz file.\n * @param tarPath - Path to tar.gz file.\n * @param destDir - Destination directory.\n */\nasync function extractTarGz(tarPath: string, destDir: string): Promise<void> {\n return new Promise((resolve, reject) => {\n exec(`tar -xzf \"${tarPath}\" -C \"${destDir}\"`, (error) => {\n if (error) {\n reject(error);\n } else {\n resolve();\n }\n });\n });\n}\n\n/**\n * Fetch checksum for a specific version and platform from the release.\n * Looks for checksums.txt in the release assets.\n * @param version - Version to get checksum for.\n * @returns The checksum or empty string if not available.\n */\nasync function fetchChecksumFromRelease(version: string): Promise<string> {\n const baseUrl = getDownloadBaseUrl();\n const checksumUrl = `${baseUrl}/electron-app-v${version}/checksums.txt`;\n\n try {\n const response = await fetch(checksumUrl);\n if (!response.ok) {\n logger.warn(\"Checksums file not found in release\", { version: version });\n return \"\";\n }\n\n const text = await response.text();\n const binaryName = getBinaryName();\n const platformKey = getPlatformKey();\n\n // Parse checksums.txt format: \"checksum filename\" or \"checksum filename\"\n const lines = text.split(\"\\n\");\n for (const line of lines) {\n const trimmed = line.trim();\n if (!trimmed) {\n continue;\n }\n\n // Match \"checksum filename\" or \"checksum filename\" format\n const match = trimmed.match(/^([a-fA-F0-9]{64})\\s+(.+)$/);\n if (match) {\n const checksum = match[1];\n const filename = match[2];\n\n // Check if this line is for our binary\n if (filename === binaryName || filename.includes(platformKey)) {\n logger.info(\"Found checksum in release\", {\n version: version,\n platform: platformKey,\n checksum: checksum.substring(0, 16) + \"...\",\n });\n return checksum;\n }\n }\n }\n\n logger.warn(\"Platform checksum not found in checksums.txt\", {\n version: version,\n platform: platformKey,\n });\n return \"\";\n } catch (error) {\n const errorMessage = error instanceof Error ? error.message : String(error);\n logger.warn(\"Failed to fetch checksums from release\", {\n version: version,\n error: errorMessage,\n });\n return \"\";\n }\n}\n\n/**\n * Download and install a specific version.\n * @param version - Version to download.\n * @param downloadUrl - URL to download from.\n * @param checksum - Optional checksum to verify (if not provided, will fetch from release).\n */\nasync function downloadAndInstall(\n version: string,\n downloadUrl: string,\n checksum?: string,\n): Promise<void> {\n const versionDir = getElectronAppDir(version);\n const binaryName = getBinaryName();\n\n console.log(`Downloading Muggle Test Electron app v${version}...`);\n console.log(`URL: ${downloadUrl}`);\n\n // Create directory\n if (existsSync(versionDir)) {\n rmSync(versionDir, { recursive: true, force: true });\n }\n mkdirSync(versionDir, { recursive: true });\n\n // Download\n const response = await fetch(downloadUrl);\n if (!response.ok) {\n throw new Error(`Download failed: ${response.status} ${response.statusText}`);\n }\n\n const tempFile = path.join(versionDir, binaryName);\n const fileStream = createWriteStream(tempFile);\n\n if (!response.body) {\n throw new Error(\"No response body\");\n }\n\n await pipeline(response.body as unknown as NodeJS.ReadableStream, fileStream);\n\n console.log(\"Download complete, verifying checksum...\");\n\n // Get checksum (from parameter or fetch from release)\n let expectedChecksum = checksum;\n if (!expectedChecksum) {\n expectedChecksum = await fetchChecksumFromRelease(version);\n }\n\n // Verify checksum\n const checksumResult = await verifyFileChecksum(tempFile, expectedChecksum || \"\");\n\n if (!checksumResult.valid && expectedChecksum) {\n rmSync(versionDir, { recursive: true, force: true });\n throw new Error(\n `Checksum verification failed!\\n` +\n `Expected: ${checksumResult.expected}\\n` +\n `Actual: ${checksumResult.actual}\\n` +\n `The downloaded file may be corrupted or tampered with.`,\n );\n }\n\n if (expectedChecksum) {\n console.log(\"Checksum verified successfully.\");\n } else {\n console.log(\"Warning: No checksum available, skipping verification.\");\n }\n\n console.log(\"Extracting...\");\n\n // Extract based on file type\n if (binaryName.endsWith(\".zip\")) {\n await extractZip(tempFile, versionDir);\n } else if (binaryName.endsWith(\".tar.gz\")) {\n await extractTarGz(tempFile, versionDir);\n }\n\n // Clean up temp file\n rmSync(tempFile, { force: true });\n\n // Save version override\n saveVersionOverride(version);\n\n console.log(`Electron app v${version} installed to ${versionDir}`);\n logger.info(\"Upgrade complete\", { version: version, path: versionDir });\n}\n\n/**\n * Execute the upgrade command.\n * @param options - Command options.\n */\nexport async function upgradeCommand(options: IUpgradeOptions): Promise<void> {\n try {\n // If specific version requested\n if (options.version) {\n const baseUrl = getDownloadBaseUrl();\n const binaryName = getBinaryName();\n const downloadUrl = `${baseUrl}/electron-app-v${options.version}/${binaryName}`;\n\n await downloadAndInstall(options.version, downloadUrl);\n\n // Auto-cleanup old versions (keep current + 1 previous)\n const cleanupResult = cleanupOldVersions({ all: false });\n if (cleanupResult.removed.length > 0) {\n console.log(\n `\\nCleaned up ${cleanupResult.removed.length} old version(s), ` +\n `freed ${formatBytes(cleanupResult.freedBytes)}`,\n );\n }\n return;\n }\n\n // Check for updates\n console.log(\"Checking for updates...\");\n const result = await checkForUpdates();\n\n console.log(`Current version: ${result.currentVersion}`);\n console.log(`Latest version: ${result.latestVersion}`);\n\n if (options.check) {\n if (result.updateAvailable) {\n console.log(\"\\nUpdate available! Run 'muggle-mcp upgrade' to install.\");\n } else {\n console.log(\"\\nYou are on the latest version.\");\n }\n return;\n }\n\n if (!result.updateAvailable && !options.force) {\n console.log(\"\\nYou are already on the latest version.\");\n console.log(\"Use --force to re-download the current version.\");\n return;\n }\n\n if (!result.downloadUrl) {\n throw new Error(\"No download URL available\");\n }\n\n // Download and install\n await downloadAndInstall(result.latestVersion, result.downloadUrl);\n\n // Auto-cleanup old versions (keep current + 1 previous)\n const cleanupResult = cleanupOldVersions({ all: false });\n if (cleanupResult.removed.length > 0) {\n console.log(\n `\\nCleaned up ${cleanupResult.removed.length} old version(s), ` +\n `freed ${formatBytes(cleanupResult.freedBytes)}`,\n );\n }\n } catch (error) {\n const errorMessage = error instanceof Error ? error.message : String(error);\n console.error(`Upgrade failed: ${errorMessage}`);\n logger.error(\"Upgrade failed\", { error: errorMessage });\n process.exit(1);\n }\n}\n","/**\n * CLI entry point for @muggleai/mcp.\n * Provides commands for serving MCP, setup, diagnostics, and authentication.\n */\n\nimport { readFileSync } from \"fs\";\nimport { dirname, resolve } from \"path\";\nimport { fileURLToPath } from \"url\";\n\nimport { Command } from \"commander\";\n\nimport { getLogger } from \"../shared/logger.js\";\n\n/** Directory containing this module. */\nconst __dirname = dirname(fileURLToPath(import.meta.url));\n\n/** Package version read from package.json. */\nconst packageVersion = JSON.parse(\n readFileSync(resolve(__dirname, \"..\", \"package.json\"), \"utf-8\")\n).version as string;\n\nimport { cleanupCommand, versionsCommand } from \"./cleanup.js\";\nimport { doctorCommand } from \"./doctor.js\";\nimport { loginCommand, logoutCommand, statusCommand } from \"./login.js\";\nimport { serveCommand } from \"./serve.js\";\nimport { setupCommand } from \"./setup.js\";\nimport { upgradeCommand } from \"./upgrade.js\";\n\nconst logger = getLogger();\n\n/**\n * Create and configure the CLI program.\n * @returns Configured Commander program.\n */\nfunction createProgram(): Command {\n const program = new Command();\n\n program\n .name(\"muggle-mcp\")\n .description(\"Unified MCP server for Muggle AI - Cloud QA and Local Testing\")\n .version(packageVersion);\n\n // Serve command (main command)\n program\n .command(\"serve\")\n .description(\"Start the MCP server\")\n .option(\"--qa\", \"Only enable Cloud QA tools\")\n .option(\"--local\", \"Only enable Local QA tools\")\n .option(\"--stdio\", \"Use stdio transport (default)\")\n .action(serveCommand);\n\n // Setup command\n program\n .command(\"setup\")\n .description(\"Download/update the Electron app for local testing\")\n .option(\"--force\", \"Force re-download even if already installed\")\n .action(setupCommand);\n\n // Upgrade command\n program\n .command(\"upgrade\")\n .description(\"Check for and install the latest electron-app version\")\n .option(\"--force\", \"Force re-download even if already on latest\")\n .option(\"--check\", \"Check for updates only, don't download\")\n .option(\"--version <version>\", \"Download a specific version (e.g., 1.0.2)\")\n .action(upgradeCommand);\n\n // Versions command\n program\n .command(\"versions\")\n .description(\"List installed electron-app versions\")\n .action(versionsCommand);\n\n // Cleanup command\n program\n .command(\"cleanup\")\n .description(\"Remove old electron-app versions to free disk space\")\n .option(\"--all\", \"Remove all old versions (default: keep one previous)\")\n .option(\"--dry-run\", \"Show what would be deleted without deleting\")\n .action(cleanupCommand);\n\n // Doctor command\n program\n .command(\"doctor\")\n .description(\"Diagnose installation and configuration issues\")\n .action(doctorCommand);\n\n // Login command\n program\n .command(\"login\")\n .description(\"Authenticate with Muggle AI (uses device code flow)\")\n .option(\"--key-name <name>\", \"Name for the API key\")\n .option(\"--key-expiry <expiry>\", \"API key expiry: 30d, 90d, 1y, never\", \"90d\")\n .action(loginCommand);\n\n // Logout command\n program\n .command(\"logout\")\n .description(\"Clear stored credentials\")\n .action(logoutCommand);\n\n // Status command\n program\n .command(\"status\")\n .description(\"Show authentication status\")\n .action(statusCommand);\n\n // Default to serve when no command specified\n program.action(() => {\n serveCommand({ stdio: true });\n });\n\n return program;\n}\n\n/**\n * Run the CLI.\n */\nexport async function runCli(): Promise<void> {\n try {\n const program = createProgram();\n await program.parseAsync(process.argv);\n } catch (error) {\n logger.error(\"CLI error\", {\n error: error instanceof Error ? error.message : String(error),\n });\n process.exit(1);\n }\n}\n","#!/usr/bin/env node\n/**\n * CLI entry point for muggle-mcp.\n */\n\nimport { runCli } from \"./index.js\";\n\nrunCli().catch((error) => {\n console.error(\"Fatal error:\", error instanceof Error ? error.message : String(error));\n process.exit(1);\n});\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/cli/cleanup.ts","../src/cli/doctor.ts","../src/cli/help.ts","../src/cli/login.ts","../src/cli/serve.ts","../src/shared/checksum.ts","../src/cli/setup.ts","../src/cli/upgrade.ts","../src/cli/index.ts","../src/cli/main.ts"],"names":["path","logger","existsSync","cmd","arch","resolve","platform","rmSync","getBinaryName","path4","mkdirSync","compareVersions","extractZip","exec","extractTarGz","createWriteStream","pipeline","cleanupResult","__dirname"],"mappings":"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","file":"cli.js","sourcesContent":["/**\n * Cleanup command - removes old electron-app versions to free disk space.\n */\n\nimport { existsSync, readdirSync, rmSync, statSync } from \"fs\";\nimport * as path from \"path\";\n\nimport { getDataDir, getElectronAppVersion } from \"../shared/config.js\";\nimport { getLogger } from \"../shared/logger.js\";\n\nconst logger = getLogger();\n\n/** Subdirectory name for electron-app versions. */\nconst ELECTRON_APP_DIR = \"electron-app\";\n\n/**\n * Options for the cleanup command.\n */\nexport interface ICleanupOptions {\n /** Remove all versions except current (default: keep current + 1 previous). */\n all?: boolean;\n /** Dry run - show what would be deleted without deleting. */\n dryRun?: boolean;\n}\n\n/**\n * Installed version info.\n */\nexport interface IInstalledVersion {\n /** Version string. */\n version: string;\n /** Full path to version directory. */\n path: string;\n /** Size in bytes. */\n sizeBytes: number;\n /** Whether this is the current active version. */\n isCurrent: boolean;\n}\n\n/**\n * Get the electron-app base directory.\n * @returns Path to ~/.muggle-ai/electron-app\n */\nfunction getElectronAppBaseDir(): string {\n return path.join(getDataDir(), ELECTRON_APP_DIR);\n}\n\n/**\n * Calculate directory size recursively.\n * @param dirPath - Path to directory.\n * @returns Size in bytes.\n */\nfunction getDirectorySize(dirPath: string): number {\n let totalSize = 0;\n\n try {\n const entries = readdirSync(dirPath, { withFileTypes: true });\n\n for (const entry of entries) {\n const fullPath = path.join(dirPath, entry.name);\n\n if (entry.isDirectory()) {\n totalSize += getDirectorySize(fullPath);\n } else if (entry.isFile()) {\n try {\n const stats = statSync(fullPath);\n totalSize += stats.size;\n } catch {\n // Skip files we can't stat\n }\n }\n }\n } catch {\n // Return 0 if we can't read the directory\n }\n\n return totalSize;\n}\n\n/**\n * Format bytes as human-readable string.\n * @param bytes - Size in bytes.\n * @returns Formatted string (e.g., \"150 MB\").\n */\nexport function formatBytes(bytes: number): string {\n if (bytes === 0) {\n return \"0 B\";\n }\n\n const units = [\"B\", \"KB\", \"MB\", \"GB\"];\n const k = 1024;\n const i = Math.floor(Math.log(bytes) / Math.log(k));\n const size = bytes / Math.pow(k, i);\n\n return `${size.toFixed(1)} ${units[i]}`;\n}\n\n/**\n * Compare semver versions.\n * @param a - First version.\n * @param b - Second version.\n * @returns Negative if a < b, positive if a > b, 0 if equal.\n */\nfunction compareVersions(a: string, b: string): number {\n const partsA = a.split(\".\").map(Number);\n const partsB = b.split(\".\").map(Number);\n\n for (let i = 0; i < 3; i++) {\n const partA = partsA[i] || 0;\n const partB = partsB[i] || 0;\n\n if (partA !== partB) {\n return partA - partB;\n }\n }\n\n return 0;\n}\n\n/**\n * List all installed electron-app versions.\n * @returns Array of installed version info, sorted by version descending.\n */\nexport function listInstalledVersions(): IInstalledVersion[] {\n const baseDir = getElectronAppBaseDir();\n const currentVersion = getElectronAppVersion();\n const versions: IInstalledVersion[] = [];\n\n if (!existsSync(baseDir)) {\n return versions;\n }\n\n try {\n const entries = readdirSync(baseDir, { withFileTypes: true });\n\n for (const entry of entries) {\n if (!entry.isDirectory()) {\n continue;\n }\n\n // Check if directory name looks like a version (e.g., \"1.0.1\")\n if (!/^\\d+\\.\\d+\\.\\d+$/.test(entry.name)) {\n continue;\n }\n\n const versionPath = path.join(baseDir, entry.name);\n const sizeBytes = getDirectorySize(versionPath);\n\n versions.push({\n version: entry.name,\n path: versionPath,\n sizeBytes: sizeBytes,\n isCurrent: entry.name === currentVersion,\n });\n }\n } catch (error) {\n const errorMessage = error instanceof Error ? error.message : String(error);\n logger.warn(\"Failed to list installed versions\", { error: errorMessage });\n }\n\n // Sort by version descending (newest first)\n versions.sort((a, b) => compareVersions(b.version, a.version));\n\n return versions;\n}\n\n/**\n * Remove old electron-app versions.\n * @param options - Cleanup options.\n * @returns Object with removed versions and freed bytes.\n */\nexport function cleanupOldVersions(options: ICleanupOptions = {}): {\n removed: IInstalledVersion[];\n freedBytes: number;\n} {\n const { all = false, dryRun = false } = options;\n const versions = listInstalledVersions();\n const removed: IInstalledVersion[] = [];\n let freedBytes = 0;\n\n // Determine which versions to keep\n // - Always keep current version\n // - By default, also keep one previous version (for rollback)\n // - With --all, only keep current\n\n const versionsToKeep = all ? 1 : 2;\n let keptCount = 0;\n\n for (const version of versions) {\n if (version.isCurrent) {\n keptCount++;\n continue;\n }\n\n if (keptCount < versionsToKeep) {\n keptCount++;\n continue;\n }\n\n // This version should be removed\n if (!dryRun) {\n try {\n rmSync(version.path, { recursive: true, force: true });\n logger.info(\"Removed old version\", {\n version: version.version,\n freedBytes: version.sizeBytes,\n });\n } catch (error) {\n const errorMessage = error instanceof Error ? error.message : String(error);\n logger.error(\"Failed to remove version\", {\n version: version.version,\n error: errorMessage,\n });\n continue;\n }\n }\n\n removed.push(version);\n freedBytes += version.sizeBytes;\n }\n\n return { removed: removed, freedBytes: freedBytes };\n}\n\n/**\n * Execute the versions command - list installed versions.\n */\nexport async function versionsCommand(): Promise<void> {\n console.log(\"\\nInstalled Electron App Versions\");\n console.log(\"================================\\n\");\n\n const versions = listInstalledVersions();\n\n if (versions.length === 0) {\n console.log(\"No versions installed.\");\n console.log(\"Run 'muggle-mcp setup' to download the Electron app.\\n\");\n return;\n }\n\n let totalSize = 0;\n\n for (const version of versions) {\n const marker = version.isCurrent ? \" (current)\" : \"\";\n const size = formatBytes(version.sizeBytes);\n console.log(` v${version.version}${marker} - ${size}`);\n totalSize += version.sizeBytes;\n }\n\n console.log(\"\");\n console.log(`Total: ${versions.length} version(s), ${formatBytes(totalSize)}`);\n console.log(\"\");\n}\n\n/**\n * Execute the cleanup command.\n * @param options - Command options.\n */\nexport async function cleanupCommand(options: ICleanupOptions): Promise<void> {\n console.log(\"\\nElectron App Cleanup\");\n console.log(\"====================\\n\");\n\n const versions = listInstalledVersions();\n\n if (versions.length === 0) {\n console.log(\"No versions installed. Nothing to clean up.\\n\");\n return;\n }\n\n if (versions.length === 1) {\n console.log(\"Only the current version is installed. Nothing to clean up.\\n\");\n return;\n }\n\n const currentVersion = versions.find((v) => v.isCurrent);\n const oldVersions = versions.filter((v) => !v.isCurrent);\n\n console.log(`Current version: v${currentVersion?.version || \"unknown\"}`);\n console.log(`Old versions: ${oldVersions.length}`);\n console.log(\"\");\n\n if (options.dryRun) {\n console.log(\"Dry run - showing what would be deleted:\\n\");\n }\n\n const result = cleanupOldVersions(options);\n\n if (result.removed.length === 0) {\n if (options.all) {\n console.log(\"No old versions to remove.\\n\");\n } else {\n console.log(\"Keeping one previous version for rollback.\");\n console.log(\"Use --all to remove all old versions.\\n\");\n }\n return;\n }\n\n console.log(options.dryRun ? \"Would remove:\" : \"Removed:\");\n\n for (const version of result.removed) {\n console.log(` v${version.version} (${formatBytes(version.sizeBytes)})`);\n }\n\n console.log(\"\");\n console.log(\n `${options.dryRun ? \"Would free\" : \"Freed\"}: ${formatBytes(result.freedBytes)}`,\n );\n console.log(\"\");\n\n if (options.dryRun) {\n console.log(\"Run without --dry-run to actually delete.\\n\");\n }\n\n logger.info(\"Cleanup completed\", {\n removed: result.removed.length,\n freedBytes: result.freedBytes,\n dryRun: options.dryRun,\n });\n}\n","/**\n * Doctor command - diagnoses installation and configuration issues.\n */\n\nimport { existsSync } from \"fs\";\n\nimport {\n getBundledElectronAppVersion,\n getConfig,\n getDataDir,\n getElectronAppVersion,\n getElectronAppVersionSource,\n isElectronAppInstalled,\n} from \"../shared/config.js\";\nimport { getAuthStatus, getCredentialsFilePath } from \"../shared/credentials.js\";\nimport { getLogger } from \"../shared/logger.js\";\n\nconst logger = getLogger();\n\n/**\n * Check result with status indicator.\n */\ninterface ICheckResult {\n /** Check name. */\n name: string;\n /** Whether check passed. */\n passed: boolean;\n /** Description of the result. */\n description: string;\n /** Suggestion to fix (if failed). */\n suggestion?: string;\n}\n\n/**\n * Run all diagnostic checks.\n * @returns Array of check results.\n */\nfunction runDiagnostics(): ICheckResult[] {\n const results: ICheckResult[] = [];\n const config = getConfig();\n\n // Check 1: Data directory exists\n const dataDir = getDataDir();\n results.push({\n name: \"Data Directory\",\n passed: existsSync(dataDir),\n description: existsSync(dataDir) ? `Found at ${dataDir}` : `Not found at ${dataDir}`,\n suggestion: \"Run 'muggle-mcp login' to create the data directory\",\n });\n\n // Check 2: Electron app installed\n const electronInstalled = isElectronAppInstalled();\n const electronVersion = getElectronAppVersion();\n const bundledVersion = getBundledElectronAppVersion();\n const versionSource = getElectronAppVersionSource();\n\n let electronDescription: string;\n if (electronInstalled) {\n electronDescription = `Installed (v${electronVersion})`;\n switch (versionSource) {\n case \"env\":\n electronDescription += ` [from ELECTRON_APP_VERSION env]`;\n break;\n case \"override\":\n electronDescription += ` [upgraded from bundled v${bundledVersion}]`;\n break;\n default:\n break;\n }\n } else {\n electronDescription = `Not installed (expected v${electronVersion})`;\n }\n\n results.push({\n name: \"Electron App\",\n passed: electronInstalled,\n description: electronDescription,\n suggestion: \"Run 'muggle-mcp setup' to download the Electron app\",\n });\n\n // Check 2b: Upgrade available hint\n if (electronInstalled) {\n results.push({\n name: \"Electron App Updates\",\n passed: true,\n description: \"Run 'muggle-mcp upgrade --check' to check for updates\",\n });\n }\n\n // Check 3: Authentication status\n const authStatus = getAuthStatus();\n results.push({\n name: \"Authentication\",\n passed: authStatus.authenticated,\n description: authStatus.authenticated\n ? `Authenticated as ${authStatus.email || \"unknown\"}`\n : \"Not authenticated\",\n suggestion: \"Run 'muggle-mcp login' to authenticate\",\n });\n\n // Check 4: API key available\n results.push({\n name: \"API Key\",\n passed: authStatus.hasApiKey,\n description: authStatus.hasApiKey ? \"API key stored\" : \"No API key stored\",\n suggestion: \"Run 'muggle-mcp login' to generate an API key\",\n });\n\n // Check 5: Credentials file\n const credentialsPath = getCredentialsFilePath();\n results.push({\n name: \"Credentials File\",\n passed: existsSync(credentialsPath),\n description: existsSync(credentialsPath)\n ? `Found at ${credentialsPath}`\n : `Not found at ${credentialsPath}`,\n suggestion: \"Run 'muggle-mcp login' to create credentials\",\n });\n\n // Check 6: Prompt service URL\n results.push({\n name: \"Prompt Service URL\",\n passed: !!config.qa.promptServiceBaseUrl,\n description: config.qa.promptServiceBaseUrl,\n });\n\n // Check 7: Web service URL (for local testing)\n results.push({\n name: \"Web Service URL\",\n passed: !!config.localQa.webServiceUrl,\n description: config.localQa.webServiceUrl,\n });\n\n return results;\n}\n\n/**\n * Format a check result for display.\n * @param result - Check result.\n * @returns Formatted string.\n */\nfunction formatCheckResult(result: ICheckResult): string {\n const icon = result.passed ? \"✓\" : \"✗\";\n const color = result.passed ? \"\\x1b[32m\" : \"\\x1b[31m\"; // Green or Red\n const reset = \"\\x1b[0m\";\n\n let output = `${color}${icon}${reset} ${result.name}: ${result.description}`;\n\n if (!result.passed && result.suggestion) {\n output += `\\n └─ ${result.suggestion}`;\n }\n\n return output;\n}\n\n/**\n * Execute the doctor command.\n */\nexport async function doctorCommand(): Promise<void> {\n console.log(\"\\nMuggle MCP Doctor\");\n console.log(\"=================\\n\");\n\n const results = runDiagnostics();\n\n for (const result of results) {\n console.log(formatCheckResult(result));\n }\n\n console.log(\"\");\n\n const failedCount = results.filter((r) => !r.passed).length;\n\n if (failedCount === 0) {\n console.log(\"All checks passed! Your installation is ready.\");\n } else {\n console.log(`${failedCount} issue(s) found. See suggestions above.`);\n }\n\n logger.info(\"Doctor command completed\", {\n totalChecks: results.length,\n passed: results.length - failedCount,\n failed: failedCount,\n });\n}\n","/**\n * Help and usage guidance for muggle-mcp CLI.\n * Provides comprehensive how-to guidance for users.\n */\n\n/**\n * Color codes for terminal output.\n */\nconst COLORS = {\n reset: \"\\x1b[0m\",\n bold: \"\\x1b[1m\",\n dim: \"\\x1b[2m\",\n cyan: \"\\x1b[36m\",\n green: \"\\x1b[32m\",\n yellow: \"\\x1b[33m\",\n blue: \"\\x1b[34m\",\n magenta: \"\\x1b[35m\",\n};\n\n/**\n * Format text with color (respects NO_COLOR environment variable).\n * @param text - Text to format.\n * @param color - Color code to apply.\n * @returns Formatted text.\n */\nfunction colorize(text: string, color: string): string {\n if (process.env.NO_COLOR) {\n return text;\n }\n return `${color}${text}${COLORS.reset}`;\n}\n\n/**\n * Format a section header.\n * @param title - Section title.\n * @returns Formatted header.\n */\nfunction header(title: string): string {\n return colorize(`\\n${title}`, COLORS.bold + COLORS.cyan);\n}\n\n/**\n * Format a command example.\n * @param cmd - Command to format.\n * @returns Formatted command.\n */\nfunction cmd(cmd: string): string {\n return colorize(cmd, COLORS.green);\n}\n\n/**\n * Format a path or filename.\n * @param path - Path to format.\n * @returns Formatted path.\n */\nfunction path(path: string): string {\n return colorize(path, COLORS.yellow);\n}\n\n/**\n * Get the post-install usage guidance message.\n * @returns Usage guidance string for postinstall.\n */\nexport function getPostInstallGuidance(): string {\n const lines = [\n \"\",\n colorize(\"=\".repeat(60), COLORS.cyan),\n colorize(\" Muggle AI MCP - Installation Complete!\", COLORS.bold + COLORS.green),\n colorize(\"=\".repeat(60), COLORS.cyan),\n \"\",\n header(\"Quick Start\"),\n \"\",\n \" 1. Configure your MCP client (e.g., Cursor):\",\n \"\",\n ` Add to ${path(\"~/.cursor/mcp.json\")}:`,\n \"\",\n ` ${colorize(\"{\", COLORS.dim)}`,\n ` ${colorize('\"mcpServers\"', COLORS.yellow)}: {`,\n ` ${colorize('\"muggle\"', COLORS.yellow)}: {`,\n ` ${colorize('\"command\"', COLORS.yellow)}: ${colorize('\"muggle-mcp\"', COLORS.green)},`,\n ` ${colorize('\"args\"', COLORS.yellow)}: [${colorize('\"serve\"', COLORS.green)}]`,\n ` }`,\n ` }`,\n ` ${colorize(\"}\", COLORS.dim)}`,\n \"\",\n \" 2. Restart your MCP client to load the new tools\",\n \"\",\n \" 3. Ask your AI assistant to test your application!\",\n \"\",\n header(\"Useful Commands\"),\n \"\",\n ` ${cmd(\"muggle-mcp help\")} Show detailed how-to guidance`,\n ` ${cmd(\"muggle-mcp doctor\")} Check installation health`,\n ` ${cmd(\"muggle-mcp status\")} Check authentication status`,\n ` ${cmd(\"muggle-mcp login\")} Login to Muggle AI`,\n \"\",\n header(\"Documentation\"),\n \"\",\n ` ${colorize(\"https://www.muggle-ai.com/muggleTestV0/docs/mcp/mcp-overview\", COLORS.blue)}`,\n \"\",\n colorize(\"=\".repeat(60), COLORS.cyan),\n \"\",\n ];\n\n return lines.join(\"\\n\");\n}\n\n/**\n * Get the comprehensive help guidance message.\n * @returns Full help guidance string.\n */\nexport function getHelpGuidance(): string {\n const lines = [\n \"\",\n colorize(\"=\".repeat(70), COLORS.cyan),\n colorize(\" Muggle AI MCP - Comprehensive How-To Guide\", COLORS.bold + COLORS.green),\n colorize(\"=\".repeat(70), COLORS.cyan),\n \"\",\n header(\"What is Muggle AI MCP?\"),\n \"\",\n \" Muggle AI MCP is a Model Context Protocol server that provides AI\",\n \" assistants with tools to perform automated QA testing of web applications.\",\n \"\",\n \" It supports both:\",\n ` ${colorize(\"•\", COLORS.green)} Cloud QA - Test remote production/staging sites`,\n ` ${colorize(\"•\", COLORS.green)} Local QA - Test localhost development servers`,\n \"\",\n header(\"Setup Instructions\"),\n \"\",\n ` ${colorize(\"Step 1:\", COLORS.bold)} Configure your MCP client`,\n \"\",\n ` For ${colorize(\"Cursor\", COLORS.bold)}, edit ${path(\"~/.cursor/mcp.json\")}:`,\n \"\",\n ` ${colorize(\"{\", COLORS.dim)}`,\n ` ${colorize('\"mcpServers\"', COLORS.yellow)}: {`,\n ` ${colorize('\"muggle\"', COLORS.yellow)}: {`,\n ` ${colorize('\"command\"', COLORS.yellow)}: ${colorize('\"muggle-mcp\"', COLORS.green)},`,\n ` ${colorize('\"args\"', COLORS.yellow)}: [${colorize('\"serve\"', COLORS.green)}]`,\n ` }`,\n ` }`,\n ` ${colorize(\"}\", COLORS.dim)}`,\n \"\",\n ` ${colorize(\"Step 2:\", COLORS.bold)} Restart your MCP client`,\n \"\",\n ` ${colorize(\"Step 3:\", COLORS.bold)} Start testing! Ask your AI assistant:`,\n ` ${colorize('\"Test the login flow on my app at http://localhost:3000\"', COLORS.dim)}`,\n \"\",\n header(\"CLI Commands\"),\n \"\",\n ` ${colorize(\"Server Commands:\", COLORS.bold)}`,\n ` ${cmd(\"muggle-mcp\")} Start MCP server (default)`,\n ` ${cmd(\"muggle-mcp serve\")} Start MCP server with all tools`,\n ` ${cmd(\"muggle-mcp serve --qa\")} Start with Cloud QA tools only`,\n ` ${cmd(\"muggle-mcp serve --local\")} Start with Local QA tools only`,\n \"\",\n ` ${colorize(\"Setup & Diagnostics:\", COLORS.bold)}`,\n ` ${cmd(\"muggle-mcp setup\")} Download/update Electron app`,\n ` ${cmd(\"muggle-mcp setup --force\")} Force re-download`,\n ` ${cmd(\"muggle-mcp doctor\")} Diagnose installation issues`,\n ` ${cmd(\"muggle-mcp upgrade\")} Check for updates`,\n ` ${cmd(\"muggle-mcp upgrade --check\")} Check updates without installing`,\n \"\",\n ` ${colorize(\"Authentication:\", COLORS.bold)}`,\n ` ${cmd(\"muggle-mcp login\")} Login to Muggle AI`,\n ` ${cmd(\"muggle-mcp logout\")} Clear stored credentials`,\n ` ${cmd(\"muggle-mcp status\")} Show authentication status`,\n \"\",\n ` ${colorize(\"Maintenance:\", COLORS.bold)}`,\n ` ${cmd(\"muggle-mcp versions\")} List installed Electron app versions`,\n ` ${cmd(\"muggle-mcp cleanup\")} Remove old Electron app versions`,\n ` ${cmd(\"muggle-mcp cleanup --all\")} Remove all old versions`,\n \"\",\n ` ${colorize(\"Help:\", COLORS.bold)}`,\n ` ${cmd(\"muggle-mcp help\")} Show this guide`,\n ` ${cmd(\"muggle-mcp --help\")} Show command synopsis`,\n ` ${cmd(\"muggle-mcp --version\")} Show version`,\n \"\",\n header(\"Authentication Flow\"),\n \"\",\n \" Authentication happens automatically when you first use a tool that\",\n \" requires it:\",\n \"\",\n ` 1. ${colorize(\"A browser window opens\", COLORS.bold)} with a verification code`,\n ` 2. ${colorize(\"Log in\", COLORS.bold)} with your Muggle AI account`,\n ` 3. ${colorize(\"The tool call continues\", COLORS.bold)} with your credentials`,\n \"\",\n ` Credentials are stored in ${path(\"~/.muggle-ai/credentials.json\")}`,\n \"\",\n header(\"Available MCP Tools\"),\n \"\",\n ` ${colorize(\"Cloud QA Tools:\", COLORS.bold)} (prefix: qa_)`,\n \" qa_project_create, qa_project_list, qa_use_case_create_from_prompts,\",\n \" qa_test_case_generate_from_prompt, qa_workflow_start_*, etc.\",\n \"\",\n ` ${colorize(\"Local QA Tools:\", COLORS.bold)} (prefix: muggle_)`,\n \" muggle_project_create, muggle_test_case_save,\",\n \" muggle_execute_test_generation, muggle_execute_replay,\",\n \" muggle_cloud_pull_project, muggle_publish_project, etc.\",\n \"\",\n header(\"Data Directory\"),\n \"\",\n ` All data is stored in ${path(\"~/.muggle-ai/\")}:`,\n \"\",\n ` ${path(\"credentials.json\")} Auth credentials (auto-generated)`,\n ` ${path(\"projects/\")} Local test projects`,\n ` ${path(\"sessions/\")} Test execution sessions`,\n ` ${path(\"electron-app/\")} Downloaded Electron app binaries`,\n \"\",\n header(\"Troubleshooting\"),\n \"\",\n ` ${colorize(\"Installation issues:\", COLORS.bold)}`,\n ` Run ${cmd(\"muggle-mcp doctor\")} to diagnose problems`,\n \"\",\n ` ${colorize(\"Electron app not found:\", COLORS.bold)}`,\n ` Run ${cmd(\"muggle-mcp setup --force\")} to re-download`,\n \"\",\n ` ${colorize(\"Authentication issues:\", COLORS.bold)}`,\n ` Run ${cmd(\"muggle-mcp logout\")} then ${cmd(\"muggle-mcp login\")}`,\n \"\",\n ` ${colorize(\"MCP not working in client:\", COLORS.bold)}`,\n \" 1. Verify mcp.json configuration\",\n \" 2. Restart your MCP client\",\n ` 3. Check ${cmd(\"muggle-mcp doctor\")} output`,\n \"\",\n header(\"Documentation & Support\"),\n \"\",\n ` Docs: ${colorize(\"https://www.muggle-ai.com/muggleTestV0/docs/mcp/mcp-overview\", COLORS.blue)}`,\n ` GitHub: ${colorize(\"https://github.com/multiplex-ai/muggle-ai-mcp\", COLORS.blue)}`,\n \"\",\n colorize(\"=\".repeat(70), COLORS.cyan),\n \"\",\n ];\n\n return lines.join(\"\\n\");\n}\n\n/**\n * Help command handler.\n * Prints comprehensive how-to guidance.\n */\nexport function helpCommand(): void {\n console.log(getHelpGuidance());\n}\n","/**\n * Login/logout/status commands for authentication.\n */\n\nimport { performLogin, performLogout } from \"../shared/auth.js\";\nimport { getAuthStatus } from \"../shared/credentials.js\";\nimport { getLogger } from \"../shared/logger.js\";\n\nconst logger = getLogger();\n\n/**\n * Options for the login command.\n */\nexport interface ILoginOptions {\n /** Name for the API key. */\n keyName?: string;\n /** API key expiry: 30d, 90d, 1y, never. */\n keyExpiry?: string;\n}\n\n/**\n * Execute the login command.\n * @param options - Command options.\n */\nexport async function loginCommand(options: ILoginOptions): Promise<void> {\n console.log(\"\\nMuggle AI Login\");\n console.log(\"===============\\n\");\n\n const expiry = (options.keyExpiry || \"90d\") as \"30d\" | \"90d\" | \"1y\" | \"never\";\n\n console.log(\"Starting device code authentication...\");\n console.log(\"A browser window will open for you to complete login.\\n\");\n\n const result = await performLogin(options.keyName, expiry);\n\n if (result.success) {\n console.log(\"✓ Login successful!\");\n\n if (result.credentials?.email) {\n console.log(` Logged in as: ${result.credentials.email}`);\n }\n\n if (result.credentials?.apiKey) {\n console.log(\" API key created and stored for future use.\");\n }\n\n console.log(\"\\nYou can now use Muggle AI MCP tools.\");\n } else {\n console.error(\"✗ Login failed\");\n\n if (result.error) {\n console.error(` Error: ${result.error}`);\n }\n\n if (result.deviceCodeResponse) {\n console.log(\"\\nIf browser didn't open, visit:\");\n console.log(` ${result.deviceCodeResponse.verificationUriComplete}`);\n console.log(` Code: ${result.deviceCodeResponse.userCode}`);\n }\n\n process.exit(1);\n }\n}\n\n/**\n * Execute the logout command.\n */\nexport async function logoutCommand(): Promise<void> {\n console.log(\"\\nLogging out...\");\n\n performLogout();\n\n console.log(\"✓ Credentials cleared successfully.\");\n logger.info(\"Logout completed\");\n}\n\n/**\n * Execute the status command.\n */\nexport async function statusCommand(): Promise<void> {\n console.log(\"\\nAuthentication Status\");\n console.log(\"=====================\\n\");\n\n const status = getAuthStatus();\n\n if (status.authenticated) {\n console.log(\"✓ Authenticated\");\n\n if (status.email) {\n console.log(` Email: ${status.email}`);\n }\n\n if (status.userId) {\n console.log(` User ID: ${status.userId}`);\n }\n\n if (status.expiresAt) {\n const expiresDate = new Date(status.expiresAt);\n console.log(` Token expires: ${expiresDate.toLocaleString()}`);\n }\n\n console.log(` API Key: ${status.hasApiKey ? \"Yes\" : \"No\"}`);\n } else {\n console.log(\"✗ Not authenticated\");\n console.log(\"\\nRun 'muggle-mcp login' to authenticate.\");\n }\n}\n","/**\n * Serve command - starts the MCP server.\n */\n\nimport { getLocalQaTools } from \"../local-qa/index.js\";\nimport { getQaTools } from \"../qa/index.js\";\nimport { getConfig } from \"../shared/config.js\";\nimport { getLogger } from \"../shared/logger.js\";\nimport { createUnifiedMcpServer, registerTools, startStdioServer } from \"../server/index.js\";\n\nconst logger = getLogger();\n\n/**\n * Options for the serve command.\n */\nexport interface IServeOptions {\n /** Only enable Cloud QA tools. */\n qa?: boolean;\n /** Only enable Local QA tools. */\n local?: boolean;\n /** Use stdio transport. */\n stdio?: boolean;\n}\n\n/**\n * Execute the serve command.\n * @param options - Command options.\n */\nexport async function serveCommand(options: IServeOptions): Promise<void> {\n const config = getConfig();\n\n // Determine which tool sets to enable\n const enableQa = options.local ? false : true;\n const enableLocal = options.qa ? false : true;\n\n logger.info(\"Starting Muggle MCP Server\", {\n version: config.serverVersion,\n enableQa: enableQa,\n enableLocal: enableLocal,\n transport: \"stdio\",\n });\n\n try {\n // Register tools based on options\n if (enableQa) {\n const qaTools = getQaTools();\n registerTools(qaTools);\n logger.info(\"Registered QA tools\", { count: qaTools.length });\n }\n\n if (enableLocal) {\n const localTools = getLocalQaTools();\n registerTools(localTools);\n logger.info(\"Registered Local QA tools\", { count: localTools.length });\n }\n\n // Create unified MCP server\n const mcpServer = createUnifiedMcpServer({\n enableQaTools: enableQa,\n enableLocalTools: enableLocal,\n });\n\n // Start stdio server (MCP clients communicate via stdin/stdout)\n await startStdioServer(mcpServer);\n\n logger.info(\"MCP server started successfully\");\n } catch (error) {\n logger.error(\"Failed to start MCP server\", {\n error: error instanceof Error ? error.message : String(error),\n stack: error instanceof Error ? error.stack : undefined,\n });\n process.exit(1);\n }\n}\n","/**\n * Checksum verification utilities for downloaded binaries.\n * Uses SHA256 for integrity verification.\n */\n\nimport * as crypto from \"crypto\";\nimport * as fs from \"fs\";\nimport * as path from \"path\";\nimport { platform } from \"os\";\n\nimport { getLogger } from \"./logger.js\";\n\nconst logger = getLogger();\n\n/**\n * Platform key for checksum lookup.\n */\nexport type PlatformKey = \"darwin-arm64\" | \"darwin-x64\" | \"win32-x64\" | \"linux-x64\";\n\n/**\n * Checksums map from package.json muggleConfig.\n */\nexport interface IChecksums {\n /** macOS ARM64 (Apple Silicon) checksum. */\n \"darwin-arm64\"?: string;\n /** macOS x64 (Intel) checksum. */\n \"darwin-x64\"?: string;\n /** Windows x64 checksum. */\n \"win32-x64\"?: string;\n /** Linux x64 checksum. */\n \"linux-x64\"?: string;\n}\n\n/**\n * Result of checksum verification.\n */\nexport interface IChecksumResult {\n /** Whether verification passed. */\n valid: boolean;\n /** Expected checksum (from config or release). */\n expected: string;\n /** Actual checksum of downloaded file. */\n actual: string;\n /** Error message if verification failed. */\n error?: string;\n}\n\n/**\n * Get the platform key for the current system.\n * @returns The platform key for checksum lookup.\n */\nexport function getPlatformKey(): PlatformKey {\n const os = platform();\n const arch = process.arch;\n\n switch (os) {\n case \"darwin\":\n return arch === \"arm64\" ? \"darwin-arm64\" : \"darwin-x64\";\n case \"win32\":\n return \"win32-x64\";\n case \"linux\":\n return \"linux-x64\";\n default:\n throw new Error(`Unsupported platform: ${os}`);\n }\n}\n\n/**\n * Calculate SHA256 checksum of a file.\n * @param filePath - Path to the file.\n * @returns The SHA256 checksum as a hex string.\n */\nexport async function calculateFileChecksum(filePath: string): Promise<string> {\n return new Promise((resolve, reject) => {\n const hash = crypto.createHash(\"sha256\");\n const stream = fs.createReadStream(filePath);\n\n stream.on(\"data\", (data) => {\n hash.update(data);\n });\n\n stream.on(\"end\", () => {\n resolve(hash.digest(\"hex\"));\n });\n\n stream.on(\"error\", (error) => {\n reject(error);\n });\n });\n}\n\n/**\n * Verify file checksum against expected value.\n * @param filePath - Path to the file to verify.\n * @param expectedChecksum - Expected SHA256 checksum.\n * @returns Verification result.\n */\nexport async function verifyFileChecksum(\n filePath: string,\n expectedChecksum: string,\n): Promise<IChecksumResult> {\n if (!expectedChecksum || expectedChecksum.trim() === \"\") {\n logger.warn(\"Checksum verification skipped - no checksum provided\", {\n file: path.basename(filePath),\n });\n return {\n valid: true,\n expected: \"\",\n actual: \"\",\n error: \"Checksum verification skipped - no checksum configured\",\n };\n }\n\n try {\n const actualChecksum = await calculateFileChecksum(filePath);\n const normalizedExpected = expectedChecksum.toLowerCase().trim();\n const normalizedActual = actualChecksum.toLowerCase();\n\n const valid = normalizedExpected === normalizedActual;\n\n if (!valid) {\n logger.error(\"Checksum verification failed\", {\n file: path.basename(filePath),\n expected: normalizedExpected,\n actual: normalizedActual,\n });\n } else {\n logger.info(\"Checksum verified successfully\", {\n file: path.basename(filePath),\n checksum: normalizedActual,\n });\n }\n\n return {\n valid: valid,\n expected: normalizedExpected,\n actual: normalizedActual,\n error: valid ? undefined : \"Checksum mismatch - file may be corrupted or tampered with\",\n };\n } catch (error) {\n const errorMessage = error instanceof Error ? error.message : String(error);\n logger.error(\"Checksum calculation failed\", {\n file: path.basename(filePath),\n error: errorMessage,\n });\n\n return {\n valid: false,\n expected: expectedChecksum,\n actual: \"\",\n error: `Failed to calculate checksum: ${errorMessage}`,\n };\n }\n}\n\n/**\n * Get checksum for current platform from checksums map.\n * @param checksums - Checksums map from config.\n * @returns Checksum for current platform, or empty string if not found.\n */\nexport function getChecksumForPlatform(checksums: IChecksums | undefined): string {\n if (!checksums) {\n return \"\";\n }\n\n const platformKey = getPlatformKey();\n return checksums[platformKey] || \"\";\n}\n","/**\n * Setup command - downloads/updates the Electron app.\n */\n\nimport { exec } from \"child_process\";\nimport { createWriteStream, existsSync, mkdirSync, rmSync } from \"fs\";\nimport { arch, platform } from \"os\";\nimport { pipeline } from \"stream/promises\";\n\nimport {\n getDownloadBaseUrl,\n getElectronAppChecksums,\n getElectronAppDir,\n getElectronAppVersion,\n isElectronAppInstalled,\n} from \"../shared/config.js\";\nimport { getChecksumForPlatform, verifyFileChecksum } from \"../shared/checksum.js\";\nimport { getLogger } from \"../shared/logger.js\";\n\nconst logger = getLogger();\n\n/**\n * Options for the setup command.\n */\nexport interface ISetupOptions {\n /** Force re-download even if already installed. */\n force?: boolean;\n}\n\n/**\n * Get platform-specific binary name.\n * @returns Binary filename.\n */\nfunction getBinaryName(): string {\n const os = platform();\n const architecture = arch();\n\n switch (os) {\n case \"darwin\": {\n const darwinArch = architecture === \"arm64\" ? \"arm64\" : \"x64\";\n return `MuggleAI-darwin-${darwinArch}.zip`;\n }\n case \"win32\":\n return \"MuggleAI-win32-x64.zip\";\n case \"linux\":\n return \"MuggleAI-linux-x64.zip\";\n default:\n throw new Error(`Unsupported platform: ${os}`);\n }\n}\n\n/**\n * Extract a zip file.\n * @param zipPath - Path to zip file.\n * @param destDir - Destination directory.\n */\nasync function extractZip(zipPath: string, destDir: string): Promise<void> {\n return new Promise((resolve, reject) => {\n const cmd =\n platform() === \"win32\"\n ? `powershell -command \"Expand-Archive -Path '${zipPath}' -DestinationPath '${destDir}' -Force\"`\n : `unzip -o \"${zipPath}\" -d \"${destDir}\"`;\n\n exec(cmd, (error) => {\n if (error) {\n reject(error);\n } else {\n resolve();\n }\n });\n });\n}\n\n/**\n * Extract a tar.gz file.\n * @param tarPath - Path to tar.gz file.\n * @param destDir - Destination directory.\n */\nasync function extractTarGz(tarPath: string, destDir: string): Promise<void> {\n return new Promise((resolve, reject) => {\n exec(`tar -xzf \"${tarPath}\" -C \"${destDir}\"`, (error) => {\n if (error) {\n reject(error);\n } else {\n resolve();\n }\n });\n });\n}\n\n/**\n * Execute the setup command.\n * @param options - Command options.\n */\nexport async function setupCommand(options: ISetupOptions): Promise<void> {\n const version = getElectronAppVersion();\n const baseUrl = getDownloadBaseUrl();\n const versionDir = getElectronAppDir(version);\n\n // Check if already installed\n if (!options.force && isElectronAppInstalled()) {\n console.log(`Electron app v${version} is already installed at ${versionDir}`);\n console.log(\"Use --force to re-download.\");\n return;\n }\n\n const binaryName = getBinaryName();\n const downloadUrl = `${baseUrl}/v${version}/${binaryName}`;\n\n console.log(`Downloading Muggle Test Electron app v${version}...`);\n console.log(`URL: ${downloadUrl}`);\n\n try {\n // Create directory\n if (existsSync(versionDir)) {\n rmSync(versionDir, { recursive: true, force: true });\n }\n mkdirSync(versionDir, { recursive: true });\n\n // Download\n const response = await fetch(downloadUrl);\n if (!response.ok) {\n throw new Error(`Download failed: ${response.status} ${response.statusText}`);\n }\n\n const tempFile = `${versionDir}/${binaryName}`;\n const fileStream = createWriteStream(tempFile);\n\n if (!response.body) {\n throw new Error(\"No response body\");\n }\n\n await pipeline(response.body as unknown as NodeJS.ReadableStream, fileStream);\n\n console.log(\"Download complete, verifying checksum...\");\n\n // Verify checksum\n const checksums = getElectronAppChecksums();\n const expectedChecksum = getChecksumForPlatform(checksums);\n const checksumResult = await verifyFileChecksum(tempFile, expectedChecksum);\n\n if (!checksumResult.valid && expectedChecksum) {\n rmSync(versionDir, { recursive: true, force: true });\n throw new Error(\n `Checksum verification failed!\\n` +\n `Expected: ${checksumResult.expected}\\n` +\n `Actual: ${checksumResult.actual}\\n` +\n `The downloaded file may be corrupted or tampered with.`,\n );\n }\n\n if (expectedChecksum) {\n console.log(\"Checksum verified successfully.\");\n } else {\n console.log(\"Warning: No checksum configured, skipping verification.\");\n }\n\n console.log(\"Extracting...\");\n\n // Extract based on file type\n if (binaryName.endsWith(\".zip\")) {\n await extractZip(tempFile, versionDir);\n } else if (binaryName.endsWith(\".tar.gz\")) {\n await extractTarGz(tempFile, versionDir);\n }\n\n // Clean up temp file\n rmSync(tempFile, { force: true });\n\n console.log(`Electron app installed to ${versionDir}`);\n logger.info(\"Setup complete\", { version: version, path: versionDir });\n } catch (error) {\n const errorMessage = error instanceof Error ? error.message : String(error);\n console.error(`Failed to download Electron app: ${errorMessage}`);\n logger.error(\"Setup failed\", { error: errorMessage });\n process.exit(1);\n }\n}\n","/**\n * Upgrade command - checks for and downloads the latest electron-app version.\n * Allows users to get newer electron-app versions independently of MCP updates.\n */\n\nimport { exec } from \"child_process\";\nimport { createWriteStream, existsSync, mkdirSync, rmSync, writeFileSync } from \"fs\";\nimport { platform } from \"os\";\nimport * as path from \"path\";\nimport { pipeline } from \"stream/promises\";\n\nimport {\n getDataDir,\n getDownloadBaseUrl,\n getElectronAppDir,\n getElectronAppVersion,\n} from \"../shared/config.js\";\nimport { getPlatformKey, verifyFileChecksum } from \"../shared/checksum.js\";\nimport { getLogger } from \"../shared/logger.js\";\nimport { cleanupOldVersions, formatBytes } from \"./cleanup.js\";\n\nconst logger = getLogger();\n\n/** GitHub API URL for releases. */\nconst GITHUB_RELEASES_API = \"https://api.github.com/repos/multiplex-ai/muggle-ai-mcp/releases\";\n\n/** Filename for storing the overridden electron-app version. */\nconst VERSION_OVERRIDE_FILE = \"electron-app-version-override.json\";\n\n/**\n * Options for the upgrade command.\n */\nexport interface IUpgradeOptions {\n /** Force re-download even if already on latest. */\n force?: boolean;\n /** Check for updates only, don't download. */\n check?: boolean;\n /** Specific version to download (e.g., \"1.0.2\"). */\n version?: string;\n}\n\n/**\n * Result of checking for updates.\n */\ninterface IUpdateCheckResult {\n /** Currently installed version. */\n currentVersion: string;\n /** Latest available version. */\n latestVersion: string;\n /** Whether an update is available. */\n updateAvailable: boolean;\n /** Download URL for the latest version. */\n downloadUrl?: string;\n}\n\n/**\n * Get platform-specific binary name.\n * @returns Binary filename.\n */\nfunction getBinaryName(): string {\n const os = platform();\n const arch = process.arch;\n\n switch (os) {\n case \"darwin\":\n return arch === \"arm64\"\n ? \"MuggleAI-darwin-arm64.zip\"\n : \"MuggleAI-darwin-x64.zip\";\n case \"win32\":\n return \"MuggleAI-win32-x64.zip\";\n case \"linux\":\n return \"MuggleAI-linux-x64.zip\";\n default:\n throw new Error(`Unsupported platform: ${os}`);\n }\n}\n\n/**\n * Extract version from release tag.\n * @param tag - Release tag (e.g., \"electron-app-v1.0.2\").\n * @returns Version string (e.g., \"1.0.2\") or null.\n */\nfunction extractVersionFromTag(tag: string): string | null {\n const match = tag.match(/^electron-app-v(\\d+\\.\\d+\\.\\d+)$/);\n return match ? match[1] : null;\n}\n\n/**\n * Get the path to the version override file.\n * @returns Path to the override file.\n */\nfunction getVersionOverridePath(): string {\n return path.join(getDataDir(), VERSION_OVERRIDE_FILE);\n}\n\n/**\n * Get the effective electron-app version (override or default).\n * @returns The version to use.\n */\nexport function getEffectiveElectronAppVersion(): string {\n const overridePath = getVersionOverridePath();\n\n if (existsSync(overridePath)) {\n try {\n const content = JSON.parse(require(\"fs\").readFileSync(overridePath, \"utf-8\"));\n if (content.version) {\n return content.version;\n }\n } catch {\n // Fall through to default\n }\n }\n\n return getElectronAppVersion();\n}\n\n/**\n * Save the version override.\n * @param version - Version to save.\n */\nfunction saveVersionOverride(version: string): void {\n const overridePath = getVersionOverridePath();\n const dataDir = getDataDir();\n\n if (!existsSync(dataDir)) {\n mkdirSync(dataDir, { recursive: true });\n }\n\n writeFileSync(overridePath, JSON.stringify({\n version: version,\n updatedAt: new Date().toISOString(),\n }, null, 2), \"utf-8\");\n}\n\n/**\n * Check for the latest electron-app version from GitHub releases.\n * @returns Update check result.\n */\nasync function checkForUpdates(): Promise<IUpdateCheckResult> {\n const currentVersion = getEffectiveElectronAppVersion();\n\n try {\n const response = await fetch(GITHUB_RELEASES_API, {\n headers: {\n \"Accept\": \"application/vnd.github.v3+json\",\n \"User-Agent\": \"muggle-mcp\",\n },\n });\n\n if (!response.ok) {\n throw new Error(`GitHub API error: ${response.status} ${response.statusText}`);\n }\n\n const releases = await response.json() as Array<{\n tag_name: string;\n prerelease: boolean;\n draft: boolean;\n }>;\n\n // Find latest electron-app release (non-prerelease, non-draft)\n for (const release of releases) {\n if (release.prerelease || release.draft) {\n continue;\n }\n\n const version = extractVersionFromTag(release.tag_name);\n if (version) {\n const updateAvailable = compareVersions(version, currentVersion) > 0;\n const baseUrl = getDownloadBaseUrl();\n const binaryName = getBinaryName();\n\n return {\n currentVersion: currentVersion,\n latestVersion: version,\n updateAvailable: updateAvailable,\n downloadUrl: `${baseUrl}/electron-app-v${version}/${binaryName}`,\n };\n }\n }\n\n // No electron-app releases found\n return {\n currentVersion: currentVersion,\n latestVersion: currentVersion,\n updateAvailable: false,\n };\n } catch (error) {\n const errorMessage = error instanceof Error ? error.message : String(error);\n logger.warn(\"Failed to check for updates\", { error: errorMessage });\n throw new Error(`Failed to check for updates: ${errorMessage}`);\n }\n}\n\n/**\n * Compare two semver versions.\n * @param a - First version.\n * @param b - Second version.\n * @returns 1 if a > b, -1 if a < b, 0 if equal.\n */\nfunction compareVersions(a: string, b: string): number {\n const partsA = a.split(\".\").map(Number);\n const partsB = b.split(\".\").map(Number);\n\n for (let i = 0; i < 3; i++) {\n const partA = partsA[i] || 0;\n const partB = partsB[i] || 0;\n\n if (partA > partB) {\n return 1;\n }\n if (partA < partB) {\n return -1;\n }\n }\n\n return 0;\n}\n\n/**\n * Extract a zip file.\n * @param zipPath - Path to zip file.\n * @param destDir - Destination directory.\n */\nasync function extractZip(zipPath: string, destDir: string): Promise<void> {\n return new Promise((resolve, reject) => {\n const cmd =\n platform() === \"win32\"\n ? `powershell -command \"Expand-Archive -Path '${zipPath}' -DestinationPath '${destDir}' -Force\"`\n : `unzip -o \"${zipPath}\" -d \"${destDir}\"`;\n\n exec(cmd, (error) => {\n if (error) {\n reject(error);\n } else {\n resolve();\n }\n });\n });\n}\n\n/**\n * Extract a tar.gz file.\n * @param tarPath - Path to tar.gz file.\n * @param destDir - Destination directory.\n */\nasync function extractTarGz(tarPath: string, destDir: string): Promise<void> {\n return new Promise((resolve, reject) => {\n exec(`tar -xzf \"${tarPath}\" -C \"${destDir}\"`, (error) => {\n if (error) {\n reject(error);\n } else {\n resolve();\n }\n });\n });\n}\n\n/**\n * Fetch checksum for a specific version and platform from the release.\n * Looks for checksums.txt in the release assets.\n * @param version - Version to get checksum for.\n * @returns The checksum or empty string if not available.\n */\nasync function fetchChecksumFromRelease(version: string): Promise<string> {\n const baseUrl = getDownloadBaseUrl();\n const checksumUrl = `${baseUrl}/electron-app-v${version}/checksums.txt`;\n\n try {\n const response = await fetch(checksumUrl);\n if (!response.ok) {\n logger.warn(\"Checksums file not found in release\", { version: version });\n return \"\";\n }\n\n const text = await response.text();\n const binaryName = getBinaryName();\n const platformKey = getPlatformKey();\n\n // Parse checksums.txt format: \"checksum filename\" or \"checksum filename\"\n const lines = text.split(\"\\n\");\n for (const line of lines) {\n const trimmed = line.trim();\n if (!trimmed) {\n continue;\n }\n\n // Match \"checksum filename\" or \"checksum filename\" format\n const match = trimmed.match(/^([a-fA-F0-9]{64})\\s+(.+)$/);\n if (match) {\n const checksum = match[1];\n const filename = match[2];\n\n // Check if this line is for our binary\n if (filename === binaryName || filename.includes(platformKey)) {\n logger.info(\"Found checksum in release\", {\n version: version,\n platform: platformKey,\n checksum: checksum.substring(0, 16) + \"...\",\n });\n return checksum;\n }\n }\n }\n\n logger.warn(\"Platform checksum not found in checksums.txt\", {\n version: version,\n platform: platformKey,\n });\n return \"\";\n } catch (error) {\n const errorMessage = error instanceof Error ? error.message : String(error);\n logger.warn(\"Failed to fetch checksums from release\", {\n version: version,\n error: errorMessage,\n });\n return \"\";\n }\n}\n\n/**\n * Download and install a specific version.\n * @param version - Version to download.\n * @param downloadUrl - URL to download from.\n * @param checksum - Optional checksum to verify (if not provided, will fetch from release).\n */\nasync function downloadAndInstall(\n version: string,\n downloadUrl: string,\n checksum?: string,\n): Promise<void> {\n const versionDir = getElectronAppDir(version);\n const binaryName = getBinaryName();\n\n console.log(`Downloading Muggle Test Electron app v${version}...`);\n console.log(`URL: ${downloadUrl}`);\n\n // Create directory\n if (existsSync(versionDir)) {\n rmSync(versionDir, { recursive: true, force: true });\n }\n mkdirSync(versionDir, { recursive: true });\n\n // Download\n const response = await fetch(downloadUrl);\n if (!response.ok) {\n throw new Error(`Download failed: ${response.status} ${response.statusText}`);\n }\n\n const tempFile = path.join(versionDir, binaryName);\n const fileStream = createWriteStream(tempFile);\n\n if (!response.body) {\n throw new Error(\"No response body\");\n }\n\n await pipeline(response.body as unknown as NodeJS.ReadableStream, fileStream);\n\n console.log(\"Download complete, verifying checksum...\");\n\n // Get checksum (from parameter or fetch from release)\n let expectedChecksum = checksum;\n if (!expectedChecksum) {\n expectedChecksum = await fetchChecksumFromRelease(version);\n }\n\n // Verify checksum\n const checksumResult = await verifyFileChecksum(tempFile, expectedChecksum || \"\");\n\n if (!checksumResult.valid && expectedChecksum) {\n rmSync(versionDir, { recursive: true, force: true });\n throw new Error(\n `Checksum verification failed!\\n` +\n `Expected: ${checksumResult.expected}\\n` +\n `Actual: ${checksumResult.actual}\\n` +\n `The downloaded file may be corrupted or tampered with.`,\n );\n }\n\n if (expectedChecksum) {\n console.log(\"Checksum verified successfully.\");\n } else {\n console.log(\"Warning: No checksum available, skipping verification.\");\n }\n\n console.log(\"Extracting...\");\n\n // Extract based on file type\n if (binaryName.endsWith(\".zip\")) {\n await extractZip(tempFile, versionDir);\n } else if (binaryName.endsWith(\".tar.gz\")) {\n await extractTarGz(tempFile, versionDir);\n }\n\n // Clean up temp file\n rmSync(tempFile, { force: true });\n\n // Save version override\n saveVersionOverride(version);\n\n console.log(`Electron app v${version} installed to ${versionDir}`);\n logger.info(\"Upgrade complete\", { version: version, path: versionDir });\n}\n\n/**\n * Execute the upgrade command.\n * @param options - Command options.\n */\nexport async function upgradeCommand(options: IUpgradeOptions): Promise<void> {\n try {\n // If specific version requested\n if (options.version) {\n const baseUrl = getDownloadBaseUrl();\n const binaryName = getBinaryName();\n const downloadUrl = `${baseUrl}/electron-app-v${options.version}/${binaryName}`;\n\n await downloadAndInstall(options.version, downloadUrl);\n\n // Auto-cleanup old versions (keep current + 1 previous)\n const cleanupResult = cleanupOldVersions({ all: false });\n if (cleanupResult.removed.length > 0) {\n console.log(\n `\\nCleaned up ${cleanupResult.removed.length} old version(s), ` +\n `freed ${formatBytes(cleanupResult.freedBytes)}`,\n );\n }\n return;\n }\n\n // Check for updates\n console.log(\"Checking for updates...\");\n const result = await checkForUpdates();\n\n console.log(`Current version: ${result.currentVersion}`);\n console.log(`Latest version: ${result.latestVersion}`);\n\n if (options.check) {\n if (result.updateAvailable) {\n console.log(\"\\nUpdate available! Run 'muggle-mcp upgrade' to install.\");\n } else {\n console.log(\"\\nYou are on the latest version.\");\n }\n return;\n }\n\n if (!result.updateAvailable && !options.force) {\n console.log(\"\\nYou are already on the latest version.\");\n console.log(\"Use --force to re-download the current version.\");\n return;\n }\n\n if (!result.downloadUrl) {\n throw new Error(\"No download URL available\");\n }\n\n // Download and install\n await downloadAndInstall(result.latestVersion, result.downloadUrl);\n\n // Auto-cleanup old versions (keep current + 1 previous)\n const cleanupResult = cleanupOldVersions({ all: false });\n if (cleanupResult.removed.length > 0) {\n console.log(\n `\\nCleaned up ${cleanupResult.removed.length} old version(s), ` +\n `freed ${formatBytes(cleanupResult.freedBytes)}`,\n );\n }\n } catch (error) {\n const errorMessage = error instanceof Error ? error.message : String(error);\n console.error(`Upgrade failed: ${errorMessage}`);\n logger.error(\"Upgrade failed\", { error: errorMessage });\n process.exit(1);\n }\n}\n","/**\n * CLI entry point for @muggleai/mcp.\n * Provides commands for serving MCP, setup, diagnostics, and authentication.\n */\n\nimport { readFileSync } from \"fs\";\nimport { dirname, resolve } from \"path\";\nimport { fileURLToPath } from \"url\";\n\nimport { Command } from \"commander\";\n\nimport { getLogger } from \"../shared/logger.js\";\n\n/** Directory containing this module. */\nconst __dirname = dirname(fileURLToPath(import.meta.url));\n\n/** Package version read from package.json. */\nconst packageVersion = JSON.parse(\n readFileSync(resolve(__dirname, \"..\", \"package.json\"), \"utf-8\")\n).version as string;\n\nimport { cleanupCommand, versionsCommand } from \"./cleanup.js\";\nimport { doctorCommand } from \"./doctor.js\";\nimport { helpCommand } from \"./help.js\";\nimport { loginCommand, logoutCommand, statusCommand } from \"./login.js\";\nimport { serveCommand } from \"./serve.js\";\nimport { setupCommand } from \"./setup.js\";\nimport { upgradeCommand } from \"./upgrade.js\";\n\nconst logger = getLogger();\n\n/**\n * Create and configure the CLI program.\n * @returns Configured Commander program.\n */\nfunction createProgram(): Command {\n const program = new Command();\n\n program\n .name(\"muggle-mcp\")\n .description(\"Unified MCP server for Muggle AI - Cloud QA and Local Testing\")\n .version(packageVersion);\n\n // Serve command (main command)\n program\n .command(\"serve\")\n .description(\"Start the MCP server\")\n .option(\"--qa\", \"Only enable Cloud QA tools\")\n .option(\"--local\", \"Only enable Local QA tools\")\n .option(\"--stdio\", \"Use stdio transport (default)\")\n .action(serveCommand);\n\n // Setup command\n program\n .command(\"setup\")\n .description(\"Download/update the Electron app for local testing\")\n .option(\"--force\", \"Force re-download even if already installed\")\n .action(setupCommand);\n\n // Upgrade command\n program\n .command(\"upgrade\")\n .description(\"Check for and install the latest electron-app version\")\n .option(\"--force\", \"Force re-download even if already on latest\")\n .option(\"--check\", \"Check for updates only, don't download\")\n .option(\"--version <version>\", \"Download a specific version (e.g., 1.0.2)\")\n .action(upgradeCommand);\n\n // Versions command\n program\n .command(\"versions\")\n .description(\"List installed electron-app versions\")\n .action(versionsCommand);\n\n // Cleanup command\n program\n .command(\"cleanup\")\n .description(\"Remove old electron-app versions to free disk space\")\n .option(\"--all\", \"Remove all old versions (default: keep one previous)\")\n .option(\"--dry-run\", \"Show what would be deleted without deleting\")\n .action(cleanupCommand);\n\n // Doctor command\n program\n .command(\"doctor\")\n .description(\"Diagnose installation and configuration issues\")\n .action(doctorCommand);\n\n // Login command\n program\n .command(\"login\")\n .description(\"Authenticate with Muggle AI (uses device code flow)\")\n .option(\"--key-name <name>\", \"Name for the API key\")\n .option(\"--key-expiry <expiry>\", \"API key expiry: 30d, 90d, 1y, never\", \"90d\")\n .action(loginCommand);\n\n // Logout command\n program\n .command(\"logout\")\n .description(\"Clear stored credentials\")\n .action(logoutCommand);\n\n // Status command\n program\n .command(\"status\")\n .description(\"Show authentication status\")\n .action(statusCommand);\n\n // Default to serve when no command specified\n program.action(() => {\n serveCommand({ stdio: true });\n });\n\n return program;\n}\n\n/**\n * Check if the user is requesting help via \"muggle-mcp help\".\n * Commander.js reserves \"help\" as a built-in command, so we intercept it.\n * @returns True if help was requested and handled.\n */\nfunction handleHelpCommand(): boolean {\n const args = process.argv.slice(2);\n\n if (args.length === 1 && args[0] === \"help\") {\n helpCommand();\n return true;\n }\n\n return false;\n}\n\n/**\n * Run the CLI.\n */\nexport async function runCli(): Promise<void> {\n try {\n // Handle \"muggle-mcp help\" specially since Commander reserves \"help\"\n if (handleHelpCommand()) {\n return;\n }\n\n const program = createProgram();\n await program.parseAsync(process.argv);\n } catch (error) {\n logger.error(\"CLI error\", {\n error: error instanceof Error ? error.message : String(error),\n });\n process.exit(1);\n }\n}\n","#!/usr/bin/env node\n/**\n * CLI entry point for muggle-mcp.\n */\n\nimport { runCli } from \"./index.js\";\n\nrunCli().catch((error) => {\n console.error(\"Fatal error:\", error instanceof Error ? error.message : String(error));\n process.exit(1);\n});\n"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@muggleai/mcp",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.6",
|
|
4
4
|
"description": "Unified MCP server for Muggle AI - Cloud QA and Local Testing tools",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -26,7 +26,7 @@
|
|
|
26
26
|
"test:watch": "vitest"
|
|
27
27
|
},
|
|
28
28
|
"muggleConfig": {
|
|
29
|
-
"electronAppVersion": "1.0.
|
|
29
|
+
"electronAppVersion": "1.0.2",
|
|
30
30
|
"downloadBaseUrl": "https://github.com/multiplex-ai/muggle-ai-mcp/releases/download",
|
|
31
31
|
"checksums": {
|
|
32
32
|
"darwin-arm64": "",
|
package/scripts/postinstall.mjs
CHANGED
|
@@ -132,7 +132,7 @@ async function downloadElectronApp() {
|
|
|
132
132
|
const baseUrl = config.downloadBaseUrl || "https://github.com/multiplex-ai/muggle-ai-mcp/releases/download";
|
|
133
133
|
|
|
134
134
|
const binaryName = getBinaryName();
|
|
135
|
-
const downloadUrl = `${baseUrl}/
|
|
135
|
+
const downloadUrl = `${baseUrl}/v${version}/${binaryName}`;
|
|
136
136
|
|
|
137
137
|
const appDir = getElectronAppDir();
|
|
138
138
|
const versionDir = join(appDir, version);
|