@posthog/wizard 2.10.4 → 2.12.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (90) hide show
  1. package/README.md +48 -7
  2. package/dist/{McpScreen-LqnNwEfV.js → AuditChecksViewer-DsfXIO9e.js} +475 -36
  3. package/dist/AuditChecksViewer-DsfXIO9e.js.map +1 -0
  4. package/dist/{add-mcp-server-to-clients-lfUH2pdU.js → add-mcp-server-to-clients-BKoew3aT.js} +157 -125
  5. package/dist/add-mcp-server-to-clients-BKoew3aT.js.map +1 -0
  6. package/dist/{readiness-Cep84RsR.js → agent-interface-D5W9BAB2.js} +329 -464
  7. package/dist/agent-interface-D5W9BAB2.js.map +1 -0
  8. package/dist/{agent-runner-DHtcWn15.js → agent-runner-B8Cx6X6x.js} +22 -31
  9. package/dist/agent-runner-B8Cx6X6x.js.map +1 -0
  10. package/dist/analytics-DmD31Ssc.js +123 -0
  11. package/dist/analytics-DmD31Ssc.js.map +1 -0
  12. package/dist/analytics-JDitS2JI.js +2 -0
  13. package/dist/bin.js +521 -46
  14. package/dist/bin.js.map +1 -1
  15. package/dist/debug-Bkaqv1ab.js +686 -0
  16. package/dist/debug-Bkaqv1ab.js.map +1 -0
  17. package/dist/{debug-CIyf0ZGx.js → debug-I5sRZubJ.js} +1 -1
  18. package/dist/{defaults-DoVkE0gW.js → defaults-GbLPuHxj.js} +8 -8
  19. package/dist/defaults-GbLPuHxj.js.map +1 -0
  20. package/dist/detection-C_RfYYDe.js +206 -0
  21. package/dist/detection-C_RfYYDe.js.map +1 -0
  22. package/dist/{env-api-key-K8TdTDII.js → env-api-key-D5G2PrXW.js} +1 -1
  23. package/dist/{env-api-key-K8TdTDII.js.map → env-api-key-D5G2PrXW.js.map} +1 -1
  24. package/dist/file-8iNrXHkG.js +16 -0
  25. package/dist/file-8iNrXHkG.js.map +1 -0
  26. package/dist/{file-utils-BWneZy6p.js → file-utils-DnTSiTJw.js} +1 -1
  27. package/dist/{file-utils-BWneZy6p.js.map → file-utils-DnTSiTJw.js.map} +1 -1
  28. package/dist/package-json-BzVey4Bd.js +2 -0
  29. package/dist/{package-json-Ctq6LSl8.js → package-json-F_7oktsp.js} +1 -1
  30. package/dist/{package-json-Ctq6LSl8.js.map → package-json-F_7oktsp.js.map} +1 -1
  31. package/dist/{package-manager-CwU26DwX.js → package-manager-qxP2PpM_.js} +2 -2
  32. package/dist/{package-manager-CwU26DwX.js.map → package-manager-qxP2PpM_.js.map} +1 -1
  33. package/dist/paths-DJS47p5x.js +26 -0
  34. package/dist/paths-DJS47p5x.js.map +1 -0
  35. package/dist/{posthog-integration-HBDZrREG.js → posthog-integration-DX77Msto.js} +43 -14
  36. package/dist/posthog-integration-DX77Msto.js.map +1 -0
  37. package/dist/posthog-vm0k9PKS.js +11 -0
  38. package/dist/posthog-vm0k9PKS.js.map +1 -0
  39. package/dist/provisioning-CHfTOEvg.js +2 -0
  40. package/dist/provisioning-DUj285NO.js +166 -0
  41. package/dist/provisioning-DUj285NO.js.map +1 -0
  42. package/dist/{registry-BIV1wRpo.js → registry-CCtIsqb8.js} +5 -6
  43. package/dist/{registry-BIV1wRpo.js.map → registry-CCtIsqb8.js.map} +1 -1
  44. package/dist/{router-CXjdWNh2.js → router-BTfmEDDJ.js} +4 -3
  45. package/dist/router-BTfmEDDJ.js.map +1 -0
  46. package/dist/{setup-utils-CHojnr4N.js → setup-utils-Bv8z6HMb.js} +17 -150
  47. package/dist/setup-utils-Bv8z6HMb.js.map +1 -0
  48. package/dist/setup-utils-CoX-vLgw.js +2 -0
  49. package/dist/{start-playground-D1iLBvqF.js → start-playground-DYNQ8rOz.js} +181 -9
  50. package/dist/start-playground-DYNQ8rOz.js.map +1 -0
  51. package/dist/{start-tui-DkT_H5zx.js → start-tui-DleQG3La.js} +1290 -163
  52. package/dist/start-tui-DleQG3La.js.map +1 -0
  53. package/dist/{steps-zpqG7W08.js → steps-C-syS8if.js} +8 -8
  54. package/dist/steps-C-syS8if.js.map +1 -0
  55. package/dist/task-stream-CX7Uf6EM.js +61 -0
  56. package/dist/task-stream-CX7Uf6EM.js.map +1 -0
  57. package/dist/{telemetry-CPoSyK0a.js → telemetry-DHZfjgqx.js} +2 -2
  58. package/dist/{telemetry-CPoSyK0a.js.map → telemetry-DHZfjgqx.js.map} +1 -1
  59. package/dist/{wizard-abort-BcEPhAxY.js → wizard-abort-DIhFXJ5N.js} +1 -1
  60. package/dist/{wizard-abort-DKctLd33.js → wizard-abort-DfhWuzaw.js} +6 -4
  61. package/dist/{wizard-abort-DKctLd33.js.map → wizard-abort-DfhWuzaw.js.map} +1 -1
  62. package/dist/wizard-session-BQC9vy9Z.js +2 -0
  63. package/dist/{wizard-session-Db6R023m.js → wizard-session-BcNJTl2I.js} +1 -1
  64. package/dist/{wizard-session-Db6R023m.js.map → wizard-session-BcNJTl2I.js.map} +1 -1
  65. package/dist/wizard-ui-YdGFRyu_.js +14 -0
  66. package/dist/wizard-ui-YdGFRyu_.js.map +1 -0
  67. package/npm-shrinkwrap.json +2 -2
  68. package/package.json +1 -1
  69. package/dist/McpScreen-LqnNwEfV.js.map +0 -1
  70. package/dist/add-mcp-server-to-clients-lfUH2pdU.js.map +0 -1
  71. package/dist/agent-runner-DHtcWn15.js.map +0 -1
  72. package/dist/agent-skill-BVjJqol6.js +0 -59
  73. package/dist/agent-skill-BVjJqol6.js.map +0 -1
  74. package/dist/analytics-Cm6i5_gc.js +0 -207
  75. package/dist/analytics-Cm6i5_gc.js.map +0 -1
  76. package/dist/analytics-CviQ_A9M.js +0 -2
  77. package/dist/debug-CyJ_3dTP.js +0 -201
  78. package/dist/debug-CyJ_3dTP.js.map +0 -1
  79. package/dist/defaults-DoVkE0gW.js.map +0 -1
  80. package/dist/detection-gcQwPKPu.js +0 -122
  81. package/dist/detection-gcQwPKPu.js.map +0 -1
  82. package/dist/package-json-BQgl5C3Z.js +0 -2
  83. package/dist/posthog-integration-HBDZrREG.js.map +0 -1
  84. package/dist/readiness-Cep84RsR.js.map +0 -1
  85. package/dist/router-CXjdWNh2.js.map +0 -1
  86. package/dist/setup-utils-CHojnr4N.js.map +0 -1
  87. package/dist/start-playground-D1iLBvqF.js.map +0 -1
  88. package/dist/start-tui-DkT_H5zx.js.map +0 -1
  89. package/dist/steps-zpqG7W08.js.map +0 -1
  90. package/dist/wizard-session-y7nf6aKH.js +0 -2
