@posthog/wizard 2.10.2 → 2.10.3

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 (37) hide show
  1. package/dist/{McpScreen-BUr995Wh.js → McpScreen-23GY1pWz.js} +3 -3
  2. package/dist/{McpScreen-BUr995Wh.js.map → McpScreen-23GY1pWz.js.map} +1 -1
  3. package/dist/{add-mcp-server-to-clients-65h6IpxC.js → add-mcp-server-to-clients-B6baHy_h.js} +3 -3
  4. package/dist/{add-mcp-server-to-clients-65h6IpxC.js.map → add-mcp-server-to-clients-B6baHy_h.js.map} +1 -1
  5. package/dist/{agent-runner-DsymRIHf.js → agent-runner-CBPBefLt.js} +6 -6
  6. package/dist/{agent-runner-DsymRIHf.js.map → agent-runner-CBPBefLt.js.map} +1 -1
  7. package/dist/analytics-DdTDVjqs.js +2 -0
  8. package/dist/{analytics-CpRZ9V5j.js → analytics-xANpxdVL.js} +2 -2
  9. package/dist/{analytics-CpRZ9V5j.js.map → analytics-xANpxdVL.js.map} +1 -1
  10. package/dist/bin.js +20 -18
  11. package/dist/bin.js.map +1 -1
  12. package/dist/{detection-D8428PBG.js → detection-Drfq0l8n.js} +3 -3
  13. package/dist/{detection-D8428PBG.js.map → detection-Drfq0l8n.js.map} +1 -1
  14. package/dist/{package-manager-B_VtY9ZS.js → package-manager-Ls_8r9Ot.js} +2 -2
  15. package/dist/{package-manager-B_VtY9ZS.js.map → package-manager-Ls_8r9Ot.js.map} +1 -1
  16. package/dist/{posthog-integration-EeKb2FkQ.js → posthog-integration-DUZpiyxg.js} +7 -7
  17. package/dist/{posthog-integration-EeKb2FkQ.js.map → posthog-integration-DUZpiyxg.js.map} +1 -1
  18. package/dist/{readiness-V6pfR5tp.js → readiness-BAgN8xAg.js} +4 -4
  19. package/dist/{readiness-V6pfR5tp.js.map → readiness-BAgN8xAg.js.map} +1 -1
  20. package/dist/{registry-BUdvRdBh.js → registry-qfhSxTjo.js} +4 -4
  21. package/dist/{registry-BUdvRdBh.js.map → registry-qfhSxTjo.js.map} +1 -1
  22. package/dist/{setup-utils-DJuYiRId.js → setup-utils-C1h1QDiG.js} +4 -4
  23. package/dist/{setup-utils-DJuYiRId.js.map → setup-utils-C1h1QDiG.js.map} +1 -1
  24. package/dist/{start-playground-mQFlOf6e.js → start-playground-xOLMYzst.js} +3 -3
  25. package/dist/{start-playground-mQFlOf6e.js.map → start-playground-xOLMYzst.js.map} +1 -1
  26. package/dist/{start-tui-CSLj4eU7.js → start-tui-Ddo4TI9T.js} +7 -7
  27. package/dist/{start-tui-CSLj4eU7.js.map → start-tui-Ddo4TI9T.js.map} +1 -1
  28. package/dist/{steps-u8U1Nz2e.js → steps-BjvFG--8.js} +5 -5
  29. package/dist/{steps-u8U1Nz2e.js.map → steps-BjvFG--8.js.map} +1 -1
  30. package/dist/{telemetry-CjokGP19.js → telemetry-CC6zPKJg.js} +2 -2
  31. package/dist/{telemetry-CjokGP19.js.map → telemetry-CC6zPKJg.js.map} +1 -1
  32. package/dist/{wizard-abort-0IZHiW_d.js → wizard-abort-Bc3lWNLb.js} +1 -1
  33. package/dist/{wizard-abort-DhECsFZO.js → wizard-abort-XhapT0Ly.js} +2 -2
  34. package/dist/{wizard-abort-DhECsFZO.js.map → wizard-abort-XhapT0Ly.js.map} +1 -1
  35. package/npm-shrinkwrap.json +2 -2
  36. package/package.json +1 -1
  37. package/dist/analytics-D6yTMqoi.js +0 -2
package/dist/bin.js CHANGED
@@ -1,9 +1,9 @@
1
1
  #!/usr/bin/env node
2
2
  import { t as __exportAll } from "./rolldown-runtime-B_-DWIq7.js";
3
3
  import { c as getUI, f as runtimeEnv, l as setUI, p as red, u as LoggingUI } from "./debug-CyJ_3dTP.js";
4
- import { T as VERSION } from "./analytics-CpRZ9V5j.js";
5
- import "./setup-utils-DJuYiRId.js";
6
- import { t as posthogIntegrationConfig } from "./posthog-integration-EeKb2FkQ.js";
4
+ import { T as VERSION } from "./analytics-xANpxdVL.js";
5
+ import "./setup-utils-C1h1QDiG.js";
6
+ import { t as posthogIntegrationConfig } from "./posthog-integration-DUZpiyxg.js";
7
7
  import { t as IGNORED_DIRS } from "./file-utils-BWneZy6p.js";
8
8
  import { satisfies } from "semver";
9
9
  import yargs from "yargs";
