@muggleai/mcp 1.0.5 → 1.0.7

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.
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/cli/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAgHH;;GAEG;AACH,wBAAsB,MAAM,IAAI,OAAO,CAAC,IAAI,CAAC,CAU5C"}
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 path2 from 'path';
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 path2.join(getDataDir(), ELECTRON_APP_DIR);
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 = path2.join(dirPath, entry.name);
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 = path2.join(baseDir, entry.name);
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: path2.basename(filePath)
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: path2.basename(filePath),
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: path2.basename(filePath),
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: path2.basename(filePath),
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 cmd = platform() === "win32" ? `powershell -command "Expand-Archive -Path '${zipPath}' -DestinationPath '${destDir}' -Force"` : `unzip -o "${zipPath}" -d "${destDir}"`;
509
- exec(cmd, (error) => {
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 path2.join(getDataDir(), VERSION_OVERRIDE_FILE);
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 cmd = platform() === "win32" ? `powershell -command "Expand-Archive -Path '${zipPath}' -DestinationPath '${destDir}' -Force"` : `unzip -o "${zipPath}" -d "${destDir}"`;
698
- exec(cmd, (error) => {
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 = path2.join(versionDir, binaryName);
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.5",
3
+ "version": "1.0.7",
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.1",
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": "",
@@ -150,10 +150,17 @@ async function downloadElectronApp() {
150
150
  mkdirSync(versionDir, { recursive: true });
151
151
 
152
152
  // Download using fetch
153
+ console.log("Fetching...");
153
154
  const response = await fetch(downloadUrl);
154
155
  if (!response.ok) {
155
- throw new Error(`Download failed: ${response.status} ${response.statusText}`);
156
+ const errorBody = await response.text().catch(() => "");
157
+ throw new Error(
158
+ `Download failed: ${response.status} ${response.statusText}\n` +
159
+ `URL: ${downloadUrl}\n` +
160
+ `Response body: ${errorBody.substring(0, 500)}`
161
+ );
156
162
  }
163
+ console.log(`Response OK (${response.status}), downloading ${response.headers.get("content-length") || "unknown"} bytes...`);
157
164
 
158
165
  const tempFile = join(versionDir, binaryName);
159
166
  const fileStream = createWriteStream(tempFile);
@@ -199,9 +206,26 @@ async function downloadElectronApp() {
199
206
 
200
207
  console.log(`Electron app installed to ${versionDir}`);
201
208
  } catch (error) {
202
- console.warn("Warning: Failed to download Electron app.");
203
- console.warn("You can manually download it later using: muggle-mcp setup");
204
- console.warn(`Error: ${error.message}`);
209
+ console.error("\n========================================");
210
+ console.error("ERROR: Failed to download Electron app");
211
+ console.error("========================================\n");
212
+ console.error("Error message:", error.message);
213
+ console.error("\nFull error details:");
214
+ console.error(error.stack || error);
215
+ console.error("\nDebug info:");
216
+ console.error(" - Platform:", platform());
217
+ console.error(" - Architecture:", process.arch);
218
+ console.error(" - Node version:", process.version);
219
+ try {
220
+ const packageJson = require("../package.json");
221
+ const config = packageJson.muggleConfig || {};
222
+ console.error(" - Electron app version:", config.electronAppVersion || "unknown");
223
+ console.error(" - Download URL:", `${config.downloadBaseUrl}/v${config.electronAppVersion}/${getBinaryName()}`);
224
+ } catch {
225
+ console.error(" - Could not read package.json config");
226
+ }
227
+ console.error("\nYou can manually download it later using: muggle-mcp setup");
228
+ console.error("Or set ELECTRON_APP_PATH to point to an existing installation.\n");
205
229
  }
206
230
  }
207
231
 
@@ -216,9 +240,12 @@ async function extractZip(zipPath, destDir) {
216
240
  ? `powershell -command "Expand-Archive -Path '${zipPath}' -DestinationPath '${destDir}' -Force"`
217
241
  : `unzip -o "${zipPath}" -d "${destDir}"`;
218
242
 
219
- exec(cmd, (error) => {
243
+ exec(cmd, (error, stdout, stderr) => {
220
244
  if (error) {
221
- reject(error);
245
+ console.error("Extraction command failed:", cmd);
246
+ console.error("stdout:", stdout);
247
+ console.error("stderr:", stderr);
248
+ reject(new Error(`Extraction failed: ${error.message}\nstderr: ${stderr}`));
222
249
  } else {
223
250
  resolve();
224
251
  }