@posthog/wizard 2.4.0 → 2.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (32) hide show
  1. package/dist/bin.js +10 -0
  2. package/dist/bin.js.map +1 -1
  3. package/dist/src/lib/constants.d.ts +1 -1
  4. package/dist/src/lib/version.d.ts +1 -1
  5. package/dist/src/lib/version.js +1 -1
  6. package/dist/src/lib/version.js.map +1 -1
  7. package/dist/src/lib/wizard-session.d.ts +2 -0
  8. package/dist/src/lib/wizard-session.js +1 -0
  9. package/dist/src/lib/wizard-session.js.map +1 -1
  10. package/dist/src/steps/add-mcp-server-to-clients/clients/claude-code.js +6 -1
  11. package/dist/src/steps/add-mcp-server-to-clients/clients/claude-code.js.map +1 -1
  12. package/dist/src/steps/add-mcp-server-to-clients/defaults.d.ts +15 -0
  13. package/dist/src/steps/add-mcp-server-to-clients/defaults.js +119 -4
  14. package/dist/src/steps/add-mcp-server-to-clients/defaults.js.map +1 -1
  15. package/dist/src/steps/add-mcp-server-to-clients/index.d.ts +2 -1
  16. package/dist/src/steps/add-mcp-server-to-clients/index.js +2 -2
  17. package/dist/src/steps/add-mcp-server-to-clients/index.js.map +1 -1
  18. package/dist/src/ui/tui/primitives/GroupedPickerMenu.d.ts +20 -0
  19. package/dist/src/ui/tui/primitives/GroupedPickerMenu.js +77 -0
  20. package/dist/src/ui/tui/primitives/GroupedPickerMenu.js.map +1 -0
  21. package/dist/src/ui/tui/primitives/PickerMenu.js +12 -3
  22. package/dist/src/ui/tui/primitives/PickerMenu.js.map +1 -1
  23. package/dist/src/ui/tui/primitives/index.d.ts +1 -0
  24. package/dist/src/ui/tui/primitives/index.js +1 -0
  25. package/dist/src/ui/tui/primitives/index.js.map +1 -1
  26. package/dist/src/ui/tui/screens/McpScreen.d.ts +1 -1
  27. package/dist/src/ui/tui/screens/McpScreen.js +21 -6
  28. package/dist/src/ui/tui/screens/McpScreen.js.map +1 -1
  29. package/dist/src/ui/tui/services/mcp-installer.d.ts +1 -1
  30. package/dist/src/ui/tui/services/mcp-installer.js +3 -3
  31. package/dist/src/ui/tui/services/mcp-installer.js.map +1 -1
  32. package/package.json +3 -3
package/dist/bin.js CHANGED
@@ -326,9 +326,17 @@ if (process.env.NODE_ENV === 'test') {
326
326
  describe: 'Add local development MCP server (http://localhost:8787)',
327
327
  type: 'boolean',
328
328
  },
329
+ features: {
330
+ describe: 'Comma-separated list of features to enable (default: all)',
331
+ type: 'string',
332
+ },
329
333
  });