@@ -366,11 +366,11 @@ const cli = yargs(hideBin(process.argv)).env("POSTHOG_WIZARD").options({
366
366
  return;
367
367
  }
368
368
  (async () => {
369
- const { posthogIntegrationConfig } = await import("./posthog-integration-EeKb2FkQ.js").then((n) => n.n);
370
- const { FRAMEWORK_REGISTRY } = await import("./registry-BUdvRdBh.js").then((n) => n.n);
371
- const { detectFramework, gatherFrameworkContext } = await import("./detection-D8428PBG.js").then((n) => n.t);
372
- const { analytics } = await import("./analytics-D6yTMqoi.js");
373
- const { wizardAbort } = await import("./wizard-abort-0IZHiW_d.js");
369
+ const { posthogIntegrationConfig } = await import("./posthog-integration-DUZpiyxg.js").then((n) => n.n);
370
+ const { FRAMEWORK_REGISTRY } = await import("./registry-qfhSxTjo.js").then((n) => n.n);
371
+ const { detectFramework, gatherFrameworkContext } = await import("./detection-Drfq0l8n.js").then((n) => n.t);
372
+ const { analytics } = await import("./analytics-DdTDVjqs.js");
373
+ const { wizardAbort } = await import("./wizard-abort-Bc3lWNLb.js");
374
374
  runWizardCI(posthogIntegrationConfig, options, async (session) => {
375
375
  const integration = session.integration ?? await detectFramework(session.installDir);
376
376
  if (!integration) {
@@ -403,7 +403,7 @@ const cli = yargs(hideBin(process.argv)).env("POSTHOG_WIZARD").options({
403
403
  getUI().log.error("This installer requires an interactive terminal (TTY) to run.\nIt appears you are running in a non-interactive environment.\nPlease run the wizard in an interactive terminal.\n\nFor CI/CD environments, use --ci mode:\n npx @posthog/wizard --ci --region us --api-key phx_xxx");
404
404
  process.exit(1);
405
405
  } else if (options.playground) (async () => {
406
- const { startPlayground } = await import("./start-playground-mQFlOf6e.js");
406
+ const { startPlayground } = await import("./start-playground-xOLMYzst.js");
407
407
  startPlayground(WIZARD_VERSION);
408
408
  })();
409
409
  else if (options.skill) (async () => {
@@ -423,7 +423,7 @@ const cli = yargs(hideBin(process.argv)).env("POSTHOG_WIZARD").options({
423
423
  }), options);
424
424
  })();
425
425
  else (async () => {
426
- const { posthogIntegrationConfig } = await import("./posthog-integration-EeKb2FkQ.js").then((n) => n.n);
426
+ const { posthogIntegrationConfig } = await import("./posthog-integration-DUZpiyxg.js").then((n) => n.n);
427
427
  runWizard(posthogIntegrationConfig, options);
428
428
  })();
429
429
  }).command("mcp <command>", "MCP server management commands", (yargs) => {
@@ -450,7 +450,7 @@ const cli = yargs(hideBin(process.argv)).env("POSTHOG_WIZARD").options({
450
450
  const { readApiKeyFromEnv } = await import("./env-api-key-K8TdTDII.js");
451
451
  const apiKey = options.apiKey || readApiKeyFromEnv();
452
452
  try {
453
- const { startTUI } = await import("./start-tui-CSLj4eU7.js");
453
+ const { startTUI } = await import("./start-tui-Ddo4TI9T.js");
454
454
  const { buildSession } = await import("./wizard-session-y7nf6aKH.js");
455
455
  const { Flow } = await import("./router-D5A1Sb4p.js").then((n) => n.n);
456
456
  const tui = startTUI(WIZARD_VERSION, Flow.McpAdd);
@@ -463,7 +463,7 @@ const cli = yargs(hideBin(process.argv)).env("POSTHOG_WIZARD").options({
463
463
  tui.store.session = session;
464
464
  } catch {
465
465
  setUI(new LoggingUI());
466
- const { addMCPServerToClientsStep } = await import("./add-mcp-server-to-clients-65h6IpxC.js").then((n) => n.r);
466
+ const { addMCPServerToClientsStep } = await import("./add-mcp-server-to-clients-B6baHy_h.js").then((n) => n.r);
467
467
  await addMCPServerToClientsStep({
468
468
  local: options.local,
469
469
  features: mcpFeatures,
@@ -481,7 +481,7 @@ const cli = yargs(hideBin(process.argv)).env("POSTHOG_WIZARD").options({
481
481
  const options = { ...argv };
482
482
  (async () => {
483
483
  try {
484
- const { startTUI } = await import("./start-tui-CSLj4eU7.js");
484
+ const { startTUI } = await import("./start-tui-Ddo4TI9T.js");
485
485
  const { buildSession } = await import("./wizard-session-y7nf6aKH.js");
486
486
  const { Flow } = await import("./router-D5A1Sb4p.js").then((n) => n.n);
487
487
  const tui = startTUI(WIZARD_VERSION, Flow.McpRemove);
@@ -492,7 +492,7 @@ const cli = yargs(hideBin(process.argv)).env("POSTHOG_WIZARD").options({
492
492
  tui.store.session = session;
493
493
  } catch {
494
494
  setUI(new LoggingUI());
495
- const { removeMCPServerFromClientsStep } = await import("./add-mcp-server-to-clients-65h6IpxC.js").then((n) => n.r);
495
+ const { removeMCPServerFromClientsStep } = await import("./add-mcp-server-to-clients-B6baHy_h.js").then((n) => n.r);
496
496
  await removeMCPServerFromClientsStep({ local: options.local });
497
497
  }
498
498
  })();
@@ -513,7 +513,7 @@ function runWizard(config, options) {
513
513
  (async () => {
514
514
  try {
515
515
  const installDir = options.installDir || process.cwd();
516
- const { startTUI } = await import("./start-tui-CSLj4eU7.js");
516
+ const { startTUI } = await import("./start-tui-Ddo4TI9T.js");
517
517
  const { buildSession } = await import("./wizard-session-y7nf6aKH.js");
518
518
  const tui = startTUI(WIZARD_VERSION, config.flowKey);
519
519
  const session = buildSession({
@@ -525,6 +525,7 @@ function runWizard(config, options) {
525
525
  signup: options.signup,
526
526
  apiKey: options.apiKey,
527
527
  projectId: options.projectId,
528
+ email: options.email,
528
529
  menu: options.menu,
529
530
  integration: options.integration,
530
531
  benchmark: options.benchmark,
@@ -535,7 +536,7 @@ function runWizard(config, options) {
535
536
  tui.store.session = session;
536
537
  await tui.store.runReadyHooks();
537
538
  await tui.store.getGate("intro");
538
- const { runAgent } = await import("./agent-runner-DsymRIHf.js");
539
+ const { runAgent } = await import("./agent-runner-CBPBefLt.js");
539
540
  await runAgent(config, tui.store.session);
540
541
  await new Promise((resolve) => {
541
542
  const unsub = tui.store.subscribe(() => {
@@ -582,7 +583,7 @@ function runWizardCI(config, options, preRun) {
582
583
  const { readEnvironment } = await Promise.resolve().then(() => environment_exports);
583
584
  const { readApiKeyFromEnv } = await import("./env-api-key-K8TdTDII.js");
584
585
  const { configureLogFileFromEnvironment, logToFile } = await import("./debug-CIyf0ZGx.js");
585
- const { wizardAbort, WizardError } = await import("./wizard-abort-0IZHiW_d.js");
586
+ const { wizardAbort, WizardError } = await import("./wizard-abort-Bc3lWNLb.js");
586
587
  configureLogFileFromEnvironment();
587
588
  const env = readEnvironment();
588
589
  const apiKey = options.apiKey ?? readApiKeyFromEnv() ?? void 0;
@@ -595,6 +596,7 @@ function runWizardCI(config, options, preRun) {
595
596
  signup: options.signup,
596
597
  localMcp: options.localMcp,
597
598
  apiKey,
599
+ email: options.email,
598
600
  menu: options.menu,
599
601
  integration: options.integration,
600
602
  projectId: options.projectId,
@@ -631,7 +633,7 @@ function runWizardCI(config, options, preRun) {
631
633
  })
632
634
  });
633
635
  }
634
- const { runAgent } = await import("./agent-runner-DsymRIHf.js");
636
+ const { runAgent } = await import("./agent-runner-CBPBefLt.js");
635
637
  await runAgent(config, session);
636
638
  } catch (error) {
637
639
  const errorMessage = error instanceof Error ? error.message : String(error);
package/dist/bin.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"bin.js","names":[],"sources":["../src/utils/environment.ts","../src/lib/workflows/revenue-analytics/detect.ts","../src/lib/workflows/revenue-analytics/steps.ts","../src/lib/workflows/revenue-analytics/index.ts","../src/lib/workflows/workflow-registry.ts","../bin.ts"],"sourcesContent":["import readEnvModule from 'read-env';\n\nconst readEnv =\n typeof readEnvModule === 'function'\n ? readEnvModule\n : (readEnvModule as any).default;\nimport { tryGetPackageJson } from './setup-utils';\nimport type { WizardOptions } from './types';\nimport fg from 'fast-glob';\nimport { IS_DEV } from '../lib/constants';\n\nexport function isNonInteractiveEnvironment(): boolean {\n if (IS_DEV) {\n return false;\n }\n\n if (!process.stdout.isTTY || !process.stderr.isTTY) {\n return true;\n }\n\n return false;\n}\n\nexport function readEnvironment(): Record<string, unknown> {\n const result = readEnv('POSTHOG_WIZARD');\n\n return result;\n}\n\nexport async function detectEnvVarPrefix(\n options: WizardOptions,\n): Promise<string> {\n const packageJson = await tryGetPackageJson(options);\n if (!packageJson) return 'VITE_PUBLIC_';\n\n const deps = { ...packageJson.dependencies, ...packageJson.devDependencies };\n const has = (name: string) => name in deps;\n const hasAnyFile = async (patterns: string[]) => {\n const matches = await fg(patterns, {\n cwd: options.installDir,\n absolute: false,\n onlyFiles: true,\n ignore: ['**/node_modules/**'],\n });\n return matches.length > 0;\n };\n\n // --- Next.js\n if (has('next') || (await hasAnyFile(['**/next.config.{js,ts,mjs,cjs}']))) {\n return 'NEXT_PUBLIC_';\n }\n\n // --- Create React App\n if (\n has('react-scripts') ||\n has('create-react-app') ||\n (await hasAnyFile(['**/config-overrides.js']))\n ) {\n return 'REACT_APP_';\n }\n\n // --- Vite (vanilla, TanStack, Solid, etc.)\n // Note: Vite does not need PUBLIC_ but we use it to follow the docs, to improve the chances of an LLM getting it right.\n if (has('vite') || (await hasAnyFile(['**/vite.config.{js,ts,mjs,cjs}']))) {\n return 'VITE_PUBLIC_';\n }\n\n // --- SvelteKit\n if (\n has('@sveltejs/kit') ||\n (await hasAnyFile(['**/svelte.config.{js,ts}']))\n ) {\n return 'PUBLIC_';\n }\n\n // --- TanStack Start (uses Vite)\n if (\n has('@tanstack/start') ||\n (await hasAnyFile(['**/tanstack.config.{js,ts}']))\n ) {\n return 'VITE_PUBLIC_';\n }\n\n // --- SolidStart (uses Vite)\n if (has('solid-start') || (await hasAnyFile(['**/solid.config.{js,ts}']))) {\n return 'VITE_PUBLIC_';\n }\n\n // --- Astro\n if (has('astro') || (await hasAnyFile(['**/astro.config.{js,ts,mjs}']))) {\n return 'PUBLIC_';\n }\n\n // We default to Vite if we can't detect a specific framework, since it's the most commonly used.\n return 'VITE_PUBLIC_';\n}\n","/**\n * Revenue analytics prerequisite detection.\n *\n * Scans the project for PostHog + Stripe SDKs and writes results\n * into frameworkContext for the intro screen to render.\n */\n\nimport type { Dirent } from 'fs';\nimport { readFileSync, readdirSync, existsSync, statSync } from 'fs';\nimport { join, relative } from 'path';\nimport { IGNORED_DIRS } from '../../../utils/file-utils.js';\nimport type { WizardSession } from '../../wizard-session.js';\nimport type { AbortCase } from '../../agent/agent-runner.js';\n\nexport const POSTHOG_SDKS = [\n 'posthog-js',\n 'posthog-node',\n 'posthog-react-native',\n 'posthog-android',\n 'posthog-ios',\n];\n\nexport const STRIPE_SDKS = [\n 'stripe',\n '@stripe/stripe-js',\n '@stripe/react-stripe-js',\n];\n\ninterface PackageMatch {\n /** Path to the package.json relative to installDir */\n path: string;\n posthogSdks: string[];\n stripeSdks: string[];\n}\n\n/**\n * Structured detection errors. The screen renders each kind into JSX\n * with proper formatting — keeps error data separate from presentation.\n */\nexport type RevenueDetectError =\n | {\n kind: 'bad-directory';\n path: string;\n reason: 'missing' | 'not-dir' | 'unreadable';\n }\n | { kind: 'no-package-json' }\n | { kind: 'no-sdks'; scannedCount: number }\n | { kind: 'missing-posthog'; foundStripe: string[] }\n | { kind: 'missing-stripe'; foundPosthog: string[] };\n\n/** `[ABORT] <reason>` cases the revenue analytics skill can emit. */\nexport const REVENUE_ABORT_CASES: AbortCase[] = [\n {\n // Skill emits: [ABORT] Could not find a PostHog distinct_id\n match: /^could not find a posthog distinct_id$/i,\n message: 'Could not find a PostHog distinct_id',\n body:\n 'The agent could not find PostHog distinct_id usage in your codebase. ' +\n 'Your users must be identified in PostHog before they can be tagged in Stripe. ' +\n 'Please identify your users and try again.',\n docsUrl: 'https://posthog.com/docs/product-analytics/identify',\n },\n {\n // Skill emits: [ABORT] Could not find a Stripe integration\n match: /^could not find a stripe integration$/i,\n message: 'Could not find a Stripe integration',\n body:\n 'The Wizard could not find an existing Stripe customer, charge, ' +\n 'subscription, or other Stripe operations. Please run the Revenue ' +\n 'Analytics Wizard on a project with an existing Stripe integration.',\n docsUrl: 'https://posthog.com/docs/revenue-analytics',\n },\n];\n\n/**\n * Recursively find all package.json files under installDir (max depth 3),\n * skipping common ignored directories. Returns matches with detected SDKs.\n */\nfunction findPackageJsons(installDir: string, maxDepth = 3): PackageMatch[] {\n const matches: PackageMatch[] = [];\n\n function scan(dir: string, depth: number): void {\n if (depth > maxDepth) return;\n\n let entries: Dirent[];\n try {\n entries = readdirSync(dir, { withFileTypes: true });\n } catch {\n return;\n }\n\n for (const entry of entries) {\n if (entry.name.startsWith('.') && entry.name !== '.') continue;\n if (IGNORED_DIRS.has(entry.name)) continue;\n\n const fullPath = join(dir, entry.name);\n\n if (entry.isFile() && entry.name === 'package.json') {\n try {\n const pkg = JSON.parse(readFileSync(fullPath, 'utf-8')) as {\n dependencies?: Record<string, string>;\n devDependencies?: Record<string, string>;\n };\n const depNames = [\n ...Object.keys(pkg.dependencies ?? {}),\n ...Object.keys(pkg.devDependencies ?? {}),\n ];\n const posthogSdks = depNames.filter((d) => POSTHOG_SDKS.includes(d));\n const stripeSdks = depNames.filter((d) => STRIPE_SDKS.includes(d));\n matches.push({\n path: relative(installDir, fullPath) || 'package.json',\n posthogSdks,\n stripeSdks,\n });\n } catch {\n // Skip malformed package.json\n }\n } else if (entry.isDirectory()) {\n scan(fullPath, depth + 1);\n }\n }\n }\n\n scan(installDir, 0);\n return matches;\n}\n\n/**\n * Scan `session.installDir` for PostHog + Stripe SDKs. Writes detection\n * results into frameworkContext via the callback — either the detected\n * SDK lists (for the intro screen) or a `RevenueDetectError` on failure.\n *\n * The skill install happens later in the bootstrap runner, not here.\n */\nexport function detectRevenuePrerequisites(\n session: WizardSession,\n setFrameworkContext: (key: string, value: unknown) => void,\n): void {\n const fail = (error: RevenueDetectError) =>\n setFrameworkContext('detectError', error);\n\n const installDir = session.installDir;\n\n // Verify the install directory exists and is readable\n if (!existsSync(installDir)) {\n fail({ kind: 'bad-directory', path: installDir, reason: 'missing' });\n return;\n }\n try {\n if (!statSync(installDir).isDirectory()) {\n fail({ kind: 'bad-directory', path: installDir, reason: 'not-dir' });\n return;\n }\n } catch {\n fail({ kind: 'bad-directory', path: installDir, reason: 'unreadable' });\n return;\n }\n\n // Find all package.json files (root + monorepo subpackages)\n const matches = findPackageJsons(installDir);\n\n if (matches.length === 0) {\n fail({ kind: 'no-package-json' });\n return;\n }\n\n // Aggregate detected SDKs across all package.json files\n const allPosthogSdks = new Set<string>();\n const allStripeSdks = new Set<string>();\n for (const match of matches) {\n for (const sdk of match.posthogSdks) allPosthogSdks.add(sdk);\n for (const sdk of match.stripeSdks) allStripeSdks.add(sdk);\n }\n\n const detectedPosthogSdks = [...allPosthogSdks];\n const detectedStripeSdks = [...allStripeSdks];\n\n if (detectedPosthogSdks.length === 0 && detectedStripeSdks.length === 0) {\n fail({ kind: 'no-sdks', scannedCount: matches.length });\n return;\n }\n\n if (detectedPosthogSdks.length === 0) {\n fail({ kind: 'missing-posthog', foundStripe: detectedStripeSdks });\n return;\n }\n\n if (detectedStripeSdks.length === 0) {\n fail({ kind: 'missing-stripe', foundPosthog: detectedPosthogSdks });\n return;\n }\n\n setFrameworkContext('detectedPosthogSdks', detectedPosthogSdks);\n setFrameworkContext('detectedStripeSdks', detectedStripeSdks);\n setFrameworkContext(\n 'detectedPackagePaths',\n matches\n .filter((m) => m.posthogSdks.length > 0 || m.stripeSdks.length > 0)\n .map((m) => m.path),\n );\n}\n","/**\n * Revenue analytics workflow step list.\n *\n * The detect step checks for PostHog + Stripe SDKs. The skill install\n * and agent run live in the workflow runner (see agent-runner.ts).\n */\n\nimport type { Workflow } from '../workflow-step.js';\nimport { RunPhase } from '../../wizard-session.js';\nimport { detectRevenuePrerequisites } from './detect.js';\n\nexport const REVENUE_ANALYTICS_WORKFLOW: Workflow = [\n {\n id: 'detect',\n label: 'Detecting prerequisites',\n // Headless step: no screen, no gate. onReady fires after bin.ts\n // assigns the session — the hook scans for PostHog + Stripe SDKs\n // and writes the results (or a detectError) to frameworkContext\n // for the intro screen to render.\n onReady: (ctx) =>\n detectRevenuePrerequisites(ctx.session, ctx.setFrameworkContext),\n },\n {\n id: 'intro',\n label: 'Welcome',\n screen: 'revenue-intro',\n gate: (session) => session.setupConfirmed,\n },\n {\n id: 'auth',\n label: 'Authentication',\n screen: 'auth',\n isComplete: (session) => session.credentials !== null,\n },\n {\n id: 'run',\n label: 'Revenue analytics',\n screen: 'run',\n isComplete: (session) =>\n session.runPhase === RunPhase.Completed ||\n session.runPhase === RunPhase.Error,\n },\n {\n id: 'outro',\n label: 'Done',\n screen: 'outro',\n isComplete: (session) => session.outroDismissed,\n },\n {\n id: 'skills',\n label: 'Skills',\n screen: 'keep-skills',\n },\n];\n","import type { WorkflowConfig } from '../workflow-step.js';\nimport { REVENUE_ANALYTICS_WORKFLOW } from './steps.js';\nimport { REVENUE_ABORT_CASES } from './detect.js';\n\nexport const revenueAnalyticsConfig: WorkflowConfig = {\n command: 'revenue',\n description: 'Set up PostHog revenue analytics (e.g. Stripe integration)',\n flowKey: 'revenue-analytics-setup',\n steps: REVENUE_ANALYTICS_WORKFLOW,\n run: {\n skillId: 'revenue-analytics-setup',\n integrationLabel: 'revenue-analytics-setup',\n customPrompt: () => 'Set up revenue analytics for this project.',\n successMessage: 'Revenue analytics configured!',\n reportFile: 'posthog-revenue-report.md',\n docsUrl: 'https://posthog.com/docs/revenue-analytics',\n spinnerMessage: 'Setting up revenue analytics...',\n estimatedDurationMinutes: 5,\n abortCases: REVENUE_ABORT_CASES,\n },\n requires: ['posthog-integration'],\n};\n\nexport { REVENUE_ANALYTICS_WORKFLOW } from './steps.js';\nexport {\n detectRevenuePrerequisites,\n POSTHOG_SDKS,\n STRIPE_SDKS,\n type RevenueDetectError,\n} from './detect.js';\n","/**\n * Central registry of all wizard workflows.\n *\n * Adding a new workflow:\n * 1. Create src/lib/workflows/<name>/ with index.ts exporting a WorkflowConfig\n * 2. Import and add it to WORKFLOW_REGISTRY below\n * 3. Add a matching Flow enum entry in src/ui/tui/flows.ts\n * 4. (If custom intro screen) add to src/ui/tui/screen-registry.tsx\n *\n * flows.ts, store.ts, and bin.ts all derive their wiring from this array —\n * no need to touch those files when adding a workflow.\n */\n\nimport type { WorkflowConfig } from './workflow-step.js';\nimport { posthogIntegrationConfig } from './posthog-integration/index.js';\nimport { revenueAnalyticsConfig } from './revenue-analytics/index.js';\n\nexport const WORKFLOW_REGISTRY: WorkflowConfig[] = [\n posthogIntegrationConfig,\n revenueAnalyticsConfig,\n];\n\n/** Look up a workflow config by its flowKey. */\nexport function getWorkflowConfig(flowKey: string): WorkflowConfig | undefined {\n return WORKFLOW_REGISTRY.find((c) => c.flowKey === flowKey);\n}\n\n/** All workflow configs that are exposed as CLI subcommands. */\nexport function getSubcommandWorkflows(): WorkflowConfig[] {\n return WORKFLOW_REGISTRY.filter((c) => c.command != null);\n}\n","#!/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 { isNonInteractiveEnvironment } from './src/utils/environment';\nimport { getUI, setUI } from './src/ui';\nimport { LoggingUI } from './src/ui/logging-ui';\nimport { getSubcommandWorkflows } from './src/lib/workflows/workflow-registry';\nimport type { WorkflowConfig } from './src/lib/workflows/workflow-step';\nimport type { WizardSession } from './src/lib/wizard-session';\nimport { runtimeEnv } from '@env';\n\n// Test mock server — only loaded when NODE_ENV is 'test'.\n// In production builds, tsdown replaces process.env.NODE_ENV with 'production',\n// making this block dead code.\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\n/** Shared yargs options for skill-based workflow subcommands. */\nconst skillSubcommandOptions = {\n debug: {\n default: false,\n describe: 'Enable verbose logging',\n type: 'boolean' as const,\n },\n 'install-dir': {\n describe: 'Directory to install in',\n type: 'string' as const,\n },\n 'local-mcp': {\n default: false,\n describe: 'Use local MCP server',\n type: 'boolean' as const,\n },\n benchmark: {\n default: false,\n describe: 'Run in benchmark mode',\n type: 'boolean' as const,\n },\n 'yara-report': {\n default: false,\n describe: 'Print YARA scanner summary',\n type: 'boolean' as const,\n hidden: true,\n },\n};\n\nconst cli = yargs(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 email: {\n describe:\n 'Email address for signup (used with --signup)\\nenv: POSTHOG_WIZARD_EMAIL',\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 skill: {\n describe:\n 'Run a specific context-mill skill by ID\\nenv: POSTHOG_WIZARD_SKILL',\n type: 'string',\n },\n });\n },\n (argv) => {\n const options = { ...argv };\n\n // CI mode validation and TTY check\n if (options.ci) {\n if (!options.region) options.region = 'us';\n if (!options.apiKey) {\n setUI(new LoggingUI());\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 return;\n }\n if (!options.installDir) {\n setUI(new LoggingUI());\n getUI().intro('PostHog Wizard');\n getUI().log.error(\n 'CI mode requires --install-dir (directory to install in)',\n );\n process.exit(1);\n return;\n }\n void (async () => {\n const { posthogIntegrationConfig } = await import(\n './src/lib/workflows/posthog-integration/index.js'\n );\n const { FRAMEWORK_REGISTRY } = await import('./src/lib/registry.js');\n const { detectFramework, gatherFrameworkContext } = await import(\n './src/lib/detection/index.js'\n );\n const { analytics } = await import('./src/utils/analytics.js');\n const { wizardAbort } = await import('./src/utils/wizard-abort.js');\n\n // preRun: honor --integration, else auto-detect, then gather\n // framework context. Bypasses onReady hooks by design.\n runWizardCI(posthogIntegrationConfig, options, async (session) => {\n const integration =\n session.integration ??\n (await detectFramework(session.installDir));\n if (!integration) {\n await wizardAbort({\n message:\n 'Could not auto-detect your framework. Please specify --integration on the command line.',\n });\n return;\n }\n session.integration = integration;\n analytics.setTag('integration', integration);\n\n const frameworkConfig = FRAMEWORK_REGISTRY[integration];\n session.frameworkConfig = frameworkConfig;\n\n const context = await gatherFrameworkContext(frameworkConfig, {\n installDir: session.installDir,\n debug: session.debug,\n forceInstall: session.forceInstall,\n default: false,\n signup: session.signup,\n localMcp: session.localMcp,\n ci: true,\n menu: session.menu,\n benchmark: session.benchmark,\n yaraReport: session.yaraReport,\n });\n for (const [key, value] of Object.entries(context)) {\n if (!(key in session.frameworkContext)) {\n session.frameworkContext[key] = value;\n }\n }\n });\n })().catch(() => {\n process.exit(1);\n });\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 if (options.skill) {\n // Run a specific skill by ID\n void (async () => {\n const { createSkillWorkflow } = await import(\n './src/lib/workflows/agent-skill/index.js'\n );\n const skillId = options.skill as string;\n const config = createSkillWorkflow({\n skillId,\n command: 'skill',\n flowKey: 'agent-skill',\n description: `Run skill: ${skillId}`,\n integrationLabel: skillId,\n successMessage: `${skillId} completed!`,\n reportFile: `posthog-${skillId}-report.md`,\n docsUrl: 'https://posthog.com/docs',\n spinnerMessage: `Running ${skillId}...`,\n estimatedDurationMinutes: 5,\n });\n runWizard(config, options);\n })();\n } else {\n // Interactive TTY: run core-integration through the unified workflow path.\n // Same codepath as `npx @posthog/wizard integrate`.\n void (async () => {\n const { posthogIntegrationConfig } = await import(\n './src/lib/workflows/posthog-integration/index.js'\n );\n runWizard(posthogIntegrationConfig, options);\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 'api-key': {\n describe:\n 'PostHog personal API key (phx_xxx) for MCP authentication',\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 const { readApiKeyFromEnv } = await import(\n './src/utils/env-api-key.js'\n );\n const apiKey =\n (options.apiKey as string | undefined) || readApiKeyFromEnv();\n\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 apiKey,\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 apiKey,\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\n// ── Skill-based workflow subcommands (derived from registry) ─────────\nfor (const wfConfig of getSubcommandWorkflows()) {\n cli.command(\n wfConfig.command!,\n wfConfig.description,\n (y) => y.options(skillSubcommandOptions),\n (argv) => {\n const options = { ...argv };\n if (options.ci) {\n runWizardCI(wfConfig, options);\n } else {\n runWizard(wfConfig, options);\n }\n },\n );\n}\n\ncli\n .help()\n .alias('help', 'h')\n .version()\n .alias('version', 'v')\n .wrap(process.stdout.isTTY ? cli.terminalWidth() : 80).argv;\n\n/**\n * Run a full wizard workflow in the TUI. Handles the full lifecycle: start TUI,\n * build session, run detection, wait for intro gate, execute the\n * agent pipeline, wait for outro dismissal, then exit.\n */\nfunction runWizard(\n config: WorkflowConfig,\n options: Record<string, unknown>,\n): void {\n void (async () => {\n try {\n const installDir = (options.installDir as string) || process.cwd();\n\n const { startTUI } = await import('./src/ui/tui/start-tui.js');\n const { buildSession } = await import('./src/lib/wizard-session.js');\n\n // flowKey values match Flow enum values by convention\n const tui = startTUI(WIZARD_VERSION, config.flowKey as any);\n\n const session = buildSession({\n debug: options.debug as boolean | undefined,\n forceInstall: options.forceInstall as boolean | undefined,\n localMcp: options.localMcp as boolean | undefined,\n installDir,\n ci: false,\n signup: options.signup as boolean | undefined,\n apiKey: options.apiKey as string | undefined,\n projectId: options.projectId as string | undefined,\n menu: options.menu as boolean | undefined,\n integration: options.integration as any,\n benchmark: options.benchmark as boolean | undefined,\n yaraReport: options.yaraReport as boolean | undefined,\n });\n // Set workflow metadata for TUI display\n session.workflowLabel = config.flowKey;\n const runDef = typeof config.run === 'object' ? config.run : null;\n session.skillId = runDef?.skillId ?? null;\n\n tui.store.session = session;\n\n await tui.store.runReadyHooks();\n await tui.store.getGate('intro');\n\n const { runAgent } = await import('./src/lib/agent/agent-runner.js');\n await runAgent(config, tui.store.session);\n\n await new Promise<void>((resolve) => {\n const unsub = tui.store.subscribe(() => {\n if (tui.store.session.skillsComplete) {\n unsub();\n resolve();\n }\n });\n if (tui.store.session.skillsComplete) {\n unsub();\n resolve();\n }\n });\n process.exit(0);\n } catch (err) {\n if (runtimeEnv('DEBUG') || runtimeEnv('POSTHOG_WIZARD_DEBUG')) {\n console.error('TUI init failed:', err); // eslint-disable-line no-console\n }\n }\n })();\n}\n\n/**\n * CI-mode pipeline shared by every non-interactive entry point.\n *\n * Validates flags, builds a `ci:true` session, runs `preRun` (or the\n * workflow's `onReady` hooks by default), executes `runAgent`, and\n * routes any failure through `wizardAbort`. `wizardAbort` owns all\n * exits — never add a raw `process.exit` here.\n */\nfunction runWizardCI(\n config: WorkflowConfig,\n options: Record<string, unknown>,\n preRun?: (session: WizardSession) => Promise<void>,\n): void {\n setUI(new LoggingUI());\n if (!options.region) options.region = 'us';\n if (!options.apiKey) {\n getUI().intro('PostHog Wizard');\n getUI().log.error('CI mode requires --api-key (personal API key phx_xxx)');\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 in)',\n );\n process.exit(1);\n }\n\n void (async () => {\n const path = await import('path');\n const { buildSession } = await import('./src/lib/wizard-session.js');\n const { readEnvironment } = await import('./src/utils/environment.js');\n const { readApiKeyFromEnv } = await import('./src/utils/env-api-key.js');\n const { configureLogFileFromEnvironment, logToFile } = await import(\n './src/utils/debug.js'\n );\n const { wizardAbort, WizardError } = await import(\n './src/utils/wizard-abort.js'\n );\n\n configureLogFileFromEnvironment();\n\n const env = readEnvironment();\n const apiKey =\n (options.apiKey as string) ?? readApiKeyFromEnv() ?? undefined;\n const installDir = path.isAbsolute(options.installDir as string)\n ? (options.installDir as string)\n : path.join(process.cwd(), options.installDir as string);\n\n const session = buildSession({\n debug: options.debug as boolean | undefined,\n forceInstall: options.forceInstall as boolean | undefined,\n installDir,\n ci: true,\n signup: options.signup as boolean | undefined,\n localMcp: options.localMcp as boolean | undefined,\n apiKey,\n menu: options.menu as boolean | undefined,\n integration: options.integration as any, // eslint-disable-line @typescript-eslint/no-explicit-any\n projectId: options.projectId as string | undefined,\n benchmark: options.benchmark as boolean | undefined,\n yaraReport: options.yaraReport as boolean | undefined,\n ...env,\n });\n session.workflowLabel = config.flowKey;\n const runDef = typeof config.run === 'object' ? config.run : null;\n session.skillId = runDef?.skillId ?? null;\n\n getUI().intro('Welcome to the PostHog setup wizard');\n getUI().log.info(`Running ${config.flowKey} in CI mode`);\n\n try {\n if (preRun) {\n await preRun(session);\n } else {\n // Run onReady hooks against a minimal store-less context.\n const readyCtx = {\n session,\n setFrameworkContext: (key: string, value: unknown) => {\n session.frameworkContext[key] = value;\n },\n setFrameworkConfig: () => undefined,\n setDetectedFramework: () => undefined,\n setUnsupportedVersion: () => undefined,\n addDiscoveredFeature: () => undefined,\n setDetectionComplete: () => undefined,\n };\n for (const step of config.steps) {\n if (step.onReady) {\n await step.onReady(readyCtx);\n }\n }\n\n // Surface detectError written by the workflow's detect hook.\n const detectError = session.frameworkContext.detectError as\n | { kind: string; [k: string]: unknown }\n | undefined;\n if (detectError) {\n await wizardAbort({\n message: `Prerequisites not met: ${detectError.kind}\\n\\nSee ${\n runDef?.docsUrl ?? 'https://posthog.com/docs'\n }`,\n error: new WizardError(`${config.flowKey} prerequisites failed`, {\n integration: config.flowKey,\n detect_error_kind: detectError.kind,\n }),\n });\n }\n }\n\n const { runAgent } = await import('./src/lib/agent/agent-runner.js');\n await runAgent(config, session);\n } catch (error) {\n const errorMessage =\n error instanceof Error ? error.message : String(error);\n const errorStack =\n error instanceof Error && error.stack ? error.stack : undefined;\n\n logToFile(`[bin.ts CI] ERROR: ${errorMessage}`);\n if (errorStack) logToFile(`[bin.ts CI] STACK: ${errorStack}`);\n\n const debugInfo = session.debug && errorStack ? `\\n\\n${errorStack}` : '';\n const docsUrl =\n session.frameworkConfig?.metadata.docsUrl ??\n runDef?.docsUrl ??\n 'https://posthog.com/docs';\n await wizardAbort({\n message: `Something went wrong: ${errorMessage}\\n\\nYou can read the documentation at ${docsUrl} to set up manually.${debugInfo}`,\n error: error as Error,\n });\n }\n })().catch(() => {\n process.exit(1);\n });\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"bin.js","names":[],"sources":["../src/utils/environment.ts","../src/lib/workflows/revenue-analytics/detect.ts","../src/lib/workflows/revenue-analytics/steps.ts","../src/lib/workflows/revenue-analytics/index.ts","../src/lib/workflows/workflow-registry.ts","../bin.ts"],"sourcesContent":["import readEnvModule from 'read-env';\n\nconst readEnv =\n typeof readEnvModule === 'function'\n ? readEnvModule\n : (readEnvModule as any).default;\nimport { tryGetPackageJson } from './setup-utils';\nimport type { WizardOptions } from './types';\nimport fg from 'fast-glob';\nimport { IS_DEV } from '../lib/constants';\n\nexport function isNonInteractiveEnvironment(): boolean {\n if (IS_DEV) {\n return false;\n }\n\n if (!process.stdout.isTTY || !process.stderr.isTTY) {\n return true;\n }\n\n return false;\n}\n\nexport function readEnvironment(): Record<string, unknown> {\n const result = readEnv('POSTHOG_WIZARD');\n\n return result;\n}\n\nexport async function detectEnvVarPrefix(\n options: WizardOptions,\n): Promise<string> {\n const packageJson = await tryGetPackageJson(options);\n if (!packageJson) return 'VITE_PUBLIC_';\n\n const deps = { ...packageJson.dependencies, ...packageJson.devDependencies };\n const has = (name: string) => name in deps;\n const hasAnyFile = async (patterns: string[]) => {\n const matches = await fg(patterns, {\n cwd: options.installDir,\n absolute: false,\n onlyFiles: true,\n ignore: ['**/node_modules/**'],\n });\n return matches.length > 0;\n };\n\n // --- Next.js\n if (has('next') || (await hasAnyFile(['**/next.config.{js,ts,mjs,cjs}']))) {\n return 'NEXT_PUBLIC_';\n }\n\n // --- Create React App\n if (\n has('react-scripts') ||\n has('create-react-app') ||\n (await hasAnyFile(['**/config-overrides.js']))\n ) {\n return 'REACT_APP_';\n }\n\n // --- Vite (vanilla, TanStack, Solid, etc.)\n // Note: Vite does not need PUBLIC_ but we use it to follow the docs, to improve the chances of an LLM getting it right.\n if (has('vite') || (await hasAnyFile(['**/vite.config.{js,ts,mjs,cjs}']))) {\n return 'VITE_PUBLIC_';\n }\n\n // --- SvelteKit\n if (\n has('@sveltejs/kit') ||\n (await hasAnyFile(['**/svelte.config.{js,ts}']))\n ) {\n return 'PUBLIC_';\n }\n\n // --- TanStack Start (uses Vite)\n if (\n has('@tanstack/start') ||\n (await hasAnyFile(['**/tanstack.config.{js,ts}']))\n ) {\n return 'VITE_PUBLIC_';\n }\n\n // --- SolidStart (uses Vite)\n if (has('solid-start') || (await hasAnyFile(['**/solid.config.{js,ts}']))) {\n return 'VITE_PUBLIC_';\n }\n\n // --- Astro\n if (has('astro') || (await hasAnyFile(['**/astro.config.{js,ts,mjs}']))) {\n return 'PUBLIC_';\n }\n\n // We default to Vite if we can't detect a specific framework, since it's the most commonly used.\n return 'VITE_PUBLIC_';\n}\n","/**\n * Revenue analytics prerequisite detection.\n *\n * Scans the project for PostHog + Stripe SDKs and writes results\n * into frameworkContext for the intro screen to render.\n */\n\nimport type { Dirent } from 'fs';\nimport { readFileSync, readdirSync, existsSync, statSync } from 'fs';\nimport { join, relative } from 'path';\nimport { IGNORED_DIRS } from '../../../utils/file-utils.js';\nimport type { WizardSession } from '../../wizard-session.js';\nimport type { AbortCase } from '../../agent/agent-runner.js';\n\nexport const POSTHOG_SDKS = [\n 'posthog-js',\n 'posthog-node',\n 'posthog-react-native',\n 'posthog-android',\n 'posthog-ios',\n];\n\nexport const STRIPE_SDKS = [\n 'stripe',\n '@stripe/stripe-js',\n '@stripe/react-stripe-js',\n];\n\ninterface PackageMatch {\n /** Path to the package.json relative to installDir */\n path: string;\n posthogSdks: string[];\n stripeSdks: string[];\n}\n\n/**\n * Structured detection errors. The screen renders each kind into JSX\n * with proper formatting — keeps error data separate from presentation.\n */\nexport type RevenueDetectError =\n | {\n kind: 'bad-directory';\n path: string;\n reason: 'missing' | 'not-dir' | 'unreadable';\n }\n | { kind: 'no-package-json' }\n | { kind: 'no-sdks'; scannedCount: number }\n | { kind: 'missing-posthog'; foundStripe: string[] }\n | { kind: 'missing-stripe'; foundPosthog: string[] };\n\n/** `[ABORT] <reason>` cases the revenue analytics skill can emit. */\nexport const REVENUE_ABORT_CASES: AbortCase[] = [\n {\n // Skill emits: [ABORT] Could not find a PostHog distinct_id\n match: /^could not find a posthog distinct_id$/i,\n message: 'Could not find a PostHog distinct_id',\n body:\n 'The agent could not find PostHog distinct_id usage in your codebase. ' +\n 'Your users must be identified in PostHog before they can be tagged in Stripe. ' +\n 'Please identify your users and try again.',\n docsUrl: 'https://posthog.com/docs/product-analytics/identify',\n },\n {\n // Skill emits: [ABORT] Could not find a Stripe integration\n match: /^could not find a stripe integration$/i,\n message: 'Could not find a Stripe integration',\n body:\n 'The Wizard could not find an existing Stripe customer, charge, ' +\n 'subscription, or other Stripe operations. Please run the Revenue ' +\n 'Analytics Wizard on a project with an existing Stripe integration.',\n docsUrl: 'https://posthog.com/docs/revenue-analytics',\n },\n];\n\n/**\n * Recursively find all package.json files under installDir (max depth 3),\n * skipping common ignored directories. Returns matches with detected SDKs.\n */\nfunction findPackageJsons(installDir: string, maxDepth = 3): PackageMatch[] {\n const matches: PackageMatch[] = [];\n\n function scan(dir: string, depth: number): void {\n if (depth > maxDepth) return;\n\n let entries: Dirent[];\n try {\n entries = readdirSync(dir, { withFileTypes: true });\n } catch {\n return;\n }\n\n for (const entry of entries) {\n if (entry.name.startsWith('.') && entry.name !== '.') continue;\n if (IGNORED_DIRS.has(entry.name)) continue;\n\n const fullPath = join(dir, entry.name);\n\n if (entry.isFile() && entry.name === 'package.json') {\n try {\n const pkg = JSON.parse(readFileSync(fullPath, 'utf-8')) as {\n dependencies?: Record<string, string>;\n devDependencies?: Record<string, string>;\n };\n const depNames = [\n ...Object.keys(pkg.dependencies ?? {}),\n ...Object.keys(pkg.devDependencies ?? {}),\n ];\n const posthogSdks = depNames.filter((d) => POSTHOG_SDKS.includes(d));\n const stripeSdks = depNames.filter((d) => STRIPE_SDKS.includes(d));\n matches.push({\n path: relative(installDir, fullPath) || 'package.json',\n posthogSdks,\n stripeSdks,\n });\n } catch {\n // Skip malformed package.json\n }\n } else if (entry.isDirectory()) {\n scan(fullPath, depth + 1);\n }\n }\n }\n\n scan(installDir, 0);\n return matches;\n}\n\n/**\n * Scan `session.installDir` for PostHog + Stripe SDKs. Writes detection\n * results into frameworkContext via the callback — either the detected\n * SDK lists (for the intro screen) or a `RevenueDetectError` on failure.\n *\n * The skill install happens later in the bootstrap runner, not here.\n */\nexport function detectRevenuePrerequisites(\n session: WizardSession,\n setFrameworkContext: (key: string, value: unknown) => void,\n): void {\n const fail = (error: RevenueDetectError) =>\n setFrameworkContext('detectError', error);\n\n const installDir = session.installDir;\n\n // Verify the install directory exists and is readable\n if (!existsSync(installDir)) {\n fail({ kind: 'bad-directory', path: installDir, reason: 'missing' });\n return;\n }\n try {\n if (!statSync(installDir).isDirectory()) {\n fail({ kind: 'bad-directory', path: installDir, reason: 'not-dir' });\n return;\n }\n } catch {\n fail({ kind: 'bad-directory', path: installDir, reason: 'unreadable' });\n return;\n }\n\n // Find all package.json files (root + monorepo subpackages)\n const matches = findPackageJsons(installDir);\n\n if (matches.length === 0) {\n fail({ kind: 'no-package-json' });\n return;\n }\n\n // Aggregate detected SDKs across all package.json files\n const allPosthogSdks = new Set<string>();\n const allStripeSdks = new Set<string>();\n for (const match of matches) {\n for (const sdk of match.posthogSdks) allPosthogSdks.add(sdk);\n for (const sdk of match.stripeSdks) allStripeSdks.add(sdk);\n }\n\n const detectedPosthogSdks = [...allPosthogSdks];\n const detectedStripeSdks = [...allStripeSdks];\n\n if (detectedPosthogSdks.length === 0 && detectedStripeSdks.length === 0) {\n fail({ kind: 'no-sdks', scannedCount: matches.length });\n return;\n }\n\n if (detectedPosthogSdks.length === 0) {\n fail({ kind: 'missing-posthog', foundStripe: detectedStripeSdks });\n return;\n }\n\n if (detectedStripeSdks.length === 0) {\n fail({ kind: 'missing-stripe', foundPosthog: detectedPosthogSdks });\n return;\n }\n\n setFrameworkContext('detectedPosthogSdks', detectedPosthogSdks);\n setFrameworkContext('detectedStripeSdks', detectedStripeSdks);\n setFrameworkContext(\n 'detectedPackagePaths',\n matches\n .filter((m) => m.posthogSdks.length > 0 || m.stripeSdks.length > 0)\n .map((m) => m.path),\n );\n}\n","/**\n * Revenue analytics workflow step list.\n *\n * The detect step checks for PostHog + Stripe SDKs. The skill install\n * and agent run live in the workflow runner (see agent-runner.ts).\n */\n\nimport type { Workflow } from '../workflow-step.js';\nimport { RunPhase } from '../../wizard-session.js';\nimport { detectRevenuePrerequisites } from './detect.js';\n\nexport const REVENUE_ANALYTICS_WORKFLOW: Workflow = [\n {\n id: 'detect',\n label: 'Detecting prerequisites',\n // Headless step: no screen, no gate. onReady fires after bin.ts\n // assigns the session — the hook scans for PostHog + Stripe SDKs\n // and writes the results (or a detectError) to frameworkContext\n // for the intro screen to render.\n onReady: (ctx) =>\n detectRevenuePrerequisites(ctx.session, ctx.setFrameworkContext),\n },\n {\n id: 'intro',\n label: 'Welcome',\n screen: 'revenue-intro',\n gate: (session) => session.setupConfirmed,\n },\n {\n id: 'auth',\n label: 'Authentication',\n screen: 'auth',\n isComplete: (session) => session.credentials !== null,\n },\n {\n id: 'run',\n label: 'Revenue analytics',\n screen: 'run',\n isComplete: (session) =>\n session.runPhase === RunPhase.Completed ||\n session.runPhase === RunPhase.Error,\n },\n {\n id: 'outro',\n label: 'Done',\n screen: 'outro',\n isComplete: (session) => session.outroDismissed,\n },\n {\n id: 'skills',\n label: 'Skills',\n screen: 'keep-skills',\n },\n];\n","import type { WorkflowConfig } from '../workflow-step.js';\nimport { REVENUE_ANALYTICS_WORKFLOW } from './steps.js';\nimport { REVENUE_ABORT_CASES } from './detect.js';\n\nexport const revenueAnalyticsConfig: WorkflowConfig = {\n command: 'revenue',\n description: 'Set up PostHog revenue analytics (e.g. Stripe integration)',\n flowKey: 'revenue-analytics-setup',\n steps: REVENUE_ANALYTICS_WORKFLOW,\n run: {\n skillId: 'revenue-analytics-setup',\n integrationLabel: 'revenue-analytics-setup',\n customPrompt: () => 'Set up revenue analytics for this project.',\n successMessage: 'Revenue analytics configured!',\n reportFile: 'posthog-revenue-report.md',\n docsUrl: 'https://posthog.com/docs/revenue-analytics',\n spinnerMessage: 'Setting up revenue analytics...',\n estimatedDurationMinutes: 5,\n abortCases: REVENUE_ABORT_CASES,\n },\n requires: ['posthog-integration'],\n};\n\nexport { REVENUE_ANALYTICS_WORKFLOW } from './steps.js';\nexport {\n detectRevenuePrerequisites,\n POSTHOG_SDKS,\n STRIPE_SDKS,\n type RevenueDetectError,\n} from './detect.js';\n","/**\n * Central registry of all wizard workflows.\n *\n * Adding a new workflow:\n * 1. Create src/lib/workflows/<name>/ with index.ts exporting a WorkflowConfig\n * 2. Import and add it to WORKFLOW_REGISTRY below\n * 3. Add a matching Flow enum entry in src/ui/tui/flows.ts\n * 4. (If custom intro screen) add to src/ui/tui/screen-registry.tsx\n *\n * flows.ts, store.ts, and bin.ts all derive their wiring from this array —\n * no need to touch those files when adding a workflow.\n */\n\nimport type { WorkflowConfig } from './workflow-step.js';\nimport { posthogIntegrationConfig } from './posthog-integration/index.js';\nimport { revenueAnalyticsConfig } from './revenue-analytics/index.js';\n\nexport const WORKFLOW_REGISTRY: WorkflowConfig[] = [\n posthogIntegrationConfig,\n revenueAnalyticsConfig,\n];\n\n/** Look up a workflow config by its flowKey. */\nexport function getWorkflowConfig(flowKey: string): WorkflowConfig | undefined {\n return WORKFLOW_REGISTRY.find((c) => c.flowKey === flowKey);\n}\n\n/** All workflow configs that are exposed as CLI subcommands. */\nexport function getSubcommandWorkflows(): WorkflowConfig[] {\n return WORKFLOW_REGISTRY.filter((c) => c.command != null);\n}\n","#!/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 { isNonInteractiveEnvironment } from './src/utils/environment';\nimport { getUI, setUI } from './src/ui';\nimport { LoggingUI } from './src/ui/logging-ui';\nimport { getSubcommandWorkflows } from './src/lib/workflows/workflow-registry';\nimport type { WorkflowConfig } from './src/lib/workflows/workflow-step';\nimport type { WizardSession } from './src/lib/wizard-session';\nimport { runtimeEnv } from '@env';\n\n// Test mock server — only loaded when NODE_ENV is 'test'.\n// In production builds, tsdown replaces process.env.NODE_ENV with 'production',\n// making this block dead code.\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\n/** Shared yargs options for skill-based workflow subcommands. */\nconst skillSubcommandOptions = {\n debug: {\n default: false,\n describe: 'Enable verbose logging',\n type: 'boolean' as const,\n },\n 'install-dir': {\n describe: 'Directory to install in',\n type: 'string' as const,\n },\n 'local-mcp': {\n default: false,\n describe: 'Use local MCP server',\n type: 'boolean' as const,\n },\n benchmark: {\n default: false,\n describe: 'Run in benchmark mode',\n type: 'boolean' as const,\n },\n 'yara-report': {\n default: false,\n describe: 'Print YARA scanner summary',\n type: 'boolean' as const,\n hidden: true,\n },\n};\n\nconst cli = yargs(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 email: {\n describe:\n 'Email address for signup (used with --signup)\\nenv: POSTHOG_WIZARD_EMAIL',\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 skill: {\n describe:\n 'Run a specific context-mill skill by ID\\nenv: POSTHOG_WIZARD_SKILL',\n type: 'string',\n },\n });\n },\n (argv) => {\n const options = { ...argv };\n\n // CI mode validation and TTY check\n if (options.ci) {\n if (!options.region) options.region = 'us';\n if (!options.apiKey) {\n setUI(new LoggingUI());\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 return;\n }\n if (!options.installDir) {\n setUI(new LoggingUI());\n getUI().intro('PostHog Wizard');\n getUI().log.error(\n 'CI mode requires --install-dir (directory to install in)',\n );\n process.exit(1);\n return;\n }\n void (async () => {\n const { posthogIntegrationConfig } = await import(\n './src/lib/workflows/posthog-integration/index.js'\n );\n const { FRAMEWORK_REGISTRY } = await import('./src/lib/registry.js');\n const { detectFramework, gatherFrameworkContext } = await import(\n './src/lib/detection/index.js'\n );\n const { analytics } = await import('./src/utils/analytics.js');\n const { wizardAbort } = await import('./src/utils/wizard-abort.js');\n\n // preRun: honor --integration, else auto-detect, then gather\n // framework context. Bypasses onReady hooks by design.\n runWizardCI(posthogIntegrationConfig, options, async (session) => {\n const integration =\n session.integration ??\n (await detectFramework(session.installDir));\n if (!integration) {\n await wizardAbort({\n message:\n 'Could not auto-detect your framework. Please specify --integration on the command line.',\n });\n return;\n }\n session.integration = integration;\n analytics.setTag('integration', integration);\n\n const frameworkConfig = FRAMEWORK_REGISTRY[integration];\n session.frameworkConfig = frameworkConfig;\n\n const context = await gatherFrameworkContext(frameworkConfig, {\n installDir: session.installDir,\n debug: session.debug,\n forceInstall: session.forceInstall,\n default: false,\n signup: session.signup,\n localMcp: session.localMcp,\n ci: true,\n menu: session.menu,\n benchmark: session.benchmark,\n yaraReport: session.yaraReport,\n });\n for (const [key, value] of Object.entries(context)) {\n if (!(key in session.frameworkContext)) {\n session.frameworkContext[key] = value;\n }\n }\n });\n })().catch(() => {\n process.exit(1);\n });\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 if (options.skill) {\n // Run a specific skill by ID\n void (async () => {\n const { createSkillWorkflow } = await import(\n './src/lib/workflows/agent-skill/index.js'\n );\n const skillId = options.skill as string;\n const config = createSkillWorkflow({\n skillId,\n command: 'skill',\n flowKey: 'agent-skill',\n description: `Run skill: ${skillId}`,\n integrationLabel: skillId,\n successMessage: `${skillId} completed!`,\n reportFile: `posthog-${skillId}-report.md`,\n docsUrl: 'https://posthog.com/docs',\n spinnerMessage: `Running ${skillId}...`,\n estimatedDurationMinutes: 5,\n });\n runWizard(config, options);\n })();\n } else {\n // Interactive TTY: run core-integration through the unified workflow path.\n // Same codepath as `npx @posthog/wizard integrate`.\n void (async () => {\n const { posthogIntegrationConfig } = await import(\n './src/lib/workflows/posthog-integration/index.js'\n );\n runWizard(posthogIntegrationConfig, options);\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 'api-key': {\n describe:\n 'PostHog personal API key (phx_xxx) for MCP authentication',\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 const { readApiKeyFromEnv } = await import(\n './src/utils/env-api-key.js'\n );\n const apiKey =\n (options.apiKey as string | undefined) || readApiKeyFromEnv();\n\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 apiKey,\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 apiKey,\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\n// ── Skill-based workflow subcommands (derived from registry) ─────────\nfor (const wfConfig of getSubcommandWorkflows()) {\n cli.command(\n wfConfig.command!,\n wfConfig.description,\n (y) => y.options(skillSubcommandOptions),\n (argv) => {\n const options = { ...argv };\n if (options.ci) {\n runWizardCI(wfConfig, options);\n } else {\n runWizard(wfConfig, options);\n }\n },\n );\n}\n\ncli\n .help()\n .alias('help', 'h')\n .version()\n .alias('version', 'v')\n .wrap(process.stdout.isTTY ? cli.terminalWidth() : 80).argv;\n\n/**\n * Run a full wizard workflow in the TUI. Handles the full lifecycle: start TUI,\n * build session, run detection, wait for intro gate, execute the\n * agent pipeline, wait for outro dismissal, then exit.\n */\nfunction runWizard(\n config: WorkflowConfig,\n options: Record<string, unknown>,\n): void {\n void (async () => {\n try {\n const installDir = (options.installDir as string) || process.cwd();\n\n const { startTUI } = await import('./src/ui/tui/start-tui.js');\n const { buildSession } = await import('./src/lib/wizard-session.js');\n\n // flowKey values match Flow enum values by convention\n const tui = startTUI(WIZARD_VERSION, config.flowKey as any);\n\n const session = buildSession({\n debug: options.debug as boolean | undefined,\n forceInstall: options.forceInstall as boolean | undefined,\n localMcp: options.localMcp as boolean | undefined,\n installDir,\n ci: false,\n signup: options.signup as boolean | undefined,\n apiKey: options.apiKey as string | undefined,\n projectId: options.projectId as string | undefined,\n email: options.email as string | undefined,\n menu: options.menu as boolean | undefined,\n integration: options.integration as any,\n benchmark: options.benchmark as boolean | undefined,\n yaraReport: options.yaraReport as boolean | undefined,\n });\n // Set workflow metadata for TUI display\n session.workflowLabel = config.flowKey;\n const runDef = typeof config.run === 'object' ? config.run : null;\n session.skillId = runDef?.skillId ?? null;\n\n tui.store.session = session;\n\n await tui.store.runReadyHooks();\n await tui.store.getGate('intro');\n\n const { runAgent } = await import('./src/lib/agent/agent-runner.js');\n await runAgent(config, tui.store.session);\n\n await new Promise<void>((resolve) => {\n const unsub = tui.store.subscribe(() => {\n if (tui.store.session.skillsComplete) {\n unsub();\n resolve();\n }\n });\n if (tui.store.session.skillsComplete) {\n unsub();\n resolve();\n }\n });\n process.exit(0);\n } catch (err) {\n if (runtimeEnv('DEBUG') || runtimeEnv('POSTHOG_WIZARD_DEBUG')) {\n console.error('TUI init failed:', err); // eslint-disable-line no-console\n }\n }\n })();\n}\n\n/**\n * CI-mode pipeline shared by every non-interactive entry point.\n *\n * Validates flags, builds a `ci:true` session, runs `preRun` (or the\n * workflow's `onReady` hooks by default), executes `runAgent`, and\n * routes any failure through `wizardAbort`. `wizardAbort` owns all\n * exits — never add a raw `process.exit` here.\n */\nfunction runWizardCI(\n config: WorkflowConfig,\n options: Record<string, unknown>,\n preRun?: (session: WizardSession) => Promise<void>,\n): void {\n setUI(new LoggingUI());\n if (!options.region) options.region = 'us';\n if (!options.apiKey) {\n getUI().intro('PostHog Wizard');\n getUI().log.error('CI mode requires --api-key (personal API key phx_xxx)');\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 in)',\n );\n process.exit(1);\n }\n\n void (async () => {\n const path = await import('path');\n const { buildSession } = await import('./src/lib/wizard-session.js');\n const { readEnvironment } = await import('./src/utils/environment.js');\n const { readApiKeyFromEnv } = await import('./src/utils/env-api-key.js');\n const { configureLogFileFromEnvironment, logToFile } = await import(\n './src/utils/debug.js'\n );\n const { wizardAbort, WizardError } = await import(\n './src/utils/wizard-abort.js'\n );\n\n configureLogFileFromEnvironment();\n\n const env = readEnvironment();\n const apiKey =\n (options.apiKey as string) ?? readApiKeyFromEnv() ?? undefined;\n const installDir = path.isAbsolute(options.installDir as string)\n ? (options.installDir as string)\n : path.join(process.cwd(), options.installDir as string);\n\n const session = buildSession({\n debug: options.debug as boolean | undefined,\n forceInstall: options.forceInstall as boolean | undefined,\n installDir,\n ci: true,\n signup: options.signup as boolean | undefined,\n localMcp: options.localMcp as boolean | undefined,\n apiKey,\n email: options.email as string | undefined,\n menu: options.menu as boolean | undefined,\n integration: options.integration as any, // eslint-disable-line @typescript-eslint/no-explicit-any\n projectId: options.projectId as string | undefined,\n benchmark: options.benchmark as boolean | undefined,\n yaraReport: options.yaraReport as boolean | undefined,\n ...env,\n });\n session.workflowLabel = config.flowKey;\n const runDef = typeof config.run === 'object' ? config.run : null;\n session.skillId = runDef?.skillId ?? null;\n\n getUI().intro('Welcome to the PostHog setup wizard');\n getUI().log.info(`Running ${config.flowKey} in CI mode`);\n\n try {\n if (preRun) {\n await preRun(session);\n } else {\n // Run onReady hooks against a minimal store-less context.\n const readyCtx = {\n session,\n setFrameworkContext: (key: string, value: unknown) => {\n session.frameworkContext[key] = value;\n },\n setFrameworkConfig: () => undefined,\n setDetectedFramework: () => undefined,\n setUnsupportedVersion: () => undefined,\n addDiscoveredFeature: () => undefined,\n setDetectionComplete: () => undefined,\n };\n for (const step of config.steps) {\n if (step.onReady) {\n await step.onReady(readyCtx);\n }\n }\n\n // Surface detectError written by the workflow's detect hook.\n const detectError = session.frameworkContext.detectError as\n | { kind: string; [k: string]: unknown }\n | undefined;\n if (detectError) {\n await wizardAbort({\n message: `Prerequisites not met: ${detectError.kind}\\n\\nSee ${\n runDef?.docsUrl ?? 'https://posthog.com/docs'\n }`,\n error: new WizardError(`${config.flowKey} prerequisites failed`, {\n integration: config.flowKey,\n detect_error_kind: detectError.kind,\n }),\n });\n }\n }\n\n const { runAgent } = await import('./src/lib/agent/agent-runner.js');\n await runAgent(config, session);\n } catch (error) {\n const errorMessage =\n error instanceof Error ? error.message : String(error);\n const errorStack =\n error instanceof Error && error.stack ? error.stack : undefined;\n\n logToFile(`[bin.ts CI] ERROR: ${errorMessage}`);\n if (errorStack) logToFile(`[bin.ts CI] STACK: ${errorStack}`);\n\n const debugInfo = session.debug && errorStack ? `\\n\\n${errorStack}` : '';\n const docsUrl =\n session.frameworkConfig?.metadata.docsUrl ??\n runDef?.docsUrl ??\n 'https://posthog.com/docs';\n await wizardAbort({\n message: `Something went wrong: ${errorMessage}\\n\\nYou can read the documentation at ${docsUrl} to set up manually.${debugInfo}`,\n error: error as Error,\n });\n }\n })().catch(() => {\n process.exit(1);\n });\n}\n"],"mappings":"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"}
@@ -1,6 +1,6 @@
1
1
  import { t as __exportAll } from "./rolldown-runtime-B_-DWIq7.js";
2
- import { l as Integration, o as DETECTION_TIMEOUT_MS } from "./analytics-CpRZ9V5j.js";
3
- import { t as FRAMEWORK_REGISTRY } from "./registry-BUdvRdBh.js";
2
+ import { l as Integration, o as DETECTION_TIMEOUT_MS } from "./analytics-xANpxdVL.js";
3
+ import { t as FRAMEWORK_REGISTRY } from "./registry-qfhSxTjo.js";
4
4
  import * as semver from "semver";
5
5
  import { readFileSync } from "fs";
6
6
  import { join } from "path";
@@ -119,4 +119,4 @@ var detection_exports = /* @__PURE__ */ __exportAll({
119
119
  //#endregion
120
120
  export { detectFramework as a, discoverFeatures as i, checkFrameworkVersion as n, gatherFrameworkContext as r, detection_exports as t };
121
121
 
122
- //# sourceMappingURL=detection-D8428PBG.js.map
122
+ //# sourceMappingURL=detection-Drfq0l8n.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"detection-D8428PBG.js","names":[],"sources":["../src/lib/detection/framework.ts","../src/lib/detection/features.ts","../src/lib/detection/context.ts","../src/lib/detection/index.ts"],"sourcesContent":["/**\n * Framework detection — identify which PostHog-supported framework\n * is present in the project directory.\n *\n * Pure function: takes an install dir, returns the detected integration\n * (or undefined). No store mutations, no UI calls.\n */\n\nimport { Integration, DETECTION_TIMEOUT_MS } from '../constants.js';\nimport { FRAMEWORK_REGISTRY } from '../registry.js';\n\n/**\n * Loop through all registered frameworks and return the first one\n * whose `detect()` predicate matches the given directory.\n * Returns undefined if no framework is detected or detection times out.\n */\nexport async function detectFramework(\n installDir: string,\n): Promise<Integration | undefined> {\n for (const integration of Object.values(Integration)) {\n const config = FRAMEWORK_REGISTRY[integration];\n try {\n const detected = await Promise.race([\n config.detection.detect({ installDir }),\n new Promise<false>((resolve) =>\n setTimeout(() => resolve(false), DETECTION_TIMEOUT_MS),\n ),\n ]);\n if (detected) {\n return integration;\n }\n } catch {\n // Skip frameworks whose detection throws\n }\n }\n}\n","/**\n * Feature discovery — scan project dependencies for known SDK patterns\n * that indicate additional PostHog workflows are relevant.\n *\n * Pure function: takes an install dir, returns a set of discovered features.\n * No store mutations, no UI calls.\n */\n\nimport { readFileSync } from 'fs';\nimport { join } from 'path';\nimport { DiscoveredFeature } from '../wizard-session.js';\n\nconst STRIPE_PACKAGES = ['stripe', '@stripe/stripe-js'];\n\nconst 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\n/**\n * Scan `package.json` at `installDir` for dependencies that indicate\n * additional PostHog features (Stripe revenue analytics, LLM observability, etc.)\n *\n * Returns an array of discovered features, or empty if nothing found\n * or no package.json exists.\n */\nexport function discoverFeatures(installDir: string): DiscoveredFeature[] {\n const features: DiscoveredFeature[] = [];\n\n try {\n const pkg = JSON.parse(\n readFileSync(join(installDir, 'package.json'), 'utf-8'),\n ) as {\n dependencies?: Record<string, string>;\n devDependencies?: Record<string, string>;\n };\n const depNames = Object.keys({\n ...pkg.dependencies,\n ...pkg.devDependencies,\n });\n\n if (depNames.some((d) => STRIPE_PACKAGES.includes(d))) {\n features.push(DiscoveredFeature.Stripe);\n }\n\n if (depNames.some((d) => LLM_PACKAGES.includes(d))) {\n features.push(DiscoveredFeature.LLM);\n }\n } catch {\n // No package.json or parse error — skip feature discovery\n }\n\n return features;\n}\n","/**\n * Framework context gathering — run gatherContext and version checks\n * for a detected framework.\n *\n * Pure functions: take a framework config and options, return results.\n * No store mutations, no UI calls.\n */\n\nimport * as semver from 'semver';\nimport { DETECTION_TIMEOUT_MS } from '../constants.js';\nimport type { FrameworkConfig } from '../framework-config.js';\nimport type { WizardOptions } from '../../utils/types.js';\n\n/**\n * Run a framework's `gatherContext()` to collect variant-specific\n * metadata (e.g., router type for Next.js, Expo vs bare for React Native).\n *\n * Returns the gathered context, or an empty object on failure/timeout.\n */\nexport async function gatherFrameworkContext(\n config: FrameworkConfig,\n options: WizardOptions,\n): Promise<Record<string, unknown>> {\n if (!config.metadata.gatherContext) return {};\n\n try {\n return await Promise.race([\n config.metadata.gatherContext(options),\n new Promise<Record<string, never>>((resolve) =>\n setTimeout(() => resolve({}), DETECTION_TIMEOUT_MS),\n ),\n ]);\n } catch {\n return {};\n }\n}\n\nexport interface VersionCheckResult {\n /** Whether the installed version is supported */\n supported:\n | true\n | {\n current: string;\n minimum: string;\n docsUrl: string;\n };\n}\n\n/**\n * Check whether the installed framework version meets the minimum requirement.\n *\n * Returns `{ supported: true }` if the version is fine (or no check is needed).\n * Returns the version details if unsupported.\n */\nexport async function checkFrameworkVersion(\n config: FrameworkConfig,\n options: WizardOptions,\n): Promise<VersionCheckResult> {\n if (\n !config.detection.minimumVersion ||\n !config.detection.getInstalledVersion\n ) {\n return { supported: true };\n }\n\n const version = await config.detection.getInstalledVersion(options);\n if (!version) return { supported: true };\n\n const coerced = semver.coerce(version);\n if (coerced && semver.lt(coerced, config.detection.minimumVersion)) {\n return {\n supported: {\n current: version,\n minimum: config.detection.minimumVersion,\n docsUrl:\n config.metadata.unsupportedVersionDocsUrl ?? config.metadata.docsUrl,\n },\n };\n }\n\n return { supported: true };\n}\n","export { detectFramework } from './framework.js';\nexport { discoverFeatures } from './features.js';\nexport {\n gatherFrameworkContext,\n checkFrameworkVersion,\n type VersionCheckResult,\n} from './context.js';\n"],"mappings":";;;;;;;;;;;;;;;;;;;AAgBA,eAAsB,gBACpB,YACkC;AAClC,MAAK,MAAM,eAAe,OAAO,OAAO,YAAY,EAAE;EACpD,MAAM,SAAS,mBAAmB;AAClC,MAAI;AAOF,OANiB,MAAM,QAAQ,KAAK,CAClC,OAAO,UAAU,OAAO,EAAE,YAAY,CAAC,EACvC,IAAI,SAAgB,YAClB,iBAAiB,QAAQ,MAAM,EAAA,IAAuB,CACvD,CACF,CAAC,CAEA,QAAO;UAEH;;;;;;;;;;;;ACnBZ,MAAM,kBAAkB,CAAC,UAAU,oBAAoB;AAEvD,MAAM,eAAe;CACnB;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACD;;;;;;;;AASD,SAAgB,iBAAiB,YAAyC;CACxE,MAAM,WAAgC,EAAE;AAExC,KAAI;EACF,MAAM,MAAM,KAAK,MACf,aAAa,KAAK,YAAY,eAAe,EAAE,QAAQ,CACxD;EAID,MAAM,WAAW,OAAO,KAAK;GAC3B,GAAG,IAAI;GACP,GAAG,IAAI;GACR,CAAC;AAEF,MAAI,SAAS,MAAM,MAAM,gBAAgB,SAAS,EAAE,CAAC,CACnD,UAAS,KAAA,SAA8B;AAGzC,MAAI,SAAS,MAAM,MAAM,aAAa,SAAS,EAAE,CAAC,CAChD,UAAS,KAAA,MAA2B;SAEhC;AAIR,QAAO;;;;;;;;;;;;;;;;;AC3CT,eAAsB,uBACpB,QACA,SACkC;AAClC,KAAI,CAAC,OAAO,SAAS,cAAe,QAAO,EAAE;AAE7C,KAAI;AACF,SAAO,MAAM,QAAQ,KAAK,CACxB,OAAO,SAAS,cAAc,QAAQ,EACtC,IAAI,SAAgC,YAClC,iBAAiB,QAAQ,EAAE,CAAC,EAAE,qBAAqB,CACpD,CACF,CAAC;SACI;AACN,SAAO,EAAE;;;;;;;;;AAqBb,eAAsB,sBACpB,QACA,SAC6B;AAC7B,KACE,CAAC,OAAO,UAAU,kBAClB,CAAC,OAAO,UAAU,oBAElB,QAAO,EAAE,WAAW,MAAM;CAG5B,MAAM,UAAU,MAAM,OAAO,UAAU,oBAAoB,QAAQ;AACnE,KAAI,CAAC,QAAS,QAAO,EAAE,WAAW,MAAM;CAExC,MAAM,UAAU,OAAO,OAAO,QAAQ;AACtC,KAAI,WAAW,OAAO,GAAG,SAAS,OAAO,UAAU,eAAe,CAChE,QAAO,EACL,WAAW;EACT,SAAS;EACT,SAAS,OAAO,UAAU;EAC1B,SACE,OAAO,SAAS,6BAA6B,OAAO,SAAS;EAChE,EACF;AAGH,QAAO,EAAE,WAAW,MAAM"}
1
+ {"version":3,"file":"detection-Drfq0l8n.js","names":[],"sources":["../src/lib/detection/framework.ts","../src/lib/detection/features.ts","../src/lib/detection/context.ts","../src/lib/detection/index.ts"],"sourcesContent":["/**\n * Framework detection — identify which PostHog-supported framework\n * is present in the project directory.\n *\n * Pure function: takes an install dir, returns the detected integration\n * (or undefined). No store mutations, no UI calls.\n */\n\nimport { Integration, DETECTION_TIMEOUT_MS } from '../constants.js';\nimport { FRAMEWORK_REGISTRY } from '../registry.js';\n\n/**\n * Loop through all registered frameworks and return the first one\n * whose `detect()` predicate matches the given directory.\n * Returns undefined if no framework is detected or detection times out.\n */\nexport async function detectFramework(\n installDir: string,\n): Promise<Integration | undefined> {\n for (const integration of Object.values(Integration)) {\n const config = FRAMEWORK_REGISTRY[integration];\n try {\n const detected = await Promise.race([\n config.detection.detect({ installDir }),\n new Promise<false>((resolve) =>\n setTimeout(() => resolve(false), DETECTION_TIMEOUT_MS),\n ),\n ]);\n if (detected) {\n return integration;\n }\n } catch {\n // Skip frameworks whose detection throws\n }\n }\n}\n","/**\n * Feature discovery — scan project dependencies for known SDK patterns\n * that indicate additional PostHog workflows are relevant.\n *\n * Pure function: takes an install dir, returns a set of discovered features.\n * No store mutations, no UI calls.\n */\n\nimport { readFileSync } from 'fs';\nimport { join } from 'path';\nimport { DiscoveredFeature } from '../wizard-session.js';\n\nconst STRIPE_PACKAGES = ['stripe', '@stripe/stripe-js'];\n\nconst 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\n/**\n * Scan `package.json` at `installDir` for dependencies that indicate\n * additional PostHog features (Stripe revenue analytics, LLM observability, etc.)\n *\n * Returns an array of discovered features, or empty if nothing found\n * or no package.json exists.\n */\nexport function discoverFeatures(installDir: string): DiscoveredFeature[] {\n const features: DiscoveredFeature[] = [];\n\n try {\n const pkg = JSON.parse(\n readFileSync(join(installDir, 'package.json'), 'utf-8'),\n ) as {\n dependencies?: Record<string, string>;\n devDependencies?: Record<string, string>;\n };\n const depNames = Object.keys({\n ...pkg.dependencies,\n ...pkg.devDependencies,\n });\n\n if (depNames.some((d) => STRIPE_PACKAGES.includes(d))) {\n features.push(DiscoveredFeature.Stripe);\n }\n\n if (depNames.some((d) => LLM_PACKAGES.includes(d))) {\n features.push(DiscoveredFeature.LLM);\n }\n } catch {\n // No package.json or parse error — skip feature discovery\n }\n\n return features;\n}\n","/**\n * Framework context gathering — run gatherContext and version checks\n * for a detected framework.\n *\n * Pure functions: take a framework config and options, return results.\n * No store mutations, no UI calls.\n */\n\nimport * as semver from 'semver';\nimport { DETECTION_TIMEOUT_MS } from '../constants.js';\nimport type { FrameworkConfig } from '../framework-config.js';\nimport type { WizardOptions } from '../../utils/types.js';\n\n/**\n * Run a framework's `gatherContext()` to collect variant-specific\n * metadata (e.g., router type for Next.js, Expo vs bare for React Native).\n *\n * Returns the gathered context, or an empty object on failure/timeout.\n */\nexport async function gatherFrameworkContext(\n config: FrameworkConfig,\n options: WizardOptions,\n): Promise<Record<string, unknown>> {\n if (!config.metadata.gatherContext) return {};\n\n try {\n return await Promise.race([\n config.metadata.gatherContext(options),\n new Promise<Record<string, never>>((resolve) =>\n setTimeout(() => resolve({}), DETECTION_TIMEOUT_MS),\n ),\n ]);\n } catch {\n return {};\n }\n}\n\nexport interface VersionCheckResult {\n /** Whether the installed version is supported */\n supported:\n | true\n | {\n current: string;\n minimum: string;\n docsUrl: string;\n };\n}\n\n/**\n * Check whether the installed framework version meets the minimum requirement.\n *\n * Returns `{ supported: true }` if the version is fine (or no check is needed).\n * Returns the version details if unsupported.\n */\nexport async function checkFrameworkVersion(\n config: FrameworkConfig,\n options: WizardOptions,\n): Promise<VersionCheckResult> {\n if (\n !config.detection.minimumVersion ||\n !config.detection.getInstalledVersion\n ) {\n return { supported: true };\n }\n\n const version = await config.detection.getInstalledVersion(options);\n if (!version) return { supported: true };\n\n const coerced = semver.coerce(version);\n if (coerced && semver.lt(coerced, config.detection.minimumVersion)) {\n return {\n supported: {\n current: version,\n minimum: config.detection.minimumVersion,\n docsUrl:\n config.metadata.unsupportedVersionDocsUrl ?? config.metadata.docsUrl,\n },\n };\n }\n\n return { supported: true };\n}\n","export { detectFramework } from './framework.js';\nexport { discoverFeatures } from './features.js';\nexport {\n gatherFrameworkContext,\n checkFrameworkVersion,\n type VersionCheckResult,\n} from './context.js';\n"],"mappings":";;;;;;;;;;;;;;;;;;;AAgBA,eAAsB,gBACpB,YACkC;AAClC,MAAK,MAAM,eAAe,OAAO,OAAO,YAAY,EAAE;EACpD,MAAM,SAAS,mBAAmB;AAClC,MAAI;AAOF,OANiB,MAAM,QAAQ,KAAK,CAClC,OAAO,UAAU,OAAO,EAAE,YAAY,CAAC,EACvC,IAAI,SAAgB,YAClB,iBAAiB,QAAQ,MAAM,EAAA,IAAuB,CACvD,CACF,CAAC,CAEA,QAAO;UAEH;;;;;;;;;;;;ACnBZ,MAAM,kBAAkB,CAAC,UAAU,oBAAoB;AAEvD,MAAM,eAAe;CACnB;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACD;;;;;;;;AASD,SAAgB,iBAAiB,YAAyC;CACxE,MAAM,WAAgC,EAAE;AAExC,KAAI;EACF,MAAM,MAAM,KAAK,MACf,aAAa,KAAK,YAAY,eAAe,EAAE,QAAQ,CACxD;EAID,MAAM,WAAW,OAAO,KAAK;GAC3B,GAAG,IAAI;GACP,GAAG,IAAI;GACR,CAAC;AAEF,MAAI,SAAS,MAAM,MAAM,gBAAgB,SAAS,EAAE,CAAC,CACnD,UAAS,KAAA,SAA8B;AAGzC,MAAI,SAAS,MAAM,MAAM,aAAa,SAAS,EAAE,CAAC,CAChD,UAAS,KAAA,MAA2B;SAEhC;AAIR,QAAO;;;;;;;;;;;;;;;;;AC3CT,eAAsB,uBACpB,QACA,SACkC;AAClC,KAAI,CAAC,OAAO,SAAS,cAAe,QAAO,EAAE;AAE7C,KAAI;AACF,SAAO,MAAM,QAAQ,KAAK,CACxB,OAAO,SAAS,cAAc,QAAQ,EACtC,IAAI,SAAgC,YAClC,iBAAiB,QAAQ,EAAE,CAAC,EAAE,qBAAqB,CACpD,CACF,CAAC;SACI;AACN,SAAO,EAAE;;;;;;;;;AAqBb,eAAsB,sBACpB,QACA,SAC6B;AAC7B,KACE,CAAC,OAAO,UAAU,kBAClB,CAAC,OAAO,UAAU,oBAElB,QAAO,EAAE,WAAW,MAAM;CAG5B,MAAM,UAAU,MAAM,OAAO,UAAU,oBAAoB,QAAQ;AACnE,KAAI,CAAC,QAAS,QAAO,EAAE,WAAW,MAAM;CAExC,MAAM,UAAU,OAAO,OAAO,QAAQ;AACtC,KAAI,WAAW,OAAO,GAAG,SAAS,OAAO,UAAU,eAAe,CAChE,QAAO,EACL,WAAW;EACT,SAAS;EACT,SAAS,OAAO,UAAU;EAC1B,SACE,OAAO,SAAS,6BAA6B,OAAO,SAAS;EAChE,EACF;AAGH,QAAO,EAAE,WAAW,MAAM"}
@@ -1,4 +1,4 @@
1
- import { s as detectAllPackageManagers } from "./setup-utils-DJuYiRId.js";
1
+ import { s as detectAllPackageManagers } from "./setup-utils-C1h1QDiG.js";
2
2
  import { execSync } from "node:child_process";
3
3
  //#region src/frameworks/python/utils.ts
4
4
  /**
@@ -219,4 +219,4 @@ function gradlePackageManager() {
219
219
  //#endregion
220
220
  export { gradlePackageManager as a, getPackageManagerName as c, detectPythonPackageManagers as i, getPythonVersion as l, composerPackageManager as n, swiftPackageManager as o, detectNodePackageManagers as r, detectPackageManager as s, bundlerPackageManager as t, getPythonVersionBucket as u };
221
221
 
222
- //# sourceMappingURL=package-manager-B_VtY9ZS.js.map
222
+ //# sourceMappingURL=package-manager-Ls_8r9Ot.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"package-manager-B_VtY9ZS.js","names":["detectPythonPM"],"sources":["../src/frameworks/python/utils.ts","../src/lib/detection/package-manager.ts"],"sourcesContent":["import { execSync } from 'node:child_process';\nimport type { WizardOptions } from '../../utils/types';\n\nexport enum PythonPackageManager {\n UV = 'uv',\n POETRY = 'poetry',\n PDM = 'pdm',\n HATCH = 'hatch',\n RYE = 'rye',\n PIPENV = 'pipenv',\n CONDA = 'conda',\n PIP = 'pip',\n UNKNOWN = 'unknown',\n}\n\n/**\n * Get the installed Python version\n */\nexport function getPythonVersion(options: WizardOptions): string | undefined {\n try {\n const version = execSync('python --version || python3 --version', {\n cwd: options.installDir,\n encoding: 'utf-8',\n })\n .trim()\n .replace('Python ', '');\n return version;\n } catch {\n return undefined;\n }\n}\n\n/**\n * Bucket Python version for analytics (e.g., \"3.11.x\" -> \"3.11\")\n */\nexport function getPythonVersionBucket(version: string): string {\n const match = version.match(/^(\\d+\\.\\d+)/);\n return match ? match[1] : version;\n}\n\n/**\n * Detect which package manager the project uses\n */\nexport async function detectPackageManager(\n options: WizardOptions,\n): Promise<PythonPackageManager> {\n const { installDir } = options;\n const fs = await import('node:fs');\n const path = await import('node:path');\n\n // Check for uv (uv.lock)\n if (fs.existsSync(path.join(installDir, 'uv.lock'))) {\n return PythonPackageManager.UV;\n }\n\n // Check pyproject.toml for various tools\n if (fs.existsSync(path.join(installDir, 'pyproject.toml'))) {\n try {\n const content = fs.readFileSync(\n path.join(installDir, 'pyproject.toml'),\n 'utf-8',\n );\n\n // Check for Poetry\n if (content.includes('[tool.poetry]')) {\n return PythonPackageManager.POETRY;\n }\n\n // Check for PDM\n if (content.includes('[tool.pdm]')) {\n return PythonPackageManager.PDM;\n }\n\n // Check for Hatch\n if (content.includes('[tool.hatch]')) {\n return PythonPackageManager.HATCH;\n }\n\n // Check for Rye\n if (content.includes('[tool.rye]')) {\n return PythonPackageManager.RYE;\n }\n } catch {\n // Continue checking\n }\n }\n\n // Check for Poetry lock file\n if (fs.existsSync(path.join(installDir, 'poetry.lock'))) {\n return PythonPackageManager.POETRY;\n }\n\n // Check for PDM lock file\n if (fs.existsSync(path.join(installDir, 'pdm.lock'))) {\n return PythonPackageManager.PDM;\n }\n\n // Check for Pipenv (Pipfile or Pipfile.lock)\n if (\n fs.existsSync(path.join(installDir, 'Pipfile')) ||\n fs.existsSync(path.join(installDir, 'Pipfile.lock'))\n ) {\n return PythonPackageManager.PIPENV;\n }\n\n // Check for Conda (environment.yml or environment.yaml)\n if (\n fs.existsSync(path.join(installDir, 'environment.yml')) ||\n fs.existsSync(path.join(installDir, 'environment.yaml'))\n ) {\n return PythonPackageManager.CONDA;\n }\n\n // Check for pip (requirements.txt, setup.py, setup.cfg, or pyproject.toml)\n if (\n fs.existsSync(path.join(installDir, 'requirements.txt')) ||\n fs.existsSync(path.join(installDir, 'setup.py')) ||\n fs.existsSync(path.join(installDir, 'setup.cfg')) ||\n fs.existsSync(path.join(installDir, 'pyproject.toml'))\n ) {\n return PythonPackageManager.PIP;\n }\n\n // Check for requirements directory\n try {\n const requirementsDir = path.join(installDir, 'requirements');\n if (\n fs.existsSync(requirementsDir) &&\n fs.statSync(requirementsDir).isDirectory()\n ) {\n const files = fs.readdirSync(requirementsDir);\n if (files.some((f) => f.endsWith('.txt'))) {\n return PythonPackageManager.PIP;\n }\n }\n } catch {\n // Continue\n }\n\n return PythonPackageManager.UNKNOWN;\n}\n\n/**\n * Get package manager display name\n */\nexport function getPackageManagerName(\n packageManager: PythonPackageManager,\n): string {\n switch (packageManager) {\n case PythonPackageManager.UV:\n return 'uv';\n case PythonPackageManager.POETRY:\n return 'Poetry';\n case PythonPackageManager.PDM:\n return 'PDM';\n case PythonPackageManager.HATCH:\n return 'Hatch';\n case PythonPackageManager.RYE:\n return 'Rye';\n case PythonPackageManager.PIPENV:\n return 'Pipenv';\n case PythonPackageManager.CONDA:\n return 'Conda';\n case PythonPackageManager.PIP:\n return 'pip';\n case PythonPackageManager.UNKNOWN:\n return 'unknown';\n }\n}\n","/**\n * Cross-ecosystem package manager detection.\n *\n * Provides a common interface (PackageManagerDetector) that each FrameworkConfig\n * implements, plus shared helpers for Node.js, Python, PHP, and Swift ecosystems.\n * The MCP tool in wizard-tools.ts delegates to whatever detector the\n * current framework supplies.\n */\n\nimport {\n detectAllPackageManagers,\n type PackageManager,\n} from '../../utils/package-manager';\nimport {\n detectPackageManager as detectPythonPM,\n PythonPackageManager,\n} from '../../frameworks/python/utils';\n\n// ---------------------------------------------------------------------------\n// Common types\n// ---------------------------------------------------------------------------\n\n/** Structured package manager info the agent can act on */\nexport interface DetectedPackageManager {\n name: string;\n label: string;\n installCommand: string;\n runCommand?: string;\n}\n\n/** Result returned by every detector */\nexport interface PackageManagerInfo {\n detected: DetectedPackageManager[];\n primary: DetectedPackageManager | null;\n recommendation: string;\n}\n\n/** Signature each framework implements */\nexport type PackageManagerDetector = (\n installDir: string,\n) => Promise<PackageManagerInfo>;\n\n// ---------------------------------------------------------------------------\n// Node.js helper\n// ---------------------------------------------------------------------------\n\nfunction serializeNodePM(pm: PackageManager): DetectedPackageManager {\n return {\n name: pm.name,\n label: pm.label,\n installCommand: pm.installCommand,\n runCommand: pm.runScriptCommand,\n };\n}\n\n/**\n * Detect Node.js package managers via lockfiles.\n * Wraps the existing detectAllPackageManagers() from utils/package-manager.ts.\n */\nexport function detectNodePackageManagers(\n installDir: string,\n): Promise<PackageManagerInfo> {\n const detected = detectAllPackageManagers({ installDir }).map(\n serializeNodePM,\n );\n\n if (detected.length === 0) {\n return Promise.resolve({\n detected: [],\n primary: null,\n recommendation: 'No lockfile found. Default to npm (npm add, npm run).',\n });\n }\n\n const primary = detected[0];\n return Promise.resolve({\n detected,\n primary,\n recommendation:\n detected.length === 1\n ? `Use ${primary.label} (${primary.installCommand}).`\n : `Multiple package managers detected. Prefer ${primary.label} (${primary.installCommand}).`,\n });\n}\n\n// ---------------------------------------------------------------------------\n// Python helper\n// ---------------------------------------------------------------------------\n\nconst PYTHON_PM_INFO: Record<PythonPackageManager, DetectedPackageManager> = {\n [PythonPackageManager.UV]: {\n name: 'uv',\n label: 'uv',\n installCommand: 'uv add',\n runCommand: 'uv run',\n },\n [PythonPackageManager.POETRY]: {\n name: 'poetry',\n label: 'Poetry',\n installCommand: 'poetry add',\n runCommand: 'poetry run',\n },\n [PythonPackageManager.PDM]: {\n name: 'pdm',\n label: 'PDM',\n installCommand: 'pdm add',\n runCommand: 'pdm run',\n },\n [PythonPackageManager.HATCH]: {\n name: 'hatch',\n label: 'Hatch',\n installCommand: 'hatch add',\n runCommand: 'hatch run',\n },\n [PythonPackageManager.RYE]: {\n name: 'rye',\n label: 'Rye',\n installCommand: 'rye add',\n runCommand: 'rye run',\n },\n [PythonPackageManager.PIPENV]: {\n name: 'pipenv',\n label: 'Pipenv',\n installCommand: 'pipenv install',\n runCommand: 'pipenv run',\n },\n [PythonPackageManager.CONDA]: {\n name: 'conda',\n label: 'Conda',\n installCommand: 'conda install',\n runCommand: 'conda run',\n },\n [PythonPackageManager.PIP]: {\n name: 'pip',\n label: 'pip',\n installCommand: 'pip install',\n },\n [PythonPackageManager.UNKNOWN]: {\n name: 'pip',\n label: 'pip (default)',\n installCommand: 'pip install',\n },\n};\n\n/**\n * Detect Python package managers via lockfiles and config files.\n * Wraps the existing detectPackageManager() from python/utils.ts.\n */\nexport async function detectPythonPackageManagers(\n installDir: string,\n): Promise<PackageManagerInfo> {\n const pm = await detectPythonPM({ installDir } as any);\n const info = PYTHON_PM_INFO[pm];\n\n return {\n detected: [info],\n primary: info,\n recommendation: `Use ${info.label} (${info.installCommand}).`,\n };\n}\n\n// ---------------------------------------------------------------------------\n// PHP (Composer) helper\n// ---------------------------------------------------------------------------\n\nconst COMPOSER: DetectedPackageManager = {\n name: 'composer',\n label: 'Composer',\n installCommand: 'composer require',\n};\n\nexport function composerPackageManager(): Promise<PackageManagerInfo> {\n return Promise.resolve({\n detected: [COMPOSER],\n primary: COMPOSER,\n recommendation: 'Use Composer (composer require).',\n });\n}\n\n// ---------------------------------------------------------------------------\n// Swift (SPM) helper\n// ---------------------------------------------------------------------------\n\nconst SPM: DetectedPackageManager = {\n name: 'spm',\n label: 'Swift Package Manager',\n installCommand: 'swift package add-dependency',\n};\n\nexport function swiftPackageManager(): Promise<PackageManagerInfo> {\n return Promise.resolve({\n detected: [SPM],\n primary: SPM,\n recommendation:\n 'Use Swift Package Manager. Add the dependency to Package.swift or via Xcode.',\n });\n}\n\n// ---------------------------------------------------------------------------\n// Ruby (Bundler) helper\n// ---------------------------------------------------------------------------\n\nconst BUNDLER: DetectedPackageManager = {\n name: 'bundler',\n label: 'Bundler',\n installCommand: 'bundle add',\n runCommand: 'bundle exec',\n};\n\nexport function bundlerPackageManager(): Promise<PackageManagerInfo> {\n return Promise.resolve({\n detected: [BUNDLER],\n primary: BUNDLER,\n recommendation: 'Use Bundler (bundle add). Run commands with bundle exec.',\n });\n}\n\n// ---------------------------------------------------------------------------\n// Android (Gradle) helper\n// ---------------------------------------------------------------------------\n\nconst GRADLE: DetectedPackageManager = {\n name: 'gradle',\n label: 'Gradle',\n installCommand: 'implementation',\n};\n\nexport function gradlePackageManager(): Promise<PackageManagerInfo> {\n return Promise.resolve({\n detected: [GRADLE],\n primary: GRADLE,\n recommendation:\n 'Add dependencies to build.gradle(.kts) using implementation().',\n });\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"package-manager-Ls_8r9Ot.js","names":["detectPythonPM"],"sources":["../src/frameworks/python/utils.ts","../src/lib/detection/package-manager.ts"],"sourcesContent":["import { execSync } from 'node:child_process';\nimport type { WizardOptions } from '../../utils/types';\n\nexport enum PythonPackageManager {\n UV = 'uv',\n POETRY = 'poetry',\n PDM = 'pdm',\n HATCH = 'hatch',\n RYE = 'rye',\n PIPENV = 'pipenv',\n CONDA = 'conda',\n PIP = 'pip',\n UNKNOWN = 'unknown',\n}\n\n/**\n * Get the installed Python version\n */\nexport function getPythonVersion(options: WizardOptions): string | undefined {\n try {\n const version = execSync('python --version || python3 --version', {\n cwd: options.installDir,\n encoding: 'utf-8',\n })\n .trim()\n .replace('Python ', '');\n return version;\n } catch {\n return undefined;\n }\n}\n\n/**\n * Bucket Python version for analytics (e.g., \"3.11.x\" -> \"3.11\")\n */\nexport function getPythonVersionBucket(version: string): string {\n const match = version.match(/^(\\d+\\.\\d+)/);\n return match ? match[1] : version;\n}\n\n/**\n * Detect which package manager the project uses\n */\nexport async function detectPackageManager(\n options: WizardOptions,\n): Promise<PythonPackageManager> {\n const { installDir } = options;\n const fs = await import('node:fs');\n const path = await import('node:path');\n\n // Check for uv (uv.lock)\n if (fs.existsSync(path.join(installDir, 'uv.lock'))) {\n return PythonPackageManager.UV;\n }\n\n // Check pyproject.toml for various tools\n if (fs.existsSync(path.join(installDir, 'pyproject.toml'))) {\n try {\n const content = fs.readFileSync(\n path.join(installDir, 'pyproject.toml'),\n 'utf-8',\n );\n\n // Check for Poetry\n if (content.includes('[tool.poetry]')) {\n return PythonPackageManager.POETRY;\n }\n\n // Check for PDM\n if (content.includes('[tool.pdm]')) {\n return PythonPackageManager.PDM;\n }\n\n // Check for Hatch\n if (content.includes('[tool.hatch]')) {\n return PythonPackageManager.HATCH;\n }\n\n // Check for Rye\n if (content.includes('[tool.rye]')) {\n return PythonPackageManager.RYE;\n }\n } catch {\n // Continue checking\n }\n }\n\n // Check for Poetry lock file\n if (fs.existsSync(path.join(installDir, 'poetry.lock'))) {\n return PythonPackageManager.POETRY;\n }\n\n // Check for PDM lock file\n if (fs.existsSync(path.join(installDir, 'pdm.lock'))) {\n return PythonPackageManager.PDM;\n }\n\n // Check for Pipenv (Pipfile or Pipfile.lock)\n if (\n fs.existsSync(path.join(installDir, 'Pipfile')) ||\n fs.existsSync(path.join(installDir, 'Pipfile.lock'))\n ) {\n return PythonPackageManager.PIPENV;\n }\n\n // Check for Conda (environment.yml or environment.yaml)\n if (\n fs.existsSync(path.join(installDir, 'environment.yml')) ||\n fs.existsSync(path.join(installDir, 'environment.yaml'))\n ) {\n return PythonPackageManager.CONDA;\n }\n\n // Check for pip (requirements.txt, setup.py, setup.cfg, or pyproject.toml)\n if (\n fs.existsSync(path.join(installDir, 'requirements.txt')) ||\n fs.existsSync(path.join(installDir, 'setup.py')) ||\n fs.existsSync(path.join(installDir, 'setup.cfg')) ||\n fs.existsSync(path.join(installDir, 'pyproject.toml'))\n ) {\n return PythonPackageManager.PIP;\n }\n\n // Check for requirements directory\n try {\n const requirementsDir = path.join(installDir, 'requirements');\n if (\n fs.existsSync(requirementsDir) &&\n fs.statSync(requirementsDir).isDirectory()\n ) {\n const files = fs.readdirSync(requirementsDir);\n if (files.some((f) => f.endsWith('.txt'))) {\n return PythonPackageManager.PIP;\n }\n }\n } catch {\n // Continue\n }\n\n return PythonPackageManager.UNKNOWN;\n}\n\n/**\n * Get package manager display name\n */\nexport function getPackageManagerName(\n packageManager: PythonPackageManager,\n): string {\n switch (packageManager) {\n case PythonPackageManager.UV:\n return 'uv';\n case PythonPackageManager.POETRY:\n return 'Poetry';\n case PythonPackageManager.PDM:\n return 'PDM';\n case PythonPackageManager.HATCH:\n return 'Hatch';\n case PythonPackageManager.RYE:\n return 'Rye';\n case PythonPackageManager.PIPENV:\n return 'Pipenv';\n case PythonPackageManager.CONDA:\n return 'Conda';\n case PythonPackageManager.PIP:\n return 'pip';\n case PythonPackageManager.UNKNOWN:\n return 'unknown';\n }\n}\n","/**\n * Cross-ecosystem package manager detection.\n *\n * Provides a common interface (PackageManagerDetector) that each FrameworkConfig\n * implements, plus shared helpers for Node.js, Python, PHP, and Swift ecosystems.\n * The MCP tool in wizard-tools.ts delegates to whatever detector the\n * current framework supplies.\n */\n\nimport {\n detectAllPackageManagers,\n type PackageManager,\n} from '../../utils/package-manager';\nimport {\n detectPackageManager as detectPythonPM,\n PythonPackageManager,\n} from '../../frameworks/python/utils';\n\n// ---------------------------------------------------------------------------\n// Common types\n// ---------------------------------------------------------------------------\n\n/** Structured package manager info the agent can act on */\nexport interface DetectedPackageManager {\n name: string;\n label: string;\n installCommand: string;\n runCommand?: string;\n}\n\n/** Result returned by every detector */\nexport interface PackageManagerInfo {\n detected: DetectedPackageManager[];\n primary: DetectedPackageManager | null;\n recommendation: string;\n}\n\n/** Signature each framework implements */\nexport type PackageManagerDetector = (\n installDir: string,\n) => Promise<PackageManagerInfo>;\n\n// ---------------------------------------------------------------------------\n// Node.js helper\n// ---------------------------------------------------------------------------\n\nfunction serializeNodePM(pm: PackageManager): DetectedPackageManager {\n return {\n name: pm.name,\n label: pm.label,\n installCommand: pm.installCommand,\n runCommand: pm.runScriptCommand,\n };\n}\n\n/**\n * Detect Node.js package managers via lockfiles.\n * Wraps the existing detectAllPackageManagers() from utils/package-manager.ts.\n */\nexport function detectNodePackageManagers(\n installDir: string,\n): Promise<PackageManagerInfo> {\n const detected = detectAllPackageManagers({ installDir }).map(\n serializeNodePM,\n );\n\n if (detected.length === 0) {\n return Promise.resolve({\n detected: [],\n primary: null,\n recommendation: 'No lockfile found. Default to npm (npm add, npm run).',\n });\n }\n\n const primary = detected[0];\n return Promise.resolve({\n detected,\n primary,\n recommendation:\n detected.length === 1\n ? `Use ${primary.label} (${primary.installCommand}).`\n : `Multiple package managers detected. Prefer ${primary.label} (${primary.installCommand}).`,\n });\n}\n\n// ---------------------------------------------------------------------------\n// Python helper\n// ---------------------------------------------------------------------------\n\nconst PYTHON_PM_INFO: Record<PythonPackageManager, DetectedPackageManager> = {\n [PythonPackageManager.UV]: {\n name: 'uv',\n label: 'uv',\n installCommand: 'uv add',\n runCommand: 'uv run',\n },\n [PythonPackageManager.POETRY]: {\n name: 'poetry',\n label: 'Poetry',\n installCommand: 'poetry add',\n runCommand: 'poetry run',\n },\n [PythonPackageManager.PDM]: {\n name: 'pdm',\n label: 'PDM',\n installCommand: 'pdm add',\n runCommand: 'pdm run',\n },\n [PythonPackageManager.HATCH]: {\n name: 'hatch',\n label: 'Hatch',\n installCommand: 'hatch add',\n runCommand: 'hatch run',\n },\n [PythonPackageManager.RYE]: {\n name: 'rye',\n label: 'Rye',\n installCommand: 'rye add',\n runCommand: 'rye run',\n },\n [PythonPackageManager.PIPENV]: {\n name: 'pipenv',\n label: 'Pipenv',\n installCommand: 'pipenv install',\n runCommand: 'pipenv run',\n },\n [PythonPackageManager.CONDA]: {\n name: 'conda',\n label: 'Conda',\n installCommand: 'conda install',\n runCommand: 'conda run',\n },\n [PythonPackageManager.PIP]: {\n name: 'pip',\n label: 'pip',\n installCommand: 'pip install',\n },\n [PythonPackageManager.UNKNOWN]: {\n name: 'pip',\n label: 'pip (default)',\n installCommand: 'pip install',\n },\n};\n\n/**\n * Detect Python package managers via lockfiles and config files.\n * Wraps the existing detectPackageManager() from python/utils.ts.\n */\nexport async function detectPythonPackageManagers(\n installDir: string,\n): Promise<PackageManagerInfo> {\n const pm = await detectPythonPM({ installDir } as any);\n const info = PYTHON_PM_INFO[pm];\n\n return {\n detected: [info],\n primary: info,\n recommendation: `Use ${info.label} (${info.installCommand}).`,\n };\n}\n\n// ---------------------------------------------------------------------------\n// PHP (Composer) helper\n// ---------------------------------------------------------------------------\n\nconst COMPOSER: DetectedPackageManager = {\n name: 'composer',\n label: 'Composer',\n installCommand: 'composer require',\n};\n\nexport function composerPackageManager(): Promise<PackageManagerInfo> {\n return Promise.resolve({\n detected: [COMPOSER],\n primary: COMPOSER,\n recommendation: 'Use Composer (composer require).',\n });\n}\n\n// ---------------------------------------------------------------------------\n// Swift (SPM) helper\n// ---------------------------------------------------------------------------\n\nconst SPM: DetectedPackageManager = {\n name: 'spm',\n label: 'Swift Package Manager',\n installCommand: 'swift package add-dependency',\n};\n\nexport function swiftPackageManager(): Promise<PackageManagerInfo> {\n return Promise.resolve({\n detected: [SPM],\n primary: SPM,\n recommendation:\n 'Use Swift Package Manager. Add the dependency to Package.swift or via Xcode.',\n });\n}\n\n// ---------------------------------------------------------------------------\n// Ruby (Bundler) helper\n// ---------------------------------------------------------------------------\n\nconst BUNDLER: DetectedPackageManager = {\n name: 'bundler',\n label: 'Bundler',\n installCommand: 'bundle add',\n runCommand: 'bundle exec',\n};\n\nexport function bundlerPackageManager(): Promise<PackageManagerInfo> {\n return Promise.resolve({\n detected: [BUNDLER],\n primary: BUNDLER,\n recommendation: 'Use Bundler (bundle add). Run commands with bundle exec.',\n });\n}\n\n// ---------------------------------------------------------------------------\n// Android (Gradle) helper\n// ---------------------------------------------------------------------------\n\nconst GRADLE: DetectedPackageManager = {\n name: 'gradle',\n label: 'Gradle',\n installCommand: 'implementation',\n};\n\nexport function gradlePackageManager(): Promise<PackageManagerInfo> {\n return Promise.resolve({\n detected: [GRADLE],\n primary: GRADLE,\n recommendation:\n 'Add dependencies to build.gradle(.kts) using implementation().',\n });\n}\n"],"mappings":"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"}
@@ -1,10 +1,10 @@
1
1
  import { t as __exportAll } from "./rolldown-runtime-B_-DWIq7.js";
2
2
  import { c as getUI } from "./debug-CyJ_3dTP.js";
3
- import { n as analytics, y as WIZARD_INTERACTION_EVENT_NAME } from "./analytics-CpRZ9V5j.js";
4
- import { a as getCloudUrlFromRegion, n as isUsingTypeScript, r as tryGetPackageJson } from "./setup-utils-DJuYiRId.js";
5
- import { i as AgentSignals, n as evaluateWizardReadiness } from "./readiness-V6pfR5tp.js";
6
- import { i as SPINNER_MESSAGE, t as FRAMEWORK_REGISTRY } from "./registry-BUdvRdBh.js";
7
- import { a as detectFramework, i as discoverFeatures, n as checkFrameworkVersion, r as gatherFrameworkContext } from "./detection-D8428PBG.js";
3
+ import { n as analytics, y as WIZARD_INTERACTION_EVENT_NAME } from "./analytics-xANpxdVL.js";
4
+ import { a as getCloudUrlFromRegion, n as isUsingTypeScript, r as tryGetPackageJson } from "./setup-utils-C1h1QDiG.js";
5
+ import { i as AgentSignals, n as evaluateWizardReadiness } from "./readiness-BAgN8xAg.js";
6
+ import { i as SPINNER_MESSAGE, t as FRAMEWORK_REGISTRY } from "./registry-qfhSxTjo.js";
7
+ import { a as detectFramework, i as discoverFeatures, n as checkFrameworkVersion, r as gatherFrameworkContext } from "./detection-Drfq0l8n.js";
8
8
  //#region src/lib/workflows/posthog-integration/detect.ts
9
9
  async function detectPostHogIntegration(ctx) {
10
10
  const session = ctx.session;
@@ -196,7 +196,7 @@ Important: Use the detect_package_manager tool (from the wizard-tools MCP server
196
196
  postRun: async (sess, credentials) => {
197
197
  const envVars = config.environment.getEnvVars(credentials.projectApiKey, credentials.host);
198
198
  if (config.environment.uploadToHosting) {
199
- const { uploadEnvironmentVariablesStep } = await import("./steps-u8U1Nz2e.js");
199
+ const { uploadEnvironmentVariablesStep } = await import("./steps-BjvFG--8.js");
200
200
  const uploadedEnvVars = await uploadEnvironmentVariablesStep(envVars, {
201
201
  integration: config.metadata.integration,
202
202
  session: sess
@@ -227,4 +227,4 @@ Important: Use the detect_package_manager tool (from the wizard-tools MCP server
227
227
  //#endregion
228
228
  export { posthog_integration_exports as n, posthogIntegrationConfig as t };
229
229
 
230
- //# sourceMappingURL=posthog-integration-EeKb2FkQ.js.map
230
+ //# sourceMappingURL=posthog-integration-DUZpiyxg.js.map