@@ -1 +0,0 @@
1
- {"version":3,"file":"setup-utils-CHojnr4N.js","names":["fs","path","generateCodeVerifier","generateCodeChallenge","fs"],"sources":["../src/utils/package-manager.ts","../src/utils/urls.ts","../src/utils/oauth.ts","../src/utils/provisioning.ts","../src/lib/api.ts","../src/utils/semver.ts","../src/utils/setup-utils.ts"],"sourcesContent":["/* eslint-disable @typescript-eslint/typedef */\nimport * as fs from 'fs';\nimport * as path from 'path';\nimport { traceStep } from '../telemetry';\nimport { getPackageDotJson, updatePackageDotJson } from './setup-utils';\nimport { analytics } from './analytics';\nimport type { WizardOptions } from './types';\n\nexport interface PackageManager {\n name: string;\n label: string;\n installCommand: string;\n buildCommand: string;\n /* The command that the package manager uses to run a script from package.json */\n runScriptCommand: string;\n flags: string;\n forceInstallFlag: string;\n detect: ({ installDir }: Pick<WizardOptions, 'installDir'>) => boolean;\n addOverride: (\n pkgName: string,\n pkgVersion: string,\n { installDir }: Pick<WizardOptions, 'installDir'>,\n ) => Promise<void>;\n}\n\nexport const BUN: PackageManager = {\n name: 'bun',\n label: 'Bun',\n installCommand: 'bun add',\n buildCommand: 'bun run build',\n runScriptCommand: 'bun run',\n flags: '',\n forceInstallFlag: '--force',\n detect: ({ installDir }: Pick<WizardOptions, 'installDir'>) =>\n ['bun.lockb', 'bun.lock'].some((lockFile) =>\n fs.existsSync(path.join(installDir, lockFile)),\n ),\n addOverride: async (\n pkgName,\n pkgVersion,\n { installDir }: Pick<WizardOptions, 'installDir'>,\n ): Promise<void> => {\n const packageDotJson = await getPackageDotJson({ installDir });\n const overrides = packageDotJson.overrides || {};\n\n await updatePackageDotJson(\n {\n ...packageDotJson,\n overrides: {\n ...overrides,\n [pkgName]: pkgVersion,\n },\n },\n { installDir: installDir },\n );\n },\n};\nexport const YARN_V1: PackageManager = {\n name: 'yarn',\n label: 'Yarn V1',\n installCommand: 'yarn add',\n buildCommand: 'yarn build',\n runScriptCommand: 'yarn',\n flags: '--ignore-workspace-root-check',\n forceInstallFlag: '--force',\n detect: ({ installDir }: Pick<WizardOptions, 'installDir'>) => {\n try {\n return fs\n .readFileSync(path.join(installDir, 'yarn.lock'), 'utf-8')\n .slice(0, 500)\n .includes('yarn lockfile v1');\n } catch (e) {\n return false;\n }\n },\n addOverride: async (\n pkgName,\n pkgVersion,\n { installDir }: Pick<WizardOptions, 'installDir'>,\n ): Promise<void> => {\n const packageDotJson = await getPackageDotJson({ installDir });\n const resolutions = packageDotJson.resolutions || {};\n\n await updatePackageDotJson(\n {\n ...packageDotJson,\n resolutions: {\n ...resolutions,\n [pkgName]: pkgVersion,\n },\n },\n { installDir },\n );\n },\n};\n/** YARN V2/3/4 */\nexport const YARN_V2: PackageManager = {\n name: 'yarn',\n label: 'Yarn V2/3/4',\n installCommand: 'yarn add',\n buildCommand: 'yarn build',\n runScriptCommand: 'yarn',\n flags: '',\n forceInstallFlag: '--force',\n detect: ({ installDir }: Pick<WizardOptions, 'installDir'>) => {\n try {\n return fs\n .readFileSync(path.join(installDir, 'yarn.lock'), 'utf-8')\n .slice(0, 500)\n .includes('__metadata');\n } catch (e) {\n return false;\n }\n },\n addOverride: async (\n pkgName,\n pkgVersion,\n { installDir }: Pick<WizardOptions, 'installDir'>,\n ): Promise<void> => {\n const packageDotJson = await getPackageDotJson({ installDir });\n const resolutions = packageDotJson.resolutions || {};\n\n await updatePackageDotJson(\n {\n ...packageDotJson,\n resolutions: {\n ...resolutions,\n [pkgName]: pkgVersion,\n },\n },\n { installDir },\n );\n },\n};\nexport const PNPM: PackageManager = {\n name: 'pnpm',\n label: 'pnpm',\n installCommand: 'pnpm add',\n buildCommand: 'pnpm build',\n runScriptCommand: 'pnpm',\n flags: '--ignore-workspace-root-check',\n forceInstallFlag: '--force',\n detect: ({ installDir }: Pick<WizardOptions, 'installDir'>) =>\n fs.existsSync(path.join(installDir, 'pnpm-lock.yaml')),\n addOverride: async (\n pkgName,\n pkgVersion,\n { installDir }: Pick<WizardOptions, 'installDir'>,\n ): Promise<void> => {\n const packageDotJson = await getPackageDotJson({ installDir });\n const pnpm = packageDotJson.pnpm || {};\n const overrides = pnpm.overrides || {};\n\n await updatePackageDotJson(\n {\n ...packageDotJson,\n pnpm: {\n ...pnpm,\n overrides: {\n ...overrides,\n [pkgName]: pkgVersion,\n },\n },\n },\n { installDir },\n );\n },\n};\nexport const NPM: PackageManager = {\n name: 'npm',\n label: 'npm',\n installCommand: 'npm add',\n buildCommand: 'npm run build',\n runScriptCommand: 'npm run',\n flags: '',\n forceInstallFlag: '--force',\n detect: ({ installDir }: Pick<WizardOptions, 'installDir'>) =>\n fs.existsSync(path.join(installDir, 'package-lock.json')),\n addOverride: async (\n pkgName,\n pkgVersion,\n { installDir }: Pick<WizardOptions, 'installDir'>,\n ): Promise<void> => {\n const packageDotJson = await getPackageDotJson({ installDir });\n const overrides = packageDotJson.overrides || {};\n\n await updatePackageDotJson(\n {\n ...packageDotJson,\n overrides: {\n ...overrides,\n [pkgName]: pkgVersion,\n },\n },\n { installDir },\n );\n },\n};\n\nexport const EXPO: PackageManager = {\n name: 'expo',\n label: 'Expo',\n installCommand: 'npx expo install',\n buildCommand: 'npx expo build',\n runScriptCommand: 'npx expo run',\n flags: '',\n forceInstallFlag: '--force',\n detect: () => false,\n addOverride: async (\n pkgName,\n pkgVersion,\n { installDir }: Pick<WizardOptions, 'installDir'>,\n ): Promise<void> => {\n const packageDotJson = await getPackageDotJson({ installDir });\n const overrides = packageDotJson.overrides || {};\n\n await updatePackageDotJson(\n {\n ...packageDotJson,\n overrides: {\n ...overrides,\n [pkgName]: pkgVersion,\n },\n },\n { installDir },\n );\n },\n};\n\nexport const packageManagers = [BUN, YARN_V1, YARN_V2, PNPM, NPM, EXPO];\n\nexport function detectAllPackageManagers({\n installDir,\n}: Pick<WizardOptions, 'installDir'>): PackageManager[] {\n return traceStep('detect-package-manager', () => {\n const detectedManagers: PackageManager[] = [];\n for (const packageManager of packageManagers) {\n if (packageManager.detect({ installDir })) {\n detectedManagers.push(packageManager);\n }\n }\n\n if (detectedManagers.length === 0) {\n analytics.setTag('package-manager', 'not-detected');\n }\n return detectedManagers;\n });\n}\n","import axios from 'axios';\nimport { IS_DEV, WIZARD_USER_AGENT } from '../lib/constants';\nimport type { CloudRegion } from './types';\n\nexport const getAssetHostFromHost = (host: string) => {\n if (host.includes('us.i.posthog.com')) {\n return 'https://us-assets.i.posthog.com';\n }\n\n if (host.includes('eu.i.posthog.com')) {\n return 'https://eu-assets.i.posthog.com';\n }\n\n return host;\n};\n\nexport const getUiHostFromHost = (host: string) => {\n if (host.includes('us.i.posthog.com')) {\n return 'https://us.posthog.com';\n }\n\n if (host.includes('eu.i.posthog.com')) {\n return 'https://eu.posthog.com';\n }\n\n return host;\n};\n\nexport const getHostFromRegion = (region: CloudRegion) => {\n if (IS_DEV) {\n return 'http://localhost:8010';\n }\n\n if (region === 'eu') {\n return 'https://eu.i.posthog.com';\n }\n\n return 'https://us.i.posthog.com';\n};\n\nexport const getCloudUrlFromRegion = (region: CloudRegion) => {\n if (IS_DEV) {\n return 'http://localhost:8010';\n }\n\n if (region === 'eu') {\n return 'https://eu.posthog.com';\n }\n\n return 'https://us.posthog.com';\n};\n\nexport async function detectRegionFromToken(\n accessToken: string,\n): Promise<CloudRegion> {\n if (IS_DEV) {\n return 'us';\n }\n\n const headers = {\n Authorization: `Bearer ${accessToken}`,\n 'User-Agent': WIZARD_USER_AGENT,\n };\n\n const [usResult, euResult] = await Promise.allSettled([\n axios.get('https://us.posthog.com/api/users/@me/', { headers }),\n axios.get('https://eu.posthog.com/api/users/@me/', { headers }),\n ]);\n\n if (usResult.status === 'fulfilled') return 'us';\n if (euResult.status === 'fulfilled') return 'eu';\n\n throw new Error(\n 'Could not determine cloud region from access token. Please check your PostHog account.',\n );\n}\n\nexport const getLlmGatewayUrlFromHost = (host: string) => {\n if (host.includes('localhost')) {\n return 'http://localhost:3308/wizard';\n }\n\n if (host.includes('eu.posthog.com') || host.includes('eu.i.posthog.com')) {\n return 'https://gateway.eu.posthog.com/wizard';\n }\n\n return 'https://gateway.us.posthog.com/wizard';\n};\n","import * as crypto from 'node:crypto';\nimport * as http from 'node:http';\nimport { execSync } from 'node:child_process';\nimport axios from 'axios';\nimport { logToFile } from './debug';\nimport opn from 'opn';\nimport { z } from 'zod';\nimport { getUI } from '../ui';\nimport {\n IS_DEV,\n ISSUES_URL,\n OAUTH_PORTS,\n OAUTH_TIMEOUT_MS,\n POSTHOG_DEV_CLIENT_ID,\n POSTHOG_OAUTH_URL,\n POSTHOG_PROXY_CLIENT_ID,\n WIZARD_USER_AGENT,\n} from '../lib/constants';\nimport { NODE_ENV } from '@env';\nimport { abort } from './setup-utils';\nimport { analytics } from './analytics';\n\nconst OAUTH_CALLBACK_STYLES = `\n <style>\n * {\n font-family: monospace;\n background-color: #1b0a00;\n color: #F7A502;\n font-weight: medium;\n font-size: 24px;\n margin: .25rem;\n }\n\n .blink {\n animation: blink-animation 1s steps(2, start) infinite;\n }\n\n @keyframes blink-animation {\n to {\n opacity: 0;\n }\n }\n </style>\n`;\n\nconst OAuthTokenResponseSchema = z.object({\n access_token: z.string(),\n expires_in: z.number(),\n token_type: z.string(),\n scope: z.string(),\n refresh_token: z.string(),\n scoped_teams: z.array(z.number()).optional(),\n scoped_organizations: z.array(z.string()).optional(),\n});\n\nexport type OAuthTokenResponse = z.infer<typeof OAuthTokenResponseSchema>;\n\ninterface OAuthConfig {\n scopes: string[];\n signup?: boolean;\n}\n\nfunction getLocalOAuthOrigin(port: number): string {\n return `http://localhost:${port}`;\n}\n\nfunction getCallbackUrl(port: number): string {\n return `${getLocalOAuthOrigin(port)}/callback`;\n}\n\nfunction getLocalLoginUrl(port: number): string {\n return `${getLocalOAuthOrigin(port)}/authorize`;\n}\n\nfunction getLocalSignupUrl(port: number): string {\n return `${getLocalLoginUrl(port)}?signup=true`;\n}\n\nfunction generateCodeVerifier(): string {\n return crypto.randomBytes(32).toString('base64url');\n}\n\nfunction generateCodeChallenge(verifier: string): string {\n return crypto.createHash('sha256').update(verifier).digest('base64url');\n}\n\nasync function startCallbackServer(\n authUrl: string,\n signupUrl: string,\n port: number,\n): Promise<{\n port: number;\n server: http.Server;\n waitForCallback: () => Promise<string>;\n}> {\n return new Promise((resolve, reject) => {\n let callbackResolve: (code: string) => void;\n let callbackReject: (error: Error) => void;\n\n const waitForCallback = () =>\n new Promise<string>((res, rej) => {\n callbackResolve = res;\n callbackReject = rej;\n });\n\n const server = http.createServer((req, res) => {\n if (!req.url) {\n res.writeHead(400);\n res.end();\n return;\n }\n const url = new URL(req.url, getLocalOAuthOrigin(port));\n\n if (url.pathname === '/authorize') {\n const isSignup = url.searchParams.get('signup') === 'true';\n const redirectUrl = isSignup ? signupUrl : authUrl;\n res.writeHead(302, { Location: redirectUrl });\n res.end();\n return;\n }\n\n const code = url.searchParams.get('code');\n const error = url.searchParams.get('error');\n\n if (error) {\n const isAccessDenied = error === 'access_denied';\n res.writeHead(isAccessDenied ? 200 : 400, {\n 'Content-Type': 'text/html; charset=utf-8',\n });\n res.end(`\n <html>\n <head>\n <meta charset=\"UTF-8\">\n <title>PostHog wizard - Authorization ${\n isAccessDenied ? 'cancelled' : 'failed'\n }</title>\n ${OAUTH_CALLBACK_STYLES}\n </head>\n <body>\n <p>${\n isAccessDenied\n ? 'Authorization cancelled.'\n : `Authorization failed.`\n }</p>\n <p>Return to your terminal. This window will close automatically.</p>\n <script>window.close();</script>\n </body>\n </html>\n `);\n callbackReject(new Error(`OAuth error: ${error}`));\n return;\n }\n\n if (code) {\n res.writeHead(200, { 'Content-Type': 'text/html; charset=utf-8' });\n res.end(`\n <html>\n <head>\n <meta charset=\"UTF-8\">\n <title>PostHog wizard is ready</title>\n ${OAUTH_CALLBACK_STYLES}\n </head>\n <body>\n <p>PostHog login complete!</p>\n <p>Return to your terminal: the wizard is hard at work on your project<span class=\"blink\">█</span></p>\n <script>window.close();</script>\n </body>\n </html>\n `);\n callbackResolve(code);\n } else {\n res.writeHead(400, { 'Content-Type': 'text/html; charset=utf-8' });\n res.end(`\n <html>\n <head>\n <meta charset=\"UTF-8\">\n <title>PostHog wizard - Invalid request</title>\n ${OAUTH_CALLBACK_STYLES}\n </head>\n <body>\n <p>Invalid request - no authorization code received.</p>\n <p>You can close this window.</p>\n </body>\n </html>\n `);\n }\n });\n\n server.listen(port, () => {\n resolve({ port, server, waitForCallback });\n });\n\n server.on('error', reject);\n });\n}\n\nfunction getPortProcessInfo(port: number): {\n command: string;\n pid: string;\n port: number;\n user: string;\n} {\n try {\n const output = execSync(`lsof -i :${port} -sTCP:LISTEN 2>/dev/null`, {\n encoding: 'utf-8',\n timeout: 3000,\n }).trim();\n const lines = output.split('\\n');\n // First line is header, second is the process\n if (lines.length < 2)\n return { command: 'unknown', pid: 'unknown', port, user: 'unknown' };\n const fields = lines[1].split(/\\s+/);\n // lsof columns: COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME\n const command = fields[0] ?? 'unknown';\n const pid = fields[1] ?? 'unknown';\n const user = fields[2] ?? 'unknown';\n return { command, pid, port, user };\n } catch {\n return { command: 'unknown', pid: 'unknown', port, user: 'unknown' };\n }\n}\n\nfunction isPortInUseError(error: unknown): boolean {\n return (\n error instanceof Error &&\n 'code' in error &&\n (error as NodeJS.ErrnoException).code === 'EADDRINUSE'\n );\n}\n\nasync function exchangeCodeForToken(\n code: string,\n codeVerifier: string,\n callbackUrl: string,\n): Promise<OAuthTokenResponse> {\n const clientId = IS_DEV ? POSTHOG_DEV_CLIENT_ID : POSTHOG_PROXY_CLIENT_ID;\n\n const response = await axios.post(\n `${POSTHOG_OAUTH_URL}/oauth/token`,\n {\n grant_type: 'authorization_code',\n code,\n redirect_uri: callbackUrl,\n client_id: clientId,\n code_verifier: codeVerifier,\n },\n {\n headers: {\n 'Content-Type': 'application/json',\n 'User-Agent': WIZARD_USER_AGENT,\n },\n },\n );\n\n return OAuthTokenResponseSchema.parse(response.data);\n}\n\nexport async function performOAuthFlow(\n config: OAuthConfig,\n): Promise<OAuthTokenResponse> {\n const clientId = IS_DEV ? POSTHOG_DEV_CLIENT_ID : POSTHOG_PROXY_CLIENT_ID;\n const codeVerifier = generateCodeVerifier();\n const codeChallenge = generateCodeChallenge(codeVerifier);\n let shouldRetry = false;\n\n do {\n shouldRetry = false;\n let lastProcessInfo: {\n command: string;\n pid: string;\n port: number;\n user: string;\n } | null = null;\n\n for (const port of OAUTH_PORTS) {\n const callbackUrl = getCallbackUrl(port);\n const authUrl = new URL(`${POSTHOG_OAUTH_URL}/oauth/authorize`);\n authUrl.searchParams.set('client_id', clientId);\n authUrl.searchParams.set('redirect_uri', callbackUrl);\n authUrl.searchParams.set('response_type', 'code');\n authUrl.searchParams.set('code_challenge', codeChallenge);\n authUrl.searchParams.set('code_challenge_method', 'S256');\n authUrl.searchParams.set('scope', config.scopes.join(' '));\n authUrl.searchParams.set('required_access_level', 'project');\n\n const signupUrl = new URL(\n `${POSTHOG_OAUTH_URL}/signup?next=${encodeURIComponent(\n authUrl.toString(),\n )}`,\n );\n const localSignupUrl = getLocalSignupUrl(port);\n const localLoginUrl = getLocalLoginUrl(port);\n const urlToOpen = config.signup ? localSignupUrl : localLoginUrl;\n\n logToFile(`[oauth] attempting callback server on port ${port}`);\n\n let server: http.Server;\n let waitForCallback: () => Promise<string>;\n try {\n ({ server, waitForCallback } = await startCallbackServer(\n authUrl.toString(),\n signupUrl.toString(),\n port,\n ));\n } catch (e) {\n if (!isPortInUseError(e)) throw e;\n lastProcessInfo = getPortProcessInfo(port);\n continue;\n }\n\n logToFile('[oauth] callback server ready, showing login URL');\n\n getUI().setLoginUrl(urlToOpen);\n\n if (NODE_ENV !== 'test') {\n opn(urlToOpen, { wait: false }).catch(() => {\n // opn throws in environments without a browser\n });\n }\n\n const loginSpinner = getUI().spinner();\n loginSpinner.start('Waiting for authorization...');\n\n try {\n const code = await Promise.race([\n waitForCallback(),\n new Promise<never>((_, reject) =>\n setTimeout(\n () => reject(new Error('Authorization timed out')),\n OAUTH_TIMEOUT_MS,\n ),\n ),\n ]);\n\n const token = await exchangeCodeForToken(\n code,\n codeVerifier,\n callbackUrl,\n );\n\n server.close();\n getUI().setLoginUrl(null);\n loginSpinner.stop('Authorization complete!');\n\n return token;\n } catch (e) {\n loginSpinner.stop('Authorization failed.');\n server.close();\n\n const error = e instanceof Error ? e : new Error('Unknown error');\n\n if (error.message.includes('timeout')) {\n getUI().log.error('Authorization timed out. Please try again.');\n } else if (error.message.includes('access_denied')) {\n getUI().log.info(\n `Authorization was cancelled.\\n\\nYou denied access to PostHog. To use the wizard, you need to authorize access to your PostHog account.\\n\\nYou can try again by re-running the wizard.`,\n );\n } else {\n getUI().log.error(\n `Authorization failed:\\n\\n${error.message}\\n\\nIf you think this is a bug in the PostHog wizard, please create an issue:\\n${ISSUES_URL}`,\n );\n }\n\n analytics.captureException(error, {\n step: 'oauth_flow',\n });\n\n await abort();\n throw error;\n }\n }\n\n if (!lastProcessInfo) {\n throw new Error('No OAuth callback ports configured');\n }\n\n await getUI().showPortConflict(lastProcessInfo);\n shouldRetry = true;\n } while (shouldRetry);\n\n throw new Error('OAuth port retry loop exited unexpectedly');\n}\n","/**\n * Provisioning API client for creating new PostHog accounts.\n *\n * Uses the agentic provisioning API with PKCE auth:\n * 1. POST /account_requests - create account, get auth code\n * 2. POST /oauth/token - exchange code for tokens (with PKCE)\n * 3. POST /resources - provision project, get API key\n */\n\nimport * as crypto from 'node:crypto';\nimport axios from 'axios';\nimport { z } from 'zod';\nimport {\n IS_DEV,\n POSTHOG_DEV_CLIENT_ID,\n POSTHOG_US_CLIENT_ID,\n WIZARD_USER_AGENT,\n} from '../lib/constants';\nimport { logToFile } from './debug';\nimport { analytics } from './analytics';\n\nconst WIZARD_CLIENT_ID = IS_DEV ? POSTHOG_DEV_CLIENT_ID : POSTHOG_US_CLIENT_ID;\nconst API_VERSION = '0.1d';\n\nconst PROVISIONING_BASE_URL = IS_DEV\n ? 'http://localhost:8010'\n : 'https://us.posthog.com';\n\nfunction generateCodeVerifier(): string {\n return crypto.randomBytes(32).toString('base64url');\n}\n\nfunction generateCodeChallenge(verifier: string): string {\n return crypto.createHash('sha256').update(verifier).digest('base64url');\n}\n\n// --- Response schemas ---\n\nconst AccountRequestResponseSchema = z.object({\n id: z.string(),\n type: z.enum(['oauth', 'requires_auth', 'error']),\n oauth: z\n .object({\n code: z.string(),\n })\n .optional(),\n error: z\n .object({\n code: z.string(),\n message: z.string(),\n })\n .optional(),\n});\n\nconst TokenResponseSchema = z.object({\n token_type: z.string(),\n access_token: z.string(),\n refresh_token: z.string(),\n expires_in: z.number(),\n account: z\n .object({\n id: z.string(),\n })\n .optional(),\n});\n\nconst ResourceResponseSchema = z.object({\n status: z.string(),\n id: z.string(),\n service_id: z.string(),\n complete: z\n .object({\n access_configuration: z.object({\n api_key: z.string(),\n host: z.string(),\n personal_api_key: z.string().optional(),\n }),\n })\n .optional(),\n});\n\nexport interface ProvisioningResult {\n accessToken: string;\n refreshToken: string;\n projectApiKey: string;\n host: string;\n personalApiKey?: string;\n projectId: string;\n accountId: string;\n}\n\n/**\n * Create a new PostHog account and provision a project via the provisioning API.\n *\n * This is the \"no browser\" signup path: the wizard collects the email,\n * calls the provisioning API to create the account, and gets back\n * credentials without opening a browser.\n */\nexport async function provisionNewAccount(\n email: string,\n name: string,\n region: 'US' | 'EU' = 'US',\n opts?: { orgName?: string; projectName?: string },\n): Promise<ProvisioningResult> {\n const codeVerifier = generateCodeVerifier();\n const codeChallenge = generateCodeChallenge(codeVerifier);\n\n logToFile('[provisioning] starting account creation');\n\n // Step 1: Create account\n const accountRes = await axios.post(\n `${PROVISIONING_BASE_URL}/api/agentic/provisioning/account_requests`,\n {\n id: crypto.randomUUID(),\n email,\n name,\n client_id: WIZARD_CLIENT_ID,\n code_challenge: codeChallenge,\n code_challenge_method: 'S256',\n configuration: {\n region,\n ...(opts?.orgName ? { organization_name: opts.orgName } : {}),\n },\n },\n {\n headers: {\n 'Content-Type': 'application/json',\n 'API-Version': API_VERSION,\n 'User-Agent': WIZARD_USER_AGENT,\n },\n timeout: 30_000,\n },\n );\n\n const accountData = AccountRequestResponseSchema.parse(accountRes.data);\n\n if (accountData.type === 'error') {\n const msg = accountData.error?.message ?? 'Account creation failed';\n analytics.captureException(new Error(msg), {\n step: 'provisioning_account_request',\n error_code: accountData.error?.code,\n });\n throw new Error(msg);\n }\n\n if (accountData.type === 'requires_auth') {\n throw new Error(\n 'This email is already associated with a PostHog account. Please use the login flow instead.',\n );\n }\n\n const code = accountData.oauth?.code;\n if (!code) {\n throw new Error('No authorization code received from account creation');\n }\n\n logToFile('[provisioning] account created, exchanging code for tokens');\n\n // Step 2: Exchange code for tokens\n const tokenRes = await axios.post(\n `${PROVISIONING_BASE_URL}/api/agentic/oauth/token`,\n new URLSearchParams({\n grant_type: 'authorization_code',\n code,\n code_verifier: codeVerifier,\n }).toString(),\n {\n headers: {\n 'Content-Type': 'application/x-www-form-urlencoded',\n 'API-Version': API_VERSION,\n 'User-Agent': WIZARD_USER_AGENT,\n },\n timeout: 30_000,\n },\n );\n\n const tokenData = TokenResponseSchema.parse(tokenRes.data);\n\n logToFile('[provisioning] tokens received, provisioning resources');\n\n // Step 3: Provision resources\n const resourceRes = await axios.post(\n `${PROVISIONING_BASE_URL}/api/agentic/provisioning/resources`,\n {\n service_id: 'analytics',\n ...(opts?.projectName\n ? { configuration: { project_name: opts.projectName } }\n : {}),\n },\n {\n headers: {\n 'Content-Type': 'application/json',\n Authorization: `Bearer ${tokenData.access_token}`,\n 'API-Version': API_VERSION,\n 'User-Agent': WIZARD_USER_AGENT,\n },\n timeout: 30_000,\n },\n );\n\n const resourceData = ResourceResponseSchema.parse(resourceRes.data);\n\n if (resourceData.status !== 'complete' || !resourceData.complete) {\n throw new Error('Resource provisioning did not complete');\n }\n\n logToFile('[provisioning] resources provisioned successfully');\n\n return {\n accessToken: tokenData.access_token,\n refreshToken: tokenData.refresh_token,\n projectApiKey: resourceData.complete.access_configuration.api_key,\n host: resourceData.complete.access_configuration.host,\n personalApiKey: resourceData.complete.access_configuration.personal_api_key,\n projectId: resourceData.id,\n accountId: tokenData.account?.id ?? '',\n };\n}\n","import axios, { AxiosError } from 'axios';\nimport { z } from 'zod';\nimport { analytics } from '../utils/analytics';\nimport { WIZARD_USER_AGENT } from './constants';\n\nexport const ApiUserSchema = z.object({\n distinct_id: z.string(),\n organizations: z.array(\n z.object({\n id: z.string().uuid(),\n }),\n ),\n team: z.object({\n id: z.number(),\n organization: z.string().uuid(),\n }),\n organization: z.object({\n id: z.string().uuid(),\n }),\n});\n\nexport const ApiProjectSchema = z.object({\n id: z.number(),\n uuid: z.string().uuid(),\n organization: z.string().uuid(),\n api_token: z.string(),\n name: z.string(),\n});\n\nexport type ApiUser = z.infer<typeof ApiUserSchema>;\nexport type ApiProject = z.infer<typeof ApiProjectSchema>;\n\nclass ApiError extends Error {\n constructor(\n message: string,\n public readonly statusCode?: number,\n public readonly endpoint?: string,\n ) {\n super(message);\n this.name = 'ApiError';\n }\n}\n\nexport async function fetchUserData(\n accessToken: string,\n baseUrl: string,\n): Promise<ApiUser> {\n try {\n const response = await axios.get(`${baseUrl}/api/users/@me/`, {\n headers: {\n Authorization: `Bearer ${accessToken}`,\n 'User-Agent': WIZARD_USER_AGENT,\n },\n });\n\n return ApiUserSchema.parse(response.data);\n } catch (error) {\n const apiError = handleApiError(error, 'fetch user data');\n analytics.captureException(apiError, {\n endpoint: '/api/users/@me/',\n baseUrl,\n });\n throw apiError;\n }\n}\n\nexport async function fetchProjectData(\n accessToken: string,\n projectId: number,\n baseUrl: string,\n): Promise<ApiProject> {\n try {\n const response = await axios.get(`${baseUrl}/api/projects/${projectId}/`, {\n headers: {\n Authorization: `Bearer ${accessToken}`,\n 'User-Agent': WIZARD_USER_AGENT,\n },\n });\n\n return ApiProjectSchema.parse(response.data);\n } catch (error) {\n const apiError = handleApiError(error, 'fetch project data');\n analytics.captureException(apiError, {\n endpoint: `/api/projects/${projectId}/`,\n baseUrl,\n projectId,\n });\n throw apiError;\n }\n}\n\nfunction handleApiError(error: unknown, operation: string): ApiError {\n if (axios.isAxiosError(error)) {\n const axiosError = error as AxiosError<{ detail?: string }>;\n const status = axiosError.response?.status;\n const detail = axiosError.response?.data?.detail;\n const endpoint = axiosError.config?.url;\n\n if (status === 401) {\n return new ApiError(\n `Authentication failed while trying to ${operation}`,\n status,\n endpoint,\n );\n }\n\n if (status === 403) {\n return new ApiError(\n `Access denied while trying to ${operation}`,\n status,\n endpoint,\n );\n }\n\n if (status === 404) {\n return new ApiError(\n `Resource not found while trying to ${operation}`,\n status,\n endpoint,\n );\n }\n\n const message = detail || `Failed to ${operation}`;\n return new ApiError(message, status, endpoint);\n }\n\n if (error instanceof z.ZodError) {\n return new ApiError(`Invalid response format while trying to ${operation}`);\n }\n\n return new ApiError(\n `Unexpected error while trying to ${operation}: ${\n error instanceof Error ? error.message : 'Unknown error'\n }`,\n );\n}\n","import {\n major,\n minVersion,\n satisfies,\n subset,\n valid,\n validRange,\n} from 'semver';\n\n/**\n * Version strings from package.json that are not semver ranges.\n * URLs, git refs, dist-tags, local paths, workspace protocol, npm aliases, etc.\n * These should be rejected early — we can't determine a clear version from them.\n */\nfunction isNonSemverVersion(version: string): boolean {\n const v = version.trim();\n return (\n v === '' ||\n v.startsWith('http://') ||\n v.startsWith('https://') ||\n v.startsWith('git+') ||\n v.startsWith('git://') ||\n v.startsWith('file:') ||\n v.startsWith('npm:') ||\n v.startsWith('workspace:') ||\n v.startsWith('/') ||\n v.includes('/') // user/repo shorthand\n );\n}\n\nexport function fulfillsVersionRange({\n version,\n acceptableVersions,\n canBeLatest,\n}: {\n version: string;\n acceptableVersions: string;\n canBeLatest: boolean;\n}): boolean {\n if (version === 'latest') {\n return canBeLatest;\n }\n\n if (isNonSemverVersion(version)) {\n return false;\n }\n\n let cleanedUserVersion, isRange;\n\n if (valid(version)) {\n cleanedUserVersion = valid(version);\n isRange = false;\n } else if (validRange(version)) {\n cleanedUserVersion = validRange(version);\n isRange = true;\n }\n\n return (\n // If the given version is a bogus format, this will still be undefined and we'll automatically reject it\n !!cleanedUserVersion &&\n (isRange\n ? subset(cleanedUserVersion, acceptableVersions)\n : satisfies(cleanedUserVersion, acceptableVersions))\n );\n}\n\n/**\n * Creates a version bucket function for analytics.\n * Converts versions like \"1.2.3\" to \"1.x\" for grouping in analytics.\n *\n * @param minMajorVersion - Optional minimum major version threshold.\n * Versions below this will be bucketed as \"<{min}.0.0\"\n *\n * @example\n * const getVersionBucket = createVersionBucket(); // no minimum\n * getVersionBucket(\"1.2.3\") // \"1.x\"\n *\n * const getVersionBucket = createVersionBucket(11);\n * getVersionBucket(\"15.3.0\") // \"15.x\"\n * getVersionBucket(\"10.0.0\") // \"<11.0.0\"\n */\nexport function createVersionBucket(minMajorVersion?: number) {\n return (version: string | undefined): string => {\n if (!version) {\n return 'none';\n }\n\n if (isNonSemverVersion(version)) {\n return 'unknown';\n }\n\n try {\n const minVer = minVersion(version);\n if (!minVer) {\n return 'invalid';\n }\n const majorVersion = major(minVer);\n if (minMajorVersion !== undefined && majorVersion < minMajorVersion) {\n return `<${minMajorVersion}.0.0`;\n }\n return `${majorVersion}.x`;\n } catch {\n return 'unknown';\n }\n };\n}\n","import * as childProcess from 'node:child_process';\nimport * as fs from 'node:fs';\nimport * as os from 'node:os';\nimport { basename, isAbsolute, join, relative } from 'node:path';\n\nimport { traceStep } from '../telemetry';\nimport { debug } from './debug';\nimport type { PackageDotJson } from './package-json';\nimport {\n type PackageManager,\n detectAllPackageManagers,\n NPM as npm,\n} from './package-manager';\nimport type { CloudRegion, WizardOptions } from './types';\nimport { getPackageVersion } from './package-json';\nimport {\n DEFAULT_HOST_URL,\n DUMMY_PROJECT_API_KEY,\n ISSUES_URL,\n} from '../lib/constants';\nimport { analytics } from './analytics';\nimport { getUI } from '../ui';\nimport {\n getCloudUrlFromRegion,\n getHostFromRegion,\n detectRegionFromToken,\n} from './urls';\nimport { performOAuthFlow } from './oauth';\nimport { provisionNewAccount } from './provisioning';\nimport { fetchUserData, fetchProjectData } from '../lib/api';\nimport { fulfillsVersionRange } from './semver';\nimport { wizardAbort } from './wizard-abort';\n\ninterface ProjectData {\n projectApiKey: string;\n accessToken: string;\n host: string;\n distinctId: string;\n projectId: number;\n}\n\nexport interface CliSetupConfig {\n filename: string;\n name: string;\n gitignore: boolean;\n\n likelyAlreadyHasAuthToken(contents: string): boolean;\n tokenContent(authToken: string): string;\n\n likelyAlreadyHasOrgAndProject(contents: string): boolean;\n orgAndProjContent(org: string, project: string): string;\n\n likelyAlreadyHasUrl?(contents: string): boolean;\n urlContent?(url: string): string;\n}\n\nexport interface CliSetupConfigContent {\n authToken: string;\n org?: string;\n project?: string;\n url?: string;\n}\n\n/** @deprecated Use wizardAbort() directly for new code. */\nexport async function abort(message?: string, status?: number): Promise<never> {\n return wizardAbort({ message, exitCode: status });\n}\n\nexport function isInGitRepo() {\n try {\n childProcess.execSync('git rev-parse --is-inside-work-tree', {\n stdio: 'ignore',\n });\n return true;\n } catch {\n return false;\n }\n}\n\nconst FREEMAIL_DOMAINS = new Set([\n 'gmail.com',\n 'googlemail.com',\n 'hotmail.com',\n 'outlook.com',\n 'yahoo.com',\n 'icloud.com',\n 'me.com',\n 'mail.com',\n 'protonmail.com',\n 'proton.me',\n 'live.com',\n 'aol.com',\n 'yandex.com',\n 'zoho.com',\n 'gmx.com',\n 'fastmail.com',\n]);\n\nfunction parseGitRemote(): { org: string; repo: string } | null {\n try {\n const url = childProcess\n .execSync('git remote get-url origin', {\n stdio: ['ignore', 'pipe', 'ignore'],\n })\n .toString()\n .trim();\n // git@github.com:acme-corp/my-app.git or https://github.com/acme-corp/my-app.git\n const match = url.match(/[/:]([\\w.-]+)\\/([\\w.-]+?)(?:\\.git)?$/);\n if (match) return { org: match[1], repo: match[2] };\n } catch {\n // not in a git repo or no remote\n }\n return null;\n}\n\nexport function detectOrgAndProject(email: string): {\n orgName: string | undefined;\n projectName: string | undefined;\n} {\n const remote = parseGitRemote();\n\n // Project name: git repo name > directory name\n const projectName = remote?.repo || basename(process.cwd()) || undefined;\n\n // Org name: git remote org > email domain (skip freemail)\n let orgName: string | undefined;\n if (remote?.org) {\n orgName = remote.org;\n } else {\n const domain = email.split('@')[1]?.toLowerCase();\n if (domain && !FREEMAIL_DOMAINS.has(domain)) {\n orgName = domain.split('.')[0];\n }\n }\n\n return { orgName, projectName };\n}\n\nexport function getUncommittedOrUntrackedFiles(): string[] {\n try {\n const gitStatus = childProcess\n .execSync('git status --porcelain=v1', {\n // we only care about stdout\n stdio: ['ignore', 'pipe', 'ignore'],\n })\n .toString();\n\n const files = gitStatus\n .split(os.EOL)\n .map((line) => line.trim())\n .filter(Boolean)\n .map((f) => `- ${f.split(/\\s+/)[1]}`);\n\n return files;\n } catch {\n return [];\n }\n}\n\nexport async function isReact19Installed({\n installDir,\n}: Pick<WizardOptions, 'installDir'>): Promise<boolean> {\n try {\n const packageJson = await tryGetPackageJson({ installDir });\n if (!packageJson) return false;\n const reactVersion = getPackageVersion('react', packageJson);\n\n if (!reactVersion) {\n return false;\n }\n\n return fulfillsVersionRange({\n version: reactVersion,\n acceptableVersions: '>=19.0.0',\n canBeLatest: true,\n });\n } catch {\n return false;\n }\n}\n\n/**\n * Installs or updates a package with the user's package manager.\n *\n * IMPORTANT: This function modifies the `package.json`! Be sure to re-read\n * it if you make additional modifications to it after calling this function!\n */\nexport async function installPackage({\n packageName,\n alreadyInstalled,\n packageNameDisplayLabel,\n packageManager,\n forceInstall = false,\n integration,\n installDir,\n}: {\n packageName: string;\n alreadyInstalled: boolean;\n packageNameDisplayLabel?: string;\n packageManager?: PackageManager;\n forceInstall?: boolean;\n integration?: string;\n installDir: string;\n}): Promise<{ packageManager?: PackageManager }> {\n return traceStep('install-package', async () => {\n const sdkInstallSpinner = getUI().spinner();\n\n const pkgManager =\n packageManager || (await getPackageManager({ installDir }));\n\n const isReact19 = await isReact19Installed({ installDir });\n const legacyPeerDepsFlag =\n isReact19 && pkgManager.name === 'npm' ? '--legacy-peer-deps' : '';\n\n sdkInstallSpinner.start(\n `${alreadyInstalled ? 'Updating' : 'Installing'} ${\n packageNameDisplayLabel ?? packageName\n } with ${pkgManager.label}.`,\n );\n\n try {\n await new Promise<void>((resolve, reject) => {\n childProcess.exec(\n `${pkgManager.installCommand} ${packageName} ${pkgManager.flags} ${\n forceInstall ? pkgManager.forceInstallFlag : ''\n } ${legacyPeerDepsFlag}`.trim(),\n { cwd: installDir },\n (err, stdout, stderr) => {\n if (err) {\n fs.writeFileSync(\n join(\n process.cwd(),\n `posthog-wizard-installation-error-${Date.now()}.log`,\n ),\n JSON.stringify({\n stdout,\n stderr,\n }),\n { encoding: 'utf8' },\n );\n\n reject(err);\n } else {\n resolve();\n }\n },\n );\n });\n } catch (e) {\n sdkInstallSpinner.stop('Installation failed.');\n getUI().log.error(\n // eslint-disable-next-line @typescript-eslint/restrict-template-expressions\n `Encountered the following error during installation:\\n\\n${e}\\n\\nThe wizard has created a \\`posthog-wizard-installation-error-*.log\\` file. If you think this issue is caused by the PostHog wizard, create an issue on GitHub and include the log file's content:\\n${ISSUES_URL}`,\n );\n await abort();\n }\n\n sdkInstallSpinner.stop(\n `${alreadyInstalled ? 'Updated' : 'Installed'} ${\n packageNameDisplayLabel ?? packageName\n } with ${pkgManager.label}.`,\n );\n\n analytics.wizardCapture('package installed', {\n package_name: packageName,\n package_manager: pkgManager.name,\n integration,\n });\n\n return { packageManager: pkgManager };\n });\n}\n\n/**\n * Get package.json or abort the wizard if not found.\n * Only use where package.json is required (e.g., package install, overrides).\n * For detection/version-checks, use tryGetPackageJson() instead.\n */\nexport async function getPackageDotJson({\n installDir,\n}: Pick<WizardOptions, 'installDir'>): Promise<PackageDotJson> {\n const packageJsonFileContents = await fs.promises\n .readFile(join(installDir, 'package.json'), 'utf8')\n .catch(() => {\n getUI().log.error(\n 'Could not find package.json. Make sure to run the wizard in the root of your app!',\n );\n return abort();\n });\n\n let packageJson: PackageDotJson | undefined = undefined;\n\n try {\n // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment\n packageJson = JSON.parse(packageJsonFileContents);\n } catch {\n getUI().log.error(\n `Unable to parse your package.json. Make sure it has a valid format!`,\n );\n\n await abort();\n }\n\n return packageJson || {};\n}\n\n/**\n * Try to get package.json, returning null if it doesn't exist.\n * Use this for detection purposes where missing package.json is expected (e.g., Python projects).\n */\nexport async function tryGetPackageJson({\n installDir,\n}: Pick<WizardOptions, 'installDir'>): Promise<PackageDotJson | null> {\n try {\n const packageJsonFileContents = await fs.promises.readFile(\n join(installDir, 'package.json'),\n 'utf8',\n );\n return JSON.parse(packageJsonFileContents) as PackageDotJson;\n } catch {\n return null;\n }\n}\n\nexport async function updatePackageDotJson(\n packageDotJson: PackageDotJson,\n { installDir }: Pick<WizardOptions, 'installDir'>,\n): Promise<void> {\n try {\n await fs.promises.writeFile(\n join(installDir, 'package.json'),\n JSON.stringify(packageDotJson, null, 2),\n {\n encoding: 'utf8',\n flag: 'w',\n },\n );\n } catch {\n getUI().log.error(`Unable to update your package.json.`);\n\n await abort();\n }\n}\n\n/**\n * Detect and return the package manager. Pure — no prompts.\n * Falls back to first detected or npm if ambiguous.\n */\n// eslint-disable-next-line @typescript-eslint/require-await\nexport async function getPackageManager(\n options: Pick<WizardOptions, 'installDir'> & { ci?: boolean },\n): Promise<PackageManager> {\n const detectedPackageManagers = detectAllPackageManagers({\n installDir: options.installDir,\n });\n\n if (detectedPackageManagers.length >= 1) {\n const selected = detectedPackageManagers[0];\n analytics.setTag('package-manager', selected.name);\n return selected;\n }\n\n // No package manager detected — default to npm\n analytics.setTag('package-manager', npm.name);\n return npm;\n}\n\nexport function isUsingTypeScript({\n installDir,\n}: Pick<WizardOptions, 'installDir'>) {\n try {\n return fs.existsSync(join(installDir, 'tsconfig.json'));\n } catch {\n return false;\n }\n}\n\n/**\n * Get project data for the wizard via OAuth or CI API key.\n */\nexport async function getOrAskForProjectData(\n _options: Pick<WizardOptions, 'signup' | 'ci' | 'apiKey' | 'projectId'> & {\n email?: string;\n region?: CloudRegion;\n },\n): Promise<{\n host: string;\n projectApiKey: string;\n accessToken: string;\n projectId: number;\n cloudRegion: CloudRegion;\n}> {\n // CI mode: bypass OAuth, use personal API key for LLM gateway\n if (_options.ci && _options.apiKey) {\n getUI().log.info('Using provided API key (CI mode - OAuth bypassed)');\n\n const cloudRegion = await detectRegionFromToken(_options.apiKey);\n const host = getHostFromRegion(cloudRegion);\n const cloudUrl = getCloudUrlFromRegion(cloudRegion);\n\n const projectData =\n _options.projectId != null\n ? await fetchProjectDataById(\n _options.apiKey,\n _options.projectId,\n cloudUrl,\n )\n : await fetchProjectDataWithApiKey(_options.apiKey, cloudUrl);\n\n return {\n host,\n projectApiKey: projectData.api_token,\n accessToken: _options.apiKey,\n projectId: projectData.id,\n cloudRegion,\n };\n }\n\n const { host, projectApiKey, accessToken, projectId, cloudRegion } =\n await traceStep('login', () =>\n askForWizardLogin({\n signup: _options.signup,\n email: _options.email,\n region: _options.region,\n }),\n );\n\n if (!projectApiKey) {\n const cloudUrl = getCloudUrlFromRegion(cloudRegion);\n getUI().log.error(`Didn't receive a project token. This shouldn't happen :(\n\nPlease let us know if you think this is a bug in the wizard:\n${ISSUES_URL}`);\n\n getUI().log\n .info(`In the meantime, we'll add a dummy project token (\"${DUMMY_PROJECT_API_KEY}\") for you to replace later.\nYou can find your project token here:\n${cloudUrl}/settings/project#variables`);\n }\n\n return {\n accessToken,\n host: host || DEFAULT_HOST_URL,\n projectApiKey: projectApiKey || DUMMY_PROJECT_API_KEY,\n projectId,\n cloudRegion,\n };\n}\n\nasync function fetchProjectDataWithApiKey(\n apiKey: string,\n cloudUrl: string,\n): Promise<{ api_token: string; id: number }> {\n const userData = await fetchUserData(apiKey, cloudUrl);\n const projectId = userData.team?.id;\n\n if (!projectId) {\n throw new Error(\n 'Could not determine project ID from API key. Please ensure your API key has access to a project in this cloud region.',\n );\n }\n\n const projectData = await fetchProjectData(apiKey, projectId, cloudUrl);\n return {\n api_token: projectData.api_token,\n id: projectId,\n };\n}\n\nasync function fetchProjectDataById(\n apiKey: string,\n projectId: number,\n cloudUrl: string,\n): Promise<{ api_token: string; id: number }> {\n const projectData = await fetchProjectData(apiKey, projectId, cloudUrl);\n return {\n api_token: projectData.api_token,\n id: projectId,\n };\n}\n\nasync function askForWizardLogin(options: {\n signup: boolean;\n email?: string;\n region?: CloudRegion;\n}): Promise<ProjectData & { cloudRegion: CloudRegion }> {\n if (options.signup) {\n return askForProvisioningSignup(options.email, options.region);\n }\n\n const tokenResponse = await performOAuthFlow({\n scopes: [\n 'user:read',\n 'project:read',\n 'introspection',\n 'llm_gateway:read',\n 'dashboard:write',\n 'insight:write',\n 'query:read',\n ],\n signup: false,\n });\n\n const projectId = tokenResponse.scoped_teams?.[0];\n\n if (projectId === undefined) {\n const error = new Error(\n 'No project access granted. Please authorize with project-level access.',\n );\n analytics.captureException(error, {\n step: 'wizard_login',\n has_scoped_teams: !!tokenResponse.scoped_teams,\n });\n getUI().log.error(error.message);\n await abort();\n }\n\n const cloudRegion = await detectRegionFromToken(tokenResponse.access_token);\n const cloudUrl = getCloudUrlFromRegion(cloudRegion);\n const host = getHostFromRegion(cloudRegion);\n\n const projectData = await fetchProjectData(\n tokenResponse.access_token,\n projectId!,\n cloudUrl,\n );\n const userData = await fetchUserData(tokenResponse.access_token, cloudUrl);\n\n const data = {\n accessToken: tokenResponse.access_token,\n projectApiKey: projectData.api_token,\n host,\n distinctId: userData.distinct_id,\n projectId: projectId!,\n cloudRegion,\n };\n\n getUI().log.success('Login complete.');\n analytics.setTag('opened-wizard-link', true);\n analytics.setDistinctId(data.distinctId);\n\n return data;\n}\n\nasync function askForProvisioningSignup(\n email?: string,\n region?: CloudRegion,\n): Promise<ProjectData & { cloudRegion: CloudRegion }> {\n if (!email || !email.includes('@')) {\n getUI().log.error(\n 'Email is required for signup. Use --email your@email.com with --signup.',\n );\n await abort();\n throw new Error('unreachable');\n }\n\n const spinner = getUI().spinner();\n spinner.start('Creating your PostHog account...');\n\n try {\n const provisionRegion = (region ?? 'us').toUpperCase() as 'US' | 'EU';\n const { orgName, projectName } = detectOrgAndProject(email);\n const result = await provisionNewAccount(email, '', provisionRegion, {\n orgName,\n projectName,\n });\n\n spinner.stop('Account created!');\n getUI().log.success('Welcome to PostHog!');\n\n const host = result.host;\n const cloudRegion: CloudRegion = host.includes('eu.') ? 'eu' : 'us';\n\n analytics.setTag('provisioning-signup', true);\n\n return {\n accessToken: result.accessToken,\n projectApiKey: result.projectApiKey,\n host,\n distinctId: email,\n projectId: parseInt(result.projectId, 10) || 0,\n cloudRegion,\n };\n } catch (error) {\n spinner.stop('Account creation failed.');\n const message = error instanceof Error ? error.message : 'Unknown error';\n\n if (message.includes('already associated')) {\n getUI().log.info(\n 'This email already has a PostHog account. Switching to login flow...',\n );\n return askForWizardLogin({ signup: false });\n }\n\n getUI().log.error(`Failed to create account: ${message}`);\n analytics.captureException(\n error instanceof Error ? error : new Error(message),\n { step: 'provisioning_signup' },\n );\n await abort();\n throw error;\n }\n}\n\n/**\n * Creates a new config file with the given filepath and codeSnippet.\n */\nexport async function createNewConfigFile(\n filepath: string,\n codeSnippet: string,\n { installDir }: Pick<WizardOptions, 'installDir'>,\n moreInformation?: string,\n): Promise<boolean> {\n if (!isAbsolute(filepath)) {\n debug(`createNewConfigFile: filepath is not absolute: ${filepath}`);\n return false;\n }\n\n const prettyFilename = relative(installDir, filepath);\n\n try {\n await fs.promises.writeFile(filepath, codeSnippet);\n\n getUI().log.success(`Added new ${prettyFilename} file.`);\n\n if (moreInformation) {\n getUI().log.info(moreInformation);\n }\n\n return true;\n } catch (e) {\n debug(e);\n getUI().log.warn(\n `Could not create a new ${prettyFilename} file. Please create one manually and follow the instructions below.`,\n );\n }\n\n return false;\n}\n"],"mappings":"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"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"start-playground-D1iLBvqF.js","names":["path"],"sources":["../src/ui/tui/playground/demos/WelcomeDemo.tsx","../src/ui/tui/playground/demos/LayoutDemo.tsx","../src/ui/tui/playground/demos/InputDemo.tsx","../src/ui/tui/playground/demos/ProgressDemo.tsx","../src/ui/tui/playground/demos/LogDemo.tsx","../src/ui/tui/playground/demos/RunScreenDemo.tsx","../src/ui/tui/playground/demos/HealthCheckDemo.tsx","../src/ui/tui/playground/demos/ModalDemo.tsx","../src/ui/tui/playground/demos/McpDemo.tsx","../src/ui/tui/playground/demos/KeyboardHintsDemo.tsx","../src/ui/tui/playground/PlaygroundApp.tsx","../src/ui/tui/playground/start-playground.ts"],"sourcesContent":["/**\n * WelcomeDemo — Splash screen. Press enter to push the tabbed view.\n */\n\nimport { Box, Text, useInput } from 'ink';\nimport type { WizardStore } from '../../store.js';\nimport { Colors, Icons } from '../../styles.js';\n\ninterface WelcomeDemoProps {\n store: WizardStore;\n}\n\nexport const WelcomeDemo = ({ store }: WelcomeDemoProps) => {\n useInput((_input, key) => {\n if (key.return) {\n store.completeSetup();\n }\n });\n\n return (\n <Box\n flexDirection=\"column\"\n flexGrow={1}\n justifyContent=\"center\"\n alignItems=\"center\"\n >\n <Text bold color={Colors.accent}>\n {Icons.diamond} PostHog Setup Wizard layout primitives playground\n </Text>\n <Box height={1} />\n <Text>Layout primitives for the PostHog Setup Wizard TUI.</Text>\n <Text dimColor>\n CardLayout, SplitView, TabContainer, ProgressList, and more.\n </Text>\n <Box height={1} />\n <Text color={Colors.primary}>\n Press enter to continue {Icons.triangleRight}\n </Text>\n </Box>\n );\n};\n","/**\n * LayoutDemo — Demonstrates CardLayout + SplitView.\n * Cycles alignment enums with keyboard shortcuts.\n */\n\nimport { Box, Text, useInput } from 'ink';\nimport { useState } from 'react';\nimport { CardLayout, SplitView } from '../../primitives/index.js';\nimport { HAlign, VAlign, Colors } from '../../styles.js';\n\nconst hAligns = [HAlign.Left, HAlign.Center, HAlign.Right];\nconst vAligns = [VAlign.Top, VAlign.Center, VAlign.Bottom];\nconst hLabels = ['Left', 'Center', 'Right'];\nconst vLabels = ['Top', 'Center', 'Bottom'];\n\nexport const LayoutDemo = () => {\n const [hIdx, setHIdx] = useState(0);\n const [vIdx, setVIdx] = useState(0);\n\n useInput((input) => {\n if (input === 'h') setHIdx((i) => (i + 1) % hAligns.length);\n if (input === 'v') setVIdx((i) => (i + 1) % vAligns.length);\n });\n\n return (\n <Box flexDirection=\"column\" flexGrow={1}>\n <Text bold color={Colors.accent}>\n Layout Demo\n </Text>\n <Text dimColor>\n Press [h] to cycle hAlign ({hLabels[hIdx]}), [v] to cycle vAlign (\n {vLabels[vIdx]})\n </Text>\n <Box height={1} />\n <SplitView\n left={\n <CardLayout hAlign={hAligns[hIdx]} vAlign={vAligns[vIdx]}>\n <Box borderStyle=\"single\" borderColor={Colors.primary} paddingX={1}>\n <Text color={Colors.primary}>Left Pane</Text>\n </Box>\n </CardLayout>\n }\n right={\n <CardLayout hAlign={HAlign.Center} vAlign={VAlign.Center}>\n <Box borderStyle=\"single\" borderColor={Colors.accent} paddingX={1}>\n <Text color={Colors.accent}>Right Pane</Text>\n </Box>\n </CardLayout>\n }\n />\n </Box>\n );\n};\n","/**\n * InputDemo — Demonstrates PickerMenu (single + multi) and ConfirmationInput.\n */\n\nimport { Box, Text } from 'ink';\nimport { useState } from 'react';\nimport { PickerMenu, ConfirmationInput } from '../../primitives/index.js';\nimport { Colors } from '../../styles.js';\n\nenum DemoStep {\n Single = 'single',\n Multi = 'multi',\n Confirm = 'confirm',\n Done = 'done',\n}\n\nexport const InputDemo = () => {\n const [step, setStep] = useState<DemoStep>(DemoStep.Single);\n const [results, setResults] = useState<string[]>([]);\n\n if (step === DemoStep.Single) {\n return (\n <Box flexDirection=\"column\">\n <Text bold color={Colors.accent}>\n Input Demo — Single Select\n </Text>\n <Box height={1} />\n <PickerMenu\n message=\"Pick a color\"\n options={[\n { label: 'Red', value: 'red', hint: 'warm' },\n { label: 'Blue', value: 'blue', hint: 'cool' },\n { label: 'Green', value: 'green', hint: 'natural' },\n ]}\n onSelect={(value) => {\n setResults((prev) => [...prev, `Single: ${value}`]);\n setStep(DemoStep.Multi);\n }}\n />\n </Box>\n );\n }\n\n if (step === DemoStep.Multi) {\n return (\n <Box flexDirection=\"column\">\n <Text bold color={Colors.accent}>\n Input Demo — Multi Select\n </Text>\n <Box height={1} />\n <PickerMenu\n message=\"Pick toppings\"\n mode=\"multi\"\n options={[\n { label: 'Cheese', value: 'cheese' },\n { label: 'Pepperoni', value: 'pepperoni' },\n { label: 'Mushrooms', value: 'mushrooms' },\n { label: 'Onions', value: 'onions' },\n ]}\n onSelect={(values) => {\n const arr = Array.isArray(values) ? values : [values];\n setResults((prev) => [...prev, `Multi: ${arr.join(', ')}`]);\n setStep(DemoStep.Confirm);\n }}\n />\n </Box>\n );\n }\n\n if (step === DemoStep.Confirm) {\n return (\n <Box flexDirection=\"column\">\n <Text bold color={Colors.accent}>\n Input Demo — Confirmation\n </Text>\n <Box height={1} />\n <ConfirmationInput\n message=\"Are you satisfied with your choices?\"\n onConfirm={() => {\n setResults((prev) => [...prev, 'Confirmed: Yes']);\n setStep(DemoStep.Done);\n }}\n onCancel={() => {\n setResults((prev) => [...prev, 'Confirmed: No']);\n setStep(DemoStep.Done);\n }}\n />\n </Box>\n );\n }\n\n // done\n return (\n <Box flexDirection=\"column\">\n <Text bold color={Colors.accent}>\n Input Demo — Results\n </Text>\n <Box height={1} />\n {results.map((r, i) => (\n <Text key={i} color={Colors.success}>\n {'\\u2714'} {r}\n </Text>\n ))}\n <Box height={1} />\n <Text dimColor>Switch away from this tab and back to restart.</Text>\n </Box>\n );\n};\n","/**\n * ProgressDemo — Demonstrates ProgressList + LoadingBox.\n * Auto-animates task progression through states.\n */\n\nimport { Box, Text } from 'ink';\nimport { useState, useEffect } from 'react';\nimport { ProgressList, LoadingBox } from '../../primitives/index.js';\nimport type { ProgressItem } from '../../primitives/index.js';\nimport { Colors } from '../../styles.js';\n\nconst INITIAL_ITEMS: ProgressItem[] = [\n {\n label: 'Detect framework',\n activeForm: 'Detecting framework',\n status: 'pending',\n },\n {\n label: 'Install dependencies',\n activeForm: 'Installing dependencies',\n status: 'pending',\n },\n {\n label: 'Configure PostHog',\n activeForm: 'Configuring PostHog',\n status: 'pending',\n },\n {\n label: 'Add analytics provider',\n activeForm: 'Adding analytics provider',\n status: 'pending',\n },\n { label: 'Verify setup', activeForm: 'Verifying setup', status: 'pending' },\n];\n\nexport const ProgressDemo = () => {\n const [items, setItems] = useState<ProgressItem[]>(INITIAL_ITEMS);\n const [tick, setTick] = useState(0);\n\n useEffect(() => {\n const timer = setInterval(() => {\n setTick((t) => t + 1);\n }, 1500);\n return () => clearInterval(timer);\n }, []);\n\n useEffect(() => {\n // Cycle: each tick advances the \"active\" task\n const total = INITIAL_ITEMS.length;\n // After all tasks complete, restart\n const cycle = tick % (total + 2); // +2 for a pause at the end\n\n setItems(\n INITIAL_ITEMS.map((item, i) => {\n if (i < cycle) return { ...item, status: 'completed' as const };\n if (i === cycle) return { ...item, status: 'in_progress' as const };\n return { ...item, status: 'pending' as const };\n }),\n );\n }, [tick]);\n\n const allDone = items.every((i) => i.status === 'completed');\n\n return (\n <Box flexDirection=\"column\" flexGrow={1}>\n <Text bold color={Colors.accent}>\n Progress Demo\n </Text>\n <Text dimColor>Tasks auto-advance every 1.5s (cycles continuously)</Text>\n <Box height={1} />\n <ProgressList items={items} title=\"Setup in progress:\" />\n <Box height={1} />\n {!allDone && <LoadingBox message=\"Working...\" />}\n {allDone && (\n <Text color={Colors.success} bold>\n {'\\u2714'} All tasks complete! Restarting...\n </Text>\n )}\n </Box>\n );\n};\n","/**\n * LogDemo — Demonstrates LogViewer.\n * Writes demo log lines to a temp file, then tails it.\n */\n\nimport { Box, Text } from 'ink';\nimport { useEffect, useState } from 'react';\nimport * as fs from 'fs';\nimport * as path from 'path';\nimport * as os from 'os';\nimport { LogViewer } from '../../primitives/index.js';\nimport { Colors } from '../../styles.js';\n\nconst DEMO_LOG_PATH = path.join(os.tmpdir(), 'posthog-playground.log');\n\nconst LOG_MESSAGES = [\n '[info] Playground started',\n '[info] Initializing demo components...',\n '[debug] Loading primitives barrel export',\n '[info] ScreenContainer mounted',\n '[info] TabContainer initialized with 6 tabs',\n '[debug] LayoutDemo: hAlign=Left, vAlign=Top',\n '[info] NavigationDemo: screenStack depth = 1',\n '[warn] TabDemo: arrow key conflict with outer container',\n '[info] InputDemo: waiting for user selection',\n '[info] ProgressDemo: tick 0, cycling tasks',\n '[debug] LogViewer: watching file for changes',\n '[info] All demos loaded successfully',\n];\n\nexport const LogDemo = () => {\n const [ready, setReady] = useState(false);\n\n useEffect(() => {\n // Write initial log content\n fs.writeFileSync(DEMO_LOG_PATH, LOG_MESSAGES.join('\\n') + '\\n');\n setReady(true);\n\n // Append lines periodically\n let lineNum = LOG_MESSAGES.length;\n const timer = setInterval(() => {\n lineNum++;\n const msg = `[info] Demo log line #${lineNum} — ${new Date().toISOString()}\\n`;\n fs.appendFileSync(DEMO_LOG_PATH, msg);\n }, 2000);\n\n return () => {\n clearInterval(timer);\n try {\n fs.unlinkSync(DEMO_LOG_PATH);\n } catch {\n // ignore\n }\n };\n }, []);\n\n return (\n <Box flexDirection=\"column\" flexGrow={1}>\n <Text bold color={Colors.accent}>\n Log Demo\n </Text>\n <Text dimColor>Tailing {DEMO_LOG_PATH} (new line every 2s)</Text>\n <Box height={1} />\n {ready && <LogViewer filePath={DEMO_LOG_PATH} height={15} />}\n </Box>\n );\n};\n","/**\n * RunScreenDemo — Renders the real RunScreen with a mock store.\n * Tasks auto-advance every 1.5s. Discovered features (Stripe, LLM)\n * are pre-populated so conditional tips appear.\n */\n\nimport { useEffect, useRef, useSyncExternalStore } from 'react';\nimport { WizardStore, TaskStatus } from '../../store.js';\nimport { DiscoveredFeature } from '../../../../lib/wizard-session.js';\nimport {\n TabContainer,\n SplitView,\n ProgressList,\n LogViewer,\n EventPlanViewer,\n HNViewer,\n} from '../../primitives/index.js';\nimport type { ProgressItem } from '../../primitives/index.js';\nimport { LearnCard } from '../../components/LearnCard.js';\nimport { TipsCard } from '../../components/TipsCard.js';\n\nconst MOCK_TASKS = [\n {\n label: 'Checking project structure and finding files for event tracking',\n activeForm: 'Checking project structure',\n status: TaskStatus.Pending,\n done: false,\n },\n {\n label: 'Verify PostHog dependencies',\n activeForm: 'Verifying PostHog dependencies',\n status: TaskStatus.Pending,\n done: false,\n },\n {\n label: 'Generate events plan (.posthog-events.json)',\n activeForm: 'Generating events plan',\n status: TaskStatus.Pending,\n done: false,\n },\n {\n label: 'Install posthog-js and posthog-node packages',\n activeForm: 'Installing packages',\n status: TaskStatus.Pending,\n done: false,\n },\n {\n label: 'Set up environment variables',\n activeForm: 'Setting up environment variables',\n status: TaskStatus.Pending,\n done: false,\n },\n {\n label: 'Create instrumentation-client.ts',\n activeForm: 'Creating instrumentation-client.ts',\n status: TaskStatus.Pending,\n done: false,\n },\n {\n label: 'Update next.config with rewrites',\n activeForm: 'Updating next.config',\n status: TaskStatus.Pending,\n done: false,\n },\n {\n label: 'Create posthog-server.ts',\n activeForm: 'Creating posthog-server.ts',\n status: TaskStatus.Pending,\n done: false,\n },\n {\n label: 'Add PostHog capture events to project files',\n activeForm: 'Adding capture events',\n status: TaskStatus.Pending,\n done: false,\n },\n];\n\nconst MOCK_EVENTS = [\n { name: 'page_viewed', description: 'Fires when a user views any page' },\n {\n name: 'button_clicked',\n description: 'Fires when the CTA button is clicked',\n },\n {\n name: 'form_submitted',\n description: 'Fires when the contact form is submitted',\n },\n {\n name: 'signup_started',\n description: 'Fires when a user begins the signup flow',\n },\n];\n\ninterface RunScreenDemoProps {\n store: WizardStore;\n}\n\nexport const RunScreenDemo = ({ store }: RunScreenDemoProps) => {\n const tickRef = useRef(0);\n const lastStatusRef = useRef('');\n\n // Seed the store with mock data on mount\n useEffect(() => {\n store.addDiscoveredFeature(DiscoveredFeature.Stripe);\n store.addDiscoveredFeature(DiscoveredFeature.LLM);\n store.setEventPlan(MOCK_EVENTS);\n store.pushStatus('Checking project structure.');\n lastStatusRef.current = 'Checking project structure.';\n\n // Set initial tasks\n const initial = MOCK_TASKS.map((t, i) =>\n i === 0 ? { ...t, status: TaskStatus.InProgress } : t,\n );\n store.setTasks(initial);\n }, []);\n\n // Auto-advance tasks every 1.5s\n useEffect(() => {\n const timer = setInterval(() => {\n tickRef.current += 1;\n const tick = tickRef.current;\n const total = MOCK_TASKS.length;\n const cycle = tick % (total + 3); // +3 for pause at end before restart\n\n const tasks = MOCK_TASKS.map((t, i) => {\n if (i < cycle)\n return { ...t, status: TaskStatus.Completed, done: true };\n if (i === cycle)\n return { ...t, status: TaskStatus.InProgress, done: false };\n return { ...t, status: TaskStatus.Pending, done: false };\n });\n\n store.setTasks(tasks);\n\n // Only push status when the message actually changes\n if (cycle < total) {\n const msg = MOCK_TASKS[cycle].activeForm + '...';\n if (msg !== lastStatusRef.current) {\n store.pushStatus(msg);\n lastStatusRef.current = msg;\n }\n }\n }, 1500);\n\n return () => clearInterval(timer);\n }, []);\n\n useSyncExternalStore(\n (cb) => store.subscribe(cb),\n () => store.getSnapshot(),\n );\n\n const progressItems: ProgressItem[] = store.tasks.map((t) => ({\n label: t.label,\n activeForm: t.activeForm,\n status: t.status,\n }));\n\n const statuses =\n store.statusMessages.length > 0 ? store.statusMessages : undefined;\n\n const tabs = [\n {\n id: 'status',\n label: 'Status',\n component: (\n <SplitView\n left={\n store.learnCardComplete ? (\n <TipsCard store={store} />\n ) : (\n <LearnCard\n store={store}\n onComplete={() => store.setLearnCardComplete()}\n />\n )\n }\n right={<ProgressList items={progressItems} title=\"Tasks\" />}\n />\n ),\n },\n ...(store.eventPlan.length > 0\n ? [\n {\n id: 'events',\n label: 'Event plan',\n component: <EventPlanViewer events={store.eventPlan} />,\n },\n ]\n : []),\n {\n id: 'logs',\n label: 'Tail logs',\n component: <LogViewer filePath=\"/tmp/posthog-wizard.log\" />,\n },\n {\n id: 'hn',\n label: 'HN',\n component: <HNViewer />,\n },\n ];\n\n return (\n <TabContainer\n tabs={tabs}\n statusMessage={statuses}\n expandableStatus\n store={store}\n />\n );\n};\n","/**\n * HealthCheckDemo — Playground demo for health check UI components.\n *\n * Shows the ModalOverlay with ServiceHealthList, cycling through states:\n * 1. Checking (spinner) — 2 seconds\n * 2. Blocking outage modal (Anthropic down, npm degraded)\n *\n * Renders components directly (not HealthCheckScreen) to avoid useInput\n * conflicts with TabContainer's key handling.\n */\n\nimport { useEffect, useState } from 'react';\nimport { Box, Text } from 'ink';\nimport { LoadingBox, ModalOverlay } from '../../primitives/index.js';\nimport { Icons } from '../../styles.js';\nimport { ServiceHealthList } from '../../components/ServiceHealthList.js';\nimport { getBlockingServiceKeys } from '../../../../lib/health-checks/readiness.js';\nimport { ServiceHealthStatus } from '../../../../lib/health-checks/types.js';\nimport type { AllServicesHealth } from '../../../../lib/health-checks/types.js';\n\nconst HEALTHY = { status: ServiceHealthStatus.Healthy } as const;\n\nconst MOCK_HEALTH: AllServicesHealth = {\n anthropic: { status: ServiceHealthStatus.Down, rawIndicator: 'major' },\n posthogOverall: HEALTHY,\n posthogComponents: { status: ServiceHealthStatus.Healthy },\n github: HEALTHY,\n npmOverall: {\n status: ServiceHealthStatus.Degraded,\n rawIndicator: 'minor',\n },\n npmComponents: {\n status: ServiceHealthStatus.Degraded,\n degradedOrDownComponents: [\n {\n name: 'Registry API',\n status: ServiceHealthStatus.Degraded,\n rawStatus: 'degraded_performance',\n },\n ],\n },\n cloudflareOverall: HEALTHY,\n cloudflareComponents: { status: ServiceHealthStatus.Healthy },\n llmGateway: HEALTHY,\n mcp: HEALTHY,\n githubReleases: HEALTHY,\n};\n\nexport const HealthCheckDemo = () => {\n const [showOutage, setShowOutage] = useState(false);\n\n useEffect(() => {\n const timer = setTimeout(() => setShowOutage(true), 2000);\n return () => clearTimeout(timer);\n }, []);\n\n if (!showOutage) {\n return (\n <Box\n flexDirection=\"column\"\n flexGrow={1}\n alignItems=\"center\"\n justifyContent=\"center\"\n >\n <LoadingBox message=\"Checking service status...\" />\n </Box>\n );\n }\n\n const blockingKeys = getBlockingServiceKeys(MOCK_HEALTH);\n\n return (\n <ModalOverlay\n borderColor=\"red\"\n title={`${Icons.warning} Ongoing service disruptions`}\n width={72}\n footer={\n <Box marginLeft={2}>\n <Text dimColor>\n Continue [Enter] / Exit [Esc] (disabled in playground)\n </Text>\n </Box>\n }\n >\n <Box flexDirection=\"column\" marginBottom={1}>\n <Box marginBottom={1}>\n <Text>\n <Text color=\"red\">{Icons.squareFilled}</Text>\n <Text dimColor> Down </Text>\n <Text color=\"#DC9300\">{Icons.squareFilled}</Text>\n <Text dimColor> Degraded</Text>\n </Text>\n </Box>\n\n <ServiceHealthList\n health={MOCK_HEALTH}\n filterKeys={blockingKeys}\n showHealthy={false}\n />\n </Box>\n\n <Text dimColor>\n The wizard may not work reliably while services are affected.\n </Text>\n </ModalOverlay>\n );\n};\n","/**\n * ModalDemo — Playground demo for the ModalOverlay primitive.\n *\n * Shows several modal variants: info, warning, error, and one with feedback text.\n */\n\nimport { Box, Text } from 'ink';\nimport { ModalOverlay } from '../../primitives/index.js';\nimport { Icons } from '../../styles.js';\n\nexport const ModalDemo = () => {\n return (\n <Box flexDirection=\"column\" gap={1} flexGrow={1}>\n <ModalOverlay borderColor=\"cyan\" title=\"Info Modal\" width={60}>\n <Text>A simple informational modal with default styling.</Text>\n </ModalOverlay>\n\n <ModalOverlay\n borderColor=\"#DC9300\"\n title={`${Icons.warning} Warning Modal`}\n width={60}\n feedback=\"Something needs your attention.\"\n >\n <Text>This modal includes a feedback message shown in yellow.</Text>\n </ModalOverlay>\n\n <ModalOverlay\n borderColor=\"red\"\n title={`${Icons.warning} Error Modal`}\n width={60}\n footer={\n <Box marginLeft={2}>\n <Text dimColor>\n Continue [Enter] / Exit [Esc] (disabled in playground)\n </Text>\n </Box>\n }\n >\n <Text>This modal has a footer section below a divider.</Text>\n </ModalOverlay>\n </Box>\n );\n};\n","/**\n * McpDemo — Playground demo for the MCP client selection screen.\n *\n * Uses a mock McpInstaller that simulates detecting three editors,\n * a short install delay, and a successful result.\n */\n\nimport { WizardStore } from '../../store.js';\nimport { McpScreen } from '../../screens/McpScreen.js';\nimport type { McpInstaller } from '../../services/mcp-installer.js';\n\nconst MOCK_CLIENTS = [\n { name: 'VS Code' },\n { name: 'Cursor' },\n { name: 'Windsurf' },\n];\n\nfunction createMockInstaller(): McpInstaller {\n return {\n async detectClients() {\n await new Promise((r) => setTimeout(r, 800));\n return MOCK_CLIENTS;\n },\n async install(clientNames) {\n await new Promise((r) => setTimeout(r, 1500));\n return clientNames;\n },\n async remove() {\n await new Promise((r) => setTimeout(r, 1000));\n return MOCK_CLIENTS.map((c) => c.name);\n },\n };\n}\n\ninterface McpDemoProps {\n store: WizardStore;\n}\n\nexport const McpDemo = ({ store }: McpDemoProps) => {\n return (\n <McpScreen store={store} installer={createMockInstaller()} mode=\"install\" />\n );\n};\n","/**\n * KeyboardHintsDemo — Demonstrates the KeyboardHintsBar with all input types.\n *\n * Cycles through SinglePicker, MultiPicker, GroupedPicker, and Confirmation\n * so the user can see the hints bar update automatically for each component.\n * The bar appears at the bottom of the screen and dismisses 3s after the\n * first keypress, then reappears when the component changes.\n */\n\nimport { Box, Text } from 'ink';\nimport { useState, type ReactNode } from 'react';\nimport {\n PickerMenu,\n GroupedPickerMenu,\n ConfirmationInput,\n} from '../../primitives/index.js';\nimport { Colors } from '../../styles.js';\n\nenum DemoStep {\n SingleSelect = 'single',\n MultiSelect = 'multi',\n GroupedSelect = 'grouped',\n Confirmation = 'confirm',\n Done = 'done',\n}\n\nconst STEP_LABELS: Record<DemoStep, string> = {\n [DemoStep.SingleSelect]: 'Single Select — hints: ↑↓ navigate, enter select',\n [DemoStep.MultiSelect]:\n 'Multi Select — hints: ↑↓ navigate, space toggle, enter confirm',\n [DemoStep.GroupedSelect]:\n 'Grouped Select — hints: ↑↓ navigate, space toggle, a toggle all, enter confirm',\n [DemoStep.Confirmation]:\n 'Confirmation — hints: ←→ switch, enter confirm, esc cancel',\n [DemoStep.Done]: 'Done',\n};\n\nexport const KeyboardHintsDemo = () => {\n const [step, setStep] = useState<DemoStep>(DemoStep.SingleSelect);\n const [log, setLog] = useState<string[]>([]);\n\n const addLog = (msg: string) => setLog((prev) => [...prev.slice(-4), msg]);\n\n if (step === DemoStep.SingleSelect) {\n return (\n <Wrapper step={step} log={log}>\n <PickerMenu\n message=\"Pick a framework\"\n options={[\n { label: 'Next.js', value: 'next' },\n { label: 'React', value: 'react' },\n { label: 'Vue', value: 'vue' },\n { label: 'Svelte', value: 'svelte' },\n ]}\n columns={2}\n onSelect={(v) => {\n addLog(`Single: ${String(v)}`);\n setStep(DemoStep.MultiSelect);\n }}\n />\n </Wrapper>\n );\n }\n\n if (step === DemoStep.MultiSelect) {\n return (\n <Wrapper step={step} log={log}>\n <PickerMenu\n message=\"Pick features to enable\"\n mode=\"multi\"\n options={[\n { label: 'Analytics', value: 'analytics' },\n { label: 'Session Replay', value: 'replay' },\n { label: 'Feature Flags', value: 'flags' },\n { label: 'Surveys', value: 'surveys' },\n ]}\n onSelect={(values) => {\n const arr = Array.isArray(values) ? values : [values];\n addLog(`Multi: ${arr.join(', ')}`);\n setStep(DemoStep.GroupedSelect);\n }}\n />\n </Wrapper>\n );\n }\n\n if (step === DemoStep.GroupedSelect) {\n return (\n <Wrapper step={step} log={log}>\n <GroupedPickerMenu\n message=\"Select integrations\"\n groups={{\n Frontend: [\n { label: 'React SDK', value: 'react-sdk' },\n { label: 'Web Analytics', value: 'web-analytics' },\n ],\n Backend: [\n { label: 'Node SDK', value: 'node-sdk' },\n { label: 'Python SDK', value: 'python-sdk' },\n ],\n Tooling: [\n { label: 'MCP Server', value: 'mcp' },\n { label: 'CLI', value: 'cli' },\n ],\n }}\n onSelect={(values) => {\n addLog(`Grouped: ${values.join(', ')}`);\n setStep(DemoStep.Confirmation);\n }}\n />\n </Wrapper>\n );\n }\n\n if (step === DemoStep.Confirmation) {\n return (\n <Wrapper step={step} log={log}>\n <ConfirmationInput\n message=\"Apply these settings?\"\n onConfirm={() => {\n addLog('Confirmed!');\n setStep(DemoStep.Done);\n }}\n onCancel={() => {\n addLog('Cancelled');\n setStep(DemoStep.Done);\n }}\n />\n </Wrapper>\n );\n }\n\n return (\n <Wrapper step={step} log={log}>\n <Text dimColor>\n All steps complete. Switch away from this tab and back to restart.\n </Text>\n </Wrapper>\n );\n};\n\nconst Wrapper = ({\n step,\n log,\n children,\n}: {\n step: DemoStep;\n log: string[];\n children: ReactNode;\n}) => (\n <Box flexDirection=\"column\">\n <Text bold color={Colors.accent}>\n Keyboard Hints Demo\n </Text>\n <Text dimColor>{STEP_LABELS[step]}</Text>\n <Box height={1} />\n {children}\n {log.length > 0 && (\n <>\n <Box height={1} />\n <Text dimColor>Log:</Text>\n {log.map((entry, i) => (\n <Text key={i} color={Colors.muted}>\n {' '}\n {entry}\n </Text>\n ))}\n </>\n )}\n </Box>\n);\n","/**\n * PlaygroundApp — Root component for the primitives playground.\n *\n * Two screens mirroring the real wizard flow:\n * intro → (press enter) → run (tabbed demo view)\n */\n\nimport { ScreenContainer, TabContainer } from '../primitives/index.js';\nimport type { WizardStore } from '../store.js';\nimport { WelcomeDemo } from './demos/WelcomeDemo.js';\nimport { LayoutDemo } from './demos/LayoutDemo.js';\nimport { InputDemo } from './demos/InputDemo.js';\nimport { ProgressDemo } from './demos/ProgressDemo.js';\nimport { LogDemo } from './demos/LogDemo.js';\nimport { RunScreenDemo } from './demos/RunScreenDemo.js';\nimport { HealthCheckDemo } from './demos/HealthCheckDemo.js';\nimport { ModalDemo } from './demos/ModalDemo.js';\nimport { McpDemo } from './demos/McpDemo.js';\nimport { KeyboardHintsDemo } from './demos/KeyboardHintsDemo.js';\n\ninterface PlaygroundAppProps {\n store: WizardStore;\n}\n\nexport const PlaygroundApp = ({ store }: PlaygroundAppProps) => {\n const tabs = [\n { id: 'layout', label: 'Layout', component: <LayoutDemo /> },\n { id: 'input', label: 'Input', component: <InputDemo /> },\n { id: 'progress', label: 'Progress', component: <ProgressDemo /> },\n { id: 'logs', label: 'Logs', component: <LogDemo /> },\n {\n id: 'run',\n label: 'RunScreen',\n component: <RunScreenDemo store={store} />,\n },\n {\n id: 'health',\n label: 'HealthCheck',\n component: <HealthCheckDemo />,\n },\n {\n id: 'modal',\n label: 'Modal',\n component: <ModalDemo />,\n },\n {\n id: 'mcp',\n label: 'MCP',\n component: <McpDemo store={store} />,\n },\n {\n id: 'hints',\n label: 'KeyHints',\n component: <KeyboardHintsDemo />,\n },\n ];\n\n return (\n <ScreenContainer\n store={store}\n screens={{\n intro: <WelcomeDemo store={store} />,\n run: (\n <TabContainer\n tabs={tabs}\n statusMessage=\"Primitives Playground — use arrow keys to switch tabs\"\n />\n ),\n }}\n />\n );\n};\n","/**\n * start-playground.ts — Launches the TUI primitives playground.\n */\n\nimport { render } from 'ink';\nimport { createElement } from 'react';\nimport { WizardStore } from '../store.js';\nimport { PlaygroundApp } from './PlaygroundApp.js';\n\nexport function startPlayground(version: string): void {\n const store = new WizardStore();\n store.version = version;\n\n // Pre-fill session so the router skips auth and lands on 'run' after intro\n store.setCredentials({\n accessToken: 'fake',\n projectApiKey: 'fake',\n host: 'https://app.posthog.com',\n projectId: 0,\n });\n\n const { unmount, waitUntilExit } = render(\n createElement(PlaygroundApp, { store }),\n );\n\n void waitUntilExit().then(() => {\n unmount();\n process.exit(0);\n });\n}\n"],"mappings":"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"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"start-tui-DkT_H5zx.js","names":[],"sources":["../src/ui/tui/ink-ui.ts","../src/ui/tui/screens/health/HealthCheckScreen.tsx","../src/ui/tui/screens/SettingsOverrideScreen.tsx","../src/ui/tui/screens/ManagedSettingsScreen.tsx","../src/ui/tui/screens/PortConflictScreen.tsx","../src/ui/tui/screens/IntroScreenLayout.tsx","../src/ui/tui/screens/PostHogIntegrationIntroScreen.tsx","../src/ui/tui/screens/RevenueIntroScreen.tsx","../src/ui/tui/screens/AgentSkillIntroScreen.tsx","../src/ui/tui/screens/SetupScreen.tsx","../src/ui/tui/screens/AuthScreen.tsx","../src/ui/tui/screens/RunScreen.tsx","../src/ui/tui/screens/KeepSkillsScreen.tsx","../src/ui/tui/screens/OutroScreen.tsx","../src/ui/tui/screens/ExitScreen.tsx","../src/ui/tui/screens/AuthErrorScreen.tsx","../src/ui/tui/services/mcp-installer.ts","../src/ui/tui/screen-registry.tsx","../src/ui/tui/App.tsx","../src/ui/tui/start-tui.ts"],"sourcesContent":["/**\n * InkUI — Ink-backed implementation of WizardUI.\n *\n * Translates business logic calls into store setter calls.\n * No direct session mutation. No imperative screen transitions.\n * The router derives the active screen from session state.\n */\n\nimport type { WizardUI, SpinnerHandle } from '../wizard-ui.js';\nimport type { WizardStore } from './store.js';\nimport type { SettingsConflict } from '../../lib/agent/agent-interface.js';\nimport type { WizardReadinessResult } from '../../lib/health-checks/readiness.js';\nimport type { OutroData } from '../../lib/wizard-session.js';\nimport { RunPhase, OutroKind } from '../../lib/wizard-session.js';\n\n// Strip ANSI escape codes (chalk formatting) from strings\n// eslint-disable-next-line no-control-regex\nconst ANSI_RE = /\\x1b\\[[0-9;]*m/g;\nfunction stripAnsi(s: string): string {\n return s.replace(ANSI_RE, '');\n}\n\nexport class InkUI implements WizardUI {\n constructor(private store: WizardStore) {}\n\n intro(message: string): void {\n this.store.pushStatus(message);\n }\n\n outro(message: string): void {\n this.store.pushStatus(stripAnsi(message));\n\n if (!this.store.session.outroData) {\n this.store.setOutroData({\n kind: OutroKind.Success,\n message: stripAnsi(message),\n });\n }\n\n // Signal that the main work is done — router resolves to mcp or outro\n if (this.store.session.runPhase === RunPhase.Running) {\n this.store.setRunPhase(RunPhase.Completed);\n }\n }\n\n outroError(data: OutroData): void {\n this.store.setOutroData(data);\n // Advance router past the run step so the outro screen renders\n if (this.store.session.runPhase !== RunPhase.Error) {\n this.store.setRunPhase(RunPhase.Error);\n }\n }\n\n setCredentials(credentials: {\n accessToken: string;\n projectApiKey: string;\n host: string;\n projectId: number;\n }): void {\n this.store.setCredentials(credentials);\n }\n\n setDetectedFramework(label: string): void {\n this.store.setDetectedFramework(label);\n }\n\n onEnterScreen(screen: string, fn: () => void): void {\n this.store.onEnterScreen(\n screen as Parameters<WizardStore['onEnterScreen']>[0],\n fn,\n );\n }\n\n setLoginUrl(url: string | null): void {\n this.store.setLoginUrl(url);\n }\n\n showBlockingOutage(result: WizardReadinessResult): Promise<void> {\n // In the TUI, the HealthCheckScreen handles outage display.\n // This is only called from agent-runner for the CI fallback path.\n this.store.setReadinessResult(result);\n return Promise.resolve();\n }\n\n setReadinessWarnings(result: WizardReadinessResult): void {\n this.store.setReadinessResult(result);\n }\n\n showPortConflict(processInfo: {\n command: string;\n pid: string;\n port: number;\n user: string;\n }): Promise<void> {\n return this.store.showPortConflict(processInfo);\n }\n\n showSettingsOverride(\n conflicts: SettingsConflict[],\n backupAndFix: () => boolean,\n ): Promise<void> {\n return this.store.showSettingsOverride(conflicts, backupAndFix);\n }\n\n showAuthError(): void {\n this.store.showAuthError();\n }\n\n startRun(): void {\n this.store.setRunPhase(RunPhase.Running);\n }\n\n cancel(message: string): void {\n this.store.pushStatus(message);\n }\n\n log = {\n info: (message: string): void => {\n this.store.pushStatus(message);\n },\n warn: (message: string): void => {\n this.store.pushStatus(message);\n },\n error: (message: string): void => {\n this.store.pushStatus(message);\n },\n success: (message: string): void => {\n this.store.pushStatus(message);\n },\n step: (message: string): void => {\n this.store.pushStatus(message);\n },\n };\n\n note(message: string): void {\n this.store.pushStatus(message);\n }\n\n spinner(): SpinnerHandle {\n return {\n start: (message?: string) => {\n if (message) this.store.pushStatus(message);\n },\n stop: (message?: string) => {\n if (message) this.store.pushStatus(message);\n },\n message: (msg?: string) => {\n if (msg) this.store.pushStatus(msg);\n },\n };\n }\n\n pushStatus(message: string): void {\n this.store.pushStatus(message);\n }\n\n syncTodos(\n todos: Array<{ content: string; status: string; activeForm?: string }>,\n ): void {\n this.store.syncTodos(todos);\n }\n\n setEventPlan(events: Array<{ name: string; description: string }>): void {\n this.store.setEventPlan(events);\n }\n}\n","/**\n * HealthCheckScreen — Flow screen between Intro and Auth.\n *\n * Three states:\n * 1. Checking: spinner while health check runs\n * 2. Healthy: isComplete returns true, router auto-advances to Auth\n * 3. Blocking outage: shows affected services with Continue/Exit\n */\n\nimport { Box, Text, useInput } from 'ink';\nimport { useState, useSyncExternalStore } from 'react';\nimport type { WizardStore } from '../../store.js';\nimport {\n ConfirmationInput,\n LoadingBox,\n ModalOverlay,\n} from '../../primitives/index.js';\nimport { Colors, Icons } from '../../styles.js';\nimport { ServiceHealthList } from '../../components/ServiceHealthList.js';\nimport { getBlockingServiceKeys } from '../../../../lib/health-checks/readiness.js';\nimport { ServiceHealthStatus } from '../../../../lib/health-checks/types.js';\nimport { wizardAbort } from '../../../../utils/wizard-abort.js';\nimport { fetchSkillMenu, downloadSkill } from '../../../../lib/wizard-tools.js';\nimport { REMOTE_SKILLS_BASE_URL } from '../../../../lib/constants.js';\n\ninterface HealthCheckScreenProps {\n store: WizardStore;\n}\n\nconst EXAMPLE_PROMPT =\n 'Integrate PostHog into this project using the skill files in .posthog/skills/. Read SKILL.md first, then follow the numbered workflow files in order.';\n\nconst SkillsDownloadedScreen = () => {\n useInput(() => {\n process.exit(0);\n });\n\n return (\n <Box flexDirection=\"column\" flexGrow={1}>\n <Text color=\"green\" bold>\n {Icons.check} Skills downloaded to .posthog/skills/\n </Text>\n\n <Box marginTop={1} flexDirection=\"column\">\n <Text>\n You can continue setup with another agent using this prompt:\n </Text>\n <Box marginTop={1} paddingLeft={2}>\n <Text color=\"cyan\">{EXAMPLE_PROMPT}</Text>\n </Box>\n </Box>\n\n <Box marginTop={1}>\n <Text color={Colors.muted}>Press any key to exit</Text>\n </Box>\n </Box>\n );\n};\n\nexport const HealthCheckScreen = ({ store }: HealthCheckScreenProps) => {\n useSyncExternalStore(\n (cb) => store.subscribe(cb),\n () => store.getSnapshot(),\n );\n\n const [downloaded, setDownloaded] = useState(false);\n const [downloading, setDownloading] = useState(false);\n\n const result = store.session.readinessResult;\n\n if (downloaded) {\n return <SkillsDownloadedScreen />;\n }\n\n // Still checking — show spinner\n if (!result) {\n return (\n <Box\n flexDirection=\"column\"\n flexGrow={1}\n alignItems=\"center\"\n justifyContent=\"center\"\n >\n <LoadingBox message=\"Checking service status...\" />\n </Box>\n );\n }\n\n // Healthy or warnings — isComplete returns true, router skips past.\n // This branch only renders for a single frame before advancing.\n const blockingKeys = getBlockingServiceKeys(result.health);\n if (blockingKeys.length === 0) return null;\n\n const isGithubReleasesDown = blockingKeys.includes('githubReleases');\n const canDownloadSkills =\n result.health.githubReleases.status === ServiceHealthStatus.Healthy;\n const integration = store.session.integration;\n\n const title = `Ongoing service disruptions`;\n\n const docsUrl = store.session.frameworkConfig?.metadata.docsUrl;\n const description = isGithubReleasesDown\n ? \"The Wizard can't download necessary skills from GitHub Releases right now.\"\n : 'The Wizard may not work reliably while services are affected.';\n\n const handleDownloadAndExit = async () => {\n if (downloading) return;\n setDownloading(true);\n const menu = await fetchSkillMenu(REMOTE_SKILLS_BASE_URL);\n if (menu) {\n const prefix = `integration-${integration}`;\n const skills = (menu.categories['integration'] ?? []).filter((s) =>\n s.id.startsWith(prefix),\n );\n for (const skill of skills) {\n downloadSkill(skill, store.session.installDir, '.posthog/skills');\n }\n }\n setDownloaded(true);\n };\n\n const handleCancel =\n canDownloadSkills && !isGithubReleasesDown\n ? () => void handleDownloadAndExit()\n : () => void wizardAbort({ message: 'Exited due to service outage.' });\n\n const cancelLabel =\n canDownloadSkills && !isGithubReleasesDown\n ? downloading\n ? 'Downloading...'\n : 'Download skills & Exit [Esc]'\n : 'Exit [Esc]';\n\n // Blocking outage — show service list with Continue/Exit\n return (\n <ModalOverlay\n borderColor=\"red\"\n title={title}\n width={72}\n footer={\n isGithubReleasesDown ? (\n <ConfirmationInput\n message=\"\"\n confirmLabel=\"\"\n cancelLabel=\"Exit [Esc]\"\n onConfirm={() =>\n void wizardAbort({ message: 'Exited due to service outage.' })\n }\n onCancel={() =>\n void wizardAbort({ message: 'Exited due to service outage.' })\n }\n />\n ) : (\n <ConfirmationInput\n message=\"Continue anyway?\"\n confirmLabel=\"Continue [Enter]\"\n cancelLabel={cancelLabel}\n onConfirm={() => store.dismissOutage()}\n onCancel={handleCancel}\n />\n )\n }\n >\n <Box flexDirection=\"column\" marginBottom={1}>\n <Box marginBottom={1}>\n <Text>\n <Text color=\"red\">{Icons.squareFilled}</Text>\n <Text dimColor> Down </Text>\n <Text color=\"#DC9300\">{Icons.squareFilled}</Text>\n <Text dimColor> Degraded</Text>\n </Text>\n </Box>\n\n <ServiceHealthList\n health={result.health}\n filterKeys={blockingKeys}\n showHealthy={false}\n />\n </Box>\n\n <Text dimColor>{description}</Text>\n\n {isGithubReleasesDown && docsUrl && (\n <Box marginTop={1}>\n <Text>\n Set up manually: <Text color=\"cyan\">{docsUrl}</Text>\n </Text>\n </Box>\n )}\n\n {canDownloadSkills && !isGithubReleasesDown && (\n <Box marginTop={1}>\n <Text>\n You can still download the PostHog integration skills and continue\n with another agent.\n </Text>\n </Box>\n )}\n </ModalOverlay>\n );\n};\n","import { Box, Text } from 'ink';\nimport { useState, useSyncExternalStore } from 'react';\nimport type { WizardStore } from '../store.js';\nimport { ConfirmationInput, ModalOverlay } from '../primitives/index.js';\nimport { Icons } from '../styles.js';\nimport type { SettingsConflictSource } from '../../../lib/agent/agent-interface.js';\n\nfunction sourcePath(source: SettingsConflictSource): string {\n switch (source) {\n case 'project':\n return '.claude/settings.json';\n case 'managed':\n return '/Library/Application Support/ClaudeCode/managed-settings.json';\n default:\n return source;\n }\n}\n\ninterface SettingsOverrideScreenProps {\n store: WizardStore;\n}\n\nexport const SettingsOverrideScreen = ({\n store,\n}: SettingsOverrideScreenProps) => {\n useSyncExternalStore(\n (cb) => store.subscribe(cb),\n () => store.getSnapshot(),\n );\n\n const [feedback, setFeedback] = useState<string | null>(null);\n const conflicts = store.session.settingsConflicts?.filter((c) => c.writable);\n\n if (!conflicts || conflicts.length === 0) {\n return null;\n }\n\n return (\n <ModalOverlay\n borderColor=\"red\"\n title={`${Icons.warning} Settings conflict`}\n width={64}\n feedback={feedback ? `${Icons.warning} ${feedback}` : null}\n footer={\n <ConfirmationInput\n message=\"Back up to .wizard-backup and continue?\"\n confirmLabel=\"Backup & continue [Enter]\"\n cancelLabel=\"Exit [Esc]\"\n onConfirm={() => {\n const ok = store.backupAndFixSettingsOverride();\n if (!ok) {\n setFeedback('Could not back up the settings file.');\n }\n }}\n onCancel={() => process.exit(1)}\n />\n }\n >\n {conflicts.map((conflict) => (\n <Box key={conflict.source} flexDirection=\"column\" marginBottom={1}>\n <Text>\n Your settings file at{' '}\n <Text bold>{sourcePath(conflict.source)}</Text> sets:\n </Text>\n <Box flexDirection=\"column\" paddingLeft={2}>\n {conflict.keys.map((key) => (\n <Text key={key}>\n {Icons.bullet}{' '}\n <Text color=\"yellow\" bold>\n {key}\n </Text>\n </Text>\n ))}\n </Box>\n </Box>\n ))}\n <Text dimColor>\n These settings override credentials and prevent the Wizard from reaching\n the PostHog LLM Gateway. We can back up the file and continue.\n </Text>\n </ModalOverlay>\n );\n};\n","/**\n * ManagedSettingsScreen — Modal when IT/org-managed settings contain overrides\n * that block the Wizard from reaching the PostHog LLM Gateway.\n *\n * Unlike SettingsOverrideScreen, the wizard cannot back up or modify these files.\n * The user must contact their IT administrator to resolve the conflict.\n */\n\nimport { Box, Text } from 'ink';\nimport { useSyncExternalStore } from 'react';\nimport type { WizardStore } from '../store.js';\nimport { ConfirmationInput, ModalOverlay } from '../primitives/index.js';\nimport { Icons } from '../styles.js';\nimport type { SettingsConflict } from '../../../lib/agent/agent-interface.js';\n\nfunction sourceLabel(source: SettingsConflict['source']): string {\n switch (source) {\n case 'managed':\n return 'Managed settings (IT/org-managed)';\n case 'project':\n return '.claude/settings.json';\n default:\n return source;\n }\n}\n\ninterface ManagedSettingsScreenProps {\n store: WizardStore;\n}\n\nexport const ManagedSettingsScreen = ({\n store,\n}: ManagedSettingsScreenProps) => {\n useSyncExternalStore(\n (cb) => store.subscribe(cb),\n () => store.getSnapshot(),\n );\n\n const conflicts = store.session.settingsConflicts;\n const readOnlyConflicts = conflicts?.filter((c) => !c.writable);\n\n if (!readOnlyConflicts || readOnlyConflicts.length === 0) {\n return null;\n }\n\n return (\n <ModalOverlay\n borderColor=\"red\"\n title={`${Icons.warning} Organization settings conflict`}\n width={68}\n footer={\n <ConfirmationInput\n message=\"Contact your IT administrator to resolve this.\"\n confirmLabel=\"\"\n cancelLabel=\"Exit [Esc]\"\n onConfirm={() => process.exit(1)}\n onCancel={() => process.exit(1)}\n />\n }\n >\n <Text dimColor>\n Your organization&apos;s managed settings contain overrides that prevent\n the Wizard from reaching the PostHog LLM Gateway.\n </Text>\n {readOnlyConflicts.map((conflict) => (\n <Box key={conflict.source} flexDirection=\"column\" marginTop={1}>\n <Text bold>{sourceLabel(conflict.source)}</Text>\n <Box flexDirection=\"column\" paddingLeft={2}>\n {conflict.keys.map((key) => (\n <Text key={key}>\n {Icons.bullet}{' '}\n <Text color=\"yellow\" bold>\n {key}\n </Text>\n </Text>\n ))}\n </Box>\n </Box>\n ))}\n <Box marginTop={1}>\n <Text dimColor>\n Try running \"claude auth logout\" or contact your IT administrator to\n resolve this.\n </Text>\n </Box>\n </ModalOverlay>\n );\n};\n","/**\n * PortConflictScreen — Modal when all OAuth port candidates are occupied.\n *\n * Shows every port the wizard tried and asks the user to free them manually.\n */\n\nimport { Box, Text } from 'ink';\nimport { useSyncExternalStore } from 'react';\nimport type { WizardStore } from '../store.js';\nimport { OAUTH_PORTS } from '../../../lib/constants.js';\nimport { ConfirmationInput, ModalOverlay } from '../primitives/index.js';\n\ninterface PortConflictScreenProps {\n store: WizardStore;\n}\n\nexport const PortConflictScreen = ({ store }: PortConflictScreenProps) => {\n useSyncExternalStore(\n (cb) => store.subscribe(cb),\n () => store.getSnapshot(),\n );\n\n const processInfo = store.session.portConflictProcess;\n\n if (!processInfo) return null;\n\n return (\n <ModalOverlay\n borderColor=\"#DC9300\"\n title=\"OAuth ports in use\"\n width={72}\n footer={\n <ConfirmationInput\n message=\"Retry after freeing ports?\"\n confirmLabel=\"Retry [Enter]\"\n cancelLabel=\"Exit [Esc]\"\n onConfirm={() => store.resolvePortConflict()}\n onCancel={() => process.exit(1)}\n />\n }\n >\n <Text>\n The wizard needs a local port for OAuth. We tried these ports which are\n all in use:\n </Text>\n <Box flexDirection=\"column\" marginY={1} paddingLeft={2} gap={0}>\n {OAUTH_PORTS.map((port) => (\n <Text key={port}>\n <Text dimColor>Port </Text>\n <Text bold>{port}</Text>\n </Text>\n ))}\n </Box>\n <Text dimColor>Please free one of these ports and retry.</Text>\n </ModalOverlay>\n );\n};\n","/**\n * IntroScreenLayout ��� Shared visual shell for all workflow intro screens.\n *\n * Purely presentational — no store subscription. Parent components own\n * the store subscription and pass derived data as props.\n *\n * Slots:\n * body — free-form content below the title bar (copy, spinners, pickers, etc.)\n * children — between detection rows and menu (extra info, warnings)\n * errorView — replaces the entire body for fatal error states\n */\n\nimport path from 'path';\nimport { Box, Text } from 'ink';\nimport type { ReactNode } from 'react';\nimport { PickerMenu } from '../primitives/index.js';\n\nexport interface DetectionRow {\n label: string;\n value: string;\n suffix?: string;\n}\n\ninterface IntroScreenLayoutProps {\n /** Absolute path to the project directory */\n installDir: string;\n\n /** Title text after the colored blocks, e.g. \"PostHog Wizard 🦔\" */\n title?: string;\n\n /** Show the subtitle copy (\"We'll use AI…\" / \".env*…\"). Default true. */\n showSubtitle?: boolean;\n\n /** Free-form content below the title (copy, spinners, pickers, notices) */\n body?: ReactNode;\n\n /** Show the detection block (Directory, detection rows, Workflow, Skill). Default true. */\n showDetection?: boolean;\n\n /** Extra detection row items rendered as \"Label ✔ value suffix\" */\n detectionRows?: DetectionRow[];\n\n /** Content rendered between detection rows and the menu */\n children?: ReactNode;\n\n /** Menu options. Pass null to hide the menu entirely. */\n menuOptions?: { label: string; value: string }[] | null;\n\n /** Called when the user picks a menu option */\n onSelect?: (value: string) => void;\n\n /** Workflow label shown at the bottom */\n workflowLabel?: string | null;\n\n /** Skill ID shown at the bottom */\n skillId?: string | null;\n\n /** Replaces the entire body (topContent + rows + children + menu) for fatal error views */\n errorView?: ReactNode;\n}\n\nconst WizardTitle = ({ title }: { title: string }) => (\n <Text bold>\n <Text color=\"#1D4AFF\">{'\\u2588'}</Text>\n <Text color=\"#F54E00\">{'\\u2588'}</Text>\n <Text color=\"#F9BD2B\">{'\\u2588'}</Text> {title}\n </Text>\n);\n\nexport const IntroScreenLayout = ({\n installDir,\n title = 'PostHog Wizard 🦔',\n showSubtitle = true,\n body,\n showDetection = true,\n detectionRows,\n children,\n menuOptions,\n onSelect,\n workflowLabel,\n skillId,\n errorView,\n}: IntroScreenLayoutProps) => {\n // Default menu: Continue / Cancel\n const resolvedMenuOptions =\n menuOptions === undefined\n ? [\n { label: 'Continue', value: 'continue' },\n { label: 'Cancel', value: 'cancel' },\n ]\n : menuOptions;\n\n if (errorView) {\n return (\n <Box\n flexDirection=\"column\"\n flexGrow={1}\n alignItems=\"center\"\n justifyContent=\"center\"\n >\n <Box flexDirection=\"column\" alignItems=\"center\" marginBottom={1}>\n <WizardTitle title={title} />\n </Box>\n {errorView}\n </Box>\n );\n }\n\n return (\n <>\n <Box\n flexDirection=\"column\"\n flexGrow={1}\n alignItems=\"center\"\n justifyContent=\"center\"\n >\n <Box flexDirection=\"column\" alignItems=\"center\">\n <WizardTitle title={title} />\n\n {showSubtitle && (\n <Box flexDirection=\"column\" alignItems=\"center\" marginTop={1}>\n <Text dimColor>\n We'll use AI to analyze your project and complete work.\n </Text>\n <Text dimColor>\n .env* file contents will not leave your machine.\n </Text>\n </Box>\n )}\n\n {body && (\n <Box flexDirection=\"column\" alignItems=\"center\" marginTop={1}>\n {body}\n </Box>\n )}\n </Box>\n\n {children}\n\n {showDetection && (\n <Box flexDirection=\"column\" marginTop={1}>\n <Text>\n <Text>\n Directory <Text color=\"green\">{'\\u2714'}</Text>{' '}\n </Text>\n <Text>\n {'/'}\n {path.basename(installDir)}\n </Text>\n </Text>\n\n {detectionRows?.map((row) => (\n <Text key={row.label}>\n <Text>\n {row.label} <Text color=\"green\">{'\\u2714'}</Text>{' '}\n </Text>\n <Text>\n {row.value}\n {row.suffix ? ` ${row.suffix}` : ''}\n </Text>\n </Text>\n ))}\n\n {workflowLabel && (\n <Text>\n Workflow{' '}\n <Text color=\"green\">{'\\u2714'}</Text> {workflowLabel}\n </Text>\n )}\n\n {workflowLabel === 'agent-skill' && skillId && (\n <Text>\n Skill{' '}\n <Text color=\"green\">{'\\u2714'}</Text> {skillId}\n </Text>\n )}\n </Box>\n )}\n\n <Box width={24}>\n {resolvedMenuOptions && onSelect && (\n <Box justifyContent=\"center\">\n <PickerMenu\n key={resolvedMenuOptions.map((o) => o.value).join(',')}\n options={resolvedMenuOptions}\n onSelect={(value) => {\n const choice = Array.isArray(value) ? value[0] : value;\n onSelect(choice);\n }}\n />\n </Box>\n )}\n </Box>\n </Box>\n </>\n );\n};\n","/**\n * PostHogIntegrationIntroScreen — Intro screen for the core PostHog integration.\n *\n * Composes IntroScreenLayout with framework-detection-specific state:\n * 1. Detecting: spinner while detection runs\n * 2. Detection failed: framework picker\n * 3. Unsupported version: upgrade prompt\n * 4. Detection succeeded: continue/change-framework/cancel\n */\n\nimport { Box, Text } from 'ink';\nimport type { ReactNode } from 'react';\nimport { useState, useSyncExternalStore } from 'react';\nimport type { WizardStore } from '../store.js';\nimport { Integration } from '../../../lib/constants.js';\nimport { PickerMenu, LoadingBox } from '../primitives/index.js';\nimport { IntroScreenLayout, type DetectionRow } from './IntroScreenLayout.js';\nimport { CONTEXT_MILL_URL } from '../../../lib/constants.js';\n\n/** Framework picker shown when auto-detection fails. */\nconst FrameworkPicker = ({\n store,\n onComplete,\n}: {\n store: WizardStore;\n onComplete?: () => void;\n}) => {\n const options = Object.values(Integration).map((value) => ({\n label: value,\n value,\n }));\n\n return (\n <PickerMenu<Integration>\n centered\n columns={2}\n message=\"Select your framework\"\n options={options}\n onSelect={(value) => {\n const integration = Array.isArray(value) ? value[0] : value;\n void import('../../../lib/registry.js').then(\n ({ FRAMEWORK_REGISTRY }) => {\n const config = FRAMEWORK_REGISTRY[integration];\n store.setFrameworkConfig(integration, config);\n store.setDetectedFramework(config.metadata.name);\n onComplete?.();\n },\n );\n }}\n />\n );\n};\n\ninterface PostHogIntegrationIntroScreenProps {\n store: WizardStore;\n}\n\nexport const PostHogIntegrationIntroScreen = ({\n store,\n}: PostHogIntegrationIntroScreenProps) => {\n useSyncExternalStore(\n (cb) => store.subscribe(cb),\n () => store.getSnapshot(),\n );\n\n const [pickingFramework, setPickingFramework] = useState(false);\n const [manuallySelected, setManuallySelected] = useState(false);\n const [showingMoreInfo, setShowingMoreInfo] = useState(false);\n\n const { session } = store;\n const config = session.frameworkConfig;\n const frameworkLabel =\n session.detectedFrameworkLabel ?? config?.metadata.name;\n const detecting = !session.detectionComplete;\n const needsFrameworkPick =\n session.detectionComplete && !session.frameworkConfig;\n const unsupported = session.unsupportedVersion;\n const showContinue =\n session.frameworkConfig !== null &&\n !detecting &&\n !pickingFramework &&\n !showingMoreInfo &&\n !unsupported;\n\n // ── Title ──────────────────────────────────────────────────────────\n\n const title = detecting ? 'PostHog Wizard starting up' : 'PostHog Wizard 🦔';\n\n // ── Description ────────────────────────────────────────────────────\n\n let body: ReactNode = null;\n\n if (detecting) {\n body = (\n <Box marginY={1}>\n <LoadingBox message=\"Detecting project framework...\" />\n </Box>\n );\n } else if (needsFrameworkPick && !pickingFramework) {\n body = (\n <>\n <Box marginY={1}>\n <Text dimColor>Could not auto-detect your framework.</Text>\n </Box>\n <FrameworkPicker\n store={store}\n onComplete={() => setPickingFramework(false)}\n />\n </>\n );\n } else if (pickingFramework) {\n body = (\n <FrameworkPicker\n store={store}\n onComplete={() => setPickingFramework(false)}\n />\n );\n } else if (showingMoreInfo) {\n body = (\n <Box flexDirection=\"column\" width={56}>\n <Text>\n The wizard is an agent that executes PostHog tasks. Its code is open\n source: <Text color=\"cyan\">https://github.com/PostHog/wizard</Text>\n </Text>\n <Box flexDirection=\"column\" marginTop={1}>\n <Text>\n The{' '}\n <Text italic color=\"cyan\">\n {session.workflowLabel}\n </Text>{' '}\n workflow installs the PostHog SDKs, instruments event tracking, and\n integrates the following dev tools for your application:\n </Text>\n </Box>\n <Box flexDirection=\"column\" marginTop={1} paddingLeft={4}>\n <Text>{`\\u2022`} Product Analytics</Text>\n <Text>{`\\u2022`} Web Analytics</Text>\n <Text>{`\\u2022`} Session Replay</Text>\n <Text>{`\\u2022`} Error Tracking</Text>\n </Box>\n <Box flexDirection=\"column\" marginTop={1}>\n <Text>\n If you prefer your own AI setup, download the skill:{' '}\n <Text color=\"cyan\">{CONTEXT_MILL_URL}/releases</Text>\n </Text>\n </Box>\n </Box>\n );\n } else if (showContinue) {\n body = (\n <>\n <Box>\n <Text>Let's do two hours of work in eight minutes.</Text>\n </Box>\n </>\n );\n }\n\n // ── Detection rows ─────────────────────────────────────────────────\n\n const detectionRows: DetectionRow[] = [];\n if (frameworkLabel) {\n const suffixParts: string[] = [];\n if (!manuallySelected) suffixParts.push('(detected)');\n if (config?.metadata.beta) suffixParts.push('[BETA]');\n\n detectionRows.push({\n label: 'Framework',\n value: frameworkLabel,\n suffix: suffixParts.join(' ') || undefined,\n });\n }\n\n // ── Children (between rows and menu) ───────────────────────────────\n\n let bodyChildren: ReactNode = null;\n\n if (config?.metadata.preRunNotice) {\n bodyChildren = <Text color=\"yellow\">{config.metadata.preRunNotice}</Text>;\n }\n\n if (unsupported) {\n bodyChildren = (\n <Box flexDirection=\"column\" marginTop={1}>\n <Text color=\"#DC9300\">\n Version {unsupported.current} is not supported by the wizard. Please\n upgrade to {unsupported.minimum} or later.\n </Text>\n <Text dimColor>Manual setup guide: {unsupported.docsUrl}</Text>\n <Box marginTop={1}>\n <Text dimColor>\n Did we get this wrong? You can also select another framework.\n </Text>\n </Box>\n <PickerMenu\n options={[\n { label: 'Select another framework', value: 'framework' },\n { label: 'Exit', value: 'exit' },\n ]}\n onSelect={(value) => {\n const choice = Array.isArray(value) ? value[0] : value;\n if (choice === 'framework') {\n setPickingFramework(true);\n setManuallySelected(true);\n } else {\n process.exit(0);\n }\n }}\n />\n </Box>\n );\n }\n\n // ── Menu ───────────────────────────────────────────────────────────\n\n let menuOptions: { label: string; value: string }[] | null = null;\n\n if (showingMoreInfo) {\n menuOptions = [{ label: 'Back', value: 'back' }];\n } else if (showContinue) {\n menuOptions = [\n { label: 'Continue', value: 'continue' },\n { label: 'Change framework', value: 'framework' },\n { label: 'More info', value: 'more-info' },\n { label: 'Cancel', value: 'cancel' },\n ];\n }\n\n const handleSelect = (value: string) => {\n if (value === 'cancel') {\n process.exit(0);\n } else if (value === 'framework') {\n setPickingFramework(true);\n setManuallySelected(true);\n } else if (value === 'more-info') {\n setShowingMoreInfo(true);\n } else if (value === 'back') {\n setShowingMoreInfo(false);\n } else {\n store.completeSetup();\n }\n };\n\n // ── Render ─────────────────────────────────────────────────────────\n\n return (\n <IntroScreenLayout\n installDir={session.installDir}\n title={title}\n showSubtitle={!showingMoreInfo}\n body={body}\n showDetection={showContinue}\n detectionRows={detectionRows}\n menuOptions={unsupported ? null : menuOptions}\n onSelect={handleSelect}\n workflowLabel={session.workflowLabel}\n skillId={session.skillId}\n >\n {bodyChildren}\n </IntroScreenLayout>\n );\n};\n","/**\n * RevenueIntroScreen — Welcome screen for the revenue analytics flow.\n *\n * Composes IntroScreenLayout with SDK-detection-specific state:\n * - Detection succeeded: shows detected PostHog + Stripe SDKs, continue/cancel\n * - Detection failed: shows the error via errorView + exit prompt\n *\n * Reads `frameworkContext.detectError` and `frameworkContext.detectedPosthogSdks`\n * / `detectedStripeSdks` set by detectRevenuePrerequisites().\n */\n\nimport { Box, Text } from 'ink';\nimport { useState, useSyncExternalStore } from 'react';\nimport type { WizardStore } from '../store.js';\nimport { PickerMenu } from '../primitives/index.js';\nimport { IntroScreenLayout, type DetectionRow } from './IntroScreenLayout.js';\nimport {\n POSTHOG_SDKS,\n STRIPE_SDKS,\n type RevenueDetectError,\n} from '../../../lib/workflows/revenue-analytics/index.js';\n\ninterface RevenueIntroScreenProps {\n store: WizardStore;\n}\n\nexport const RevenueIntroScreen = ({ store }: RevenueIntroScreenProps) => {\n useSyncExternalStore(\n (cb) => store.subscribe(cb),\n () => store.getSnapshot(),\n );\n\n const [showingMoreInfo, setShowingMoreInfo] = useState(false);\n\n const { session } = store;\n const detectError = session.frameworkContext.detectError as\n | RevenueDetectError\n | undefined;\n const detectedPosthogSdks =\n (session.frameworkContext.detectedPosthogSdks as string[] | undefined) ??\n [];\n const detectedStripeSdks =\n (session.frameworkContext.detectedStripeSdks as string[] | undefined) ?? [];\n const detectedPackagePaths =\n (session.frameworkContext.detectedPackagePaths as string[] | undefined) ??\n [];\n\n // ── Detection rows ─────────────────────────────────────────────────\n\n const detectionRows: DetectionRow[] = [];\n if (detectedPosthogSdks.length > 0) {\n detectionRows.push({\n label: 'PostHog SDK',\n value: detectedPosthogSdks.join(', '),\n });\n }\n if (detectedStripeSdks.length > 0) {\n detectionRows.push({\n label: 'Stripe SDK',\n value: detectedStripeSdks.join(', '),\n });\n }\n\n // ── Body ────────────────────────────────────────────────────────────\n\n const body = showingMoreInfo ? (\n <Box flexDirection=\"column\" width={56}>\n <Text>\n The wizard is an agent that executes PostHog tasks. Its code is open\n source: <Text color=\"cyan\">https://github.com/PostHog/wizard</Text>.\n </Text>\n <Box flexDirection=\"column\" marginTop={1}>\n <Text>\n The{' '}\n <Text italic color=\"cyan\">\n {session.workflowLabel}\n </Text>{' '}\n workflow links Stripe customers and purchases to PostHog product data\n and persons. It unlocks insights like:\n </Text>\n </Box>\n <Box flexDirection=\"column\" marginTop={1} paddingLeft={4}>\n <Text>{'\\u2022'} Revenue per user</Text>\n <Text>{'\\u2022'} Lifetime value</Text>\n <Text>{'\\u2022'} MRR / churn tracking</Text>\n </Box>\n </Box>\n ) : (\n <>\n <Box flexDirection=\"column\" alignItems=\"center\">\n <Text>Let's create revenue analytics with Stripe and PostHog.</Text>\n <Box flexDirection=\"column\" marginTop={1}>\n <Text>Link purchases to product data.</Text>\n </Box>\n </Box>\n\n {detectedPackagePaths.length > 1 && (\n <Box flexDirection=\"column\" marginTop={1}>\n <Text dimColor>Found in {detectedPackagePaths.length} packages:</Text>\n {detectedPackagePaths.map((p) => (\n <Text key={p} dimColor>\n {' '}\n {'\\u2022'} {p}\n </Text>\n ))}\n </Box>\n )}\n </>\n );\n\n // ── Error view ─────────────────────────────────────────────────────\n\n const errorView = detectError ? (\n <>\n <Box flexDirection=\"column\" marginBottom={1}>\n <Text color=\"red\" bold>\n {'\\u2718'} Cannot set up revenue analytics\n </Text>\n <Box marginTop={1} flexDirection=\"column\">\n <DetectErrorBody error={detectError} />\n </Box>\n </Box>\n\n <PickerMenu\n options={[{ label: 'Exit', value: 'exit' }]}\n onSelect={() => process.exit(1)}\n />\n </>\n ) : undefined;\n\n // ── Menu ───────────────────────────────────────────────────────────\n const menuOptions = showingMoreInfo\n ? [{ label: 'Back', value: 'back' }]\n : [\n { label: 'Continue', value: 'continue' },\n { label: 'More info', value: 'more-info' },\n { label: 'Cancel', value: 'cancel' },\n ];\n // ── Render ─────────────────────────────────────────────────────────\n\n return (\n <IntroScreenLayout\n installDir={session.installDir}\n showSubtitle={!showingMoreInfo}\n body={body}\n showDetection={!showingMoreInfo}\n detectionRows={detectionRows}\n errorView={errorView}\n workflowLabel={session.workflowLabel}\n skillId={session.skillId}\n menuOptions={menuOptions}\n onSelect={(value) => {\n if (value === 'cancel') {\n process.exit(0);\n } else if (value === 'more-info') {\n setShowingMoreInfo(true);\n } else if (value === 'back') {\n setShowingMoreInfo(false);\n } else {\n store.completeSetup();\n }\n }}\n />\n );\n};\n\nconst DetectErrorBody = ({ error }: { error: RevenueDetectError }) => {\n switch (error.kind) {\n case 'bad-directory': {\n const reasonText = {\n missing: 'does not exist',\n 'not-dir': 'is not a directory',\n unreadable: 'could not be accessed',\n }[error.reason];\n return (\n <>\n <Text>This path {reasonText}:</Text>\n <Text dimColor>\n {' '}\n {error.path}\n </Text>\n </>\n );\n }\n\n case 'no-package-json':\n return (\n <>\n <Text>No package.json found in this directory.</Text>\n <Text dimColor>\n Revenue analytics currently supports Node.js / TypeScript projects.\n </Text>\n <Text dimColor>Run this command from your project root.</Text>\n </>\n );\n\n case 'no-sdks':\n return (\n <>\n <Text>\n Neither PostHog nor Stripe SDKs detected (scanned{' '}\n {error.scannedCount} package.json file\n {error.scannedCount === 1 ? '' : 's'}).\n </Text>\n <Box marginTop={1} flexDirection=\"column\">\n <Text>Revenue analytics requires:</Text>\n <Text dimColor>\n {' \\u2022'} A PostHog SDK ({POSTHOG_SDKS.slice(0, 3).join(', ')},\n …)\n </Text>\n <Text dimColor>\n {' \\u2022'} A Stripe SDK ({STRIPE_SDKS.join(', ')})\n </Text>\n </Box>\n <Box marginTop={1}>\n <Text dimColor>\n Install Stripe and run <Text bold>npx @posthog/wizard</Text> to\n set up PostHog.\n </Text>\n </Box>\n </>\n );\n\n case 'missing-posthog':\n return (\n <>\n <Text>\n Found Stripe ({error.foundStripe.join(', ')}) but no PostHog SDK.\n </Text>\n <Box marginTop={1}>\n <Text dimColor>\n Run <Text bold>npx @posthog/wizard</Text> first to set up the base\n PostHog integration.\n </Text>\n </Box>\n </>\n );\n\n case 'missing-stripe':\n return (\n <>\n <Text>\n Found PostHog ({error.foundPosthog.join(', ')}) but no Stripe SDK.\n </Text>\n <Text dimColor>\n Revenue analytics currently supports Stripe only.\n </Text>\n <Box marginTop={1} flexDirection=\"column\">\n <Text dimColor>Install one of:</Text>\n {STRIPE_SDKS.map((sdk) => (\n <Text key={sdk} dimColor>\n {' \\u2022'} {sdk}\n </Text>\n ))}\n </Box>\n </>\n );\n }\n};\n","/**\n * AgentSkillIntroScreen — Intro screen for the generic agent-skill workflow.\n *\n * Main menu: one-liner body, detection rows, continue/cancel.\n * More info: skill name, download URL fetched from the skill menu.\n */\n\nimport { Box, Text } from 'ink';\nimport type { ReactNode } from 'react';\nimport { useState, useEffect, useSyncExternalStore } from 'react';\nimport type { WizardStore } from '../store.js';\nimport { IntroScreenLayout } from './IntroScreenLayout.js';\nimport { fetchSkillMenu, type SkillEntry } from '../../../lib/wizard-tools.js';\nimport { getSkillsBaseUrl } from '../../../lib/constants.js';\n\ninterface AgentSkillIntroScreenProps {\n store: WizardStore;\n}\n\nexport const AgentSkillIntroScreen = ({\n store,\n}: AgentSkillIntroScreenProps) => {\n useSyncExternalStore(\n (cb) => store.subscribe(cb),\n () => store.getSnapshot(),\n );\n\n const [showingMoreInfo, setShowingMoreInfo] = useState(false);\n const [skillEntry, setSkillEntry] = useState<SkillEntry | null>(null);\n const [fetchFailed, setFetchFailed] = useState(false);\n\n const { session } = store;\n const skillId = session.skillId ?? 'unknown';\n const isMainMenu = !showingMoreInfo;\n\n // Fetch skill entry from the menu when more-info is first opened\n useEffect(() => {\n if (!showingMoreInfo || skillEntry || fetchFailed) return;\n\n const baseUrl = getSkillsBaseUrl(session.localMcp);\n void fetchSkillMenu(baseUrl).then((menu) => {\n if (!menu) {\n setFetchFailed(true);\n return;\n }\n const allSkills = Object.values(menu.categories).flat();\n const match = allSkills.find((s) => s.id === skillId);\n if (match) {\n setSkillEntry(match);\n } else {\n setFetchFailed(true);\n }\n });\n }, [showingMoreInfo, skillEntry, fetchFailed, skillId, session.localMcp]);\n\n // ── Body ─────────────────────────────────────────────────────────────\n\n let body: ReactNode;\n\n if (showingMoreInfo) {\n body = (\n <Box flexDirection=\"column\" width={56}>\n <Box flexDirection=\"column\" marginBottom={1}>\n <Text>\n The wizard is an agent that executes PostHog tasks. Its code is open\n source: <Text color=\"cyan\">https://github.com/PostHog/wizard</Text>\n </Text>\n </Box>\n <Text>\n Skill:{' '}\n <Text italic color=\"cyan\">\n {skillEntry?.id ?? skillId}\n </Text>\n </Text>\n <Text>\n URL:{' '}\n <Text color=\"cyan\">\n {skillEntry?.downloadUrl ??\n (fetchFailed ? 'unavailable' : 'Loading...')}\n </Text>\n </Text>\n <Box marginTop={1}>\n <Text dimColor>\n {skillEntry?.name ?? (fetchFailed ? skillId : 'Loading...')}\n </Text>\n </Box>\n </Box>\n );\n } else {\n body = (\n <Text>\n Let's run the{' '}\n <Text italic color=\"cyan\">\n {skillId}\n </Text>{' '}\n skill.\n </Text>\n );\n }\n\n // ── Menu ─────────────────────────────────────────────────────────────\n\n const menuOptions = showingMoreInfo\n ? [{ label: 'Back', value: 'back' }]\n : [\n { label: 'Continue', value: 'continue' },\n { label: 'More info', value: 'more-info' },\n { label: 'Cancel', value: 'cancel' },\n ];\n\n const handleSelect = (value: string) => {\n if (value === 'cancel') {\n process.exit(0);\n } else if (value === 'more-info') {\n setShowingMoreInfo(true);\n } else if (value === 'back') {\n setShowingMoreInfo(false);\n } else {\n store.completeSetup();\n }\n };\n\n // ── Render ───────────────────────────────────────────────────────────\n\n return (\n <IntroScreenLayout\n installDir={session.installDir}\n showSubtitle={!showingMoreInfo}\n body={body}\n showDetection={isMainMenu}\n workflowLabel={session.workflowLabel}\n skillId={session.skillId}\n menuOptions={menuOptions}\n onSelect={handleSelect}\n />\n );\n};\n","/**\n * SetupScreen — Generic framework disambiguation.\n *\n * Iterates unresolved setup questions from the FrameworkConfig\n * and renders a PickerMenu for each. If all questions are auto-resolved,\n * this screen is skipped entirely (the router skips it via its show() predicate).\n */\n\nimport { Box, Text } from 'ink';\nimport { useState, useEffect } from 'react';\nimport { useSyncExternalStore } from 'react';\nimport type { WizardStore } from '../store.js';\nimport { PickerMenu } from '../primitives/index.js';\nimport { Colors } from '../styles.js';\nimport type { SetupQuestion } from '../../../lib/framework-config.js';\n\ninterface SetupScreenProps {\n store: WizardStore;\n}\n\nexport const SetupScreen = ({ store }: SetupScreenProps) => {\n useSyncExternalStore(\n (cb) => store.subscribe(cb),\n () => store.getSnapshot(),\n );\n\n const config = store.session.frameworkConfig;\n const questions = config?.metadata.setup?.questions ?? [];\n\n // Track which question index we're currently showing\n const [currentIndex, setCurrentIndex] = useState(0);\n const [resolving, setResolving] = useState(true);\n\n // On mount, run auto-detection for all questions\n useEffect(() => {\n void (async () => {\n for (const q of questions) {\n // Skip if already resolved (e.g. by CLI arg)\n if (q.key in store.session.frameworkContext) continue;\n\n try {\n const detected = await q.detect({\n installDir: store.session.installDir,\n });\n if (detected !== null) {\n store.setFrameworkContext(q.key, detected);\n }\n } catch {\n // Detection failed — will ask the user\n }\n }\n setResolving(false);\n\n // If all resolved, the router's isComplete predicate will\n // resolve past this screen on the next render cycle.\n })();\n }, []);\n\n if (resolving) {\n return (\n <Box flexDirection=\"column\" flexGrow={1}>\n <Text dimColor>Detecting project configuration...</Text>\n </Box>\n );\n }\n\n // Get unresolved questions\n const unresolved = questions.filter(\n (q: SetupQuestion) => !(q.key in store.session.frameworkContext),\n );\n\n if (unresolved.length === 0) {\n // All resolved — should have already advanced\n return null;\n }\n\n const question = unresolved[currentIndex] ?? unresolved[0];\n if (!question) return null;\n\n return (\n <Box flexDirection=\"column\" flexGrow={1}>\n <Box flexDirection=\"column\" marginBottom={1}>\n <Text bold color={Colors.accent}>\n Project Setup\n </Text>\n {config && (\n <Text dimColor>Configuring {config.metadata.name} integration</Text>\n )}\n </Box>\n\n <PickerMenu<string>\n message={question.message}\n options={question.options.map((o) => ({\n label: o.label,\n value: o.value,\n hint: o.hint,\n }))}\n onSelect={(value) => {\n const selected = Array.isArray(value) ? value[0] : value;\n store.setFrameworkContext(question.key, selected);\n\n // Check if more unresolved questions remain\n const remaining = unresolved.filter(\n (q: SetupQuestion) =>\n q.key !== question.key &&\n !(q.key in store.session.frameworkContext),\n );\n\n if (remaining.length > 0) {\n setCurrentIndex((i) => i + 1);\n }\n // When no remaining questions, setFrameworkContext already\n // triggered emitChange — router resolves past this screen.\n }}\n />\n </Box>\n );\n};\n","/**\n * AuthScreen — Shown while waiting for OAuth authentication.\n *\n * Displays framework detection results, beta/disclosure notices,\n * a waiting spinner, and the login URL when available.\n * The router resolves past this screen once session.credentials is set.\n */\n\nimport { Box, Text } from 'ink';\nimport { useSyncExternalStore } from 'react';\nimport type { WizardStore } from '../store.js';\nimport { LoadingBox } from '../primitives/index.js';\nimport { Colors } from '../styles.js';\n\ninterface AuthScreenProps {\n store: WizardStore;\n}\n\nexport const AuthScreen = ({ store }: AuthScreenProps) => {\n useSyncExternalStore(\n (cb) => store.subscribe(cb),\n () => store.getSnapshot(),\n );\n\n const { session } = store;\n const config = session.frameworkConfig;\n const frameworkLabel =\n session.detectedFrameworkLabel ?? config?.metadata.name;\n\n return (\n <Box flexDirection=\"column\" flexGrow={1}>\n <Box flexDirection=\"column\" marginBottom={1}>\n <Text bold color={Colors.accent}>\n PostHog Setup Wizard\n </Text>\n\n {frameworkLabel && (\n <Text>\n <Text color=\"green\">{'\\u2714'} </Text>\n <Text>Framework: {frameworkLabel}</Text>\n </Text>\n )}\n\n {config?.metadata.beta && (\n <Text color=\"yellow\">\n [BETA] The {config.metadata.name} wizard is in beta. Questions or\n feedback? Email wizard@posthog.com\n </Text>\n )}\n\n {config?.metadata.preRunNotice && (\n <Text color=\"yellow\">{config.metadata.preRunNotice}</Text>\n )}\n </Box>\n\n <LoadingBox message=\"Waiting for authentication...\" />\n\n {session.loginUrl && (\n <Box marginTop={1} flexDirection=\"column\">\n <Text dimColor>\n If the browser didn't open, copy and paste this URL:\n </Text>\n <Text color=\"cyan\">{session.loginUrl}</Text>\n </Box>\n )}\n </Box>\n );\n};\n","/**\n * RunScreen — Tabbed observational view of the agent run.\n *\n * Two tabs:\n * - Status: SplitView with LearnCard (left) + ProgressList (right)\n * - Logs: LogViewer tailing the wizard log file\n *\n * No prompts — the agent runs headlessly.\n * LearnCard shows animated educational content and reacts to discovered features.\n */\n\nimport { useSyncExternalStore } from 'react';\nimport { Box } from 'ink';\nimport type { WizardStore } from '../store.js';\nimport {\n TabContainer,\n SplitView,\n ProgressList,\n LogViewer,\n EventPlanViewer,\n HNViewer,\n} from '../primitives/index.js';\nimport type { ProgressItem } from '../primitives/index.js';\nimport { ADDITIONAL_FEATURE_LABELS } from '../../../lib/wizard-session.js';\nimport { LearnCard } from '../components/LearnCard.js';\nimport { TipsCard } from '../components/TipsCard.js';\nimport { useStdoutDimensions } from '../hooks/useStdoutDimensions.js';\n\nconst LOG_FILE = '/tmp/posthog-wizard.log';\n\ninterface RunScreenProps {\n store: WizardStore;\n}\n\nexport const RunScreen = ({ store }: RunScreenProps) => {\n useSyncExternalStore(\n (cb) => store.subscribe(cb),\n () => store.getSnapshot(),\n );\n\n const [columns] = useStdoutDimensions();\n\n const progressItems: ProgressItem[] = store.tasks.map((t) => ({\n label: t.label,\n activeForm: t.activeForm,\n status: t.status,\n }));\n\n // When all tasks are done but the queue has features, show a transitional item\n const queue = store.session.additionalFeatureQueue;\n const allDone =\n progressItems.length > 0 &&\n progressItems.every((t) => t.status === 'completed');\n if (allDone && queue.length > 0) {\n const nextLabel = ADDITIONAL_FEATURE_LABELS[queue[0]];\n progressItems.push({\n label: `Set up ${nextLabel}`,\n activeForm: `Setting up ${nextLabel}...`,\n status: 'in_progress',\n });\n }\n\n const statuses =\n store.statusMessages.length > 0 ? store.statusMessages : undefined;\n\n const leftPane = store.learnCardComplete ? (\n <TipsCard store={store} />\n ) : (\n <LearnCard store={store} onComplete={() => store.setLearnCardComplete()} />\n );\n const progressList = <ProgressList items={progressItems} title=\"Tasks\" />;\n\n // On narrow terminals, drop the learn pane and show only progress\n const statusComponent =\n columns < 80 ? (\n <Box flexDirection=\"column\" flexGrow={1}>\n {progressList}\n </Box>\n ) : (\n <SplitView left={leftPane} right={progressList} />\n );\n\n const tabs = [\n {\n id: 'status',\n label: 'Status',\n component: statusComponent,\n },\n ...(store.eventPlan.length > 0\n ? [\n {\n id: 'events',\n label: 'Event plan',\n component: <EventPlanViewer events={store.eventPlan} />,\n },\n ]\n : []),\n {\n id: 'logs',\n label: 'Tail logs',\n component: <LogViewer filePath={LOG_FILE} />,\n },\n {\n id: 'hn',\n label: 'HN',\n component: <HNViewer />,\n },\n ];\n\n return (\n <TabContainer\n tabs={tabs}\n statusMessage={statuses}\n expandableStatus\n store={store}\n />\n );\n};\n","/**\n * KeepSkillsScreen — Ask whether to keep installed skills in .claude/skills/.\n *\n * Shown after the outro summary so users see the agent's output first,\n * then decide whether to keep the skills that powered it.\n *\n * When done, calls store.setSkillsComplete() and exits the process.\n */\n\nimport { Box, Text } from 'ink';\nimport { useState, useEffect } from 'react';\nimport { useSyncExternalStore } from 'react';\nimport { readdir, rm } from 'node:fs/promises';\nimport { join } from 'node:path';\nimport type { WizardStore } from '../store.js';\nimport { ConfirmationInput } from '../primitives/index.js';\nimport { Colors } from '../styles.js';\nimport { CONTEXT_MILL_URL } from '../../../lib/constants.js';\n\ninterface KeepSkillsScreenProps {\n store: WizardStore;\n}\n\ninterface SkillEntry {\n name: string;\n children: string[];\n}\n\nenum Phase {\n Loading = 'loading',\n Ask = 'ask',\n Removing = 'removing',\n Done = 'done',\n}\n\nexport const KeepSkillsScreen = ({ store }: KeepSkillsScreenProps) => {\n useSyncExternalStore(\n (cb) => store.subscribe(cb),\n () => store.getSnapshot(),\n );\n\n const [phase, setPhase] = useState<Phase>(Phase.Loading);\n const [skills, setSkills] = useState<SkillEntry[]>([]);\n\n const skillsDir = join(store.session.installDir, '.claude', 'skills');\n\n useEffect(() => {\n void (async () => {\n try {\n const entries = await readdir(skillsDir, { withFileTypes: true });\n const dirs = entries.filter((e) => e.isDirectory());\n const result: SkillEntry[] = [];\n for (const dir of dirs) {\n const children = await readdir(join(skillsDir, dir.name));\n result.push({ name: dir.name, children });\n }\n if (result.length === 0) {\n store.setSkillsComplete(true);\n process.exit(0);\n }\n setSkills(result);\n setPhase(Phase.Ask);\n } catch {\n store.setSkillsComplete(true);\n process.exit(0);\n }\n })();\n }, []); // eslint-disable-line\n\n const handleKeep = () => {\n store.setSkillsComplete(true);\n process.exit(0);\n };\n\n const handleRemove = async () => {\n setPhase(Phase.Removing);\n try {\n await rm(skillsDir, { recursive: true, force: true });\n } catch {\n // Best-effort removal\n }\n setPhase(Phase.Done);\n // Give React a tick to paint the \"Skills removed.\" message before exit\n setTimeout(() => {\n store.setSkillsComplete(false);\n process.exit(0);\n }, 600);\n };\n\n return (\n <Box flexDirection=\"column\" flexGrow={1}>\n <Text bold color={Colors.accent}>\n Keep the skills?\n </Text>\n\n <Box marginTop={1} flexDirection=\"column\">\n {phase === Phase.Loading && (\n <Text dimColor>Checking installed skills...</Text>\n )}\n\n {phase === Phase.Ask && (\n <>\n <Text dimColor>\n The wizard installed open-source skills that help AI coding agents\n integrate PostHog into your project:\n </Text>\n <Box marginTop={1} flexDirection=\"column\" marginLeft={2}>\n <Text dimColor>.claude/</Text>\n <Text dimColor> skills/</Text>\n {skills.map((skill) => (\n <Box key={skill.name} flexDirection=\"column\">\n <Text dimColor> {skill.name}/</Text>\n {skill.children.map((child) => (\n <Text key={child} dimColor>\n {' '}\n {child}\n </Text>\n ))}\n </Box>\n ))}\n </Box>\n <Box marginTop={1}>\n <Text dimColor>\n Source: <Text color=\"cyan\">{CONTEXT_MILL_URL}</Text>\n </Text>\n </Box>\n <Box marginTop={1}>\n <ConfirmationInput\n message=\"Keep the installed skills?\"\n confirmLabel=\"Keep [Enter]\"\n cancelLabel=\"Remove [Esc]\"\n onConfirm={handleKeep}\n onCancel={() => void handleRemove()}\n />\n </Box>\n </>\n )}\n\n {phase === Phase.Removing && <Text dimColor>Removing skills...</Text>}\n\n {phase === Phase.Done && <Text dimColor>Skills removed.</Text>}\n </Box>\n </Box>\n );\n};\n","/**\n * OutroScreen — Summary after the agent run.\n * Reads store.session.outroData to render success, error, or cancel view.\n * Keeps the process alive until the user presses a key to exit.\n */\n\nimport { Box, Text, useInput } from 'ink';\nimport { useSyncExternalStore } from 'react';\nimport type { WizardStore } from '../store.js';\nimport { OutroKind } from '../../../lib/wizard-session.js';\nimport { Colors } from '../styles.js';\n\ninterface OutroScreenProps {\n store: WizardStore;\n}\n\nexport const OutroScreen = ({ store }: OutroScreenProps) => {\n useSyncExternalStore(\n (cb) => store.subscribe(cb),\n () => store.getSnapshot(),\n );\n\n useInput(() => {\n store.setOutroDismissed();\n });\n\n const outroData = store.session.outroData;\n\n if (!outroData) {\n return (\n <Box flexDirection=\"column\" flexGrow={1}>\n <Text dimColor>Finishing up...</Text>\n </Box>\n );\n }\n\n return (\n <Box flexDirection=\"column\" flexGrow={1}>\n {outroData.kind === OutroKind.Success && (\n <Box flexDirection=\"column\">\n <Text color=\"green\" bold>\n {'\\u2714'} {outroData.message || 'Done!'}\n </Text>\n\n {outroData.reportFile && (\n <Box marginTop={1}>\n <Text>\n Check <Text bold>./{outroData.reportFile}</Text> for details\n </Text>\n </Box>\n )}\n\n {outroData.changes && outroData.changes.length > 0 && (\n <Box flexDirection=\"column\" marginTop={1}>\n <Text color=\"cyan\" bold>\n What the agent did:\n </Text>\n {outroData.changes.map((change, i) => (\n <Text key={i}>\n {'\\u2022'} {change}\n </Text>\n ))}\n </Box>\n )}\n\n {store.eventPlan.length > 0 && (\n <Box flexDirection=\"column\" marginTop={1}>\n <Text color=\"cyan\" bold>\n Events added:\n </Text>\n {store.eventPlan.map((event) => (\n <Text key={event.name}>\n {'\\u2022'} <Text bold>{event.name}</Text>\n <Text dimColor> {event.description}</Text>\n </Text>\n ))}\n </Box>\n )}\n\n {outroData.docsUrl && (\n <Box marginTop={1}>\n <Text>\n Learn more: <Text color=\"cyan\">{outroData.docsUrl}</Text>\n </Text>\n </Box>\n )}\n\n {outroData.continueUrl && (\n <Box>\n <Text>\n Continue onboarding:{' '}\n <Text color=\"cyan\">{outroData.continueUrl}</Text>\n </Text>\n </Box>\n )}\n\n <Box marginTop={1}>\n <Text dimColor>\n Note: This wizard uses an LLM agent to analyze and modify your\n project. Please review the changes made.\n </Text>\n </Box>\n <Box>\n <Text dimColor>\n How did this work for you? Drop us a line: wizard@posthog.com\n </Text>\n </Box>\n </Box>\n )}\n\n {outroData.kind === OutroKind.Error && (\n <Box flexDirection=\"column\">\n <Text color=\"red\" bold>\n {'\\u2718'} {outroData.message || 'An error occurred'}\n </Text>\n\n {outroData.body && (\n <Box marginTop={1}>\n <Text dimColor>{outroData.body}</Text>\n </Box>\n )}\n\n {outroData.docsUrl && (\n <Box marginTop={1}>\n <Text>\n Docs: <Text color=\"cyan\">{outroData.docsUrl}</Text>\n </Text>\n </Box>\n )}\n </Box>\n )}\n\n {outroData.kind === OutroKind.Cancel && (\n <Box flexDirection=\"column\">\n <Text color=\"yellow\">\n {'\\u25A0'} {outroData.message || 'Cancelled'}\n </Text>\n </Box>\n )}\n\n <Box marginTop={1}>\n <Text color={Colors.muted}>Press any key to continue</Text>\n </Box>\n </Box>\n );\n};\n","/**\n * ExitScreen — Final step in every workflow.\n *\n * Renders nothing. Immediately exits the process.\n * The cleanup handler in start-tui.ts handles the exit summary line.\n */\n\nimport { useEffect } from 'react';\n\nexport const ExitScreen = () => {\n useEffect(() => {\n process.exit(0);\n }, []);\n\n return null;\n};\n","/**\n * AuthErrorScreen — Shown when the Anthropic API returns a 401.\n *\n * Claude Code's own auth can conflict with the wizard's OAuth token.\n * This overlay tells the user to log out of Claude Code and retry.\n */\n\nimport { Box, Text, useInput } from 'ink';\nimport { Colors } from '../styles.js';\n\nexport const AuthErrorScreen = () => {\n useInput(() => {\n process.exit(1);\n });\n\n return (\n <Box flexDirection=\"column\" flexGrow={1}>\n <Text color=\"red\" bold>\n {'\\u2718'} Authentication error\n </Text>\n\n <Box flexDirection=\"column\" marginTop={1}>\n <Text>\n The Wizard couldn't connect to the PostHog LLM Gateway. If\n you use Claude Code, its credentials might conflict with the\n Wizard.\n </Text>\n </Box>\n\n <Box marginTop={1}>\n <Text dimColor>\n Try logging out of Claude Code temporarily and re-running the Wizard\n by running:\n </Text>\n </Box>\n\n <Box flexDirection=\"column\" marginTop={1} paddingLeft={2}>\n <Text color=\"cyan\">claude auth logout</Text>\n </Box>\n\n <Box marginTop={1}>\n <Text color={Colors.muted}>Press any key to exit</Text>\n </Box>\n </Box>\n );\n};\n","/**\n * McpInstaller — service layer between McpScreen and MCP business logic.\n *\n * Decouples the screen from step internals. Testable, swappable,\n * no dynamic imports in React components.\n */\n\nimport {\n getSupportedClients,\n removeMCPServer,\n getInstalledClients,\n} from '../../../steps/add-mcp-server-to-clients/index.js';\nimport { ALL_FEATURE_VALUES } from '../../../steps/add-mcp-server-to-clients/defaults.js';\nimport { logToFile } from '../../../utils/debug.js';\n\nexport interface McpClientInfo {\n name: string;\n}\n\nexport interface McpInstaller {\n /** Detect which MCP-capable editors are available on this machine. */\n detectClients(): Promise<McpClientInfo[]>;\n\n /** Install the PostHog MCP server to the given clients. Returns names of successfully installed clients. */\n install(\n clientNames: string[],\n features?: string[],\n apiKey?: string,\n ): Promise<string[]>;\n\n /** Remove the PostHog MCP server from all installed clients. Returns names of removed clients. */\n remove(): Promise<string[]>;\n}\n\n/**\n * Production McpInstaller backed by real MCP client detection and installation.\n */\nexport function createMcpInstaller(): McpInstaller {\n // Cache the raw MCPClient objects so install() can reference them by name\n let cachedClients: Array<{ name: string; raw: unknown }> = [];\n\n return {\n async detectClients(): Promise<McpClientInfo[]> {\n const supported = await getSupportedClients();\n cachedClients = supported.map((c) => ({ name: c.name, raw: c }));\n return supported.map((c) => ({ name: c.name }));\n },\n\n async install(\n clientNames: string[],\n features?: string[],\n apiKey?: string,\n ): Promise<string[]> {\n const resolvedFeatures = features ?? [...ALL_FEATURE_VALUES];\n const toInstall = cachedClients\n .filter((c) => clientNames.includes(c.name))\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n .map((c) => c.raw as any);\n\n if (toInstall.length === 0) {\n logToFile(\n `[McpInstaller] No clients matched. clientNames=${JSON.stringify(\n clientNames,\n )}, cached=${JSON.stringify(cachedClients.map((c) => c.name))}`,\n );\n return [];\n }\n\n const installed: string[] = [];\n for (const client of toInstall) {\n try {\n const result = await client.addServer(\n apiKey,\n resolvedFeatures,\n false,\n );\n if (result?.success) {\n installed.push(client.name as string);\n } else {\n logToFile(\n `[McpInstaller] addServer returned success=false for ${client.name}`,\n );\n }\n } catch (err) {\n logToFile(\n `[McpInstaller] addServer threw for ${client.name}: ${\n err instanceof Error ? err.message : String(err)\n }`,\n );\n }\n }\n return installed;\n },\n\n async remove(): Promise<string[]> {\n const installed = await getInstalledClients();\n if (installed.length === 0) return [];\n await removeMCPServer(installed);\n return installed.map((c) => c.name);\n },\n };\n}\n","/**\n * Screen registry — maps screen names to React components.\n *\n * Adding a new screen:\n * 1. Create the component in screens/\n * 2. Add an entry here\n * 3. Add the screen name to the router flow (router.ts)\n *\n * App.tsx never needs to change.\n */\n\nimport type { ReactNode } from 'react';\nimport type { WizardStore } from './store.js';\nimport { Screen, Overlay, type ScreenName } from './router.js';\n\nimport { HealthCheckScreen } from './screens/health/HealthCheckScreen.js';\nimport { SettingsOverrideScreen } from './screens/SettingsOverrideScreen.js';\nimport { ManagedSettingsScreen } from './screens/ManagedSettingsScreen.js';\nimport { PortConflictScreen } from './screens/PortConflictScreen.js';\nimport { PostHogIntegrationIntroScreen } from './screens/PostHogIntegrationIntroScreen.js';\nimport { RevenueIntroScreen } from './screens/RevenueIntroScreen.js';\nimport { AgentSkillIntroScreen } from './screens/AgentSkillIntroScreen.js';\nimport { SetupScreen } from './screens/SetupScreen.js';\nimport { AuthScreen } from './screens/AuthScreen.js';\nimport { RunScreen } from './screens/RunScreen.js';\nimport { McpScreen } from './screens/McpScreen.js';\nimport { KeepSkillsScreen } from './screens/KeepSkillsScreen.js';\nimport { OutroScreen } from './screens/OutroScreen.js';\nimport { ExitScreen } from './screens/ExitScreen.js';\nimport { AuthErrorScreen } from './screens/AuthErrorScreen.js';\nimport { createMcpInstaller } from './services/mcp-installer.js';\nimport type { McpInstaller } from './services/mcp-installer.js';\n\nexport interface ScreenServices {\n mcpInstaller: McpInstaller;\n}\n\nexport function createServices(): ScreenServices {\n return {\n mcpInstaller: createMcpInstaller(),\n };\n}\n\nexport function createScreens(\n store: WizardStore,\n services: ScreenServices,\n): Record<ScreenName, ReactNode> {\n return {\n // Overlays\n [Overlay.SettingsOverride]: <SettingsOverrideScreen store={store} />,\n [Overlay.ManagedSettings]: <ManagedSettingsScreen store={store} />,\n [Overlay.PortConflict]: <PortConflictScreen store={store} />,\n [Overlay.AuthError]: <AuthErrorScreen />,\n\n // Wizard flow\n [Screen.Intro]: <PostHogIntegrationIntroScreen store={store} />,\n [Screen.RevenueIntro]: <RevenueIntroScreen store={store} />,\n [Screen.AgentSkillIntro]: <AgentSkillIntroScreen store={store} />,\n [Screen.HealthCheck]: <HealthCheckScreen store={store} />,\n [Screen.Setup]: <SetupScreen store={store} />,\n [Screen.Auth]: <AuthScreen store={store} />,\n [Screen.Run]: <RunScreen store={store} />,\n [Screen.Mcp]: <McpScreen store={store} installer={services.mcpInstaller} />,\n [Screen.KeepSkills]: <KeepSkillsScreen store={store} />,\n [Screen.Outro]: <OutroScreen store={store} />,\n [Screen.Exit]: <ExitScreen />,\n\n // Standalone MCP flows\n [Screen.McpAdd]: (\n <McpScreen store={store} installer={services.mcpInstaller} />\n ),\n [Screen.McpRemove]: (\n <McpScreen\n store={store}\n installer={services.mcpInstaller}\n mode=\"remove\"\n />\n ),\n };\n}\n","import { useMemo } from 'react';\nimport { ScreenContainer } from './primitives/index.js';\nimport type { WizardStore } from './store.js';\nimport { createScreens, createServices } from './screen-registry.js';\n\ninterface AppProps {\n store: WizardStore;\n}\n\nexport const App = ({ store }: AppProps) => {\n const services = useMemo(() => createServices(), []);\n const screens = useMemo(\n () => createScreens(store, services),\n [store, services],\n );\n\n return <ScreenContainer store={store} screens={screens} />;\n};\n","/**\n * start-tui.ts — Sets up the Ink TUI renderer and InkUI.\n *\n * Renders in the terminal's alternate screen buffer so the wizard\n * doesn't pollute scrollback history. On exit, the previous terminal\n * content is restored and a single exit summary line is printed.\n */\n\nimport { render } from 'ink';\nimport { createElement } from 'react';\nimport { WizardStore, Flow } from './store.js';\nimport { InkUI } from './ink-ui.js';\nimport { setUI } from '../index.js';\nimport { App } from './App.js';\nimport { OutroKind } from '../../lib/wizard-session.js';\n\n// ANSI escape sequences\nconst RESET_ATTRS = '\\x1b[0m';\nconst CLEAR_SCREEN = '\\x1b[2J';\nconst CURSOR_HOME = '\\x1b[H';\nconst BG_BLACK = '\\x1b[48;2;0;0;0m';\nconst ENTER_ALT_SCREEN = '\\x1b[?1049h';\nconst LEAVE_ALT_SCREEN = '\\x1b[?1049l';\nconst GREEN = '\\x1b[32m';\nconst BOLD = '\\x1b[1m';\nconst DIM = '\\x1b[2m';\n\nfunction getExitLine(store: WizardStore): string {\n const outro = store.session.outroData;\n const label = store.session.workflowLabel ?? 'Wizard';\n\n if (outro?.kind === OutroKind.Success) {\n return `${GREEN}${BOLD}\\u2714${RESET_ATTRS} ${\n outro.message ?? `${label} completed successfully.`\n }`;\n }\n\n return `${DIM}${label} exited.${RESET_ATTRS}`;\n}\n\nexport function startTUI(\n version: string,\n flow: Flow = Flow.PostHogIntegration,\n): {\n unmount: () => void;\n store: WizardStore;\n waitForSetup: () => Promise<void>;\n} {\n // Enter alternate screen buffer, then set up dark background\n process.stdout.write(\n ENTER_ALT_SCREEN + BG_BLACK + CLEAR_SCREEN + CURSOR_HOME,\n );\n\n const store = new WizardStore(flow);\n store.version = version;\n\n // Swap in the InkUI\n const inkUI = new InkUI(store);\n setUI(inkUI);\n\n // Render the Ink app\n const { unmount: inkUnmount } = render(createElement(App, { store }));\n\n // On exit: unmount Ink, leave alt screen (restores previous content),\n // then print exit summary line into the main buffer.\n let cleaned = false;\n const cleanup = () => {\n if (cleaned) return;\n cleaned = true;\n inkUnmount();\n process.stdout.write(RESET_ATTRS + LEAVE_ALT_SCREEN);\n process.stdout.write(getExitLine(store) + '\\n');\n };\n process.on('exit', cleanup);\n\n return {\n unmount: cleanup,\n store,\n waitForSetup: () => store.getGate('intro'),\n };\n}\n"],"mappings":";;;;;;;;;;;;;;;;;AAiBA,MAAM,UAAU;AAChB,SAAS,UAAU,GAAmB;AACpC,QAAO,EAAE,QAAQ,SAAS,GAAG;;AAG/B,IAAa,QAAb,MAAuC;CACrC,YAAY,OAA4B;AAApB,OAAA,QAAA;;CAEpB,MAAM,SAAuB;AAC3B,OAAK,MAAM,WAAW,QAAQ;;CAGhC,MAAM,SAAuB;AAC3B,OAAK,MAAM,WAAW,UAAU,QAAQ,CAAC;AAEzC,MAAI,CAAC,KAAK,MAAM,QAAQ,UACtB,MAAK,MAAM,aAAa;GACtB,MAAA;GACA,SAAS,UAAU,QAAQ;GAC5B,CAAC;AAIJ,MAAI,KAAK,MAAM,QAAQ,aAAA,UACrB,MAAK,MAAM,YAAA,YAA+B;;CAI9C,WAAW,MAAuB;AAChC,OAAK,MAAM,aAAa,KAAK;AAE7B,MAAI,KAAK,MAAM,QAAQ,aAAA,QACrB,MAAK,MAAM,YAAA,QAA2B;;CAI1C,eAAe,aAKN;AACP,OAAK,MAAM,eAAe,YAAY;;CAGxC,qBAAqB,OAAqB;AACxC,OAAK,MAAM,qBAAqB,MAAM;;CAGxC,cAAc,QAAgB,IAAsB;AAClD,OAAK,MAAM,cACT,QACA,GACD;;CAGH,YAAY,KAA0B;AACpC,OAAK,MAAM,YAAY,IAAI;;CAG7B,mBAAmB,QAA8C;AAG/D,OAAK,MAAM,mBAAmB,OAAO;AACrC,SAAO,QAAQ,SAAS;;CAG1B,qBAAqB,QAAqC;AACxD,OAAK,MAAM,mBAAmB,OAAO;;CAGvC,iBAAiB,aAKC;AAChB,SAAO,KAAK,MAAM,iBAAiB,YAAY;;CAGjD,qBACE,WACA,cACe;AACf,SAAO,KAAK,MAAM,qBAAqB,WAAW,aAAa;;CAGjE,gBAAsB;AACpB,OAAK,MAAM,eAAe;;CAG5B,WAAiB;AACf,OAAK,MAAM,YAAA,UAA6B;;CAG1C,OAAO,SAAuB;AAC5B,OAAK,MAAM,WAAW,QAAQ;;CAGhC,MAAM;EACJ,OAAO,YAA0B;AAC/B,QAAK,MAAM,WAAW,QAAQ;;EAEhC,OAAO,YAA0B;AAC/B,QAAK,MAAM,WAAW,QAAQ;;EAEhC,QAAQ,YAA0B;AAChC,QAAK,MAAM,WAAW,QAAQ;;EAEhC,UAAU,YAA0B;AAClC,QAAK,MAAM,WAAW,QAAQ;;EAEhC,OAAO,YAA0B;AAC/B,QAAK,MAAM,WAAW,QAAQ;;EAEjC;CAED,KAAK,SAAuB;AAC1B,OAAK,MAAM,WAAW,QAAQ;;CAGhC,UAAyB;AACvB,SAAO;GACL,QAAQ,YAAqB;AAC3B,QAAI,QAAS,MAAK,MAAM,WAAW,QAAQ;;GAE7C,OAAO,YAAqB;AAC1B,QAAI,QAAS,MAAK,MAAM,WAAW,QAAQ;;GAE7C,UAAU,QAAiB;AACzB,QAAI,IAAK,MAAK,MAAM,WAAW,IAAI;;GAEtC;;CAGH,WAAW,SAAuB;AAChC,OAAK,MAAM,WAAW,QAAQ;;CAGhC,UACE,OACM;AACN,OAAK,MAAM,UAAU,MAAM;;CAG7B,aAAa,QAA4D;AACvE,OAAK,MAAM,aAAa,OAAO;;;;;;;;;;;;;ACtInC,MAAM,iBACJ;AAEF,MAAM,+BAA+B;AACnC,gBAAe;AACb,UAAQ,KAAK,EAAE;GACf;AAEF,QACE,qBAAC,KAAD;EAAK,eAAc;EAAS,UAAU;YAAtC;GACE,qBAAC,MAAD;IAAM,OAAM;IAAQ,MAAA;cAApB,CACG,MAAM,OAAM,yCACR;;GAEP,qBAAC,KAAD;IAAK,WAAW;IAAG,eAAc;cAAjC,CACE,oBAAC,MAAD,EAAA,UAAM,gEAEC,CAAA,EACP,oBAAC,KAAD;KAAK,WAAW;KAAG,aAAa;eAC9B,oBAAC,MAAD;MAAM,OAAM;gBAAQ;MAAsB,CAAA;KACtC,CAAA,CACF;;GAEN,oBAAC,KAAD;IAAK,WAAW;cACd,oBAAC,MAAD;KAAM,OAAO,OAAO;eAAO;KAA4B,CAAA;IACnD,CAAA;GACF;;;AAIV,MAAa,qBAAqB,EAAE,YAAoC;AACtE,uBACG,OAAO,MAAM,UAAU,GAAG,QACrB,MAAM,aAAa,CAC1B;CAED,MAAM,CAAC,YAAY,iBAAiB,SAAS,MAAM;CACnD,MAAM,CAAC,aAAa,kBAAkB,SAAS,MAAM;CAErD,MAAM,SAAS,MAAM,QAAQ;AAE7B,KAAI,WACF,QAAO,oBAAC,wBAAD,EAA0B,CAAA;AAInC,KAAI,CAAC,OACH,QACE,oBAAC,KAAD;EACE,eAAc;EACd,UAAU;EACV,YAAW;EACX,gBAAe;YAEf,oBAAC,YAAD,EAAY,SAAQ,8BAA+B,CAAA;EAC/C,CAAA;CAMV,MAAM,eAAe,uBAAuB,OAAO,OAAO;AAC1D,KAAI,aAAa,WAAW,EAAG,QAAO;CAEtC,MAAM,uBAAuB,aAAa,SAAS,iBAAiB;CACpE,MAAM,oBACJ,OAAO,OAAO,eAAe,WAAA;CAC/B,MAAM,cAAc,MAAM,QAAQ;CAElC,MAAM,QAAQ;CAEd,MAAM,UAAU,MAAM,QAAQ,iBAAiB,SAAS;CACxD,MAAM,cAAc,uBAChB,+EACA;CAEJ,MAAM,wBAAwB,YAAY;AACxC,MAAI,YAAa;AACjB,iBAAe,KAAK;EACpB,MAAM,OAAO,MAAM,eAAe,uBAAuB;AACzD,MAAI,MAAM;GACR,MAAM,SAAS,eAAe;GAC9B,MAAM,UAAU,KAAK,WAAW,kBAAkB,EAAE,EAAE,QAAQ,MAC5D,EAAE,GAAG,WAAW,OAAO,CACxB;AACD,QAAK,MAAM,SAAS,OAClB,eAAc,OAAO,MAAM,QAAQ,YAAY,kBAAkB;;AAGrE,gBAAc,KAAK;;AAgBrB,QACE,qBAAC,cAAD;EACE,aAAY;EACL;EACP,OAAO;EACP,QACE,uBACE,oBAAC,mBAAD;GACE,SAAQ;GACR,cAAa;GACb,aAAY;GACZ,iBACE,KAAK,YAAY,EAAE,SAAS,iCAAiC,CAAC;GAEhE,gBACE,KAAK,YAAY,EAAE,SAAS,iCAAiC,CAAC;GAEhE,CAAA,GAEF,oBAAC,mBAAD;GACE,SAAQ;GACR,cAAa;GACb,aA7BR,qBAAqB,CAAC,uBAClB,cACE,mBACA,iCACF;GA0BI,iBAAiB,MAAM,eAAe;GACtC,UApCR,qBAAqB,CAAC,6BACZ,KAAK,uBAAuB,SAC5B,KAAK,YAAY,EAAE,SAAS,iCAAiC,CAAC;GAmChE,CAAA;YAxBR;GA4BE,qBAAC,KAAD;IAAK,eAAc;IAAS,cAAc;cAA1C,CACE,oBAAC,KAAD;KAAK,cAAc;eACjB,qBAAC,MAAD,EAAA,UAAA;MACE,oBAAC,MAAD;OAAM,OAAM;iBAAO,MAAM;OAAoB,CAAA;MAC7C,oBAAC,MAAD;OAAM,UAAA;iBAAS;OAAa,CAAA;MAC5B,oBAAC,MAAD;OAAM,OAAM;iBAAW,MAAM;OAAoB,CAAA;MACjD,oBAAC,MAAD;OAAM,UAAA;iBAAS;OAAgB,CAAA;MAC1B,EAAA,CAAA;KACH,CAAA,EAEN,oBAAC,mBAAD;KACE,QAAQ,OAAO;KACf,YAAY;KACZ,aAAa;KACb,CAAA,CACE;;GAEN,oBAAC,MAAD;IAAM,UAAA;cAAU;IAAmB,CAAA;GAElC,wBAAwB,WACvB,oBAAC,KAAD;IAAK,WAAW;cACd,qBAAC,MAAD,EAAA,UAAA,CAAM,qBACa,oBAAC,MAAD;KAAM,OAAM;eAAQ;KAAe,CAAA,CAC/C,EAAA,CAAA;IACH,CAAA;GAGP,qBAAqB,CAAC,wBACrB,oBAAC,KAAD;IAAK,WAAW;cACd,oBAAC,MAAD,EAAA,UAAM,0FAGC,CAAA;IACH,CAAA;GAEK;;;;;AC/LnB,SAAS,WAAW,QAAwC;AAC1D,SAAQ,QAAR;EACE,KAAK,UACH,QAAO;EACT,KAAK,UACH,QAAO;EACT,QACE,QAAO;;;AAQb,MAAa,0BAA0B,EACrC,YACiC;AACjC,uBACG,OAAO,MAAM,UAAU,GAAG,QACrB,MAAM,aAAa,CAC1B;CAED,MAAM,CAAC,UAAU,eAAe,SAAwB,KAAK;CAC7D,MAAM,YAAY,MAAM,QAAQ,mBAAmB,QAAQ,MAAM,EAAE,SAAS;AAE5E,KAAI,CAAC,aAAa,UAAU,WAAW,EACrC,QAAO;AAGT,QACE,qBAAC,cAAD;EACE,aAAY;EACZ,OAAO,GAAG,MAAM,QAAQ;EACxB,OAAO;EACP,UAAU,WAAW,GAAG,MAAM,QAAQ,GAAG,aAAa;EACtD,QACE,oBAAC,mBAAD;GACE,SAAQ;GACR,cAAa;GACb,aAAY;GACZ,iBAAiB;AAEf,QAAI,CADO,MAAM,8BAA8B,CAE7C,aAAY,uCAAuC;;GAGvD,gBAAgB,QAAQ,KAAK,EAAE;GAC/B,CAAA;YAjBN,CAoBG,UAAU,KAAK,aACd,qBAAC,KAAD;GAA2B,eAAc;GAAS,cAAc;aAAhE,CACE,qBAAC,MAAD,EAAA,UAAA;IAAM;IACkB;IACtB,oBAAC,MAAD;KAAM,MAAA;eAAM,WAAW,SAAS,OAAO;KAAQ,CAAA;;IAC1C,EAAA,CAAA,EACP,oBAAC,KAAD;IAAK,eAAc;IAAS,aAAa;cACtC,SAAS,KAAK,KAAK,QAClB,qBAAC,MAAD,EAAA,UAAA;KACG,MAAM;KAAQ;KACf,oBAAC,MAAD;MAAM,OAAM;MAAS,MAAA;gBAClB;MACI,CAAA;KACF,EAAA,EALI,IAKJ,CACP;IACE,CAAA,CACF;KAfI,SAAS,OAeb,CACN,EACF,oBAAC,MAAD;GAAM,UAAA;aAAS;GAGR,CAAA,CACM;;;;;;;;;;;;ACjEnB,SAAS,YAAY,QAA4C;AAC/D,SAAQ,QAAR;EACE,KAAK,UACH,QAAO;EACT,KAAK,UACH,QAAO;EACT,QACE,QAAO;;;AAQb,MAAa,yBAAyB,EACpC,YACgC;AAChC,uBACG,OAAO,MAAM,UAAU,GAAG,QACrB,MAAM,aAAa,CAC1B;CAGD,MAAM,oBADY,MAAM,QAAQ,mBACK,QAAQ,MAAM,CAAC,EAAE,SAAS;AAE/D,KAAI,CAAC,qBAAqB,kBAAkB,WAAW,EACrD,QAAO;AAGT,QACE,qBAAC,cAAD;EACE,aAAY;EACZ,OAAO,GAAG,MAAM,QAAQ;EACxB,OAAO;EACP,QACE,oBAAC,mBAAD;GACE,SAAQ;GACR,cAAa;GACb,aAAY;GACZ,iBAAiB,QAAQ,KAAK,EAAE;GAChC,gBAAgB,QAAQ,KAAK,EAAE;GAC/B,CAAA;YAXN;GAcE,oBAAC,MAAD;IAAM,UAAA;cAAS;IAGR,CAAA;GACN,kBAAkB,KAAK,aACtB,qBAAC,KAAD;IAA2B,eAAc;IAAS,WAAW;cAA7D,CACE,oBAAC,MAAD;KAAM,MAAA;eAAM,YAAY,SAAS,OAAO;KAAQ,CAAA,EAChD,oBAAC,KAAD;KAAK,eAAc;KAAS,aAAa;eACtC,SAAS,KAAK,KAAK,QAClB,qBAAC,MAAD,EAAA,UAAA;MACG,MAAM;MAAQ;MACf,oBAAC,MAAD;OAAM,OAAM;OAAS,MAAA;iBAClB;OACI,CAAA;MACF,EAAA,EALI,IAKJ,CACP;KACE,CAAA,CACF;MAZI,SAAS,OAYb,CACN;GACF,oBAAC,KAAD;IAAK,WAAW;cACd,oBAAC,MAAD;KAAM,UAAA;eAAS;KAGR,CAAA;IACH,CAAA;GACO;;;;;;;;;;ACrEnB,MAAa,sBAAsB,EAAE,YAAqC;AACxE,uBACG,OAAO,MAAM,UAAU,GAAG,QACrB,MAAM,aAAa,CAC1B;AAID,KAAI,CAFgB,MAAM,QAAQ,oBAEhB,QAAO;AAEzB,QACE,qBAAC,cAAD;EACE,aAAY;EACZ,OAAM;EACN,OAAO;EACP,QACE,oBAAC,mBAAD;GACE,SAAQ;GACR,cAAa;GACb,aAAY;GACZ,iBAAiB,MAAM,qBAAqB;GAC5C,gBAAgB,QAAQ,KAAK,EAAE;GAC/B,CAAA;YAXN;GAcE,oBAAC,MAAD,EAAA,UAAM,uFAGC,CAAA;GACP,oBAAC,KAAD;IAAK,eAAc;IAAS,SAAS;IAAG,aAAa;IAAG,KAAK;cAC1D,YAAY,KAAK,SAChB,qBAAC,MAAD,EAAA,UAAA,CACE,oBAAC,MAAD;KAAM,UAAA;eAAS;KAAY,CAAA,EAC3B,oBAAC,MAAD;KAAM,MAAA;eAAM;KAAY,CAAA,CACnB,EAAA,EAHI,KAGJ,CACP;IACE,CAAA;GACN,oBAAC,MAAD;IAAM,UAAA;cAAS;IAAgD,CAAA;GAClD;;;;;;;;;;;;;;;;ACOnB,MAAM,eAAe,EAAE,YACrB,qBAAC,MAAD;CAAM,MAAA;WAAN;EACE,oBAAC,MAAD;GAAM,OAAM;aAAW;GAAgB,CAAA;EACvC,oBAAC,MAAD;GAAM,OAAM;aAAW;GAAgB,CAAA;EACvC,oBAAC,MAAD;GAAM,OAAM;aAAW;GAAgB,CAAA;;EAAE;EACpC;;AAGT,MAAa,qBAAqB,EAChC,YACA,QAAQ,qBACR,eAAe,MACf,MACA,gBAAgB,MAChB,eACA,UACA,aACA,UACA,eACA,SACA,gBAC4B;CAE5B,MAAM,sBACJ,gBAAgB,KAAA,IACZ,CACE;EAAE,OAAO;EAAY,OAAO;EAAY,EACxC;EAAE,OAAO;EAAU,OAAO;EAAU,CACrC,GACD;AAEN,KAAI,UACF,QACE,qBAAC,KAAD;EACE,eAAc;EACd,UAAU;EACV,YAAW;EACX,gBAAe;YAJjB,CAME,oBAAC,KAAD;GAAK,eAAc;GAAS,YAAW;GAAS,cAAc;aAC5D,oBAAC,aAAD,EAAoB,OAAS,CAAA;GACzB,CAAA,EACL,UACG;;AAIV,QACE,oBAAA,UAAA,EAAA,UACE,qBAAC,KAAD;EACE,eAAc;EACd,UAAU;EACV,YAAW;EACX,gBAAe;YAJjB;GAME,qBAAC,KAAD;IAAK,eAAc;IAAS,YAAW;cAAvC;KACE,oBAAC,aAAD,EAAoB,OAAS,CAAA;KAE5B,gBACC,qBAAC,KAAD;MAAK,eAAc;MAAS,YAAW;MAAS,WAAW;gBAA3D,CACE,oBAAC,MAAD;OAAM,UAAA;iBAAS;OAER,CAAA,EACP,oBAAC,MAAD;OAAM,UAAA;iBAAS;OAER,CAAA,CACH;;KAGP,QACC,oBAAC,KAAD;MAAK,eAAc;MAAS,YAAW;MAAS,WAAW;gBACxD;MACG,CAAA;KAEJ;;GAEL;GAEA,iBACC,qBAAC,KAAD;IAAK,eAAc;IAAS,WAAW;cAAvC;KACE,qBAAC,MAAD,EAAA,UAAA,CACE,qBAAC,MAAD,EAAA,UAAA;MAAM;MACM,oBAAC,MAAD;OAAM,OAAM;iBAAS;OAAgB,CAAA;MAAC;MAC3C,EAAA,CAAA,EACP,qBAAC,MAAD,EAAA,UAAA,CACG,KACA,KAAK,SAAS,WAAW,CACrB,EAAA,CAAA,CACF,EAAA,CAAA;KAEN,eAAe,KAAK,QACnB,qBAAC,MAAD,EAAA,UAAA,CACE,qBAAC,MAAD,EAAA,UAAA;MACG,IAAI;MAAM;MAAC,oBAAC,MAAD;OAAM,OAAM;iBAAS;OAAgB,CAAA;MAAC;MAC7C,EAAA,CAAA,EACP,qBAAC,MAAD,EAAA,UAAA,CACG,IAAI,OACJ,IAAI,SAAS,IAAI,IAAI,WAAW,GAC5B,EAAA,CAAA,CACF,EAAA,EARI,IAAI,MAQR,CACP;KAED,iBACC,qBAAC,MAAD,EAAA,UAAA;MAAM;MACK;MACT,oBAAC,MAAD;OAAM,OAAM;iBAAS;OAAgB,CAAA;;MAAE;MAClC,EAAA,CAAA;KAGR,kBAAkB,iBAAiB,WAClC,qBAAC,MAAD,EAAA,UAAA;MAAM;MACE;MACN,oBAAC,MAAD;OAAM,OAAM;iBAAS;OAAgB,CAAA;;MAAE;MAClC,EAAA,CAAA;KAEL;;GAGR,oBAAC,KAAD;IAAK,OAAO;cACT,uBAAuB,YACtB,oBAAC,KAAD;KAAK,gBAAe;eAClB,oBAAC,YAAD;MAEE,SAAS;MACT,WAAW,UAAU;AAEnB,gBADe,MAAM,QAAQ,MAAM,GAAG,MAAM,KAAK,MACjC;;MAElB,EANK,oBAAoB,KAAK,MAAM,EAAE,MAAM,CAAC,KAAK,IAAI,CAMtD;KACE,CAAA;IAEJ,CAAA;GACF;KACL,CAAA;;;;;;;;;;;;;;AC9KP,MAAM,mBAAmB,EACvB,OACA,iBAII;AAMJ,QACE,oBAAC,YAAD;EACE,UAAA;EACA,SAAS;EACT,SAAQ;EACR,SAVY,OAAO,OAAO,YAAY,CAAC,KAAK,WAAW;GACzD,OAAO;GACP;GACD,EAAE;EAQC,WAAW,UAAU;GACnB,MAAM,cAAc,MAAM,QAAQ,MAAM,GAAG,MAAM,KAAK;AACjD,UAAO,0BAAA,MAAA,MAAA,EAAA,EAAA,CAA4B,MACrC,EAAE,yBAAyB;IAC1B,MAAM,SAAS,mBAAmB;AAClC,UAAM,mBAAmB,aAAa,OAAO;AAC7C,UAAM,qBAAqB,OAAO,SAAS,KAAK;AAChD,kBAAc;KAEjB;;EAEH,CAAA;;AAQN,MAAa,iCAAiC,EAC5C,YACwC;AACxC,uBACG,OAAO,MAAM,UAAU,GAAG,QACrB,MAAM,aAAa,CAC1B;CAED,MAAM,CAAC,kBAAkB,uBAAuB,SAAS,MAAM;CAC/D,MAAM,CAAC,kBAAkB,uBAAuB,SAAS,MAAM;CAC/D,MAAM,CAAC,iBAAiB,sBAAsB,SAAS,MAAM;CAE7D,MAAM,EAAE,YAAY;CACpB,MAAM,SAAS,QAAQ;CACvB,MAAM,iBACJ,QAAQ,0BAA0B,QAAQ,SAAS;CACrD,MAAM,YAAY,CAAC,QAAQ;CAC3B,MAAM,qBACJ,QAAQ,qBAAqB,CAAC,QAAQ;CACxC,MAAM,cAAc,QAAQ;CAC5B,MAAM,eACJ,QAAQ,oBAAoB,QAC5B,CAAC,aACD,CAAC,oBACD,CAAC,mBACD,CAAC;CAIH,MAAM,QAAQ,YAAY,+BAA+B;CAIzD,IAAI,OAAkB;AAEtB,KAAI,UACF,QACE,oBAAC,KAAD;EAAK,SAAS;YACZ,oBAAC,YAAD,EAAY,SAAQ,kCAAmC,CAAA;EACnD,CAAA;UAEC,sBAAsB,CAAC,iBAChC,QACE,qBAAA,UAAA,EAAA,UAAA,CACE,oBAAC,KAAD;EAAK,SAAS;YACZ,oBAAC,MAAD;GAAM,UAAA;aAAS;GAA4C,CAAA;EACvD,CAAA,EACN,oBAAC,iBAAD;EACS;EACP,kBAAkB,oBAAoB,MAAM;EAC5C,CAAA,CACD,EAAA,CAAA;UAEI,iBACT,QACE,oBAAC,iBAAD;EACS;EACP,kBAAkB,oBAAoB,MAAM;EAC5C,CAAA;UAEK,gBACT,QACE,qBAAC,KAAD;EAAK,eAAc;EAAS,OAAO;YAAnC;GACE,qBAAC,MAAD,EAAA,UAAA,CAAM,iFAEI,oBAAC,MAAD;IAAM,OAAM;cAAO;IAAwC,CAAA,CAC9D,EAAA,CAAA;GACP,oBAAC,KAAD;IAAK,eAAc;IAAS,WAAW;cACrC,qBAAC,MAAD,EAAA,UAAA;KAAM;KACA;KACJ,oBAAC,MAAD;MAAM,QAAA;MAAO,OAAM;gBAChB,QAAQ;MACJ,CAAA;KAAC;KAAI;KAGP,EAAA,CAAA;IACH,CAAA;GACN,qBAAC,KAAD;IAAK,eAAc;IAAS,WAAW;IAAG,aAAa;cAAvD;KACE,qBAAC,MAAD,EAAA,UAAA,CAAO,UAAS,qBAAyB,EAAA,CAAA;KACzC,qBAAC,MAAD,EAAA,UAAA,CAAO,UAAS,iBAAqB,EAAA,CAAA;KACrC,qBAAC,MAAD,EAAA,UAAA,CAAO,UAAS,kBAAsB,EAAA,CAAA;KACtC,qBAAC,MAAD,EAAA,UAAA,CAAO,UAAS,kBAAsB,EAAA,CAAA;KAClC;;GACN,oBAAC,KAAD;IAAK,eAAc;IAAS,WAAW;cACrC,qBAAC,MAAD,EAAA,UAAA;KAAM;KACiD;KACrD,qBAAC,MAAD;MAAM,OAAM;gBAAZ,CAAoB,kBAAiB,YAAgB;;KAChD,EAAA,CAAA;IACH,CAAA;GACF;;UAEC,aACT,QACE,oBAAA,UAAA,EAAA,UACE,oBAAC,KAAD,EAAA,UACE,oBAAC,MAAD,EAAA,UAAM,gDAAmD,CAAA,EACrD,CAAA,EACL,CAAA;CAMP,MAAM,gBAAgC,EAAE;AACxC,KAAI,gBAAgB;EAClB,MAAM,cAAwB,EAAE;AAChC,MAAI,CAAC,iBAAkB,aAAY,KAAK,aAAa;AACrD,MAAI,QAAQ,SAAS,KAAM,aAAY,KAAK,SAAS;AAErD,gBAAc,KAAK;GACjB,OAAO;GACP,OAAO;GACP,QAAQ,YAAY,KAAK,IAAI,IAAI,KAAA;GAClC,CAAC;;CAKJ,IAAI,eAA0B;AAE9B,KAAI,QAAQ,SAAS,aACnB,gBAAe,oBAAC,MAAD;EAAM,OAAM;YAAU,OAAO,SAAS;EAAoB,CAAA;AAG3E,KAAI,YACF,gBACE,qBAAC,KAAD;EAAK,eAAc;EAAS,WAAW;YAAvC;GACE,qBAAC,MAAD;IAAM,OAAM;cAAZ;KAAsB;KACX,YAAY;KAAQ;KACjB,YAAY;KAAQ;KAC3B;;GACP,qBAAC,MAAD;IAAM,UAAA;cAAN,CAAe,wBAAqB,YAAY,QAAe;;GAC/D,oBAAC,KAAD;IAAK,WAAW;cACd,oBAAC,MAAD;KAAM,UAAA;eAAS;KAER,CAAA;IACH,CAAA;GACN,oBAAC,YAAD;IACE,SAAS,CACP;KAAE,OAAO;KAA4B,OAAO;KAAa,EACzD;KAAE,OAAO;KAAQ,OAAO;KAAQ,CACjC;IACD,WAAW,UAAU;AAEnB,UADe,MAAM,QAAQ,MAAM,GAAG,MAAM,KAAK,WAClC,aAAa;AAC1B,0BAAoB,KAAK;AACzB,0BAAoB,KAAK;WAEzB,SAAQ,KAAK,EAAE;;IAGnB,CAAA;GACE;;CAMV,IAAI,cAAyD;AAE7D,KAAI,gBACF,eAAc,CAAC;EAAE,OAAO;EAAQ,OAAO;EAAQ,CAAC;UACvC,aACT,eAAc;EACZ;GAAE,OAAO;GAAY,OAAO;GAAY;EACxC;GAAE,OAAO;GAAoB,OAAO;GAAa;EACjD;GAAE,OAAO;GAAa,OAAO;GAAa;EAC1C;GAAE,OAAO;GAAU,OAAO;GAAU;EACrC;CAGH,MAAM,gBAAgB,UAAkB;AACtC,MAAI,UAAU,SACZ,SAAQ,KAAK,EAAE;WACN,UAAU,aAAa;AAChC,uBAAoB,KAAK;AACzB,uBAAoB,KAAK;aAChB,UAAU,YACnB,oBAAmB,KAAK;WACf,UAAU,OACnB,oBAAmB,MAAM;MAEzB,OAAM,eAAe;;AAMzB,QACE,oBAAC,mBAAD;EACE,YAAY,QAAQ;EACb;EACP,cAAc,CAAC;EACT;EACN,eAAe;EACA;EACf,aAAa,cAAc,OAAO;EAClC,UAAU;EACV,eAAe,QAAQ;EACvB,SAAS,QAAQ;YAEhB;EACiB,CAAA;;;;;;;;;;;;;;ACzOxB,MAAa,sBAAsB,EAAE,YAAqC;AACxE,uBACG,OAAO,MAAM,UAAU,GAAG,QACrB,MAAM,aAAa,CAC1B;CAED,MAAM,CAAC,iBAAiB,sBAAsB,SAAS,MAAM;CAE7D,MAAM,EAAE,YAAY;CACpB,MAAM,cAAc,QAAQ,iBAAiB;CAG7C,MAAM,sBACH,QAAQ,iBAAiB,uBAC1B,EAAE;CACJ,MAAM,qBACH,QAAQ,iBAAiB,sBAA+C,EAAE;CAC7E,MAAM,uBACH,QAAQ,iBAAiB,wBAC1B,EAAE;CAIJ,MAAM,gBAAgC,EAAE;AACxC,KAAI,oBAAoB,SAAS,EAC/B,eAAc,KAAK;EACjB,OAAO;EACP,OAAO,oBAAoB,KAAK,KAAK;EACtC,CAAC;AAEJ,KAAI,mBAAmB,SAAS,EAC9B,eAAc,KAAK;EACjB,OAAO;EACP,OAAO,mBAAmB,KAAK,KAAK;EACrC,CAAC;CAKJ,MAAM,OAAO,kBACX,qBAAC,KAAD;EAAK,eAAc;EAAS,OAAO;YAAnC;GACE,qBAAC,MAAD,EAAA,UAAA;IAAM;IAEI,oBAAC,MAAD;KAAM,OAAM;eAAO;KAAwC,CAAA;;IAC9D,EAAA,CAAA;GACP,oBAAC,KAAD;IAAK,eAAc;IAAS,WAAW;cACrC,qBAAC,MAAD,EAAA,UAAA;KAAM;KACA;KACJ,oBAAC,MAAD;MAAM,QAAA;MAAO,OAAM;gBAChB,QAAQ;MACJ,CAAA;KAAC;KAAI;KAGP,EAAA,CAAA;IACH,CAAA;GACN,qBAAC,KAAD;IAAK,eAAc;IAAS,WAAW;IAAG,aAAa;cAAvD;KACE,qBAAC,MAAD,EAAA,UAAA,CAAO,KAAS,oBAAwB,EAAA,CAAA;KACxC,qBAAC,MAAD,EAAA,UAAA,CAAO,KAAS,kBAAsB,EAAA,CAAA;KACtC,qBAAC,MAAD,EAAA,UAAA,CAAO,KAAS,wBAA4B,EAAA,CAAA;KACxC;;GACF;MAEN,qBAAA,UAAA,EAAA,UAAA,CACE,qBAAC,KAAD;EAAK,eAAc;EAAS,YAAW;YAAvC,CACE,oBAAC,MAAD,EAAA,UAAM,2DAA8D,CAAA,EACpE,oBAAC,KAAD;GAAK,eAAc;GAAS,WAAW;aACrC,oBAAC,MAAD,EAAA,UAAM,mCAAsC,CAAA;GACxC,CAAA,CACF;KAEL,qBAAqB,SAAS,KAC7B,qBAAC,KAAD;EAAK,eAAc;EAAS,WAAW;YAAvC,CACE,qBAAC,MAAD;GAAM,UAAA;aAAN;IAAe;IAAU,qBAAqB;IAAO;IAAiB;MACrE,qBAAqB,KAAK,MACzB,qBAAC,MAAD;GAAc,UAAA;aAAd;IACG;IACA;IAAS;IAAE;IACP;KAHI,EAGJ,CACP,CACE;IAEP,EAAA,CAAA;CAKL,MAAM,YAAY,cAChB,qBAAA,UAAA,EAAA,UAAA,CACE,qBAAC,KAAD;EAAK,eAAc;EAAS,cAAc;YAA1C,CACE,qBAAC,MAAD;GAAM,OAAM;GAAM,MAAA;aAAlB,CACG,KAAS,mCACL;MACP,oBAAC,KAAD;GAAK,WAAW;GAAG,eAAc;aAC/B,oBAAC,iBAAD,EAAiB,OAAO,aAAe,CAAA;GACnC,CAAA,CACF;KAEN,oBAAC,YAAD;EACE,SAAS,CAAC;GAAE,OAAO;GAAQ,OAAO;GAAQ,CAAC;EAC3C,gBAAgB,QAAQ,KAAK,EAAE;EAC/B,CAAA,CACD,EAAA,CAAA,GACD,KAAA;CAGJ,MAAM,cAAc,kBAChB,CAAC;EAAE,OAAO;EAAQ,OAAO;EAAQ,CAAC,GAClC;EACE;GAAE,OAAO;GAAY,OAAO;GAAY;EACxC;GAAE,OAAO;GAAa,OAAO;GAAa;EAC1C;GAAE,OAAO;GAAU,OAAO;GAAU;EACrC;AAGL,QACE,oBAAC,mBAAD;EACE,YAAY,QAAQ;EACpB,cAAc,CAAC;EACT;EACN,eAAe,CAAC;EACD;EACJ;EACX,eAAe,QAAQ;EACvB,SAAS,QAAQ;EACJ;EACb,WAAW,UAAU;AACnB,OAAI,UAAU,SACZ,SAAQ,KAAK,EAAE;YACN,UAAU,YACnB,oBAAmB,KAAK;YACf,UAAU,OACnB,oBAAmB,MAAM;OAEzB,OAAM,eAAe;;EAGzB,CAAA;;AAIN,MAAM,mBAAmB,EAAE,YAA2C;AACpE,SAAQ,MAAM,MAAd;EACE,KAAK,iBAAiB;GACpB,MAAM,aAAa;IACjB,SAAS;IACT,WAAW;IACX,YAAY;IACb,CAAC,MAAM;AACR,UACE,qBAAA,UAAA,EAAA,UAAA,CACE,qBAAC,MAAD,EAAA,UAAA;IAAM;IAAW;IAAW;IAAQ,EAAA,CAAA,EACpC,qBAAC,MAAD;IAAM,UAAA;cAAN,CACG,MACA,MAAM,KACF;MACN,EAAA,CAAA;;EAIP,KAAK,kBACH,QACE,qBAAA,UAAA,EAAA,UAAA;GACE,oBAAC,MAAD,EAAA,UAAM,4CAA+C,CAAA;GACrD,oBAAC,MAAD;IAAM,UAAA;cAAS;IAER,CAAA;GACP,oBAAC,MAAD;IAAM,UAAA;cAAS;IAA+C,CAAA;GAC7D,EAAA,CAAA;EAGP,KAAK,UACH,QACE,qBAAA,UAAA,EAAA,UAAA;GACE,qBAAC,MAAD,EAAA,UAAA;IAAM;IAC8C;IACjD,MAAM;IAAa;IACnB,MAAM,iBAAiB,IAAI,KAAK;IAAI;IAChC,EAAA,CAAA;GACP,qBAAC,KAAD;IAAK,WAAW;IAAG,eAAc;cAAjC;KACE,oBAAC,MAAD,EAAA,UAAM,+BAAkC,CAAA;KACxC,qBAAC,MAAD;MAAM,UAAA;gBAAN;OACG;OAAW;OAAiB,aAAa,MAAM,GAAG,EAAE,CAAC,KAAK,KAAK;OAAC;OAE5D;;KACP,qBAAC,MAAD;MAAM,UAAA;gBAAN;OACG;OAAW;OAAgB,YAAY,KAAK,KAAK;OAAC;OAC9C;;KACH;;GACN,oBAAC,KAAD;IAAK,WAAW;cACd,qBAAC,MAAD;KAAM,UAAA;eAAN;MAAe;MACU,oBAAC,MAAD;OAAM,MAAA;iBAAK;OAA0B,CAAA;;MAEvD;;IACH,CAAA;GACL,EAAA,CAAA;EAGP,KAAK,kBACH,QACE,qBAAA,UAAA,EAAA,UAAA,CACE,qBAAC,MAAD,EAAA,UAAA;GAAM;GACW,MAAM,YAAY,KAAK,KAAK;GAAC;GACvC,EAAA,CAAA,EACP,oBAAC,KAAD;GAAK,WAAW;aACd,qBAAC,MAAD;IAAM,UAAA;cAAN;KAAe;KACT,oBAAC,MAAD;MAAM,MAAA;gBAAK;MAA0B,CAAA;;KAEpC;;GACH,CAAA,CACL,EAAA,CAAA;EAGP,KAAK,iBACH,QACE,qBAAA,UAAA,EAAA,UAAA;GACE,qBAAC,MAAD,EAAA,UAAA;IAAM;IACY,MAAM,aAAa,KAAK,KAAK;IAAC;IACzC,EAAA,CAAA;GACP,oBAAC,MAAD;IAAM,UAAA;cAAS;IAER,CAAA;GACP,qBAAC,KAAD;IAAK,WAAW;IAAG,eAAc;cAAjC,CACE,oBAAC,MAAD;KAAM,UAAA;eAAS;KAAsB,CAAA,EACpC,YAAY,KAAK,QAChB,qBAAC,MAAD;KAAgB,UAAA;eAAhB;MACG;MAAW;MAAE;MACT;OAFI,IAEJ,CACP,CACE;;GACL,EAAA,CAAA;;;;;;;;;;;AC5OX,MAAa,yBAAyB,EACpC,YACgC;AAChC,uBACG,OAAO,MAAM,UAAU,GAAG,QACrB,MAAM,aAAa,CAC1B;CAED,MAAM,CAAC,iBAAiB,sBAAsB,SAAS,MAAM;CAC7D,MAAM,CAAC,YAAY,iBAAiB,SAA4B,KAAK;CACrE,MAAM,CAAC,aAAa,kBAAkB,SAAS,MAAM;CAErD,MAAM,EAAE,YAAY;CACpB,MAAM,UAAU,QAAQ,WAAW;CACnC,MAAM,aAAa,CAAC;AAGpB,iBAAgB;AACd,MAAI,CAAC,mBAAmB,cAAc,YAAa;AAG9C,iBADW,iBAAiB,QAAQ,SAAS,CACtB,CAAC,MAAM,SAAS;AAC1C,OAAI,CAAC,MAAM;AACT,mBAAe,KAAK;AACpB;;GAGF,MAAM,QADY,OAAO,OAAO,KAAK,WAAW,CAAC,MAAM,CAC/B,MAAM,MAAM,EAAE,OAAO,QAAQ;AACrD,OAAI,MACF,eAAc,MAAM;OAEpB,gBAAe,KAAK;IAEtB;IACD;EAAC;EAAiB;EAAY;EAAa;EAAS,QAAQ;EAAS,CAAC;CAIzE,IAAI;AAEJ,KAAI,gBACF,QACE,qBAAC,KAAD;EAAK,eAAc;EAAS,OAAO;YAAnC;GACE,oBAAC,KAAD;IAAK,eAAc;IAAS,cAAc;cACxC,qBAAC,MAAD,EAAA,UAAA,CAAM,iFAEI,oBAAC,MAAD;KAAM,OAAM;eAAO;KAAwC,CAAA,CAC9D,EAAA,CAAA;IACH,CAAA;GACN,qBAAC,MAAD,EAAA,UAAA;IAAM;IACG;IACP,oBAAC,MAAD;KAAM,QAAA;KAAO,OAAM;eAChB,YAAY,MAAM;KACd,CAAA;IACF,EAAA,CAAA;GACP,qBAAC,MAAD,EAAA,UAAA;IAAM;IACC;IACL,oBAAC,MAAD;KAAM,OAAM;eACT,YAAY,gBACV,cAAc,gBAAgB;KAC5B,CAAA;IACF,EAAA,CAAA;GACP,oBAAC,KAAD;IAAK,WAAW;cACd,oBAAC,MAAD;KAAM,UAAA;eACH,YAAY,SAAS,cAAc,UAAU;KACzC,CAAA;IACH,CAAA;GACF;;KAGR,QACE,qBAAC,MAAD,EAAA,UAAA;EAAM;EACU;EACd,oBAAC,MAAD;GAAM,QAAA;GAAO,OAAM;aAChB;GACI,CAAA;EAAC;EAAI;EAEP,EAAA,CAAA;CAMX,MAAM,cAAc,kBAChB,CAAC;EAAE,OAAO;EAAQ,OAAO;EAAQ,CAAC,GAClC;EACE;GAAE,OAAO;GAAY,OAAO;GAAY;EACxC;GAAE,OAAO;GAAa,OAAO;GAAa;EAC1C;GAAE,OAAO;GAAU,OAAO;GAAU;EACrC;CAEL,MAAM,gBAAgB,UAAkB;AACtC,MAAI,UAAU,SACZ,SAAQ,KAAK,EAAE;WACN,UAAU,YACnB,oBAAmB,KAAK;WACf,UAAU,OACnB,oBAAmB,MAAM;MAEzB,OAAM,eAAe;;AAMzB,QACE,oBAAC,mBAAD;EACE,YAAY,QAAQ;EACpB,cAAc,CAAC;EACT;EACN,eAAe;EACf,eAAe,QAAQ;EACvB,SAAS,QAAQ;EACJ;EACb,UAAU;EACV,CAAA;;;;;;;;;;;AClHN,MAAa,eAAe,EAAE,YAA8B;AAC1D,uBACG,OAAO,MAAM,UAAU,GAAG,QACrB,MAAM,aAAa,CAC1B;CAED,MAAM,SAAS,MAAM,QAAQ;CAC7B,MAAM,YAAY,QAAQ,SAAS,OAAO,aAAa,EAAE;CAGzD,MAAM,CAAC,cAAc,mBAAmB,SAAS,EAAE;CACnD,MAAM,CAAC,WAAW,gBAAgB,SAAS,KAAK;AAGhD,iBAAgB;AACd,GAAM,YAAY;AAChB,QAAK,MAAM,KAAK,WAAW;AAEzB,QAAI,EAAE,OAAO,MAAM,QAAQ,iBAAkB;AAE7C,QAAI;KACF,MAAM,WAAW,MAAM,EAAE,OAAO,EAC9B,YAAY,MAAM,QAAQ,YAC3B,CAAC;AACF,SAAI,aAAa,KACf,OAAM,oBAAoB,EAAE,KAAK,SAAS;YAEtC;;AAIV,gBAAa,MAAM;MAIjB;IACH,EAAE,CAAC;AAEN,KAAI,UACF,QACE,oBAAC,KAAD;EAAK,eAAc;EAAS,UAAU;YACpC,oBAAC,MAAD;GAAM,UAAA;aAAS;GAAyC,CAAA;EACpD,CAAA;CAKV,MAAM,aAAa,UAAU,QAC1B,MAAqB,EAAE,EAAE,OAAO,MAAM,QAAQ,kBAChD;AAED,KAAI,WAAW,WAAW,EAExB,QAAO;CAGT,MAAM,WAAW,WAAW,iBAAiB,WAAW;AACxD,KAAI,CAAC,SAAU,QAAO;AAEtB,QACE,qBAAC,KAAD;EAAK,eAAc;EAAS,UAAU;YAAtC,CACE,qBAAC,KAAD;GAAK,eAAc;GAAS,cAAc;aAA1C,CACE,oBAAC,MAAD;IAAM,MAAA;IAAK,OAAO,OAAO;cAAQ;IAE1B,CAAA,EACN,UACC,qBAAC,MAAD;IAAM,UAAA;cAAN;KAAe;KAAa,OAAO,SAAS;KAAK;KAAmB;MAElE;MAEN,oBAAC,YAAD;GACE,SAAS,SAAS;GAClB,SAAS,SAAS,QAAQ,KAAK,OAAO;IACpC,OAAO,EAAE;IACT,OAAO,EAAE;IACT,MAAM,EAAE;IACT,EAAE;GACH,WAAW,UAAU;IACnB,MAAM,WAAW,MAAM,QAAQ,MAAM,GAAG,MAAM,KAAK;AACnD,UAAM,oBAAoB,SAAS,KAAK,SAAS;AASjD,QANkB,WAAW,QAC1B,MACC,EAAE,QAAQ,SAAS,OACnB,EAAE,EAAE,OAAO,MAAM,QAAQ,kBAC5B,CAEa,SAAS,EACrB,kBAAiB,MAAM,IAAI,EAAE;;GAKjC,CAAA,CACE;;;;;;;;;;;;ACjGV,MAAa,cAAc,EAAE,YAA6B;AACxD,uBACG,OAAO,MAAM,UAAU,GAAG,QACrB,MAAM,aAAa,CAC1B;CAED,MAAM,EAAE,YAAY;CACpB,MAAM,SAAS,QAAQ;CACvB,MAAM,iBACJ,QAAQ,0BAA0B,QAAQ,SAAS;AAErD,QACE,qBAAC,KAAD;EAAK,eAAc;EAAS,UAAU;YAAtC;GACE,qBAAC,KAAD;IAAK,eAAc;IAAS,cAAc;cAA1C;KACE,oBAAC,MAAD;MAAM,MAAA;MAAK,OAAO,OAAO;gBAAQ;MAE1B,CAAA;KAEN,kBACC,qBAAC,MAAD,EAAA,UAAA,CACE,qBAAC,MAAD;MAAM,OAAM;gBAAZ,CAAqB,KAAS,IAAQ;SACtC,qBAAC,MAAD,EAAA,UAAA,CAAM,eAAY,eAAsB,EAAA,CAAA,CACnC,EAAA,CAAA;KAGR,QAAQ,SAAS,QAChB,qBAAC,MAAD;MAAM,OAAM;gBAAZ;OAAqB;OACP,OAAO,SAAS;OAAK;OAE5B;;KAGR,QAAQ,SAAS,gBAChB,oBAAC,MAAD;MAAM,OAAM;gBAAU,OAAO,SAAS;MAAoB,CAAA;KAExD;;GAEN,oBAAC,YAAD,EAAY,SAAQ,iCAAkC,CAAA;GAErD,QAAQ,YACP,qBAAC,KAAD;IAAK,WAAW;IAAG,eAAc;cAAjC,CACE,oBAAC,MAAD;KAAM,UAAA;eAAS;KAER,CAAA,EACP,oBAAC,MAAD;KAAM,OAAM;eAAQ,QAAQ;KAAgB,CAAA,CACxC;;GAEJ;;;;;;;;;;;;;;;ACrCV,MAAM,WAAW;AAMjB,MAAa,aAAa,EAAE,YAA4B;AACtD,uBACG,OAAO,MAAM,UAAU,GAAG,QACrB,MAAM,aAAa,CAC1B;CAED,MAAM,CAAC,WAAW,qBAAqB;CAEvC,MAAM,gBAAgC,MAAM,MAAM,KAAK,OAAO;EAC5D,OAAO,EAAE;EACT,YAAY,EAAE;EACd,QAAQ,EAAE;EACX,EAAE;CAGH,MAAM,QAAQ,MAAM,QAAQ;AAI5B,KAFE,cAAc,SAAS,KACvB,cAAc,OAAO,MAAM,EAAE,WAAW,YAAY,IACvC,MAAM,SAAS,GAAG;EAC/B,MAAM,YAAY,0BAA0B,MAAM;AAClD,gBAAc,KAAK;GACjB,OAAO,UAAU;GACjB,YAAY,cAAc,UAAU;GACpC,QAAQ;GACT,CAAC;;CAGJ,MAAM,WACJ,MAAM,eAAe,SAAS,IAAI,MAAM,iBAAiB,KAAA;CAE3D,MAAM,WAAW,MAAM,oBACrB,oBAAC,UAAD,EAAiB,OAAS,CAAA,GAE1B,oBAAC,WAAD;EAAkB;EAAO,kBAAkB,MAAM,sBAAsB;EAAI,CAAA;CAE7E,MAAM,eAAe,oBAAC,cAAD;EAAc,OAAO;EAAe,OAAM;EAAU,CAAA;AAuCzE,QACE,oBAAC,cAAD;EACE,MA7BS;GACX;IACE,IAAI;IACJ,OAAO;IACP,WAZF,UAAU,KACR,oBAAC,KAAD;KAAK,eAAc;KAAS,UAAU;eACnC;KACG,CAAA,GAEN,oBAAC,WAAD;KAAW,MAAM;KAAU,OAAO;KAAgB,CAAA;IAQnD;GACD,GAAI,MAAM,UAAU,SAAS,IACzB,CACE;IACE,IAAI;IACJ,OAAO;IACP,WAAW,oBAAC,iBAAD,EAAiB,QAAQ,MAAM,WAAa,CAAA;IACxD,CACF,GACD,EAAE;GACN;IACE,IAAI;IACJ,OAAO;IACP,WAAW,oBAAC,WAAD,EAAW,UAAU,UAAY,CAAA;IAC7C;GACD;IACE,IAAI;IACJ,OAAO;IACP,WAAW,oBAAC,UAAD,EAAY,CAAA;IACxB;GACF;EAKG,eAAe;EACf,kBAAA;EACO;EACP,CAAA;;;;;;;;;;;;AChFN,MAAa,oBAAoB,EAAE,YAAmC;AACpE,uBACG,OAAO,MAAM,UAAU,GAAG,QACrB,MAAM,aAAa,CAC1B;CAED,MAAM,CAAC,OAAO,YAAY,SAAA,UAA8B;CACxD,MAAM,CAAC,QAAQ,aAAa,SAAuB,EAAE,CAAC;CAEtD,MAAM,YAAY,KAAK,MAAM,QAAQ,YAAY,WAAW,SAAS;AAErE,iBAAgB;AACd,GAAM,YAAY;AAChB,OAAI;IAEF,MAAM,QADU,MAAM,QAAQ,WAAW,EAAE,eAAe,MAAM,CAAC,EAC5C,QAAQ,MAAM,EAAE,aAAa,CAAC;IACnD,MAAM,SAAuB,EAAE;AAC/B,SAAK,MAAM,OAAO,MAAM;KACtB,MAAM,WAAW,MAAM,QAAQ,KAAK,WAAW,IAAI,KAAK,CAAC;AACzD,YAAO,KAAK;MAAE,MAAM,IAAI;MAAM;MAAU,CAAC;;AAE3C,QAAI,OAAO,WAAW,GAAG;AACvB,WAAM,kBAAkB,KAAK;AAC7B,aAAQ,KAAK,EAAE;;AAEjB,cAAU,OAAO;AACjB,aAAA,MAAmB;WACb;AACN,UAAM,kBAAkB,KAAK;AAC7B,YAAQ,KAAK,EAAE;;MAEf;IACH,EAAE,CAAC;CAEN,MAAM,mBAAmB;AACvB,QAAM,kBAAkB,KAAK;AAC7B,UAAQ,KAAK,EAAE;;CAGjB,MAAM,eAAe,YAAY;AAC/B,WAAA,WAAwB;AACxB,MAAI;AACF,SAAM,GAAG,WAAW;IAAE,WAAW;IAAM,OAAO;IAAM,CAAC;UAC/C;AAGR,WAAA,OAAoB;AAEpB,mBAAiB;AACf,SAAM,kBAAkB,MAAM;AAC9B,WAAQ,KAAK,EAAE;KACd,IAAI;;AAGT,QACE,qBAAC,KAAD;EAAK,eAAc;EAAS,UAAU;YAAtC,CACE,oBAAC,MAAD;GAAM,MAAA;GAAK,OAAO,OAAO;aAAQ;GAE1B,CAAA,EAEP,qBAAC,KAAD;GAAK,WAAW;GAAG,eAAc;aAAjC;IACG,UAAA,aACC,oBAAC,MAAD;KAAM,UAAA;eAAS;KAAmC,CAAA;IAGnD,UAAA,SACC,qBAAA,UAAA,EAAA,UAAA;KACE,oBAAC,MAAD;MAAM,UAAA;gBAAS;MAGR,CAAA;KACP,qBAAC,KAAD;MAAK,WAAW;MAAG,eAAc;MAAS,YAAY;gBAAtD;OACE,oBAAC,MAAD;QAAM,UAAA;kBAAS;QAAe,CAAA;OAC9B,oBAAC,MAAD;QAAM,UAAA;kBAAS;QAAe,CAAA;OAC7B,OAAO,KAAK,UACX,qBAAC,KAAD;QAAsB,eAAc;kBAApC,CACE,qBAAC,MAAD;SAAM,UAAA;mBAAN;UAAe;UAAE,MAAM;UAAK;UAAQ;YACnC,MAAM,SAAS,KAAK,UACnB,qBAAC,MAAD;SAAkB,UAAA;mBAAlB,CACG,UACA,MACI;WAHI,MAGJ,CACP,CACE;UARI,MAAM,KAQV,CACN;OACE;;KACN,oBAAC,KAAD;MAAK,WAAW;gBACd,qBAAC,MAAD;OAAM,UAAA;iBAAN,CAAe,YACL,oBAAC,MAAD;QAAM,OAAM;;QAAgC,CAAA,CAC/C;;MACH,CAAA;KACN,oBAAC,KAAD;MAAK,WAAW;gBACd,oBAAC,mBAAD;OACE,SAAQ;OACR,cAAa;OACb,aAAY;OACZ,WAAW;OACX,gBAAgB,KAAK,cAAc;OACnC,CAAA;MACE,CAAA;KACL,EAAA,CAAA;IAGJ,UAAA,cAA4B,oBAAC,MAAD;KAAM,UAAA;eAAS;KAAyB,CAAA;IAEpE,UAAA,UAAwB,oBAAC,MAAD;KAAM,UAAA;eAAS;KAAsB,CAAA;IAC1D;KACF;;;;;;;;;;AC9HV,MAAa,eAAe,EAAE,YAA8B;AAC1D,uBACG,OAAO,MAAM,UAAU,GAAG,QACrB,MAAM,aAAa,CAC1B;AAED,gBAAe;AACb,QAAM,mBAAmB;GACzB;CAEF,MAAM,YAAY,MAAM,QAAQ;AAEhC,KAAI,CAAC,UACH,QACE,oBAAC,KAAD;EAAK,eAAc;EAAS,UAAU;YACpC,oBAAC,MAAD;GAAM,UAAA;aAAS;GAAsB,CAAA;EACjC,CAAA;AAIV,QACE,qBAAC,KAAD;EAAK,eAAc;EAAS,UAAU;YAAtC;GACG,UAAU,SAAA,aACT,qBAAC,KAAD;IAAK,eAAc;cAAnB;KACE,qBAAC,MAAD;MAAM,OAAM;MAAQ,MAAA;gBAApB;OACG;OAAS;OAAE,UAAU,WAAW;OAC5B;;KAEN,UAAU,cACT,oBAAC,KAAD;MAAK,WAAW;gBACd,qBAAC,MAAD,EAAA,UAAA;OAAM;OACE,qBAAC,MAAD;QAAM,MAAA;kBAAN,CAAW,MAAG,UAAU,WAAkB;;;OAC3C,EAAA,CAAA;MACH,CAAA;KAGP,UAAU,WAAW,UAAU,QAAQ,SAAS,KAC/C,qBAAC,KAAD;MAAK,eAAc;MAAS,WAAW;gBAAvC,CACE,oBAAC,MAAD;OAAM,OAAM;OAAO,MAAA;iBAAK;OAEjB,CAAA,EACN,UAAU,QAAQ,KAAK,QAAQ,MAC9B,qBAAC,MAAD,EAAA,UAAA;OACG;OAAS;OAAE;OACP,EAAA,EAFI,EAEJ,CACP,CACE;;KAGP,MAAM,UAAU,SAAS,KACxB,qBAAC,KAAD;MAAK,eAAc;MAAS,WAAW;gBAAvC,CACE,oBAAC,MAAD;OAAM,OAAM;OAAO,MAAA;iBAAK;OAEjB,CAAA,EACN,MAAM,UAAU,KAAK,UACpB,qBAAC,MAAD,EAAA,UAAA;OACG;OAAS;OAAC,oBAAC,MAAD;QAAM,MAAA;kBAAM,MAAM;QAAY,CAAA;OACzC,qBAAC,MAAD;QAAM,UAAA;kBAAN,CAAe,KAAE,MAAM,YAAmB;;OACrC,EAAA,EAHI,MAAM,KAGV,CACP,CACE;;KAGP,UAAU,WACT,oBAAC,KAAD;MAAK,WAAW;gBACd,qBAAC,MAAD,EAAA,UAAA,CAAM,gBACQ,oBAAC,MAAD;OAAM,OAAM;iBAAQ,UAAU;OAAe,CAAA,CACpD,EAAA,CAAA;MACH,CAAA;KAGP,UAAU,eACT,oBAAC,KAAD,EAAA,UACE,qBAAC,MAAD,EAAA,UAAA;MAAM;MACiB;MACrB,oBAAC,MAAD;OAAM,OAAM;iBAAQ,UAAU;OAAmB,CAAA;MAC5C,EAAA,CAAA,EACH,CAAA;KAGR,oBAAC,KAAD;MAAK,WAAW;gBACd,oBAAC,MAAD;OAAM,UAAA;iBAAS;OAGR,CAAA;MACH,CAAA;KACN,oBAAC,KAAD,EAAA,UACE,oBAAC,MAAD;MAAM,UAAA;gBAAS;MAER,CAAA,EACH,CAAA;KACF;;GAGP,UAAU,SAAA,WACT,qBAAC,KAAD;IAAK,eAAc;cAAnB;KACE,qBAAC,MAAD;MAAM,OAAM;MAAM,MAAA;gBAAlB;OACG;OAAS;OAAE,UAAU,WAAW;OAC5B;;KAEN,UAAU,QACT,oBAAC,KAAD;MAAK,WAAW;gBACd,oBAAC,MAAD;OAAM,UAAA;iBAAU,UAAU;OAAY,CAAA;MAClC,CAAA;KAGP,UAAU,WACT,oBAAC,KAAD;MAAK,WAAW;gBACd,qBAAC,MAAD,EAAA,UAAA,CAAM,UACE,oBAAC,MAAD;OAAM,OAAM;iBAAQ,UAAU;OAAe,CAAA,CAC9C,EAAA,CAAA;MACH,CAAA;KAEJ;;GAGP,UAAU,SAAA,YACT,oBAAC,KAAD;IAAK,eAAc;cACjB,qBAAC,MAAD;KAAM,OAAM;eAAZ;MACG;MAAS;MAAE,UAAU,WAAW;MAC5B;;IACH,CAAA;GAGR,oBAAC,KAAD;IAAK,WAAW;cACd,oBAAC,MAAD;KAAM,OAAO,OAAO;eAAO;KAAgC,CAAA;IACvD,CAAA;GACF;;;;;;;;;;;ACtIV,MAAa,mBAAmB;AAC9B,iBAAgB;AACd,UAAQ,KAAK,EAAE;IACd,EAAE,CAAC;AAEN,QAAO;;;;;;;;;;ACJT,MAAa,wBAAwB;AACnC,gBAAe;AACb,UAAQ,KAAK,EAAE;GACf;AAEF,QACE,qBAAC,KAAD;EAAK,eAAc;EAAS,UAAU;YAAtC;GACE,qBAAC,MAAD;IAAM,OAAM;IAAM,MAAA;cAAlB,CACG,KAAS,wBACL;;GAEP,oBAAC,KAAD;IAAK,eAAc;IAAS,WAAW;cACrC,oBAAC,MAAD,EAAA,UAAM,mIAIC,CAAA;IACH,CAAA;GAEN,oBAAC,KAAD;IAAK,WAAW;cACd,oBAAC,MAAD;KAAM,UAAA;eAAS;KAGR,CAAA;IACH,CAAA;GAEN,oBAAC,KAAD;IAAK,eAAc;IAAS,WAAW;IAAG,aAAa;cACrD,oBAAC,MAAD;KAAM,OAAM;eAAO;KAAyB,CAAA;IACxC,CAAA;GAEN,oBAAC,KAAD;IAAK,WAAW;cACd,oBAAC,MAAD;KAAM,OAAO,OAAO;eAAO;KAA4B,CAAA;IACnD,CAAA;GACF;;;;;;;;;;;;;;ACNV,SAAgB,qBAAmC;CAEjD,IAAI,gBAAuD,EAAE;AAE7D,QAAO;EACL,MAAM,gBAA0C;GAC9C,MAAM,YAAY,MAAM,qBAAqB;AAC7C,mBAAgB,UAAU,KAAK,OAAO;IAAE,MAAM,EAAE;IAAM,KAAK;IAAG,EAAE;AAChE,UAAO,UAAU,KAAK,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE;;EAGjD,MAAM,QACJ,aACA,UACA,QACmB;GACnB,MAAM,mBAAmB,YAAY,CAAC,GAAG,mBAAmB;GAC5D,MAAM,YAAY,cACf,QAAQ,MAAM,YAAY,SAAS,EAAE,KAAK,CAAC,CAE3C,KAAK,MAAM,EAAE,IAAW;AAE3B,OAAI,UAAU,WAAW,GAAG;AAC1B,cACE,kDAAkD,KAAK,UACrD,YACD,CAAC,WAAW,KAAK,UAAU,cAAc,KAAK,MAAM,EAAE,KAAK,CAAC,GAC9D;AACD,WAAO,EAAE;;GAGX,MAAM,YAAsB,EAAE;AAC9B,QAAK,MAAM,UAAU,UACnB,KAAI;AAMF,SALe,MAAM,OAAO,UAC1B,QACA,kBACA,MACD,GACW,QACV,WAAU,KAAK,OAAO,KAAe;QAErC,WACE,uDAAuD,OAAO,OAC/D;YAEI,KAAK;AACZ,cACE,sCAAsC,OAAO,KAAK,IAChD,eAAe,QAAQ,IAAI,UAAU,OAAO,IAAI,GAEnD;;AAGL,UAAO;;EAGT,MAAM,SAA4B;GAChC,MAAM,YAAY,MAAM,qBAAqB;AAC7C,OAAI,UAAU,WAAW,EAAG,QAAO,EAAE;AACrC,SAAM,gBAAgB,UAAU;AAChC,UAAO,UAAU,KAAK,MAAM,EAAE,KAAK;;EAEtC;;;;AC/DH,SAAgB,iBAAiC;AAC/C,QAAO,EACL,cAAc,oBAAoB,EACnC;;AAGH,SAAgB,cACd,OACA,UAC+B;AAC/B,QAAO;yBAEuB,oBAAC,wBAAD,EAA+B,OAAS,CAAA;wBACzC,oBAAC,uBAAD,EAA8B,OAAS,CAAA;qBAC1C,oBAAC,oBAAD,EAA2B,OAAS,CAAA;kBACvC,oBAAC,iBAAD,EAAmB,CAAA;aAGxB,oBAAC,+BAAD,EAAsC,OAAS,CAAA;qBACxC,oBAAC,oBAAD,EAA2B,OAAS,CAAA;yBACjC,oBAAC,uBAAD,EAA8B,OAAS,CAAA;oBAC3C,oBAAC,mBAAD,EAA0B,OAAS,CAAA;aACzC,oBAAC,aAAD,EAAoB,OAAS,CAAA;YAC9B,oBAAC,YAAD,EAAmB,OAAS,CAAA;WAC7B,oBAAC,WAAD,EAAkB,OAAS,CAAA;WAC3B,oBAAC,WAAD;GAAkB;GAAO,WAAW,SAAS;GAAgB,CAAA;mBACtD,oBAAC,kBAAD,EAAyB,OAAS,CAAA;aACvC,oBAAC,aAAD,EAAoB,OAAS,CAAA;YAC9B,oBAAC,YAAD,EAAc,CAAA;eAI3B,oBAAC,WAAD;GAAkB;GAAO,WAAW,SAAS;GAAgB,CAAA;kBAG7D,oBAAC,WAAD;GACS;GACP,WAAW,SAAS;GACpB,MAAK;GACL,CAAA;EAEL;;;;ACrEH,MAAa,OAAO,EAAE,YAAsB;CAC1C,MAAM,WAAW,cAAc,gBAAgB,EAAE,EAAE,CAAC;AAMpD,QAAO,oBAAC,iBAAD;EAAwB;EAAO,SALtB,cACR,cAAc,OAAO,SAAS,EACpC,CAAC,OAAO,SAAS,CAClB;EAEyD,CAAA;;;;;;;;;;;ACC5D,MAAM,cAAc;AACpB,MAAM,eAAe;AACrB,MAAM,cAAc;AACpB,MAAM,WAAW;AACjB,MAAM,mBAAmB;AACzB,MAAM,mBAAmB;AACzB,MAAM,QAAQ;AACd,MAAM,OAAO;AACb,MAAM,MAAM;AAEZ,SAAS,YAAY,OAA4B;CAC/C,MAAM,QAAQ,MAAM,QAAQ;CAC5B,MAAM,QAAQ,MAAM,QAAQ,iBAAiB;AAE7C,KAAI,OAAO,SAAA,UACT,QAAO,GAAG,QAAQ,KAAK,QAAQ,YAAY,GACzC,MAAM,WAAW,GAAG,MAAM;AAI9B,QAAO,GAAG,MAAM,MAAM,UAAU;;AAGlC,SAAgB,SACd,SACA,OAAA,uBAKA;AAEA,SAAQ,OAAO,MACb,mBAAmB,WAAW,eAAe,YAC9C;CAED,MAAM,QAAQ,IAAI,YAAY,KAAK;AACnC,OAAM,UAAU;AAIhB,OADc,IAAI,MAAM,MAAM,CAClB;CAGZ,MAAM,EAAE,SAAS,eAAe,OAAO,cAAc,KAAK,EAAE,OAAO,CAAC,CAAC;CAIrE,IAAI,UAAU;CACd,MAAM,gBAAgB;AACpB,MAAI,QAAS;AACb,YAAU;AACV,cAAY;AACZ,UAAQ,OAAO,MAAM,cAAc,iBAAiB;AACpD,UAAQ,OAAO,MAAM,YAAY,MAAM,GAAG,KAAK;;AAEjD,SAAQ,GAAG,QAAQ,QAAQ;AAE3B,QAAO;EACL,SAAS;EACT;EACA,oBAAoB,MAAM,QAAQ,QAAQ;EAC3C"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"steps-zpqG7W08.js","names":["path","fs","spawnSync"],"sources":["../src/steps/upload-environment-variables/EnvironmentProvider.ts","../src/steps/upload-environment-variables/providers/vercel.ts","../src/steps/upload-environment-variables/index.ts"],"sourcesContent":["export abstract class EnvironmentProvider {\n protected options: { installDir: string };\n\n name: string;\n\n constructor(options: { installDir: string }) {\n this.options = options;\n }\n\n abstract detect(): Promise<boolean>;\n\n abstract uploadEnvVars(\n vars: Record<string, string>,\n ): Promise<Record<string, boolean>>;\n}\n","import { execSync, spawn, spawnSync } from 'child_process';\nimport { EnvironmentProvider } from '../EnvironmentProvider';\nimport * as fs from 'fs';\nimport * as path from 'path';\nimport { getUI } from '../../../ui';\nimport { analytics } from '../../../utils/analytics';\n\nexport class VercelEnvironmentProvider extends EnvironmentProvider {\n name = 'Vercel';\n environments = ['production', 'preview', 'development'];\n\n constructor(options: { installDir: string }) {\n super(options);\n }\n\n // eslint-disable-next-line @typescript-eslint/require-await\n async detect(): Promise<boolean> {\n const vercelDetected =\n this.hasVercelCli() && this.isProjectLinked() && this.isAuthenticated();\n\n analytics.setTag('vercel-detected', vercelDetected);\n\n return vercelDetected;\n }\n\n hasDotVercelDir(): boolean {\n const dotVercelDir = path.join(this.options.installDir, '.vercel');\n return fs.existsSync(dotVercelDir);\n }\n\n hasVercelCli(): boolean {\n try {\n execSync('vercel --version', { stdio: 'ignore' });\n analytics.setTag('vercel-cli-installed', true);\n return true;\n } catch {\n analytics.setTag('vercel-cli-installed', false);\n return false;\n }\n }\n\n isProjectLinked(): boolean {\n const isProjectLinked = fs.existsSync(\n path.join(this.options.installDir, '.vercel', 'project.json'),\n );\n\n analytics.setTag('vercel-project-linked', isProjectLinked);\n\n return isProjectLinked;\n }\n\n isAuthenticated(): boolean {\n const result = spawnSync('vercel', ['whoami'], {\n encoding: 'utf-8',\n stdio: ['pipe', 'pipe', 'pipe'], // suppress prompts\n env: {\n ...process.env,\n FORCE_COLOR: '0', // avoid ANSI formatting\n CI: '1', // hint to CLI that it's a non-interactive env\n },\n });\n\n const output = (\n String(result.stdout) + String(result.stderr)\n ).toLowerCase();\n\n if (\n output.includes('log in to vercel') ||\n output.includes('vercel login') ||\n result.status !== 0\n ) {\n analytics.setTag('vercel-authenticated', false);\n return false;\n }\n\n analytics.setTag('vercel-authenticated', true);\n\n return true;\n }\n\n async uploadEnvironmentVariable(\n key: string,\n value: string,\n environment: string,\n ): Promise<void> {\n await new Promise<void>((resolve, reject) => {\n const proc = spawn('vercel', ['env', 'add', key, environment], {\n stdio: ['pipe', 'pipe', 'pipe'],\n });\n\n let stderr = '';\n proc.stderr.on('data', (data) => {\n stderr += data.toString();\n });\n\n proc.stdin.write(value);\n proc.stdin.end();\n\n proc.on('close', (code) => {\n if (\n stderr.includes('already exists') ||\n stderr.includes('already been added') ||\n stderr.includes('vercel env rm')\n ) {\n reject(\n new Error(\n `❌ Environment variable ${key} already exists in ${this.name}. Please upload it manually.`,\n ),\n );\n } else if (code === 0) {\n resolve();\n } else {\n reject(\n new Error(\n `❌ Failed to upload environment variable ${key} to ${this.name}. Please upload it manually.`,\n ),\n );\n }\n });\n });\n }\n\n async uploadEnvVars(\n vars: Record<string, string>,\n ): Promise<Record<string, boolean>> {\n const results: Record<string, boolean> = {};\n\n for (const [key, value] of Object.entries(vars)) {\n const spinner = getUI().spinner();\n\n spinner.start(`Uploading ${key} to ${this.name}...`);\n await Promise.all(\n this.environments.map((environment) =>\n this.uploadEnvironmentVariable(key, value, environment),\n ),\n )\n .then(() => {\n spinner.stop(`✅ Uploaded ${key} to ${this.name}`);\n results[key] = true;\n })\n .catch((err) => {\n spinner.stop(\n err instanceof Error\n ? err.message\n : `❌ Failed to upload environment variables to ${this.name}. Please upload it manually.`,\n );\n results[key] = false;\n });\n }\n\n return results;\n }\n}\n","import type { Integration } from '../../lib/constants';\nimport { traceStep } from '../../telemetry';\nimport { analytics } from '../../utils/analytics';\nimport { getUI } from '../../ui';\nimport type { WizardSession } from '../../lib/wizard-session';\nimport { EnvironmentProvider } from './EnvironmentProvider';\nimport { VercelEnvironmentProvider } from './providers/vercel';\n\nexport const uploadEnvironmentVariablesStep = async (\n envVars: Record<string, string>,\n {\n integration,\n session,\n }: {\n integration: Integration;\n session: WizardSession;\n },\n): Promise<string[]> => {\n const providers: EnvironmentProvider[] = [\n new VercelEnvironmentProvider({ installDir: session.installDir }),\n ];\n\n let provider: EnvironmentProvider | null = null;\n\n for (const p of providers) {\n if (await p.detect()) {\n provider = p;\n break;\n }\n }\n\n if (!provider) {\n analytics.wizardCapture('env upload skipped', {\n reason: 'no environment provider found',\n integration,\n });\n return [];\n }\n\n // Auto-accept — the agent already wrote env vars via MCP tools\n getUI().log.info(`Uploading environment variables to ${provider.name}...`);\n\n const results = await traceStep(\n 'uploading environment variables',\n async () => {\n return await provider.uploadEnvVars(envVars);\n },\n );\n\n analytics.wizardCapture('env uploaded', {\n provider: provider.name,\n integration,\n });\n\n return Object.keys(results).filter((key) => results[key]);\n};\n"],"mappings":"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"}
@@ -1,2 +0,0 @@
1
- import { r as buildSession } from "./wizard-session-Db6R023m.js";
2
- export { buildSession };