330
334
  }, (argv) => {
331
335
  const options = { ...argv };
336
+ const mcpFeatures = options.features
337
+ ?.split(',')
338
+ .map((s) => s.trim())
339
+ .filter(Boolean);
332
340
  void (async () => {
333
341
  try {
334
342
  const { startTUI } = await import('./src/ui/tui/start-tui.js');
@@ -338,6 +346,7 @@ if (process.env.NODE_ENV === 'test') {
338
346
  const session = buildSession({
339
347
  debug: options.debug,
340
348
  localMcp: options.local,
349
+ mcpFeatures,
341
350
  });
342
351
  tui.store.session = session;
343
352
  }
@@ -347,6 +356,7 @@ if (process.env.NODE_ENV === 'test') {
347
356
  const { addMCPServerToClientsStep } = await import('./src/steps/add-mcp-server-to-clients/index.js');
348
357
  await addMCPServerToClientsStep({
349
358
  local: options.local,
359
+ features: mcpFeatures,
350
360
  });
351
361
  }
352
362
  })();
package/dist/bin.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"bin.js","sourceRoot":"","sources":["../bin.ts"],"names":[],"mappings":"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","sourcesContent":["#!/usr/bin/env node\nimport { satisfies } from 'semver';\nimport { red } from './src/utils/logging';\n\nimport yargs from 'yargs';\nimport { hideBin } from 'yargs/helpers';\nimport { VERSION } from './src/lib/version.js';\n\nconst WIZARD_VERSION = VERSION;\n\nconst NODE_VERSION_RANGE = '>=18.17.0';\n\n// Have to run this above the other imports because they are importing clack that\n// has the problematic imports.\nif (!satisfies(process.version, NODE_VERSION_RANGE)) {\n red(\n `PostHog wizard requires Node.js ${NODE_VERSION_RANGE}. You are using Node.js ${process.version}. Please upgrade your Node.js version.`,\n );\n process.exit(1);\n}\n\nimport { runWizard } from './src/run';\nimport { isNonInteractiveEnvironment } from './src/utils/environment';\nimport { getUI, setUI } from './src/ui';\nimport { LoggingUI } from './src/ui/logging-ui';\nimport type { Integration } from './src/lib/constants';\nimport type { FrameworkConfig } from './src/lib/framework-config';\n\nif (process.env.NODE_ENV === 'test') {\n void (async () => {\n try {\n const { server } = await import('./e2e-tests/mocks/server.js');\n server.listen({\n onUnhandledRequest: 'bypass',\n });\n } catch (error) {\n // Mock server import failed - this can happen during non-E2E tests\n }\n })();\n}\n\nyargs(hideBin(process.argv))\n .env('POSTHOG_WIZARD')\n // global options\n .options({\n debug: {\n default: false,\n describe: 'Enable verbose logging\\nenv: POSTHOG_WIZARD_DEBUG',\n type: 'boolean',\n },\n region: {\n describe: 'PostHog cloud region\\nenv: POSTHOG_WIZARD_REGION',\n choices: ['us', 'eu'],\n type: 'string',\n },\n default: {\n default: true,\n describe:\n 'Use default options for all prompts\\nenv: POSTHOG_WIZARD_DEFAULT',\n type: 'boolean',\n },\n signup: {\n default: false,\n describe:\n 'Create a new PostHog account during setup\\nenv: POSTHOG_WIZARD_SIGNUP',\n type: 'boolean',\n },\n 'local-mcp': {\n default: false,\n describe:\n 'Use local MCP server at http://localhost:8787/mcp\\nenv: POSTHOG_WIZARD_LOCAL_MCP',\n type: 'boolean',\n },\n ci: {\n default: false,\n describe:\n 'Enable CI mode for non-interactive execution\\nenv: POSTHOG_WIZARD_CI',\n type: 'boolean',\n },\n 'api-key': {\n describe:\n 'PostHog personal API key (phx_xxx) for authentication\\nenv: POSTHOG_WIZARD_API_KEY',\n type: 'string',\n },\n 'project-id': {\n describe:\n 'PostHog project ID to use (optional; when not set, uses default from API key or OAuth)\\nenv: POSTHOG_WIZARD_PROJECT_ID',\n type: 'string',\n },\n })\n .command(\n ['$0'],\n 'Run the PostHog setup wizard',\n (yargs) => {\n return yargs.options({\n 'force-install': {\n default: false,\n describe:\n 'Force install packages even if peer dependency checks fail\\nenv: POSTHOG_WIZARD_FORCE_INSTALL',\n type: 'boolean',\n },\n 'install-dir': {\n describe:\n 'Directory to install PostHog in\\nenv: POSTHOG_WIZARD_INSTALL_DIR',\n type: 'string',\n },\n playground: {\n default: false,\n describe: 'Launch the TUI primitives playground',\n type: 'boolean',\n },\n integration: {\n describe: 'Integration to set up',\n choices: [\n 'nextjs',\n 'astro',\n 'react',\n 'svelte',\n 'react-native',\n 'tanstack-router',\n 'tanstack-start',\n ],\n type: 'string',\n },\n menu: {\n default: false,\n describe:\n 'Show menu for manual integration selection instead of auto-detecting\\nenv: POSTHOG_WIZARD_MENU',\n type: 'boolean',\n },\n benchmark: {\n default: false,\n describe:\n 'Run in benchmark mode with per-phase token tracking\\nenv: POSTHOG_WIZARD_BENCHMARK',\n type: 'boolean',\n },\n 'yara-report': {\n default: false,\n describe:\n 'Print YARA scanner summary after the agent run\\nenv: POSTHOG_WIZARD_YARA_REPORT',\n type: 'boolean',\n hidden: true,\n },\n });\n },\n (argv) => {\n const options = { ...argv };\n\n // CI mode validation and TTY check\n if (options.ci) {\n // Use LoggingUI for CI mode (no dependencies, no prompts)\n setUI(new LoggingUI());\n // Default region to 'us' if not specified\n if (!options.region) {\n options.region = 'us';\n }\n if (!options.apiKey) {\n getUI().intro(`PostHog Wizard`);\n getUI().log.error(\n 'CI mode requires --api-key (personal API key phx_xxx)',\n );\n process.exit(1);\n }\n if (!options.installDir) {\n getUI().intro(`PostHog Wizard`);\n getUI().log.error(\n 'CI mode requires --install-dir (directory to install PostHog in)',\n );\n process.exit(1);\n }\n\n void runWizard(options as Parameters<typeof runWizard>[0]);\n } else if (isNonInteractiveEnvironment()) {\n // Non-interactive non-CI: error out\n getUI().intro(`PostHog Wizard`);\n getUI().log.error(\n 'This installer requires an interactive terminal (TTY) to run.\\n' +\n 'It appears you are running in a non-interactive environment.\\n' +\n 'Please run the wizard in an interactive terminal.\\n\\n' +\n 'For CI/CD environments, use --ci mode:\\n' +\n ' npx @posthog/wizard --ci --region us --api-key phx_xxx',\n );\n process.exit(1);\n } else if (options.playground) {\n // Playground mode: launch the TUI primitives playground\n void (async () => {\n const { startPlayground } = await import(\n './src/ui/tui/playground/start-playground.js'\n );\n (startPlayground as (version: string) => void)(WIZARD_VERSION);\n })();\n } else {\n // Interactive TTY: launch the Ink TUI\n void (async () => {\n try {\n const { startTUI } = await import('./src/ui/tui/start-tui.js');\n const { buildSession } = await import(\n './src/lib/wizard-session.js'\n );\n\n const tui = startTUI(WIZARD_VERSION);\n\n // Build session from CLI args and attach to store\n const session = buildSession({\n debug: options.debug as boolean | undefined,\n forceInstall: options.forceInstall as boolean | undefined,\n installDir: options.installDir as string | undefined,\n ci: false,\n signup: options.signup as boolean | undefined,\n localMcp: options.localMcp as boolean | undefined,\n apiKey: options.apiKey as string | undefined,\n menu: options.menu as boolean | undefined,\n integration: options.integration as Parameters<\n typeof buildSession\n >[0]['integration'],\n benchmark: options.benchmark as boolean | undefined,\n yaraReport: options.yaraReport as boolean | undefined,\n projectId: options.projectId as string | undefined,\n });\n tui.store.session = session;\n\n // Detect framework while IntroScreen shows its spinner.\n // Runs concurrently — IntroScreen reacts when detection completes.\n const { FRAMEWORK_REGISTRY } = (await import(\n './src/lib/registry.js'\n )) as { FRAMEWORK_REGISTRY: Record<Integration, FrameworkConfig> };\n const { detectIntegration } = (await import('./src/run.js')) as {\n detectIntegration: (\n installDir: string,\n ) => Promise<Integration | undefined>;\n };\n const installDir = session.installDir ?? process.cwd();\n\n const { DETECTION_TIMEOUT_MS } = (await import(\n './src/lib/constants.js'\n )) as { DETECTION_TIMEOUT_MS: number };\n\n const detectedIntegration = await Promise.race([\n detectIntegration(installDir),\n new Promise<undefined>((resolve) =>\n setTimeout(() => resolve(undefined), DETECTION_TIMEOUT_MS),\n ),\n ]);\n\n if (detectedIntegration) {\n const config = FRAMEWORK_REGISTRY[detectedIntegration];\n\n // Run gatherContext for the friendly variant label\n if (config.metadata.gatherContext) {\n try {\n const context = await Promise.race([\n config.metadata.gatherContext({\n installDir,\n debug: session.debug,\n forceInstall: session.forceInstall,\n default: false,\n signup: session.signup,\n localMcp: session.localMcp,\n ci: session.ci,\n menu: session.menu,\n benchmark: session.benchmark,\n yaraReport: session.yaraReport,\n }),\n new Promise<Record<string, never>>((resolve) =>\n setTimeout(() => resolve({}), DETECTION_TIMEOUT_MS),\n ),\n ]);\n for (const [key, value] of Object.entries(context)) {\n if (!(key in session.frameworkContext)) {\n tui.store.setFrameworkContext(key, value);\n }\n }\n } catch {\n // Detection failed — will show generic name\n }\n }\n\n tui.store.setFrameworkConfig(detectedIntegration, config);\n\n if (!session.detectedFrameworkLabel) {\n tui.store.setDetectedFramework(config.metadata.name);\n }\n\n // Early version check — surface on IntroScreen before user proceeds\n if (\n config.detection.minimumVersion &&\n config.detection.getInstalledVersion\n ) {\n const semver = await import('semver');\n const version = await config.detection.getInstalledVersion({\n installDir,\n debug: session.debug,\n forceInstall: session.forceInstall,\n default: false,\n signup: session.signup,\n localMcp: session.localMcp,\n ci: session.ci,\n menu: session.menu,\n benchmark: session.benchmark,\n yaraReport: session.yaraReport,\n });\n if (version) {\n const coerced = semver.coerce(version);\n if (\n coerced &&\n semver.lt(coerced, config.detection.minimumVersion)\n ) {\n tui.store.setUnsupportedVersion({\n current: version,\n minimum: config.detection.minimumVersion,\n docsUrl:\n config.metadata.unsupportedVersionDocsUrl ??\n config.metadata.docsUrl,\n });\n }\n }\n }\n }\n\n // Feature discovery — deterministic scan of package.json deps\n try {\n const { readFileSync } = await import('fs');\n const pkgPath = require('path').join(installDir, 'package.json');\n const pkg = JSON.parse(readFileSync(pkgPath, 'utf-8'));\n const allDeps = {\n ...pkg.dependencies,\n ...pkg.devDependencies,\n };\n const depNames = Object.keys(allDeps);\n\n const { DiscoveredFeature } = await import(\n './src/lib/wizard-session.js'\n );\n\n if (\n depNames.some((d) =>\n ['stripe', '@stripe/stripe-js'].includes(d),\n )\n ) {\n tui.store.addDiscoveredFeature(DiscoveredFeature.Stripe);\n }\n\n // LLM SDK detection — sourced from PostHog LLM analytics skill\n const LLM_PACKAGES = [\n 'openai',\n '@anthropic-ai/sdk',\n 'ai',\n '@ai-sdk/openai',\n 'langchain',\n '@langchain/openai',\n '@langchain/langgraph',\n '@google/generative-ai',\n '@google/genai',\n '@instructor-ai/instructor',\n '@mastra/core',\n 'portkey-ai',\n ];\n if (depNames.some((d) => LLM_PACKAGES.includes(d))) {\n tui.store.addDiscoveredFeature(DiscoveredFeature.LLM);\n }\n } catch {\n // No package.json or parse error — skip feature discovery\n }\n\n // Signal detection is done — IntroScreen shows picker or results\n tui.store.setDetectionComplete();\n\n // Wait for IntroScreen confirmation\n await tui.waitForSetup();\n\n // Ensure health check has completed before starting the wizard.\n // The flow gate on Intro (readinessResult !== null) keeps the\n // TUI on IntroScreen until this resolves. If blocking, the\n // outage overlay was already pushed in the .then() callback.\n await tui.store.healthGateComplete;\n\n await runWizard(\n options as Parameters<typeof runWizard>[0],\n tui.store.session,\n );\n\n // Keep the outro screen visible — let process.exit() handle cleanup\n } catch (err) {\n // TUI unavailable (e.g., in test environment) — continue with default UI\n if (process.env.DEBUG || process.env.POSTHOG_WIZARD_DEBUG) {\n console.error('TUI init failed:', err); // eslint-disable-line no-console\n }\n await runWizard(options as Parameters<typeof runWizard>[0]);\n }\n })();\n }\n },\n )\n .command('mcp <command>', 'MCP server management commands', (yargs) => {\n return yargs\n .command(\n 'add',\n 'Install PostHog MCP server to supported clients',\n (yargs) => {\n return yargs.options({\n local: {\n default: false,\n describe:\n 'Add local development MCP server (http://localhost:8787)',\n type: 'boolean',\n },\n });\n },\n (argv) => {\n const options = { ...argv };\n void (async () => {\n try {\n const { startTUI } = await import('./src/ui/tui/start-tui.js');\n const { buildSession } = await import(\n './src/lib/wizard-session.js'\n );\n\n const { Flow } = await import('./src/ui/tui/router.js');\n const tui = startTUI(WIZARD_VERSION, Flow.McpAdd);\n const session = buildSession({\n debug: options.debug,\n localMcp: options.local,\n });\n tui.store.session = session;\n } catch {\n // TUI unavailable — fallback to logging\n setUI(new LoggingUI());\n const { addMCPServerToClientsStep } = await import(\n './src/steps/add-mcp-server-to-clients/index.js'\n );\n await addMCPServerToClientsStep({\n local: options.local,\n });\n }\n })();\n },\n )\n .command(\n 'remove',\n 'Remove PostHog MCP server from supported clients',\n (yargs) => {\n return yargs.options({\n local: {\n default: false,\n describe:\n 'Remove local development MCP server (http://localhost:8787)',\n type: 'boolean',\n },\n });\n },\n (argv) => {\n const options = { ...argv };\n void (async () => {\n try {\n const { startTUI } = await import('./src/ui/tui/start-tui.js');\n const { buildSession } = await import(\n './src/lib/wizard-session.js'\n );\n\n const { Flow } = await import('./src/ui/tui/router.js');\n const tui = startTUI(WIZARD_VERSION, Flow.McpRemove);\n const session = buildSession({\n debug: options.debug,\n localMcp: options.local,\n });\n tui.store.session = session;\n } catch {\n // TUI unavailable — fallback to logging\n setUI(new LoggingUI());\n const { removeMCPServerFromClientsStep } = await import(\n './src/steps/add-mcp-server-to-clients/index.js'\n );\n await removeMCPServerFromClientsStep({\n local: options.local,\n });\n }\n })();\n },\n )\n .demandCommand(1, 'You must specify a subcommand (add or remove)')\n .help();\n })\n .help()\n .alias('help', 'h')\n .version()\n .alias('version', 'v')\n .wrap(process.stdout.isTTY ? yargs.terminalWidth() : 80).argv;\n"]}
1
+ {"version":3,"file":"bin.js","sourceRoot":"","sources":["../bin.ts"],"names":[],"mappings":"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","sourcesContent":["#!/usr/bin/env node\nimport { satisfies } from 'semver';\nimport { red } from './src/utils/logging';\n\nimport yargs from 'yargs';\nimport { hideBin } from 'yargs/helpers';\nimport { VERSION } from './src/lib/version.js';\n\nconst WIZARD_VERSION = VERSION;\n\nconst NODE_VERSION_RANGE = '>=18.17.0';\n\n// Have to run this above the other imports because they are importing clack that\n// has the problematic imports.\nif (!satisfies(process.version, NODE_VERSION_RANGE)) {\n red(\n `PostHog wizard requires Node.js ${NODE_VERSION_RANGE}. You are using Node.js ${process.version}. Please upgrade your Node.js version.`,\n );\n process.exit(1);\n}\n\nimport { runWizard } from './src/run';\nimport { isNonInteractiveEnvironment } from './src/utils/environment';\nimport { getUI, setUI } from './src/ui';\nimport { LoggingUI } from './src/ui/logging-ui';\nimport type { Integration } from './src/lib/constants';\nimport type { FrameworkConfig } from './src/lib/framework-config';\n\nif (process.env.NODE_ENV === 'test') {\n void (async () => {\n try {\n const { server } = await import('./e2e-tests/mocks/server.js');\n server.listen({\n onUnhandledRequest: 'bypass',\n });\n } catch (error) {\n // Mock server import failed - this can happen during non-E2E tests\n }\n })();\n}\n\nyargs(hideBin(process.argv))\n .env('POSTHOG_WIZARD')\n // global options\n .options({\n debug: {\n default: false,\n describe: 'Enable verbose logging\\nenv: POSTHOG_WIZARD_DEBUG',\n type: 'boolean',\n },\n region: {\n describe: 'PostHog cloud region\\nenv: POSTHOG_WIZARD_REGION',\n choices: ['us', 'eu'],\n type: 'string',\n },\n default: {\n default: true,\n describe:\n 'Use default options for all prompts\\nenv: POSTHOG_WIZARD_DEFAULT',\n type: 'boolean',\n },\n signup: {\n default: false,\n describe:\n 'Create a new PostHog account during setup\\nenv: POSTHOG_WIZARD_SIGNUP',\n type: 'boolean',\n },\n 'local-mcp': {\n default: false,\n describe:\n 'Use local MCP server at http://localhost:8787/mcp\\nenv: POSTHOG_WIZARD_LOCAL_MCP',\n type: 'boolean',\n },\n ci: {\n default: false,\n describe:\n 'Enable CI mode for non-interactive execution\\nenv: POSTHOG_WIZARD_CI',\n type: 'boolean',\n },\n 'api-key': {\n describe:\n 'PostHog personal API key (phx_xxx) for authentication\\nenv: POSTHOG_WIZARD_API_KEY',\n type: 'string',\n },\n 'project-id': {\n describe:\n 'PostHog project ID to use (optional; when not set, uses default from API key or OAuth)\\nenv: POSTHOG_WIZARD_PROJECT_ID',\n type: 'string',\n },\n })\n .command(\n ['$0'],\n 'Run the PostHog setup wizard',\n (yargs) => {\n return yargs.options({\n 'force-install': {\n default: false,\n describe:\n 'Force install packages even if peer dependency checks fail\\nenv: POSTHOG_WIZARD_FORCE_INSTALL',\n type: 'boolean',\n },\n 'install-dir': {\n describe:\n 'Directory to install PostHog in\\nenv: POSTHOG_WIZARD_INSTALL_DIR',\n type: 'string',\n },\n playground: {\n default: false,\n describe: 'Launch the TUI primitives playground',\n type: 'boolean',\n },\n integration: {\n describe: 'Integration to set up',\n choices: [\n 'nextjs',\n 'astro',\n 'react',\n 'svelte',\n 'react-native',\n 'tanstack-router',\n 'tanstack-start',\n ],\n type: 'string',\n },\n menu: {\n default: false,\n describe:\n 'Show menu for manual integration selection instead of auto-detecting\\nenv: POSTHOG_WIZARD_MENU',\n type: 'boolean',\n },\n benchmark: {\n default: false,\n describe:\n 'Run in benchmark mode with per-phase token tracking\\nenv: POSTHOG_WIZARD_BENCHMARK',\n type: 'boolean',\n },\n 'yara-report': {\n default: false,\n describe:\n 'Print YARA scanner summary after the agent run\\nenv: POSTHOG_WIZARD_YARA_REPORT',\n type: 'boolean',\n hidden: true,\n },\n });\n },\n (argv) => {\n const options = { ...argv };\n\n // CI mode validation and TTY check\n if (options.ci) {\n // Use LoggingUI for CI mode (no dependencies, no prompts)\n setUI(new LoggingUI());\n // Default region to 'us' if not specified\n if (!options.region) {\n options.region = 'us';\n }\n if (!options.apiKey) {\n getUI().intro(`PostHog Wizard`);\n getUI().log.error(\n 'CI mode requires --api-key (personal API key phx_xxx)',\n );\n process.exit(1);\n }\n if (!options.installDir) {\n getUI().intro(`PostHog Wizard`);\n getUI().log.error(\n 'CI mode requires --install-dir (directory to install PostHog in)',\n );\n process.exit(1);\n }\n\n void runWizard(options as Parameters<typeof runWizard>[0]);\n } else if (isNonInteractiveEnvironment()) {\n // Non-interactive non-CI: error out\n getUI().intro(`PostHog Wizard`);\n getUI().log.error(\n 'This installer requires an interactive terminal (TTY) to run.\\n' +\n 'It appears you are running in a non-interactive environment.\\n' +\n 'Please run the wizard in an interactive terminal.\\n\\n' +\n 'For CI/CD environments, use --ci mode:\\n' +\n ' npx @posthog/wizard --ci --region us --api-key phx_xxx',\n );\n process.exit(1);\n } else if (options.playground) {\n // Playground mode: launch the TUI primitives playground\n void (async () => {\n const { startPlayground } = await import(\n './src/ui/tui/playground/start-playground.js'\n );\n (startPlayground as (version: string) => void)(WIZARD_VERSION);\n })();\n } else {\n // Interactive TTY: launch the Ink TUI\n void (async () => {\n try {\n const { startTUI } = await import('./src/ui/tui/start-tui.js');\n const { buildSession } = await import(\n './src/lib/wizard-session.js'\n );\n\n const tui = startTUI(WIZARD_VERSION);\n\n // Build session from CLI args and attach to store\n const session = buildSession({\n debug: options.debug as boolean | undefined,\n forceInstall: options.forceInstall as boolean | undefined,\n installDir: options.installDir as string | undefined,\n ci: false,\n signup: options.signup as boolean | undefined,\n localMcp: options.localMcp as boolean | undefined,\n apiKey: options.apiKey as string | undefined,\n menu: options.menu as boolean | undefined,\n integration: options.integration as Parameters<\n typeof buildSession\n >[0]['integration'],\n benchmark: options.benchmark as boolean | undefined,\n yaraReport: options.yaraReport as boolean | undefined,\n projectId: options.projectId as string | undefined,\n });\n tui.store.session = session;\n\n // Detect framework while IntroScreen shows its spinner.\n // Runs concurrently — IntroScreen reacts when detection completes.\n const { FRAMEWORK_REGISTRY } = (await import(\n './src/lib/registry.js'\n )) as { FRAMEWORK_REGISTRY: Record<Integration, FrameworkConfig> };\n const { detectIntegration } = (await import('./src/run.js')) as {\n detectIntegration: (\n installDir: string,\n ) => Promise<Integration | undefined>;\n };\n const installDir = session.installDir ?? process.cwd();\n\n const { DETECTION_TIMEOUT_MS } = (await import(\n './src/lib/constants.js'\n )) as { DETECTION_TIMEOUT_MS: number };\n\n const detectedIntegration = await Promise.race([\n detectIntegration(installDir),\n new Promise<undefined>((resolve) =>\n setTimeout(() => resolve(undefined), DETECTION_TIMEOUT_MS),\n ),\n ]);\n\n if (detectedIntegration) {\n const config = FRAMEWORK_REGISTRY[detectedIntegration];\n\n // Run gatherContext for the friendly variant label\n if (config.metadata.gatherContext) {\n try {\n const context = await Promise.race([\n config.metadata.gatherContext({\n installDir,\n debug: session.debug,\n forceInstall: session.forceInstall,\n default: false,\n signup: session.signup,\n localMcp: session.localMcp,\n ci: session.ci,\n menu: session.menu,\n benchmark: session.benchmark,\n yaraReport: session.yaraReport,\n }),\n new Promise<Record<string, never>>((resolve) =>\n setTimeout(() => resolve({}), DETECTION_TIMEOUT_MS),\n ),\n ]);\n for (const [key, value] of Object.entries(context)) {\n if (!(key in session.frameworkContext)) {\n tui.store.setFrameworkContext(key, value);\n }\n }\n } catch {\n // Detection failed — will show generic name\n }\n }\n\n tui.store.setFrameworkConfig(detectedIntegration, config);\n\n if (!session.detectedFrameworkLabel) {\n tui.store.setDetectedFramework(config.metadata.name);\n }\n\n // Early version check — surface on IntroScreen before user proceeds\n if (\n config.detection.minimumVersion &&\n config.detection.getInstalledVersion\n ) {\n const semver = await import('semver');\n const version = await config.detection.getInstalledVersion({\n installDir,\n debug: session.debug,\n forceInstall: session.forceInstall,\n default: false,\n signup: session.signup,\n localMcp: session.localMcp,\n ci: session.ci,\n menu: session.menu,\n benchmark: session.benchmark,\n yaraReport: session.yaraReport,\n });\n if (version) {\n const coerced = semver.coerce(version);\n if (\n coerced &&\n semver.lt(coerced, config.detection.minimumVersion)\n ) {\n tui.store.setUnsupportedVersion({\n current: version,\n minimum: config.detection.minimumVersion,\n docsUrl:\n config.metadata.unsupportedVersionDocsUrl ??\n config.metadata.docsUrl,\n });\n }\n }\n }\n }\n\n // Feature discovery — deterministic scan of package.json deps\n try {\n const { readFileSync } = await import('fs');\n const pkgPath = require('path').join(installDir, 'package.json');\n const pkg = JSON.parse(readFileSync(pkgPath, 'utf-8'));\n const allDeps = {\n ...pkg.dependencies,\n ...pkg.devDependencies,\n };\n const depNames = Object.keys(allDeps);\n\n const { DiscoveredFeature } = await import(\n './src/lib/wizard-session.js'\n );\n\n if (\n depNames.some((d) =>\n ['stripe', '@stripe/stripe-js'].includes(d),\n )\n ) {\n tui.store.addDiscoveredFeature(DiscoveredFeature.Stripe);\n }\n\n // LLM SDK detection — sourced from PostHog LLM analytics skill\n const LLM_PACKAGES = [\n 'openai',\n '@anthropic-ai/sdk',\n 'ai',\n '@ai-sdk/openai',\n 'langchain',\n '@langchain/openai',\n '@langchain/langgraph',\n '@google/generative-ai',\n '@google/genai',\n '@instructor-ai/instructor',\n '@mastra/core',\n 'portkey-ai',\n ];\n if (depNames.some((d) => LLM_PACKAGES.includes(d))) {\n tui.store.addDiscoveredFeature(DiscoveredFeature.LLM);\n }\n } catch {\n // No package.json or parse error — skip feature discovery\n }\n\n // Signal detection is done — IntroScreen shows picker or results\n tui.store.setDetectionComplete();\n\n // Wait for IntroScreen confirmation\n await tui.waitForSetup();\n\n // Ensure health check has completed before starting the wizard.\n // The flow gate on Intro (readinessResult !== null) keeps the\n // TUI on IntroScreen until this resolves. If blocking, the\n // outage overlay was already pushed in the .then() callback.\n await tui.store.healthGateComplete;\n\n await runWizard(\n options as Parameters<typeof runWizard>[0],\n tui.store.session,\n );\n\n // Keep the outro screen visible — let process.exit() handle cleanup\n } catch (err) {\n // TUI unavailable (e.g., in test environment) — continue with default UI\n if (process.env.DEBUG || process.env.POSTHOG_WIZARD_DEBUG) {\n console.error('TUI init failed:', err); // eslint-disable-line no-console\n }\n await runWizard(options as Parameters<typeof runWizard>[0]);\n }\n })();\n }\n },\n )\n .command('mcp <command>', 'MCP server management commands', (yargs) => {\n return yargs\n .command(\n 'add',\n 'Install PostHog MCP server to supported clients',\n (yargs) => {\n return yargs.options({\n local: {\n default: false,\n describe:\n 'Add local development MCP server (http://localhost:8787)',\n type: 'boolean',\n },\n features: {\n describe:\n 'Comma-separated list of features to enable (default: all)',\n type: 'string',\n },\n });\n },\n (argv) => {\n const options = { ...argv };\n const mcpFeatures = options.features\n ?.split(',')\n .map((s) => s.trim())\n .filter(Boolean);\n void (async () => {\n try {\n const { startTUI } = await import('./src/ui/tui/start-tui.js');\n const { buildSession } = await import(\n './src/lib/wizard-session.js'\n );\n\n const { Flow } = await import('./src/ui/tui/router.js');\n const tui = startTUI(WIZARD_VERSION, Flow.McpAdd);\n const session = buildSession({\n debug: options.debug,\n localMcp: options.local,\n mcpFeatures,\n });\n tui.store.session = session;\n } catch {\n // TUI unavailable — fallback to logging\n setUI(new LoggingUI());\n const { addMCPServerToClientsStep } = await import(\n './src/steps/add-mcp-server-to-clients/index.js'\n );\n await addMCPServerToClientsStep({\n local: options.local,\n features: mcpFeatures,\n });\n }\n })();\n },\n )\n .command(\n 'remove',\n 'Remove PostHog MCP server from supported clients',\n (yargs) => {\n return yargs.options({\n local: {\n default: false,\n describe:\n 'Remove local development MCP server (http://localhost:8787)',\n type: 'boolean',\n },\n });\n },\n (argv) => {\n const options = { ...argv };\n void (async () => {\n try {\n const { startTUI } = await import('./src/ui/tui/start-tui.js');\n const { buildSession } = await import(\n './src/lib/wizard-session.js'\n );\n\n const { Flow } = await import('./src/ui/tui/router.js');\n const tui = startTUI(WIZARD_VERSION, Flow.McpRemove);\n const session = buildSession({\n debug: options.debug,\n localMcp: options.local,\n });\n tui.store.session = session;\n } catch {\n // TUI unavailable — fallback to logging\n setUI(new LoggingUI());\n const { removeMCPServerFromClientsStep } = await import(\n './src/steps/add-mcp-server-to-clients/index.js'\n );\n await removeMCPServerFromClientsStep({\n local: options.local,\n });\n }\n })();\n },\n )\n .demandCommand(1, 'You must specify a subcommand (add or remove)')\n .help();\n })\n .help()\n .alias('help', 'h')\n .version()\n .alias('version', 'v')\n .wrap(process.stdout.isTTY ? yargs.terminalWidth() : 80).argv;\n"]}
@@ -53,7 +53,7 @@ export declare const WIZARD_VARIANT_FLAG_KEY = "wizard-variant";
53
53
  /** Variant key -> metadata for wizard run (VARIANT flag selects which entry to use). */
54
54
  export declare const WIZARD_VARIANTS: Record<string, Record<string, string>>;
55
55
  /** User-Agent for wizard HTTP requests and MCP server identification. */
56
- export declare const WIZARD_USER_AGENT = "posthog/wizard; version: 2.4.0";
56
+ export declare const WIZARD_USER_AGENT = "posthog/wizard; version: 2.5.0";
57
57
  /** Header prefix for PostHog properties (e.g. X-POSTHOG-PROPERTY-VARIANT). */
58
58
  export declare const POSTHOG_PROPERTY_HEADER_PREFIX = "X-POSTHOG-PROPERTY-";
59
59
  /** Header prefix for PostHog feature flags. */
@@ -1 +1 @@
1
- export declare const VERSION = "2.4.0";
1
+ export declare const VERSION = "2.5.0";
@@ -2,5 +2,5 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.VERSION = void 0;
4
4
  // Auto-generated by scripts/generate-version.js — do not edit
5
- exports.VERSION = '2.4.0';
5
+ exports.VERSION = '2.5.0';
6
6
  //# sourceMappingURL=version.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"version.js","sourceRoot":"","sources":["../../../src/lib/version.ts"],"names":[],"mappings":";;;AAAA,8DAA8D;AACjD,QAAA,OAAO,GAAG,OAAO,CAAC","sourcesContent":["// Auto-generated by scripts/generate-version.js — do not edit\nexport const VERSION = '2.4.0';\n"]}
1
+ {"version":3,"file":"version.js","sourceRoot":"","sources":["../../../src/lib/version.ts"],"names":[],"mappings":";;;AAAA,8DAA8D;AACjD,QAAA,OAAO,GAAG,OAAO,CAAC","sourcesContent":["// Auto-generated by scripts/generate-version.js — do not edit\nexport const VERSION = '2.5.0';\n"]}
@@ -65,6 +65,7 @@ export interface WizardSession {
65
65
  ci: boolean;
66
66
  signup: boolean;
67
67
  localMcp: boolean;
68
+ mcpFeatures?: string[];
68
69
  apiKey?: string;
69
70
  menu: boolean;
70
71
  benchmark: boolean;
@@ -120,6 +121,7 @@ export declare function buildSession(args: {
120
121
  ci?: boolean;
121
122
  signup?: boolean;
122
123
  localMcp?: boolean;
124
+ mcpFeatures?: string[];
123
125
  apiKey?: string;
124
126
  menu?: boolean;
125
127
  integration?: Integration;
@@ -76,6 +76,7 @@ function buildSession(args) {
76
76
  ci: args.ci ?? false,
77
77
  signup: args.signup ?? false,
78
78
  localMcp: args.localMcp ?? false,
79
+ mcpFeatures: args.mcpFeatures,
79
80
  apiKey: args.apiKey,
80
81
  menu: args.menu ?? false,
81
82
  benchmark: args.benchmark ?? false,
@@ -1 +1 @@
1
- {"version":3,"file":"wizard-session.js","sourceRoot":"","sources":["../../../src/lib/wizard-session.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * WizardSession — single source of truth for every decision the wizard needs.\n *\n * Populated in layers:\n * CLI args / env vars → populate fields directly\n * Auto-detection → framework, typescript, package manager\n * TUI screens → region, framework disambiguation, etc.\n * OAuth → credentials\n *\n * Business logic reads from the session. Never calls a prompt.\n */\n\nimport type { Integration } from './constants';\nimport type { FrameworkConfig } from './framework-config';\nimport type { WizardReadinessResult } from './health-checks/readiness';\nimport type { SettingsConflict } from './agent-interface';\n\nfunction parseProjectIdArg(value: string | undefined): number | undefined {\n if (value === undefined || value === '') return undefined;\n const n = Number(value);\n return Number.isInteger(n) && n > 0 ? n : undefined;\n}\n\nexport type CloudRegion = 'us' | 'eu';\n\n/** Lifecycle phase of the main work (agent run, MCP install, etc.) */\nexport enum RunPhase {\n /** Still gathering input (intro, setup screens) */\n Idle = 'idle',\n /** Main work is in progress */\n Running = 'running',\n /** Main work finished successfully */\n Completed = 'completed',\n /** Main work finished with an error */\n Error = 'error',\n}\n\n/** Features discovered by the feature-discovery subagent */\nexport enum DiscoveredFeature {\n Stripe = 'stripe',\n LLM = 'llm',\n}\n\n/** Additional features the agent can integrate after the main setup */\nexport enum AdditionalFeature {\n LLM = 'llm',\n}\n\n/** Human-readable labels for additional features (used in TUI progress) */\nexport const ADDITIONAL_FEATURE_LABELS: Record<AdditionalFeature, string> = {\n [AdditionalFeature.LLM]: 'LLM analytics',\n};\n\n/** Agent prompts for each additional feature, injected via the stop hook */\nexport const ADDITIONAL_FEATURE_PROMPTS: Record<AdditionalFeature, string> = {\n [AdditionalFeature.LLM]: `Now integrate LLM analytics with PostHog. Use the PostHog MCP server to find the appropriate LLM analytics skill, install it, and follow its workflow. PostHog basics are already installed. Update the setup report markdown file when complete with additions from this task. `,\n};\n\n/** Outcome of the MCP server installation step */\nexport enum McpOutcome {\n NoClients = 'no_clients',\n Skipped = 'skipped',\n Installed = 'installed',\n Failed = 'failed',\n}\n\n/** Outcome kind for the outro screen */\nexport enum OutroKind {\n Success = 'success',\n Error = 'error',\n Cancel = 'cancel',\n}\n\nexport interface OutroData {\n kind: OutroKind;\n message?: string;\n changes?: string[];\n docsUrl?: string;\n continueUrl?: string;\n}\n\nexport interface WizardSession {\n // From CLI args\n debug: boolean;\n forceInstall: boolean;\n installDir: string;\n ci: boolean;\n signup: boolean;\n localMcp: boolean;\n apiKey?: string;\n menu: boolean;\n benchmark: boolean;\n yaraReport: boolean;\n projectId?: number;\n\n // From detection + screens\n setupConfirmed: boolean;\n integration: Integration | null;\n frameworkContext: Record<string, unknown>;\n typescript: boolean;\n\n /** Human-readable label for the detected framework variant (e.g., \"Django with Wagtail CMS\") */\n detectedFrameworkLabel: string | null;\n\n /** True once framework detection has run (whether it found something or not) */\n detectionComplete: boolean;\n\n /** Set when the detected framework version is too old for the wizard */\n unsupportedVersion: {\n current: string;\n minimum: string;\n docsUrl: string;\n } | null;\n\n // From OAuth\n credentials: {\n accessToken: string;\n projectApiKey: string;\n host: string;\n projectId: number;\n } | null;\n\n // Lifecycle\n runPhase: RunPhase;\n loginUrl: string | null;\n\n // Feature discovery\n discoveredFeatures: DiscoveredFeature[];\n llmOptIn: boolean;\n\n // Screen completion\n mcpComplete: boolean;\n mcpOutcome: McpOutcome | null;\n mcpInstalledClients: string[];\n\n // Runtime\n readinessResult: WizardReadinessResult | null;\n outageDismissed: boolean;\n settingsOverrideKeys: string[] | null;\n settingsConflicts: SettingsConflict[] | null;\n portConflictProcess: { command: string; pid: string; user: string } | null;\n outroData: OutroData | null;\n\n // Additional features queue (drained via stop hook after main integration)\n additionalFeatureQueue: AdditionalFeature[];\n\n // Resolved framework config (set after integration is known)\n frameworkConfig: FrameworkConfig | null;\n}\n\n/**\n * Build a WizardSession from CLI args, pre-populating whatever is known.\n */\nexport function buildSession(args: {\n debug?: boolean;\n forceInstall?: boolean;\n installDir?: string;\n ci?: boolean;\n signup?: boolean;\n localMcp?: boolean;\n apiKey?: string;\n menu?: boolean;\n integration?: Integration;\n benchmark?: boolean;\n yaraReport?: boolean;\n projectId?: string;\n}): WizardSession {\n return {\n debug: args.debug ?? false,\n forceInstall: args.forceInstall ?? false,\n installDir: args.installDir ?? process.cwd(),\n ci: args.ci ?? false,\n signup: args.signup ?? false,\n localMcp: args.localMcp ?? false,\n apiKey: args.apiKey,\n menu: args.menu ?? false,\n benchmark: args.benchmark ?? false,\n yaraReport: args.yaraReport ?? false,\n projectId: parseProjectIdArg(args.projectId),\n\n setupConfirmed: false,\n integration: args.integration ?? null,\n frameworkContext: {},\n typescript: false,\n detectedFrameworkLabel: null,\n detectionComplete: false,\n unsupportedVersion: null,\n\n runPhase: RunPhase.Idle,\n discoveredFeatures: [],\n llmOptIn: false,\n mcpComplete: false,\n mcpOutcome: null,\n mcpInstalledClients: [],\n loginUrl: null,\n credentials: null,\n readinessResult: null,\n outageDismissed: false,\n settingsOverrideKeys: null,\n settingsConflicts: null,\n portConflictProcess: null,\n outroData: null,\n additionalFeatureQueue: [],\n frameworkConfig: null,\n };\n}\n"]}
1
+ {"version":3,"file":"wizard-session.js","sourceRoot":"","sources":["../../../src/lib/wizard-session.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * WizardSession — single source of truth for every decision the wizard needs.\n *\n * Populated in layers:\n * CLI args / env vars → populate fields directly\n * Auto-detection → framework, typescript, package manager\n * TUI screens → region, framework disambiguation, etc.\n * OAuth → credentials\n *\n * Business logic reads from the session. Never calls a prompt.\n */\n\nimport type { Integration } from './constants';\nimport type { FrameworkConfig } from './framework-config';\nimport type { WizardReadinessResult } from './health-checks/readiness';\nimport type { SettingsConflict } from './agent-interface';\n\nfunction parseProjectIdArg(value: string | undefined): number | undefined {\n if (value === undefined || value === '') return undefined;\n const n = Number(value);\n return Number.isInteger(n) && n > 0 ? n : undefined;\n}\n\nexport type CloudRegion = 'us' | 'eu';\n\n/** Lifecycle phase of the main work (agent run, MCP install, etc.) */\nexport enum RunPhase {\n /** Still gathering input (intro, setup screens) */\n Idle = 'idle',\n /** Main work is in progress */\n Running = 'running',\n /** Main work finished successfully */\n Completed = 'completed',\n /** Main work finished with an error */\n Error = 'error',\n}\n\n/** Features discovered by the feature-discovery subagent */\nexport enum DiscoveredFeature {\n Stripe = 'stripe',\n LLM = 'llm',\n}\n\n/** Additional features the agent can integrate after the main setup */\nexport enum AdditionalFeature {\n LLM = 'llm',\n}\n\n/** Human-readable labels for additional features (used in TUI progress) */\nexport const ADDITIONAL_FEATURE_LABELS: Record<AdditionalFeature, string> = {\n [AdditionalFeature.LLM]: 'LLM analytics',\n};\n\n/** Agent prompts for each additional feature, injected via the stop hook */\nexport const ADDITIONAL_FEATURE_PROMPTS: Record<AdditionalFeature, string> = {\n [AdditionalFeature.LLM]: `Now integrate LLM analytics with PostHog. Use the PostHog MCP server to find the appropriate LLM analytics skill, install it, and follow its workflow. PostHog basics are already installed. Update the setup report markdown file when complete with additions from this task. `,\n};\n\n/** Outcome of the MCP server installation step */\nexport enum McpOutcome {\n NoClients = 'no_clients',\n Skipped = 'skipped',\n Installed = 'installed',\n Failed = 'failed',\n}\n\n/** Outcome kind for the outro screen */\nexport enum OutroKind {\n Success = 'success',\n Error = 'error',\n Cancel = 'cancel',\n}\n\nexport interface OutroData {\n kind: OutroKind;\n message?: string;\n changes?: string[];\n docsUrl?: string;\n continueUrl?: string;\n}\n\nexport interface WizardSession {\n // From CLI args\n debug: boolean;\n forceInstall: boolean;\n installDir: string;\n ci: boolean;\n signup: boolean;\n localMcp: boolean;\n mcpFeatures?: string[];\n apiKey?: string;\n menu: boolean;\n benchmark: boolean;\n yaraReport: boolean;\n projectId?: number;\n\n // From detection + screens\n setupConfirmed: boolean;\n integration: Integration | null;\n frameworkContext: Record<string, unknown>;\n typescript: boolean;\n\n /** Human-readable label for the detected framework variant (e.g., \"Django with Wagtail CMS\") */\n detectedFrameworkLabel: string | null;\n\n /** True once framework detection has run (whether it found something or not) */\n detectionComplete: boolean;\n\n /** Set when the detected framework version is too old for the wizard */\n unsupportedVersion: {\n current: string;\n minimum: string;\n docsUrl: string;\n } | null;\n\n // From OAuth\n credentials: {\n accessToken: string;\n projectApiKey: string;\n host: string;\n projectId: number;\n } | null;\n\n // Lifecycle\n runPhase: RunPhase;\n loginUrl: string | null;\n\n // Feature discovery\n discoveredFeatures: DiscoveredFeature[];\n llmOptIn: boolean;\n\n // Screen completion\n mcpComplete: boolean;\n mcpOutcome: McpOutcome | null;\n mcpInstalledClients: string[];\n\n // Runtime\n readinessResult: WizardReadinessResult | null;\n outageDismissed: boolean;\n settingsOverrideKeys: string[] | null;\n settingsConflicts: SettingsConflict[] | null;\n portConflictProcess: { command: string; pid: string; user: string } | null;\n outroData: OutroData | null;\n\n // Additional features queue (drained via stop hook after main integration)\n additionalFeatureQueue: AdditionalFeature[];\n\n // Resolved framework config (set after integration is known)\n frameworkConfig: FrameworkConfig | null;\n}\n\n/**\n * Build a WizardSession from CLI args, pre-populating whatever is known.\n */\nexport function buildSession(args: {\n debug?: boolean;\n forceInstall?: boolean;\n installDir?: string;\n ci?: boolean;\n signup?: boolean;\n localMcp?: boolean;\n mcpFeatures?: string[];\n apiKey?: string;\n menu?: boolean;\n integration?: Integration;\n benchmark?: boolean;\n yaraReport?: boolean;\n projectId?: string;\n}): WizardSession {\n return {\n debug: args.debug ?? false,\n forceInstall: args.forceInstall ?? false,\n installDir: args.installDir ?? process.cwd(),\n ci: args.ci ?? false,\n signup: args.signup ?? false,\n localMcp: args.localMcp ?? false,\n mcpFeatures: args.mcpFeatures,\n apiKey: args.apiKey,\n menu: args.menu ?? false,\n benchmark: args.benchmark ?? false,\n yaraReport: args.yaraReport ?? false,\n projectId: parseProjectIdArg(args.projectId),\n\n setupConfirmed: false,\n integration: args.integration ?? null,\n frameworkContext: {},\n typescript: false,\n detectedFrameworkLabel: null,\n detectionComplete: false,\n unsupportedVersion: null,\n\n runPhase: RunPhase.Idle,\n discoveredFeatures: [],\n llmOptIn: false,\n mcpComplete: false,\n mcpOutcome: null,\n mcpInstalledClients: [],\n loginUrl: null,\n credentials: null,\n readinessResult: null,\n outageDismissed: false,\n settingsOverrideKeys: null,\n settingsConflicts: null,\n portConflictProcess: null,\n outroData: null,\n additionalFeatureQueue: [],\n frameworkConfig: null,\n };\n}\n"]}
@@ -138,7 +138,12 @@ class ClaudeCodeMCPClient extends MCPClient_1.DefaultMCPClient {
138
138
  (0, child_process_1.execSync)(command);
139
139
  }
140
140
  catch (error) {
141
- analytics_1.analytics.captureException(new Error(`Failed to add server to Claude Code: ${error instanceof Error ? error.message : String(error)}`));
141
+ const msg = error instanceof Error ? error.message : String(error);
142
+ // "already exists" means a previous install succeeded, treat as success
143
+ if (msg.includes('already exists')) {
144
+ return Promise.resolve({ success: true });
145
+ }
146
+ analytics_1.analytics.captureException(new Error(`Failed to add server to Claude Code: ${msg}`));
142
147
  return Promise.resolve({ success: false });
143
148
  }
144
149
  return Promise.resolve({ success: true });
@@ -1 +1 @@
1
- {"version":3,"file":"claude-code.js","sourceRoot":"","sources":["../../../../../src/steps/add-mcp-server-to-clients/clients/claude-code.ts"],"names":[],"mappings":"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","sourcesContent":["import { DefaultMCPClient } from '../MCPClient';\nimport { buildMCPUrl, DefaultMCPClientConfig } from '../defaults';\nimport { z } from 'zod';\nimport { execSync } from 'child_process';\nimport { analytics } from '../../../utils/analytics';\nimport { debug } from '../../../utils/debug';\nimport * as os from 'os';\nimport * as path from 'path';\nimport * as fs from 'fs';\n\nexport const ClaudeCodeMCPConfig = DefaultMCPClientConfig;\n\nexport type ClaudeCodeMCPConfig = z.infer<typeof DefaultMCPClientConfig>;\n\nexport class ClaudeCodeMCPClient extends DefaultMCPClient {\n name = 'Claude Code';\n private claudeBinaryPath: string | null = null;\n\n constructor() {\n super();\n }\n\n private findClaudeBinary(): string | null {\n if (this.claudeBinaryPath) {\n return this.claudeBinaryPath;\n }\n\n // Common installation paths for Claude Code CLI\n const possiblePaths = [\n path.join(os.homedir(), '.claude', 'local', 'claude'),\n '/usr/local/bin/claude',\n '/opt/homebrew/bin/claude',\n ];\n\n for (const claudePath of possiblePaths) {\n if (fs.existsSync(claudePath)) {\n debug(` Found claude binary at: ${claudePath}`);\n this.claudeBinaryPath = claudePath;\n return claudePath;\n }\n }\n\n // Try PATH as fallback\n try {\n execSync('command -v claude', { stdio: 'pipe' });\n debug(' Found claude in PATH');\n this.claudeBinaryPath = 'claude';\n return 'claude';\n } catch {\n // Not in PATH\n }\n\n return null;\n }\n\n isClientSupported(): Promise<boolean> {\n try {\n debug(' Checking for Claude Code...');\n const claudeBinary = this.findClaudeBinary();\n\n if (!claudeBinary) {\n debug(' Claude Code not found. Installation paths checked:');\n debug(` - ${path.join(os.homedir(), '.claude', 'local', 'claude')}`);\n debug(` - /usr/local/bin/claude`);\n debug(` - /opt/homebrew/bin/claude`);\n debug(` - PATH`);\n return Promise.resolve(false);\n }\n\n const output = execSync(`${claudeBinary} --version`, { stdio: 'pipe' });\n const version = output.toString().trim();\n debug(` Claude Code detected: ${version}`);\n return Promise.resolve(true);\n } catch (error) {\n debug(\n ` Claude Code check failed: ${\n error instanceof Error ? error.message : String(error)\n }`,\n );\n return Promise.resolve(false);\n }\n }\n\n isServerInstalled(local?: boolean): Promise<boolean> {\n try {\n const claudeBinary = this.findClaudeBinary();\n if (!claudeBinary) {\n return Promise.resolve(false);\n }\n\n // check if specific server name exists in output\n const output = execSync(`${claudeBinary} mcp list`, {\n stdio: 'pipe',\n });\n\n const outputStr = output.toString();\n const serverName = local ? 'posthog-local' : 'posthog';\n\n if (outputStr.includes(serverName)) {\n return Promise.resolve(true);\n }\n } catch {\n //\n }\n\n return Promise.resolve(false);\n }\n\n getConfigPath(): Promise<string> {\n throw new Error('Not implemented');\n }\n\n addServer(\n apiKey?: string,\n selectedFeatures?: string[],\n local?: boolean,\n ): Promise<{ success: boolean }> {\n const claudeBinary = this.findClaudeBinary();\n if (!claudeBinary) {\n return Promise.resolve({ success: false });\n }\n\n const serverName = local ? 'posthog-local' : 'posthog';\n const url = buildMCPUrl('streamable-http', selectedFeatures, local);\n\n // OAuth mode: no auth header\n const authArgs = apiKey ? `--header \"Authorization: Bearer ${apiKey}\"` : '';\n const command =\n `${claudeBinary} mcp add --transport http ${serverName} ${url} ${authArgs} -s user`.trim();\n\n try {\n execSync(command);\n } catch (error) {\n analytics.captureException(\n new Error(\n `Failed to add server to Claude Code: ${\n error instanceof Error ? error.message : String(error)\n }`,\n ),\n );\n return Promise.resolve({ success: false });\n }\n\n return Promise.resolve({ success: true });\n }\n\n removeServer(local?: boolean): Promise<{ success: boolean }> {\n const claudeBinary = this.findClaudeBinary();\n if (!claudeBinary) {\n return Promise.resolve({ success: false });\n }\n\n const serverName = local ? 'posthog-local' : 'posthog';\n const command = `${claudeBinary} mcp remove --scope user ${serverName}`;\n\n try {\n execSync(command);\n } catch (error) {\n analytics.captureException(\n new Error(\n `Failed to remove server from Claude Code: ${\n error instanceof Error ? error.message : String(error)\n }`,\n ),\n );\n return Promise.resolve({ success: false });\n }\n\n return Promise.resolve({ success: true });\n }\n}\n"]}
1
+ {"version":3,"file":"claude-code.js","sourceRoot":"","sources":["../../../../../src/steps/add-mcp-server-to-clients/clients/claude-code.ts"],"names":[],"mappings":"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","sourcesContent":["import { DefaultMCPClient } from '../MCPClient';\nimport { buildMCPUrl, DefaultMCPClientConfig } from '../defaults';\nimport { z } from 'zod';\nimport { execSync } from 'child_process';\nimport { analytics } from '../../../utils/analytics';\nimport { debug } from '../../../utils/debug';\nimport * as os from 'os';\nimport * as path from 'path';\nimport * as fs from 'fs';\n\nexport const ClaudeCodeMCPConfig = DefaultMCPClientConfig;\n\nexport type ClaudeCodeMCPConfig = z.infer<typeof DefaultMCPClientConfig>;\n\nexport class ClaudeCodeMCPClient extends DefaultMCPClient {\n name = 'Claude Code';\n private claudeBinaryPath: string | null = null;\n\n constructor() {\n super();\n }\n\n private findClaudeBinary(): string | null {\n if (this.claudeBinaryPath) {\n return this.claudeBinaryPath;\n }\n\n // Common installation paths for Claude Code CLI\n const possiblePaths = [\n path.join(os.homedir(), '.claude', 'local', 'claude'),\n '/usr/local/bin/claude',\n '/opt/homebrew/bin/claude',\n ];\n\n for (const claudePath of possiblePaths) {\n if (fs.existsSync(claudePath)) {\n debug(` Found claude binary at: ${claudePath}`);\n this.claudeBinaryPath = claudePath;\n return claudePath;\n }\n }\n\n // Try PATH as fallback\n try {\n execSync('command -v claude', { stdio: 'pipe' });\n debug(' Found claude in PATH');\n this.claudeBinaryPath = 'claude';\n return 'claude';\n } catch {\n // Not in PATH\n }\n\n return null;\n }\n\n isClientSupported(): Promise<boolean> {\n try {\n debug(' Checking for Claude Code...');\n const claudeBinary = this.findClaudeBinary();\n\n if (!claudeBinary) {\n debug(' Claude Code not found. Installation paths checked:');\n debug(` - ${path.join(os.homedir(), '.claude', 'local', 'claude')}`);\n debug(` - /usr/local/bin/claude`);\n debug(` - /opt/homebrew/bin/claude`);\n debug(` - PATH`);\n return Promise.resolve(false);\n }\n\n const output = execSync(`${claudeBinary} --version`, { stdio: 'pipe' });\n const version = output.toString().trim();\n debug(` Claude Code detected: ${version}`);\n return Promise.resolve(true);\n } catch (error) {\n debug(\n ` Claude Code check failed: ${\n error instanceof Error ? error.message : String(error)\n }`,\n );\n return Promise.resolve(false);\n }\n }\n\n isServerInstalled(local?: boolean): Promise<boolean> {\n try {\n const claudeBinary = this.findClaudeBinary();\n if (!claudeBinary) {\n return Promise.resolve(false);\n }\n\n // check if specific server name exists in output\n const output = execSync(`${claudeBinary} mcp list`, {\n stdio: 'pipe',\n });\n\n const outputStr = output.toString();\n const serverName = local ? 'posthog-local' : 'posthog';\n\n if (outputStr.includes(serverName)) {\n return Promise.resolve(true);\n }\n } catch {\n //\n }\n\n return Promise.resolve(false);\n }\n\n getConfigPath(): Promise<string> {\n throw new Error('Not implemented');\n }\n\n addServer(\n apiKey?: string,\n selectedFeatures?: string[],\n local?: boolean,\n ): Promise<{ success: boolean }> {\n const claudeBinary = this.findClaudeBinary();\n if (!claudeBinary) {\n return Promise.resolve({ success: false });\n }\n\n const serverName = local ? 'posthog-local' : 'posthog';\n const url = buildMCPUrl('streamable-http', selectedFeatures, local);\n\n // OAuth mode: no auth header\n const authArgs = apiKey ? `--header \"Authorization: Bearer ${apiKey}\"` : '';\n const command =\n `${claudeBinary} mcp add --transport http ${serverName} ${url} ${authArgs} -s user`.trim();\n\n try {\n execSync(command);\n } catch (error) {\n const msg = error instanceof Error ? error.message : String(error);\n // \"already exists\" means a previous install succeeded, treat as success\n if (msg.includes('already exists')) {\n return Promise.resolve({ success: true });\n }\n analytics.captureException(\n new Error(`Failed to add server to Claude Code: ${msg}`),\n );\n return Promise.resolve({ success: false });\n }\n\n return Promise.resolve({ success: true });\n }\n\n removeServer(local?: boolean): Promise<{ success: boolean }> {\n const claudeBinary = this.findClaudeBinary();\n if (!claudeBinary) {\n return Promise.resolve({ success: false });\n }\n\n const serverName = local ? 'posthog-local' : 'posthog';\n const command = `${claudeBinary} mcp remove --scope user ${serverName}`;\n\n try {\n execSync(command);\n } catch (error) {\n analytics.captureException(\n new Error(\n `Failed to remove server from Claude Code: ${\n error instanceof Error ? error.message : String(error)\n }`,\n ),\n );\n return Promise.resolve({ success: false });\n }\n\n return Promise.resolve({ success: true });\n }\n}\n"]}
@@ -75,11 +75,26 @@ export declare const AVAILABLE_FEATURES: {
75
75
  label: string;
76
76
  hint: string;
77
77
  }[];
78
+ 'AI Engineering': {
79
+ value: string;
80
+ label: string;
81
+ hint: string;
82
+ }[];
78
83
  'Development Tools': {
79
84
  value: string;
80
85
  label: string;
81
86
  hint: string;
82
87
  }[];
88
+ 'Data Management': {
89
+ value: string;
90
+ label: string;
91
+ hint: string;
92
+ }[];
93
+ 'CDP & Automation': {
94
+ value: string;
95
+ label: string;
96
+ hint: string;
97
+ }[];
83
98
  'Platform & Management': {
84
99
  value: string;
85
100
  label: string;
@@ -30,7 +30,7 @@ exports.AVAILABLE_FEATURES = {
30
30
  {
31
31
  value: 'insights',
32
32
  label: 'Insights',
33
- hint: 'Analytics insights and SQL queries',
33
+ hint: 'Analytics insights',
34
34
  },
35
35
  {
36
36
  value: 'experiments',
@@ -38,18 +38,103 @@ exports.AVAILABLE_FEATURES = {
38
38
  hint: 'A/B testing experiments',
39
39
  },
40
40
  {
41
- value: 'llm-analytics',
41
+ value: 'surveys',
42
+ label: 'Surveys',
43
+ hint: 'Survey management',
44
+ },
45
+ {
46
+ value: 'annotations',
47
+ label: 'Annotations',
48
+ hint: 'Annotation management',
49
+ },
50
+ {
51
+ value: 'sql',
52
+ label: 'SQL',
53
+ hint: 'SQL query execution',
54
+ },
55
+ ],
56
+ 'AI Engineering': [
57
+ {
58
+ value: 'llm_analytics',
42
59
  label: 'LLM Analytics',
43
60
  hint: 'LLM usage and cost tracking',
44
61
  },
62
+ {
63
+ value: 'prompts',
64
+ label: 'Prompts',
65
+ hint: 'LLM prompt management',
66
+ },
67
+ {
68
+ value: 'logs',
69
+ label: 'Logs',
70
+ hint: 'Log querying',
71
+ },
45
72
  ],
46
73
  'Development Tools': [
47
74
  {
48
- value: 'error-tracking',
75
+ value: 'error_tracking',
49
76
  label: 'Error Tracking',
50
77
  hint: 'Error monitoring and debugging',
51
78
  },
52
- { value: 'flags', label: 'Feature Flags', hint: 'Feature flag management' },
79
+ {
80
+ value: 'flags',
81
+ label: 'Feature Flags',
82
+ hint: 'Feature flag management',
83
+ },
84
+ {
85
+ value: 'early_access_features',
86
+ label: 'Early Access Features',
87
+ hint: 'Early access feature management',
88
+ },
89
+ {
90
+ value: 'cohorts',
91
+ label: 'Cohorts',
92
+ hint: 'Cohort management',
93
+ },
94
+ ],
95
+ 'Data Management': [
96
+ {
97
+ value: 'events',
98
+ label: 'Events',
99
+ hint: 'Event and property definitions',
100
+ },
101
+ {
102
+ value: 'persons',
103
+ label: 'Persons',
104
+ hint: 'Person and group management',
105
+ },
106
+ {
107
+ value: 'actions',
108
+ label: 'Actions',
109
+ hint: 'Action definitions',
110
+ },
111
+ {
112
+ value: 'data_warehouse',
113
+ label: 'Data Warehouse',
114
+ hint: 'Data warehouse management',
115
+ },
116
+ {
117
+ value: 'data_schema',
118
+ label: 'Data Schema',
119
+ hint: 'Data schema exploration',
120
+ },
121
+ ],
122
+ 'CDP & Automation': [
123
+ {
124
+ value: 'hog_functions',
125
+ label: 'Hog Functions',
126
+ hint: 'CDP function management',
127
+ },
128
+ {
129
+ value: 'hog_function_templates',
130
+ label: 'Hog Function Templates',
131
+ hint: 'CDP function template browsing',
132
+ },
133
+ {
134
+ value: 'workflows',
135
+ label: 'Workflows',
136
+ hint: 'Workflow management',
137
+ },
53
138
  ],
54
139
  'Platform & Management': [
55
140
  {
@@ -62,6 +147,36 @@ exports.AVAILABLE_FEATURES = {
62
147
  label: 'Documentation',
63
148
  hint: 'PostHog documentation search',
64
149
  },
150
+ {
151
+ value: 'notebooks',
152
+ label: 'Notebooks',
153
+ hint: 'Notebook management',
154
+ },
155
+ {
156
+ value: 'alerts',
157
+ label: 'Alerts',
158
+ hint: 'Alert management',
159
+ },
160
+ {
161
+ value: 'activity_logs',
162
+ label: 'Activity Logs',
163
+ hint: 'Activity log viewing',
164
+ },
165
+ {
166
+ value: 'search',
167
+ label: 'Search',
168
+ hint: 'Entity search across the project',
169
+ },
170
+ {
171
+ value: 'reverse_proxy',
172
+ label: 'Reverse Proxy',
173
+ hint: 'Reverse proxy record management',
174
+ },
175
+ {
176
+ value: 'debug',
177
+ label: 'Debug',
178
+ hint: 'Debug and diagnostic tools',
179
+ },
65
180
  ],
66
181
  };
67
182
  exports.ALL_FEATURE_VALUES = Object.values(exports.AVAILABLE_FEATURES)
@@ -1 +1 @@
1
- {"version":3,"file":"defaults.js","sourceRoot":"","sources":["../../../../src/steps/add-mcp-server-to-clients/defaults.ts"],"names":[],"mappings":";;;;;;AAAA,8CAAoB;AAEP,QAAA,sBAAsB,GAAG,aAAC;KACpC,MAAM,CAAC;IACN,UAAU,EAAE,aAAC,CAAC,MAAM,CAClB,aAAC,CAAC,MAAM,EAAE,EACV,aAAC,CAAC,KAAK,CAAC;QACN,aAAC,CAAC,MAAM,CAAC;YACP,OAAO,EAAE,aAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;YAC9B,IAAI,EAAE,aAAC,CAAC,KAAK,CAAC,aAAC,CAAC,MAAM,EAAE,CAAC,CAAC,QAAQ,EAAE;YACpC,GAAG,EAAE,aAAC,CAAC,MAAM,CAAC,aAAC,CAAC,MAAM,EAAE,EAAE,aAAC,CAAC,MAAM,EAAE,CAAC,CAAC,QAAQ,EAAE;SACjD,CAAC;QACF,aAAC,CAAC,MAAM,CAAC;YACP,GAAG,EAAE,aAAC,CAAC,MAAM,EAAE;YACf,OAAO,EAAE,aAAC,CAAC,MAAM,CAAC,aAAC,CAAC,MAAM,EAAE,EAAE,aAAC,CAAC,MAAM,EAAE,CAAC,CAAC,QAAQ,EAAE;SACrD,CAAC;KACH,CAAC,CACH;CACF,CAAC;KACD,WAAW,EAAE,CAAC;AAEJ,QAAA,kBAAkB,GAAG;IAChC,kBAAkB,EAAE;QAClB;YACE,KAAK,EAAE,YAAY;YACnB,KAAK,EAAE,YAAY;YACnB,IAAI,EAAE,mCAAmC;SAC1C;QACD;YACE,KAAK,EAAE,UAAU;YACjB,KAAK,EAAE,UAAU;YACjB,IAAI,EAAE,oCAAoC;SAC3C;QACD;YACE,KAAK,EAAE,aAAa;YACpB,KAAK,EAAE,aAAa;YACpB,IAAI,EAAE,yBAAyB;SAChC;QACD;YACE,KAAK,EAAE,eAAe;YACtB,KAAK,EAAE,eAAe;YACtB,IAAI,EAAE,6BAA6B;SACpC;KACF;IACD,mBAAmB,EAAE;QACnB;YACE,KAAK,EAAE,gBAAgB;YACvB,KAAK,EAAE,gBAAgB;YACvB,IAAI,EAAE,gCAAgC;SACvC;QACD,EAAE,KAAK,EAAE,OAAO,EAAE,KAAK,EAAE,eAAe,EAAE,IAAI,EAAE,yBAAyB,EAAE;KAC5E;IACD,uBAAuB,EAAE;QACvB;YACE,KAAK,EAAE,WAAW;YAClB,KAAK,EAAE,WAAW;YAClB,IAAI,EAAE,qCAAqC;SAC5C;QACD;YACE,KAAK,EAAE,MAAM;YACb,KAAK,EAAE,eAAe;YACtB,IAAI,EAAE,8BAA8B;SACrC;KACF;CACF,CAAC;AAEW,QAAA,kBAAkB,GAAG,MAAM,CAAC,MAAM,CAAC,0BAAkB,CAAC;KAChE,IAAI,EAAE;KACN,GAAG,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;AAI5B,MAAM,WAAW,GAAG,CACzB,IAAmB,EACnB,gBAA2B,EAC3B,KAAe,EACf,EAAE;IACF,MAAM,IAAI,GAAG,KAAK,CAAC,CAAC,CAAC,uBAAuB,CAAC,CAAC,CAAC,yBAAyB,CAAC;IACzE,MAAM,OAAO,GAAG,GAAG,IAAI,IAAI,IAAI,KAAK,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,KAAK,EAAE,CAAC;IAE5D,MAAM,qBAAqB,GACzB,gBAAgB;QAChB,gBAAgB,CAAC,MAAM,KAAK,0BAAkB,CAAC,MAAM;QACrD,0BAAkB,CAAC,KAAK,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,gBAAgB,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC,CAAC;IAE5E,MAAM,MAAM,GAAa,EAAE,CAAC;IAE5B,kDAAkD;IAClD,IACE,gBAAgB;QAChB,gBAAgB,CAAC,MAAM,GAAG,CAAC;QAC3B,CAAC,qBAAqB,EACtB,CAAC;QACD,MAAM,CAAC,IAAI,CAAC,YAAY,gBAAgB,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;IACxD,CAAC;IAED,OAAO,MAAM,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,OAAO,IAAI,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC;AACxE,CAAC,CAAC;AAzBW,QAAA,WAAW,eAyBtB;AAEK,MAAM,yBAAyB,GAAG,CACvC,MAA0B,EAC1B,IAAmB,EACnB,gBAA2B,EAC3B,KAAe,EACf,EAAE;IACF,MAAM,MAAM,GAA4B;QACtC,GAAG,EAAE,IAAA,mBAAW,EAAC,IAAI,EAAE,gBAAgB,EAAE,KAAK,CAAC;KAChD,CAAC;IAEF,+DAA+D;IAC/D,IAAI,MAAM,EAAE,CAAC;QACX,MAAM,CAAC,OAAO,GAAG;YACf,aAAa,EAAE,UAAU,MAAM,EAAE;SAClC,CAAC;IACJ,CAAC;IAED,OAAO,MAAM,CAAC;AAChB,CAAC,CAAC;AAlBW,QAAA,yBAAyB,6BAkBpC;AAEK,MAAM,sBAAsB,GAAG,CACpC,MAA0B,EAC1B,IAAmB,EACnB,gBAA2B,EAC3B,KAAe,EACf,EAAE;IACF,MAAM,eAAe,GAAG,IAAA,mBAAW,EAAC,IAAI,EAAE,gBAAgB,EAAE,KAAK,CAAC,CAAC;IAEnE,mDAAmD;IACnD,IAAI,CAAC,MAAM,EAAE,CAAC;QACZ,OAAO;YACL,OAAO,EAAE,KAAK;YACd,IAAI,EAAE,CAAC,IAAI,EAAE,mBAAmB,EAAE,eAAe,CAAC;SACnD,CAAC;IACJ,CAAC;IAED,oCAAoC;IACpC,OAAO;QACL,OAAO,EAAE,KAAK;QACd,IAAI,EAAE;YACJ,IAAI;YACJ,mBAAmB;YACnB,eAAe;YACf,UAAU;YACV,uCAAuC;SACxC;QACD,GAAG,EAAE;YACH,mBAAmB,EAAE,UAAU,MAAM,EAAE;SACxC;KACF,CAAC;AACJ,CAAC,CAAC;AA9BW,QAAA,sBAAsB,0BA8BjC","sourcesContent":["import z from 'zod';\n\nexport const DefaultMCPClientConfig = z\n .object({\n mcpServers: z.record(\n z.string(),\n z.union([\n z.object({\n command: z.string().optional(),\n args: z.array(z.string()).optional(),\n env: z.record(z.string(), z.string()).optional(),\n }),\n z.object({\n url: z.string(),\n headers: z.record(z.string(), z.string()).optional(),\n }),\n ]),\n ),\n })\n .passthrough();\n\nexport const AVAILABLE_FEATURES = {\n 'Data & Analytics': [\n {\n value: 'dashboards',\n label: 'Dashboards',\n hint: 'Dashboard creation and management',\n },\n {\n value: 'insights',\n label: 'Insights',\n hint: 'Analytics insights and SQL queries',\n },\n {\n value: 'experiments',\n label: 'Experiments',\n hint: 'A/B testing experiments',\n },\n {\n value: 'llm-analytics',\n label: 'LLM Analytics',\n hint: 'LLM usage and cost tracking',\n },\n ],\n 'Development Tools': [\n {\n value: 'error-tracking',\n label: 'Error Tracking',\n hint: 'Error monitoring and debugging',\n },\n { value: 'flags', label: 'Feature Flags', hint: 'Feature flag management' },\n ],\n 'Platform & Management': [\n {\n value: 'workspace',\n label: 'Workspace',\n hint: 'Organization and project management',\n },\n {\n value: 'docs',\n label: 'Documentation',\n hint: 'PostHog documentation search',\n },\n ],\n};\n\nexport const ALL_FEATURE_VALUES = Object.values(AVAILABLE_FEATURES)\n .flat()\n .map((feature) => feature.value);\n\ntype MCPServerType = 'sse' | 'streamable-http';\n\nexport const buildMCPUrl = (\n type: MCPServerType,\n selectedFeatures?: string[],\n local?: boolean,\n) => {\n const host = local ? 'http://localhost:8787' : 'https://mcp.posthog.com';\n const baseUrl = `${host}/${type === 'sse' ? 'sse' : 'mcp'}`;\n\n const isAllFeaturesSelected =\n selectedFeatures &&\n selectedFeatures.length === ALL_FEATURE_VALUES.length &&\n ALL_FEATURE_VALUES.every((feature) => selectedFeatures.includes(feature));\n\n const params: string[] = [];\n\n // Add features param if not all features selected\n if (\n selectedFeatures &&\n selectedFeatures.length > 0 &&\n !isAllFeaturesSelected\n ) {\n params.push(`features=${selectedFeatures.join(',')}`);\n }\n\n return params.length > 0 ? `${baseUrl}?${params.join('&')}` : baseUrl;\n};\n\nexport const getNativeHTTPServerConfig = (\n apiKey: string | undefined,\n type: MCPServerType,\n selectedFeatures?: string[],\n local?: boolean,\n) => {\n const config: Record<string, unknown> = {\n url: buildMCPUrl(type, selectedFeatures, local),\n };\n\n // Only add auth header if API key is provided (not OAuth mode)\n if (apiKey) {\n config.headers = {\n Authorization: `Bearer ${apiKey}`,\n };\n }\n\n return config;\n};\n\nexport const getDefaultServerConfig = (\n apiKey: string | undefined,\n type: MCPServerType,\n selectedFeatures?: string[],\n local?: boolean,\n) => {\n const urlWithFeatures = buildMCPUrl(type, selectedFeatures, local);\n\n // OAuth mode: no auth header, let MCP handle OAuth\n if (!apiKey) {\n return {\n command: 'npx',\n args: ['-y', 'mcp-remote@latest', urlWithFeatures],\n };\n }\n\n // API key mode: include auth header\n return {\n command: 'npx',\n args: [\n '-y',\n 'mcp-remote@latest',\n urlWithFeatures,\n '--header',\n `Authorization:\\${POSTHOG_AUTH_HEADER}`,\n ],\n env: {\n POSTHOG_AUTH_HEADER: `Bearer ${apiKey}`,\n },\n };\n};\n"]}
1
+ {"version":3,"file":"defaults.js","sourceRoot":"","sources":["../../../../src/steps/add-mcp-server-to-clients/defaults.ts"],"names":[],"mappings":"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","sourcesContent":["import z from 'zod';\n\nexport const DefaultMCPClientConfig = z\n .object({\n mcpServers: z.record(\n z.string(),\n z.union([\n z.object({\n command: z.string().optional(),\n args: z.array(z.string()).optional(),\n env: z.record(z.string(), z.string()).optional(),\n }),\n z.object({\n url: z.string(),\n headers: z.record(z.string(), z.string()).optional(),\n }),\n ]),\n ),\n })\n .passthrough();\n\nexport const AVAILABLE_FEATURES = {\n 'Data & Analytics': [\n {\n value: 'dashboards',\n label: 'Dashboards',\n hint: 'Dashboard creation and management',\n },\n {\n value: 'insights',\n label: 'Insights',\n hint: 'Analytics insights',\n },\n {\n value: 'experiments',\n label: 'Experiments',\n hint: 'A/B testing experiments',\n },\n {\n value: 'surveys',\n label: 'Surveys',\n hint: 'Survey management',\n },\n {\n value: 'annotations',\n label: 'Annotations',\n hint: 'Annotation management',\n },\n {\n value: 'sql',\n label: 'SQL',\n hint: 'SQL query execution',\n },\n ],\n 'AI Engineering': [\n {\n value: 'llm_analytics',\n label: 'LLM Analytics',\n hint: 'LLM usage and cost tracking',\n },\n {\n value: 'prompts',\n label: 'Prompts',\n hint: 'LLM prompt management',\n },\n {\n value: 'logs',\n label: 'Logs',\n hint: 'Log querying',\n },\n ],\n 'Development Tools': [\n {\n value: 'error_tracking',\n label: 'Error Tracking',\n hint: 'Error monitoring and debugging',\n },\n {\n value: 'flags',\n label: 'Feature Flags',\n hint: 'Feature flag management',\n },\n {\n value: 'early_access_features',\n label: 'Early Access Features',\n hint: 'Early access feature management',\n },\n {\n value: 'cohorts',\n label: 'Cohorts',\n hint: 'Cohort management',\n },\n ],\n 'Data Management': [\n {\n value: 'events',\n label: 'Events',\n hint: 'Event and property definitions',\n },\n {\n value: 'persons',\n label: 'Persons',\n hint: 'Person and group management',\n },\n {\n value: 'actions',\n label: 'Actions',\n hint: 'Action definitions',\n },\n {\n value: 'data_warehouse',\n label: 'Data Warehouse',\n hint: 'Data warehouse management',\n },\n {\n value: 'data_schema',\n label: 'Data Schema',\n hint: 'Data schema exploration',\n },\n ],\n 'CDP & Automation': [\n {\n value: 'hog_functions',\n label: 'Hog Functions',\n hint: 'CDP function management',\n },\n {\n value: 'hog_function_templates',\n label: 'Hog Function Templates',\n hint: 'CDP function template browsing',\n },\n {\n value: 'workflows',\n label: 'Workflows',\n hint: 'Workflow management',\n },\n ],\n 'Platform & Management': [\n {\n value: 'workspace',\n label: 'Workspace',\n hint: 'Organization and project management',\n },\n {\n value: 'docs',\n label: 'Documentation',\n hint: 'PostHog documentation search',\n },\n {\n value: 'notebooks',\n label: 'Notebooks',\n hint: 'Notebook management',\n },\n {\n value: 'alerts',\n label: 'Alerts',\n hint: 'Alert management',\n },\n {\n value: 'activity_logs',\n label: 'Activity Logs',\n hint: 'Activity log viewing',\n },\n {\n value: 'search',\n label: 'Search',\n hint: 'Entity search across the project',\n },\n {\n value: 'reverse_proxy',\n label: 'Reverse Proxy',\n hint: 'Reverse proxy record management',\n },\n {\n value: 'debug',\n label: 'Debug',\n hint: 'Debug and diagnostic tools',\n },\n ],\n};\n\nexport const ALL_FEATURE_VALUES = Object.values(AVAILABLE_FEATURES)\n .flat()\n .map((feature) => feature.value);\n\ntype MCPServerType = 'sse' | 'streamable-http';\n\nexport const buildMCPUrl = (\n type: MCPServerType,\n selectedFeatures?: string[],\n local?: boolean,\n) => {\n const host = local ? 'http://localhost:8787' : 'https://mcp.posthog.com';\n const baseUrl = `${host}/${type === 'sse' ? 'sse' : 'mcp'}`;\n\n const isAllFeaturesSelected =\n selectedFeatures &&\n selectedFeatures.length === ALL_FEATURE_VALUES.length &&\n ALL_FEATURE_VALUES.every((feature) => selectedFeatures.includes(feature));\n\n const params: string[] = [];\n\n // Add features param if not all features selected\n if (\n selectedFeatures &&\n selectedFeatures.length > 0 &&\n !isAllFeaturesSelected\n ) {\n params.push(`features=${selectedFeatures.join(',')}`);\n }\n\n return params.length > 0 ? `${baseUrl}?${params.join('&')}` : baseUrl;\n};\n\nexport const getNativeHTTPServerConfig = (\n apiKey: string | undefined,\n type: MCPServerType,\n selectedFeatures?: string[],\n local?: boolean,\n) => {\n const config: Record<string, unknown> = {\n url: buildMCPUrl(type, selectedFeatures, local),\n };\n\n // Only add auth header if API key is provided (not OAuth mode)\n if (apiKey) {\n config.headers = {\n Authorization: `Bearer ${apiKey}`,\n };\n }\n\n return config;\n};\n\nexport const getDefaultServerConfig = (\n apiKey: string | undefined,\n type: MCPServerType,\n selectedFeatures?: string[],\n local?: boolean,\n) => {\n const urlWithFeatures = buildMCPUrl(type, selectedFeatures, local);\n\n // OAuth mode: no auth header, let MCP handle OAuth\n if (!apiKey) {\n return {\n command: 'npx',\n args: ['-y', 'mcp-remote@latest', urlWithFeatures],\n };\n }\n\n // API key mode: include auth header\n return {\n command: 'npx',\n args: [\n '-y',\n 'mcp-remote@latest',\n urlWithFeatures,\n '--header',\n `Authorization:\\${POSTHOG_AUTH_HEADER}`,\n ],\n env: {\n POSTHOG_AUTH_HEADER: `Bearer ${apiKey}`,\n },\n };\n};\n"]}
@@ -5,11 +5,12 @@ export declare const getSupportedClients: () => Promise<MCPClient[]>;
5
5
  * Add MCP server to clients. No prompts — pure orchestration.
6
6
  * Prompts are handled by McpScreen (TUI) or auto-accepted (CI).
7
7
  */
8
- export declare const addMCPServerToClientsStep: ({ integration, local, ci, cloudRegion: _cloudRegion, }: {
8
+ export declare const addMCPServerToClientsStep: ({ integration, local, ci, cloudRegion: _cloudRegion, features, }: {
9
9
  integration?: Integration;
10
10
  local?: boolean;
11
11
  ci?: boolean;
12
12
  cloudRegion?: import("../../utils/types").CloudRegion;
13
+ features?: string[];
13
14
  }) => Promise<string[]>;
14
15
  export declare const removeMCPServerFromClientsStep: ({ integration, local, }: {
15
16
  integration?: Integration;
@@ -40,7 +40,7 @@ exports.getSupportedClients = getSupportedClients;
40
40
  * Add MCP server to clients. No prompts — pure orchestration.
41
41
  * Prompts are handled by McpScreen (TUI) or auto-accepted (CI).
42
42
  */
43
- const addMCPServerToClientsStep = async ({ integration, local = false, ci = false, cloudRegion: _cloudRegion, }) => {
43
+ const addMCPServerToClientsStep = async ({ integration, local = false, ci = false, cloudRegion: _cloudRegion, features, }) => {
44
44
  const ui = (0, ui_1.getUI)();
45
45
  // CI mode: skip MCP installation entirely
46
46
  if (ci) {
@@ -54,7 +54,7 @@ const addMCPServerToClientsStep = async ({ integration, local = false, ci = fals
54
54
  }
55
55
  // Auto-install to all supported clients
56
56
  await (0, telemetry_1.traceStep)('adding mcp servers', async () => {
57
- await (0, exports.addMCPServer)(supportedClients, undefined, [...defaults_1.ALL_FEATURE_VALUES], local);
57
+ await (0, exports.addMCPServer)(supportedClients, undefined, features ?? [...defaults_1.ALL_FEATURE_VALUES], local);
58
58
  });
59
59
  ui.log.success(`Added the MCP server to:
60
60
  ${supportedClients.map((c) => `- ${c.name}`).join('\n ')} `);
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../src/steps/add-mcp-server-to-clients/index.ts"],"names":[],"mappings":"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","sourcesContent":["import type { Integration } from '../../lib/constants';\nimport { traceStep } from '../../telemetry';\nimport { analytics } from '../../utils/analytics';\nimport { getUI } from '../../ui';\nimport { MCPClient } from './MCPClient';\nimport { CursorMCPClient } from './clients/cursor';\nimport { ClaudeMCPClient } from './clients/claude';\nimport { ClaudeCodeMCPClient } from './clients/claude-code';\nimport { VisualStudioCodeClient } from './clients/visual-studio-code';\nimport { ZedClient } from './clients/zed';\nimport { CodexMCPClient } from './clients/codex';\nimport { ALL_FEATURE_VALUES } from './defaults';\nimport { debug } from '../../utils/debug';\n\nexport const getSupportedClients = async (): Promise<MCPClient[]> => {\n const allClients = [\n new CursorMCPClient(),\n new ClaudeMCPClient(),\n new ClaudeCodeMCPClient(),\n new VisualStudioCodeClient(),\n new ZedClient(),\n new CodexMCPClient(),\n ];\n const supportedClients: MCPClient[] = [];\n\n debug('Checking for supported MCP clients...');\n for (const client of allClients) {\n const isSupported = await client.isClientSupported();\n debug(`${client.name}: ${isSupported ? '✓ supported' : '✗ not supported'}`);\n if (isSupported) {\n supportedClients.push(client);\n }\n }\n debug(\n `Found ${supportedClients.length} supported client(s): ${supportedClients\n .map((c) => c.name)\n .join(', ')}`,\n );\n\n return supportedClients;\n};\n\n/**\n * Add MCP server to clients. No prompts — pure orchestration.\n * Prompts are handled by McpScreen (TUI) or auto-accepted (CI).\n */\nexport const addMCPServerToClientsStep = async ({\n integration,\n local = false,\n ci = false,\n cloudRegion: _cloudRegion,\n}: {\n integration?: Integration;\n local?: boolean;\n ci?: boolean;\n cloudRegion?: import('../../utils/types').CloudRegion;\n}): Promise<string[]> => {\n const ui = getUI();\n\n // CI mode: skip MCP installation entirely\n if (ci) {\n ui.log.info('Skipping MCP installation (CI mode)');\n return [];\n }\n\n const supportedClients = await getSupportedClients();\n\n if (supportedClients.length === 0) {\n ui.log.info(\n 'No supported MCP clients detected. Skipping MCP installation.',\n );\n return [];\n }\n\n // Auto-install to all supported clients\n await traceStep('adding mcp servers', async () => {\n await addMCPServer(\n supportedClients,\n undefined,\n [...ALL_FEATURE_VALUES],\n local,\n );\n });\n\n ui.log.success(\n `Added the MCP server to:\n ${supportedClients.map((c) => `- ${c.name}`).join('\\n ')} `,\n );\n\n analytics.wizardCapture('mcp servers added', {\n clients: supportedClients.map((c) => c.name),\n integration,\n });\n\n return supportedClients.map((c) => c.name);\n};\n\nexport const removeMCPServerFromClientsStep = async ({\n integration,\n local = false,\n}: {\n integration?: Integration;\n local?: boolean;\n}): Promise<string[]> => {\n const installedClients = await getInstalledClients(local);\n if (installedClients.length === 0) {\n analytics.wizardCapture('mcp no servers to remove', {\n integration,\n });\n return [];\n }\n\n // Auto-remove from all installed clients\n const results = await traceStep('removing mcp servers', async () => {\n await removeMCPServer(installedClients, local);\n return installedClients.map((c) => c.name);\n });\n\n analytics.wizardCapture('mcp servers removed', {\n clients: results,\n integration,\n });\n\n return results;\n};\n\nexport const getInstalledClients = async (\n local?: boolean,\n): Promise<MCPClient[]> => {\n const clients = await getSupportedClients();\n const installedClients: MCPClient[] = [];\n\n for (const client of clients) {\n if (await client.isServerInstalled(local)) {\n installedClients.push(client);\n }\n }\n\n return installedClients;\n};\n\nexport const addMCPServer = async (\n clients: MCPClient[],\n personalApiKey?: string,\n selectedFeatures?: string[],\n local?: boolean,\n): Promise<void> => {\n for (const client of clients) {\n await client.addServer(personalApiKey, selectedFeatures, local);\n }\n};\n\nexport const removeMCPServer = async (\n clients: MCPClient[],\n local?: boolean,\n): Promise<void> => {\n for (const client of clients) {\n await client.removeServer(local);\n }\n};\n"]}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../src/steps/add-mcp-server-to-clients/index.ts"],"names":[],"mappings":"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","sourcesContent":["import type { Integration } from '../../lib/constants';\nimport { traceStep } from '../../telemetry';\nimport { analytics } from '../../utils/analytics';\nimport { getUI } from '../../ui';\nimport { MCPClient } from './MCPClient';\nimport { CursorMCPClient } from './clients/cursor';\nimport { ClaudeMCPClient } from './clients/claude';\nimport { ClaudeCodeMCPClient } from './clients/claude-code';\nimport { VisualStudioCodeClient } from './clients/visual-studio-code';\nimport { ZedClient } from './clients/zed';\nimport { CodexMCPClient } from './clients/codex';\nimport { ALL_FEATURE_VALUES } from './defaults';\nimport { debug } from '../../utils/debug';\n\nexport const getSupportedClients = async (): Promise<MCPClient[]> => {\n const allClients = [\n new CursorMCPClient(),\n new ClaudeMCPClient(),\n new ClaudeCodeMCPClient(),\n new VisualStudioCodeClient(),\n new ZedClient(),\n new CodexMCPClient(),\n ];\n const supportedClients: MCPClient[] = [];\n\n debug('Checking for supported MCP clients...');\n for (const client of allClients) {\n const isSupported = await client.isClientSupported();\n debug(`${client.name}: ${isSupported ? '✓ supported' : '✗ not supported'}`);\n if (isSupported) {\n supportedClients.push(client);\n }\n }\n debug(\n `Found ${supportedClients.length} supported client(s): ${supportedClients\n .map((c) => c.name)\n .join(', ')}`,\n );\n\n return supportedClients;\n};\n\n/**\n * Add MCP server to clients. No prompts — pure orchestration.\n * Prompts are handled by McpScreen (TUI) or auto-accepted (CI).\n */\nexport const addMCPServerToClientsStep = async ({\n integration,\n local = false,\n ci = false,\n cloudRegion: _cloudRegion,\n features,\n}: {\n integration?: Integration;\n local?: boolean;\n ci?: boolean;\n cloudRegion?: import('../../utils/types').CloudRegion;\n features?: string[];\n}): Promise<string[]> => {\n const ui = getUI();\n\n // CI mode: skip MCP installation entirely\n if (ci) {\n ui.log.info('Skipping MCP installation (CI mode)');\n return [];\n }\n\n const supportedClients = await getSupportedClients();\n\n if (supportedClients.length === 0) {\n ui.log.info(\n 'No supported MCP clients detected. Skipping MCP installation.',\n );\n return [];\n }\n\n // Auto-install to all supported clients\n await traceStep('adding mcp servers', async () => {\n await addMCPServer(\n supportedClients,\n undefined,\n features ?? [...ALL_FEATURE_VALUES],\n local,\n );\n });\n\n ui.log.success(\n `Added the MCP server to:\n ${supportedClients.map((c) => `- ${c.name}`).join('\\n ')} `,\n );\n\n analytics.wizardCapture('mcp servers added', {\n clients: supportedClients.map((c) => c.name),\n integration,\n });\n\n return supportedClients.map((c) => c.name);\n};\n\nexport const removeMCPServerFromClientsStep = async ({\n integration,\n local = false,\n}: {\n integration?: Integration;\n local?: boolean;\n}): Promise<string[]> => {\n const installedClients = await getInstalledClients(local);\n if (installedClients.length === 0) {\n analytics.wizardCapture('mcp no servers to remove', {\n integration,\n });\n return [];\n }\n\n // Auto-remove from all installed clients\n const results = await traceStep('removing mcp servers', async () => {\n await removeMCPServer(installedClients, local);\n return installedClients.map((c) => c.name);\n });\n\n analytics.wizardCapture('mcp servers removed', {\n clients: results,\n integration,\n });\n\n return results;\n};\n\nexport const getInstalledClients = async (\n local?: boolean,\n): Promise<MCPClient[]> => {\n const clients = await getSupportedClients();\n const installedClients: MCPClient[] = [];\n\n for (const client of clients) {\n if (await client.isServerInstalled(local)) {\n installedClients.push(client);\n }\n }\n\n return installedClients;\n};\n\nexport const addMCPServer = async (\n clients: MCPClient[],\n personalApiKey?: string,\n selectedFeatures?: string[],\n local?: boolean,\n): Promise<void> => {\n for (const client of clients) {\n await client.addServer(personalApiKey, selectedFeatures, local);\n }\n};\n\nexport const removeMCPServer = async (\n clients: MCPClient[],\n local?: boolean,\n): Promise<void> => {\n for (const client of clients) {\n await client.removeServer(local);\n }\n};\n"]}
@@ -0,0 +1,20 @@
1
+ /**
2
+ * GroupedPickerMenu — Multi-select with category headers.
3
+ *
4
+ * Renders groups of options with bold category labels.
5
+ * Arrow keys navigate selectable items (headers are skipped),
6
+ * space toggles, "a" toggles all, enter submits.
7
+ */
8
+ interface GroupOption {
9
+ value: string;
10
+ label: string;
11
+ hint?: string;
12
+ }
13
+ interface GroupedPickerMenuProps {
14
+ message?: string;
15
+ groups: Record<string, GroupOption[]>;
16
+ initialSelected?: string[];
17
+ onSelect: (values: string[]) => void;
18
+ }
19
+ export declare const GroupedPickerMenu: ({ message, groups, initialSelected, onSelect, }: GroupedPickerMenuProps) => import("react/jsx-runtime").JSX.Element;
20
+ export {};
@@ -0,0 +1,77 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ /**
3
+ * GroupedPickerMenu — Multi-select with category headers.
4
+ *
5
+ * Renders groups of options with bold category labels.
6
+ * Arrow keys navigate selectable items (headers are skipped),
7
+ * space toggles, "a" toggles all, enter submits.
8
+ */
9
+ import { Box, Text, useInput } from 'ink';
10
+ import { useState, useMemo } from 'react';
11
+ import { Icons, Colors } from '../styles.js';
12
+ import { PromptLabel } from './PromptLabel.js';
13
+ export const GroupedPickerMenu = ({ message, groups, initialSelected, onSelect, }) => {
14
+ // Build a flat row list with headers interleaved
15
+ const rows = useMemo(() => {
16
+ const result = [];
17
+ for (const [groupName, options] of Object.entries(groups)) {
18
+ result.push({ kind: 'header', label: groupName });
19
+ for (const opt of options) {
20
+ result.push({ kind: 'option', ...opt });
21
+ }
22
+ }
23
+ return result;
24
+ }, [groups]);
25
+ // Indices of selectable (non-header) rows
26
+ const selectableIndices = useMemo(() => rows.map((r, i) => (r.kind === 'option' ? i : -1)).filter((i) => i >= 0), [rows]);
27
+ // All option values for toggle-all
28
+ const allValues = useMemo(() => rows.filter((r) => r.kind === 'option').map((r) => r.value), [rows]);
29
+ const [focusedSelectable, setFocusedSelectable] = useState(0);
30
+ const [selected, setSelected] = useState(() => new Set(initialSelected ?? allValues));
31
+ const focusedRowIdx = selectableIndices[focusedSelectable] ?? 0;
32
+ useInput((input, key) => {
33
+ if (key.upArrow) {
34
+ setFocusedSelectable((prev) => (prev > 0 ? prev - 1 : selectableIndices.length - 1));
35
+ }
36
+ if (key.downArrow) {
37
+ setFocusedSelectable((prev) => (prev < selectableIndices.length - 1 ? prev + 1 : 0));
38
+ }
39
+ if (input === ' ') {
40
+ const row = rows[focusedRowIdx];
41
+ if (row?.kind === 'option') {
42
+ setSelected((prev) => {
43
+ const next = new Set(prev);
44
+ if (next.has(row.value)) {
45
+ next.delete(row.value);
46
+ }
47
+ else {
48
+ next.add(row.value);
49
+ }
50
+ return next;
51
+ });
52
+ }
53
+ }
54
+ if (input === 'a') {
55
+ setSelected((prev) => {
56
+ if (prev.size === allValues.length) {
57
+ return new Set();
58
+ }
59
+ return new Set(allValues);
60
+ });
61
+ }
62
+ if (key.return) {
63
+ onSelect([...selected]);
64
+ }
65
+ });
66
+ return (_jsxs(Box, { flexDirection: "column", children: [_jsx(PromptLabel, { message: message }), _jsx(Text, { dimColor: true, children: " (space to toggle, a to toggle all, enter to confirm)" }), _jsx(Box, { flexDirection: "column", marginTop: 1, marginLeft: 2, children: rows.map((row, idx) => {
67
+ if (row.kind === 'header') {
68
+ return (_jsx(Box, { marginTop: idx > 0 ? 1 : 0, children: _jsx(Text, { bold: true, dimColor: true, children: row.label }) }, `h-${idx}`));
69
+ }
70
+ const isFocused = focusedRowIdx === idx;
71
+ const isSelected = selected.has(row.value);
72
+ const checkbox = isSelected ? Icons.squareFilled : Icons.squareOpen;
73
+ const label = row.hint ? `${row.label} (${row.hint})` : row.label;
74
+ return (_jsxs(Box, { gap: 1, marginLeft: 1, children: [_jsx(Text, { color: isSelected ? 'white' : Colors.muted, dimColor: !isFocused && !isSelected, children: checkbox }), _jsx(Text, { color: isFocused ? Colors.accent : undefined, bold: isFocused, dimColor: !isFocused, children: label })] }, row.value));
75
+ }) })] }));
76
+ };
77
+ //# sourceMappingURL=GroupedPickerMenu.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"GroupedPickerMenu.js","sourceRoot":"","sources":["../../../../../src/ui/tui/primitives/GroupedPickerMenu.tsx"],"names":[],"mappings":"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","sourcesContent":["/**\n * GroupedPickerMenu — Multi-select with category headers.\n *\n * Renders groups of options with bold category labels.\n * Arrow keys navigate selectable items (headers are skipped),\n * space toggles, \"a\" toggles all, enter submits.\n */\n\nimport { Box, Text, useInput } from 'ink';\nimport { useState, useMemo } from 'react';\nimport { Icons, Colors } from '../styles.js';\nimport { PromptLabel } from './PromptLabel.js';\n\ninterface GroupOption {\n value: string;\n label: string;\n hint?: string;\n}\n\ninterface GroupedPickerMenuProps {\n message?: string;\n groups: Record<string, GroupOption[]>;\n initialSelected?: string[];\n onSelect: (values: string[]) => void;\n}\n\ntype Row =\n | { kind: 'header'; label: string }\n | { kind: 'option'; value: string; label: string; hint?: string };\n\nexport const GroupedPickerMenu = ({\n message,\n groups,\n initialSelected,\n onSelect,\n}: GroupedPickerMenuProps) => {\n // Build a flat row list with headers interleaved\n const rows = useMemo<Row[]>(() => {\n const result: Row[] = [];\n for (const [groupName, options] of Object.entries(groups)) {\n result.push({ kind: 'header', label: groupName });\n for (const opt of options) {\n result.push({ kind: 'option', ...opt });\n }\n }\n return result;\n }, [groups]);\n\n // Indices of selectable (non-header) rows\n const selectableIndices = useMemo(\n () => rows.map((r, i) => (r.kind === 'option' ? i : -1)).filter((i) => i >= 0),\n [rows],\n );\n\n // All option values for toggle-all\n const allValues = useMemo(\n () =>\n rows.filter((r): r is Row & { kind: 'option' } => r.kind === 'option').map((r) => r.value),\n [rows],\n );\n\n const [focusedSelectable, setFocusedSelectable] = useState(0);\n const [selected, setSelected] = useState<Set<string>>(\n () => new Set(initialSelected ?? allValues),\n );\n\n const focusedRowIdx = selectableIndices[focusedSelectable] ?? 0;\n\n useInput((input, key) => {\n if (key.upArrow) {\n setFocusedSelectable((prev) => (prev > 0 ? prev - 1 : selectableIndices.length - 1));\n }\n if (key.downArrow) {\n setFocusedSelectable((prev) => (prev < selectableIndices.length - 1 ? prev + 1 : 0));\n }\n if (input === ' ') {\n const row = rows[focusedRowIdx];\n if (row?.kind === 'option') {\n setSelected((prev) => {\n const next = new Set(prev);\n if (next.has(row.value)) {\n next.delete(row.value);\n } else {\n next.add(row.value);\n }\n return next;\n });\n }\n }\n if (input === 'a') {\n setSelected((prev) => {\n if (prev.size === allValues.length) {\n return new Set();\n }\n return new Set(allValues);\n });\n }\n if (key.return) {\n onSelect([...selected]);\n }\n });\n\n return (\n <Box flexDirection=\"column\">\n <PromptLabel message={message} />\n <Text dimColor> (space to toggle, a to toggle all, enter to confirm)</Text>\n <Box flexDirection=\"column\" marginTop={1} marginLeft={2}>\n {rows.map((row, idx) => {\n if (row.kind === 'header') {\n return (\n <Box key={`h-${idx}`} marginTop={idx > 0 ? 1 : 0}>\n <Text bold dimColor>\n {row.label}\n </Text>\n </Box>\n );\n }\n\n const isFocused = focusedRowIdx === idx;\n const isSelected = selected.has(row.value);\n const checkbox = isSelected ? Icons.squareFilled : Icons.squareOpen;\n const label = row.hint ? `${row.label} (${row.hint})` : row.label;\n\n return (\n <Box key={row.value} gap={1} marginLeft={1}>\n <Text\n color={isSelected ? 'white' : Colors.muted}\n dimColor={!isFocused && !isSelected}\n >\n {checkbox}\n </Text>\n <Text\n color={isFocused ? Colors.accent : undefined}\n bold={isFocused}\n dimColor={!isFocused}\n >\n {label}\n </Text>\n </Box>\n );\n })}\n </Box>\n </Box>\n );\n};\n"]}
@@ -112,15 +112,24 @@ const MultiPickerMenu = ({ message, options, centered = false, columns = 1, onSe
112
112
  });
113
113
  }
114
114
  if (key.return) {
115
- const values = [...selected].sort().map((i) => options[i].value);
116
- onSelect(values);
115
+ if (selected.size === 0) {
116
+ // Nothing toggled, select hovered
117
+ const hovered = options[focused];
118
+ if (hovered) {
119
+ onSelect(hovered.value);
120
+ }
121
+ }
122
+ else {
123
+ const values = [...selected].sort().map((i) => options[i].value);
124
+ onSelect(values);
125
+ }
117
126
  }
118
127
  });
119
128
  const columnArrays = [];
120
129
  for (let c = 0; c < columns; c++) {
121
130
  columnArrays.push(options.slice(c * rows, c * rows + rows));
122
131
  }
123
- return (_jsxs(Box, { flexDirection: "column", alignItems: centered ? 'center' : undefined, children: [_jsx(PromptLabel, { message: message }), _jsx(Text, { dimColor: true, children: " (space to toggle, enter to submit)" }), _jsx(Box, { flexDirection: "row", gap: 4, marginLeft: centered ? 0 : 2, marginTop: 1, children: columnArrays.map((colOpts, colIdx) => (_jsx(Box, { flexDirection: "column", children: colOpts.map((opt, rowIdx) => {
132
+ return (_jsxs(Box, { flexDirection: "column", alignItems: centered ? 'center' : undefined, children: [_jsx(PromptLabel, { message: message }), _jsx(Text, { dimColor: true, children: " (space to multi-select, enter to confirm)" }), _jsx(Box, { flexDirection: "row", gap: 4, marginLeft: centered ? 0 : 2, marginTop: 1, children: columnArrays.map((colOpts, colIdx) => (_jsx(Box, { flexDirection: "column", children: colOpts.map((opt, rowIdx) => {
124
133
  const flatIdx = colIdx * rows + rowIdx;
125
134
  const isFocused = flatIdx === focused;
126
135
  const isSelected = selected.has(flatIdx);
@@ -1 +1 @@
1
- {"version":3,"file":"PickerMenu.js","sourceRoot":"","sources":["../../../../../src/ui/tui/primitives/PickerMenu.tsx"],"names":[],"mappings":"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","sourcesContent":["/**\n * PickerMenu — Single and multi select.\n * Single mode: custom renderer with small triangle indicator.\n * Multi mode: checkbox glyphs with space to toggle.\n */\n\nimport { Box, Text, useInput } from 'ink';\nimport { useState } from 'react';\nimport { Icons, Colors } from '../styles.js';\nimport { PromptLabel } from './PromptLabel.js';\n\ninterface PickerOption<T> {\n label: string;\n value: T;\n hint?: string;\n}\n\ninterface PickerMenuProps<T> {\n message?: string;\n options: PickerOption<T>[];\n mode?: 'single' | 'multi';\n centered?: boolean;\n columns?: 1 | 2 | 3 | 4;\n onSelect: (value: T | T[]) => void;\n}\n\nexport const PickerMenu = <T,>({\n message,\n options,\n mode = 'single',\n centered = false,\n columns = 1,\n onSelect,\n}: PickerMenuProps<T>) => {\n if (mode === 'multi') {\n return (\n <MultiPickerMenu\n message={message}\n options={options}\n centered={centered}\n columns={columns}\n onSelect={onSelect}\n />\n );\n }\n\n return (\n <SinglePickerMenu\n message={message}\n options={options}\n centered={centered}\n columns={columns}\n onSelect={onSelect}\n />\n );\n};\n\n/** Custom single-select with triangle indicator and accent highlight. */\nconst SinglePickerMenu = <T,>({\n message,\n options,\n centered = false,\n columns = 1,\n onSelect,\n}: {\n message?: string;\n options: PickerOption<T>[];\n centered?: boolean;\n columns?: number;\n onSelect: (value: T | T[]) => void;\n}) => {\n const [focused, setFocused] = useState(0);\n const rows = Math.ceil(options.length / columns);\n\n useInput((_input, key) => {\n const col = Math.floor(focused / rows);\n const row = focused % rows;\n\n if (key.upArrow) {\n if (row > 0) {\n setFocused(col * rows + row - 1);\n } else {\n setFocused(Math.min(col * rows + rows - 1, options.length - 1));\n }\n }\n if (key.downArrow) {\n const next = col * rows + row + 1;\n if (next < options.length && row + 1 < rows) {\n setFocused(next);\n } else {\n setFocused(col * rows);\n }\n }\n if (key.leftArrow && columns > 1) {\n const prevCol = col > 0 ? col - 1 : columns - 1;\n setFocused(Math.min(prevCol * rows + row, options.length - 1));\n }\n if (key.rightArrow && columns > 1) {\n const nextCol = col < columns - 1 ? col + 1 : 0;\n setFocused(Math.min(nextCol * rows + row, options.length - 1));\n }\n if (key.return) {\n const selected = options[focused];\n if (selected) {\n onSelect(selected.value);\n }\n }\n });\n\n // Chunk options into columns (column-first ordering)\n const columnArrays: PickerOption<T>[][] = [];\n for (let c = 0; c < columns; c++) {\n columnArrays.push(options.slice(c * rows, c * rows + rows));\n }\n\n const align = centered ? 'center' : undefined;\n\n return (\n <Box flexDirection=\"column\" alignItems={align}>\n <PromptLabel message={message} />\n <Box flexDirection=\"row\" gap={4}>\n {columnArrays.map((colOpts, colIdx) => (\n <Box key={colIdx} flexDirection=\"column\">\n {colOpts.map((opt, rowIdx) => {\n const flatIdx = colIdx * rows + rowIdx;\n const isFocused = flatIdx === focused;\n const label = opt.hint ? `${opt.label} (${opt.hint})` : opt.label;\n return (\n <Box key={flatIdx} gap={1}>\n <Text\n color={isFocused ? Colors.accent : undefined}\n dimColor={!isFocused}\n >\n {isFocused ? Icons.triangleSmallRight : ' '}\n </Text>\n <Text\n color={isFocused ? Colors.accent : undefined}\n bold={isFocused}\n dimColor={!isFocused}\n >\n {label}\n </Text>\n </Box>\n );\n })}\n </Box>\n ))}\n </Box>\n </Box>\n );\n};\n\n/** Custom multi-select with checkbox glyphs and accent highlight. */\nconst MultiPickerMenu = <T,>({\n message,\n options,\n centered = false,\n columns = 1,\n onSelect,\n}: {\n message?: string;\n options: PickerOption<T>[];\n centered?: boolean;\n columns?: number;\n onSelect: (value: T | T[]) => void;\n}) => {\n const [focused, setFocused] = useState(0);\n const [selected, setSelected] = useState<Set<number>>(new Set());\n const rows = Math.ceil(options.length / columns);\n\n useInput((_input, key) => {\n const col = Math.floor(focused / rows);\n const row = focused % rows;\n\n if (key.upArrow) {\n if (row > 0) {\n setFocused(col * rows + row - 1);\n } else {\n setFocused(Math.min(col * rows + rows - 1, options.length - 1));\n }\n }\n if (key.downArrow) {\n const next = col * rows + row + 1;\n if (next < options.length && row + 1 < rows) {\n setFocused(next);\n } else {\n setFocused(col * rows);\n }\n }\n if (key.leftArrow && columns > 1) {\n const prevCol = col > 0 ? col - 1 : columns - 1;\n setFocused(Math.min(prevCol * rows + row, options.length - 1));\n }\n if (key.rightArrow && columns > 1) {\n const nextCol = col < columns - 1 ? col + 1 : 0;\n setFocused(Math.min(nextCol * rows + row, options.length - 1));\n }\n if (_input === ' ') {\n setSelected((prev) => {\n const next = new Set(prev);\n if (next.has(focused)) {\n next.delete(focused);\n } else {\n next.add(focused);\n }\n return next;\n });\n }\n if (key.return) {\n const values = [...selected].sort().map((i) => options[i].value);\n onSelect(values);\n }\n });\n\n const columnArrays: PickerOption<T>[][] = [];\n for (let c = 0; c < columns; c++) {\n columnArrays.push(options.slice(c * rows, c * rows + rows));\n }\n\n return (\n <Box flexDirection=\"column\" alignItems={centered ? 'center' : undefined}>\n <PromptLabel message={message} />\n <Text dimColor> (space to toggle, enter to submit)</Text>\n <Box\n flexDirection=\"row\"\n gap={4}\n marginLeft={centered ? 0 : 2}\n marginTop={1}\n >\n {columnArrays.map((colOpts, colIdx) => (\n <Box key={colIdx} flexDirection=\"column\">\n {colOpts.map((opt, rowIdx) => {\n const flatIdx = colIdx * rows + rowIdx;\n const isFocused = flatIdx === focused;\n const isSelected = selected.has(flatIdx);\n const label = opt.hint ? `${opt.label} (${opt.hint})` : opt.label;\n const checkbox = isSelected\n ? Icons.squareFilled\n : Icons.squareOpen;\n return (\n <Box key={flatIdx} gap={1}>\n <Text\n color={isSelected ? 'white' : Colors.muted}\n dimColor={!isFocused && !isSelected}\n >\n {checkbox}\n </Text>\n <Text\n color={isFocused ? Colors.accent : undefined}\n bold={isFocused}\n dimColor={!isFocused}\n >\n {label}\n </Text>\n </Box>\n );\n })}\n </Box>\n ))}\n </Box>\n </Box>\n );\n};\n"]}
1
+ {"version":3,"file":"PickerMenu.js","sourceRoot":"","sources":["../../../../../src/ui/tui/primitives/PickerMenu.tsx"],"names":[],"mappings":"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","sourcesContent":["/**\n * PickerMenu — Single and multi select.\n * Single mode: custom renderer with small triangle indicator.\n * Multi mode: checkbox glyphs with space to toggle.\n */\n\nimport { Box, Text, useInput } from 'ink';\nimport { useState } from 'react';\nimport { Icons, Colors } from '../styles.js';\nimport { PromptLabel } from './PromptLabel.js';\n\ninterface PickerOption<T> {\n label: string;\n value: T;\n hint?: string;\n}\n\ninterface PickerMenuProps<T> {\n message?: string;\n options: PickerOption<T>[];\n mode?: 'single' | 'multi';\n centered?: boolean;\n columns?: 1 | 2 | 3 | 4;\n onSelect: (value: T | T[]) => void;\n}\n\nexport const PickerMenu = <T,>({\n message,\n options,\n mode = 'single',\n centered = false,\n columns = 1,\n onSelect,\n}: PickerMenuProps<T>) => {\n if (mode === 'multi') {\n return (\n <MultiPickerMenu\n message={message}\n options={options}\n centered={centered}\n columns={columns}\n onSelect={onSelect}\n />\n );\n }\n\n return (\n <SinglePickerMenu\n message={message}\n options={options}\n centered={centered}\n columns={columns}\n onSelect={onSelect}\n />\n );\n};\n\n/** Custom single-select with triangle indicator and accent highlight. */\nconst SinglePickerMenu = <T,>({\n message,\n options,\n centered = false,\n columns = 1,\n onSelect,\n}: {\n message?: string;\n options: PickerOption<T>[];\n centered?: boolean;\n columns?: number;\n onSelect: (value: T | T[]) => void;\n}) => {\n const [focused, setFocused] = useState(0);\n const rows = Math.ceil(options.length / columns);\n\n useInput((_input, key) => {\n const col = Math.floor(focused / rows);\n const row = focused % rows;\n\n if (key.upArrow) {\n if (row > 0) {\n setFocused(col * rows + row - 1);\n } else {\n setFocused(Math.min(col * rows + rows - 1, options.length - 1));\n }\n }\n if (key.downArrow) {\n const next = col * rows + row + 1;\n if (next < options.length && row + 1 < rows) {\n setFocused(next);\n } else {\n setFocused(col * rows);\n }\n }\n if (key.leftArrow && columns > 1) {\n const prevCol = col > 0 ? col - 1 : columns - 1;\n setFocused(Math.min(prevCol * rows + row, options.length - 1));\n }\n if (key.rightArrow && columns > 1) {\n const nextCol = col < columns - 1 ? col + 1 : 0;\n setFocused(Math.min(nextCol * rows + row, options.length - 1));\n }\n if (key.return) {\n const selected = options[focused];\n if (selected) {\n onSelect(selected.value);\n }\n }\n });\n\n // Chunk options into columns (column-first ordering)\n const columnArrays: PickerOption<T>[][] = [];\n for (let c = 0; c < columns; c++) {\n columnArrays.push(options.slice(c * rows, c * rows + rows));\n }\n\n const align = centered ? 'center' : undefined;\n\n return (\n <Box flexDirection=\"column\" alignItems={align}>\n <PromptLabel message={message} />\n <Box flexDirection=\"row\" gap={4}>\n {columnArrays.map((colOpts, colIdx) => (\n <Box key={colIdx} flexDirection=\"column\">\n {colOpts.map((opt, rowIdx) => {\n const flatIdx = colIdx * rows + rowIdx;\n const isFocused = flatIdx === focused;\n const label = opt.hint ? `${opt.label} (${opt.hint})` : opt.label;\n return (\n <Box key={flatIdx} gap={1}>\n <Text\n color={isFocused ? Colors.accent : undefined}\n dimColor={!isFocused}\n >\n {isFocused ? Icons.triangleSmallRight : ' '}\n </Text>\n <Text\n color={isFocused ? Colors.accent : undefined}\n bold={isFocused}\n dimColor={!isFocused}\n >\n {label}\n </Text>\n </Box>\n );\n })}\n </Box>\n ))}\n </Box>\n </Box>\n );\n};\n\n/** Custom multi-select with checkbox glyphs and accent highlight. */\nconst MultiPickerMenu = <T,>({\n message,\n options,\n centered = false,\n columns = 1,\n onSelect,\n}: {\n message?: string;\n options: PickerOption<T>[];\n centered?: boolean;\n columns?: number;\n onSelect: (value: T | T[]) => void;\n}) => {\n const [focused, setFocused] = useState(0);\n const [selected, setSelected] = useState<Set<number>>(new Set());\n const rows = Math.ceil(options.length / columns);\n\n useInput((_input, key) => {\n const col = Math.floor(focused / rows);\n const row = focused % rows;\n\n if (key.upArrow) {\n if (row > 0) {\n setFocused(col * rows + row - 1);\n } else {\n setFocused(Math.min(col * rows + rows - 1, options.length - 1));\n }\n }\n if (key.downArrow) {\n const next = col * rows + row + 1;\n if (next < options.length && row + 1 < rows) {\n setFocused(next);\n } else {\n setFocused(col * rows);\n }\n }\n if (key.leftArrow && columns > 1) {\n const prevCol = col > 0 ? col - 1 : columns - 1;\n setFocused(Math.min(prevCol * rows + row, options.length - 1));\n }\n if (key.rightArrow && columns > 1) {\n const nextCol = col < columns - 1 ? col + 1 : 0;\n setFocused(Math.min(nextCol * rows + row, options.length - 1));\n }\n if (_input === ' ') {\n setSelected((prev) => {\n const next = new Set(prev);\n if (next.has(focused)) {\n next.delete(focused);\n } else {\n next.add(focused);\n }\n return next;\n });\n }\n if (key.return) {\n if (selected.size === 0) {\n // Nothing toggled, select hovered\n const hovered = options[focused];\n if (hovered) {\n onSelect(hovered.value);\n }\n } else {\n const values = [...selected].sort().map((i) => options[i].value);\n onSelect(values);\n }\n }\n });\n\n const columnArrays: PickerOption<T>[][] = [];\n for (let c = 0; c < columns; c++) {\n columnArrays.push(options.slice(c * rows, c * rows + rows));\n }\n\n return (\n <Box flexDirection=\"column\" alignItems={centered ? 'center' : undefined}>\n <PromptLabel message={message} />\n <Text dimColor> (space to multi-select, enter to confirm)</Text>\n <Box\n flexDirection=\"row\"\n gap={4}\n marginLeft={centered ? 0 : 2}\n marginTop={1}\n >\n {columnArrays.map((colOpts, colIdx) => (\n <Box key={colIdx} flexDirection=\"column\">\n {colOpts.map((opt, rowIdx) => {\n const flatIdx = colIdx * rows + rowIdx;\n const isFocused = flatIdx === focused;\n const isSelected = selected.has(flatIdx);\n const label = opt.hint ? `${opt.label} (${opt.hint})` : opt.label;\n const checkbox = isSelected\n ? Icons.squareFilled\n : Icons.squareOpen;\n return (\n <Box key={flatIdx} gap={1}>\n <Text\n color={isSelected ? 'white' : Colors.muted}\n dimColor={!isFocused && !isSelected}\n >\n {checkbox}\n </Text>\n <Text\n color={isFocused ? Colors.accent : undefined}\n bold={isFocused}\n dimColor={!isFocused}\n >\n {label}\n </Text>\n </Box>\n );\n })}\n </Box>\n ))}\n </Box>\n </Box>\n );\n};\n"]}
@@ -8,6 +8,7 @@ export { ProgressList } from './ProgressList.js';
8
8
  export type { ProgressItem } from './ProgressList.js';
9
9
  export { PromptLabel } from './PromptLabel.js';
10
10
  export { PickerMenu } from './PickerMenu.js';
11
+ export { GroupedPickerMenu } from './GroupedPickerMenu.js';
11
12
  export { ConfirmationInput } from './ConfirmationInput.js';
12
13
  export { Divider } from './Divider.js';
13
14
  export { ModalOverlay } from './ModalOverlay.js';
@@ -7,6 +7,7 @@ export { LoadingBox } from './LoadingBox.js';
7
7
  export { ProgressList } from './ProgressList.js';
8
8
  export { PromptLabel } from './PromptLabel.js';
9
9
  export { PickerMenu } from './PickerMenu.js';
10
+ export { GroupedPickerMenu } from './GroupedPickerMenu.js';
10
11
  export { ConfirmationInput } from './ConfirmationInput.js';
11
12
  export { Divider } from './Divider.js';
12
13
  export { ModalOverlay } from './ModalOverlay.js';
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../../src/ui/tui/primitives/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAC7C,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAC3C,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAC7C,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAEjD,OAAO,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAC/C,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAC7C,OAAO,EAAE,iBAAiB,EAAE,MAAM,wBAAwB,CAAC;AAC3D,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AACvC,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AACjD,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAC3C,OAAO,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAC;AACvD,OAAO,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAC;AACvD,OAAO,EAAE,mBAAmB,EAAE,MAAM,0BAA0B,CAAC;AAC/D,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAEjD,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AACzC,OAAO,EAAE,kBAAkB,EAAE,MAAM,yBAAyB,CAAC;AAE7D,OAAO,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AAOzD,OAAO,EACL,mBAAmB,EACnB,mBAAmB,EACnB,QAAQ,EACR,eAAe,GAChB,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EACL,cAAc,EACd,uBAAuB,EACvB,sBAAsB,EACtB,yBAAyB,GAC1B,MAAM,gBAAgB,CAAC","sourcesContent":["/**\n * Barrel export for all TUI layout primitives.\n */\n\nexport { CardLayout } from './CardLayout.js';\nexport { SplitView } from './SplitView.js';\nexport { LoadingBox } from './LoadingBox.js';\nexport { ProgressList } from './ProgressList.js';\nexport type { ProgressItem } from './ProgressList.js';\nexport { PromptLabel } from './PromptLabel.js';\nexport { PickerMenu } from './PickerMenu.js';\nexport { ConfirmationInput } from './ConfirmationInput.js';\nexport { Divider } from './Divider.js';\nexport { ModalOverlay } from './ModalOverlay.js';\nexport { LogViewer } from './LogViewer.js';\nexport { EventPlanViewer } from './EventPlanViewer.js';\nexport { ScreenContainer } from './ScreenContainer.js';\nexport { ScreenErrorBoundary } from './ScreenErrorBoundary.js';\nexport { TabContainer } from './TabContainer.js';\nexport type { TabDefinition } from './TabContainer.js';\nexport { HNViewer } from './HNViewer.js';\nexport { DissolveTransition } from './DissolveTransition.js';\nexport type { WipeDirection } from './DissolveTransition.js';\nexport { ContentSequencer } from './ContentSequencer.js';\nexport type {\n ContentBlock,\n ContentObjectBlock,\n ContentLinesBlock,\n ContentClearBlock,\n} from './ContentSequencer.js';\nexport {\n estimateBlockHeight,\n computeVisibleRange,\n wordWrap,\n wrapAndTruncate,\n} from './layout-helpers.js';\nexport {\n TextRevealMode,\n TEXT_REVEAL_MODE_LABELS,\n TEXT_REVEAL_MODE_COUNT,\n TEXT_REVEAL_MODE_DEFAULTS,\n} from './TextBlock.js';\n"]}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../../src/ui/tui/primitives/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAC7C,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAC3C,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAC7C,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAEjD,OAAO,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAC/C,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAC7C,OAAO,EAAE,iBAAiB,EAAE,MAAM,wBAAwB,CAAC;AAC3D,OAAO,EAAE,iBAAiB,EAAE,MAAM,wBAAwB,CAAC;AAC3D,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AACvC,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AACjD,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAC3C,OAAO,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAC;AACvD,OAAO,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAC;AACvD,OAAO,EAAE,mBAAmB,EAAE,MAAM,0BAA0B,CAAC;AAC/D,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAEjD,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AACzC,OAAO,EAAE,kBAAkB,EAAE,MAAM,yBAAyB,CAAC;AAE7D,OAAO,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AAOzD,OAAO,EACL,mBAAmB,EACnB,mBAAmB,EACnB,QAAQ,EACR,eAAe,GAChB,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EACL,cAAc,EACd,uBAAuB,EACvB,sBAAsB,EACtB,yBAAyB,GAC1B,MAAM,gBAAgB,CAAC","sourcesContent":["/**\n * Barrel export for all TUI layout primitives.\n */\n\nexport { CardLayout } from './CardLayout.js';\nexport { SplitView } from './SplitView.js';\nexport { LoadingBox } from './LoadingBox.js';\nexport { ProgressList } from './ProgressList.js';\nexport type { ProgressItem } from './ProgressList.js';\nexport { PromptLabel } from './PromptLabel.js';\nexport { PickerMenu } from './PickerMenu.js';\nexport { GroupedPickerMenu } from './GroupedPickerMenu.js';\nexport { ConfirmationInput } from './ConfirmationInput.js';\nexport { Divider } from './Divider.js';\nexport { ModalOverlay } from './ModalOverlay.js';\nexport { LogViewer } from './LogViewer.js';\nexport { EventPlanViewer } from './EventPlanViewer.js';\nexport { ScreenContainer } from './ScreenContainer.js';\nexport { ScreenErrorBoundary } from './ScreenErrorBoundary.js';\nexport { TabContainer } from './TabContainer.js';\nexport type { TabDefinition } from './TabContainer.js';\nexport { HNViewer } from './HNViewer.js';\nexport { DissolveTransition } from './DissolveTransition.js';\nexport type { WipeDirection } from './DissolveTransition.js';\nexport { ContentSequencer } from './ContentSequencer.js';\nexport type {\n ContentBlock,\n ContentObjectBlock,\n ContentLinesBlock,\n ContentClearBlock,\n} from './ContentSequencer.js';\nexport {\n estimateBlockHeight,\n computeVisibleRange,\n wordWrap,\n wrapAndTruncate,\n} from './layout-helpers.js';\nexport {\n TextRevealMode,\n TEXT_REVEAL_MODE_LABELS,\n TEXT_REVEAL_MODE_COUNT,\n TEXT_REVEAL_MODE_DEFAULTS,\n} from './TextBlock.js';\n"]}
@@ -5,7 +5,7 @@
5
5
  * importing business logic directly. Testable, no dynamic imports.
6
6
  *
7
7
  * Supports two modes via the `mode` prop:
8
- * - 'install': detect clients → confirm → install
8
+ * - 'install': detect clients → confirm → [pick clients] → pick features → install
9
9
  * - 'remove': detect installed clients → confirm → remove
10
10
  *
11
11
  * When done, calls store.setMcpComplete(). The router resolves to outro.
@@ -6,7 +6,7 @@ import { jsxs as _jsxs, jsx as _jsx, Fragment as _Fragment } from "react/jsx-run
6
6
  * importing business logic directly. Testable, no dynamic imports.
7
7
  *
8
8
  * Supports two modes via the `mode` prop:
9
- * - 'install': detect clients → confirm → install
9
+ * - 'install': detect clients → confirm → [pick clients] → pick features → install
10
10
  * - 'remove': detect installed clients → confirm → remove
11
11
  *
12
12
  * When done, calls store.setMcpComplete(). The router resolves to outro.
@@ -15,13 +15,15 @@ import { Box, Text } from 'ink';
15
15
  import { useState, useEffect } from 'react';
16
16
  import { useSyncExternalStore } from 'react';
17
17
  import { McpOutcome } from '../store.js';
18
- import { ConfirmationInput, PickerMenu } from '../primitives/index.js';
18
+ import { ConfirmationInput, PickerMenu, GroupedPickerMenu, } from '../primitives/index.js';
19
19
  import { Colors } from '../styles.js';
20
+ import { AVAILABLE_FEATURES, ALL_FEATURE_VALUES, } from '../../../steps/add-mcp-server-to-clients/defaults.js';
20
21
  var Phase;
21
22
  (function (Phase) {
22
23
  Phase["Detecting"] = "detecting";
23
24
  Phase["Ask"] = "ask";
24
25
  Phase["Pick"] = "pick";
26
+ Phase["FeatureSelect"] = "feature-select";
25
27
  Phase["Working"] = "working";
26
28
  Phase["Done"] = "done";
27
29
  Phase["None"] = "none";
@@ -37,6 +39,7 @@ export const McpScreen = ({ store, installer, mode = 'install', standalone = fal
37
39
  const isRemove = mode === 'remove';
38
40
  const [phase, setPhase] = useState(Phase.Detecting);
39
41
  const [clients, setClients] = useState([]);
42
+ const [selectedClientNames, setSelectedClientNames] = useState([]);
40
43
  const [resultClients, setResultClients] = useState([]);
41
44
  useEffect(() => {
42
45
  void (async () => {
@@ -57,12 +60,22 @@ export const McpScreen = ({ store, installer, mode = 'install', standalone = fal
57
60
  }
58
61
  })();
59
62
  }, [installer]); // eslint-disable-line
63
+ const proceedToFeatureSelectOrInstall = (clientNames) => {
64
+ setSelectedClientNames(clientNames);
65
+ // Skip feature picker if CLI already specified features
66
+ if (store.session.mcpFeatures) {
67
+ void doInstall(clientNames, store.session.mcpFeatures);
68
+ }
69
+ else {
70
+ setPhase(Phase.FeatureSelect);
71
+ }
72
+ };
60
73
  const handleConfirm = () => {
61
74
  if (isRemove) {
62
75
  void doRemove();
63
76
  }
64
77
  else if (clients.length === 1) {
65
- void doInstall(clients.map((c) => c.name));
78
+ proceedToFeatureSelectOrInstall(clients.map((c) => c.name));
66
79
  }
67
80
  else {
68
81
  setPhase(Phase.Pick);
@@ -71,11 +84,11 @@ export const McpScreen = ({ store, installer, mode = 'install', standalone = fal
71
84
  const handleSkip = () => {
72
85
  markDone(store, McpOutcome.Skipped, [], standalone);
73
86
  };
74
- const doInstall = async (names) => {
87
+ const doInstall = async (names, features) => {
75
88
  setPhase(Phase.Working);
76
89
  let result = [];
77
90
  try {
78
- result = await installer.install(names);
91
+ result = await installer.install(names, features);
79
92
  setResultClients(result);
80
93
  }
81
94
  catch {
@@ -106,7 +119,9 @@ export const McpScreen = ({ store, installer, mode = 'install', standalone = fal
106
119
  value: c.name,
107
120
  })), mode: "multi", onSelect: (selected) => {
108
121
  const names = Array.isArray(selected) ? selected : [selected];
109
- void doInstall(names);
122
+ proceedToFeatureSelectOrInstall(names);
123
+ } })), phase === Phase.FeatureSelect && (_jsx(GroupedPickerMenu, { message: "Select features to enable", groups: AVAILABLE_FEATURES, initialSelected: [...ALL_FEATURE_VALUES], onSelect: (features) => {
124
+ void doInstall(selectedClientNames, features);
110
125
  } })), phase === Phase.Working && (_jsxs(Text, { dimColor: true, children: [isRemove ? 'Removing' : 'Installing', " MCP server..."] })), phase === Phase.Done && (_jsx(Box, { flexDirection: "column", children: resultClients.length > 0 ? (_jsxs(_Fragment, { children: [_jsxs(Text, { color: "green", bold: true, children: ['\u2714', " MCP server", ' ', isRemove ? 'removed from' : 'installed for', ":"] }), resultClients.map((name, i) => (_jsxs(Text, { children: [' ', '\u2022', " ", name] }, i)))] })) : (_jsxs(Text, { dimColor: true, children: [isRemove ? 'Removal' : 'Installation', " skipped."] })) }))] })] }));
111
126
  };
112
127
  //# sourceMappingURL=McpScreen.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"McpScreen.js","sourceRoot":"","sources":["../../../../../src/ui/tui/screens/McpScreen.tsx"],"names":[],"mappings":"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","sourcesContent":["/**\n * McpScreen — MCP server install/remove flow.\n *\n * Uses an McpInstaller service (passed via props) instead of\n * importing business logic directly. Testable, no dynamic imports.\n *\n * Supports two modes via the `mode` prop:\n * - 'install': detect clients → confirm → install\n * - 'remove': detect installed clients → confirm → remove\n *\n * When done, calls store.setMcpComplete(). The router resolves to outro.\n */\n\nimport { Box, Text } from 'ink';\nimport { useState, useEffect } from 'react';\nimport { useSyncExternalStore } from 'react';\nimport { type WizardStore, McpOutcome } from '../store.js';\nimport { ConfirmationInput, PickerMenu } from '../primitives/index.js';\nimport { Colors } from '../styles.js';\nimport type { McpInstaller, McpClientInfo } from '../services/mcp-installer.js';\n\nexport type McpMode = 'install' | 'remove';\n\ninterface McpScreenProps {\n store: WizardStore;\n installer: McpInstaller;\n mode?: McpMode;\n /** When true, exit the process after completion instead of routing to outro. */\n standalone?: boolean;\n}\n\nenum Phase {\n Detecting = 'detecting',\n Ask = 'ask',\n Pick = 'pick',\n Working = 'working',\n Done = 'done',\n None = 'none',\n}\n\nconst markDone = (\n store: WizardStore,\n outcome: McpOutcome,\n clients: string[] = [],\n standalone = false,\n) => {\n store.setMcpComplete(outcome, clients);\n if (standalone) {\n process.exit(0);\n }\n};\n\nexport const McpScreen = ({\n store,\n installer,\n mode = 'install',\n standalone = false,\n}: McpScreenProps) => {\n useSyncExternalStore(\n (cb) => store.subscribe(cb),\n () => store.getSnapshot(),\n );\n\n const isRemove = mode === 'remove';\n\n const [phase, setPhase] = useState<Phase>(Phase.Detecting);\n const [clients, setClients] = useState<McpClientInfo[]>([]);\n const [resultClients, setResultClients] = useState<string[]>([]);\n\n useEffect(() => {\n void (async () => {\n try {\n const detected = await installer.detectClients();\n if (detected.length === 0) {\n setPhase(Phase.None);\n setTimeout(\n () => markDone(store, McpOutcome.NoClients, [], standalone),\n 1500,\n );\n } else {\n setClients(detected);\n setPhase(Phase.Ask);\n }\n } catch {\n setPhase(Phase.None);\n setTimeout(\n () => markDone(store, McpOutcome.Failed, [], standalone),\n 1500,\n );\n }\n })();\n }, [installer]); // eslint-disable-line\n\n const handleConfirm = () => {\n if (isRemove) {\n void doRemove();\n } else if (clients.length === 1) {\n void doInstall(clients.map((c) => c.name));\n } else {\n setPhase(Phase.Pick);\n }\n };\n\n const handleSkip = () => {\n markDone(store, McpOutcome.Skipped, [], standalone);\n };\n\n const doInstall = async (names: string[]) => {\n setPhase(Phase.Working);\n let result: string[] = [];\n try {\n result = await installer.install(names);\n setResultClients(result);\n } catch {\n setResultClients([]);\n }\n setPhase(Phase.Done);\n const outcome =\n result.length > 0 ? McpOutcome.Installed : McpOutcome.Failed;\n setTimeout(() => markDone(store, outcome, result, standalone), 2000);\n };\n\n const doRemove = async () => {\n setPhase(Phase.Working);\n let result: string[] = [];\n try {\n result = await installer.remove();\n setResultClients(result);\n } catch {\n setResultClients([]);\n }\n setPhase(Phase.Done);\n const outcome =\n result.length > 0 ? McpOutcome.Installed : McpOutcome.Failed;\n setTimeout(() => markDone(store, outcome, result, standalone), 2000);\n };\n\n return (\n <Box flexDirection=\"column\" flexGrow={1}>\n <Text bold color={Colors.accent}>\n MCP Server {isRemove ? 'Removal' : 'Setup'}\n </Text>\n\n <Box marginTop={1} flexDirection=\"column\">\n {phase === Phase.Detecting && (\n <Text dimColor>Detecting supported editors...</Text>\n )}\n\n {phase === Phase.None && (\n <Text dimColor>\n No {isRemove ? 'installed' : 'supported'} MCP clients detected.\n Skipping...\n </Text>\n )}\n\n {phase === Phase.Ask && (\n <>\n <Text dimColor>\n Detected: {clients.map((c) => c.name).join(', ')}\n </Text>\n <Box marginTop={1}>\n <ConfirmationInput\n message={\n isRemove\n ? 'Remove the PostHog MCP server from your editor?'\n : 'Install the PostHog MCP server to your editor?'\n }\n confirmLabel={isRemove ? 'Remove MCP' : 'Install MCP'}\n cancelLabel=\"No thanks\"\n onConfirm={handleConfirm}\n onCancel={handleSkip}\n />\n </Box>\n </>\n )}\n\n {phase === Phase.Pick && (\n <PickerMenu\n message=\"Select editor to install MCP server\"\n options={clients.map((c) => ({\n label: c.name,\n value: c.name,\n }))}\n mode=\"multi\"\n onSelect={(selected) => {\n const names = Array.isArray(selected) ? selected : [selected];\n void doInstall(names);\n }}\n />\n )}\n\n {phase === Phase.Working && (\n <Text dimColor>\n {isRemove ? 'Removing' : 'Installing'} MCP server...\n </Text>\n )}\n\n {phase === Phase.Done && (\n <Box flexDirection=\"column\">\n {resultClients.length > 0 ? (\n <>\n <Text color=\"green\" bold>\n {'\\u2714'} MCP server{' '}\n {isRemove ? 'removed from' : 'installed for'}:\n </Text>\n {resultClients.map((name, i) => (\n <Text key={i}>\n {' '}\n {'\\u2022'} {name}\n </Text>\n ))}\n </>\n ) : (\n <Text dimColor>\n {isRemove ? 'Removal' : 'Installation'} skipped.\n </Text>\n )}\n </Box>\n )}\n </Box>\n </Box>\n );\n};\n"]}
1
+ {"version":3,"file":"McpScreen.js","sourceRoot":"","sources":["../../../../../src/ui/tui/screens/McpScreen.tsx"],"names":[],"mappings":"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","sourcesContent":["/**\n * McpScreen — MCP server install/remove flow.\n *\n * Uses an McpInstaller service (passed via props) instead of\n * importing business logic directly. Testable, no dynamic imports.\n *\n * Supports two modes via the `mode` prop:\n * - 'install': detect clients → confirm → [pick clients] → pick features → install\n * - 'remove': detect installed clients → confirm → remove\n *\n * When done, calls store.setMcpComplete(). The router resolves to outro.\n */\n\nimport { Box, Text } from 'ink';\nimport { useState, useEffect } from 'react';\nimport { useSyncExternalStore } from 'react';\nimport { type WizardStore, McpOutcome } from '../store.js';\nimport {\n ConfirmationInput,\n PickerMenu,\n GroupedPickerMenu,\n} from '../primitives/index.js';\nimport { Colors } from '../styles.js';\nimport type { McpInstaller, McpClientInfo } from '../services/mcp-installer.js';\nimport {\n AVAILABLE_FEATURES,\n ALL_FEATURE_VALUES,\n} from '../../../steps/add-mcp-server-to-clients/defaults.js';\n\nexport type McpMode = 'install' | 'remove';\n\ninterface McpScreenProps {\n store: WizardStore;\n installer: McpInstaller;\n mode?: McpMode;\n /** When true, exit the process after completion instead of routing to outro. */\n standalone?: boolean;\n}\n\nenum Phase {\n Detecting = 'detecting',\n Ask = 'ask',\n Pick = 'pick',\n FeatureSelect = 'feature-select',\n Working = 'working',\n Done = 'done',\n None = 'none',\n}\n\nconst markDone = (\n store: WizardStore,\n outcome: McpOutcome,\n clients: string[] = [],\n standalone = false,\n) => {\n store.setMcpComplete(outcome, clients);\n if (standalone) {\n process.exit(0);\n }\n};\n\nexport const McpScreen = ({\n store,\n installer,\n mode = 'install',\n standalone = false,\n}: McpScreenProps) => {\n useSyncExternalStore(\n (cb) => store.subscribe(cb),\n () => store.getSnapshot(),\n );\n\n const isRemove = mode === 'remove';\n\n const [phase, setPhase] = useState<Phase>(Phase.Detecting);\n const [clients, setClients] = useState<McpClientInfo[]>([]);\n const [selectedClientNames, setSelectedClientNames] = useState<string[]>([]);\n const [resultClients, setResultClients] = useState<string[]>([]);\n\n useEffect(() => {\n void (async () => {\n try {\n const detected = await installer.detectClients();\n if (detected.length === 0) {\n setPhase(Phase.None);\n setTimeout(\n () => markDone(store, McpOutcome.NoClients, [], standalone),\n 1500,\n );\n } else {\n setClients(detected);\n setPhase(Phase.Ask);\n }\n } catch {\n setPhase(Phase.None);\n setTimeout(\n () => markDone(store, McpOutcome.Failed, [], standalone),\n 1500,\n );\n }\n })();\n }, [installer]); // eslint-disable-line\n\n const proceedToFeatureSelectOrInstall = (clientNames: string[]) => {\n setSelectedClientNames(clientNames);\n // Skip feature picker if CLI already specified features\n if (store.session.mcpFeatures) {\n void doInstall(clientNames, store.session.mcpFeatures);\n } else {\n setPhase(Phase.FeatureSelect);\n }\n };\n\n const handleConfirm = () => {\n if (isRemove) {\n void doRemove();\n } else if (clients.length === 1) {\n proceedToFeatureSelectOrInstall(clients.map((c) => c.name));\n } else {\n setPhase(Phase.Pick);\n }\n };\n\n const handleSkip = () => {\n markDone(store, McpOutcome.Skipped, [], standalone);\n };\n\n const doInstall = async (names: string[], features?: string[]) => {\n setPhase(Phase.Working);\n let result: string[] = [];\n try {\n result = await installer.install(names, features);\n setResultClients(result);\n } catch {\n setResultClients([]);\n }\n setPhase(Phase.Done);\n const outcome =\n result.length > 0 ? McpOutcome.Installed : McpOutcome.Failed;\n setTimeout(() => markDone(store, outcome, result, standalone), 2000);\n };\n\n const doRemove = async () => {\n setPhase(Phase.Working);\n let result: string[] = [];\n try {\n result = await installer.remove();\n setResultClients(result);\n } catch {\n setResultClients([]);\n }\n setPhase(Phase.Done);\n const outcome =\n result.length > 0 ? McpOutcome.Installed : McpOutcome.Failed;\n setTimeout(() => markDone(store, outcome, result, standalone), 2000);\n };\n\n return (\n <Box flexDirection=\"column\" flexGrow={1}>\n <Text bold color={Colors.accent}>\n MCP Server {isRemove ? 'Removal' : 'Setup'}\n </Text>\n\n <Box marginTop={1} flexDirection=\"column\">\n {phase === Phase.Detecting && (\n <Text dimColor>Detecting supported editors...</Text>\n )}\n\n {phase === Phase.None && (\n <Text dimColor>\n No {isRemove ? 'installed' : 'supported'} MCP clients detected.\n Skipping...\n </Text>\n )}\n\n {phase === Phase.Ask && (\n <>\n <Text dimColor>\n Detected: {clients.map((c) => c.name).join(', ')}\n </Text>\n <Box marginTop={1}>\n <ConfirmationInput\n message={\n isRemove\n ? 'Remove the PostHog MCP server from your editor?'\n : 'Install the PostHog MCP server to your editor?'\n }\n confirmLabel={isRemove ? 'Remove MCP' : 'Install MCP'}\n cancelLabel=\"No thanks\"\n onConfirm={handleConfirm}\n onCancel={handleSkip}\n />\n </Box>\n </>\n )}\n\n {phase === Phase.Pick && (\n <PickerMenu\n message=\"Select editor to install MCP server\"\n options={clients.map((c) => ({\n label: c.name,\n value: c.name,\n }))}\n mode=\"multi\"\n onSelect={(selected) => {\n const names = Array.isArray(selected) ? selected : [selected];\n proceedToFeatureSelectOrInstall(names);\n }}\n />\n )}\n\n {phase === Phase.FeatureSelect && (\n <GroupedPickerMenu\n message=\"Select features to enable\"\n groups={AVAILABLE_FEATURES}\n initialSelected={[...ALL_FEATURE_VALUES]}\n onSelect={(features) => {\n void doInstall(selectedClientNames, features);\n }}\n />\n )}\n\n {phase === Phase.Working && (\n <Text dimColor>\n {isRemove ? 'Removing' : 'Installing'} MCP server...\n </Text>\n )}\n\n {phase === Phase.Done && (\n <Box flexDirection=\"column\">\n {resultClients.length > 0 ? (\n <>\n <Text color=\"green\" bold>\n {'\\u2714'} MCP server{' '}\n {isRemove ? 'removed from' : 'installed for'}:\n </Text>\n {resultClients.map((name, i) => (\n <Text key={i}>\n {' '}\n {'\\u2022'} {name}\n </Text>\n ))}\n </>\n ) : (\n <Text dimColor>\n {isRemove ? 'Removal' : 'Installation'} skipped.\n </Text>\n )}\n </Box>\n )}\n </Box>\n </Box>\n );\n};\n"]}
@@ -11,7 +11,7 @@ export interface McpInstaller {
11
11
  /** Detect which MCP-capable editors are available on this machine. */
12
12
  detectClients(): Promise<McpClientInfo[]>;
13
13
  /** Install the PostHog MCP server to the given clients. Returns names of successfully installed clients. */
14
- install(clientNames: string[]): Promise<string[]>;
14
+ install(clientNames: string[], features?: string[]): Promise<string[]>;
15
15
  /** Remove the PostHog MCP server from all installed clients. Returns names of removed clients. */
16
16
  remove(): Promise<string[]>;
17
17
  }
@@ -19,8 +19,8 @@ export function createMcpInstaller() {
19
19
  cachedClients = supported.map((c) => ({ name: c.name, raw: c }));
20
20
  return supported.map((c) => ({ name: c.name }));
21
21
  },
22
- async install(clientNames) {
23
- const features = [...ALL_FEATURE_VALUES];
22
+ async install(clientNames, features) {
23
+ const resolvedFeatures = features ?? [...ALL_FEATURE_VALUES];
24
24
  const toInstall = cachedClients
25
25
  .filter((c) => clientNames.includes(c.name))
26
26
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
@@ -32,7 +32,7 @@ export function createMcpInstaller() {
32
32
  const installed = [];
33
33
  for (const client of toInstall) {
34
34
  try {
35
- const result = await client.addServer(undefined, features, false);
35
+ const result = await client.addServer(undefined, resolvedFeatures, false);
36
36
  if (result?.success) {
37
37
  installed.push(client.name);
38
38
  }
@@ -1 +1 @@
1
- {"version":3,"file":"mcp-installer.js","sourceRoot":"","sources":["../../../../../src/ui/tui/services/mcp-installer.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EACL,mBAAmB,EACnB,eAAe,EACf,mBAAmB,GACpB,MAAM,mDAAmD,CAAC;AAC3D,OAAO,EAAE,kBAAkB,EAAE,MAAM,sDAAsD,CAAC;AAC1F,OAAO,EAAE,SAAS,EAAE,MAAM,yBAAyB,CAAC;AAiBpD;;GAEG;AACH,MAAM,UAAU,kBAAkB;IAChC,0EAA0E;IAC1E,IAAI,aAAa,GAA0C,EAAE,CAAC;IAE9D,OAAO;QACL,KAAK,CAAC,aAAa;YACjB,MAAM,SAAS,GAAG,MAAM,mBAAmB,EAAE,CAAC;YAC9C,aAAa,GAAG,SAAS,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,GAAG,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC;YACjE,OAAO,SAAS,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC;QAClD,CAAC;QAED,KAAK,CAAC,OAAO,CAAC,WAAqB;YACjC,MAAM,QAAQ,GAAG,CAAC,GAAG,kBAAkB,CAAC,CAAC;YACzC,MAAM,SAAS,GAAG,aAAa;iBAC5B,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,WAAW,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;gBAC5C,8DAA8D;iBAC7D,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,GAAU,CAAC,CAAC;YAE5B,IAAI,SAAS,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;gBAC3B,SAAS,CACP,kDAAkD,IAAI,CAAC,SAAS,CAC9D,WAAW,CACZ,YAAY,IAAI,CAAC,SAAS,CAAC,aAAa,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,EAAE,CAChE,CAAC;gBACF,OAAO,EAAE,CAAC;YACZ,CAAC;YAED,MAAM,SAAS,GAAa,EAAE,CAAC;YAC/B,KAAK,MAAM,MAAM,IAAI,SAAS,EAAE,CAAC;gBAC/B,IAAI,CAAC;oBACH,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,SAAS,CAAC,SAAS,EAAE,QAAQ,EAAE,KAAK,CAAC,CAAC;oBAClE,IAAI,MAAM,EAAE,OAAO,EAAE,CAAC;wBACpB,SAAS,CAAC,IAAI,CAAC,MAAM,CAAC,IAAc,CAAC,CAAC;oBACxC,CAAC;yBAAM,CAAC;wBACN,SAAS,CACP,uDAAuD,MAAM,CAAC,IAAI,EAAE,CACrE,CAAC;oBACJ,CAAC;gBACH,CAAC;gBAAC,OAAO,GAAG,EAAE,CAAC;oBACb,SAAS,CACP,sCAAsC,MAAM,CAAC,IAAI,KAC/C,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CACjD,EAAE,CACH,CAAC;gBACJ,CAAC;YACH,CAAC;YACD,OAAO,SAAS,CAAC;QACnB,CAAC;QAED,KAAK,CAAC,MAAM;YACV,MAAM,SAAS,GAAG,MAAM,mBAAmB,EAAE,CAAC;YAC9C,IAAI,SAAS,CAAC,MAAM,KAAK,CAAC;gBAAE,OAAO,EAAE,CAAC;YACtC,MAAM,eAAe,CAAC,SAAS,CAAC,CAAC;YACjC,OAAO,SAAS,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;QACtC,CAAC;KACF,CAAC;AACJ,CAAC","sourcesContent":["/**\n * McpInstaller — service layer between McpScreen and MCP business logic.\n *\n * Decouples the screen from step internals. Testable, swappable,\n * no dynamic imports in React components.\n */\n\nimport {\n getSupportedClients,\n removeMCPServer,\n getInstalledClients,\n} from '../../../steps/add-mcp-server-to-clients/index.js';\nimport { ALL_FEATURE_VALUES } from '../../../steps/add-mcp-server-to-clients/defaults.js';\nimport { logToFile } from '../../../utils/debug.js';\n\nexport interface McpClientInfo {\n name: string;\n}\n\nexport interface McpInstaller {\n /** Detect which MCP-capable editors are available on this machine. */\n detectClients(): Promise<McpClientInfo[]>;\n\n /** Install the PostHog MCP server to the given clients. Returns names of successfully installed clients. */\n install(clientNames: string[]): Promise<string[]>;\n\n /** Remove the PostHog MCP server from all installed clients. Returns names of removed clients. */\n remove(): Promise<string[]>;\n}\n\n/**\n * Production McpInstaller backed by real MCP client detection and installation.\n */\nexport function createMcpInstaller(): McpInstaller {\n // Cache the raw MCPClient objects so install() can reference them by name\n let cachedClients: Array<{ name: string; raw: unknown }> = [];\n\n return {\n async detectClients(): Promise<McpClientInfo[]> {\n const supported = await getSupportedClients();\n cachedClients = supported.map((c) => ({ name: c.name, raw: c }));\n return supported.map((c) => ({ name: c.name }));\n },\n\n async install(clientNames: string[]): Promise<string[]> {\n const features = [...ALL_FEATURE_VALUES];\n const toInstall = cachedClients\n .filter((c) => clientNames.includes(c.name))\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n .map((c) => c.raw as any);\n\n if (toInstall.length === 0) {\n logToFile(\n `[McpInstaller] No clients matched. clientNames=${JSON.stringify(\n clientNames,\n )}, cached=${JSON.stringify(cachedClients.map((c) => c.name))}`,\n );\n return [];\n }\n\n const installed: string[] = [];\n for (const client of toInstall) {\n try {\n const result = await client.addServer(undefined, features, false);\n if (result?.success) {\n installed.push(client.name as string);\n } else {\n logToFile(\n `[McpInstaller] addServer returned success=false for ${client.name}`,\n );\n }\n } catch (err) {\n logToFile(\n `[McpInstaller] addServer threw for ${client.name}: ${\n err instanceof Error ? err.message : String(err)\n }`,\n );\n }\n }\n return installed;\n },\n\n async remove(): Promise<string[]> {\n const installed = await getInstalledClients();\n if (installed.length === 0) return [];\n await removeMCPServer(installed);\n return installed.map((c) => c.name);\n },\n };\n}\n"]}
1
+ {"version":3,"file":"mcp-installer.js","sourceRoot":"","sources":["../../../../../src/ui/tui/services/mcp-installer.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EACL,mBAAmB,EACnB,eAAe,EACf,mBAAmB,GACpB,MAAM,mDAAmD,CAAC;AAC3D,OAAO,EAAE,kBAAkB,EAAE,MAAM,sDAAsD,CAAC;AAC1F,OAAO,EAAE,SAAS,EAAE,MAAM,yBAAyB,CAAC;AAiBpD;;GAEG;AACH,MAAM,UAAU,kBAAkB;IAChC,0EAA0E;IAC1E,IAAI,aAAa,GAA0C,EAAE,CAAC;IAE9D,OAAO;QACL,KAAK,CAAC,aAAa;YACjB,MAAM,SAAS,GAAG,MAAM,mBAAmB,EAAE,CAAC;YAC9C,aAAa,GAAG,SAAS,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,GAAG,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC;YACjE,OAAO,SAAS,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC;QAClD,CAAC;QAED,KAAK,CAAC,OAAO,CACX,WAAqB,EACrB,QAAmB;YAEnB,MAAM,gBAAgB,GAAG,QAAQ,IAAI,CAAC,GAAG,kBAAkB,CAAC,CAAC;YAC7D,MAAM,SAAS,GAAG,aAAa;iBAC5B,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,WAAW,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;gBAC5C,8DAA8D;iBAC7D,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,GAAU,CAAC,CAAC;YAE5B,IAAI,SAAS,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;gBAC3B,SAAS,CACP,kDAAkD,IAAI,CAAC,SAAS,CAC9D,WAAW,CACZ,YAAY,IAAI,CAAC,SAAS,CAAC,aAAa,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,EAAE,CAChE,CAAC;gBACF,OAAO,EAAE,CAAC;YACZ,CAAC;YAED,MAAM,SAAS,GAAa,EAAE,CAAC;YAC/B,KAAK,MAAM,MAAM,IAAI,SAAS,EAAE,CAAC;gBAC/B,IAAI,CAAC;oBACH,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,SAAS,CACnC,SAAS,EACT,gBAAgB,EAChB,KAAK,CACN,CAAC;oBACF,IAAI,MAAM,EAAE,OAAO,EAAE,CAAC;wBACpB,SAAS,CAAC,IAAI,CAAC,MAAM,CAAC,IAAc,CAAC,CAAC;oBACxC,CAAC;yBAAM,CAAC;wBACN,SAAS,CACP,uDAAuD,MAAM,CAAC,IAAI,EAAE,CACrE,CAAC;oBACJ,CAAC;gBACH,CAAC;gBAAC,OAAO,GAAG,EAAE,CAAC;oBACb,SAAS,CACP,sCAAsC,MAAM,CAAC,IAAI,KAC/C,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CACjD,EAAE,CACH,CAAC;gBACJ,CAAC;YACH,CAAC;YACD,OAAO,SAAS,CAAC;QACnB,CAAC;QAED,KAAK,CAAC,MAAM;YACV,MAAM,SAAS,GAAG,MAAM,mBAAmB,EAAE,CAAC;YAC9C,IAAI,SAAS,CAAC,MAAM,KAAK,CAAC;gBAAE,OAAO,EAAE,CAAC;YACtC,MAAM,eAAe,CAAC,SAAS,CAAC,CAAC;YACjC,OAAO,SAAS,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;QACtC,CAAC;KACF,CAAC;AACJ,CAAC","sourcesContent":["/**\n * McpInstaller — service layer between McpScreen and MCP business logic.\n *\n * Decouples the screen from step internals. Testable, swappable,\n * no dynamic imports in React components.\n */\n\nimport {\n getSupportedClients,\n removeMCPServer,\n getInstalledClients,\n} from '../../../steps/add-mcp-server-to-clients/index.js';\nimport { ALL_FEATURE_VALUES } from '../../../steps/add-mcp-server-to-clients/defaults.js';\nimport { logToFile } from '../../../utils/debug.js';\n\nexport interface McpClientInfo {\n name: string;\n}\n\nexport interface McpInstaller {\n /** Detect which MCP-capable editors are available on this machine. */\n detectClients(): Promise<McpClientInfo[]>;\n\n /** Install the PostHog MCP server to the given clients. Returns names of successfully installed clients. */\n install(clientNames: string[], features?: string[]): Promise<string[]>;\n\n /** Remove the PostHog MCP server from all installed clients. Returns names of removed clients. */\n remove(): Promise<string[]>;\n}\n\n/**\n * Production McpInstaller backed by real MCP client detection and installation.\n */\nexport function createMcpInstaller(): McpInstaller {\n // Cache the raw MCPClient objects so install() can reference them by name\n let cachedClients: Array<{ name: string; raw: unknown }> = [];\n\n return {\n async detectClients(): Promise<McpClientInfo[]> {\n const supported = await getSupportedClients();\n cachedClients = supported.map((c) => ({ name: c.name, raw: c }));\n return supported.map((c) => ({ name: c.name }));\n },\n\n async install(\n clientNames: string[],\n features?: string[],\n ): Promise<string[]> {\n const resolvedFeatures = features ?? [...ALL_FEATURE_VALUES];\n const toInstall = cachedClients\n .filter((c) => clientNames.includes(c.name))\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n .map((c) => c.raw as any);\n\n if (toInstall.length === 0) {\n logToFile(\n `[McpInstaller] No clients matched. clientNames=${JSON.stringify(\n clientNames,\n )}, cached=${JSON.stringify(cachedClients.map((c) => c.name))}`,\n );\n return [];\n }\n\n const installed: string[] = [];\n for (const client of toInstall) {\n try {\n const result = await client.addServer(\n undefined,\n resolvedFeatures,\n false,\n );\n if (result?.success) {\n installed.push(client.name as string);\n } else {\n logToFile(\n `[McpInstaller] addServer returned success=false for ${client.name}`,\n );\n }\n } catch (err) {\n logToFile(\n `[McpInstaller] addServer threw for ${client.name}: ${\n err instanceof Error ? err.message : String(err)\n }`,\n );\n }\n }\n return installed;\n },\n\n async remove(): Promise<string[]> {\n const installed = await getInstalledClients();\n if (installed.length === 0) return [];\n await removeMCPServer(installed);\n return installed.map((c) => c.name);\n },\n };\n}\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@posthog/wizard",
3
- "version": "2.4.0",
3
+ "version": "2.5.0",
4
4
  "homepage": "https://github.com/PostHog/wizard",
5
5
  "repository": "https://github.com/PostHog/wizard",
6
6
  "description": "The PostHog wizard helps you to configure your project",
@@ -92,7 +92,7 @@
92
92
  "typescript": "^5.0.4"
93
93
  },
94
94
  "engines": {
95
- "node": ">=18",
95
+ "node": "^20.20.0 || >=22.22.0",
96
96
  "npm": ">=3.10.7"
97
97
  },
98
98
  "jest": {
@@ -137,7 +137,7 @@
137
137
  "author": "PostHog",
138
138
  "license": "MIT",
139
139
  "volta": {
140
- "node": "20.18.2",
140
+ "node": "20.20.0",
141
141
  "pnpm": "10.23.0"
142
142
  },
143
143
  "scripts": {