{"version":3,"sources":["../../../lib/launcher/index.ts","../../../../node_modules/tsup/assets/cjs_shims.js"],"sourcesContent":["import { spawn, ChildProcess } from \"child_process\";\nimport { fileURLToPath } from \"url\";\nimport path from \"path\";\n\n/**\n * Configuration options for launching the MCP Inspector.\n */\nexport interface LaunchOptions {\n  /**\n   * Server configuration for auto-connect\n   */\n  server?: {\n    /**\n     * Display name for the server in the UI\n     */\n    name: string;\n\n    /**\n     * HTTP URL of the MCP server (required for HTTP transport)\n     */\n    url: string;\n\n    /**\n     * Custom headers to send with requests\n     */\n    headers?: Record<string, string>;\n\n    /**\n     * If true, triggers OAuth flow on connect\n     */\n    useOAuth?: boolean;\n  };\n\n  /**\n   * Initial tab to navigate to.\n   * Options: \"servers\", \"tools\", \"resources\", \"prompts\", \"chat\", \"playground\"\n   */\n  defaultTab?: string;\n\n  /**\n   * Enable verbose logging output.\n   * When false (default), the inspector runs silently.\n   */\n  verbose?: boolean;\n\n  /**\n   * Content Security Policy mode for the App Builder sandbox.\n   * - \"permissive\": disables CSP enforcement for easier development (default)\n   * - \"widget-declared\": enforces CSP directives declared by the widget\n   */\n  cspMode?: \"permissive\" | \"widget-declared\";\n}\n\n/**\n * Handle for a running MCP Inspector instance.\n */\nexport interface InspectorInstance {\n  /**\n   * The URL where the inspector is running\n   */\n  url: string;\n\n  /**\n   * Stop the inspector server\n   */\n  stop: () => Promise<void>;\n\n  /**\n   * The underlying child process (for advanced use)\n   */\n  process: ChildProcess;\n}\n\n/**\n * Waits for the inspector server to be ready by polling the health endpoint.\n */\nasync function waitForServer(port: number, timeout = 30000): Promise<void> {\n  const start = Date.now();\n  while (Date.now() - start < timeout) {\n    try {\n      const res = await fetch(`http://localhost:${port}/health`);\n      if (res.ok) return;\n    } catch {\n      // Server not ready yet\n    }\n    await new Promise((r) => setTimeout(r, 100));\n  }\n  throw new Error(`Inspector failed to start within ${timeout}ms`);\n}\n\n/**\n * Launches the MCP Inspector with the specified configuration.\n *\n * @example\n * ```typescript\n * import { launchInspector } from '@mcpjam/inspector';\n *\n * const inspector = await launchInspector({\n *   server: {\n *     name: 'My MCP Server',\n *     url: 'http://localhost:3000/mcp',\n *   },\n *   defaultTab: 'playground',\n * });\n *\n * console.log(`Inspector running at ${inspector.url}`);\n *\n * // Later: stop the inspector\n * await inspector.stop();\n * ```\n */\nconst INSPECTOR_PORT = 6274;\n\nexport async function launchInspector(\n  options: LaunchOptions = {},\n): Promise<InspectorInstance> {\n  // Find bin/start.js relative to this file\n  // From dist/lib/launcher/index.js -> ../../../bin/start.js\n  const __dirname = path.dirname(fileURLToPath(import.meta.url));\n  const binPath = path.resolve(__dirname, \"../../../bin/start.js\");\n\n  // Build environment\n  const env: Record<string, string> = {\n    ...(Object.fromEntries(\n      Object.entries(process.env).filter(([, v]) => v !== undefined),\n    ) as Record<string, string>),\n  };\n\n  if (options.server) {\n    const config = {\n      mcpServers: {\n        [options.server.name]: {\n          url: options.server.url,\n          ...(options.server.headers && { headers: options.server.headers }),\n          ...(options.server.useOAuth && { useOAuth: true }),\n        },\n      },\n    };\n    env.MCP_CONFIG_DATA = JSON.stringify(config);\n    env.MCP_AUTO_CONNECT_SERVER = options.server.name;\n  }\n\n  if (options.defaultTab) {\n    // Map public API \"chat\" to internal \"chat-v2\" tab\n    const tab = options.defaultTab === \"chat\" ? \"chat-v2\" : options.defaultTab;\n    env.MCP_INITIAL_TAB = tab;\n  }\n\n  if (options.verbose) {\n    env.VERBOSE_LOGS = \"true\";\n  }\n\n  if (options.cspMode) {\n    env.MCP_CSP_MODE = options.cspMode;\n  }\n\n  // Spawn the process\n  const child = spawn(\"node\", [binPath], {\n    env,\n    stdio: \"inherit\",\n    detached: false,\n  });\n\n  // Wait for server to be ready, racing against spawn errors\n  await new Promise<void>((resolve, reject) => {\n    let resolved = false;\n\n    child.on(\"error\", (err) => {\n      if (!resolved) {\n        resolved = true;\n        reject(new Error(`Failed to spawn inspector process: ${err.message}`));\n      }\n    });\n\n    waitForServer(INSPECTOR_PORT)\n      .then(() => {\n        if (!resolved) {\n          resolved = true;\n          resolve();\n        }\n      })\n      .catch((err) => {\n        if (!resolved) {\n          resolved = true;\n          reject(err);\n        }\n      });\n  });\n\n  const tabHash = options.defaultTab\n    ? `#${options.defaultTab === \"chat\" ? \"chat-v2\" : options.defaultTab}`\n    : \"\";\n  const url = `http://localhost:${INSPECTOR_PORT}${tabHash}`;\n\n  return {\n    url,\n    process: child,\n    stop: async () => {\n      child.kill(\"SIGTERM\");\n      // Wait for process to exit\n      await new Promise<void>((resolve) => {\n        const timeout = setTimeout(() => {\n          // Force kill if SIGTERM didn't work\n          child.kill(\"SIGKILL\");\n          resolve();\n        }, 5000);\n\n        child.on(\"exit\", () => {\n          clearTimeout(timeout);\n          resolve();\n        });\n      });\n    },\n  };\n}\n","// Shim globals in cjs bundle\n// There's a weird bug that esbuild will always inject importMetaUrl\n// if we export it as `const importMetaUrl = ... __filename ...`\n// But using a function will not cause this issue\n\nconst getImportMetaUrl = () => \n  typeof document === \"undefined\" \n    ? new URL(`file:${__filename}`).href \n    : (document.currentScript && document.currentScript.tagName.toUpperCase() === 'SCRIPT') \n      ? document.currentScript.src \n      : new URL(\"main.js\", document.baseURI).href;\n\nexport const importMetaUrl = /* @__PURE__ */ getImportMetaUrl()\n"],"mappings":"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","names":["path"]}