@posthog/wizard 2.70.0 → 2.70.1

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 (91) hide show
  1. package/dist/{add-mcp-server-to-clients-D2z2adQL.js → add-mcp-server-to-clients-BCnjUqnW.js} +4 -4
  2. package/dist/{add-mcp-server-to-clients-D2z2adQL.js.map → add-mcp-server-to-clients-BCnjUqnW.js.map} +1 -1
  3. package/dist/{agent-interface-NZHof8u3.js → agent-interface-Lu7tnLr0.js} +7 -7
  4. package/dist/{agent-interface-NZHof8u3.js.map → agent-interface-Lu7tnLr0.js.map} +1 -1
  5. package/dist/{agent-prompt-loader-CQijHoX1.js → agent-prompt-loader-y5GxgEkc.js} +5 -5
  6. package/dist/{agent-prompt-loader-CQijHoX1.js.map → agent-prompt-loader-y5GxgEkc.js.map} +1 -1
  7. package/dist/{agent-runner-CK9z7-0z.js → agent-runner-vKtpgqVI.js} +20 -15
  8. package/dist/agent-runner-vKtpgqVI.js.map +1 -0
  9. package/dist/analytics-D-bMEYjD.js +2 -0
  10. package/dist/{analytics-DXPSL5IY.js → analytics-DTyJClPr.js} +2 -2
  11. package/dist/{analytics-DXPSL5IY.js.map → analytics-DTyJClPr.js.map} +1 -1
  12. package/dist/{api-CeapT_rn.js → api-j-OfJ8Dz.js} +3 -3
  13. package/dist/{api-CeapT_rn.js.map → api-j-OfJ8Dz.js.map} +1 -1
  14. package/dist/bin.js +54 -49
  15. package/dist/bin.js.map +1 -1
  16. package/dist/{bounded-fs-DdHuSE1X.js → bounded-fs-BWX25ixc.js} +3 -3
  17. package/dist/{bounded-fs-DdHuSE1X.js.map → bounded-fs-BWX25ixc.js.map} +1 -1
  18. package/dist/{ci-install-c-n8dJng.js → ci-install-zNWgp1TL.js} +4 -4
  19. package/dist/{ci-install-c-n8dJng.js.map → ci-install-zNWgp1TL.js.map} +1 -1
  20. package/dist/{debug-D5YT7Lil.js → debug-BM0fZaGl.js} +3 -3
  21. package/dist/{debug-D5YT7Lil.js.map → debug-BM0fZaGl.js.map} +1 -1
  22. package/dist/{debug-D2KQFr3-.js → debug-xr2Pq5VA.js} +1 -1
  23. package/dist/{env-api-key-ClK4nxHy.js → env-api-key-DlxCZWU0.js} +2 -2
  24. package/dist/{env-api-key-ClK4nxHy.js.map → env-api-key-DlxCZWU0.js.map} +1 -1
  25. package/dist/{environment-DbDconLv.js → environment-o-bTOuzK.js} +4 -4
  26. package/dist/{environment-DbDconLv.js.map → environment-o-bTOuzK.js.map} +1 -1
  27. package/dist/{file-watcher-CQj0wp1a.js → file-watcher-D7G4f5sP.js} +2 -2
  28. package/dist/{file-watcher-CQj0wp1a.js.map → file-watcher-D7G4f5sP.js.map} +1 -1
  29. package/dist/{headless-ui-BKU7MJQf.js → headless-ui-C46DctKG.js} +2 -2
  30. package/dist/{headless-ui-BKU7MJQf.js.map → headless-ui-C46DctKG.js.map} +1 -1
  31. package/dist/{interactive-Bfvo61oS.js → interactive-B5zy3Gxk.js} +2 -2
  32. package/dist/{interactive-Bfvo61oS.js.map → interactive-B5zy3Gxk.js.map} +1 -1
  33. package/dist/{mcp-C_pqYZQY.js → mcp-lJRwE-YW.js} +2 -2
  34. package/dist/{mcp-C_pqYZQY.js.map → mcp-lJRwE-YW.js.map} +1 -1
  35. package/dist/{mcp-prompt-streaming-DOHJxT8K.js → mcp-prompt-streaming-Dsos09hT.js} +4 -4
  36. package/dist/{mcp-prompt-streaming-DOHJxT8K.js.map → mcp-prompt-streaming-Dsos09hT.js.map} +1 -1
  37. package/dist/{non-interactive-CkBbj2As.js → non-interactive-qcCCtiYQ.js} +2 -2
  38. package/dist/{non-interactive-CkBbj2As.js.map → non-interactive-qcCCtiYQ.js.map} +1 -1
  39. package/dist/{orchestrator-tools-DaVjzCRn.js → orchestrator-tools-ezFTbAIp.js} +3 -3
  40. package/dist/{orchestrator-tools-DaVjzCRn.js.map → orchestrator-tools-ezFTbAIp.js.map} +1 -1
  41. package/dist/{package-manager-BD3WR7Ta.js → package-manager-CGfN9UhH.js} +2 -2
  42. package/dist/{package-manager-BD3WR7Ta.js.map → package-manager-CGfN9UhH.js.map} +1 -1
  43. package/dist/{pi-uDtK02b4.js → pi-DzQLHIcQ.js} +11 -11
  44. package/dist/{pi-uDtK02b4.js.map → pi-DzQLHIcQ.js.map} +1 -1
  45. package/dist/{playground-ELiBuGN0.js → playground-DLN31BPV.js} +6 -6
  46. package/dist/{playground-ELiBuGN0.js.map → playground-DLN31BPV.js.map} +1 -1
  47. package/dist/{posthog-DISFn-54.js → posthog-Dxr8XK4x.js} +2 -2
  48. package/dist/{posthog-DISFn-54.js.map → posthog-Dxr8XK4x.js.map} +1 -1
  49. package/dist/{posthog-integration-BGk6dYzS.js → posthog-integration-MDfRO911.js} +15 -15
  50. package/dist/posthog-integration-MDfRO911.js.map +1 -0
  51. package/dist/{provisioning-DoKcXygK.js → provisioning-Di5GNV9k.js} +3 -3
  52. package/dist/{provisioning-DoKcXygK.js.map → provisioning-Di5GNV9k.js.map} +1 -1
  53. package/dist/{queue-tools-B75RxrcC.js → queue-tools-KosDptd6.js} +3 -3
  54. package/dist/{queue-tools-B75RxrcC.js.map → queue-tools-KosDptd6.js.map} +1 -1
  55. package/dist/{registry-DbwlUbvA.js → registry-BBdaIFWq.js} +5 -5
  56. package/dist/{registry-DbwlUbvA.js.map → registry-BBdaIFWq.js.map} +1 -1
  57. package/dist/{security-lqzh7NaZ.js → security-BwOvjMaq.js} +5 -5
  58. package/dist/{security-lqzh7NaZ.js.map → security-BwOvjMaq.js.map} +1 -1
  59. package/dist/{setup-utils-DeIoqwPw.js → setup-utils-Bo3WZt3a.js} +8 -8
  60. package/dist/{setup-utils-DeIoqwPw.js.map → setup-utils-Bo3WZt3a.js.map} +1 -1
  61. package/dist/{start-tui-ebV_ynrs.js → start-tui-B1LrB7k1.js} +48 -18
  62. package/dist/{start-tui-ebV_ynrs.js.map → start-tui-B1LrB7k1.js.map} +1 -1
  63. package/dist/{steps-BB2izees.js → steps-BMrQJpQh.js} +7 -7
  64. package/dist/{steps-BB2izees.js.map → steps-BMrQJpQh.js.map} +1 -1
  65. package/dist/{store-BbDrhStP.js → store-DhNTBWQR.js} +5 -5
  66. package/dist/{store-BbDrhStP.js.map → store-DhNTBWQR.js.map} +1 -1
  67. package/dist/{subagent-oTBoYK3h.js → subagent-q6M-mBHo.js} +2 -2
  68. package/dist/{subagent-oTBoYK3h.js.map → subagent-q6M-mBHo.js.map} +1 -1
  69. package/dist/{task-BPsA2HrW.js → task-CgAOxod7.js} +12 -12
  70. package/dist/{task-BPsA2HrW.js.map → task-CgAOxod7.js.map} +1 -1
  71. package/dist/{task-stream-DffFXskR.js → task-stream-rxR1IsdJ.js} +4 -4
  72. package/dist/{task-stream-DffFXskR.js.map → task-stream-rxR1IsdJ.js.map} +1 -1
  73. package/dist/{tasks-CmyTWgU7.js → tasks-lzvWF__k.js} +2 -2
  74. package/dist/{tasks-CmyTWgU7.js.map → tasks-lzvWF__k.js.map} +1 -1
  75. package/dist/{telemetry-DfZNqwpb.js → telemetry-CickTk_7.js} +3 -3
  76. package/dist/{telemetry-DfZNqwpb.js.map → telemetry-CickTk_7.js.map} +1 -1
  77. package/dist/{terminal-DTJLXrQX.js → terminal-BjUFxn_x.js} +11 -11
  78. package/dist/{terminal-DTJLXrQX.js.map → terminal-BjUFxn_x.js.map} +1 -1
  79. package/dist/{tools-B4s78y8L.js → tools-MKXGXFSk.js} +6 -6
  80. package/dist/{tools-B4s78y8L.js.map → tools-MKXGXFSk.js.map} +1 -1
  81. package/dist/{wizard-abort-CE6vlOGM.js → wizard-abort-CW_C2EXr.js} +1 -1
  82. package/dist/{wizard-abort-XQFt0vkZ.js → wizard-abort-CooWEh9N.js} +3 -3
  83. package/dist/{wizard-abort-XQFt0vkZ.js.map → wizard-abort-CooWEh9N.js.map} +1 -1
  84. package/dist/{yara-hooks-gZxdqlkx.js → yara-hooks-BpngckdZ.js} +4 -4
  85. package/dist/{yara-hooks-gZxdqlkx.js.map → yara-hooks-BpngckdZ.js.map} +1 -1
  86. package/dist/yara-hooks-C-qG6EJt.js +2 -0
  87. package/package.json +1 -1
  88. package/dist/agent-runner-CK9z7-0z.js.map +0 -1
  89. package/dist/analytics-CbkGZjMp.js +0 -2
  90. package/dist/posthog-integration-BGk6dYzS.js.map +0 -1
  91. package/dist/yara-hooks-COTd_ALD.js +0 -2
@@ -1 +1 @@
1
- {"version":3,"file":"registry-DbwlUbvA.js","names":["IGNORE_PATTERNS","EXTRA_IGNORE","SOURCE_PROBE_LIMIT","path","EXTRA_IGNORE","SOURCE_PROBE_LIMIT","path","fs","EXTRA_IGNORE","EXTRA_IGNORE","path","EXTRA_IGNORE","path","EXTRA_IGNORE","SOURCE_PROBE_LIMIT","path","EXTRA_IGNORE","path","EXTRA_IGNORE","SOURCE_PROBE_LIMIT","path","EXTRA_IGNORE","path","EXTRA_IGNORE","SOURCE_PROBE_LIMIT","path","fs","path","fs","path","fs","EXTRA_IGNORE","fs","path","fs","path","path","path","fs","fs","path","path","fs","path","fs","path","fs","path","fs","path","fs","detectPackageManager","fs","path","getPackageManagerName","path","fs","fs","path","fs","path"],"sources":["../src/frameworks/nextjs/utils.ts","../src/frameworks/nextjs/nextjs-wizard-agent.ts","../src/frameworks/nuxt/nuxt-wizard-agent.ts","../src/frameworks/vue/vue-wizard-agent.ts","../src/frameworks/react-router/utils.ts","../src/frameworks/react-router/react-router-wizard-agent.ts","../src/frameworks/tanstack-router/utils.ts","../src/frameworks/tanstack-router/tanstack-router-wizard-agent.ts","../src/frameworks/tanstack-start/utils.ts","../src/frameworks/tanstack-start/tanstack-start-wizard-agent.ts","../src/frameworks/react-native/utils.ts","../src/frameworks/react-native/react-native-wizard-agent.ts","../src/frameworks/angular/utils.ts","../src/frameworks/angular/angular-wizard-agent.ts","../src/frameworks/astro/utils.ts","../src/frameworks/astro/astro-wizard-agent.ts","../src/lib/framework-config.ts","../src/frameworks/django/utils.ts","../src/frameworks/django/django-wizard-agent.ts","../src/frameworks/flask/utils.ts","../src/frameworks/flask/flask-wizard-agent.ts","../src/frameworks/fastapi/utils.ts","../src/frameworks/fastapi/fastapi-wizard-agent.ts","../src/frameworks/laravel/utils.ts","../src/frameworks/laravel/laravel-wizard-agent.ts","../src/frameworks/svelte/svelte-wizard-agent.ts","../src/frameworks/flutter/flutter-wizard-agent.ts","../src/frameworks/swift/utils.ts","../src/frameworks/swift/swift-wizard-agent.ts","../src/frameworks/kmp/kmp-wizard-agent.ts","../src/frameworks/android/utils.ts","../src/frameworks/android/android-wizard-agent.ts","../src/frameworks/rails/utils.ts","../src/frameworks/rails/rails-wizard-agent.ts","../src/frameworks/elixir/elixir-wizard-agent.ts","../src/frameworks/go/go-wizard-agent.ts","../src/frameworks/java/java-wizard-agent.ts","../src/frameworks/rust/rust-wizard-agent.ts","../src/frameworks/python/python-wizard-agent.ts","../src/frameworks/ruby/utils.ts","../src/frameworks/ruby/ruby-wizard-agent.ts","../src/frameworks/javascript-node/javascript-node-wizard-agent.ts","../src/frameworks/javascript-web/utils.ts","../src/frameworks/javascript-web/javascript-web-wizard-agent.ts","../src/lib/registry.ts"],"sourcesContent":["import type { WizardRunOptions } from '@utils/types';\nimport { boundedGlob } from '@utils/bounded-fs';\nimport { createVersionBucket } from '@utils/semver';\n\nexport const getNextJsVersionBucket = createVersionBucket();\n\nexport enum NextJsRouter {\n APP_ROUTER = 'app-router',\n PAGES_ROUTER = 'pages-router',\n}\n\nexport const IGNORE_PATTERNS = ['**/public/**'];\n\n/**\n * Detect Next.js router type. Pure — returns null if ambiguous.\n */\nexport async function getNextJsRouter({\n installDir,\n}: Pick<WizardRunOptions, 'installDir'>): Promise<NextJsRouter | null> {\n const pagesMatches = await boundedGlob('**/pages/_app.@(ts|tsx|js|jsx)', {\n cwd: installDir,\n extraIgnore: IGNORE_PATTERNS,\n limit: 1,\n });\n\n const hasPagesDir = pagesMatches.length > 0;\n\n const appMatches = await boundedGlob('**/app/**/layout.@(ts|tsx|js|jsx)', {\n cwd: installDir,\n extraIgnore: IGNORE_PATTERNS,\n limit: 1,\n });\n\n const hasAppDir = appMatches.length > 0;\n\n if (hasPagesDir && !hasAppDir) {\n return NextJsRouter.PAGES_ROUTER;\n }\n\n if (hasAppDir && !hasPagesDir) {\n return NextJsRouter.APP_ROUTER;\n }\n\n // Ambiguous (both or neither) — return null, SetupScreen handles it\n return null;\n}\n\nexport const getNextJsRouterName = (router: NextJsRouter) => {\n return router === NextJsRouter.APP_ROUTER ? 'app router' : 'pages router';\n};\n","/* Simplified Next.js wizard using posthog-agent with PostHog MCP */\nimport type { WizardRunOptions } from '@utils/types';\nimport type { FrameworkConfig } from '@lib/framework-config';\nimport { detectNodePackageManagers } from '@lib/detection/package-manager';\nimport { Integration } from '@lib/constants';\nimport {\n getDeclaredVersion,\n getInstalledPackageVersion,\n hasDeclaredDependency,\n type PackageJson,\n} from '@utils/package-json';\nimport { tryGetPackageJson } from '@utils/setup-utils';\nimport { getUI } from '@ui';\nimport {\n getNextJsRouter,\n getNextJsVersionBucket,\n getNextJsRouterName,\n NextJsRouter,\n} from './utils';\n\ntype NextjsContext = {\n router?: NextJsRouter;\n};\n\nexport const NEXTJS_AGENT_CONFIG: FrameworkConfig<NextjsContext> = {\n metadata: {\n name: 'Next.js',\n integration: Integration.nextjs,\n docsUrl: 'https://posthog.com/docs/libraries/next-js',\n unsupportedVersionDocsUrl: 'https://posthog.com/docs/libraries/next-js',\n gatherContext: async (options: WizardRunOptions) => {\n const router = await getNextJsRouter(options);\n if (router) {\n const emoji =\n router === NextJsRouter.APP_ROUTER ? '\\u{1F4F1}' : '\\u{1F4C3}';\n getUI().setDetectedFramework(\n `Next.js ${getNextJsRouterName(router)} ${emoji}`,\n );\n return { router };\n }\n return {};\n },\n setup: {\n questions: [\n {\n key: 'router',\n message: 'Which Next.js router are you using?',\n options: [\n { label: 'App Router', value: NextJsRouter.APP_ROUTER },\n { label: 'Pages Router', value: NextJsRouter.PAGES_ROUTER },\n ],\n detect: async (opts) => {\n const result = await getNextJsRouter(opts);\n return result;\n },\n },\n ],\n },\n },\n\n detection: {\n packageName: 'next',\n packageDisplayName: 'Next.js',\n getVersion: (packageJson: unknown) =>\n getDeclaredVersion('next', packageJson as PackageJson),\n getVersionBucket: getNextJsVersionBucket,\n minimumVersion: '15.3.0',\n getInstalledVersion: (options: WizardRunOptions) =>\n Promise.resolve(getInstalledPackageVersion('next', options.installDir)),\n detect: async (options) => {\n const packageJson = await tryGetPackageJson(options);\n return packageJson ? hasDeclaredDependency('next', packageJson) : false;\n },\n detectPackageManager: detectNodePackageManagers,\n },\n\n environment: {\n uploadToHosting: true,\n getEnvVars: (apiKey: string, host: string) => ({\n NEXT_PUBLIC_POSTHOG_PROJECT_TOKEN: apiKey,\n NEXT_PUBLIC_POSTHOG_HOST: host,\n }),\n },\n\n analytics: {\n getTags: (context) => ({\n router: context.router === NextJsRouter.APP_ROUTER ? 'app' : 'pages',\n }),\n },\n\n prompts: {\n projectTypeDetection:\n 'This is a JavaScript/TypeScript project. Look for package.json and lockfiles (package-lock.json, yarn.lock, pnpm-lock.yaml, bun.lockb) to confirm.',\n getAdditionalContextLines: (context) => {\n const routerType =\n context.router === NextJsRouter.APP_ROUTER ? 'app' : 'pages';\n return [`Router: ${routerType}`];\n },\n },\n\n ui: {\n successMessage: 'PostHog integration complete',\n estimatedDurationMinutes: 8,\n getOutroChanges: (context) => {\n const router = context.router ?? NextJsRouter.APP_ROUTER;\n const routerName = getNextJsRouterName(router);\n return [\n `Analyzed your Next.js project structure (${routerName})`,\n `Created and configured PostHog initializers`,\n `Integrated PostHog into your application`,\n ];\n },\n getOutroNextSteps: () => {\n return [\n 'Start your development server to see PostHog in action',\n 'Visit your PostHog dashboard to see incoming events',\n ];\n },\n },\n};\n","/* Nuxt wizard using posthog-agent with PostHog MCP */\nimport type { WizardRunOptions } from '@utils/types';\nimport type { FrameworkConfig } from '@lib/framework-config';\nimport { detectNodePackageManagers } from '@lib/detection/package-manager';\nimport { Integration } from '@lib/constants';\nimport {\n getDeclaredVersion,\n getInstalledPackageVersion,\n hasDeclaredDependency,\n type PackageJson,\n} from '@utils/package-json';\nimport { tryGetPackageJson } from '@utils/setup-utils';\nimport { createVersionBucket } from '@utils/semver';\n\nconst getNuxtVersionBucket = createVersionBucket();\n\ntype NuxtContext = {\n versionBucket?: string;\n};\n\nexport const NUXT_AGENT_CONFIG: FrameworkConfig<NuxtContext> = {\n metadata: {\n name: 'Nuxt',\n integration: Integration.nuxt,\n docsUrl: 'https://posthog.com/docs/libraries/nuxt',\n gatherContext: async (options: WizardRunOptions) => {\n const packageJson = await tryGetPackageJson(options);\n if (!packageJson) return {};\n const version = getDeclaredVersion('nuxt', packageJson);\n const versionBucket = getNuxtVersionBucket(version);\n return { versionBucket };\n },\n },\n\n detection: {\n packageName: 'nuxt',\n packageDisplayName: 'Nuxt',\n getVersion: (packageJson: unknown) =>\n getDeclaredVersion('nuxt', packageJson as PackageJson),\n getVersionBucket: getNuxtVersionBucket,\n getInstalledVersion: (options: WizardRunOptions) =>\n Promise.resolve(getInstalledPackageVersion('nuxt', options.installDir)),\n detect: async (options) => {\n const packageJson = await tryGetPackageJson(options);\n return packageJson ? hasDeclaredDependency('nuxt', packageJson) : false;\n },\n detectPackageManager: detectNodePackageManagers,\n },\n\n environment: {\n uploadToHosting: true,\n getEnvVars: (apiKey: string, host: string) => ({\n NUXT_PUBLIC_POSTHOG_PROJECT_TOKEN: apiKey,\n NUXT_PUBLIC_POSTHOG_HOST: host,\n }),\n },\n\n analytics: {\n getTags: (context) => ({\n ...(context.versionBucket\n ? { versionBucket: context.versionBucket }\n : {}),\n }),\n },\n\n prompts: {\n projectTypeDetection:\n 'This is a JavaScript/TypeScript project. Look for package.json and lockfiles (package-lock.json, yarn.lock, pnpm-lock.yaml, bun.lockb) to confirm.',\n getAdditionalContextLines: (context) => {\n const lines: string[] = [];\n if (context.versionBucket) {\n lines.push(`Nuxt version: ${context.versionBucket}`);\n }\n const frameworkId = 'nuxt';\n lines.push(\n `Framework docs ID: ${frameworkId} (use posthog://docs/frameworks/${frameworkId} for documentation)`,\n );\n return lines;\n },\n },\n\n ui: {\n successMessage: 'PostHog integration complete',\n estimatedDurationMinutes: 5,\n getOutroChanges: () => [\n 'Analyzed your Nuxt project structure',\n 'Configured PostHog module/plugin',\n 'Integrated PostHog into your application',\n ],\n getOutroNextSteps: () => [\n 'Start your development server to see PostHog in action',\n 'Visit your PostHog dashboard to see incoming events',\n ],\n },\n};\n","/* Vue wizard using posthog-agent with PostHog MCP */\nimport type { FrameworkConfig } from '@lib/framework-config';\nimport { detectNodePackageManagers } from '@lib/detection/package-manager';\nimport { Integration } from '@lib/constants';\nimport {\n getDeclaredVersion,\n getInstalledPackageVersion,\n hasDeclaredDependency,\n type PackageJson,\n} from '@utils/package-json';\nimport { tryGetPackageJson } from '@utils/setup-utils';\nimport { createVersionBucket } from '@utils/semver';\n\nconst getVueVersionBucket = createVersionBucket();\n\ntype VueContext = Record<string, unknown>;\n\nexport const VUE_AGENT_CONFIG: FrameworkConfig<VueContext> = {\n metadata: {\n name: 'Vue',\n integration: Integration.vue,\n docsUrl: 'https://posthog.com/docs/libraries/vue',\n },\n\n detection: {\n packageName: 'vue',\n packageDisplayName: 'Vue',\n getVersion: (packageJson: unknown) =>\n getDeclaredVersion('vue', packageJson as PackageJson),\n getVersionBucket: getVueVersionBucket,\n getInstalledVersion: (options) =>\n Promise.resolve(getInstalledPackageVersion('vue', options.installDir)),\n detect: async (options) => {\n const packageJson = await tryGetPackageJson(options);\n return packageJson ? hasDeclaredDependency('vue', packageJson) : false;\n },\n detectPackageManager: detectNodePackageManagers,\n },\n\n environment: {\n uploadToHosting: true,\n getEnvVars: (apiKey: string, host: string) => ({\n VITE_POSTHOG_PROJECT_TOKEN: apiKey,\n VITE_POSTHOG_HOST: host,\n }),\n },\n\n analytics: {\n getTags: () => ({}),\n },\n\n prompts: {\n projectTypeDetection:\n 'This is a JavaScript/TypeScript project. Look for package.json and lockfiles (package-lock.json, yarn.lock, pnpm-lock.yaml, bun.lockb) to confirm.',\n getAdditionalContextLines: () => {\n const frameworkId = 'vue';\n return [\n `Framework docs ID: ${frameworkId} (use posthog://docs/frameworks/${frameworkId} for documentation)`,\n ];\n },\n },\n\n ui: {\n successMessage: 'PostHog integration complete',\n estimatedDurationMinutes: 5,\n getOutroChanges: () => [\n 'Analyzed your Vue project structure',\n 'Created and configured PostHog initializers',\n 'Integrated PostHog into your application',\n ],\n getOutroNextSteps: () => [\n 'Start your development server to see PostHog in action',\n 'Visit your PostHog dashboard to see incoming events',\n ],\n },\n};\n","import { major } from 'semver';\nimport { tryGetPackageJson } from '@utils/setup-utils';\nimport type { WizardRunOptions } from '@utils/types';\nimport { boundedGlob, readProjectFile } from '@utils/bounded-fs';\nimport { getDeclaredVersion } from '@utils/package-json';\nimport { createVersionBucket } from '@utils/semver';\nimport * as path from 'node:path';\nimport * as semver from 'semver';\n\nexport enum ReactRouterMode {\n V6 = 'v6',\n V7_FRAMEWORK = 'v7-framework',\n V7_DATA = 'v7-data',\n V7_DECLARATIVE = 'v7-declarative',\n}\n\nconst EXTRA_IGNORE = ['**/public/**'];\n\nexport const getReactRouterVersionBucket = createVersionBucket();\n\n/** Content probes read at most this many files, one in memory at a time. */\nconst SOURCE_PROBE_LIMIT = 200;\n\n/** Files that set up a React Router — never a blanket source sweep. */\nconst ROUTER_FILE_GLOBS = [\n '**/routes/**/*.@(ts|tsx|js|jsx)',\n '**/*[Rr]out*.@(ts|tsx|js|jsx)',\n '**/@(main|app|App|index|root).@(ts|tsx|js|jsx)',\n];\n\nasync function hasReactRouterConfig({\n installDir,\n}: Pick<WizardRunOptions, 'installDir'>): Promise<boolean> {\n const configMatches = await boundedGlob(\n '**/react-router.config.@(ts|js|tsx|jsx)',\n {\n cwd: installDir,\n extraIgnore: EXTRA_IGNORE,\n limit: 1,\n },\n );\n return configMatches.length > 0;\n}\n\nasync function hasCreateBrowserRouter({\n installDir,\n}: Pick<WizardRunOptions, 'installDir'>): Promise<boolean> {\n const sourceFiles = await boundedGlob(ROUTER_FILE_GLOBS, {\n cwd: installDir,\n extraIgnore: EXTRA_IGNORE,\n limit: SOURCE_PROBE_LIMIT,\n });\n\n for (const file of sourceFiles) {\n const content = readProjectFile(path.join(installDir, file));\n if (content?.includes('createBrowserRouter')) {\n return true;\n }\n }\n\n return false;\n}\n\nasync function hasDeclarativeRouter({\n installDir,\n}: Pick<WizardRunOptions, 'installDir'>): Promise<boolean> {\n const sourceFiles = await boundedGlob(ROUTER_FILE_GLOBS, {\n cwd: installDir,\n extraIgnore: EXTRA_IGNORE,\n limit: SOURCE_PROBE_LIMIT,\n });\n\n for (const file of sourceFiles) {\n const content = readProjectFile(path.join(installDir, file));\n if (!content) continue;\n if (\n content.includes('<BrowserRouter') ||\n (content.includes('BrowserRouter') &&\n (content.includes('from \"react-router-dom\"') ||\n content.includes(\"from 'react-router-dom'\")))\n ) {\n return true;\n }\n }\n\n return false;\n}\n\n/**\n * Detect React Router mode. Pure — returns null if ambiguous.\n */\nexport async function getReactRouterMode(\n options: WizardRunOptions,\n): Promise<ReactRouterMode | null> {\n const { installDir } = options;\n\n const packageJson = await tryGetPackageJson(options);\n if (!packageJson) return null;\n\n const reactRouterVersion =\n getDeclaredVersion('react-router-dom', packageJson) ||\n getDeclaredVersion('react-router', packageJson);\n\n if (!reactRouterVersion) {\n return null;\n }\n\n const coercedVersion = semver.coerce(reactRouterVersion);\n const majorVersion = coercedVersion ? major(coercedVersion) : null;\n\n if (majorVersion === 6) {\n return ReactRouterMode.V6;\n }\n\n if (majorVersion === 7) {\n const hasConfig = await hasReactRouterConfig({ installDir });\n if (hasConfig) return ReactRouterMode.V7_FRAMEWORK;\n\n const hasDataMode = await hasCreateBrowserRouter({ installDir });\n if (hasDataMode) return ReactRouterMode.V7_DATA;\n\n const hasDeclarative = await hasDeclarativeRouter({ installDir });\n if (hasDeclarative) return ReactRouterMode.V7_DECLARATIVE;\n\n // v7 but can't detect mode\n return null;\n }\n\n return null;\n}\n\nexport function getReactRouterModeName(mode: ReactRouterMode): string {\n switch (mode) {\n case ReactRouterMode.V6:\n return 'v6';\n case ReactRouterMode.V7_FRAMEWORK:\n return 'v7 Framework mode';\n case ReactRouterMode.V7_DATA:\n return 'v7 Data mode';\n case ReactRouterMode.V7_DECLARATIVE:\n return 'v7 Declarative mode';\n }\n}\n","/* React Router wizard using posthog-agent with PostHog MCP */\nimport type { WizardRunOptions } from '@utils/types';\nimport type { FrameworkConfig } from '@lib/framework-config';\nimport { detectNodePackageManagers } from '@lib/detection/package-manager';\nimport { Integration } from '@lib/constants';\nimport {\n getDeclaredVersion,\n getInstalledPackageVersion,\n hasDeclaredDependency,\n type PackageJson,\n} from '@utils/package-json';\nimport { tryGetPackageJson } from '@utils/setup-utils';\nimport { getUI } from '@ui';\nimport {\n getReactRouterMode,\n getReactRouterModeName,\n getReactRouterVersionBucket,\n ReactRouterMode,\n} from './utils';\n\ntype ReactRouterContext = {\n routerMode?: ReactRouterMode;\n};\n\nexport const REACT_ROUTER_AGENT_CONFIG: FrameworkConfig<ReactRouterContext> = {\n metadata: {\n name: 'React Router',\n integration: Integration.reactRouter,\n docsUrl: 'https://posthog.com/docs/libraries/react',\n unsupportedVersionDocsUrl: 'https://posthog.com/docs/libraries/react',\n gatherContext: async (options: WizardRunOptions) => {\n const routerMode = await getReactRouterMode(options);\n if (routerMode) {\n getUI().setDetectedFramework(\n `React Router ${getReactRouterModeName(routerMode)}`,\n );\n return { routerMode };\n }\n return {};\n },\n },\n\n detection: {\n packageName: 'react-router',\n packageDisplayName: 'React Router',\n getVersion: (packageJson: unknown) =>\n getDeclaredVersion('react-router', packageJson as PackageJson),\n getVersionBucket: getReactRouterVersionBucket,\n minimumVersion: '6.0.0',\n getInstalledVersion: (options: WizardRunOptions) =>\n Promise.resolve(\n getInstalledPackageVersion('react-router', options.installDir),\n ),\n detect: async (options) => {\n const packageJson = await tryGetPackageJson(options);\n return packageJson\n ? hasDeclaredDependency('react-router', packageJson)\n : false;\n },\n detectPackageManager: detectNodePackageManagers,\n },\n\n environment: {\n uploadToHosting: false,\n getEnvVars: (apiKey: string, host: string) => ({\n REACT_APP_POSTHOG_PROJECT_TOKEN: apiKey,\n REACT_APP_POSTHOG_HOST: host,\n }),\n },\n\n analytics: {\n getTags: (context) => ({\n routerMode: context.routerMode || 'unknown',\n }),\n },\n\n prompts: {\n projectTypeDetection:\n 'This is a JavaScript/TypeScript project. Look for package.json and lockfiles (package-lock.json, yarn.lock, pnpm-lock.yaml, bun.lockb) to confirm.',\n getAdditionalContextLines: (context) => {\n const routerMode = context.routerMode;\n const modeName = routerMode\n ? getReactRouterModeName(routerMode)\n : 'unknown';\n\n // Map router mode to framework ID for MCP docs resource\n const frameworkIdMap: Record<ReactRouterMode, string> = {\n [ReactRouterMode.V6]: 'react-react-router-6',\n [ReactRouterMode.V7_FRAMEWORK]: 'react-react-router-7-framework',\n [ReactRouterMode.V7_DATA]: 'react-react-router-7-data',\n [ReactRouterMode.V7_DECLARATIVE]: 'react-react-router-7-declarative',\n };\n\n const frameworkId = routerMode\n ? frameworkIdMap[routerMode]\n : ReactRouterMode.V7_FRAMEWORK;\n\n return [\n `Router mode: ${modeName}`,\n `Framework docs ID: ${frameworkId} (use posthog://docs/frameworks/${frameworkId} for documentation)`,\n ];\n },\n },\n\n ui: {\n successMessage: 'PostHog integration complete',\n estimatedDurationMinutes: 8,\n getOutroChanges: (context) => {\n const modeName = context.routerMode\n ? getReactRouterModeName(context.routerMode)\n : 'React Router';\n return [\n `Analyzed your React Router project structure (${modeName})`,\n `Created and configured PostHog initializers`,\n `Integrated PostHog into your application`,\n ];\n },\n getOutroNextSteps: () => [\n 'Start your development server to see PostHog in action',\n 'Visit your PostHog dashboard to see incoming events',\n ],\n },\n};\n","import type { WizardRunOptions } from '@utils/types';\nimport { boundedGlob, readProjectFile } from '@utils/bounded-fs';\nimport { hasDeclaredDependency } from '@utils/package-json';\nimport { createVersionBucket } from '@utils/semver';\nimport * as fs from 'node:fs';\nimport * as path from 'node:path';\n\nexport enum TanStackRouterMode {\n FILE_BASED = 'file-based',\n CODE_BASED = 'code-based',\n}\n\nconst EXTRA_IGNORE = ['**/public/**', '**/.vinxi/**', '**/.output/**'];\n\nexport const getTanStackRouterVersionBucket = createVersionBucket();\n\n/** Content probes read at most this many files, one in memory at a time. */\nconst SOURCE_PROBE_LIMIT = 200;\n\n/** Files that define TanStack routes — never a blanket source sweep. */\nconst ROUTE_FILE_GLOBS = [\n '**/routes/**/*.@(ts|tsx|js|jsx)',\n '**/*[Rr]oute*.@(ts|tsx|js|jsx)',\n '**/@(main|router|app|App|index).@(ts|tsx|js|jsx)',\n];\n\nasync function hasFileBasedRouting({\n installDir,\n}: Pick<WizardRunOptions, 'installDir'>): Promise<boolean> {\n const generatedFiles = await boundedGlob(\n '**/routeTree.gen.@(ts|tsx|js|jsx)',\n {\n cwd: installDir,\n extraIgnore: EXTRA_IGNORE,\n limit: 1,\n },\n );\n\n if (generatedFiles.length > 0) {\n return true;\n }\n\n try {\n const packageJsonPath = path.join(installDir, 'package.json');\n const content = fs.readFileSync(packageJsonPath, 'utf-8');\n const packageJson = JSON.parse(content) as Record<string, unknown>;\n\n if (\n hasDeclaredDependency('@tanstack/router-plugin', packageJson) ||\n hasDeclaredDependency('@tanstack/router-vite-plugin', packageJson)\n ) {\n return true;\n }\n } catch {\n // package.json not found or unreadable\n }\n\n const sourceFiles = await boundedGlob(ROUTE_FILE_GLOBS, {\n cwd: installDir,\n extraIgnore: EXTRA_IGNORE,\n limit: SOURCE_PROBE_LIMIT,\n });\n\n for (const file of sourceFiles) {\n const content = readProjectFile(path.join(installDir, file));\n if (content?.includes('createFileRoute')) {\n return true;\n }\n }\n\n return false;\n}\n\nasync function hasCodeBasedRouting({\n installDir,\n}: Pick<WizardRunOptions, 'installDir'>): Promise<boolean> {\n const sourceFiles = await boundedGlob(ROUTE_FILE_GLOBS, {\n cwd: installDir,\n extraIgnore: EXTRA_IGNORE,\n limit: SOURCE_PROBE_LIMIT,\n });\n\n let hasCreateRoute = false;\n let hasCreateFileRoute = false;\n\n for (const file of sourceFiles) {\n const content = readProjectFile(path.join(installDir, file));\n if (!content) continue;\n\n if (content.includes('createRoute(')) {\n hasCreateRoute = true;\n }\n if (content.includes('createFileRoute')) {\n hasCreateFileRoute = true;\n }\n }\n\n return hasCreateRoute && !hasCreateFileRoute;\n}\n\n/**\n * Detect TanStack Router mode. Pure — returns null if ambiguous.\n */\nexport async function getTanStackRouterMode(\n options: WizardRunOptions,\n): Promise<TanStackRouterMode | null> {\n const { installDir } = options;\n\n const isFileBased = await hasFileBasedRouting({ installDir });\n if (isFileBased) {\n return TanStackRouterMode.FILE_BASED;\n }\n\n const isCodeBased = await hasCodeBasedRouting({ installDir });\n if (isCodeBased) {\n return TanStackRouterMode.CODE_BASED;\n }\n\n return null;\n}\n\nexport function getTanStackRouterModeName(mode: TanStackRouterMode): string {\n switch (mode) {\n case TanStackRouterMode.FILE_BASED:\n return 'File-based routing';\n case TanStackRouterMode.CODE_BASED:\n return 'Code-based routing';\n }\n}\n","/* TanStack Router wizard using posthog-agent with PostHog MCP */\nimport type { WizardRunOptions } from '@utils/types';\nimport type { FrameworkConfig } from '@lib/framework-config';\nimport { detectNodePackageManagers } from '@lib/detection/package-manager';\nimport { Integration } from '@lib/constants';\nimport {\n getDeclaredVersion,\n getInstalledPackageVersion,\n hasDeclaredDependency,\n type PackageJson,\n} from '@utils/package-json';\nimport { tryGetPackageJson } from '@utils/setup-utils';\nimport { getUI } from '@ui';\nimport {\n getTanStackRouterMode,\n getTanStackRouterModeName,\n getTanStackRouterVersionBucket,\n TanStackRouterMode,\n} from './utils';\n\ntype TanStackRouterContext = {\n routerMode?: TanStackRouterMode;\n};\n\nexport const TANSTACK_ROUTER_AGENT_CONFIG: FrameworkConfig<TanStackRouterContext> =\n {\n metadata: {\n name: 'React (TanStack Router)',\n integration: Integration.tanstackRouter,\n docsUrl: 'https://posthog.com/docs/libraries/react',\n gatherContext: async (options: WizardRunOptions) => {\n const routerMode = await getTanStackRouterMode(options);\n if (routerMode) {\n getUI().setDetectedFramework(\n `TanStack Router ${getTanStackRouterModeName(routerMode)}`,\n );\n return { routerMode };\n }\n return {};\n },\n },\n\n detection: {\n packageName: '@tanstack/react-router',\n packageDisplayName: 'TanStack Router',\n getVersion: (packageJson: unknown) =>\n getDeclaredVersion(\n '@tanstack/react-router',\n packageJson as PackageJson,\n ),\n getVersionBucket: getTanStackRouterVersionBucket,\n minimumVersion: '1.0.0',\n getInstalledVersion: (options: WizardRunOptions) =>\n Promise.resolve(\n getInstalledPackageVersion(\n '@tanstack/react-router',\n options.installDir,\n ),\n ),\n detect: async (options) => {\n const packageJson = await tryGetPackageJson(options);\n if (!packageJson) {\n return false;\n }\n // Exclude TanStack Start projects (they have their own integration)\n if (hasDeclaredDependency('@tanstack/react-start', packageJson)) {\n return false;\n }\n return hasDeclaredDependency('@tanstack/react-router', packageJson);\n },\n detectPackageManager: detectNodePackageManagers,\n },\n\n environment: {\n uploadToHosting: false,\n getEnvVars: (apiKey: string, host: string) => ({\n VITE_PUBLIC_POSTHOG_PROJECT_TOKEN: apiKey,\n VITE_PUBLIC_POSTHOG_HOST: host,\n }),\n },\n\n analytics: {\n getTags: (context) => ({\n routerMode: context.routerMode || 'unknown',\n }),\n },\n\n prompts: {\n projectTypeDetection:\n 'This is a JavaScript/TypeScript project. Look for package.json and lockfiles (package-lock.json, yarn.lock, pnpm-lock.yaml, bun.lockb) to confirm.',\n getAdditionalContextLines: (context) => {\n const routerMode = context.routerMode;\n const modeName = routerMode\n ? getTanStackRouterModeName(routerMode)\n : 'unknown';\n\n // Map router mode to framework ID for MCP docs resource\n const frameworkIdMap: Record<TanStackRouterMode, string> = {\n [TanStackRouterMode.FILE_BASED]: 'react-tanstack-router-file-based',\n [TanStackRouterMode.CODE_BASED]: 'react-tanstack-router-code-based',\n };\n\n const frameworkId = routerMode\n ? frameworkIdMap[routerMode]\n : 'react-tanstack-router-file-based';\n\n return [\n `Router mode: ${modeName}`,\n `Framework docs ID: ${frameworkId} (use posthog://docs/frameworks/${frameworkId} for documentation)`,\n ];\n },\n },\n\n ui: {\n successMessage: 'PostHog integration complete',\n estimatedDurationMinutes: 8,\n getOutroChanges: (context) => {\n const modeName = context.routerMode\n ? getTanStackRouterModeName(context.routerMode)\n : 'TanStack Router';\n return [\n `Analyzed your React (TanStack Router) project structure (${modeName})`,\n `Created and configured PostHog initializers`,\n `Integrated PostHog into your application`,\n ];\n },\n getOutroNextSteps: () => [\n 'Start your development server to see PostHog in action',\n 'Visit your PostHog dashboard to see incoming events',\n ],\n },\n };\n","import { createVersionBucket } from '@utils/semver';\n\n/**\n * Get TanStack Start version bucket for analytics\n */\nexport const getTanStackStartVersionBucket = createVersionBucket();\n","/* TanStack Start wizard using posthog-agent with PostHog MCP */\nimport type { WizardRunOptions } from '@utils/types';\nimport type { FrameworkConfig } from '@lib/framework-config';\nimport { detectNodePackageManagers } from '@lib/detection/package-manager';\nimport { Integration } from '@lib/constants';\nimport {\n getDeclaredVersion,\n getInstalledPackageVersion,\n hasDeclaredDependency,\n type PackageJson,\n} from '@utils/package-json';\nimport { tryGetPackageJson } from '@utils/setup-utils';\nimport { getTanStackStartVersionBucket } from './utils';\n\ntype TanStackStartContext = Record<string, unknown>;\n\nexport const TANSTACK_START_AGENT_CONFIG: FrameworkConfig<TanStackStartContext> =\n {\n metadata: {\n name: 'TanStack Start',\n integration: Integration.tanstackStart,\n docsUrl: 'https://posthog.com/docs/libraries/react',\n },\n\n detection: {\n packageName: '@tanstack/react-start',\n packageDisplayName: 'TanStack Start',\n getVersion: (packageJson: unknown) =>\n getDeclaredVersion('@tanstack/react-start', packageJson as PackageJson),\n getVersionBucket: getTanStackStartVersionBucket,\n minimumVersion: '1.0.0',\n getInstalledVersion: (options: WizardRunOptions) =>\n Promise.resolve(\n getInstalledPackageVersion(\n '@tanstack/react-start',\n options.installDir,\n ),\n ),\n detect: async (options) => {\n const packageJson = await tryGetPackageJson(options);\n return packageJson\n ? hasDeclaredDependency('@tanstack/react-start', packageJson)\n : false;\n },\n detectPackageManager: detectNodePackageManagers,\n },\n\n environment: {\n uploadToHosting: false,\n getEnvVars: (apiKey: string, host: string) => ({\n VITE_PUBLIC_POSTHOG_PROJECT_TOKEN: apiKey,\n VITE_PUBLIC_POSTHOG_HOST: host,\n }),\n },\n\n analytics: {\n getTags: () => ({}),\n },\n\n prompts: {\n projectTypeDetection:\n 'This is a JavaScript/TypeScript project. Look for package.json and lockfiles (package-lock.json, yarn.lock, pnpm-lock.yaml, bun.lockb) to confirm.',\n getAdditionalContextLines: () => {\n // TanStack Start always uses file-based routing (it's a full-stack framework built on TanStack Router)\n const frameworkId = 'react-tanstack-start';\n\n return [\n `Framework docs ID: ${frameworkId} (use posthog://docs/frameworks/${frameworkId} for documentation)`,\n ];\n },\n },\n\n ui: {\n successMessage: 'PostHog integration complete',\n estimatedDurationMinutes: 8,\n getOutroChanges: () => [\n `Analyzed your TanStack Start project structure`,\n `Created and configured PostHog initializers`,\n `Integrated PostHog into your application`,\n ],\n getOutroNextSteps: () => [\n 'Start your development server to see PostHog in action',\n 'Visit your PostHog dashboard to see incoming events',\n ],\n },\n };\n","import { createVersionBucket } from '@utils/semver';\nimport { tryGetPackageJson } from '@utils/setup-utils';\nimport { hasDeclaredDependency } from '@utils/package-json';\nimport { getUI } from '@ui';\nimport type { WizardRunOptions } from '@utils/types';\n\nexport const getReactNativeVersionBucket = createVersionBucket();\n\nexport enum ReactNativeVariant {\n EXPO = 'expo',\n REACT_NATIVE = 'react-native',\n}\n\nexport function getReactNativeVariantName(variant: ReactNativeVariant): string {\n return variant === ReactNativeVariant.EXPO ? 'Expo' : 'React Native';\n}\n\nexport async function detectReactNativeVariant(\n options: Pick<WizardRunOptions, 'installDir'>,\n): Promise<ReactNativeVariant> {\n const packageJson = await tryGetPackageJson(options);\n\n if (packageJson && hasDeclaredDependency('expo', packageJson)) {\n getUI().setDetectedFramework(\n `${getReactNativeVariantName(ReactNativeVariant.EXPO)} 📱`,\n );\n return ReactNativeVariant.EXPO;\n }\n\n getUI().setDetectedFramework(\n `${getReactNativeVariantName(ReactNativeVariant.REACT_NATIVE)} 📱`,\n );\n return ReactNativeVariant.REACT_NATIVE;\n}\n","/* React Native wizard using posthog-agent with PostHog MCP */\nimport type { WizardRunOptions } from '@utils/types';\nimport type { FrameworkConfig } from '@lib/framework-config';\nimport { detectNodePackageManagers } from '@lib/detection/package-manager';\nimport { Integration } from '@lib/constants';\nimport {\n getDeclaredVersion,\n getInstalledPackageVersion,\n hasDeclaredDependency,\n type PackageJson,\n} from '@utils/package-json';\nimport { tryGetPackageJson } from '@utils/setup-utils';\nimport {\n detectReactNativeVariant,\n getReactNativeVariantName,\n getReactNativeVersionBucket,\n ReactNativeVariant,\n} from './utils';\n\ntype ReactNativeContext = {\n variant?: ReactNativeVariant;\n};\n\nexport const REACT_NATIVE_AGENT_CONFIG: FrameworkConfig<ReactNativeContext> = {\n metadata: {\n name: 'React Native',\n integration: Integration.reactNative,\n docsUrl: 'https://posthog.com/docs/libraries/react-native',\n gatherContext: async (options: WizardRunOptions) => {\n const variant = await detectReactNativeVariant(options);\n return { variant };\n },\n },\n\n detection: {\n packageName: 'react-native',\n packageDisplayName: 'React Native',\n getVersion: (packageJson: unknown) =>\n getDeclaredVersion('react-native', packageJson as PackageJson),\n getVersionBucket: getReactNativeVersionBucket,\n minimumVersion: '0.73.0',\n getInstalledVersion: (options: WizardRunOptions) =>\n Promise.resolve(\n getInstalledPackageVersion('react-native', options.installDir),\n ),\n detect: async (options) => {\n const packageJson = await tryGetPackageJson(options);\n return packageJson\n ? hasDeclaredDependency('react-native', packageJson)\n : false;\n },\n detectPackageManager: detectNodePackageManagers,\n },\n\n environment: {\n uploadToHosting: false,\n getEnvVars: (apiKey: string, host: string) => ({\n POSTHOG_PROJECT_TOKEN: apiKey,\n POSTHOG_HOST: host,\n }),\n },\n\n analytics: {\n getTags: (context) => ({\n variant:\n context.variant === ReactNativeVariant.EXPO ? 'expo' : 'react-native',\n }),\n },\n\n prompts: {\n projectTypeDetection:\n 'This is a React Native project. Look for package.json, android/ and ios/ directories, and lockfiles to confirm. Check for expo in package.json to determine the variant.',\n getAdditionalContextLines: (context) => {\n const isExpo = context.variant === ReactNativeVariant.EXPO;\n const frameworkId = 'react-native';\n\n const lines = [\n `Framework docs ID: ${frameworkId} (use posthog://docs/frameworks/${frameworkId} for documentation)`,\n `Variant: ${isExpo ? 'Expo' : 'React Native'}`,\n ];\n\n if (isExpo) {\n lines.push(\n 'Use `npx expo install` for package installation.',\n 'Use EXPO_PUBLIC_ prefix for environment variables exposed to the client.',\n );\n } else {\n lines.push(\n 'This is a React Native project without Expo. Native linking may be required.',\n 'For iOS, ensure pods are installed after adding PostHog.',\n );\n }\n\n return lines;\n },\n },\n\n ui: {\n successMessage: 'PostHog integration complete',\n estimatedDurationMinutes: 10,\n getOutroChanges: (context) => {\n const variant = context.variant ?? ReactNativeVariant.REACT_NATIVE;\n const variantName = getReactNativeVariantName(variant);\n return [\n `Analyzed your React Native project structure (${variantName})`,\n `Installed and configured the PostHog React Native SDK`,\n `Integrated PostHog into your application`,\n ];\n },\n getOutroNextSteps: (context) => {\n const isExpo = context.variant === ReactNativeVariant.EXPO;\n const steps = [];\n\n if (!isExpo) {\n steps.push('Run `npx pod-install` to install iOS dependencies');\n }\n\n steps.push(\n isExpo\n ? 'Start your development server with `npx expo start` to see PostHog in action'\n : 'Start your development server to see PostHog in action',\n 'Visit your PostHog dashboard to see incoming events',\n );\n\n return steps;\n },\n },\n};\n","import { createVersionBucket } from '@utils/semver';\n\n/**\n * Get Angular version bucket for analytics\n */\nexport const getAngularVersionBucket = createVersionBucket();\n","/* Angular wizard using posthog-agent with PostHog MCP */\nimport type { WizardRunOptions } from '@utils/types';\nimport type { FrameworkConfig } from '@lib/framework-config';\nimport { detectNodePackageManagers } from '@lib/detection/package-manager';\nimport { Integration } from '@lib/constants';\nimport {\n getDeclaredVersion,\n getInstalledPackageVersion,\n hasDeclaredDependency,\n type PackageJson,\n} from '@utils/package-json';\nimport { tryGetPackageJson } from '@utils/setup-utils';\nimport { getAngularVersionBucket } from './utils';\n\ntype AngularContext = Record<string, unknown>;\n\nexport const ANGULAR_AGENT_CONFIG: FrameworkConfig<AngularContext> = {\n metadata: {\n name: 'Angular',\n integration: Integration.angular,\n docsUrl: 'https://posthog.com/docs/libraries/angular',\n },\n\n detection: {\n packageName: '@angular/core',\n packageDisplayName: 'Angular',\n getVersion: (packageJson: unknown) =>\n getDeclaredVersion('@angular/core', packageJson as PackageJson),\n getVersionBucket: getAngularVersionBucket,\n minimumVersion: '19.0.0',\n getInstalledVersion: (options: WizardRunOptions) =>\n Promise.resolve(\n getInstalledPackageVersion('@angular/core', options.installDir),\n ),\n detect: async (options) => {\n const packageJson = await tryGetPackageJson(options);\n return packageJson\n ? hasDeclaredDependency('@angular/core', packageJson)\n : false;\n },\n detectPackageManager: detectNodePackageManagers,\n },\n\n environment: {\n uploadToHosting: false,\n getEnvVars: (apiKey: string, host: string) => ({\n NG_APP_POSTHOG_PROJECT_TOKEN: apiKey,\n NG_APP_POSTHOG_HOST: host,\n }),\n },\n\n analytics: {\n getTags: () => ({}),\n },\n\n prompts: {\n projectTypeDetection:\n 'This is an Angular project. Look for package.json, angular.json, and lockfiles (package-lock.json, yarn.lock, pnpm-lock.yaml) to confirm.',\n getAdditionalContextLines: () => {\n const frameworkId = 'angular';\n\n return [\n `Framework docs ID: ${frameworkId} (use posthog://docs/frameworks/${frameworkId} for documentation)`,\n 'Angular uses dependency injection for services. PostHog should be initialized as a service.',\n 'For standalone components, ensure PostHog is properly provided in the application config.',\n ];\n },\n },\n\n ui: {\n successMessage: 'PostHog integration complete',\n estimatedDurationMinutes: 8,\n getOutroChanges: () => [\n `Analyzed your Angular project structure`,\n `Created and configured PostHog service`,\n `Integrated PostHog into your application`,\n ],\n getOutroNextSteps: () => [\n 'Start your development server with `ng serve` to see PostHog in action',\n 'Visit your PostHog dashboard to see incoming events',\n ],\n },\n};\n","import { boundedGlob, readProjectFile } from '@utils/bounded-fs';\nimport fs from 'fs/promises';\nimport path from 'path';\nimport type { WizardRunOptions } from '@utils/types';\nimport { createVersionBucket } from '@utils/semver';\n\nexport const getAstroVersionBucket = createVersionBucket();\n\nexport enum AstroRenderingMode {\n STATIC = 'static',\n SSR = 'ssr',\n HYBRID = 'hybrid',\n VIEW_TRANSITIONS = 'view-transitions',\n}\n\nconst EXTRA_IGNORE = ['**/.astro/**'];\n\n/**\n * Detect the Astro rendering mode. Pure — always resolves (Astro detection is reliable).\n */\nexport async function getAstroRenderingMode({\n installDir,\n}: Pick<WizardRunOptions, 'installDir'>): Promise<AstroRenderingMode> {\n const configMatches = await boundedGlob('astro.config.@(mjs|ts|js)', {\n cwd: installDir,\n extraIgnore: EXTRA_IGNORE,\n limit: 1,\n });\n\n let hasAdapter = false;\n let outputMode: string | null = null;\n let usesViewTransitions = false;\n\n try {\n const packageJsonPath = path.join(installDir, 'package.json');\n const packageJsonContent = await fs.readFile(packageJsonPath, 'utf-8');\n const packageJson = JSON.parse(packageJsonContent);\n const allDeps = {\n ...packageJson.dependencies,\n ...packageJson.devDependencies,\n };\n\n hasAdapter = Object.keys(allDeps).some(\n (dep) =>\n dep.startsWith('@astrojs/') &&\n (dep.includes('node') ||\n dep.includes('vercel') ||\n dep.includes('netlify') ||\n dep.includes('cloudflare') ||\n dep.includes('deno')),\n );\n } catch {\n // package.json not found or invalid\n }\n\n if (configMatches.length > 0) {\n try {\n const configPath = path.join(installDir, configMatches[0]);\n const configContent = await fs.readFile(configPath, 'utf-8');\n const outputMatch = configContent.match(/output:\\s*['\"](\\w+)['\"]/);\n if (outputMatch) {\n outputMode = outputMatch[1];\n }\n } catch {\n // Config file not readable\n }\n }\n\n const viewTransitionMatches = await boundedGlob(\n '**/*.@(astro|ts|tsx|js|jsx)',\n {\n cwd: installDir,\n extraIgnore: EXTRA_IGNORE,\n limit: 20,\n },\n );\n\n for (const file of viewTransitionMatches) {\n const content = readProjectFile(path.join(installDir, file));\n if (!content) continue;\n if (\n content.includes('ClientRouter') ||\n content.includes('ViewTransitions') ||\n content.includes('astro:transitions')\n ) {\n usesViewTransitions = true;\n break;\n }\n }\n\n if (usesViewTransitions) {\n return AstroRenderingMode.VIEW_TRANSITIONS;\n }\n\n if (outputMode === 'server' && hasAdapter) {\n return AstroRenderingMode.SSR;\n }\n\n if (hasAdapter) {\n return AstroRenderingMode.HYBRID;\n }\n\n return AstroRenderingMode.STATIC;\n}\n\nexport const getAstroRenderingModeName = (mode: AstroRenderingMode): string => {\n switch (mode) {\n case AstroRenderingMode.STATIC:\n return 'Static (SSG)';\n case AstroRenderingMode.VIEW_TRANSITIONS:\n return 'View Transitions';\n case AstroRenderingMode.SSR:\n return 'Server (SSR)';\n case AstroRenderingMode.HYBRID:\n return 'Hybrid';\n default:\n return 'Static';\n }\n};\n","/* Astro wizard using posthog-agent with PostHog MCP */\nimport type { WizardRunOptions } from '@utils/types';\nimport type { FrameworkConfig } from '@lib/framework-config';\nimport { detectNodePackageManagers } from '@lib/detection/package-manager';\nimport { Integration } from '@lib/constants';\nimport {\n getDeclaredVersion,\n getInstalledPackageVersion,\n hasDeclaredDependency,\n type PackageJson,\n} from '@utils/package-json';\nimport { tryGetPackageJson } from '@utils/setup-utils';\nimport { getUI } from '@ui';\nimport {\n getAstroRenderingMode,\n getAstroVersionBucket,\n getAstroRenderingModeName,\n AstroRenderingMode,\n} from './utils';\n\ntype AstroContext = {\n renderingMode?: AstroRenderingMode;\n};\n\nexport const ASTRO_AGENT_CONFIG: FrameworkConfig<AstroContext> = {\n metadata: {\n name: 'Astro',\n integration: Integration.astro,\n docsUrl: 'https://posthog.com/docs/libraries/astro',\n gatherContext: async (options: WizardRunOptions) => {\n const renderingMode = await getAstroRenderingMode(options);\n getUI().setDetectedFramework(\n `Astro ${getAstroRenderingModeName(renderingMode)}`,\n );\n return { renderingMode };\n },\n },\n\n detection: {\n packageName: 'astro',\n packageDisplayName: 'Astro',\n getVersion: (packageJson: unknown) =>\n getDeclaredVersion('astro', packageJson as PackageJson),\n getVersionBucket: getAstroVersionBucket,\n minimumVersion: '4.0.0',\n getInstalledVersion: (options: WizardRunOptions) =>\n Promise.resolve(getInstalledPackageVersion('astro', options.installDir)),\n detect: async (options) => {\n const packageJson = await tryGetPackageJson(options);\n return packageJson ? hasDeclaredDependency('astro', packageJson) : false;\n },\n detectPackageManager: detectNodePackageManagers,\n },\n\n environment: {\n uploadToHosting: true,\n getEnvVars: (apiKey: string, host: string) => ({\n PUBLIC_POSTHOG_PROJECT_TOKEN: apiKey,\n PUBLIC_POSTHOG_HOST: host,\n }),\n },\n\n analytics: {\n getTags: (context) => ({\n 'rendering-mode': context.renderingMode ?? 'static',\n }),\n },\n\n prompts: {\n projectTypeDetection:\n 'This is a JavaScript/TypeScript project. Look for package.json and lockfiles (package-lock.json, yarn.lock, pnpm-lock.yaml, bun.lockb) to confirm.',\n getAdditionalContextLines: (context) => {\n const modeName = getAstroRenderingModeName(\n context.renderingMode ?? AstroRenderingMode.STATIC,\n );\n\n // Map rendering mode to framework ID for MCP docs resource\n const frameworkIdMap: Record<AstroRenderingMode, string> = {\n [AstroRenderingMode.STATIC]: 'astro-static',\n [AstroRenderingMode.VIEW_TRANSITIONS]: 'astro-view-transitions',\n [AstroRenderingMode.SSR]: 'astro-ssr',\n [AstroRenderingMode.HYBRID]: 'astro-hybrid',\n };\n\n const frameworkId =\n frameworkIdMap[context.renderingMode ?? AstroRenderingMode.STATIC];\n\n const lines = [\n `Rendering mode: ${modeName}`,\n `Framework docs ID: ${frameworkId} (use posthog://docs/frameworks/${frameworkId} for documentation)`,\n ];\n\n // Add mode-specific guidance\n if (context.renderingMode === AstroRenderingMode.VIEW_TRANSITIONS) {\n lines.push(\n 'IMPORTANT: Use window.__posthog_initialized guard to prevent re-initialization during soft navigation',\n );\n lines.push(\n \"IMPORTANT: Set capture_pageview: 'history_change' for automatic pageview tracking\",\n );\n }\n\n if (\n context.renderingMode === AstroRenderingMode.SSR ||\n context.renderingMode === AstroRenderingMode.HYBRID\n ) {\n lines.push(\n 'IMPORTANT: Use posthog-node for server-side tracking in API routes',\n );\n lines.push(\n 'IMPORTANT: Create a singleton pattern for the posthog-node client',\n );\n }\n\n return lines;\n },\n },\n\n ui: {\n successMessage: 'PostHog integration complete',\n estimatedDurationMinutes: 6,\n getOutroChanges: (context) => {\n const modeName = getAstroRenderingModeName(\n context.renderingMode ?? AstroRenderingMode.STATIC,\n );\n const changes = [\n `Analyzed your Astro project structure (${modeName})`,\n `Created PostHog component with is:inline script`,\n `Integrated PostHog into your layout`,\n ];\n\n if (\n context.renderingMode === AstroRenderingMode.SSR ||\n context.renderingMode === AstroRenderingMode.HYBRID\n ) {\n changes.push(`Set up posthog-node for server-side tracking`);\n }\n\n if (context.renderingMode === AstroRenderingMode.VIEW_TRANSITIONS) {\n changes.push(\n `Added initialization guard for view transitions compatibility`,\n );\n }\n\n return changes;\n },\n getOutroNextSteps: () => {\n return [\n 'Start your development server to see PostHog in action',\n 'Visit your PostHog dashboard to see incoming events',\n ];\n },\n },\n};\n","import type { Integration } from './constants';\nimport type { WizardRunOptions } from '@utils/types';\nimport type { PackageManagerDetector } from './detection/package-manager';\n\n/**\n * A setup question that the SetupScreen renders for framework disambiguation.\n * If detect() returns a value, the question is auto-resolved and not shown.\n */\nexport interface SetupQuestion {\n /** Stored in session.frameworkContext[key] */\n key: string;\n /** Displayed to user, e.g. \"Which router are you using?\" */\n message: string;\n /** Picker options */\n options: Array<{ label: string; value: string; hint?: string }>;\n /** Auto-detect; null = ask the user */\n detect: (\n options: Pick<WizardRunOptions, 'installDir'>,\n ) => Promise<string | null>;\n}\n\n/**\n * Configuration interface for framework-specific agent integrations.\n * Each framework exports a FrameworkConfig that the universal runner uses.\n *\n * The TContext generic represents the framework-specific context gathered\n * before the agent runs (e.g., router type for Next.js, project type for Django).\n * The runner threads this opaquely — all framework-specific logic stays inside the config.\n */\nexport interface FrameworkConfig<\n TContext extends Record<string, unknown> = Record<string, unknown>,\n> {\n metadata: FrameworkMetadata<TContext>;\n detection: FrameworkDetection;\n environment: EnvironmentConfig;\n analytics: AnalyticsConfig<TContext>;\n prompts: PromptConfig<TContext>;\n ui: UIConfig<TContext>;\n}\n\n/**\n * Basic framework information and documentation\n */\nexport interface FrameworkMetadata<\n TContext extends Record<string, unknown> = Record<string, unknown>,\n> {\n /** Display name (e.g., \"Next.js\", \"React\") */\n name: string;\n\n /** Integration type from constants */\n integration: Integration;\n\n /** URL to framework-specific PostHog docs */\n docsUrl: string;\n\n /**\n * Optional URL to docs for users with unsupported framework versions.\n * If not provided, defaults to docsUrl.\n */\n unsupportedVersionDocsUrl?: string;\n\n /** If true, shows a beta notice before running the wizard. */\n beta?: boolean;\n\n /** Optional notice shown before the agent runs (e.g., \"Close Xcode before proceeding\"). */\n preRunNotice?: string;\n\n /**\n * Optional function to gather framework-specific context before agent runs.\n * For Next.js: detects router type\n * For React Native: detects Expo vs bare\n */\n gatherContext?: (options: WizardRunOptions) => Promise<TContext>;\n\n /** Optional additional MCP servers for this framework (e.g., Svelte MCP). */\n additionalMcpServers?: Record<string, { url: string }>;\n\n /**\n * Setup questions for framework disambiguation.\n * The SetupScreen iterates unresolved questions and renders a PickerMenu for each.\n * If all questions are auto-resolved (or none defined), the screen is skipped.\n */\n setup?: {\n questions: SetupQuestion[];\n };\n}\n\n/**\n * Framework detection and version handling\n */\nexport interface FrameworkDetection {\n /** Package name to check in package.json (e.g., \"next\", \"react\") */\n packageName: string;\n\n /** Human-readable name for error messages (e.g., \"Next.js\") */\n packageDisplayName: string;\n\n /** Extract version from package.json */\n getVersion: (packageJson: unknown) => string | undefined;\n\n /** Optional: Convert version to analytics bucket (e.g., \"15.x\") */\n getVersionBucket?: (version: string) => string;\n\n /**\n * Whether this framework uses package.json (Node.js/JavaScript).\n * If false, skips package.json checks (for Python, Go, etc.)\n * Defaults to true if not specified.\n */\n usesPackageJson?: boolean;\n\n /** Minimum supported version. If set, runner checks before proceeding. */\n minimumVersion?: string;\n\n /** Get the currently installed version. Called by runner for version check. */\n getInstalledVersion?: (\n options: WizardRunOptions,\n ) => Promise<string | undefined>;\n\n /** Detect whether this framework is present in the project. */\n detect: (options: Pick<WizardRunOptions, 'installDir'>) => Promise<boolean>;\n\n /** Detect the project's package manager(s). Used by the in-process MCP tool. */\n detectPackageManager: PackageManagerDetector;\n}\n\n/**\n * Environment variable configuration\n */\nexport interface EnvironmentConfig {\n /** Whether to upload env vars to hosting providers post-agent */\n uploadToHosting: boolean;\n\n /**\n * Build the environment variables object for this framework.\n * Returns the exact variable names and values to upload to hosting providers.\n */\n getEnvVars: (apiKey: string, host: string) => Record<string, string>;\n}\n\n/**\n * Analytics configuration\n */\nexport interface AnalyticsConfig<\n TContext extends Record<string, unknown> = Record<string, unknown>,\n> {\n /** Generate tags from context (e.g., { 'nextjs-version': '15.x', 'router': 'app' }) */\n getTags: (context: TContext) => Record<string, string>;\n\n /** Optional: Additional event properties */\n getEventProperties?: (context: TContext) => Record<string, string>;\n}\n\n/**\n * Default package installation instruction used when frameworks don't\n * provide their own. Frameworks with specific needs (e.g., Swift SPM,\n * Composer) override this in their config.\n */\nexport const DEFAULT_PACKAGE_INSTALLATION =\n 'Use the detect_package_manager tool to determine the package manager. Do not manually edit package.json; the package manager handles it automatically.';\n\nexport const PYTHON_PACKAGE_INSTALLATION =\n 'Use the detect_package_manager tool to determine the package manager. If the detected tool manages dependencies directly (e.g. uv add, poetry add), use it — it will update the manifest automatically. If using pip, you must also add the dependency to requirements.txt or the appropriate manifest file.';\n\n/**\n * Prompt configuration\n */\nexport interface PromptConfig<\n TContext extends Record<string, unknown> = Record<string, unknown>,\n> {\n /**\n * Optional: Additional context lines to append to base prompt\n * For Next.js: \"- Router: app\"\n * For React Native: \"- Platform: Expo\"\n */\n getAdditionalContextLines?: (context: TContext) => string[];\n\n /**\n * How to detect the project type for this framework.\n * Included in the agent prompt as project context.\n * e.g., \"Look for package.json and lockfiles\" or \"Look for requirements.txt and manage.py\"\n */\n projectTypeDetection: string;\n\n /**\n * How to install packages for this framework.\n * Included in the agent prompt as project context.\n * Defaults to DEFAULT_PACKAGE_INSTALLATION. Only override if the framework\n * has specific installation guidance (e.g., Swift SPM, Composer).\n */\n packageInstallation?: string;\n}\n\n/**\n * UI messaging configuration\n */\nexport interface UIConfig<\n TContext extends Record<string, unknown> = Record<string, unknown>,\n> {\n /** Success message when agent completes */\n successMessage: string;\n\n /** Estimated time for agent to complete (in minutes) */\n estimatedDurationMinutes: number;\n\n /** Generate \"What the agent did\" bullets from context */\n getOutroChanges: (context: TContext) => string[];\n\n /** Generate \"Next steps\" bullets from context */\n getOutroNextSteps: (context: TContext) => string[];\n}\n\n/**\n * Generate welcome message from framework name\n */\nexport function getWelcomeMessage(frameworkName: string): string {\n return `PostHog ${frameworkName} wizard (agent-powered)`;\n}\n\n/**\n * Shared spinner message for all frameworks\n */\nexport const SPINNER_MESSAGE =\n 'Writing your PostHog setup with events, error capture and more...';\n","import { boundedGlob, readProjectFile } from '@utils/bounded-fs';\nimport { getUI } from '@ui';\nimport type { WizardRunOptions } from '@utils/types';\nimport { createVersionBucket } from '@utils/semver';\nimport * as fs from 'node:fs';\nimport * as path from 'node:path';\n\nexport enum DjangoProjectType {\n STANDARD = 'standard', // Traditional Django project (django-admin startproject)\n DRF = 'drf', // Django REST Framework API\n WAGTAIL = 'wagtail', // Wagtail CMS\n CHANNELS = 'channels', // Django Channels (async/websockets)\n}\n\nconst EXTRA_IGNORE = ['**/env/**', '**/.env/**', '**/migrations/**'];\n\n/**\n * Get Django version bucket for analytics\n */\nexport const getDjangoVersionBucket = createVersionBucket();\n\n/**\n * Extract Django version from requirements files or pyproject.toml\n */\nexport async function getDjangoVersion(\n options: Pick<WizardRunOptions, 'installDir'>,\n): Promise<string | undefined> {\n const { installDir } = options;\n\n // Check requirements files\n const requirementsFiles = await boundedGlob(\n ['**/requirements*.txt', '**/pyproject.toml', '**/setup.py', '**/Pipfile'],\n {\n cwd: installDir,\n extraIgnore: EXTRA_IGNORE,\n },\n );\n\n for (const reqFile of requirementsFiles) {\n const content = readProjectFile(path.join(installDir, reqFile));\n if (!content) continue;\n\n // Try to extract version from requirements.txt format (Django==4.2.0 or Django>=4.0)\n const requirementsMatch = content.match(\n /[Dd]jango[=<>~!]+([0-9]+\\.[0-9]+(?:\\.[0-9]+)?)/,\n );\n if (requirementsMatch) {\n return requirementsMatch[1];\n }\n\n // Try to extract from pyproject.toml format\n const pyprojectMatch = content.match(\n /[Dd]jango[\"\\s]*[=<>~!]+\\s*[\"']?([0-9]+\\.[0-9]+(?:\\.[0-9]+)?)/,\n );\n if (pyprojectMatch) {\n return pyprojectMatch[1];\n }\n }\n\n return undefined;\n}\n\n/**\n * Check if Django REST Framework is installed\n */\nasync function hasDRF({\n installDir,\n}: Pick<WizardRunOptions, 'installDir'>): Promise<boolean> {\n const requirementsFiles = await boundedGlob(\n ['**/requirements*.txt', '**/pyproject.toml', '**/Pipfile'],\n {\n cwd: installDir,\n extraIgnore: EXTRA_IGNORE,\n },\n );\n\n for (const reqFile of requirementsFiles) {\n const content = readProjectFile(path.join(installDir, reqFile));\n if (content?.includes('djangorestframework')) {\n return true;\n }\n }\n\n // Also check INSTALLED_APPS in settings\n const settingsFiles = await boundedGlob('**/settings.py', {\n cwd: installDir,\n extraIgnore: EXTRA_IGNORE,\n });\n\n for (const settingsFile of settingsFiles) {\n const content = readProjectFile(path.join(installDir, settingsFile));\n if (content?.includes('rest_framework')) {\n return true;\n }\n }\n\n return false;\n}\n\n/**\n * Check if Wagtail is installed\n */\nasync function hasWagtail({\n installDir,\n}: Pick<WizardRunOptions, 'installDir'>): Promise<boolean> {\n const requirementsFiles = await boundedGlob(\n ['**/requirements*.txt', '**/pyproject.toml', '**/Pipfile'],\n {\n cwd: installDir,\n extraIgnore: EXTRA_IGNORE,\n },\n );\n\n for (const reqFile of requirementsFiles) {\n const content = readProjectFile(path.join(installDir, reqFile));\n if (content?.includes('wagtail')) {\n return true;\n }\n }\n\n return false;\n}\n\n/**\n * Check if Django Channels is installed\n */\nasync function hasChannels({\n installDir,\n}: Pick<WizardRunOptions, 'installDir'>): Promise<boolean> {\n const requirementsFiles = await boundedGlob(\n ['**/requirements*.txt', '**/pyproject.toml', '**/Pipfile'],\n {\n cwd: installDir,\n extraIgnore: EXTRA_IGNORE,\n },\n );\n\n for (const reqFile of requirementsFiles) {\n const content = readProjectFile(path.join(installDir, reqFile));\n if (content?.includes('channels')) {\n return true;\n }\n }\n\n return false;\n}\n\n/**\n * Detect Django project type\n */\nexport async function getDjangoProjectType(\n options: WizardRunOptions,\n): Promise<DjangoProjectType> {\n const { installDir } = options;\n\n // Check for Wagtail first (CMS)\n if (await hasWagtail({ installDir })) {\n getUI().setDetectedFramework('Django with Wagtail CMS');\n return DjangoProjectType.WAGTAIL;\n }\n\n // Check for Django REST Framework\n if (await hasDRF({ installDir })) {\n getUI().setDetectedFramework('Django REST Framework');\n return DjangoProjectType.DRF;\n }\n\n // Check for Django Channels\n if (await hasChannels({ installDir })) {\n getUI().setDetectedFramework('Django Channels');\n return DjangoProjectType.CHANNELS;\n }\n\n // Default to standard Django\n getUI().setDetectedFramework('Django');\n return DjangoProjectType.STANDARD;\n}\n\n/**\n * Get human-readable name for Django project type\n */\nexport function getDjangoProjectTypeName(\n projectType: DjangoProjectType,\n): string {\n switch (projectType) {\n case DjangoProjectType.STANDARD:\n return 'Standard Django';\n case DjangoProjectType.DRF:\n return 'Django REST Framework';\n case DjangoProjectType.WAGTAIL:\n return 'Wagtail CMS';\n case DjangoProjectType.CHANNELS:\n return 'Django Channels';\n }\n}\n\n/**\n * Find the main Django settings file\n */\nexport async function findDjangoSettingsFile(\n options: Pick<WizardRunOptions, 'installDir'>,\n): Promise<string | undefined> {\n const { installDir } = options;\n\n // Look for settings.py files\n const settingsFiles = await boundedGlob('**/settings.py', {\n cwd: installDir,\n extraIgnore: EXTRA_IGNORE,\n });\n\n if (settingsFiles.length === 0) {\n // Try settings/__init__.py for split settings\n const splitSettingsFiles = await boundedGlob('**/settings/__init__.py', {\n cwd: installDir,\n extraIgnore: EXTRA_IGNORE,\n limit: 1,\n });\n\n if (splitSettingsFiles.length > 0) {\n return splitSettingsFiles[0];\n }\n\n return undefined;\n }\n\n // If multiple settings files, prefer the one next to manage.py or in root\n if (settingsFiles.length === 1) {\n return settingsFiles[0];\n }\n\n // Try to find the main settings file by looking for ROOT_URLCONF\n for (const settingsFile of settingsFiles) {\n const content = readProjectFile(path.join(installDir, settingsFile));\n if (content?.includes('ROOT_URLCONF')) {\n return settingsFile;\n }\n }\n\n // Default to first found\n return settingsFiles[0];\n}\n\n/**\n * Find the main Django urls.py file\n */\nexport async function findDjangoUrlsFile(\n options: Pick<WizardRunOptions, 'installDir'>,\n): Promise<string | undefined> {\n const { installDir } = options;\n\n // First, try to find the root urls.py referenced in settings\n const settingsFile = await findDjangoSettingsFile(options);\n if (settingsFile) {\n const settingsContent = readProjectFile(\n path.join(installDir, settingsFile),\n );\n const urlconfMatch = settingsContent?.match(\n /ROOT_URLCONF\\s*=\\s*['\"]([^'\"]+)['\"]/,\n );\n if (urlconfMatch) {\n const urlconfPath = urlconfMatch[1].replace(/\\./g, '/') + '.py';\n const fullPath = path.join(installDir, urlconfPath);\n if (fs.existsSync(fullPath)) {\n return urlconfPath;\n }\n }\n }\n\n // Fallback to glob search\n const urlsFiles = await boundedGlob('**/urls.py', {\n cwd: installDir,\n extraIgnore: [...EXTRA_IGNORE, '**/admin/**'],\n });\n\n if (urlsFiles.length === 0) {\n return undefined;\n }\n\n // Prefer urls.py files that contain urlpatterns\n for (const urlsFile of urlsFiles) {\n const content = readProjectFile(path.join(installDir, urlsFile));\n if (content?.includes('urlpatterns')) {\n return urlsFile;\n }\n }\n\n return urlsFiles[0];\n}\n","/* Django wizard using posthog-agent with PostHog MCP */\nimport type { WizardRunOptions } from '@utils/types';\nimport type { FrameworkConfig } from '@lib/framework-config';\nimport { PYTHON_PACKAGE_INSTALLATION } from '@lib/framework-config';\nimport { detectPythonPackageManagers } from '@lib/detection/package-manager';\nimport { Integration } from '@lib/constants';\nimport { boundedGlob, readProjectFile } from '@utils/bounded-fs';\nimport * as path from 'node:path';\nimport {\n getDjangoVersion,\n getDjangoProjectType,\n getDjangoProjectTypeName,\n getDjangoVersionBucket,\n DjangoProjectType,\n findDjangoSettingsFile,\n} from './utils';\n\nconst EXTRA_IGNORE = ['**/env/**', '**/.env/**'];\n\ntype DjangoContext = {\n projectType?: DjangoProjectType;\n settingsFile?: string;\n};\n\nexport const DJANGO_AGENT_CONFIG: FrameworkConfig<DjangoContext> = {\n metadata: {\n name: 'Django',\n integration: Integration.django,\n docsUrl: 'https://posthog.com/docs/libraries/django',\n unsupportedVersionDocsUrl: 'https://posthog.com/docs/libraries/python',\n gatherContext: async (options: WizardRunOptions) => {\n const projectType = await getDjangoProjectType(options);\n const settingsFile = await findDjangoSettingsFile(options);\n return { projectType, settingsFile };\n },\n },\n\n detection: {\n packageName: 'django',\n packageDisplayName: 'Django',\n usesPackageJson: false,\n getVersion: () => undefined,\n getVersionBucket: getDjangoVersionBucket,\n minimumVersion: '3.0.0',\n getInstalledVersion: (options: WizardRunOptions) =>\n getDjangoVersion(options),\n detect: async (options) => {\n const { installDir } = options;\n\n const managePyMatches = await boundedGlob('**/manage.py', {\n cwd: installDir,\n extraIgnore: EXTRA_IGNORE,\n });\n\n if (managePyMatches.length > 0) {\n for (const match of managePyMatches) {\n const content = readProjectFile(path.join(installDir, match));\n if (!content) continue;\n // Check for actual Django imports and usage\n if (\n content.includes('from django') ||\n content.includes('import django') ||\n content.includes('DJANGO_SETTINGS_MODULE') ||\n /execute_from_command_line/.test(content)\n ) {\n return true;\n }\n }\n }\n\n const requirementsFiles = await boundedGlob(\n ['**/requirements*.txt', '**/pyproject.toml', '**/setup.py'],\n {\n cwd: installDir,\n extraIgnore: EXTRA_IGNORE,\n },\n );\n\n for (const reqFile of requirementsFiles) {\n const content = readProjectFile(path.join(installDir, reqFile));\n if (!content) continue;\n // Match Django as a package requirement, not in comments or other text\n // Look for: django, django>=, django==, django~=, Django (capitalized)\n if (\n /^django([>=~!<\\s]|$)/im.test(content) ||\n /[\"']django[\"']/i.test(content)\n ) {\n return true;\n }\n }\n\n return false;\n },\n detectPackageManager: detectPythonPackageManagers,\n },\n\n environment: {\n uploadToHosting: false,\n getEnvVars: (apiKey: string, host: string) => ({\n POSTHOG_PROJECT_TOKEN: apiKey,\n POSTHOG_HOST: host,\n }),\n },\n\n analytics: {\n getTags: (context) => ({\n projectType: context.projectType || 'unknown',\n }),\n },\n\n prompts: {\n packageInstallation: PYTHON_PACKAGE_INSTALLATION,\n projectTypeDetection:\n 'This is a Python/Django project. Look for requirements.txt, pyproject.toml, setup.py, Pipfile, or manage.py to confirm.',\n getAdditionalContextLines: (context) => {\n const projectTypeName = context.projectType\n ? getDjangoProjectTypeName(context.projectType)\n : 'unknown';\n\n // Map project type to framework ID for MCP docs resource\n const frameworkIdMap: Record<DjangoProjectType, string> = {\n [DjangoProjectType.STANDARD]: 'django',\n [DjangoProjectType.DRF]: 'django',\n [DjangoProjectType.WAGTAIL]: 'django',\n [DjangoProjectType.CHANNELS]: 'django',\n };\n\n const frameworkId = context.projectType\n ? frameworkIdMap[context.projectType]\n : 'django';\n\n const lines = [\n `Project type: ${projectTypeName}`,\n `Framework docs ID: ${frameworkId} (use posthog://docs/frameworks/${frameworkId} for documentation)`,\n ];\n\n if (context.settingsFile) {\n lines.push(`Settings file: ${context.settingsFile}`);\n }\n\n return lines;\n },\n },\n\n ui: {\n successMessage: 'PostHog integration complete',\n estimatedDurationMinutes: 5,\n getOutroChanges: (context) => {\n const projectTypeName = context.projectType\n ? getDjangoProjectTypeName(context.projectType)\n : 'Django';\n return [\n `Analyzed your ${projectTypeName} project structure`,\n `Installed the PostHog Python package`,\n `Configured PostHog in your Django settings`,\n `Added PostHog middleware for automatic event tracking`,\n ];\n },\n getOutroNextSteps: () => [\n 'Start your Django development server to see PostHog in action',\n 'Visit your PostHog dashboard to see incoming events',\n 'Use identify_context() within new_context() to associate events with users',\n ],\n },\n};\n","import { boundedGlob, readProjectFile } from '@utils/bounded-fs';\nimport { getUI } from '@ui';\nimport type { WizardRunOptions } from '@utils/types';\nimport { createVersionBucket } from '@utils/semver';\nimport * as path from 'node:path';\n\nexport enum FlaskProjectType {\n STANDARD = 'standard', // Basic Flask app\n RESTFUL = 'restful', // Flask-RESTful API\n RESTX = 'restx', // Flask-RESTX (Swagger docs)\n SMOREST = 'smorest', // flask-smorest (OpenAPI)\n BLUEPRINT = 'blueprint', // Large app with blueprints\n}\n\nconst EXTRA_IGNORE = [\n '**/env/**',\n '**/.env/**',\n '**/migrations/**',\n '**/instance/**',\n];\n\n/** Content probes read at most this many files, one in memory at a time. */\nconst SOURCE_PROBE_LIMIT = 200;\n\n/**\n * Get Flask version bucket for analytics\n */\nexport const getFlaskVersionBucket = createVersionBucket();\n\n/**\n * Extract Flask version from requirements files or pyproject.toml\n */\nexport async function getFlaskVersion(\n options: Pick<WizardRunOptions, 'installDir'>,\n): Promise<string | undefined> {\n const { installDir } = options;\n\n // Check requirements files\n const requirementsFiles = await boundedGlob(\n ['**/requirements*.txt', '**/pyproject.toml', '**/setup.py', '**/Pipfile'],\n {\n cwd: installDir,\n extraIgnore: EXTRA_IGNORE,\n },\n );\n\n for (const reqFile of requirementsFiles) {\n const content = readProjectFile(path.join(installDir, reqFile));\n if (!content) continue;\n\n // Try to extract version from requirements.txt format (Flask==3.0.0 or flask>=2.0)\n const requirementsMatch = content.match(\n /[Ff]lask[=<>~!]+([0-9]+\\.[0-9]+(?:\\.[0-9]+)?)/,\n );\n if (requirementsMatch) {\n return requirementsMatch[1];\n }\n\n // Try to extract from pyproject.toml format\n const pyprojectMatch = content.match(\n /[Ff]lask[\"\\s]*[=<>~!]+\\s*[\"']?([0-9]+\\.[0-9]+(?:\\.[0-9]+)?)/,\n );\n if (pyprojectMatch) {\n return pyprojectMatch[1];\n }\n }\n\n return undefined;\n}\n\n/**\n * Check if Flask-RESTful is installed\n */\nasync function hasFlaskRESTful({\n installDir,\n}: Pick<WizardRunOptions, 'installDir'>): Promise<boolean> {\n const requirementsFiles = await boundedGlob(\n ['**/requirements*.txt', '**/pyproject.toml', '**/Pipfile'],\n {\n cwd: installDir,\n extraIgnore: EXTRA_IGNORE,\n },\n );\n\n for (const reqFile of requirementsFiles) {\n const content = readProjectFile(path.join(installDir, reqFile));\n if (!content) continue;\n if (\n content.includes('flask-restful') ||\n content.includes('Flask-RESTful')\n ) {\n return true;\n }\n }\n\n // Also check imports in Python files\n const pyFiles = await boundedGlob(['**/*.py'], {\n cwd: installDir,\n extraIgnore: EXTRA_IGNORE,\n limit: SOURCE_PROBE_LIMIT,\n });\n\n for (const pyFile of pyFiles) {\n const content = readProjectFile(path.join(installDir, pyFile));\n if (!content) continue;\n if (\n content.includes('from flask_restful import') ||\n content.includes('import flask_restful')\n ) {\n return true;\n }\n }\n\n return false;\n}\n\n/**\n * Check if Flask-RESTX is installed\n */\nasync function hasFlaskRESTX({\n installDir,\n}: Pick<WizardRunOptions, 'installDir'>): Promise<boolean> {\n const requirementsFiles = await boundedGlob(\n ['**/requirements*.txt', '**/pyproject.toml', '**/Pipfile'],\n {\n cwd: installDir,\n extraIgnore: EXTRA_IGNORE,\n },\n );\n\n for (const reqFile of requirementsFiles) {\n const content = readProjectFile(path.join(installDir, reqFile));\n if (!content) continue;\n if (content.includes('flask-restx') || content.includes('Flask-RESTX')) {\n return true;\n }\n }\n\n // Also check imports in Python files\n const pyFiles = await boundedGlob(['**/*.py'], {\n cwd: installDir,\n extraIgnore: EXTRA_IGNORE,\n limit: SOURCE_PROBE_LIMIT,\n });\n\n for (const pyFile of pyFiles) {\n const content = readProjectFile(path.join(installDir, pyFile));\n if (!content) continue;\n if (\n content.includes('from flask_restx import') ||\n content.includes('import flask_restx')\n ) {\n return true;\n }\n }\n\n return false;\n}\n\n/**\n * Check if flask-smorest is installed\n */\nasync function hasFlaskSmorest({\n installDir,\n}: Pick<WizardRunOptions, 'installDir'>): Promise<boolean> {\n const requirementsFiles = await boundedGlob(\n ['**/requirements*.txt', '**/pyproject.toml', '**/Pipfile'],\n {\n cwd: installDir,\n extraIgnore: EXTRA_IGNORE,\n },\n );\n\n for (const reqFile of requirementsFiles) {\n const content = readProjectFile(path.join(installDir, reqFile));\n if (!content) continue;\n if (content.includes('flask-smorest')) {\n return true;\n }\n }\n\n // Also check imports in Python files\n const pyFiles = await boundedGlob(['**/*.py'], {\n cwd: installDir,\n extraIgnore: EXTRA_IGNORE,\n limit: SOURCE_PROBE_LIMIT,\n });\n\n for (const pyFile of pyFiles) {\n const content = readProjectFile(path.join(installDir, pyFile));\n if (!content) continue;\n if (\n content.includes('from flask_smorest import') ||\n content.includes('import flask_smorest')\n ) {\n return true;\n }\n }\n\n return false;\n}\n\n/**\n * Check if app uses Flask Blueprints\n */\nasync function hasBlueprints({\n installDir,\n}: Pick<WizardRunOptions, 'installDir'>): Promise<boolean> {\n const pyFiles = await boundedGlob(['**/*.py'], {\n cwd: installDir,\n extraIgnore: EXTRA_IGNORE,\n limit: SOURCE_PROBE_LIMIT,\n });\n\n for (const pyFile of pyFiles) {\n const content = readProjectFile(path.join(installDir, pyFile));\n if (!content) continue;\n if (\n content.includes('Blueprint(') ||\n content.includes('register_blueprint(') ||\n content.includes('from flask import Blueprint')\n ) {\n return true;\n }\n }\n\n return false;\n}\n\n/**\n * Detect Flask project type\n */\nexport async function getFlaskProjectType(\n options: WizardRunOptions,\n): Promise<FlaskProjectType> {\n const { installDir } = options;\n\n // Check for Flask-RESTX first (most specific - includes Swagger)\n if (await hasFlaskRESTX({ installDir })) {\n getUI().setDetectedFramework('Flask-RESTX');\n return FlaskProjectType.RESTX;\n }\n\n // Check for flask-smorest (OpenAPI-first)\n if (await hasFlaskSmorest({ installDir })) {\n getUI().setDetectedFramework('flask-smorest');\n return FlaskProjectType.SMOREST;\n }\n\n // Check for Flask-RESTful\n if (await hasFlaskRESTful({ installDir })) {\n getUI().setDetectedFramework('Flask-RESTful');\n return FlaskProjectType.RESTFUL;\n }\n\n // Check for Blueprints (large app structure)\n if (await hasBlueprints({ installDir })) {\n getUI().setDetectedFramework('Flask with Blueprints');\n return FlaskProjectType.BLUEPRINT;\n }\n\n // Default to standard Flask\n getUI().setDetectedFramework('Flask');\n return FlaskProjectType.STANDARD;\n}\n\n/**\n * Get human-readable name for Flask project type\n */\nexport function getFlaskProjectTypeName(projectType: FlaskProjectType): string {\n switch (projectType) {\n case FlaskProjectType.STANDARD:\n return 'Standard Flask';\n case FlaskProjectType.RESTFUL:\n return 'Flask-RESTful';\n case FlaskProjectType.RESTX:\n return 'Flask-RESTX';\n case FlaskProjectType.SMOREST:\n return 'flask-smorest';\n case FlaskProjectType.BLUEPRINT:\n return 'Flask with Blueprints';\n }\n}\n\n/**\n * Find the main Flask app file\n */\nexport async function findFlaskAppFile(\n options: Pick<WizardRunOptions, 'installDir'>,\n): Promise<string | undefined> {\n const { installDir } = options;\n\n // Common Flask app file patterns\n const commonPatterns = [\n '**/app.py',\n '**/wsgi.py',\n '**/application.py',\n '**/run.py',\n '**/main.py',\n '**/__init__.py',\n ];\n\n const appFiles = await boundedGlob(commonPatterns, {\n cwd: installDir,\n extraIgnore: EXTRA_IGNORE,\n });\n\n // Look for files with Flask() instantiation or create_app() factory\n for (const appFile of appFiles) {\n const content = readProjectFile(path.join(installDir, appFile));\n if (!content) continue;\n // Check for Flask app instantiation or application factory\n if (\n content.includes('Flask(__name__)') ||\n content.includes('Flask(') ||\n content.includes('def create_app(')\n ) {\n return appFile;\n }\n }\n\n // If no file with Flask() found, check all Python files\n const allPyFiles = await boundedGlob(['**/*.py'], {\n cwd: installDir,\n extraIgnore: EXTRA_IGNORE,\n limit: SOURCE_PROBE_LIMIT,\n });\n\n for (const pyFile of allPyFiles) {\n const content = readProjectFile(path.join(installDir, pyFile));\n if (!content) continue;\n if (\n content.includes('Flask(__name__)') ||\n content.includes('def create_app(')\n ) {\n return pyFile;\n }\n }\n\n // Return first common pattern file if exists\n if (appFiles.length > 0) {\n return appFiles[0];\n }\n\n return undefined;\n}\n","/* Flask wizard using posthog-agent with PostHog MCP */\nimport type { WizardRunOptions } from '@utils/types';\nimport type { FrameworkConfig } from '@lib/framework-config';\nimport { PYTHON_PACKAGE_INSTALLATION } from '@lib/framework-config';\nimport { detectPythonPackageManagers } from '@lib/detection/package-manager';\nimport { Integration } from '@lib/constants';\nimport { boundedGlob, readProjectFile } from '@utils/bounded-fs';\nimport * as path from 'node:path';\nimport {\n getFlaskVersion,\n getFlaskProjectType,\n getFlaskProjectTypeName,\n getFlaskVersionBucket,\n FlaskProjectType,\n findFlaskAppFile,\n} from './utils';\n\nconst EXTRA_IGNORE = ['**/env/**', '**/.env/**'];\n\ntype FlaskContext = {\n projectType?: FlaskProjectType;\n appFile?: string;\n};\n\nexport const FLASK_AGENT_CONFIG: FrameworkConfig<FlaskContext> = {\n metadata: {\n name: 'Flask',\n integration: Integration.flask,\n docsUrl: 'https://posthog.com/docs/libraries/python',\n unsupportedVersionDocsUrl: 'https://posthog.com/docs/libraries/python',\n gatherContext: async (options: WizardRunOptions) => {\n const projectType = await getFlaskProjectType(options);\n const appFile = await findFlaskAppFile(options);\n return { projectType, appFile };\n },\n },\n\n detection: {\n packageName: 'flask',\n packageDisplayName: 'Flask',\n usesPackageJson: false,\n getVersion: () => undefined,\n getVersionBucket: getFlaskVersionBucket,\n minimumVersion: '2.0.0',\n getInstalledVersion: (options: WizardRunOptions) =>\n getFlaskVersion(options),\n detect: async (options) => {\n const { installDir } = options;\n\n const requirementsFiles = await boundedGlob(\n [\n '**/requirements*.txt',\n '**/pyproject.toml',\n '**/setup.py',\n '**/Pipfile',\n ],\n {\n cwd: installDir,\n extraIgnore: EXTRA_IGNORE,\n },\n );\n\n for (const reqFile of requirementsFiles) {\n const content = readProjectFile(path.join(installDir, reqFile));\n if (!content) continue;\n if (\n /^flask([<>=~!]|$|\\s)/im.test(content) ||\n /[\"']flask[\"']/i.test(content)\n ) {\n return true;\n }\n }\n\n const pyFiles = await boundedGlob(\n ['**/app.py', '**/wsgi.py', '**/application.py', '**/__init__.py'],\n {\n cwd: installDir,\n extraIgnore: EXTRA_IGNORE,\n },\n );\n\n for (const pyFile of pyFiles) {\n const content = readProjectFile(path.join(installDir, pyFile));\n if (!content) continue;\n if (\n content.includes('from flask import') ||\n content.includes('import flask') ||\n /Flask\\s*\\(/.test(content)\n ) {\n return true;\n }\n }\n\n return false;\n },\n detectPackageManager: detectPythonPackageManagers,\n },\n\n environment: {\n uploadToHosting: false,\n getEnvVars: (apiKey: string, host: string) => ({\n POSTHOG_PROJECT_TOKEN: apiKey,\n POSTHOG_HOST: host,\n }),\n },\n\n analytics: {\n getTags: (context) => ({\n projectType: context.projectType || 'unknown',\n }),\n },\n\n prompts: {\n packageInstallation: PYTHON_PACKAGE_INSTALLATION,\n projectTypeDetection:\n 'This is a Python/Flask project. Look for requirements.txt, pyproject.toml, setup.py, Pipfile, or app.py/wsgi.py to confirm.',\n getAdditionalContextLines: (context) => {\n const projectTypeName = context.projectType\n ? getFlaskProjectTypeName(context.projectType)\n : 'unknown';\n\n // Map project type to framework ID for MCP docs resource\n const frameworkIdMap: Record<FlaskProjectType, string> = {\n [FlaskProjectType.STANDARD]: 'flask',\n [FlaskProjectType.RESTFUL]: 'flask',\n [FlaskProjectType.RESTX]: 'flask',\n [FlaskProjectType.SMOREST]: 'flask',\n [FlaskProjectType.BLUEPRINT]: 'flask',\n };\n\n const frameworkId = context.projectType\n ? frameworkIdMap[context.projectType]\n : 'flask';\n\n const lines = [\n `Project type: ${projectTypeName}`,\n `Framework docs ID: ${frameworkId} (use posthog://docs/frameworks/${frameworkId} for documentation)`,\n ];\n\n if (context.appFile) {\n lines.push(`App file: ${context.appFile}`);\n }\n\n return lines;\n },\n },\n\n ui: {\n successMessage: 'PostHog integration complete',\n estimatedDurationMinutes: 5,\n getOutroChanges: (context) => {\n const projectTypeName = context.projectType\n ? getFlaskProjectTypeName(context.projectType)\n : 'Flask';\n return [\n `Analyzed your ${projectTypeName} project structure`,\n `Installed the PostHog Python package`,\n `Configured PostHog in your Flask application`,\n `Added PostHog initialization with automatic event tracking`,\n ];\n },\n getOutroNextSteps: () => [\n 'Start your Flask development server to see PostHog in action',\n 'Visit your PostHog dashboard to see incoming events',\n 'Use posthog.identify() to associate events with users',\n ],\n },\n};\n","import { major, minVersion } from 'semver';\nimport { boundedGlob, readProjectFile } from '@utils/bounded-fs';\nimport { getUI } from '@ui';\nimport type { WizardRunOptions } from '@utils/types';\nimport * as path from 'node:path';\n\nexport enum FastAPIProjectType {\n STANDARD = 'standard', // Basic FastAPI app\n ROUTER = 'router', // FastAPI with APIRouter\n FULLSTACK = 'fullstack', // FastAPI with templates (Jinja2)\n}\n\nconst EXTRA_IGNORE = ['**/env/**', '**/.env/**', '**/migrations/**'];\n\n/** Content probes read at most this many files, one in memory at a time. */\nconst SOURCE_PROBE_LIMIT = 200;\n\n/**\n * Get FastAPI version bucket for analytics\n */\nexport function getFastAPIVersionBucket(version: string | undefined): string {\n if (!version) {\n return 'none';\n }\n\n try {\n const minVer = minVersion(version);\n if (!minVer) {\n return 'invalid';\n }\n const majorVersion = major(minVer);\n // FastAPI 0.x is still the common version range\n if (majorVersion === 0) {\n return '0.x';\n }\n return `${majorVersion}.x`;\n } catch {\n return 'unknown';\n }\n}\n\n/**\n * Extract FastAPI version from requirements files or pyproject.toml\n */\nexport async function getFastAPIVersion(\n options: Pick<WizardRunOptions, 'installDir'>,\n): Promise<string | undefined> {\n const { installDir } = options;\n\n // Check requirements files\n const requirementsFiles = await boundedGlob(\n ['**/requirements*.txt', '**/pyproject.toml', '**/setup.py', '**/Pipfile'],\n {\n cwd: installDir,\n extraIgnore: EXTRA_IGNORE,\n },\n );\n\n for (const reqFile of requirementsFiles) {\n const content = readProjectFile(path.join(installDir, reqFile));\n if (!content) continue;\n\n // Try to extract version from requirements.txt format (fastapi==0.109.0 or fastapi>=0.100)\n const requirementsMatch = content.match(\n /[Ff]ast[Aa][Pp][Ii][=<>~!]+([0-9]+\\.[0-9]+(?:\\.[0-9]+)?)/,\n );\n if (requirementsMatch) {\n return requirementsMatch[1];\n }\n\n // Try to extract from pyproject.toml format\n const pyprojectMatch = content.match(\n /[Ff]ast[Aa][Pp][Ii][\"\\s]*[=<>~!]+\\s*[\"']?([0-9]+\\.[0-9]+(?:\\.[0-9]+)?)/,\n );\n if (pyprojectMatch) {\n return pyprojectMatch[1];\n }\n }\n\n return undefined;\n}\n\n/**\n * Check if app uses FastAPI APIRouter\n */\nasync function hasAPIRouter({\n installDir,\n}: Pick<WizardRunOptions, 'installDir'>): Promise<boolean> {\n const pyFiles = await boundedGlob(['**/*.py'], {\n cwd: installDir,\n extraIgnore: EXTRA_IGNORE,\n limit: SOURCE_PROBE_LIMIT,\n });\n\n for (const pyFile of pyFiles) {\n const content = readProjectFile(path.join(installDir, pyFile));\n if (!content) continue;\n if (\n content.includes('APIRouter(') ||\n content.includes('include_router(') ||\n content.includes('from fastapi import APIRouter')\n ) {\n return true;\n }\n }\n\n return false;\n}\n\n/**\n * Check if app uses Jinja2 templates (fullstack pattern)\n */\nasync function hasTemplates({\n installDir,\n}: Pick<WizardRunOptions, 'installDir'>): Promise<boolean> {\n // Check for Jinja2Templates usage in Python files\n const pyFiles = await boundedGlob(['**/*.py'], {\n cwd: installDir,\n extraIgnore: EXTRA_IGNORE,\n limit: SOURCE_PROBE_LIMIT,\n });\n\n for (const pyFile of pyFiles) {\n const content = readProjectFile(path.join(installDir, pyFile));\n if (!content) continue;\n if (\n content.includes('Jinja2Templates') ||\n content.includes('from fastapi.templating import')\n ) {\n return true;\n }\n }\n\n // Check for templates directory\n const templateFiles = await boundedGlob(['**/templates/**'], {\n cwd: installDir,\n extraIgnore: EXTRA_IGNORE,\n limit: 1,\n });\n\n return templateFiles.length > 0;\n}\n\n/**\n * Detect FastAPI project type\n */\nexport async function getFastAPIProjectType(\n options: WizardRunOptions,\n): Promise<FastAPIProjectType> {\n const { installDir } = options;\n\n // Check for fullstack pattern (templates)\n if (await hasTemplates({ installDir })) {\n getUI().setDetectedFramework('FastAPI fullstack with templates');\n return FastAPIProjectType.FULLSTACK;\n }\n\n // Check for APIRouter (modular structure)\n if (await hasAPIRouter({ installDir })) {\n getUI().setDetectedFramework('FastAPI with APIRouter');\n return FastAPIProjectType.ROUTER;\n }\n\n // Default to standard FastAPI\n getUI().setDetectedFramework('FastAPI');\n return FastAPIProjectType.STANDARD;\n}\n\n/**\n * Get human-readable name for FastAPI project type\n */\nexport function getFastAPIProjectTypeName(\n projectType: FastAPIProjectType,\n): string {\n switch (projectType) {\n case FastAPIProjectType.STANDARD:\n return 'Standard FastAPI';\n case FastAPIProjectType.ROUTER:\n return 'FastAPI with APIRouter';\n case FastAPIProjectType.FULLSTACK:\n return 'FastAPI Fullstack';\n }\n}\n\n/**\n * Find the main FastAPI app file\n */\nexport async function findFastAPIAppFile(\n options: Pick<WizardRunOptions, 'installDir'>,\n): Promise<string | undefined> {\n const { installDir } = options;\n\n // Common FastAPI app file patterns\n const commonPatterns = [\n '**/main.py',\n '**/app.py',\n '**/application.py',\n '**/api.py',\n '**/__init__.py',\n ];\n\n const appFiles = await boundedGlob(commonPatterns, {\n cwd: installDir,\n extraIgnore: EXTRA_IGNORE,\n });\n\n // Look for files with FastAPI() instantiation\n for (const appFile of appFiles) {\n const content = readProjectFile(path.join(installDir, appFile));\n if (!content) continue;\n // Check for FastAPI app instantiation\n if (\n content.includes('FastAPI(') ||\n content.includes('from fastapi import FastAPI')\n ) {\n return appFile;\n }\n }\n\n // If no file with FastAPI() found, check all Python files\n const allPyFiles = await boundedGlob(['**/*.py'], {\n cwd: installDir,\n extraIgnore: EXTRA_IGNORE,\n limit: SOURCE_PROBE_LIMIT,\n });\n\n for (const pyFile of allPyFiles) {\n const content = readProjectFile(path.join(installDir, pyFile));\n if (content?.includes('FastAPI(')) {\n return pyFile;\n }\n }\n\n // Return first common pattern file if exists\n if (appFiles.length > 0) {\n return appFiles[0];\n }\n\n return undefined;\n}\n","/* FastAPI wizard using posthog-agent with PostHog MCP */\nimport type { WizardRunOptions } from '@utils/types';\nimport type { FrameworkConfig } from '@lib/framework-config';\nimport { PYTHON_PACKAGE_INSTALLATION } from '@lib/framework-config';\nimport { detectPythonPackageManagers } from '@lib/detection/package-manager';\nimport { Integration } from '@lib/constants';\nimport {\n getFastAPIVersion,\n getFastAPIProjectType,\n getFastAPIProjectTypeName,\n getFastAPIVersionBucket,\n FastAPIProjectType,\n findFastAPIAppFile,\n} from './utils';\nimport { boundedGlob, readProjectFile } from '@utils/bounded-fs';\nimport * as path from 'node:path';\n\nconst EXTRA_IGNORE = ['**/env/**', '**/.env/**'];\n\n/**\n * FastAPI framework configuration for the universal agent runner\n */\n\nexport const FASTAPI_AGENT_CONFIG: FrameworkConfig = {\n metadata: {\n name: 'FastAPI',\n integration: Integration.fastapi,\n docsUrl: 'https://posthog.com/docs/libraries/python',\n unsupportedVersionDocsUrl: 'https://posthog.com/docs/libraries/python',\n gatherContext: async (options: WizardRunOptions) => {\n const projectType = await getFastAPIProjectType(options);\n const appFile = await findFastAPIAppFile(options);\n return { projectType, appFile };\n },\n },\n\n detection: {\n packageName: 'fastapi',\n packageDisplayName: 'FastAPI',\n usesPackageJson: false,\n getVersion: (_packageJson: any) => {\n // For FastAPI, we don't use package.json. Version is extracted separately\n // from requirements.txt or pyproject.toml in the wizard entry point\n return undefined;\n },\n getVersionBucket: getFastAPIVersionBucket,\n getInstalledVersion: getFastAPIVersion,\n detect: async (options) => {\n const { installDir } = options;\n\n // Note: Django and Flask are checked before FastAPI in INTEGRATION_ORDER,\n // so if we get here, the project is not a Django or Flask project.\n\n // Check for FastAPI in requirements files\n const requirementsFiles = await boundedGlob(\n [\n '**/requirements*.txt',\n '**/pyproject.toml',\n '**/setup.py',\n '**/Pipfile',\n ],\n {\n cwd: installDir,\n extraIgnore: EXTRA_IGNORE,\n },\n );\n\n for (const reqFile of requirementsFiles) {\n const content = readProjectFile(path.join(installDir, reqFile));\n if (!content) continue;\n // Check for fastapi package (case-insensitive)\n // Match \"fastapi\" as a standalone package\n if (\n /^fastapi([<>=~!]|$|\\s)/im.test(content) ||\n /[\"']fastapi[\"']/i.test(content)\n ) {\n return true;\n }\n }\n\n // Check for FastAPI app patterns in Python files\n const pyFiles = await boundedGlob(\n ['**/main.py', '**/app.py', '**/application.py', '**/__init__.py'],\n {\n cwd: installDir,\n extraIgnore: EXTRA_IGNORE,\n },\n );\n\n for (const pyFile of pyFiles) {\n const content = readProjectFile(path.join(installDir, pyFile));\n if (!content) continue;\n if (\n content.includes('from fastapi import') ||\n content.includes('import fastapi') ||\n /FastAPI\\s*\\(/.test(content)\n ) {\n return true;\n }\n }\n\n return false;\n },\n detectPackageManager: detectPythonPackageManagers,\n },\n\n environment: {\n uploadToHosting: false,\n getEnvVars: (apiKey: string, host: string) => ({\n POSTHOG_PROJECT_TOKEN: apiKey,\n POSTHOG_HOST: host,\n }),\n },\n\n analytics: {\n getTags: (context: any) => {\n const projectType = context.projectType as FastAPIProjectType;\n return {\n projectType: projectType || 'unknown',\n };\n },\n },\n\n prompts: {\n packageInstallation: PYTHON_PACKAGE_INSTALLATION,\n projectTypeDetection:\n 'This is a Python/FastAPI project. Look for requirements.txt, pyproject.toml, setup.py, Pipfile, or main.py/app.py to confirm.',\n getAdditionalContextLines: (context: any) => {\n const projectType = context.projectType as FastAPIProjectType;\n const projectTypeName = projectType\n ? getFastAPIProjectTypeName(projectType)\n : 'unknown';\n\n // Map project type to framework ID for MCP docs resource\n const frameworkIdMap: Record<FastAPIProjectType, string> = {\n [FastAPIProjectType.STANDARD]: 'fastapi',\n [FastAPIProjectType.ROUTER]: 'fastapi',\n [FastAPIProjectType.FULLSTACK]: 'fastapi',\n };\n\n const frameworkId = projectType ? frameworkIdMap[projectType] : 'fastapi';\n\n const lines = [\n `Project type: ${projectTypeName}`,\n `Framework docs ID: ${frameworkId} (use posthog://docs/frameworks/${frameworkId} for documentation)`,\n ];\n\n if (context.appFile) {\n lines.push(`App file: ${context.appFile}`);\n }\n\n return lines;\n },\n },\n\n ui: {\n successMessage: 'PostHog integration complete',\n estimatedDurationMinutes: 5,\n getOutroChanges: (context: any) => {\n const projectType = context.projectType as FastAPIProjectType;\n const projectTypeName = projectType\n ? getFastAPIProjectTypeName(projectType)\n : 'FastAPI';\n return [\n `Analyzed your ${projectTypeName} project structure`,\n `Installed the PostHog Python package`,\n `Configured PostHog in your FastAPI application`,\n `Added PostHog initialization with lifespan event handling`,\n ];\n },\n getOutroNextSteps: () => [\n 'Start your FastAPI development server to see PostHog in action',\n 'Visit your PostHog dashboard to see incoming events',\n 'Use posthog.identify() to associate events with users',\n ],\n },\n};\n","import { boundedGlob, readProjectFile } from '@utils/bounded-fs';\nimport { getUI } from '@ui';\nimport type { WizardRunOptions } from '@utils/types';\nimport { createVersionBucket } from '@utils/semver';\nimport * as fs from 'node:fs';\nimport * as path from 'node:path';\n\nexport enum LaravelProjectType {\n STANDARD = 'standard', // Basic Laravel app\n INERTIA = 'inertia', // Inertia.js (Vue/React SPA) - may need JS SDK too\n LIVEWIRE = 'livewire', // Livewire (reactive components, includes Filament)\n}\n\nconst EXTRA_IGNORE = [\n '**/storage/**',\n '**/bootstrap/cache/**',\n '**/.phpunit.cache/**',\n '**/public/build/**',\n '**/public/hot/**',\n];\n\n/** Content probes read at most this many files, one in memory at a time. */\nconst SOURCE_PROBE_LIMIT = 200;\n\n/**\n * Get Laravel version bucket for analytics\n */\nexport const getLaravelVersionBucket = createVersionBucket();\n\n/**\n * Read and parse composer.json\n */\nexport function getComposerJson(\n options: Pick<WizardRunOptions, 'installDir'>,\n): Record<string, any> | undefined {\n const { installDir } = options;\n\n const composerPath = path.join(installDir, 'composer.json');\n try {\n const content = fs.readFileSync(composerPath, 'utf-8');\n return JSON.parse(content);\n } catch {\n return undefined;\n }\n}\n\n/**\n * Check if a package is installed (present in composer.json)\n */\nfunction hasComposerPackage(\n packageName: string,\n options: Pick<WizardRunOptions, 'installDir'>,\n): boolean {\n const composer = getComposerJson(options);\n if (!composer) return false;\n\n return !!(\n composer.require?.[packageName] || composer['require-dev']?.[packageName]\n );\n}\n\n/**\n * Extract version for a package from composer.json\n */\nfunction getComposerPackageVersion(\n packageName: string,\n options: Pick<WizardRunOptions, 'installDir'>,\n): string | undefined {\n const composer = getComposerJson(options);\n if (!composer) return undefined;\n\n const version =\n composer.require?.[packageName] || composer['require-dev']?.[packageName];\n if (version) {\n // Clean version string (remove ^, ~, >=, etc.)\n return version.replace(/^[\\^~>=<]+/, '');\n }\n\n return undefined;\n}\n\n/**\n * Check if a pattern exists in PHP source files\n */\nasync function hasLaravelCodePattern(\n pattern: RegExp | string,\n options: Pick<WizardRunOptions, 'installDir'>,\n filePatterns: string[] = ['**/*.php'],\n): Promise<boolean> {\n const { installDir } = options;\n\n const phpFiles = await boundedGlob(filePatterns, {\n cwd: installDir,\n extraIgnore: EXTRA_IGNORE,\n limit: SOURCE_PROBE_LIMIT,\n });\n\n const searchPattern =\n typeof pattern === 'string' ? new RegExp(pattern) : pattern;\n\n for (const phpFile of phpFiles) {\n const content = readProjectFile(path.join(installDir, phpFile));\n if (!content) continue;\n if (searchPattern.test(content)) return true;\n }\n\n return false;\n}\n\n/**\n * Get Laravel version from composer.json\n */\nexport function getLaravelVersion(\n options: Pick<WizardRunOptions, 'installDir'>,\n): string | undefined {\n return getComposerPackageVersion('laravel/framework', options);\n}\n\n/**\n * Get human-readable name for Laravel project type\n */\nexport function getLaravelProjectTypeName(\n projectType: LaravelProjectType,\n): string {\n switch (projectType) {\n case LaravelProjectType.STANDARD:\n return 'Standard Laravel';\n case LaravelProjectType.INERTIA:\n return 'Laravel with Inertia.js';\n case LaravelProjectType.LIVEWIRE:\n return 'Laravel with Livewire';\n default:\n return 'Laravel';\n }\n}\n\n/**\n * Check for Inertia.js\n */\nasync function hasInertia(\n options: Pick<WizardRunOptions, 'installDir'>,\n): Promise<boolean> {\n return (\n hasComposerPackage('inertiajs/inertia-laravel', options) ||\n (await hasLaravelCodePattern(/Inertia::render|inertia\\(/, options))\n );\n}\n\n/**\n * Check for Livewire\n */\nasync function hasLivewire(\n options: Pick<WizardRunOptions, 'installDir'>,\n): Promise<boolean> {\n return (\n hasComposerPackage('livewire/livewire', options) ||\n (await hasLaravelCodePattern(/extends\\s+Component|@livewire/, options))\n );\n}\n\n/**\n * Detect Laravel project type\n */\nexport async function getLaravelProjectType(\n options: WizardRunOptions,\n): Promise<LaravelProjectType> {\n // Check for SPA/Reactive frameworks (important to detect - affects SDK needs)\n if (await hasInertia(options)) {\n getUI().setDetectedFramework('Laravel with Inertia.js');\n return LaravelProjectType.INERTIA;\n }\n if (await hasLivewire(options)) {\n getUI().setDetectedFramework('Laravel with Livewire');\n return LaravelProjectType.LIVEWIRE;\n }\n\n // Default to standard\n getUI().setDetectedFramework('Laravel');\n return LaravelProjectType.STANDARD;\n}\n\n/**\n * Find the main service provider file\n */\nexport async function findLaravelServiceProvider(\n options: Pick<WizardRunOptions, 'installDir'>,\n): Promise<string | undefined> {\n const { installDir } = options;\n\n // Look for AppServiceProvider first (most common place for setup)\n const appServiceProvider = path.join(\n installDir,\n 'app/Providers/AppServiceProvider.php',\n );\n\n if (fs.existsSync(appServiceProvider)) {\n return 'app/Providers/AppServiceProvider.php';\n }\n\n // Fall back to searching for any service provider\n const providers = await boundedGlob(\n ['**/app/Providers/*ServiceProvider.php'],\n {\n cwd: installDir,\n extraIgnore: EXTRA_IGNORE,\n limit: 1,\n },\n );\n\n return providers[0];\n}\n\n/**\n * Find the bootstrap file (differs between Laravel versions)\n */\nexport function findLaravelBootstrapFile(\n options: Pick<WizardRunOptions, 'installDir'>,\n): string | undefined {\n const { installDir } = options;\n\n // Laravel 11+ uses bootstrap/app.php with new structure\n const bootstrapApp = path.join(installDir, 'bootstrap/app.php');\n if (fs.existsSync(bootstrapApp)) {\n return 'bootstrap/app.php';\n }\n\n // Older Laravel uses app/Http/Kernel.php\n const httpKernel = path.join(installDir, 'app/Http/Kernel.php');\n if (fs.existsSync(httpKernel)) {\n return 'app/Http/Kernel.php';\n }\n\n return undefined;\n}\n\n/**\n * Detect Laravel version structure for configuration guidance\n */\nexport function detectLaravelStructure(\n options: Pick<WizardRunOptions, 'installDir'>,\n): 'legacy' | 'modern' | 'latest' {\n const version = getLaravelVersion(options);\n if (!version) return 'modern';\n\n try {\n const majorVersion = parseInt(version.split('.')[0], 10);\n if (majorVersion >= 11) return 'latest'; // Laravel 11+ (new structure)\n if (majorVersion >= 9) return 'modern'; // Laravel 9-10\n return 'legacy'; // Laravel 8 and below\n } catch {\n return 'modern';\n }\n}\n","/* Laravel wizard using posthog-agent with PostHog MCP */\nimport type { WizardRunOptions } from '@utils/types';\nimport type { FrameworkConfig } from '@lib/framework-config';\nimport { composerPackageManager } from '@lib/detection/package-manager';\nimport { Integration } from '@lib/constants';\nimport { boundedGlob } from '@utils/bounded-fs';\nimport * as fs from 'node:fs';\nimport * as path from 'node:path';\nimport {\n getLaravelVersion,\n getLaravelProjectType,\n getLaravelProjectTypeName,\n getLaravelVersionBucket,\n LaravelProjectType,\n findLaravelServiceProvider,\n findLaravelBootstrapFile,\n detectLaravelStructure,\n} from './utils';\n\ntype LaravelContext = {\n projectType?: LaravelProjectType;\n serviceProvider?: string;\n bootstrapFile?: string;\n laravelStructure?: string;\n};\n\nexport const LARAVEL_AGENT_CONFIG: FrameworkConfig<LaravelContext> = {\n metadata: {\n name: 'Laravel',\n integration: Integration.laravel,\n docsUrl: 'https://posthog.com/docs/libraries/php',\n unsupportedVersionDocsUrl: 'https://posthog.com/docs/libraries/php',\n gatherContext: async (options: WizardRunOptions) => {\n const projectType = await getLaravelProjectType(options);\n const serviceProvider = await findLaravelServiceProvider(options);\n const bootstrapFile = findLaravelBootstrapFile(options);\n const laravelStructure = detectLaravelStructure(options);\n\n return {\n projectType,\n serviceProvider,\n bootstrapFile,\n laravelStructure,\n };\n },\n },\n\n detection: {\n packageName: 'laravel/framework',\n packageDisplayName: 'Laravel',\n usesPackageJson: false,\n getVersion: () => undefined,\n getVersionBucket: getLaravelVersionBucket,\n minimumVersion: '9.0.0',\n getInstalledVersion: (options: WizardRunOptions) =>\n Promise.resolve(getLaravelVersion(options)),\n detect: async (options) => {\n const { installDir } = options;\n\n const artisanPath = path.join(installDir, 'artisan');\n if (fs.existsSync(artisanPath)) {\n try {\n const content = fs.readFileSync(artisanPath, 'utf-8');\n if (content.includes('Laravel') || content.includes('Artisan')) {\n return true;\n }\n } catch {\n // Continue to other checks\n }\n }\n\n const composerPath = path.join(installDir, 'composer.json');\n if (fs.existsSync(composerPath)) {\n try {\n const content = fs.readFileSync(composerPath, 'utf-8');\n const composer = JSON.parse(content);\n if (\n composer.require?.['laravel/framework'] ||\n composer['require-dev']?.['laravel/framework']\n ) {\n return true;\n }\n } catch {\n // Continue to other checks\n }\n }\n\n const hasLaravelStructure = await boundedGlob(\n ['**/bootstrap/app.php', '**/app/Http/Kernel.php'],\n { cwd: installDir, limit: 1 },\n );\n\n return hasLaravelStructure.length > 0;\n },\n detectPackageManager: composerPackageManager,\n },\n\n environment: {\n uploadToHosting: false,\n getEnvVars: (apiKey: string, host: string) => ({\n POSTHOG_PROJECT_TOKEN: apiKey,\n POSTHOG_HOST: host,\n }),\n },\n\n analytics: {\n getTags: (context) => ({\n projectType: context.projectType || 'unknown',\n laravelStructure: context.laravelStructure || 'unknown',\n }),\n },\n\n prompts: {\n projectTypeDetection:\n 'This is a PHP/Laravel project. Look for composer.json, artisan CLI, and app/ directory structure to confirm. Check for Laravel-specific packages like laravel/framework.',\n packageInstallation:\n 'Use Composer to install packages. Run `composer require posthog/posthog-php` without pinning a specific version.',\n getAdditionalContextLines: (context) => {\n const projectTypeName = context.projectType\n ? getLaravelProjectTypeName(context.projectType)\n : 'unknown';\n\n const lines = [\n `Project type: ${projectTypeName}`,\n `Framework docs ID: php (use posthog://docs/frameworks/php for documentation)`,\n `Laravel structure: ${context.laravelStructure} (affects where to add configuration)`,\n ];\n\n if (context.serviceProvider) {\n lines.push(`Service provider: ${context.serviceProvider}`);\n }\n\n if (context.bootstrapFile) {\n lines.push(`Bootstrap file: ${context.bootstrapFile}`);\n }\n\n // Add Laravel-specific guidance based on version structure\n if (context.laravelStructure === 'latest') {\n lines.push(\n 'Note: Laravel 11+ uses simplified bootstrap/app.php for middleware and providers',\n );\n } else {\n lines.push(\n 'Note: Use app/Http/Kernel.php for middleware, app/Providers for service providers',\n );\n }\n\n return lines;\n },\n },\n\n ui: {\n successMessage: 'PostHog integration complete',\n estimatedDurationMinutes: 5,\n getOutroChanges: (context) => {\n const projectTypeName = context.projectType\n ? getLaravelProjectTypeName(context.projectType)\n : 'Laravel';\n\n const changes = [\n `Analyzed your ${projectTypeName} project structure`,\n `Installed the PostHog PHP package via Composer`,\n `Configured PostHog in your Laravel application`,\n ];\n\n if (context.laravelStructure === 'latest') {\n changes.push('Added PostHog initialization to bootstrap/app.php');\n } else {\n changes.push('Created a PostHog service provider for initialization');\n }\n\n if (context.projectType === LaravelProjectType.INERTIA) {\n changes.push('Configured PostHog to work with Inertia.js');\n }\n\n if (context.projectType === LaravelProjectType.LIVEWIRE) {\n changes.push('Configured PostHog to work with Livewire');\n }\n\n return changes;\n },\n getOutroNextSteps: () => [\n 'Start your Laravel development server with `php artisan serve`',\n 'Visit your PostHog dashboard to see incoming events',\n 'Use PostHog::capture() to track custom events',\n 'Use PostHog::identify() to associate events with users',\n ],\n },\n};\n","/* SvelteKit wizard using posthog-agent with PostHog MCP */\nimport type { FrameworkConfig } from '@lib/framework-config';\nimport { detectNodePackageManagers } from '@lib/detection/package-manager';\nimport { Integration } from '@lib/constants';\nimport {\n getDeclaredVersion,\n hasDeclaredDependency,\n type PackageJson,\n} from '@utils/package-json';\nimport { tryGetPackageJson } from '@utils/setup-utils';\n\ntype SvelteKitContext = Record<string, unknown>;\n\nexport const SVELTEKIT_AGENT_CONFIG: FrameworkConfig<SvelteKitContext> = {\n metadata: {\n name: 'SvelteKit',\n integration: Integration.sveltekit,\n docsUrl: 'https://posthog.com/docs/libraries/svelte',\n additionalMcpServers: {\n svelte: { url: 'https://mcp.svelte.dev/mcp' },\n },\n },\n\n detection: {\n packageName: '@sveltejs/kit',\n packageDisplayName: 'SvelteKit',\n getVersion: (packageJson: unknown) =>\n getDeclaredVersion('@sveltejs/kit', packageJson as PackageJson),\n detect: async (options) => {\n const packageJson = await tryGetPackageJson(options);\n return packageJson\n ? hasDeclaredDependency('@sveltejs/kit', packageJson)\n : false;\n },\n minimumVersion: '2.0.0',\n detectPackageManager: detectNodePackageManagers,\n },\n\n environment: {\n uploadToHosting: true,\n getEnvVars: (apiKey: string, host: string) => ({\n PUBLIC_POSTHOG_PROJECT_TOKEN: apiKey,\n PUBLIC_POSTHOG_HOST: host,\n }),\n },\n\n analytics: {\n getTags: () => ({}),\n },\n\n prompts: {\n projectTypeDetection:\n 'This is a JavaScript/TypeScript project using SvelteKit. Look for package.json, svelte.config.js, and lockfiles (package-lock.json, yarn.lock, pnpm-lock.yaml, bun.lockb) to confirm.',\n getAdditionalContextLines: () => [\n 'Framework docs ID: sveltekit (use posthog://docs/frameworks/sveltekit for documentation)',\n ],\n },\n\n ui: {\n successMessage: 'PostHog integration complete',\n estimatedDurationMinutes: 8,\n getOutroChanges: () => [\n 'Analyzed your SvelteKit project structure',\n 'Created and configured PostHog initializers',\n 'Integrated PostHog into your application',\n ],\n getOutroNextSteps: () => [\n 'Start your development server to see PostHog in action',\n 'Visit your PostHog dashboard to see incoming events',\n ],\n },\n};\n","/* Flutter wizard using posthog-agent with PostHog MCP */\nimport type { WizardRunOptions } from '@utils/types';\nimport type { FrameworkConfig } from '@lib/framework-config';\nimport { Integration } from '@lib/constants';\nimport * as fs from 'node:fs';\nimport * as path from 'node:path';\nimport { pubPackageManager } from '@lib/detection/package-manager';\n\n/** Platform subtrees `flutter create` scaffolds; each needs its own setup notes. */\nconst FLUTTER_PLATFORM_DIRS = [\n 'android',\n 'ios',\n 'web',\n 'macos',\n 'linux',\n 'windows',\n] as const;\n\ntype FlutterContext = {\n platforms?: string[];\n};\n\nfunction readPubspec(installDir: string): string | undefined {\n const pubspecPath = path.join(installDir, 'pubspec.yaml');\n if (!fs.existsSync(pubspecPath)) return undefined;\n return fs.readFileSync(pubspecPath, 'utf-8');\n}\n\nexport const FLUTTER_AGENT_CONFIG: FrameworkConfig<FlutterContext> = {\n metadata: {\n name: 'Flutter',\n integration: Integration.flutter,\n docsUrl: 'https://posthog.com/docs/libraries/flutter',\n gatherContext: (options: WizardRunOptions) => {\n const platforms = FLUTTER_PLATFORM_DIRS.filter((dir) =>\n fs.existsSync(path.join(options.installDir, dir)),\n );\n return Promise.resolve({ platforms });\n },\n },\n\n detection: {\n packageName: 'posthog_flutter',\n packageDisplayName: 'Flutter',\n usesPackageJson: false,\n getVersion: () => undefined,\n detectPackageManager: pubPackageManager,\n // A pubspec.yaml alone is any Dart project; depending on the Flutter SDK\n // (`sdk: flutter`) is what makes it a Flutter app. Anchored to a key/value\n // line so comments (`# sdk: flutter`) don't match.\n detect: (options) => {\n const pubspec = readPubspec(options.installDir);\n return Promise.resolve(/^\\s*sdk:\\s*flutter\\s*$/m.test(pubspec ?? ''));\n },\n },\n\n environment: {\n uploadToHosting: false,\n getEnvVars: (apiKey: string, host: string) => ({\n POSTHOG_PROJECT_TOKEN: apiKey,\n POSTHOG_HOST: host,\n }),\n },\n\n analytics: {\n getTags: (context) => ({\n ...(context.platforms?.length\n ? { platforms: context.platforms.join(',') }\n : {}),\n }),\n },\n\n prompts: {\n projectTypeDetection:\n 'This is a Flutter project. Look for pubspec.yaml declaring a dependency on the Flutter SDK (flutter: sdk: flutter) and a lib/ directory with Dart source files to confirm.',\n packageInstallation:\n 'Add the PostHog Flutter SDK with `flutter pub add posthog_flutter`. Do not edit pubspec.yaml by hand; the pub tool updates it and resolves the version automatically.',\n getAdditionalContextLines: (context) => {\n const lines = [\n 'Framework docs ID: flutter (use posthog://docs/frameworks/flutter for documentation)',\n 'Prefer manual initialization in Dart (PostHogConfig + Posthog().setup) over the platform auto-init so configuration lives in one place; when doing so, disable auto-init in the Android manifest and iOS Info.plist per the docs.',\n ];\n\n if (context.platforms?.length) {\n lines.push(\n `Enabled target platforms: ${context.platforms.join(\n ', ',\n )}. Apply the platform-specific setup steps from the docs for each (e.g. AndroidManifest.xml on Android, Info.plist on iOS/macOS, the JS snippet in web/index.html for web).`,\n );\n }\n\n return lines;\n },\n },\n\n ui: {\n successMessage: 'PostHog integration complete',\n estimatedDurationMinutes: 5,\n getOutroChanges: () => [\n 'Analyzed your Flutter project structure',\n 'Added the posthog_flutter SDK to your pubspec',\n 'Configured PostHog initialization',\n 'Added event capture and user identification',\n ],\n getOutroNextSteps: () => [\n 'Run your app to see PostHog in action',\n 'Visit your PostHog dashboard to see incoming events',\n 'Check out the PostHog Flutter docs for session replay, feature flags, and more',\n ],\n },\n};\n","import type { WizardRunOptions } from '@utils/types';\nimport { boundedGlob, readProjectFile } from '@utils/bounded-fs';\nimport fg from 'fast-glob';\nimport * as fs from 'node:fs';\nimport * as path from 'node:path';\n\nconst EXTRA_IGNORE = ['**/.build/**', '**/*.xcodeproj/**'];\n\n/** Content probes read at most this many files, one in memory at a time. */\nconst SOURCE_PROBE_LIMIT = 200;\n\nexport enum SwiftProjectType {\n SWIFTUI = 'swiftui',\n UIKIT = 'uikit',\n SPM = 'spm',\n}\n\nexport function getSwiftProjectTypeName(projectType: SwiftProjectType): string {\n switch (projectType) {\n case SwiftProjectType.SWIFTUI:\n return 'SwiftUI';\n case SwiftProjectType.UIKIT:\n return 'UIKit';\n case SwiftProjectType.SPM:\n return 'Swift Package';\n }\n}\n\nexport async function detectSwiftProjectType(\n options: WizardRunOptions,\n): Promise<SwiftProjectType | undefined> {\n const { installDir } = options;\n\n // Pure SPM package: Package.swift with no Xcode project/workspace and no\n // XcodeGen spec (project.yml generates an app's .xcodeproj, often\n // uncommitted) — same app signals as the framework detect glob.\n const hasPackageSwift = fs.existsSync(path.join(installDir, 'Package.swift'));\n const hasXcodeGenSpec = fs.existsSync(path.join(installDir, 'project.yml'));\n const xcodeProjects = await fg('*.{xcodeproj,xcworkspace}', {\n cwd: installDir,\n onlyDirectories: true,\n });\n\n if (hasPackageSwift && xcodeProjects.length === 0 && !hasXcodeGenSpec) {\n return SwiftProjectType.SPM;\n }\n\n // Check Swift source files for SwiftUI vs UIKit imports\n const swiftFiles = await boundedGlob('**/*.swift', {\n cwd: installDir,\n extraIgnore: EXTRA_IGNORE,\n limit: SOURCE_PROBE_LIMIT,\n });\n\n let hasSwiftUI = false;\n let hasUIKit = false;\n\n for (const file of swiftFiles) {\n const content = readProjectFile(path.join(installDir, file));\n if (!content) continue;\n if (content.includes('import SwiftUI')) {\n hasSwiftUI = true;\n }\n if (content.includes('import UIKit')) {\n hasUIKit = true;\n }\n }\n\n if (hasSwiftUI) return SwiftProjectType.SWIFTUI;\n if (hasUIKit) return SwiftProjectType.UIKIT;\n\n return undefined;\n}\n","/* Swift wizard using posthog-agent with PostHog MCP */\nimport type { WizardRunOptions } from '@utils/types';\nimport type { FrameworkConfig } from '@lib/framework-config';\nimport { swiftPackageManager } from '@lib/detection/package-manager';\nimport { Integration } from '@lib/constants';\nimport { boundedGlob } from '@utils/bounded-fs';\nimport fg from 'fast-glob';\nimport * as fs from 'node:fs';\nimport * as path from 'node:path';\nimport {\n detectSwiftProjectType,\n getSwiftProjectTypeName,\n SwiftProjectType,\n} from './utils';\n\ntype SwiftContext = {\n projectType?: SwiftProjectType;\n};\n\nexport const SWIFT_AGENT_CONFIG: FrameworkConfig<SwiftContext> = {\n metadata: {\n name: 'Swift (iOS/macOS)',\n integration: Integration.swift,\n docsUrl: 'https://posthog.com/docs/libraries/ios',\n preRunNotice:\n 'Please close the Xcode project before proceeding. Xcode may overwrite changes the wizard makes to project files.',\n gatherContext: async (options: WizardRunOptions) => {\n const projectType = await detectSwiftProjectType(options);\n return { projectType };\n },\n },\n\n detection: {\n packageName: 'posthog-ios',\n packageDisplayName: 'Swift',\n usesPackageJson: false,\n getVersion: () => undefined,\n detect: async (options) => {\n const { installDir } = options;\n\n // Xcode project/workspace, or an XcodeGen `project.yml` (the generated\n // .xcodeproj is often uncommitted).\n const xcodeProjects = await fg('*.{xcodeproj,xcworkspace}', {\n cwd: installDir,\n onlyDirectories: true,\n });\n const hasXcodeGenSpec = fs.existsSync(\n path.join(installDir, 'project.yml'),\n );\n\n if (xcodeProjects.length > 0 || hasXcodeGenSpec) {\n // Verify it contains Swift source files\n const swiftFiles = await boundedGlob('**/*.swift', {\n cwd: installDir,\n extraIgnore: ['**/.build/**', '**/*.xcodeproj/**'],\n limit: 1,\n });\n if (swiftFiles.length > 0) {\n return true;\n }\n }\n\n // Check for Swift Package Manager project\n const packageSwiftPath = path.join(installDir, 'Package.swift');\n if (fs.existsSync(packageSwiftPath)) {\n return true;\n }\n\n return false;\n },\n detectPackageManager: swiftPackageManager,\n },\n\n environment: {\n uploadToHosting: false,\n getEnvVars: (apiKey: string, host: string) => ({\n POSTHOG_PROJECT_TOKEN: apiKey,\n POSTHOG_HOST: host,\n }),\n },\n\n analytics: {\n getTags: (context) => ({\n projectType: context.projectType || 'unknown',\n }),\n },\n\n prompts: {\n projectTypeDetection:\n 'This is a Swift project. Look for .xcodeproj directories, Package.swift, and .swift source files to confirm. Check for SwiftUI or UIKit imports to determine the UI framework.',\n packageInstallation:\n 'Add the posthog-ios package via Swift Package Manager. For Xcode projects, add XCRemoteSwiftPackageReference and XCSwiftPackageProductDependency to the .pbxproj file. For Swift packages, add the dependency to Package.swift.',\n getAdditionalContextLines: (context) => {\n const projectTypeName = context.projectType\n ? getSwiftProjectTypeName(context.projectType)\n : 'unknown';\n\n const lines = [\n `Project type: ${projectTypeName}`,\n `Framework docs ID: swift (use posthog://docs/frameworks/swift for documentation)`,\n ];\n\n return lines;\n },\n },\n\n ui: {\n successMessage: 'PostHog integration complete',\n estimatedDurationMinutes: 5,\n getOutroChanges: (context) => {\n const projectTypeName = context.projectType\n ? getSwiftProjectTypeName(context.projectType)\n : 'Swift';\n\n const changes = [\n `Analyzed your ${projectTypeName} project structure`,\n `Added the PostHog iOS SDK via Swift Package Manager`,\n `Configured PostHog initialization in your app entry point`,\n `Added event capture and user identification`,\n ];\n\n return changes;\n },\n getOutroNextSteps: () => [\n 'Set POSTHOG_PROJECT_TOKEN and POSTHOG_HOST in your Xcode scheme environment variables',\n 'Build and run your app to see PostHog in action',\n 'Visit your PostHog dashboard to see incoming events',\n ],\n },\n};\n","/* Kotlin Multiplatform (KMP) wizard using posthog-agent with PostHog MCP */\nimport type { FrameworkConfig } from '../../lib/framework-config';\nimport { Integration } from '../../lib/constants';\nimport { gradlePackageManager } from '../../lib/detection/package-manager';\nimport { boundedGlob, readProjectFile } from '@utils/bounded-fs';\nimport * as path from 'node:path';\n\nexport const KMP_AGENT_CONFIG: FrameworkConfig = {\n metadata: {\n name: 'Kotlin Multiplatform',\n integration: Integration.kmp,\n beta: true,\n docsUrl: 'https://posthog.com/docs/libraries/kmp',\n preRunNotice:\n 'The PostHog Kotlin Multiplatform SDK is in early access (0.x pre-release). The API may change between minor versions.',\n },\n\n detection: {\n packageName: 'posthog-kmp',\n packageDisplayName: 'Kotlin Multiplatform',\n usesPackageJson: false,\n getVersion: () => undefined,\n detectPackageManager: gradlePackageManager,\n // KMP is detected before Android/Swift because a KMP project also looks like\n // an Android and/or Swift project. Detection therefore requires the Kotlin\n // Multiplatform Gradle plugin or a `commonMain` source set — signals that a\n // plain Android or Swift project does not have.\n detect: async (options) => {\n const { installDir } = options;\n\n // Strategy 1: a Gradle build file that applies the Kotlin Multiplatform plugin.\n const buildFiles = await boundedGlob(\n ['**/build.gradle', '**/build.gradle.kts'],\n { cwd: installDir },\n );\n\n for (const file of buildFiles) {\n const content = readProjectFile(path.join(installDir, file));\n if (!content) continue;\n if (\n content.includes('kotlin(\"multiplatform\")') ||\n content.includes('org.jetbrains.kotlin.multiplatform') ||\n content.includes('kotlin-multiplatform')\n ) {\n return true;\n }\n }\n\n // Strategy 2: a KMP `commonMain` source set exists.\n const commonMain = await boundedGlob('**/src/commonMain/**', {\n cwd: installDir,\n limit: 1,\n });\n\n return commonMain.length > 0;\n },\n },\n\n environment: {\n uploadToHosting: false,\n getEnvVars: (apiKey: string, host: string) => ({\n POSTHOG_PROJECT_TOKEN: apiKey,\n POSTHOG_HOST: host,\n }),\n },\n\n analytics: {\n getTags: () => ({}),\n },\n\n prompts: {\n projectTypeDetection:\n 'This is a Kotlin Multiplatform (KMP) project. Look for a build.gradle.kts (or build.gradle) that applies the Kotlin Multiplatform plugin (kotlin(\"multiplatform\") or org.jetbrains.kotlin.multiplatform) and a shared module with a src/commonMain source set.',\n packageInstallation:\n 'Add the PostHog KMP SDK to the shared module\\'s commonMain dependencies in build.gradle.kts: within the kotlin { sourceSets { ... } } block, add implementation(\"com.posthog:posthog-kmp:<VERSION>\") to commonMain.dependencies. Match the existing dependency format (Groovy vs Kotlin DSL).',\n getAdditionalContextLines: () => [\n 'Framework docs ID: kmp (use posthog://docs/frameworks/kmp for documentation)',\n 'Initialize once, early in the app lifecycle, from shared code. All PostHog APIs live in the com.posthog.kmp package.',\n 'Setup call: PostHog.setup(config = PostHogConfig(apiKey = \"<POSTHOG_PROJECT_TOKEN>\", host = \"<POSTHOG_HOST>\"), context = PostHogContext())',\n 'PostHogContext is platform-specific: on Android pass the Application via PostHogContext(application); on iOS and Web use the no-argument PostHogContext().',\n 'Imports: com.posthog.kmp.PostHog, com.posthog.kmp.PostHogConfig, com.posthog.kmp.PostHogContext.',\n ],\n },\n\n ui: {\n successMessage: 'PostHog integration complete',\n estimatedDurationMinutes: 5,\n getOutroChanges: () => [\n 'Analyzed your Kotlin Multiplatform project structure',\n 'Added the PostHog KMP SDK to your shared module',\n 'Configured PostHog initialization in your shared code',\n 'Added event capture and user identification',\n ],\n getOutroNextSteps: () => [\n 'Wire up the platform-specific PostHogContext for each target (Android/iOS/Web)',\n 'Build and run your app to see PostHog in action',\n 'Visit your PostHog dashboard to see incoming events',\n 'Check out the PostHog KMP docs for feature flags, session replay, and more',\n ],\n },\n};\n","import type { WizardRunOptions } from '@utils/types';\nimport { createVersionBucket } from '@utils/semver';\nimport { boundedGlob, readProjectFile } from '@utils/bounded-fs';\nimport * as fs from 'node:fs';\nimport * as path from 'node:path';\n\n/**\n * Extract minSdk from the app-level build.gradle(.kts).\n * Returns the value as a semver-like string (e.g. \"24\" from minSdk = 24).\n */\nexport async function getMinSdkVersion(\n options: WizardRunOptions,\n): Promise<string | undefined> {\n const { installDir } = options;\n\n const buildFiles = await boundedGlob(\n ['**/build.gradle', '**/build.gradle.kts'],\n { cwd: installDir },\n );\n\n for (const file of buildFiles) {\n const content = readProjectFile(path.join(installDir, file));\n if (!content) continue;\n // Match: minSdk = 24, minSdkVersion 21, minSdkVersion = 21\n const match = content.match(/minSdk(?:Version)?\\s*=?\\s*(\\d+)/);\n if (match) return match[1];\n }\n\n return undefined;\n}\n\nexport const getKotlinVersionBucket = createVersionBucket();\n\n/**\n * Read the root or app-level build.gradle(.kts) and extract the Kotlin version.\n */\nexport function getKotlinVersion(\n options: WizardRunOptions,\n): string | undefined {\n const { installDir } = options;\n\n for (const name of [\n 'build.gradle',\n 'build.gradle.kts',\n 'gradle/libs.versions.toml',\n ]) {\n const filePath = path.join(installDir, name);\n if (!fs.existsSync(filePath)) continue;\n\n const content = fs.readFileSync(filePath, 'utf-8');\n\n // build.gradle: kotlinVersion = \"2.0.21\" or ext.kotlin_version = '1.9.0'\n const match = content.match(/kotlin[_-]?[Vv]ersion\\s*=\\s*[\"']([^\"']+)[\"']/);\n if (match) return match[1];\n\n // libs.versions.toml: kotlin = \"2.0.21\"\n const tomlMatch = content.match(/^kotlin\\s*=\\s*[\"']([^\"']+)[\"']/m);\n if (tomlMatch) return tomlMatch[1];\n }\n\n return undefined;\n}\n","/* Android (Kotlin) wizard using posthog-agent with PostHog MCP */\nimport type { WizardRunOptions } from '@utils/types';\nimport type { FrameworkConfig } from '@lib/framework-config';\nimport { Integration } from '@lib/constants';\nimport { boundedGlob } from '@utils/bounded-fs';\nimport * as fs from 'node:fs';\nimport * as path from 'node:path';\nimport {\n getKotlinVersion,\n getKotlinVersionBucket,\n getMinSdkVersion,\n} from './utils';\nimport { gradlePackageManager } from '@lib/detection/package-manager';\n\ntype AndroidContext = {\n kotlinVersion?: string;\n};\n\nexport const ANDROID_AGENT_CONFIG: FrameworkConfig<AndroidContext> = {\n metadata: {\n name: 'Android (Kotlin)',\n integration: Integration.android,\n docsUrl: 'https://posthog.com/docs/libraries/android',\n gatherContext: (options: WizardRunOptions) => {\n const kotlinVersion = getKotlinVersion(options);\n return Promise.resolve({ kotlinVersion });\n },\n },\n\n detection: {\n packageName: 'posthog-android',\n packageDisplayName: 'Android (Kotlin)',\n usesPackageJson: false,\n getVersion: () => undefined,\n getVersionBucket: (version: string) => getKotlinVersionBucket(version),\n // This is actually pretty high for a minimum, but android apis aren't super stable.\n minimumVersion: '21.0.0',\n getInstalledVersion: (options: WizardRunOptions) =>\n getMinSdkVersion(options),\n detectPackageManager: gradlePackageManager,\n detect: async (options) => {\n const { installDir } = options;\n\n // pubspec.yaml means Flutter — its android/ subtree would match below.\n if (fs.existsSync(path.join(installDir, 'pubspec.yaml'))) {\n return false;\n }\n\n // Strategy 1: Check for build.gradle(.kts) with Android plugin\n for (const name of ['build.gradle', 'build.gradle.kts']) {\n const buildGradlePath = path.join(installDir, name);\n if (fs.existsSync(buildGradlePath)) {\n const content = fs.readFileSync(buildGradlePath, 'utf-8');\n if (\n content.includes('com.android.application') ||\n content.includes('com.android.library') ||\n content.includes('com.android.tools.build:gradle')\n ) {\n return true;\n }\n }\n }\n\n // Strategy 2: Check for AndroidManifest.xml with Kotlin source files\n // This could be an issue if we have Flutter in the mix, but we'll figure that out later.\n const manifestFiles = await boundedGlob('**/AndroidManifest.xml', {\n cwd: installDir,\n limit: 1,\n });\n\n if (manifestFiles.length > 0) {\n const kotlinFiles = await boundedGlob('**/*.kt', {\n cwd: installDir,\n limit: 1,\n });\n if (kotlinFiles.length > 0) {\n return true;\n }\n }\n\n return false;\n },\n },\n\n environment: {\n uploadToHosting: false,\n getEnvVars: (apiKey: string, host: string) => ({\n POSTHOG_PROJECT_TOKEN: apiKey,\n POSTHOG_HOST: host,\n }),\n },\n\n analytics: {\n getTags: (context) => ({\n ...(context.kotlinVersion\n ? { kotlinVersion: getKotlinVersionBucket(context.kotlinVersion) }\n : {}),\n }),\n },\n\n prompts: {\n projectTypeDetection:\n 'This is an Android/Kotlin project. Look for build.gradle or build.gradle.kts files, AndroidManifest.xml, and Kotlin source files (.kt) to confirm.',\n packageInstallation:\n 'Add the PostHog Android SDK dependency to the app-level build.gradle(.kts) file. Use implementation(\"com.posthog:posthog-android:<VERSION>\"). Check the existing dependency format (Groovy vs Kotlin DSL) and match it.',\n getAdditionalContextLines: (context) => {\n const lines = [\n `Framework docs ID: android (use posthog://docs/frameworks/android for documentation)`,\n ];\n\n if (context.kotlinVersion) {\n lines.push(`Kotlin version: ${context.kotlinVersion}`);\n }\n\n return lines;\n },\n },\n\n ui: {\n successMessage: 'PostHog integration complete',\n estimatedDurationMinutes: 5,\n getOutroChanges: () => [\n `Analyzed your Android project structure`,\n `Added the PostHog Android SDK dependency`,\n `Configured PostHog initialization in your Application class`,\n `Added event capture and user identification`,\n ],\n getOutroNextSteps: () => [\n 'Build and run your app to see PostHog in action',\n 'Visit your PostHog dashboard to see incoming events',\n 'Check out the PostHog Android docs for advanced features like feature flags and session replay',\n ],\n },\n};\n","import fg from 'fast-glob';\nimport { getUI } from '@ui';\nimport type { WizardRunOptions } from '@utils/types';\nimport { createVersionBucket } from '@utils/semver';\nimport * as fs from 'node:fs';\nimport * as path from 'node:path';\n\nexport enum RailsProjectType {\n STANDARD = 'standard', // Traditional Rails app (rails new)\n API = 'api', // Rails API-only (rails new --api)\n}\n\nconst IGNORE_PATTERNS = [\n '**/node_modules/**',\n '**/vendor/**',\n '**/vendor/bundle/**',\n '**/tmp/**',\n '**/log/**',\n '**/storage/**',\n];\n\n/**\n * Get Rails version bucket for analytics\n */\nexport const getRailsVersionBucket = createVersionBucket();\n\n/**\n * Read and parse Gemfile contents\n */\nfunction readGemfile(\n options: Pick<WizardRunOptions, 'installDir'>,\n): string | undefined {\n const { installDir } = options;\n\n const gemfilePath = path.join(installDir, 'Gemfile');\n try {\n return fs.readFileSync(gemfilePath, 'utf-8');\n } catch {\n return undefined;\n }\n}\n\n/**\n * Check if a gem is present in the Gemfile\n */\nexport function hasGem(\n gemName: string,\n options: Pick<WizardRunOptions, 'installDir'>,\n): boolean {\n const content = readGemfile(options);\n if (!content) return false;\n\n // Match gem declarations like: gem 'rails', gem \"rails\", gem 'rails', '~> 7.0'\n const gemPattern = new RegExp(`^\\\\s*gem\\\\s+['\"]${gemName}['\"]`, 'im');\n return gemPattern.test(content);\n}\n\n/**\n * Extract version for a gem from Gemfile\n */\nexport function getGemVersion(\n gemName: string,\n options: Pick<WizardRunOptions, 'installDir'>,\n): string | undefined {\n const content = readGemfile(options);\n if (!content) return undefined;\n\n const versionPattern = new RegExp(\n `^\\\\s*gem\\\\s+['\"]${gemName}['\"]\\\\s*,\\\\s*['\"][^0-9]*([0-9]+\\\\.[0-9]+(?:\\\\.[0-9]+)?)['\"]`,\n 'im',\n );\n const match = content.match(versionPattern);\n return match?.[1];\n}\n\n/**\n * Get Rails version from Gemfile\n */\nexport function getRailsVersion(\n options: Pick<WizardRunOptions, 'installDir'>,\n): string | undefined {\n return getGemVersion('rails', options);\n}\n\n/**\n * Detect Rails project type\n */\nexport function getRailsProjectType(\n options: WizardRunOptions,\n): RailsProjectType {\n const { installDir } = options;\n\n // Check for API-only mode in config/application.rb\n const appConfigPath = path.join(installDir, 'config/application.rb');\n if (fs.existsSync(appConfigPath)) {\n try {\n const content = fs.readFileSync(appConfigPath, 'utf-8');\n if (content.includes('config.api_only = true')) {\n getUI().setDetectedFramework('Rails API-only');\n return RailsProjectType.API;\n }\n } catch {\n // Continue to default\n }\n }\n\n getUI().setDetectedFramework('Rails');\n return RailsProjectType.STANDARD;\n}\n\n/**\n * Get human-readable name for Rails project type\n */\nexport function getRailsProjectTypeName(projectType: RailsProjectType): string {\n switch (projectType) {\n case RailsProjectType.STANDARD:\n return 'Standard Rails';\n case RailsProjectType.API:\n return 'Rails API';\n }\n}\n\n/**\n * Find the Rails initializers directory\n */\nexport function findInitializersDir(\n options: Pick<WizardRunOptions, 'installDir'>,\n): string | undefined {\n const { installDir } = options;\n\n const initializersDir = path.join(installDir, 'config/initializers');\n if (fs.existsSync(initializersDir)) {\n return 'config/initializers';\n }\n\n return undefined;\n}\n\n/**\n * Detect if the project is a Rails project by looking for typical Rails files\n */\nexport async function isRailsProject(\n options: Pick<WizardRunOptions, 'installDir'>,\n): Promise<boolean> {\n const { installDir } = options;\n\n // Check for bin/rails\n const binRailsPath = path.join(installDir, 'bin/rails');\n if (fs.existsSync(binRailsPath)) {\n return true;\n }\n\n // Check for config/application.rb with Rails reference\n const appConfigPath = path.join(installDir, 'config/application.rb');\n if (fs.existsSync(appConfigPath)) {\n try {\n const content = fs.readFileSync(appConfigPath, 'utf-8');\n if (\n content.includes('Rails::Application') ||\n content.includes('require \"rails\"') ||\n content.includes(\"require 'rails'\")\n ) {\n return true;\n }\n } catch {\n // Continue to other checks\n }\n }\n\n // Check Gemfile for rails gem\n if (hasGem('rails', options)) {\n return true;\n }\n\n // Check for typical Rails directory structure\n const railsStructureFiles = await fg(\n ['config/routes.rb', 'config/environment.rb'],\n { cwd: installDir, ignore: IGNORE_PATTERNS },\n );\n\n return railsStructureFiles.length >= 2;\n}\n","/* Ruby on Rails wizard using posthog-agent with PostHog MCP */\nimport type { WizardRunOptions } from '@utils/types';\nimport type { FrameworkConfig } from '@lib/framework-config';\nimport { bundlerPackageManager } from '@lib/detection/package-manager';\nimport { Integration } from '@lib/constants';\nimport {\n getRailsVersion,\n getRailsProjectType,\n getRailsProjectTypeName,\n getRailsVersionBucket,\n RailsProjectType,\n findInitializersDir,\n isRailsProject,\n} from './utils';\n\ntype RailsContext = {\n projectType?: RailsProjectType;\n initializersDir?: string;\n};\n\nexport const RAILS_AGENT_CONFIG: FrameworkConfig<RailsContext> = {\n metadata: {\n name: 'Ruby on Rails',\n integration: Integration.rails,\n docsUrl: 'https://posthog.com/docs/libraries/ruby-on-rails',\n unsupportedVersionDocsUrl: 'https://posthog.com/docs/libraries/ruby',\n gatherContext: (options: WizardRunOptions) => {\n const projectType = getRailsProjectType(options);\n const initializersDir = findInitializersDir(options);\n return Promise.resolve({ projectType, initializersDir });\n },\n },\n\n detection: {\n packageName: 'rails',\n packageDisplayName: 'Ruby on Rails',\n usesPackageJson: false,\n getVersion: () => undefined,\n getVersionBucket: getRailsVersionBucket,\n minimumVersion: '6.0.0',\n getInstalledVersion: (options: WizardRunOptions) =>\n Promise.resolve(getRailsVersion(options)),\n detect: async (options) => isRailsProject(options),\n detectPackageManager: bundlerPackageManager,\n },\n\n environment: {\n uploadToHosting: false,\n getEnvVars: (apiKey: string, host: string) => ({\n POSTHOG_PROJECT_TOKEN: apiKey,\n POSTHOG_HOST: host,\n }),\n },\n\n analytics: {\n getTags: (context) => ({\n projectType: context.projectType || 'unknown',\n }),\n },\n\n prompts: {\n projectTypeDetection:\n 'This is a Ruby on Rails project. Look for Gemfile, config/application.rb, bin/rails, and config/routes.rb to confirm.',\n packageInstallation:\n \"Use Bundler to install gems. Add `gem 'posthog-ruby'` and `gem 'posthog-rails'` to the Gemfile and run `bundle install`. Do not pin specific versions.\",\n getAdditionalContextLines: (context) => {\n const projectTypeName = context.projectType\n ? getRailsProjectTypeName(context.projectType)\n : 'unknown';\n\n const lines = [\n `Project type: ${projectTypeName}`,\n `Framework docs ID: ruby-on-rails (use posthog://docs/frameworks/ruby-on-rails for documentation)`,\n ];\n\n if (context.initializersDir) {\n lines.push(`Initializers directory: ${context.initializersDir}`);\n }\n\n if (context.projectType === RailsProjectType.API) {\n lines.push(\n 'Note: This is an API-only Rails app — skip frontend posthog-js integration',\n );\n }\n\n return lines;\n },\n },\n\n ui: {\n successMessage: 'PostHog integration complete',\n estimatedDurationMinutes: 5,\n getOutroChanges: (context) => {\n const projectTypeName = context.projectType\n ? getRailsProjectTypeName(context.projectType)\n : 'Rails';\n\n const changes = [\n `Analyzed your ${projectTypeName} project structure`,\n `Installed the posthog-ruby and posthog-rails gems via Bundler`,\n `Created PostHog initializer in config/initializers/posthog.rb`,\n `Configured automatic exception capture and ActiveJob instrumentation`,\n ];\n\n if (context.projectType !== RailsProjectType.API) {\n changes.push(\n 'Added posthog-js snippet to the layout template for frontend tracking',\n );\n }\n\n return changes;\n },\n getOutroNextSteps: () => [\n 'Start your Rails development server with `bin/rails server`',\n 'Visit your PostHog dashboard to see incoming events',\n 'Use PostHog.capture() to track custom events',\n 'Use PostHog.identify() to associate events with users',\n 'Define posthog_distinct_id on your User model for automatic user association',\n ],\n },\n};\n","/* Elixir wizard using posthog-agent with PostHog MCP */\nimport * as fs from 'node:fs';\nimport * as path from 'node:path';\nimport type { WizardRunOptions } from '@utils/types';\nimport type { FrameworkConfig } from '@lib/framework-config';\nimport { mixPackageManager } from '@lib/detection/package-manager';\nimport { Integration } from '@lib/constants';\n\ntype ElixirContext = {\n phoenix?: boolean;\n};\n\nfunction readMixExs(installDir: string): string | undefined {\n const mixExsPath = path.join(installDir, 'mix.exs');\n if (!fs.existsSync(mixExsPath)) {\n return undefined;\n }\n return fs.readFileSync(mixExsPath, 'utf-8');\n}\n\n/** Phoenix apps get the Plug integration; plain Elixir apps don't. */\nfunction isPhoenixProject(installDir: string): boolean {\n const mixExs = readMixExs(installDir);\n return !!mixExs && /\\{\\s*:phoenix\\s*,/.test(mixExs);\n}\n\nexport const ELIXIR_AGENT_CONFIG: FrameworkConfig<ElixirContext> = {\n metadata: {\n name: 'Elixir',\n integration: Integration.elixir,\n docsUrl: 'https://posthog.com/docs/libraries/elixir',\n gatherContext: (options: WizardRunOptions) => {\n const phoenix = isPhoenixProject(options.installDir);\n return Promise.resolve({ phoenix });\n },\n },\n\n detection: {\n packageName: 'posthog',\n packageDisplayName: 'Elixir',\n usesPackageJson: false,\n getVersion: () => undefined,\n // A mix.exs defining a project marks a Mix project root; the def project\n // check keeps stray files named mix.exs from claiming the directory.\n detect: (options) => {\n const mixExs = readMixExs(options.installDir);\n return Promise.resolve(!!mixExs && /def\\s+project\\b/.test(mixExs));\n },\n detectPackageManager: mixPackageManager,\n },\n\n environment: {\n uploadToHosting: false,\n getEnvVars: (apiKey: string, host: string) => ({\n POSTHOG_API_KEY: apiKey,\n POSTHOG_HOST: host,\n }),\n },\n\n analytics: {\n getTags: (context) => ({\n projectType: context.phoenix ? 'phoenix' : 'elixir',\n }),\n },\n\n prompts: {\n projectTypeDetection:\n 'This is an Elixir project. Look for mix.exs, mix.lock, config/, lib/, and application.ex to confirm; Phoenix apps also have endpoint and router modules.',\n packageInstallation:\n 'Mix has no single add command. Add `{:posthog, \"~> 2.0\"}` to the deps list in mix.exs, then run `mix deps.get` to fetch it.',\n getAdditionalContextLines: (context) => {\n const lines = [\n `Framework docs ID: elixir (use posthog://docs/frameworks/elixir for documentation)`,\n 'Configure PostHog in application config (api_key, api_host, in_app_otp_apps) reading from environment variables; set test_mode: true in the test environment.',\n ];\n if (context.phoenix) {\n lines.push(\n 'This is a Phoenix app — add PostHog.Integrations.Plug before the router so request context is attached to captured events.',\n );\n }\n return lines;\n },\n },\n\n ui: {\n successMessage: 'PostHog integration complete',\n estimatedDurationMinutes: 5,\n getOutroChanges: (context) => [\n `Analyzed your ${\n context.phoenix ? 'Phoenix' : 'Elixir'\n } project structure`,\n 'Added the posthog Hex package to mix.exs and fetched it with mix deps.get',\n 'Configured PostHog in application config from environment variables',\n 'Instrumented meaningful events with PostHog.capture',\n ],\n getOutroNextSteps: (context) => [\n context.phoenix\n ? 'Start your Phoenix server with `mix phx.server` and trigger the instrumented code paths'\n : 'Run your Elixir application and trigger the instrumented code paths',\n 'Visit your PostHog dashboard to see incoming events',\n 'Use PostHog.capture/2 to track custom events',\n 'Use PostHog.set_context/1 to set a distinct_id once per request or job process',\n ],\n },\n};\n","/* Go wizard using posthog-agent with PostHog MCP */\nimport * as fs from 'node:fs';\nimport * as path from 'node:path';\nimport type { WizardRunOptions } from '@utils/types';\nimport type { FrameworkConfig } from '@lib/framework-config';\nimport { goModulesPackageManager } from '@lib/detection/package-manager';\nimport { Integration } from '@lib/constants';\n\ntype GoContext = {\n goVersion?: string;\n};\n\nfunction readGoMod(installDir: string): string | undefined {\n const goModPath = path.join(installDir, 'go.mod');\n if (!fs.existsSync(goModPath)) {\n return undefined;\n }\n return fs.readFileSync(goModPath, 'utf-8');\n}\n\n/** The `go 1.x` directive from go.mod (the toolchain floor, not a patch version). */\nfunction getGoVersion(installDir: string): string | undefined {\n const goMod = readGoMod(installDir);\n return goMod?.match(/^go\\s+([\\d.]+)/m)?.[1];\n}\n\nexport const GO_AGENT_CONFIG: FrameworkConfig<GoContext> = {\n metadata: {\n name: 'Go',\n integration: Integration.go,\n docsUrl: 'https://posthog.com/docs/libraries/go',\n gatherContext: (options: WizardRunOptions) => {\n const goVersion = getGoVersion(options.installDir);\n return Promise.resolve({ goVersion });\n },\n },\n\n detection: {\n packageName: 'posthog-go',\n packageDisplayName: 'Go',\n usesPackageJson: false,\n getVersion: () => undefined,\n // A go.mod with a module directive marks a Go module root; a bare\n // directory containing .go files without one is not integratable.\n detect: (options) => {\n const goMod = readGoMod(options.installDir);\n return Promise.resolve(!!goMod && /^module\\s+\\S+/m.test(goMod));\n },\n detectPackageManager: goModulesPackageManager,\n },\n\n environment: {\n uploadToHosting: false,\n getEnvVars: (apiKey: string, host: string) => ({\n POSTHOG_API_KEY: apiKey,\n POSTHOG_HOST: host,\n }),\n },\n\n analytics: {\n getTags: (context) => ({\n goVersion: context.goVersion || 'unknown',\n }),\n },\n\n prompts: {\n projectTypeDetection:\n 'This is a Go project. Look for go.mod, go.sum, cmd/, internal/, and main packages to confirm.',\n packageInstallation:\n 'Install the PostHog Go SDK with `go get github.com/posthog/posthog-go`. Do not manually edit go.mod or go.sum; the go tool updates them automatically. Run `go mod tidy` afterwards if imports change.',\n getAdditionalContextLines: (context) => {\n const lines = [\n `Framework docs ID: go (use posthog://docs/frameworks/go for documentation)`,\n ];\n if (context.goVersion) {\n lines.push(`Go version (go.mod directive): ${context.goVersion}`);\n }\n lines.push(\n 'Create one PostHog client per process and close it during graceful shutdown (`defer client.Close()`) so queued events flush.',\n );\n return lines;\n },\n },\n\n ui: {\n successMessage: 'PostHog integration complete',\n estimatedDurationMinutes: 5,\n getOutroChanges: () => [\n 'Analyzed your Go project structure',\n 'Installed the posthog-go SDK via go get',\n 'Initialized a shared PostHog client configured from environment variables',\n 'Instrumented meaningful server events with client.Enqueue(posthog.Capture{...})',\n ],\n getOutroNextSteps: () => [\n 'Run your Go service and trigger the instrumented code paths',\n 'Visit your PostHog dashboard to see incoming events',\n 'Use client.Enqueue(posthog.Capture{...}) to track custom events',\n 'Keep client.Close() in your graceful shutdown path so queued events flush',\n ],\n },\n};\n","/* Java (server) wizard using posthog-agent with PostHog MCP */\nimport fg from 'fast-glob';\nimport * as fs from 'node:fs';\nimport * as path from 'node:path';\nimport type { WizardRunOptions } from '@utils/types';\nimport type { FrameworkConfig } from '@lib/framework-config';\nimport { detectJavaPackageManagers } from '@lib/detection/package-manager';\nimport { Integration } from '@lib/constants';\n\ntype JavaContext = {\n buildTool?: 'maven' | 'gradle';\n};\n\nconst GRADLE_FILES = [\n 'build.gradle',\n 'build.gradle.kts',\n 'settings.gradle',\n 'settings.gradle.kts',\n];\n\nconst ANDROID_GRADLE_MARKERS = [\n 'com.android.application',\n 'com.android.library',\n 'com.android.tools.build:gradle',\n];\n\nconst KMP_GRADLE_MARKERS = [\n 'kotlin(\"multiplatform\")',\n 'org.jetbrains.kotlin.multiplatform',\n 'kotlin-multiplatform',\n];\n\nfunction readRootGradleFiles(installDir: string): string[] {\n return GRADLE_FILES.map((name) => path.join(installDir, name))\n .filter((p) => fs.existsSync(p))\n .map((p) => fs.readFileSync(p, 'utf-8'));\n}\n\nfunction getBuildTool(installDir: string): 'maven' | 'gradle' | undefined {\n if (fs.existsSync(path.join(installDir, 'pom.xml'))) {\n return 'maven';\n }\n if (readRootGradleFiles(installDir).length > 0) {\n return 'gradle';\n }\n return undefined;\n}\n\nexport const JAVA_AGENT_CONFIG: FrameworkConfig<JavaContext> = {\n metadata: {\n name: 'Java',\n integration: Integration.java,\n docsUrl: 'https://posthog.com/docs/libraries/java',\n gatherContext: (options: WizardRunOptions) => {\n const buildTool = getBuildTool(options.installDir);\n return Promise.resolve({ buildTool });\n },\n },\n\n detection: {\n packageName: 'posthog-server',\n packageDisplayName: 'Java',\n usesPackageJson: false,\n getVersion: () => undefined,\n // Maven projects (pom.xml) are unambiguously JVM backends. Gradle\n // projects are only claimed when they are neither Android nor KMP —\n // those detectors are ordered earlier, and this re-check keeps a\n // direct java detect() call from ever claiming their projects.\n detect: async (options) => {\n const { installDir } = options;\n\n // pubspec.yaml means Flutter — its gradle subtree is not a JVM backend.\n if (fs.existsSync(path.join(installDir, 'pubspec.yaml'))) {\n return false;\n }\n\n if (fs.existsSync(path.join(installDir, 'pom.xml'))) {\n return true;\n }\n\n const gradleContents = readRootGradleFiles(installDir);\n if (gradleContents.length === 0) {\n return false;\n }\n const combined = gradleContents.join('\\n');\n if (\n [...ANDROID_GRADLE_MARKERS, ...KMP_GRADLE_MARKERS].some((marker) =>\n combined.includes(marker),\n )\n ) {\n return false;\n }\n\n const manifestFiles = await fg('**/AndroidManifest.xml', {\n cwd: installDir,\n ignore: ['**/build/**', '**/node_modules/**', '**/.gradle/**'],\n });\n return manifestFiles.length === 0;\n },\n detectPackageManager: detectJavaPackageManagers,\n },\n\n environment: {\n uploadToHosting: false,\n getEnvVars: (apiKey: string, host: string) => ({\n POSTHOG_API_KEY: apiKey,\n POSTHOG_HOST: host,\n }),\n },\n\n analytics: {\n getTags: (context) => ({\n buildTool: context.buildTool || 'unknown',\n }),\n },\n\n prompts: {\n projectTypeDetection:\n 'This is a Java server project. Look for pom.xml (Maven) or build.gradle/build.gradle.kts (Gradle), src/main/java/, and the framework in use (Spring Boot, Quarkus, Micronaut, plain servlets) to confirm.',\n packageInstallation:\n 'Neither Maven nor Gradle has a single add command. Add the com.posthog:posthog-server dependency (pinned to the latest release on Maven Central) to pom.xml or build.gradle(.kts), matching the existing dependency format, then run `mvn install` or `gradle build` to resolve it.',\n getAdditionalContextLines: (context) => {\n const lines = [\n `Framework docs ID: java (use posthog://docs/frameworks/java for documentation)`,\n 'Use the posthog-server SDK (com.posthog:posthog-server) — posthog-android is a different library and must not be used on the server.',\n 'Create one PostHog client per process with PostHogConfig.builder(...) and PostHog.with(config); call close() during graceful shutdown, and flush() before returning in serverless handlers.',\n ];\n if (context.buildTool) {\n lines.push(`Build tool: ${context.buildTool}`);\n }\n return lines;\n },\n },\n\n ui: {\n successMessage: 'PostHog integration complete',\n estimatedDurationMinutes: 5,\n getOutroChanges: (context) => [\n 'Analyzed your Java project structure',\n `Added the posthog-server dependency to your ${\n context.buildTool === 'maven' ? 'pom.xml' : 'Gradle build'\n }`,\n 'Initialized a shared PostHog client configured from environment variables',\n 'Instrumented meaningful server events with posthog.capture',\n ],\n getOutroNextSteps: () => [\n 'Run your Java service and trigger the instrumented code paths',\n 'Visit your PostHog dashboard to see incoming events',\n 'Use posthog.capture(distinctId, eventName, options) to track custom events',\n 'Keep posthog.close() in your graceful shutdown path so queued events flush',\n ],\n },\n};\n","/* Rust wizard using posthog-agent with PostHog MCP */\nimport * as fs from 'node:fs';\nimport * as path from 'node:path';\nimport type { WizardRunOptions } from '@utils/types';\nimport type { FrameworkConfig } from '@lib/framework-config';\nimport { cargoPackageManager } from '@lib/detection/package-manager';\nimport { Integration } from '@lib/constants';\n\ntype RustContext = {\n asyncRuntime?: boolean;\n};\n\nfunction readCargoToml(installDir: string): string | undefined {\n const cargoTomlPath = path.join(installDir, 'Cargo.toml');\n if (!fs.existsSync(cargoTomlPath)) {\n return undefined;\n }\n return fs.readFileSync(cargoTomlPath, 'utf-8');\n}\n\n/** posthog-rs defaults to its async client; projects without an async runtime need the blocking one. */\nfunction hasAsyncRuntime(installDir: string): boolean {\n const cargoToml = readCargoToml(installDir);\n return !!cargoToml && /^\\s*(tokio|async-std|smol)\\s*[=.]/m.test(cargoToml);\n}\n\nexport const RUST_AGENT_CONFIG: FrameworkConfig<RustContext> = {\n metadata: {\n name: 'Rust',\n integration: Integration.rust,\n docsUrl: 'https://posthog.com/docs/libraries/rust',\n gatherContext: (options: WizardRunOptions) => {\n const asyncRuntime = hasAsyncRuntime(options.installDir);\n return Promise.resolve({ asyncRuntime });\n },\n },\n\n detection: {\n packageName: 'posthog-rs',\n packageDisplayName: 'Rust',\n usesPackageJson: false,\n getVersion: () => undefined,\n // A Cargo.toml with a [package] section marks a crate root. A\n // workspace-root-only manifest ([workspace], no [package]) falls\n // through — the agentic monorepo scan finds the nested crates.\n detect: (options) => {\n const cargoToml = readCargoToml(options.installDir);\n return Promise.resolve(!!cargoToml && /^\\s*\\[package\\]/m.test(cargoToml));\n },\n detectPackageManager: cargoPackageManager,\n },\n\n environment: {\n uploadToHosting: false,\n getEnvVars: (apiKey: string, host: string) => ({\n POSTHOG_API_KEY: apiKey,\n POSTHOG_HOST: host,\n }),\n },\n\n analytics: {\n getTags: (context) => ({\n asyncRuntime: context.asyncRuntime ? 'true' : 'false',\n }),\n },\n\n prompts: {\n projectTypeDetection:\n 'This is a Rust project. Look for Cargo.toml with a [package] section, src/main.rs or src/lib.rs, and Cargo.lock to confirm.',\n packageInstallation:\n 'Install the PostHog Rust SDK with `cargo add posthog-rs`. Do not manually edit Cargo.toml; cargo updates it automatically.',\n getAdditionalContextLines: (context) => {\n const lines = [\n `Framework docs ID: rust (use posthog://docs/frameworks/rust for documentation)`,\n 'capture() hands events to a background worker — the client must flush() or shutdown() before the process exits or buffered events are lost.',\n ];\n if (context.asyncRuntime) {\n lines.push(\n 'An async runtime is present — use the default async posthog-rs client.',\n );\n } else {\n lines.push(\n 'No async runtime detected — install with `cargo add posthog-rs --no-default-features` and use the blocking client.',\n );\n }\n return lines;\n },\n },\n\n ui: {\n successMessage: 'PostHog integration complete',\n estimatedDurationMinutes: 5,\n getOutroChanges: () => [\n 'Analyzed your Rust project structure',\n 'Installed the posthog-rs crate via cargo add',\n 'Initialized a shared PostHog client configured from environment variables',\n 'Instrumented meaningful events with client.capture',\n ],\n getOutroNextSteps: () => [\n 'Run your Rust application and trigger the instrumented code paths',\n 'Visit your PostHog dashboard to see incoming events',\n 'Use Event::new(event_name, distinct_id) and client.capture to track custom events',\n 'Keep flush()/shutdown() in your exit path so queued events are sent',\n ],\n },\n};\n","/* Generic Python language wizard using posthog-agent with PostHog MCP */\nimport type { WizardRunOptions } from '@utils/types';\nimport type { FrameworkConfig } from '@lib/framework-config';\nimport { PYTHON_PACKAGE_INSTALLATION } from '@lib/framework-config';\nimport { detectPythonPackageManagers } from '@lib/detection/package-manager';\nimport { Integration } from '@lib/constants';\nimport fg from 'fast-glob';\nimport * as fs from 'node:fs';\nimport * as path from 'node:path';\nimport {\n getPythonVersion,\n getPythonVersionBucket,\n detectPackageManager,\n getPackageManagerName,\n PythonPackageManager,\n} from './utils';\n\ntype PythonContext = {\n packageManager?: PythonPackageManager;\n};\n\nexport const PYTHON_AGENT_CONFIG: FrameworkConfig<PythonContext> = {\n metadata: {\n name: 'Python Language',\n integration: Integration.python,\n docsUrl: 'https://posthog.com/docs/libraries/python',\n gatherContext: async (options: WizardRunOptions) => {\n const packageManager = await detectPackageManager(options);\n return { packageManager };\n },\n },\n\n detection: {\n packageName: 'python',\n packageDisplayName: 'Python',\n usesPackageJson: false,\n getVersion: () => undefined,\n getVersionBucket: getPythonVersionBucket,\n minimumVersion: '3.8.0',\n getInstalledVersion: (options: WizardRunOptions) =>\n Promise.resolve(getPythonVersion(options)),\n detect: async (options) => {\n const { installDir } = options;\n\n // Look for Python package management files\n const pythonConfigFiles = await fg(\n [\n '**/requirements*.txt',\n '**/pyproject.toml',\n '**/setup.py',\n '**/Pipfile',\n ],\n {\n cwd: installDir,\n ignore: ['**/venv/**', '**/.venv/**', '**/env/**', '**/.env/**'],\n },\n );\n\n if (pythonConfigFiles.length === 0) {\n return false;\n }\n\n // Make sure this isn't Django or Flask (those should be detected first)\n // Check for Django\n const managePyMatches = await fg('**/manage.py', {\n cwd: installDir,\n ignore: ['**/venv/**', '**/.venv/**', '**/env/**', '**/.env/**'],\n });\n\n for (const match of managePyMatches) {\n try {\n const content = fs.readFileSync(\n path.join(installDir, match),\n 'utf-8',\n );\n if (\n content.includes('django') ||\n content.includes('DJANGO_SETTINGS_MODULE')\n ) {\n return false; // Django detected, use django agent instead\n }\n } catch {\n continue;\n }\n }\n\n // Check for Flask\n for (const configFile of pythonConfigFiles) {\n try {\n const content = fs.readFileSync(\n path.join(installDir, configFile),\n 'utf-8',\n );\n if (\n /^flask([<>=~!]|$|\\s)/im.test(content) ||\n /[\"']flask[\"']/i.test(content)\n ) {\n return false; // Flask detected, use flask agent instead\n }\n } catch {\n continue;\n }\n }\n\n const pyFiles = await fg(\n ['**/app.py', '**/wsgi.py', '**/application.py', '**/__init__.py'],\n {\n cwd: installDir,\n ignore: [\n '**/venv/**',\n '**/.venv/**',\n '**/env/**',\n '**/.env/**',\n '**/__pycache__/**',\n ],\n },\n );\n\n for (const pyFile of pyFiles) {\n try {\n const content = fs.readFileSync(\n path.join(installDir, pyFile),\n 'utf-8',\n );\n if (\n content.includes('from flask import') ||\n content.includes('import flask') ||\n /Flask\\s*\\(/.test(content)\n ) {\n return false; // Flask detected, use flask agent instead\n }\n } catch {\n continue;\n }\n }\n\n // If we have Python config files but it's not Django or Flask, it's a generic Python project\n return true;\n },\n detectPackageManager: detectPythonPackageManagers,\n },\n\n environment: {\n uploadToHosting: false,\n getEnvVars: (apiKey: string, host: string) => ({\n POSTHOG_PROJECT_TOKEN: apiKey,\n POSTHOG_HOST: host,\n }),\n },\n\n analytics: {\n getTags: (context) => {\n const packageManagerName = context.packageManager\n ? getPackageManagerName(context.packageManager)\n : 'unknown';\n return {\n packageManager: packageManagerName,\n };\n },\n },\n\n prompts: {\n packageInstallation: PYTHON_PACKAGE_INSTALLATION,\n projectTypeDetection:\n 'This is a generic Python project. Look for requirements.txt, pyproject.toml, setup.py, or Pipfile to confirm.',\n getAdditionalContextLines: (context) => {\n const packageManagerName = context.packageManager\n ? getPackageManagerName(context.packageManager)\n : 'unknown';\n\n return [\n `Package manager: ${packageManagerName}`,\n `Framework docs ID: python (use posthog://docs/frameworks/python for documentation)`,\n `Project type: Generic Python application (CLI, script, worker, data pipeline, etc.)`,\n ];\n },\n },\n\n ui: {\n successMessage: 'PostHog integration complete',\n estimatedDurationMinutes: 5,\n getOutroChanges: (context) => {\n const packageManagerName = context.packageManager\n ? getPackageManagerName(context.packageManager)\n : 'package manager';\n return [\n `Analyzed your Python project structure`,\n `Installed the PostHog Python package using ${packageManagerName}`,\n `Created PostHog initialization using instance-based API (Posthog class)`,\n `Configured exception autocapture and graceful shutdown`,\n `Added example code for events, feature flags, and error capture (without PII)`,\n ];\n },\n getOutroNextSteps: () => [\n 'Use Posthog() class (not module-level posthog) with enable_exception_autocapture=True',\n 'Call posthog_client.shutdown() on application exit (use atexit.register)',\n 'NEVER send PII in event properties (no emails, names, or user content)',\n 'Use posthog_client.capture() for events and posthog_client.identify() for users',\n 'Visit your PostHog dashboard to see incoming events',\n ],\n },\n};\n","import { boundedGlob } from '@utils/bounded-fs';\nimport type { WizardRunOptions } from '@utils/types';\nimport { createVersionBucket } from '@utils/semver';\nimport * as fs from 'node:fs';\nimport * as path from 'node:path';\n\nexport enum RubyPackageManager {\n BUNDLER = 'bundler',\n MANUAL = 'manual',\n}\n\nconst EXTRA_IGNORE = ['**/tmp/**', '**/log/**'];\n\n/**\n * Get Ruby version bucket for analytics\n */\nexport const getRubyVersionBucket = createVersionBucket();\n\n/**\n * Detect Ruby package manager\n */\nexport function detectPackageManager(\n options: Pick<WizardRunOptions, 'installDir'>,\n): RubyPackageManager {\n const { installDir } = options;\n\n const gemfilePath = path.join(installDir, 'Gemfile');\n if (fs.existsSync(gemfilePath)) {\n return RubyPackageManager.BUNDLER;\n }\n\n return RubyPackageManager.MANUAL;\n}\n\n/**\n * Get human-readable name for package manager\n */\nexport function getPackageManagerName(\n packageManager: RubyPackageManager,\n): string {\n switch (packageManager) {\n case RubyPackageManager.BUNDLER:\n return 'Bundler';\n case RubyPackageManager.MANUAL:\n return 'gem install';\n }\n}\n\n/**\n * Get Ruby version from .ruby-version file or Gemfile\n */\nexport function getRubyVersion(\n options: Pick<WizardRunOptions, 'installDir'>,\n): string | undefined {\n const { installDir } = options;\n\n // Check .ruby-version file\n const rubyVersionPath = path.join(installDir, '.ruby-version');\n try {\n const content = fs.readFileSync(rubyVersionPath, 'utf-8').trim();\n // Remove \"ruby-\" prefix if present\n const version = content.replace(/^ruby-/, '');\n if (/^[0-9]+\\.[0-9]+/.test(version)) {\n return version;\n }\n } catch {\n // Continue to other checks\n }\n\n // Check Gemfile for ruby version declaration\n const gemfilePath = path.join(installDir, 'Gemfile');\n try {\n const content = fs.readFileSync(gemfilePath, 'utf-8');\n const match = content.match(/ruby\\s+['\"]([0-9]+\\.[0-9]+(?:\\.[0-9]+)?)['\"]/);\n if (match) {\n return match[1];\n }\n } catch {\n // No Gemfile\n }\n\n return undefined;\n}\n\n/**\n * Check if the project is a Ruby project (but not Rails)\n */\nexport async function isRubyProject(\n options: Pick<WizardRunOptions, 'installDir'>,\n): Promise<boolean> {\n const { installDir } = options;\n\n // Check for Gemfile\n const gemfilePath = path.join(installDir, 'Gemfile');\n if (fs.existsSync(gemfilePath)) {\n // Make sure this isn't a Rails project (Rails should be detected first)\n try {\n const content = fs.readFileSync(gemfilePath, 'utf-8');\n if (/^\\s*gem\\s+['\"]rails['\"]/im.test(content)) {\n return false; // Rails project, use rails agent instead\n }\n } catch {\n // Continue checking\n }\n return true;\n }\n\n // Check for .ruby-version file\n const rubyVersionPath = path.join(installDir, '.ruby-version');\n if (fs.existsSync(rubyVersionPath)) {\n return true;\n }\n\n // Check for *.gemspec files\n const gemspecFiles = await boundedGlob('*.gemspec', {\n cwd: installDir,\n extraIgnore: EXTRA_IGNORE,\n limit: 1,\n });\n\n if (gemspecFiles.length > 0) {\n return true;\n }\n\n // Check for Ruby source files in the root\n const rubyFiles = await boundedGlob(['*.rb', 'lib/**/*.rb', 'bin/**/*.rb'], {\n cwd: installDir,\n extraIgnore: EXTRA_IGNORE,\n limit: 1,\n });\n\n return rubyFiles.length > 0;\n}\n","/* Generic Ruby language wizard using posthog-agent with PostHog MCP */\nimport type { WizardRunOptions } from '@utils/types';\nimport type { FrameworkConfig } from '@lib/framework-config';\nimport { bundlerPackageManager } from '@lib/detection/package-manager';\nimport { Integration } from '@lib/constants';\nimport {\n getRubyVersion,\n getRubyVersionBucket,\n detectPackageManager,\n getPackageManagerName,\n RubyPackageManager,\n isRubyProject,\n} from './utils';\n\ntype RubyContext = {\n packageManager?: RubyPackageManager;\n};\n\nexport const RUBY_AGENT_CONFIG: FrameworkConfig<RubyContext> = {\n metadata: {\n name: 'Ruby',\n integration: Integration.ruby,\n docsUrl: 'https://posthog.com/docs/libraries/ruby',\n gatherContext: (options: WizardRunOptions) => {\n const packageManager = detectPackageManager(options);\n return Promise.resolve({ packageManager });\n },\n },\n\n detection: {\n packageName: 'ruby',\n packageDisplayName: 'Ruby',\n usesPackageJson: false,\n getVersion: () => undefined,\n getVersionBucket: getRubyVersionBucket,\n minimumVersion: '2.7.0',\n getInstalledVersion: (options: WizardRunOptions) =>\n Promise.resolve(getRubyVersion(options)),\n detect: async (options) => isRubyProject(options),\n detectPackageManager: bundlerPackageManager,\n },\n\n environment: {\n uploadToHosting: false,\n getEnvVars: (apiKey: string, host: string) => ({\n POSTHOG_PROJECT_TOKEN: apiKey,\n POSTHOG_HOST: host,\n }),\n },\n\n analytics: {\n getTags: (context) => {\n const packageManagerName = context.packageManager\n ? getPackageManagerName(context.packageManager)\n : 'unknown';\n return {\n packageManager: packageManagerName,\n };\n },\n },\n\n prompts: {\n projectTypeDetection:\n 'This is a Ruby project. Look for Gemfile, *.gemspec, .ruby-version, or *.rb files to confirm.',\n packageInstallation:\n \"Use Bundler if a Gemfile is present (add `gem 'posthog-ruby'` and run `bundle install`). Otherwise use `gem install posthog-ruby`. Do not pin a specific version.\",\n getAdditionalContextLines: (context) => {\n const packageManagerName = context.packageManager\n ? getPackageManagerName(context.packageManager)\n : 'unknown';\n\n const lines = [\n `Package manager: ${packageManagerName}`,\n `Framework docs ID: ruby (use posthog://docs/frameworks/ruby for documentation)`,\n `Project type: Generic Ruby application (CLI, script, gem, worker, etc.)`,\n ``,\n `## CRITICAL: Ruby PostHog Best Practices`,\n ``,\n `### 1. Gem Name vs Require`,\n `The gem is named posthog-ruby but you require it as 'posthog':`,\n ` gem 'posthog-ruby' # in Gemfile`,\n ` require 'posthog' # in code (NOT require 'posthog-ruby')`,\n ``,\n `### 2. Use Instance-Based API (REQUIRED for scripts/CLIs)`,\n `Use PostHog::Client.new for scripts and standalone applications:`,\n ``,\n `client = PostHog::Client.new(`,\n ` api_key: ENV['POSTHOG_PROJECT_TOKEN'],`,\n ` host: ENV['POSTHOG_HOST'] || 'https://us.i.posthog.com'`,\n `)`,\n ``,\n `### 3. MUST Call shutdown Before Exit`,\n `In scripts and CLIs, you MUST call client.shutdown or events will be lost:`,\n ``,\n `begin`,\n ` client.capture(distinct_id: 'user_123', event: 'my_event')`,\n `ensure`,\n ` client.shutdown`,\n `end`,\n ``,\n `### 4. capture_exception Takes Positional Args`,\n `client.capture_exception(exception, distinct_id, additional_properties)`,\n `Do NOT use keyword arguments for capture_exception.`,\n ``,\n `### 5. NEVER Send PII`,\n `Do NOT include emails, names, phone numbers, or user content in event properties.`,\n ];\n\n return lines;\n },\n },\n\n ui: {\n successMessage: 'PostHog integration complete',\n estimatedDurationMinutes: 5,\n getOutroChanges: (context) => {\n const packageManagerName = context.packageManager\n ? getPackageManagerName(context.packageManager)\n : 'package manager';\n return [\n `Analyzed your Ruby project structure`,\n `Installed the posthog-ruby gem using ${packageManagerName}`,\n `Created PostHog initialization with instance-based API`,\n `Configured shutdown handler for proper event flushing`,\n ];\n },\n getOutroNextSteps: () => [\n 'Use client.capture() for events and client.identify() for users',\n 'Always call client.shutdown() before your application exits',\n 'Visit your PostHog dashboard to see incoming events',\n ],\n },\n};\n","/* Generic Node.js language wizard using posthog-agent with PostHog MCP */\nimport type { FrameworkConfig } from '@lib/framework-config';\nimport { Integration } from '@lib/constants';\nimport { tryGetPackageJson } from '@utils/setup-utils';\nimport { detectNodePackageManagers } from '@lib/detection/package-manager';\n\ntype JavaScriptNodeContext = Record<string, unknown>;\n\nexport const JAVASCRIPT_NODE_AGENT_CONFIG: FrameworkConfig<JavaScriptNodeContext> =\n {\n metadata: {\n name: 'Node.js',\n integration: Integration.javascriptNode,\n docsUrl: 'https://posthog.com/docs/libraries/node',\n },\n\n detection: {\n packageName: 'posthog-node',\n packageDisplayName: 'Node.js',\n usesPackageJson: false,\n getVersion: () => undefined,\n detectPackageManager: detectNodePackageManagers,\n detect: async (options) => {\n const packageJson = await tryGetPackageJson(options);\n return !!packageJson;\n },\n },\n\n environment: {\n uploadToHosting: false,\n getEnvVars: (apiKey: string, host: string) => ({\n POSTHOG_PROJECT_TOKEN: apiKey,\n POSTHOG_HOST: host,\n }),\n },\n\n analytics: {\n getTags: () => ({}),\n },\n\n prompts: {\n projectTypeDetection:\n 'This is a server-side Node.js project. Look for package.json and lockfiles to confirm.',\n packageInstallation:\n 'Use npm, yarn, pnpm, or bun based on the existing lockfile (package-lock.json, yarn.lock, pnpm-lock.yaml, bun.lockb). Install posthog-node as a regular dependency.',\n getAdditionalContextLines: () => [\n `Framework docs ID: javascript_node (use posthog://docs/frameworks/javascript_node for documentation)`,\n ],\n },\n\n ui: {\n successMessage: 'PostHog integration complete',\n estimatedDurationMinutes: 5,\n getOutroChanges: () => [\n `Analyzed your Node.js project structure`,\n `Installed the posthog-node package`,\n `Created PostHog initialization with proper configuration`,\n `Configured graceful shutdown for event flushing`,\n `Added example code for events, feature flags, and error capture`,\n ],\n getOutroNextSteps: () => [\n 'Use the PostHog client instance for all tracking calls',\n 'Call posthog.shutdown() on application exit to flush pending events',\n 'NEVER send PII in event properties (no emails, names, or user content)',\n 'Use posthog.capture() for events and posthog.identify() for users',\n 'Visit your PostHog dashboard to see incoming events',\n ],\n },\n };\n","import * as fs from 'node:fs';\nimport * as path from 'node:path';\nimport { boundedGlob } from '@utils/bounded-fs';\nimport { detectAllPackageManagers } from '@utils/package-manager';\nimport type { WizardRunOptions } from '@utils/types';\n\nexport type JavaScriptContext = {\n packageManagerName?: string;\n hasTypeScript?: boolean;\n hasBundler?: string;\n};\n\nconst INDEX_HTML_MAX_DEPTH = 6;\n\n/**\n * Packages that indicate a specific framework integration exists.\n * If any of these are in package.json, we should NOT match as generic JavaScript.\n *\n * When adding a new JS framework integration to the wizard,\n * add its detection package here too.\n */\nexport const FRAMEWORK_PACKAGES = [\n 'next',\n 'nuxt',\n 'vue',\n 'react-router',\n '@tanstack/react-start',\n '@tanstack/react-router',\n 'react-native',\n '@angular/core',\n 'astro',\n '@sveltejs/kit',\n] as const;\n\n/**\n * Detect the JS package manager for the project by checking lockfiles.\n * Reuses the existing package manager detection infrastructure.\n */\nexport function detectJsPackageManager(\n options: Pick<WizardRunOptions, 'installDir'>,\n): string {\n const detected = detectAllPackageManagers(options);\n if (detected.length > 0) {\n return detected[0].label;\n }\n return 'unknown';\n}\n\n/**\n * Detect the bundler used in the project by checking package.json dependencies.\n */\nexport function detectBundler(\n options: Pick<WizardRunOptions, 'installDir'>,\n): string | undefined {\n try {\n const content = fs.readFileSync(\n path.join(options.installDir, 'package.json'),\n 'utf-8',\n );\n const pkg = JSON.parse(content);\n const allDeps: Record<string, string> = {\n ...pkg.dependencies,\n ...pkg.devDependencies,\n };\n\n if (allDeps['vite']) return 'vite';\n if (allDeps['webpack']) return 'webpack';\n if (allDeps['esbuild']) return 'esbuild';\n if (allDeps['parcel']) return 'parcel';\n if (allDeps['rollup']) return 'rollup';\n return undefined;\n } catch {\n return undefined;\n }\n}\n\n/**\n * Heuristic: check if there is an index.html anywhere in the project,\n * ignoring common build and dependency directories.\n */\nexport async function hasIndexHtml(\n options: Pick<WizardRunOptions, 'installDir'>,\n): Promise<boolean> {\n const matches = await boundedGlob('**/index.html', {\n cwd: options.installDir,\n deep: INDEX_HTML_MAX_DEPTH,\n limit: 1,\n });\n\n return matches.length > 0;\n}\n","/* Generic JavaScript Web (client-side) wizard using posthog-agent with PostHog MCP */\nimport type { WizardRunOptions } from '@utils/types';\nimport type { FrameworkConfig } from '@lib/framework-config';\nimport { Integration } from '@lib/constants';\nimport * as fs from 'node:fs';\nimport * as path from 'node:path';\nimport { hasDeclaredDependency } from '@utils/package-json';\nimport { tryGetPackageJson } from '@utils/setup-utils';\nimport {\n FRAMEWORK_PACKAGES,\n detectJsPackageManager,\n detectBundler,\n hasIndexHtml,\n type JavaScriptContext,\n} from './utils';\nimport { detectNodePackageManagers } from '@lib/detection/package-manager';\n\nexport const JAVASCRIPT_WEB_AGENT_CONFIG: FrameworkConfig<JavaScriptContext> = {\n metadata: {\n name: 'JavaScript (Web)',\n integration: Integration.javascript_web,\n docsUrl: 'https://posthog.com/docs/libraries/js',\n gatherContext: (options: WizardRunOptions) => {\n const packageManagerName = detectJsPackageManager(options);\n const hasTypeScript = fs.existsSync(\n path.join(options.installDir, 'tsconfig.json'),\n );\n const hasBundler = detectBundler(options);\n return Promise.resolve({ packageManagerName, hasTypeScript, hasBundler });\n },\n },\n\n detection: {\n packageName: 'posthog-js',\n packageDisplayName: 'JavaScript (Web)',\n usesPackageJson: false,\n getVersion: () => undefined,\n detectPackageManager: detectNodePackageManagers,\n detect: async (options) => {\n const packageJson = await tryGetPackageJson(options);\n if (!packageJson) {\n return false;\n }\n\n // Exclude projects with known framework packages\n for (const frameworkPkg of FRAMEWORK_PACKAGES) {\n if (hasDeclaredDependency(frameworkPkg, packageJson)) {\n return false;\n }\n }\n\n const { installDir } = options;\n\n // Has (index.html OR has a bundler) AND is a JavaScript project\n const hasIndexHtmlFlag = await hasIndexHtml(options);\n\n const bundler = detectBundler(options);\n const hasBundler = !!bundler;\n\n const hasLockfile = [\n 'package-lock.json',\n 'yarn.lock',\n 'pnpm-lock.yaml',\n 'bun.lockb',\n 'bun.lock',\n 'deno.lock',\n ].some((lockfile) => fs.existsSync(path.join(installDir, lockfile)));\n\n // We only treat this as JS Web if there's BOTH:\n // - a lockfile, and\n // - at least one frontend signal (index.html or bundler)\n if (hasLockfile && (hasIndexHtmlFlag || hasBundler)) {\n return true;\n }\n\n // Otherwise → Node/Backend (handled by javascriptNode fallback)\n return false;\n },\n },\n\n environment: {\n uploadToHosting: false,\n getEnvVars: (apiKey: string, host: string) => ({\n POSTHOG_PROJECT_TOKEN: apiKey,\n POSTHOG_HOST: host,\n }),\n },\n\n analytics: {\n getTags: (context) => {\n const tags: Record<string, string> = {\n packageManager: context.packageManagerName ?? 'unknown',\n };\n if (context.hasBundler) {\n tags.bundler = context.hasBundler;\n }\n return tags;\n },\n },\n\n prompts: {\n projectTypeDetection:\n 'This is a JavaScript/TypeScript project. Look for package.json and lockfiles (package-lock.json, yarn.lock, pnpm-lock.yaml, bun.lockb) to confirm.',\n packageInstallation:\n 'Look for lockfiles to determine the package manager (npm, yarn, pnpm, bun). Do not manually edit package.json.',\n getAdditionalContextLines: (context) => {\n const lines = [\n `Package manager: ${context.packageManagerName ?? 'unknown'}`,\n `Has TypeScript: ${context.hasTypeScript ? 'yes' : 'no'}`,\n `Framework docs ID: js (use posthog://docs/frameworks/js for documentation if available)`,\n `Project type: Generic JavaScript/TypeScript application (no specific framework detected)`,\n ];\n\n if (context.hasBundler) {\n lines.unshift(`Bundler: ${context.hasBundler}`);\n }\n\n return lines;\n },\n },\n\n ui: {\n successMessage: 'PostHog integration complete',\n estimatedDurationMinutes: 5,\n getOutroChanges: (context) => {\n const packageManagerName =\n context.packageManagerName ?? 'package manager';\n return [\n `Analyzed your JavaScript project structure`,\n `Installed the posthog-js package using ${packageManagerName}`,\n `Created PostHog initialization code`,\n `Configured autocapture, error tracking, and event capture`,\n ];\n },\n getOutroNextSteps: () => [\n 'Ensure posthog.init() is called before any capture calls',\n 'Autocapture tracks clicks, form submissions, and pageviews automatically',\n 'Use posthog.capture() for custom events and posthog.identify() for users',\n 'NEVER send PII in event properties (no emails, names, or user content)',\n 'Visit your PostHog dashboard to see incoming events',\n ],\n },\n};\n","import type { FrameworkConfig } from './framework-config';\nimport { Integration } from './constants';\nimport { NEXTJS_AGENT_CONFIG } from '@frameworks/nextjs/nextjs-wizard-agent';\nimport { NUXT_AGENT_CONFIG } from '@frameworks/nuxt/nuxt-wizard-agent';\nimport { VUE_AGENT_CONFIG } from '@frameworks/vue/vue-wizard-agent';\nimport { REACT_ROUTER_AGENT_CONFIG } from '@frameworks/react-router/react-router-wizard-agent';\nimport { TANSTACK_ROUTER_AGENT_CONFIG } from '@frameworks/tanstack-router/tanstack-router-wizard-agent';\nimport { TANSTACK_START_AGENT_CONFIG } from '@frameworks/tanstack-start/tanstack-start-wizard-agent';\nimport { REACT_NATIVE_AGENT_CONFIG } from '@frameworks/react-native/react-native-wizard-agent';\nimport { ANGULAR_AGENT_CONFIG } from '@frameworks/angular/angular-wizard-agent';\nimport { ASTRO_AGENT_CONFIG } from '@frameworks/astro/astro-wizard-agent';\nimport { DJANGO_AGENT_CONFIG } from '@frameworks/django/django-wizard-agent';\nimport { FLASK_AGENT_CONFIG } from '@frameworks/flask/flask-wizard-agent';\nimport { FASTAPI_AGENT_CONFIG } from '@frameworks/fastapi/fastapi-wizard-agent';\nimport { LARAVEL_AGENT_CONFIG } from '@frameworks/laravel/laravel-wizard-agent';\nimport { SVELTEKIT_AGENT_CONFIG } from '@frameworks/svelte/svelte-wizard-agent';\nimport { FLUTTER_AGENT_CONFIG } from '@frameworks/flutter/flutter-wizard-agent';\nimport { SWIFT_AGENT_CONFIG } from '@frameworks/swift/swift-wizard-agent';\nimport { KMP_AGENT_CONFIG } from '@frameworks/kmp/kmp-wizard-agent';\nimport { ANDROID_AGENT_CONFIG } from '@frameworks/android/android-wizard-agent';\nimport { RAILS_AGENT_CONFIG } from '@frameworks/rails/rails-wizard-agent';\nimport { ELIXIR_AGENT_CONFIG } from '@frameworks/elixir/elixir-wizard-agent';\nimport { GO_AGENT_CONFIG } from '@frameworks/go/go-wizard-agent';\nimport { JAVA_AGENT_CONFIG } from '@frameworks/java/java-wizard-agent';\nimport { RUST_AGENT_CONFIG } from '@frameworks/rust/rust-wizard-agent';\nimport { PYTHON_AGENT_CONFIG } from '@frameworks/python/python-wizard-agent';\nimport { RUBY_AGENT_CONFIG } from '@frameworks/ruby/ruby-wizard-agent';\nimport { JAVASCRIPT_NODE_AGENT_CONFIG } from '@frameworks/javascript-node/javascript-node-wizard-agent';\nimport { JAVASCRIPT_WEB_AGENT_CONFIG } from '@frameworks/javascript-web/javascript-web-wizard-agent';\n\nexport const FRAMEWORK_REGISTRY: Record<Integration, FrameworkConfig> = {\n [Integration.nextjs]: NEXTJS_AGENT_CONFIG,\n [Integration.nuxt]: NUXT_AGENT_CONFIG,\n [Integration.vue]: VUE_AGENT_CONFIG,\n [Integration.tanstackStart]: TANSTACK_START_AGENT_CONFIG,\n [Integration.reactRouter]: REACT_ROUTER_AGENT_CONFIG,\n [Integration.tanstackRouter]: TANSTACK_ROUTER_AGENT_CONFIG,\n [Integration.reactNative]: REACT_NATIVE_AGENT_CONFIG,\n [Integration.angular]: ANGULAR_AGENT_CONFIG,\n [Integration.astro]: ASTRO_AGENT_CONFIG,\n [Integration.django]: DJANGO_AGENT_CONFIG,\n [Integration.flask]: FLASK_AGENT_CONFIG,\n [Integration.fastapi]: FASTAPI_AGENT_CONFIG,\n [Integration.laravel]: LARAVEL_AGENT_CONFIG,\n [Integration.sveltekit]: SVELTEKIT_AGENT_CONFIG,\n [Integration.flutter]: FLUTTER_AGENT_CONFIG,\n [Integration.kmp]: KMP_AGENT_CONFIG,\n [Integration.swift]: SWIFT_AGENT_CONFIG,\n [Integration.android]: ANDROID_AGENT_CONFIG,\n [Integration.rails]: RAILS_AGENT_CONFIG,\n [Integration.elixir]: ELIXIR_AGENT_CONFIG,\n [Integration.go]: GO_AGENT_CONFIG,\n [Integration.rust]: RUST_AGENT_CONFIG,\n [Integration.java]: JAVA_AGENT_CONFIG,\n [Integration.python]: PYTHON_AGENT_CONFIG,\n [Integration.ruby]: RUBY_AGENT_CONFIG,\n [Integration.javascriptNode]: JAVASCRIPT_NODE_AGENT_CONFIG,\n [Integration.javascript_web]: JAVASCRIPT_WEB_AGENT_CONFIG,\n};\n"],"mappings":"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"}
1
+ {"version":3,"file":"registry-BBdaIFWq.js","names":["IGNORE_PATTERNS","EXTRA_IGNORE","SOURCE_PROBE_LIMIT","path","EXTRA_IGNORE","SOURCE_PROBE_LIMIT","path","fs","EXTRA_IGNORE","EXTRA_IGNORE","path","EXTRA_IGNORE","path","EXTRA_IGNORE","SOURCE_PROBE_LIMIT","path","EXTRA_IGNORE","path","EXTRA_IGNORE","SOURCE_PROBE_LIMIT","path","EXTRA_IGNORE","path","EXTRA_IGNORE","SOURCE_PROBE_LIMIT","path","fs","path","fs","path","fs","EXTRA_IGNORE","fs","path","fs","path","path","path","fs","fs","path","path","fs","path","fs","path","fs","path","fs","path","fs","detectPackageManager","fs","path","getPackageManagerName","path","fs","fs","path","fs","path"],"sources":["../src/frameworks/nextjs/utils.ts","../src/frameworks/nextjs/nextjs-wizard-agent.ts","../src/frameworks/nuxt/nuxt-wizard-agent.ts","../src/frameworks/vue/vue-wizard-agent.ts","../src/frameworks/react-router/utils.ts","../src/frameworks/react-router/react-router-wizard-agent.ts","../src/frameworks/tanstack-router/utils.ts","../src/frameworks/tanstack-router/tanstack-router-wizard-agent.ts","../src/frameworks/tanstack-start/utils.ts","../src/frameworks/tanstack-start/tanstack-start-wizard-agent.ts","../src/frameworks/react-native/utils.ts","../src/frameworks/react-native/react-native-wizard-agent.ts","../src/frameworks/angular/utils.ts","../src/frameworks/angular/angular-wizard-agent.ts","../src/frameworks/astro/utils.ts","../src/frameworks/astro/astro-wizard-agent.ts","../src/lib/framework-config.ts","../src/frameworks/django/utils.ts","../src/frameworks/django/django-wizard-agent.ts","../src/frameworks/flask/utils.ts","../src/frameworks/flask/flask-wizard-agent.ts","../src/frameworks/fastapi/utils.ts","../src/frameworks/fastapi/fastapi-wizard-agent.ts","../src/frameworks/laravel/utils.ts","../src/frameworks/laravel/laravel-wizard-agent.ts","../src/frameworks/svelte/svelte-wizard-agent.ts","../src/frameworks/flutter/flutter-wizard-agent.ts","../src/frameworks/swift/utils.ts","../src/frameworks/swift/swift-wizard-agent.ts","../src/frameworks/kmp/kmp-wizard-agent.ts","../src/frameworks/android/utils.ts","../src/frameworks/android/android-wizard-agent.ts","../src/frameworks/rails/utils.ts","../src/frameworks/rails/rails-wizard-agent.ts","../src/frameworks/elixir/elixir-wizard-agent.ts","../src/frameworks/go/go-wizard-agent.ts","../src/frameworks/java/java-wizard-agent.ts","../src/frameworks/rust/rust-wizard-agent.ts","../src/frameworks/python/python-wizard-agent.ts","../src/frameworks/ruby/utils.ts","../src/frameworks/ruby/ruby-wizard-agent.ts","../src/frameworks/javascript-node/javascript-node-wizard-agent.ts","../src/frameworks/javascript-web/utils.ts","../src/frameworks/javascript-web/javascript-web-wizard-agent.ts","../src/lib/registry.ts"],"sourcesContent":["import type { WizardRunOptions } from '@utils/types';\nimport { boundedGlob } from '@utils/bounded-fs';\nimport { createVersionBucket } from '@utils/semver';\n\nexport const getNextJsVersionBucket = createVersionBucket();\n\nexport enum NextJsRouter {\n APP_ROUTER = 'app-router',\n PAGES_ROUTER = 'pages-router',\n}\n\nexport const IGNORE_PATTERNS = ['**/public/**'];\n\n/**\n * Detect Next.js router type. Pure — returns null if ambiguous.\n */\nexport async function getNextJsRouter({\n installDir,\n}: Pick<WizardRunOptions, 'installDir'>): Promise<NextJsRouter | null> {\n const pagesMatches = await boundedGlob('**/pages/_app.@(ts|tsx|js|jsx)', {\n cwd: installDir,\n extraIgnore: IGNORE_PATTERNS,\n limit: 1,\n });\n\n const hasPagesDir = pagesMatches.length > 0;\n\n const appMatches = await boundedGlob('**/app/**/layout.@(ts|tsx|js|jsx)', {\n cwd: installDir,\n extraIgnore: IGNORE_PATTERNS,\n limit: 1,\n });\n\n const hasAppDir = appMatches.length > 0;\n\n if (hasPagesDir && !hasAppDir) {\n return NextJsRouter.PAGES_ROUTER;\n }\n\n if (hasAppDir && !hasPagesDir) {\n return NextJsRouter.APP_ROUTER;\n }\n\n // Ambiguous (both or neither) — return null, SetupScreen handles it\n return null;\n}\n\nexport const getNextJsRouterName = (router: NextJsRouter) => {\n return router === NextJsRouter.APP_ROUTER ? 'app router' : 'pages router';\n};\n","/* Simplified Next.js wizard using posthog-agent with PostHog MCP */\nimport type { WizardRunOptions } from '@utils/types';\nimport type { FrameworkConfig } from '@lib/framework-config';\nimport { detectNodePackageManagers } from '@lib/detection/package-manager';\nimport { Integration } from '@lib/constants';\nimport {\n getDeclaredVersion,\n getInstalledPackageVersion,\n hasDeclaredDependency,\n type PackageJson,\n} from '@utils/package-json';\nimport { tryGetPackageJson } from '@utils/setup-utils';\nimport { getUI } from '@ui';\nimport {\n getNextJsRouter,\n getNextJsVersionBucket,\n getNextJsRouterName,\n NextJsRouter,\n} from './utils';\n\ntype NextjsContext = {\n router?: NextJsRouter;\n};\n\nexport const NEXTJS_AGENT_CONFIG: FrameworkConfig<NextjsContext> = {\n metadata: {\n name: 'Next.js',\n integration: Integration.nextjs,\n docsUrl: 'https://posthog.com/docs/libraries/next-js',\n unsupportedVersionDocsUrl: 'https://posthog.com/docs/libraries/next-js',\n gatherContext: async (options: WizardRunOptions) => {\n const router = await getNextJsRouter(options);\n if (router) {\n const emoji =\n router === NextJsRouter.APP_ROUTER ? '\\u{1F4F1}' : '\\u{1F4C3}';\n getUI().setDetectedFramework(\n `Next.js ${getNextJsRouterName(router)} ${emoji}`,\n );\n return { router };\n }\n return {};\n },\n setup: {\n questions: [\n {\n key: 'router',\n message: 'Which Next.js router are you using?',\n options: [\n { label: 'App Router', value: NextJsRouter.APP_ROUTER },\n { label: 'Pages Router', value: NextJsRouter.PAGES_ROUTER },\n ],\n detect: async (opts) => {\n const result = await getNextJsRouter(opts);\n return result;\n },\n },\n ],\n },\n },\n\n detection: {\n packageName: 'next',\n packageDisplayName: 'Next.js',\n getVersion: (packageJson: unknown) =>\n getDeclaredVersion('next', packageJson as PackageJson),\n getVersionBucket: getNextJsVersionBucket,\n minimumVersion: '15.3.0',\n getInstalledVersion: (options: WizardRunOptions) =>\n Promise.resolve(getInstalledPackageVersion('next', options.installDir)),\n detect: async (options) => {\n const packageJson = await tryGetPackageJson(options);\n return packageJson ? hasDeclaredDependency('next', packageJson) : false;\n },\n detectPackageManager: detectNodePackageManagers,\n },\n\n environment: {\n uploadToHosting: true,\n getEnvVars: (apiKey: string, host: string) => ({\n NEXT_PUBLIC_POSTHOG_PROJECT_TOKEN: apiKey,\n NEXT_PUBLIC_POSTHOG_HOST: host,\n }),\n },\n\n analytics: {\n getTags: (context) => ({\n router: context.router === NextJsRouter.APP_ROUTER ? 'app' : 'pages',\n }),\n },\n\n prompts: {\n projectTypeDetection:\n 'This is a JavaScript/TypeScript project. Look for package.json and lockfiles (package-lock.json, yarn.lock, pnpm-lock.yaml, bun.lockb) to confirm.',\n getAdditionalContextLines: (context) => {\n const routerType =\n context.router === NextJsRouter.APP_ROUTER ? 'app' : 'pages';\n return [`Router: ${routerType}`];\n },\n },\n\n ui: {\n successMessage: 'PostHog integration complete',\n estimatedDurationMinutes: 8,\n getOutroChanges: (context) => {\n const router = context.router ?? NextJsRouter.APP_ROUTER;\n const routerName = getNextJsRouterName(router);\n return [\n `Analyzed your Next.js project structure (${routerName})`,\n `Created and configured PostHog initializers`,\n `Integrated PostHog into your application`,\n ];\n },\n getOutroNextSteps: () => {\n return [\n 'Start your development server to see PostHog in action',\n 'Visit your PostHog dashboard to see incoming events',\n ];\n },\n },\n};\n","/* Nuxt wizard using posthog-agent with PostHog MCP */\nimport type { WizardRunOptions } from '@utils/types';\nimport type { FrameworkConfig } from '@lib/framework-config';\nimport { detectNodePackageManagers } from '@lib/detection/package-manager';\nimport { Integration } from '@lib/constants';\nimport {\n getDeclaredVersion,\n getInstalledPackageVersion,\n hasDeclaredDependency,\n type PackageJson,\n} from '@utils/package-json';\nimport { tryGetPackageJson } from '@utils/setup-utils';\nimport { createVersionBucket } from '@utils/semver';\n\nconst getNuxtVersionBucket = createVersionBucket();\n\ntype NuxtContext = {\n versionBucket?: string;\n};\n\nexport const NUXT_AGENT_CONFIG: FrameworkConfig<NuxtContext> = {\n metadata: {\n name: 'Nuxt',\n integration: Integration.nuxt,\n docsUrl: 'https://posthog.com/docs/libraries/nuxt',\n gatherContext: async (options: WizardRunOptions) => {\n const packageJson = await tryGetPackageJson(options);\n if (!packageJson) return {};\n const version = getDeclaredVersion('nuxt', packageJson);\n const versionBucket = getNuxtVersionBucket(version);\n return { versionBucket };\n },\n },\n\n detection: {\n packageName: 'nuxt',\n packageDisplayName: 'Nuxt',\n getVersion: (packageJson: unknown) =>\n getDeclaredVersion('nuxt', packageJson as PackageJson),\n getVersionBucket: getNuxtVersionBucket,\n getInstalledVersion: (options: WizardRunOptions) =>\n Promise.resolve(getInstalledPackageVersion('nuxt', options.installDir)),\n detect: async (options) => {\n const packageJson = await tryGetPackageJson(options);\n return packageJson ? hasDeclaredDependency('nuxt', packageJson) : false;\n },\n detectPackageManager: detectNodePackageManagers,\n },\n\n environment: {\n uploadToHosting: true,\n getEnvVars: (apiKey: string, host: string) => ({\n NUXT_PUBLIC_POSTHOG_PROJECT_TOKEN: apiKey,\n NUXT_PUBLIC_POSTHOG_HOST: host,\n }),\n },\n\n analytics: {\n getTags: (context) => ({\n ...(context.versionBucket\n ? { versionBucket: context.versionBucket }\n : {}),\n }),\n },\n\n prompts: {\n projectTypeDetection:\n 'This is a JavaScript/TypeScript project. Look for package.json and lockfiles (package-lock.json, yarn.lock, pnpm-lock.yaml, bun.lockb) to confirm.',\n getAdditionalContextLines: (context) => {\n const lines: string[] = [];\n if (context.versionBucket) {\n lines.push(`Nuxt version: ${context.versionBucket}`);\n }\n const frameworkId = 'nuxt';\n lines.push(\n `Framework docs ID: ${frameworkId} (use posthog://docs/frameworks/${frameworkId} for documentation)`,\n );\n return lines;\n },\n },\n\n ui: {\n successMessage: 'PostHog integration complete',\n estimatedDurationMinutes: 5,\n getOutroChanges: () => [\n 'Analyzed your Nuxt project structure',\n 'Configured PostHog module/plugin',\n 'Integrated PostHog into your application',\n ],\n getOutroNextSteps: () => [\n 'Start your development server to see PostHog in action',\n 'Visit your PostHog dashboard to see incoming events',\n ],\n },\n};\n","/* Vue wizard using posthog-agent with PostHog MCP */\nimport type { FrameworkConfig } from '@lib/framework-config';\nimport { detectNodePackageManagers } from '@lib/detection/package-manager';\nimport { Integration } from '@lib/constants';\nimport {\n getDeclaredVersion,\n getInstalledPackageVersion,\n hasDeclaredDependency,\n type PackageJson,\n} from '@utils/package-json';\nimport { tryGetPackageJson } from '@utils/setup-utils';\nimport { createVersionBucket } from '@utils/semver';\n\nconst getVueVersionBucket = createVersionBucket();\n\ntype VueContext = Record<string, unknown>;\n\nexport const VUE_AGENT_CONFIG: FrameworkConfig<VueContext> = {\n metadata: {\n name: 'Vue',\n integration: Integration.vue,\n docsUrl: 'https://posthog.com/docs/libraries/vue',\n },\n\n detection: {\n packageName: 'vue',\n packageDisplayName: 'Vue',\n getVersion: (packageJson: unknown) =>\n getDeclaredVersion('vue', packageJson as PackageJson),\n getVersionBucket: getVueVersionBucket,\n getInstalledVersion: (options) =>\n Promise.resolve(getInstalledPackageVersion('vue', options.installDir)),\n detect: async (options) => {\n const packageJson = await tryGetPackageJson(options);\n return packageJson ? hasDeclaredDependency('vue', packageJson) : false;\n },\n detectPackageManager: detectNodePackageManagers,\n },\n\n environment: {\n uploadToHosting: true,\n getEnvVars: (apiKey: string, host: string) => ({\n VITE_POSTHOG_PROJECT_TOKEN: apiKey,\n VITE_POSTHOG_HOST: host,\n }),\n },\n\n analytics: {\n getTags: () => ({}),\n },\n\n prompts: {\n projectTypeDetection:\n 'This is a JavaScript/TypeScript project. Look for package.json and lockfiles (package-lock.json, yarn.lock, pnpm-lock.yaml, bun.lockb) to confirm.',\n getAdditionalContextLines: () => {\n const frameworkId = 'vue';\n return [\n `Framework docs ID: ${frameworkId} (use posthog://docs/frameworks/${frameworkId} for documentation)`,\n ];\n },\n },\n\n ui: {\n successMessage: 'PostHog integration complete',\n estimatedDurationMinutes: 5,\n getOutroChanges: () => [\n 'Analyzed your Vue project structure',\n 'Created and configured PostHog initializers',\n 'Integrated PostHog into your application',\n ],\n getOutroNextSteps: () => [\n 'Start your development server to see PostHog in action',\n 'Visit your PostHog dashboard to see incoming events',\n ],\n },\n};\n","import { major } from 'semver';\nimport { tryGetPackageJson } from '@utils/setup-utils';\nimport type { WizardRunOptions } from '@utils/types';\nimport { boundedGlob, readProjectFile } from '@utils/bounded-fs';\nimport { getDeclaredVersion } from '@utils/package-json';\nimport { createVersionBucket } from '@utils/semver';\nimport * as path from 'node:path';\nimport * as semver from 'semver';\n\nexport enum ReactRouterMode {\n V6 = 'v6',\n V7_FRAMEWORK = 'v7-framework',\n V7_DATA = 'v7-data',\n V7_DECLARATIVE = 'v7-declarative',\n}\n\nconst EXTRA_IGNORE = ['**/public/**'];\n\nexport const getReactRouterVersionBucket = createVersionBucket();\n\n/** Content probes read at most this many files, one in memory at a time. */\nconst SOURCE_PROBE_LIMIT = 200;\n\n/** Files that set up a React Router — never a blanket source sweep. */\nconst ROUTER_FILE_GLOBS = [\n '**/routes/**/*.@(ts|tsx|js|jsx)',\n '**/*[Rr]out*.@(ts|tsx|js|jsx)',\n '**/@(main|app|App|index|root).@(ts|tsx|js|jsx)',\n];\n\nasync function hasReactRouterConfig({\n installDir,\n}: Pick<WizardRunOptions, 'installDir'>): Promise<boolean> {\n const configMatches = await boundedGlob(\n '**/react-router.config.@(ts|js|tsx|jsx)',\n {\n cwd: installDir,\n extraIgnore: EXTRA_IGNORE,\n limit: 1,\n },\n );\n return configMatches.length > 0;\n}\n\nasync function hasCreateBrowserRouter({\n installDir,\n}: Pick<WizardRunOptions, 'installDir'>): Promise<boolean> {\n const sourceFiles = await boundedGlob(ROUTER_FILE_GLOBS, {\n cwd: installDir,\n extraIgnore: EXTRA_IGNORE,\n limit: SOURCE_PROBE_LIMIT,\n });\n\n for (const file of sourceFiles) {\n const content = readProjectFile(path.join(installDir, file));\n if (content?.includes('createBrowserRouter')) {\n return true;\n }\n }\n\n return false;\n}\n\nasync function hasDeclarativeRouter({\n installDir,\n}: Pick<WizardRunOptions, 'installDir'>): Promise<boolean> {\n const sourceFiles = await boundedGlob(ROUTER_FILE_GLOBS, {\n cwd: installDir,\n extraIgnore: EXTRA_IGNORE,\n limit: SOURCE_PROBE_LIMIT,\n });\n\n for (const file of sourceFiles) {\n const content = readProjectFile(path.join(installDir, file));\n if (!content) continue;\n if (\n content.includes('<BrowserRouter') ||\n (content.includes('BrowserRouter') &&\n (content.includes('from \"react-router-dom\"') ||\n content.includes(\"from 'react-router-dom'\")))\n ) {\n return true;\n }\n }\n\n return false;\n}\n\n/**\n * Detect React Router mode. Pure — returns null if ambiguous.\n */\nexport async function getReactRouterMode(\n options: WizardRunOptions,\n): Promise<ReactRouterMode | null> {\n const { installDir } = options;\n\n const packageJson = await tryGetPackageJson(options);\n if (!packageJson) return null;\n\n const reactRouterVersion =\n getDeclaredVersion('react-router-dom', packageJson) ||\n getDeclaredVersion('react-router', packageJson);\n\n if (!reactRouterVersion) {\n return null;\n }\n\n const coercedVersion = semver.coerce(reactRouterVersion);\n const majorVersion = coercedVersion ? major(coercedVersion) : null;\n\n if (majorVersion === 6) {\n return ReactRouterMode.V6;\n }\n\n if (majorVersion === 7) {\n const hasConfig = await hasReactRouterConfig({ installDir });\n if (hasConfig) return ReactRouterMode.V7_FRAMEWORK;\n\n const hasDataMode = await hasCreateBrowserRouter({ installDir });\n if (hasDataMode) return ReactRouterMode.V7_DATA;\n\n const hasDeclarative = await hasDeclarativeRouter({ installDir });\n if (hasDeclarative) return ReactRouterMode.V7_DECLARATIVE;\n\n // v7 but can't detect mode\n return null;\n }\n\n return null;\n}\n\nexport function getReactRouterModeName(mode: ReactRouterMode): string {\n switch (mode) {\n case ReactRouterMode.V6:\n return 'v6';\n case ReactRouterMode.V7_FRAMEWORK:\n return 'v7 Framework mode';\n case ReactRouterMode.V7_DATA:\n return 'v7 Data mode';\n case ReactRouterMode.V7_DECLARATIVE:\n return 'v7 Declarative mode';\n }\n}\n","/* React Router wizard using posthog-agent with PostHog MCP */\nimport type { WizardRunOptions } from '@utils/types';\nimport type { FrameworkConfig } from '@lib/framework-config';\nimport { detectNodePackageManagers } from '@lib/detection/package-manager';\nimport { Integration } from '@lib/constants';\nimport {\n getDeclaredVersion,\n getInstalledPackageVersion,\n hasDeclaredDependency,\n type PackageJson,\n} from '@utils/package-json';\nimport { tryGetPackageJson } from '@utils/setup-utils';\nimport { getUI } from '@ui';\nimport {\n getReactRouterMode,\n getReactRouterModeName,\n getReactRouterVersionBucket,\n ReactRouterMode,\n} from './utils';\n\ntype ReactRouterContext = {\n routerMode?: ReactRouterMode;\n};\n\nexport const REACT_ROUTER_AGENT_CONFIG: FrameworkConfig<ReactRouterContext> = {\n metadata: {\n name: 'React Router',\n integration: Integration.reactRouter,\n docsUrl: 'https://posthog.com/docs/libraries/react',\n unsupportedVersionDocsUrl: 'https://posthog.com/docs/libraries/react',\n gatherContext: async (options: WizardRunOptions) => {\n const routerMode = await getReactRouterMode(options);\n if (routerMode) {\n getUI().setDetectedFramework(\n `React Router ${getReactRouterModeName(routerMode)}`,\n );\n return { routerMode };\n }\n return {};\n },\n },\n\n detection: {\n packageName: 'react-router',\n packageDisplayName: 'React Router',\n getVersion: (packageJson: unknown) =>\n getDeclaredVersion('react-router', packageJson as PackageJson),\n getVersionBucket: getReactRouterVersionBucket,\n minimumVersion: '6.0.0',\n getInstalledVersion: (options: WizardRunOptions) =>\n Promise.resolve(\n getInstalledPackageVersion('react-router', options.installDir),\n ),\n detect: async (options) => {\n const packageJson = await tryGetPackageJson(options);\n return packageJson\n ? hasDeclaredDependency('react-router', packageJson)\n : false;\n },\n detectPackageManager: detectNodePackageManagers,\n },\n\n environment: {\n uploadToHosting: false,\n getEnvVars: (apiKey: string, host: string) => ({\n REACT_APP_POSTHOG_PROJECT_TOKEN: apiKey,\n REACT_APP_POSTHOG_HOST: host,\n }),\n },\n\n analytics: {\n getTags: (context) => ({\n routerMode: context.routerMode || 'unknown',\n }),\n },\n\n prompts: {\n projectTypeDetection:\n 'This is a JavaScript/TypeScript project. Look for package.json and lockfiles (package-lock.json, yarn.lock, pnpm-lock.yaml, bun.lockb) to confirm.',\n getAdditionalContextLines: (context) => {\n const routerMode = context.routerMode;\n const modeName = routerMode\n ? getReactRouterModeName(routerMode)\n : 'unknown';\n\n // Map router mode to framework ID for MCP docs resource\n const frameworkIdMap: Record<ReactRouterMode, string> = {\n [ReactRouterMode.V6]: 'react-react-router-6',\n [ReactRouterMode.V7_FRAMEWORK]: 'react-react-router-7-framework',\n [ReactRouterMode.V7_DATA]: 'react-react-router-7-data',\n [ReactRouterMode.V7_DECLARATIVE]: 'react-react-router-7-declarative',\n };\n\n const frameworkId = routerMode\n ? frameworkIdMap[routerMode]\n : ReactRouterMode.V7_FRAMEWORK;\n\n return [\n `Router mode: ${modeName}`,\n `Framework docs ID: ${frameworkId} (use posthog://docs/frameworks/${frameworkId} for documentation)`,\n ];\n },\n },\n\n ui: {\n successMessage: 'PostHog integration complete',\n estimatedDurationMinutes: 8,\n getOutroChanges: (context) => {\n const modeName = context.routerMode\n ? getReactRouterModeName(context.routerMode)\n : 'React Router';\n return [\n `Analyzed your React Router project structure (${modeName})`,\n `Created and configured PostHog initializers`,\n `Integrated PostHog into your application`,\n ];\n },\n getOutroNextSteps: () => [\n 'Start your development server to see PostHog in action',\n 'Visit your PostHog dashboard to see incoming events',\n ],\n },\n};\n","import type { WizardRunOptions } from '@utils/types';\nimport { boundedGlob, readProjectFile } from '@utils/bounded-fs';\nimport { hasDeclaredDependency } from '@utils/package-json';\nimport { createVersionBucket } from '@utils/semver';\nimport * as fs from 'node:fs';\nimport * as path from 'node:path';\n\nexport enum TanStackRouterMode {\n FILE_BASED = 'file-based',\n CODE_BASED = 'code-based',\n}\n\nconst EXTRA_IGNORE = ['**/public/**', '**/.vinxi/**', '**/.output/**'];\n\nexport const getTanStackRouterVersionBucket = createVersionBucket();\n\n/** Content probes read at most this many files, one in memory at a time. */\nconst SOURCE_PROBE_LIMIT = 200;\n\n/** Files that define TanStack routes — never a blanket source sweep. */\nconst ROUTE_FILE_GLOBS = [\n '**/routes/**/*.@(ts|tsx|js|jsx)',\n '**/*[Rr]oute*.@(ts|tsx|js|jsx)',\n '**/@(main|router|app|App|index).@(ts|tsx|js|jsx)',\n];\n\nasync function hasFileBasedRouting({\n installDir,\n}: Pick<WizardRunOptions, 'installDir'>): Promise<boolean> {\n const generatedFiles = await boundedGlob(\n '**/routeTree.gen.@(ts|tsx|js|jsx)',\n {\n cwd: installDir,\n extraIgnore: EXTRA_IGNORE,\n limit: 1,\n },\n );\n\n if (generatedFiles.length > 0) {\n return true;\n }\n\n try {\n const packageJsonPath = path.join(installDir, 'package.json');\n const content = fs.readFileSync(packageJsonPath, 'utf-8');\n const packageJson = JSON.parse(content) as Record<string, unknown>;\n\n if (\n hasDeclaredDependency('@tanstack/router-plugin', packageJson) ||\n hasDeclaredDependency('@tanstack/router-vite-plugin', packageJson)\n ) {\n return true;\n }\n } catch {\n // package.json not found or unreadable\n }\n\n const sourceFiles = await boundedGlob(ROUTE_FILE_GLOBS, {\n cwd: installDir,\n extraIgnore: EXTRA_IGNORE,\n limit: SOURCE_PROBE_LIMIT,\n });\n\n for (const file of sourceFiles) {\n const content = readProjectFile(path.join(installDir, file));\n if (content?.includes('createFileRoute')) {\n return true;\n }\n }\n\n return false;\n}\n\nasync function hasCodeBasedRouting({\n installDir,\n}: Pick<WizardRunOptions, 'installDir'>): Promise<boolean> {\n const sourceFiles = await boundedGlob(ROUTE_FILE_GLOBS, {\n cwd: installDir,\n extraIgnore: EXTRA_IGNORE,\n limit: SOURCE_PROBE_LIMIT,\n });\n\n let hasCreateRoute = false;\n let hasCreateFileRoute = false;\n\n for (const file of sourceFiles) {\n const content = readProjectFile(path.join(installDir, file));\n if (!content) continue;\n\n if (content.includes('createRoute(')) {\n hasCreateRoute = true;\n }\n if (content.includes('createFileRoute')) {\n hasCreateFileRoute = true;\n }\n }\n\n return hasCreateRoute && !hasCreateFileRoute;\n}\n\n/**\n * Detect TanStack Router mode. Pure — returns null if ambiguous.\n */\nexport async function getTanStackRouterMode(\n options: WizardRunOptions,\n): Promise<TanStackRouterMode | null> {\n const { installDir } = options;\n\n const isFileBased = await hasFileBasedRouting({ installDir });\n if (isFileBased) {\n return TanStackRouterMode.FILE_BASED;\n }\n\n const isCodeBased = await hasCodeBasedRouting({ installDir });\n if (isCodeBased) {\n return TanStackRouterMode.CODE_BASED;\n }\n\n return null;\n}\n\nexport function getTanStackRouterModeName(mode: TanStackRouterMode): string {\n switch (mode) {\n case TanStackRouterMode.FILE_BASED:\n return 'File-based routing';\n case TanStackRouterMode.CODE_BASED:\n return 'Code-based routing';\n }\n}\n","/* TanStack Router wizard using posthog-agent with PostHog MCP */\nimport type { WizardRunOptions } from '@utils/types';\nimport type { FrameworkConfig } from '@lib/framework-config';\nimport { detectNodePackageManagers } from '@lib/detection/package-manager';\nimport { Integration } from '@lib/constants';\nimport {\n getDeclaredVersion,\n getInstalledPackageVersion,\n hasDeclaredDependency,\n type PackageJson,\n} from '@utils/package-json';\nimport { tryGetPackageJson } from '@utils/setup-utils';\nimport { getUI } from '@ui';\nimport {\n getTanStackRouterMode,\n getTanStackRouterModeName,\n getTanStackRouterVersionBucket,\n TanStackRouterMode,\n} from './utils';\n\ntype TanStackRouterContext = {\n routerMode?: TanStackRouterMode;\n};\n\nexport const TANSTACK_ROUTER_AGENT_CONFIG: FrameworkConfig<TanStackRouterContext> =\n {\n metadata: {\n name: 'React (TanStack Router)',\n integration: Integration.tanstackRouter,\n docsUrl: 'https://posthog.com/docs/libraries/react',\n gatherContext: async (options: WizardRunOptions) => {\n const routerMode = await getTanStackRouterMode(options);\n if (routerMode) {\n getUI().setDetectedFramework(\n `TanStack Router ${getTanStackRouterModeName(routerMode)}`,\n );\n return { routerMode };\n }\n return {};\n },\n },\n\n detection: {\n packageName: '@tanstack/react-router',\n packageDisplayName: 'TanStack Router',\n getVersion: (packageJson: unknown) =>\n getDeclaredVersion(\n '@tanstack/react-router',\n packageJson as PackageJson,\n ),\n getVersionBucket: getTanStackRouterVersionBucket,\n minimumVersion: '1.0.0',\n getInstalledVersion: (options: WizardRunOptions) =>\n Promise.resolve(\n getInstalledPackageVersion(\n '@tanstack/react-router',\n options.installDir,\n ),\n ),\n detect: async (options) => {\n const packageJson = await tryGetPackageJson(options);\n if (!packageJson) {\n return false;\n }\n // Exclude TanStack Start projects (they have their own integration)\n if (hasDeclaredDependency('@tanstack/react-start', packageJson)) {\n return false;\n }\n return hasDeclaredDependency('@tanstack/react-router', packageJson);\n },\n detectPackageManager: detectNodePackageManagers,\n },\n\n environment: {\n uploadToHosting: false,\n getEnvVars: (apiKey: string, host: string) => ({\n VITE_PUBLIC_POSTHOG_PROJECT_TOKEN: apiKey,\n VITE_PUBLIC_POSTHOG_HOST: host,\n }),\n },\n\n analytics: {\n getTags: (context) => ({\n routerMode: context.routerMode || 'unknown',\n }),\n },\n\n prompts: {\n projectTypeDetection:\n 'This is a JavaScript/TypeScript project. Look for package.json and lockfiles (package-lock.json, yarn.lock, pnpm-lock.yaml, bun.lockb) to confirm.',\n getAdditionalContextLines: (context) => {\n const routerMode = context.routerMode;\n const modeName = routerMode\n ? getTanStackRouterModeName(routerMode)\n : 'unknown';\n\n // Map router mode to framework ID for MCP docs resource\n const frameworkIdMap: Record<TanStackRouterMode, string> = {\n [TanStackRouterMode.FILE_BASED]: 'react-tanstack-router-file-based',\n [TanStackRouterMode.CODE_BASED]: 'react-tanstack-router-code-based',\n };\n\n const frameworkId = routerMode\n ? frameworkIdMap[routerMode]\n : 'react-tanstack-router-file-based';\n\n return [\n `Router mode: ${modeName}`,\n `Framework docs ID: ${frameworkId} (use posthog://docs/frameworks/${frameworkId} for documentation)`,\n ];\n },\n },\n\n ui: {\n successMessage: 'PostHog integration complete',\n estimatedDurationMinutes: 8,\n getOutroChanges: (context) => {\n const modeName = context.routerMode\n ? getTanStackRouterModeName(context.routerMode)\n : 'TanStack Router';\n return [\n `Analyzed your React (TanStack Router) project structure (${modeName})`,\n `Created and configured PostHog initializers`,\n `Integrated PostHog into your application`,\n ];\n },\n getOutroNextSteps: () => [\n 'Start your development server to see PostHog in action',\n 'Visit your PostHog dashboard to see incoming events',\n ],\n },\n };\n","import { createVersionBucket } from '@utils/semver';\n\n/**\n * Get TanStack Start version bucket for analytics\n */\nexport const getTanStackStartVersionBucket = createVersionBucket();\n","/* TanStack Start wizard using posthog-agent with PostHog MCP */\nimport type { WizardRunOptions } from '@utils/types';\nimport type { FrameworkConfig } from '@lib/framework-config';\nimport { detectNodePackageManagers } from '@lib/detection/package-manager';\nimport { Integration } from '@lib/constants';\nimport {\n getDeclaredVersion,\n getInstalledPackageVersion,\n hasDeclaredDependency,\n type PackageJson,\n} from '@utils/package-json';\nimport { tryGetPackageJson } from '@utils/setup-utils';\nimport { getTanStackStartVersionBucket } from './utils';\n\ntype TanStackStartContext = Record<string, unknown>;\n\nexport const TANSTACK_START_AGENT_CONFIG: FrameworkConfig<TanStackStartContext> =\n {\n metadata: {\n name: 'TanStack Start',\n integration: Integration.tanstackStart,\n docsUrl: 'https://posthog.com/docs/libraries/react',\n },\n\n detection: {\n packageName: '@tanstack/react-start',\n packageDisplayName: 'TanStack Start',\n getVersion: (packageJson: unknown) =>\n getDeclaredVersion('@tanstack/react-start', packageJson as PackageJson),\n getVersionBucket: getTanStackStartVersionBucket,\n minimumVersion: '1.0.0',\n getInstalledVersion: (options: WizardRunOptions) =>\n Promise.resolve(\n getInstalledPackageVersion(\n '@tanstack/react-start',\n options.installDir,\n ),\n ),\n detect: async (options) => {\n const packageJson = await tryGetPackageJson(options);\n return packageJson\n ? hasDeclaredDependency('@tanstack/react-start', packageJson)\n : false;\n },\n detectPackageManager: detectNodePackageManagers,\n },\n\n environment: {\n uploadToHosting: false,\n getEnvVars: (apiKey: string, host: string) => ({\n VITE_PUBLIC_POSTHOG_PROJECT_TOKEN: apiKey,\n VITE_PUBLIC_POSTHOG_HOST: host,\n }),\n },\n\n analytics: {\n getTags: () => ({}),\n },\n\n prompts: {\n projectTypeDetection:\n 'This is a JavaScript/TypeScript project. Look for package.json and lockfiles (package-lock.json, yarn.lock, pnpm-lock.yaml, bun.lockb) to confirm.',\n getAdditionalContextLines: () => {\n // TanStack Start always uses file-based routing (it's a full-stack framework built on TanStack Router)\n const frameworkId = 'react-tanstack-start';\n\n return [\n `Framework docs ID: ${frameworkId} (use posthog://docs/frameworks/${frameworkId} for documentation)`,\n ];\n },\n },\n\n ui: {\n successMessage: 'PostHog integration complete',\n estimatedDurationMinutes: 8,\n getOutroChanges: () => [\n `Analyzed your TanStack Start project structure`,\n `Created and configured PostHog initializers`,\n `Integrated PostHog into your application`,\n ],\n getOutroNextSteps: () => [\n 'Start your development server to see PostHog in action',\n 'Visit your PostHog dashboard to see incoming events',\n ],\n },\n };\n","import { createVersionBucket } from '@utils/semver';\nimport { tryGetPackageJson } from '@utils/setup-utils';\nimport { hasDeclaredDependency } from '@utils/package-json';\nimport { getUI } from '@ui';\nimport type { WizardRunOptions } from '@utils/types';\n\nexport const getReactNativeVersionBucket = createVersionBucket();\n\nexport enum ReactNativeVariant {\n EXPO = 'expo',\n REACT_NATIVE = 'react-native',\n}\n\nexport function getReactNativeVariantName(variant: ReactNativeVariant): string {\n return variant === ReactNativeVariant.EXPO ? 'Expo' : 'React Native';\n}\n\nexport async function detectReactNativeVariant(\n options: Pick<WizardRunOptions, 'installDir'>,\n): Promise<ReactNativeVariant> {\n const packageJson = await tryGetPackageJson(options);\n\n if (packageJson && hasDeclaredDependency('expo', packageJson)) {\n getUI().setDetectedFramework(\n `${getReactNativeVariantName(ReactNativeVariant.EXPO)} 📱`,\n );\n return ReactNativeVariant.EXPO;\n }\n\n getUI().setDetectedFramework(\n `${getReactNativeVariantName(ReactNativeVariant.REACT_NATIVE)} 📱`,\n );\n return ReactNativeVariant.REACT_NATIVE;\n}\n","/* React Native wizard using posthog-agent with PostHog MCP */\nimport type { WizardRunOptions } from '@utils/types';\nimport type { FrameworkConfig } from '@lib/framework-config';\nimport { detectNodePackageManagers } from '@lib/detection/package-manager';\nimport { Integration } from '@lib/constants';\nimport {\n getDeclaredVersion,\n getInstalledPackageVersion,\n hasDeclaredDependency,\n type PackageJson,\n} from '@utils/package-json';\nimport { tryGetPackageJson } from '@utils/setup-utils';\nimport {\n detectReactNativeVariant,\n getReactNativeVariantName,\n getReactNativeVersionBucket,\n ReactNativeVariant,\n} from './utils';\n\ntype ReactNativeContext = {\n variant?: ReactNativeVariant;\n};\n\nexport const REACT_NATIVE_AGENT_CONFIG: FrameworkConfig<ReactNativeContext> = {\n metadata: {\n name: 'React Native',\n integration: Integration.reactNative,\n docsUrl: 'https://posthog.com/docs/libraries/react-native',\n gatherContext: async (options: WizardRunOptions) => {\n const variant = await detectReactNativeVariant(options);\n return { variant };\n },\n },\n\n detection: {\n packageName: 'react-native',\n packageDisplayName: 'React Native',\n getVersion: (packageJson: unknown) =>\n getDeclaredVersion('react-native', packageJson as PackageJson),\n getVersionBucket: getReactNativeVersionBucket,\n minimumVersion: '0.73.0',\n getInstalledVersion: (options: WizardRunOptions) =>\n Promise.resolve(\n getInstalledPackageVersion('react-native', options.installDir),\n ),\n detect: async (options) => {\n const packageJson = await tryGetPackageJson(options);\n return packageJson\n ? hasDeclaredDependency('react-native', packageJson)\n : false;\n },\n detectPackageManager: detectNodePackageManagers,\n },\n\n environment: {\n uploadToHosting: false,\n getEnvVars: (apiKey: string, host: string) => ({\n POSTHOG_PROJECT_TOKEN: apiKey,\n POSTHOG_HOST: host,\n }),\n },\n\n analytics: {\n getTags: (context) => ({\n variant:\n context.variant === ReactNativeVariant.EXPO ? 'expo' : 'react-native',\n }),\n },\n\n prompts: {\n projectTypeDetection:\n 'This is a React Native project. Look for package.json, android/ and ios/ directories, and lockfiles to confirm. Check for expo in package.json to determine the variant.',\n getAdditionalContextLines: (context) => {\n const isExpo = context.variant === ReactNativeVariant.EXPO;\n const frameworkId = 'react-native';\n\n const lines = [\n `Framework docs ID: ${frameworkId} (use posthog://docs/frameworks/${frameworkId} for documentation)`,\n `Variant: ${isExpo ? 'Expo' : 'React Native'}`,\n ];\n\n if (isExpo) {\n lines.push(\n 'Use `npx expo install` for package installation.',\n 'Use EXPO_PUBLIC_ prefix for environment variables exposed to the client.',\n );\n } else {\n lines.push(\n 'This is a React Native project without Expo. Native linking may be required.',\n 'For iOS, ensure pods are installed after adding PostHog.',\n );\n }\n\n return lines;\n },\n },\n\n ui: {\n successMessage: 'PostHog integration complete',\n estimatedDurationMinutes: 10,\n getOutroChanges: (context) => {\n const variant = context.variant ?? ReactNativeVariant.REACT_NATIVE;\n const variantName = getReactNativeVariantName(variant);\n return [\n `Analyzed your React Native project structure (${variantName})`,\n `Installed and configured the PostHog React Native SDK`,\n `Integrated PostHog into your application`,\n ];\n },\n getOutroNextSteps: (context) => {\n const isExpo = context.variant === ReactNativeVariant.EXPO;\n const steps = [];\n\n if (!isExpo) {\n steps.push('Run `npx pod-install` to install iOS dependencies');\n }\n\n steps.push(\n isExpo\n ? 'Start your development server with `npx expo start` to see PostHog in action'\n : 'Start your development server to see PostHog in action',\n 'Visit your PostHog dashboard to see incoming events',\n );\n\n return steps;\n },\n },\n};\n","import { createVersionBucket } from '@utils/semver';\n\n/**\n * Get Angular version bucket for analytics\n */\nexport const getAngularVersionBucket = createVersionBucket();\n","/* Angular wizard using posthog-agent with PostHog MCP */\nimport type { WizardRunOptions } from '@utils/types';\nimport type { FrameworkConfig } from '@lib/framework-config';\nimport { detectNodePackageManagers } from '@lib/detection/package-manager';\nimport { Integration } from '@lib/constants';\nimport {\n getDeclaredVersion,\n getInstalledPackageVersion,\n hasDeclaredDependency,\n type PackageJson,\n} from '@utils/package-json';\nimport { tryGetPackageJson } from '@utils/setup-utils';\nimport { getAngularVersionBucket } from './utils';\n\ntype AngularContext = Record<string, unknown>;\n\nexport const ANGULAR_AGENT_CONFIG: FrameworkConfig<AngularContext> = {\n metadata: {\n name: 'Angular',\n integration: Integration.angular,\n docsUrl: 'https://posthog.com/docs/libraries/angular',\n },\n\n detection: {\n packageName: '@angular/core',\n packageDisplayName: 'Angular',\n getVersion: (packageJson: unknown) =>\n getDeclaredVersion('@angular/core', packageJson as PackageJson),\n getVersionBucket: getAngularVersionBucket,\n minimumVersion: '19.0.0',\n getInstalledVersion: (options: WizardRunOptions) =>\n Promise.resolve(\n getInstalledPackageVersion('@angular/core', options.installDir),\n ),\n detect: async (options) => {\n const packageJson = await tryGetPackageJson(options);\n return packageJson\n ? hasDeclaredDependency('@angular/core', packageJson)\n : false;\n },\n detectPackageManager: detectNodePackageManagers,\n },\n\n environment: {\n uploadToHosting: false,\n getEnvVars: (apiKey: string, host: string) => ({\n NG_APP_POSTHOG_PROJECT_TOKEN: apiKey,\n NG_APP_POSTHOG_HOST: host,\n }),\n },\n\n analytics: {\n getTags: () => ({}),\n },\n\n prompts: {\n projectTypeDetection:\n 'This is an Angular project. Look for package.json, angular.json, and lockfiles (package-lock.json, yarn.lock, pnpm-lock.yaml) to confirm.',\n getAdditionalContextLines: () => {\n const frameworkId = 'angular';\n\n return [\n `Framework docs ID: ${frameworkId} (use posthog://docs/frameworks/${frameworkId} for documentation)`,\n 'Angular uses dependency injection for services. PostHog should be initialized as a service.',\n 'For standalone components, ensure PostHog is properly provided in the application config.',\n ];\n },\n },\n\n ui: {\n successMessage: 'PostHog integration complete',\n estimatedDurationMinutes: 8,\n getOutroChanges: () => [\n `Analyzed your Angular project structure`,\n `Created and configured PostHog service`,\n `Integrated PostHog into your application`,\n ],\n getOutroNextSteps: () => [\n 'Start your development server with `ng serve` to see PostHog in action',\n 'Visit your PostHog dashboard to see incoming events',\n ],\n },\n};\n","import { boundedGlob, readProjectFile } from '@utils/bounded-fs';\nimport fs from 'fs/promises';\nimport path from 'path';\nimport type { WizardRunOptions } from '@utils/types';\nimport { createVersionBucket } from '@utils/semver';\n\nexport const getAstroVersionBucket = createVersionBucket();\n\nexport enum AstroRenderingMode {\n STATIC = 'static',\n SSR = 'ssr',\n HYBRID = 'hybrid',\n VIEW_TRANSITIONS = 'view-transitions',\n}\n\nconst EXTRA_IGNORE = ['**/.astro/**'];\n\n/**\n * Detect the Astro rendering mode. Pure — always resolves (Astro detection is reliable).\n */\nexport async function getAstroRenderingMode({\n installDir,\n}: Pick<WizardRunOptions, 'installDir'>): Promise<AstroRenderingMode> {\n const configMatches = await boundedGlob('astro.config.@(mjs|ts|js)', {\n cwd: installDir,\n extraIgnore: EXTRA_IGNORE,\n limit: 1,\n });\n\n let hasAdapter = false;\n let outputMode: string | null = null;\n let usesViewTransitions = false;\n\n try {\n const packageJsonPath = path.join(installDir, 'package.json');\n const packageJsonContent = await fs.readFile(packageJsonPath, 'utf-8');\n const packageJson = JSON.parse(packageJsonContent);\n const allDeps = {\n ...packageJson.dependencies,\n ...packageJson.devDependencies,\n };\n\n hasAdapter = Object.keys(allDeps).some(\n (dep) =>\n dep.startsWith('@astrojs/') &&\n (dep.includes('node') ||\n dep.includes('vercel') ||\n dep.includes('netlify') ||\n dep.includes('cloudflare') ||\n dep.includes('deno')),\n );\n } catch {\n // package.json not found or invalid\n }\n\n if (configMatches.length > 0) {\n try {\n const configPath = path.join(installDir, configMatches[0]);\n const configContent = await fs.readFile(configPath, 'utf-8');\n const outputMatch = configContent.match(/output:\\s*['\"](\\w+)['\"]/);\n if (outputMatch) {\n outputMode = outputMatch[1];\n }\n } catch {\n // Config file not readable\n }\n }\n\n const viewTransitionMatches = await boundedGlob(\n '**/*.@(astro|ts|tsx|js|jsx)',\n {\n cwd: installDir,\n extraIgnore: EXTRA_IGNORE,\n limit: 20,\n },\n );\n\n for (const file of viewTransitionMatches) {\n const content = readProjectFile(path.join(installDir, file));\n if (!content) continue;\n if (\n content.includes('ClientRouter') ||\n content.includes('ViewTransitions') ||\n content.includes('astro:transitions')\n ) {\n usesViewTransitions = true;\n break;\n }\n }\n\n if (usesViewTransitions) {\n return AstroRenderingMode.VIEW_TRANSITIONS;\n }\n\n if (outputMode === 'server' && hasAdapter) {\n return AstroRenderingMode.SSR;\n }\n\n if (hasAdapter) {\n return AstroRenderingMode.HYBRID;\n }\n\n return AstroRenderingMode.STATIC;\n}\n\nexport const getAstroRenderingModeName = (mode: AstroRenderingMode): string => {\n switch (mode) {\n case AstroRenderingMode.STATIC:\n return 'Static (SSG)';\n case AstroRenderingMode.VIEW_TRANSITIONS:\n return 'View Transitions';\n case AstroRenderingMode.SSR:\n return 'Server (SSR)';\n case AstroRenderingMode.HYBRID:\n return 'Hybrid';\n default:\n return 'Static';\n }\n};\n","/* Astro wizard using posthog-agent with PostHog MCP */\nimport type { WizardRunOptions } from '@utils/types';\nimport type { FrameworkConfig } from '@lib/framework-config';\nimport { detectNodePackageManagers } from '@lib/detection/package-manager';\nimport { Integration } from '@lib/constants';\nimport {\n getDeclaredVersion,\n getInstalledPackageVersion,\n hasDeclaredDependency,\n type PackageJson,\n} from '@utils/package-json';\nimport { tryGetPackageJson } from '@utils/setup-utils';\nimport { getUI } from '@ui';\nimport {\n getAstroRenderingMode,\n getAstroVersionBucket,\n getAstroRenderingModeName,\n AstroRenderingMode,\n} from './utils';\n\ntype AstroContext = {\n renderingMode?: AstroRenderingMode;\n};\n\nexport const ASTRO_AGENT_CONFIG: FrameworkConfig<AstroContext> = {\n metadata: {\n name: 'Astro',\n integration: Integration.astro,\n docsUrl: 'https://posthog.com/docs/libraries/astro',\n gatherContext: async (options: WizardRunOptions) => {\n const renderingMode = await getAstroRenderingMode(options);\n getUI().setDetectedFramework(\n `Astro ${getAstroRenderingModeName(renderingMode)}`,\n );\n return { renderingMode };\n },\n },\n\n detection: {\n packageName: 'astro',\n packageDisplayName: 'Astro',\n getVersion: (packageJson: unknown) =>\n getDeclaredVersion('astro', packageJson as PackageJson),\n getVersionBucket: getAstroVersionBucket,\n minimumVersion: '4.0.0',\n getInstalledVersion: (options: WizardRunOptions) =>\n Promise.resolve(getInstalledPackageVersion('astro', options.installDir)),\n detect: async (options) => {\n const packageJson = await tryGetPackageJson(options);\n return packageJson ? hasDeclaredDependency('astro', packageJson) : false;\n },\n detectPackageManager: detectNodePackageManagers,\n },\n\n environment: {\n uploadToHosting: true,\n getEnvVars: (apiKey: string, host: string) => ({\n PUBLIC_POSTHOG_PROJECT_TOKEN: apiKey,\n PUBLIC_POSTHOG_HOST: host,\n }),\n },\n\n analytics: {\n getTags: (context) => ({\n 'rendering-mode': context.renderingMode ?? 'static',\n }),\n },\n\n prompts: {\n projectTypeDetection:\n 'This is a JavaScript/TypeScript project. Look for package.json and lockfiles (package-lock.json, yarn.lock, pnpm-lock.yaml, bun.lockb) to confirm.',\n getAdditionalContextLines: (context) => {\n const modeName = getAstroRenderingModeName(\n context.renderingMode ?? AstroRenderingMode.STATIC,\n );\n\n // Map rendering mode to framework ID for MCP docs resource\n const frameworkIdMap: Record<AstroRenderingMode, string> = {\n [AstroRenderingMode.STATIC]: 'astro-static',\n [AstroRenderingMode.VIEW_TRANSITIONS]: 'astro-view-transitions',\n [AstroRenderingMode.SSR]: 'astro-ssr',\n [AstroRenderingMode.HYBRID]: 'astro-hybrid',\n };\n\n const frameworkId =\n frameworkIdMap[context.renderingMode ?? AstroRenderingMode.STATIC];\n\n const lines = [\n `Rendering mode: ${modeName}`,\n `Framework docs ID: ${frameworkId} (use posthog://docs/frameworks/${frameworkId} for documentation)`,\n ];\n\n // Add mode-specific guidance\n if (context.renderingMode === AstroRenderingMode.VIEW_TRANSITIONS) {\n lines.push(\n 'IMPORTANT: Use window.__posthog_initialized guard to prevent re-initialization during soft navigation',\n );\n lines.push(\n \"IMPORTANT: Set capture_pageview: 'history_change' for automatic pageview tracking\",\n );\n }\n\n if (\n context.renderingMode === AstroRenderingMode.SSR ||\n context.renderingMode === AstroRenderingMode.HYBRID\n ) {\n lines.push(\n 'IMPORTANT: Use posthog-node for server-side tracking in API routes',\n );\n lines.push(\n 'IMPORTANT: Create a singleton pattern for the posthog-node client',\n );\n }\n\n return lines;\n },\n },\n\n ui: {\n successMessage: 'PostHog integration complete',\n estimatedDurationMinutes: 6,\n getOutroChanges: (context) => {\n const modeName = getAstroRenderingModeName(\n context.renderingMode ?? AstroRenderingMode.STATIC,\n );\n const changes = [\n `Analyzed your Astro project structure (${modeName})`,\n `Created PostHog component with is:inline script`,\n `Integrated PostHog into your layout`,\n ];\n\n if (\n context.renderingMode === AstroRenderingMode.SSR ||\n context.renderingMode === AstroRenderingMode.HYBRID\n ) {\n changes.push(`Set up posthog-node for server-side tracking`);\n }\n\n if (context.renderingMode === AstroRenderingMode.VIEW_TRANSITIONS) {\n changes.push(\n `Added initialization guard for view transitions compatibility`,\n );\n }\n\n return changes;\n },\n getOutroNextSteps: () => {\n return [\n 'Start your development server to see PostHog in action',\n 'Visit your PostHog dashboard to see incoming events',\n ];\n },\n },\n};\n","import type { Integration } from './constants';\nimport type { WizardRunOptions } from '@utils/types';\nimport type { PackageManagerDetector } from './detection/package-manager';\n\n/**\n * A setup question that the SetupScreen renders for framework disambiguation.\n * If detect() returns a value, the question is auto-resolved and not shown.\n */\nexport interface SetupQuestion {\n /** Stored in session.frameworkContext[key] */\n key: string;\n /** Displayed to user, e.g. \"Which router are you using?\" */\n message: string;\n /** Picker options */\n options: Array<{ label: string; value: string; hint?: string }>;\n /** Auto-detect; null = ask the user */\n detect: (\n options: Pick<WizardRunOptions, 'installDir'>,\n ) => Promise<string | null>;\n}\n\n/**\n * Configuration interface for framework-specific agent integrations.\n * Each framework exports a FrameworkConfig that the universal runner uses.\n *\n * The TContext generic represents the framework-specific context gathered\n * before the agent runs (e.g., router type for Next.js, project type for Django).\n * The runner threads this opaquely — all framework-specific logic stays inside the config.\n */\nexport interface FrameworkConfig<\n TContext extends Record<string, unknown> = Record<string, unknown>,\n> {\n metadata: FrameworkMetadata<TContext>;\n detection: FrameworkDetection;\n environment: EnvironmentConfig;\n analytics: AnalyticsConfig<TContext>;\n prompts: PromptConfig<TContext>;\n ui: UIConfig<TContext>;\n}\n\n/**\n * Basic framework information and documentation\n */\nexport interface FrameworkMetadata<\n TContext extends Record<string, unknown> = Record<string, unknown>,\n> {\n /** Display name (e.g., \"Next.js\", \"React\") */\n name: string;\n\n /** Integration type from constants */\n integration: Integration;\n\n /** URL to framework-specific PostHog docs */\n docsUrl: string;\n\n /**\n * Optional URL to docs for users with unsupported framework versions.\n * If not provided, defaults to docsUrl.\n */\n unsupportedVersionDocsUrl?: string;\n\n /** If true, shows a beta notice before running the wizard. */\n beta?: boolean;\n\n /** Optional notice shown before the agent runs (e.g., \"Close Xcode before proceeding\"). */\n preRunNotice?: string;\n\n /**\n * Optional function to gather framework-specific context before agent runs.\n * For Next.js: detects router type\n * For React Native: detects Expo vs bare\n */\n gatherContext?: (options: WizardRunOptions) => Promise<TContext>;\n\n /** Optional additional MCP servers for this framework (e.g., Svelte MCP). */\n additionalMcpServers?: Record<string, { url: string }>;\n\n /**\n * Setup questions for framework disambiguation.\n * The SetupScreen iterates unresolved questions and renders a PickerMenu for each.\n * If all questions are auto-resolved (or none defined), the screen is skipped.\n */\n setup?: {\n questions: SetupQuestion[];\n };\n}\n\n/**\n * Framework detection and version handling\n */\nexport interface FrameworkDetection {\n /** Package name to check in package.json (e.g., \"next\", \"react\") */\n packageName: string;\n\n /** Human-readable name for error messages (e.g., \"Next.js\") */\n packageDisplayName: string;\n\n /** Extract version from package.json */\n getVersion: (packageJson: unknown) => string | undefined;\n\n /** Optional: Convert version to analytics bucket (e.g., \"15.x\") */\n getVersionBucket?: (version: string) => string;\n\n /**\n * Whether this framework uses package.json (Node.js/JavaScript).\n * If false, skips package.json checks (for Python, Go, etc.)\n * Defaults to true if not specified.\n */\n usesPackageJson?: boolean;\n\n /** Minimum supported version. If set, runner checks before proceeding. */\n minimumVersion?: string;\n\n /** Get the currently installed version. Called by runner for version check. */\n getInstalledVersion?: (\n options: WizardRunOptions,\n ) => Promise<string | undefined>;\n\n /** Detect whether this framework is present in the project. */\n detect: (options: Pick<WizardRunOptions, 'installDir'>) => Promise<boolean>;\n\n /** Detect the project's package manager(s). Used by the in-process MCP tool. */\n detectPackageManager: PackageManagerDetector;\n}\n\n/**\n * Environment variable configuration\n */\nexport interface EnvironmentConfig {\n /** Whether to upload env vars to hosting providers post-agent */\n uploadToHosting: boolean;\n\n /**\n * Build the environment variables object for this framework.\n * Returns the exact variable names and values to upload to hosting providers.\n */\n getEnvVars: (apiKey: string, host: string) => Record<string, string>;\n}\n\n/**\n * Analytics configuration\n */\nexport interface AnalyticsConfig<\n TContext extends Record<string, unknown> = Record<string, unknown>,\n> {\n /** Generate tags from context (e.g., { 'nextjs-version': '15.x', 'router': 'app' }) */\n getTags: (context: TContext) => Record<string, string>;\n\n /** Optional: Additional event properties */\n getEventProperties?: (context: TContext) => Record<string, string>;\n}\n\n/**\n * Default package installation instruction used when frameworks don't\n * provide their own. Frameworks with specific needs (e.g., Swift SPM,\n * Composer) override this in their config.\n */\nexport const DEFAULT_PACKAGE_INSTALLATION =\n 'Use the detect_package_manager tool to determine the package manager. Do not manually edit package.json; the package manager handles it automatically.';\n\nexport const PYTHON_PACKAGE_INSTALLATION =\n 'Use the detect_package_manager tool to determine the package manager. If the detected tool manages dependencies directly (e.g. uv add, poetry add), use it — it will update the manifest automatically. If using pip, you must also add the dependency to requirements.txt or the appropriate manifest file.';\n\n/**\n * Prompt configuration\n */\nexport interface PromptConfig<\n TContext extends Record<string, unknown> = Record<string, unknown>,\n> {\n /**\n * Optional: Additional context lines to append to base prompt\n * For Next.js: \"- Router: app\"\n * For React Native: \"- Platform: Expo\"\n */\n getAdditionalContextLines?: (context: TContext) => string[];\n\n /**\n * How to detect the project type for this framework.\n * Included in the agent prompt as project context.\n * e.g., \"Look for package.json and lockfiles\" or \"Look for requirements.txt and manage.py\"\n */\n projectTypeDetection: string;\n\n /**\n * How to install packages for this framework.\n * Included in the agent prompt as project context.\n * Defaults to DEFAULT_PACKAGE_INSTALLATION. Only override if the framework\n * has specific installation guidance (e.g., Swift SPM, Composer).\n */\n packageInstallation?: string;\n}\n\n/**\n * UI messaging configuration\n */\nexport interface UIConfig<\n TContext extends Record<string, unknown> = Record<string, unknown>,\n> {\n /** Success message when agent completes */\n successMessage: string;\n\n /** Estimated time for agent to complete (in minutes) */\n estimatedDurationMinutes: number;\n\n /** Generate \"What the agent did\" bullets from context */\n getOutroChanges: (context: TContext) => string[];\n\n /** Generate \"Next steps\" bullets from context */\n getOutroNextSteps: (context: TContext) => string[];\n}\n\n/**\n * Generate welcome message from framework name\n */\nexport function getWelcomeMessage(frameworkName: string): string {\n return `PostHog ${frameworkName} wizard (agent-powered)`;\n}\n\n/**\n * Shared spinner message for all frameworks\n */\nexport const SPINNER_MESSAGE =\n 'Writing your PostHog setup with events, error capture and more...';\n","import { boundedGlob, readProjectFile } from '@utils/bounded-fs';\nimport { getUI } from '@ui';\nimport type { WizardRunOptions } from '@utils/types';\nimport { createVersionBucket } from '@utils/semver';\nimport * as fs from 'node:fs';\nimport * as path from 'node:path';\n\nexport enum DjangoProjectType {\n STANDARD = 'standard', // Traditional Django project (django-admin startproject)\n DRF = 'drf', // Django REST Framework API\n WAGTAIL = 'wagtail', // Wagtail CMS\n CHANNELS = 'channels', // Django Channels (async/websockets)\n}\n\nconst EXTRA_IGNORE = ['**/env/**', '**/.env/**', '**/migrations/**'];\n\n/**\n * Get Django version bucket for analytics\n */\nexport const getDjangoVersionBucket = createVersionBucket();\n\n/**\n * Extract Django version from requirements files or pyproject.toml\n */\nexport async function getDjangoVersion(\n options: Pick<WizardRunOptions, 'installDir'>,\n): Promise<string | undefined> {\n const { installDir } = options;\n\n // Check requirements files\n const requirementsFiles = await boundedGlob(\n ['**/requirements*.txt', '**/pyproject.toml', '**/setup.py', '**/Pipfile'],\n {\n cwd: installDir,\n extraIgnore: EXTRA_IGNORE,\n },\n );\n\n for (const reqFile of requirementsFiles) {\n const content = readProjectFile(path.join(installDir, reqFile));\n if (!content) continue;\n\n // Try to extract version from requirements.txt format (Django==4.2.0 or Django>=4.0)\n const requirementsMatch = content.match(\n /[Dd]jango[=<>~!]+([0-9]+\\.[0-9]+(?:\\.[0-9]+)?)/,\n );\n if (requirementsMatch) {\n return requirementsMatch[1];\n }\n\n // Try to extract from pyproject.toml format\n const pyprojectMatch = content.match(\n /[Dd]jango[\"\\s]*[=<>~!]+\\s*[\"']?([0-9]+\\.[0-9]+(?:\\.[0-9]+)?)/,\n );\n if (pyprojectMatch) {\n return pyprojectMatch[1];\n }\n }\n\n return undefined;\n}\n\n/**\n * Check if Django REST Framework is installed\n */\nasync function hasDRF({\n installDir,\n}: Pick<WizardRunOptions, 'installDir'>): Promise<boolean> {\n const requirementsFiles = await boundedGlob(\n ['**/requirements*.txt', '**/pyproject.toml', '**/Pipfile'],\n {\n cwd: installDir,\n extraIgnore: EXTRA_IGNORE,\n },\n );\n\n for (const reqFile of requirementsFiles) {\n const content = readProjectFile(path.join(installDir, reqFile));\n if (content?.includes('djangorestframework')) {\n return true;\n }\n }\n\n // Also check INSTALLED_APPS in settings\n const settingsFiles = await boundedGlob('**/settings.py', {\n cwd: installDir,\n extraIgnore: EXTRA_IGNORE,\n });\n\n for (const settingsFile of settingsFiles) {\n const content = readProjectFile(path.join(installDir, settingsFile));\n if (content?.includes('rest_framework')) {\n return true;\n }\n }\n\n return false;\n}\n\n/**\n * Check if Wagtail is installed\n */\nasync function hasWagtail({\n installDir,\n}: Pick<WizardRunOptions, 'installDir'>): Promise<boolean> {\n const requirementsFiles = await boundedGlob(\n ['**/requirements*.txt', '**/pyproject.toml', '**/Pipfile'],\n {\n cwd: installDir,\n extraIgnore: EXTRA_IGNORE,\n },\n );\n\n for (const reqFile of requirementsFiles) {\n const content = readProjectFile(path.join(installDir, reqFile));\n if (content?.includes('wagtail')) {\n return true;\n }\n }\n\n return false;\n}\n\n/**\n * Check if Django Channels is installed\n */\nasync function hasChannels({\n installDir,\n}: Pick<WizardRunOptions, 'installDir'>): Promise<boolean> {\n const requirementsFiles = await boundedGlob(\n ['**/requirements*.txt', '**/pyproject.toml', '**/Pipfile'],\n {\n cwd: installDir,\n extraIgnore: EXTRA_IGNORE,\n },\n );\n\n for (const reqFile of requirementsFiles) {\n const content = readProjectFile(path.join(installDir, reqFile));\n if (content?.includes('channels')) {\n return true;\n }\n }\n\n return false;\n}\n\n/**\n * Detect Django project type\n */\nexport async function getDjangoProjectType(\n options: WizardRunOptions,\n): Promise<DjangoProjectType> {\n const { installDir } = options;\n\n // Check for Wagtail first (CMS)\n if (await hasWagtail({ installDir })) {\n getUI().setDetectedFramework('Django with Wagtail CMS');\n return DjangoProjectType.WAGTAIL;\n }\n\n // Check for Django REST Framework\n if (await hasDRF({ installDir })) {\n getUI().setDetectedFramework('Django REST Framework');\n return DjangoProjectType.DRF;\n }\n\n // Check for Django Channels\n if (await hasChannels({ installDir })) {\n getUI().setDetectedFramework('Django Channels');\n return DjangoProjectType.CHANNELS;\n }\n\n // Default to standard Django\n getUI().setDetectedFramework('Django');\n return DjangoProjectType.STANDARD;\n}\n\n/**\n * Get human-readable name for Django project type\n */\nexport function getDjangoProjectTypeName(\n projectType: DjangoProjectType,\n): string {\n switch (projectType) {\n case DjangoProjectType.STANDARD:\n return 'Standard Django';\n case DjangoProjectType.DRF:\n return 'Django REST Framework';\n case DjangoProjectType.WAGTAIL:\n return 'Wagtail CMS';\n case DjangoProjectType.CHANNELS:\n return 'Django Channels';\n }\n}\n\n/**\n * Find the main Django settings file\n */\nexport async function findDjangoSettingsFile(\n options: Pick<WizardRunOptions, 'installDir'>,\n): Promise<string | undefined> {\n const { installDir } = options;\n\n // Look for settings.py files\n const settingsFiles = await boundedGlob('**/settings.py', {\n cwd: installDir,\n extraIgnore: EXTRA_IGNORE,\n });\n\n if (settingsFiles.length === 0) {\n // Try settings/__init__.py for split settings\n const splitSettingsFiles = await boundedGlob('**/settings/__init__.py', {\n cwd: installDir,\n extraIgnore: EXTRA_IGNORE,\n limit: 1,\n });\n\n if (splitSettingsFiles.length > 0) {\n return splitSettingsFiles[0];\n }\n\n return undefined;\n }\n\n // If multiple settings files, prefer the one next to manage.py or in root\n if (settingsFiles.length === 1) {\n return settingsFiles[0];\n }\n\n // Try to find the main settings file by looking for ROOT_URLCONF\n for (const settingsFile of settingsFiles) {\n const content = readProjectFile(path.join(installDir, settingsFile));\n if (content?.includes('ROOT_URLCONF')) {\n return settingsFile;\n }\n }\n\n // Default to first found\n return settingsFiles[0];\n}\n\n/**\n * Find the main Django urls.py file\n */\nexport async function findDjangoUrlsFile(\n options: Pick<WizardRunOptions, 'installDir'>,\n): Promise<string | undefined> {\n const { installDir } = options;\n\n // First, try to find the root urls.py referenced in settings\n const settingsFile = await findDjangoSettingsFile(options);\n if (settingsFile) {\n const settingsContent = readProjectFile(\n path.join(installDir, settingsFile),\n );\n const urlconfMatch = settingsContent?.match(\n /ROOT_URLCONF\\s*=\\s*['\"]([^'\"]+)['\"]/,\n );\n if (urlconfMatch) {\n const urlconfPath = urlconfMatch[1].replace(/\\./g, '/') + '.py';\n const fullPath = path.join(installDir, urlconfPath);\n if (fs.existsSync(fullPath)) {\n return urlconfPath;\n }\n }\n }\n\n // Fallback to glob search\n const urlsFiles = await boundedGlob('**/urls.py', {\n cwd: installDir,\n extraIgnore: [...EXTRA_IGNORE, '**/admin/**'],\n });\n\n if (urlsFiles.length === 0) {\n return undefined;\n }\n\n // Prefer urls.py files that contain urlpatterns\n for (const urlsFile of urlsFiles) {\n const content = readProjectFile(path.join(installDir, urlsFile));\n if (content?.includes('urlpatterns')) {\n return urlsFile;\n }\n }\n\n return urlsFiles[0];\n}\n","/* Django wizard using posthog-agent with PostHog MCP */\nimport type { WizardRunOptions } from '@utils/types';\nimport type { FrameworkConfig } from '@lib/framework-config';\nimport { PYTHON_PACKAGE_INSTALLATION } from '@lib/framework-config';\nimport { detectPythonPackageManagers } from '@lib/detection/package-manager';\nimport { Integration } from '@lib/constants';\nimport { boundedGlob, readProjectFile } from '@utils/bounded-fs';\nimport * as path from 'node:path';\nimport {\n getDjangoVersion,\n getDjangoProjectType,\n getDjangoProjectTypeName,\n getDjangoVersionBucket,\n DjangoProjectType,\n findDjangoSettingsFile,\n} from './utils';\n\nconst EXTRA_IGNORE = ['**/env/**', '**/.env/**'];\n\ntype DjangoContext = {\n projectType?: DjangoProjectType;\n settingsFile?: string;\n};\n\nexport const DJANGO_AGENT_CONFIG: FrameworkConfig<DjangoContext> = {\n metadata: {\n name: 'Django',\n integration: Integration.django,\n docsUrl: 'https://posthog.com/docs/libraries/django',\n unsupportedVersionDocsUrl: 'https://posthog.com/docs/libraries/python',\n gatherContext: async (options: WizardRunOptions) => {\n const projectType = await getDjangoProjectType(options);\n const settingsFile = await findDjangoSettingsFile(options);\n return { projectType, settingsFile };\n },\n },\n\n detection: {\n packageName: 'django',\n packageDisplayName: 'Django',\n usesPackageJson: false,\n getVersion: () => undefined,\n getVersionBucket: getDjangoVersionBucket,\n minimumVersion: '3.0.0',\n getInstalledVersion: (options: WizardRunOptions) =>\n getDjangoVersion(options),\n detect: async (options) => {\n const { installDir } = options;\n\n const managePyMatches = await boundedGlob('**/manage.py', {\n cwd: installDir,\n extraIgnore: EXTRA_IGNORE,\n });\n\n if (managePyMatches.length > 0) {\n for (const match of managePyMatches) {\n const content = readProjectFile(path.join(installDir, match));\n if (!content) continue;\n // Check for actual Django imports and usage\n if (\n content.includes('from django') ||\n content.includes('import django') ||\n content.includes('DJANGO_SETTINGS_MODULE') ||\n /execute_from_command_line/.test(content)\n ) {\n return true;\n }\n }\n }\n\n const requirementsFiles = await boundedGlob(\n ['**/requirements*.txt', '**/pyproject.toml', '**/setup.py'],\n {\n cwd: installDir,\n extraIgnore: EXTRA_IGNORE,\n },\n );\n\n for (const reqFile of requirementsFiles) {\n const content = readProjectFile(path.join(installDir, reqFile));\n if (!content) continue;\n // Match Django as a package requirement, not in comments or other text\n // Look for: django, django>=, django==, django~=, Django (capitalized)\n if (\n /^django([>=~!<\\s]|$)/im.test(content) ||\n /[\"']django[\"']/i.test(content)\n ) {\n return true;\n }\n }\n\n return false;\n },\n detectPackageManager: detectPythonPackageManagers,\n },\n\n environment: {\n uploadToHosting: false,\n getEnvVars: (apiKey: string, host: string) => ({\n POSTHOG_PROJECT_TOKEN: apiKey,\n POSTHOG_HOST: host,\n }),\n },\n\n analytics: {\n getTags: (context) => ({\n projectType: context.projectType || 'unknown',\n }),\n },\n\n prompts: {\n packageInstallation: PYTHON_PACKAGE_INSTALLATION,\n projectTypeDetection:\n 'This is a Python/Django project. Look for requirements.txt, pyproject.toml, setup.py, Pipfile, or manage.py to confirm.',\n getAdditionalContextLines: (context) => {\n const projectTypeName = context.projectType\n ? getDjangoProjectTypeName(context.projectType)\n : 'unknown';\n\n // Map project type to framework ID for MCP docs resource\n const frameworkIdMap: Record<DjangoProjectType, string> = {\n [DjangoProjectType.STANDARD]: 'django',\n [DjangoProjectType.DRF]: 'django',\n [DjangoProjectType.WAGTAIL]: 'django',\n [DjangoProjectType.CHANNELS]: 'django',\n };\n\n const frameworkId = context.projectType\n ? frameworkIdMap[context.projectType]\n : 'django';\n\n const lines = [\n `Project type: ${projectTypeName}`,\n `Framework docs ID: ${frameworkId} (use posthog://docs/frameworks/${frameworkId} for documentation)`,\n ];\n\n if (context.settingsFile) {\n lines.push(`Settings file: ${context.settingsFile}`);\n }\n\n return lines;\n },\n },\n\n ui: {\n successMessage: 'PostHog integration complete',\n estimatedDurationMinutes: 5,\n getOutroChanges: (context) => {\n const projectTypeName = context.projectType\n ? getDjangoProjectTypeName(context.projectType)\n : 'Django';\n return [\n `Analyzed your ${projectTypeName} project structure`,\n `Installed the PostHog Python package`,\n `Configured PostHog in your Django settings`,\n `Added PostHog middleware for automatic event tracking`,\n ];\n },\n getOutroNextSteps: () => [\n 'Start your Django development server to see PostHog in action',\n 'Visit your PostHog dashboard to see incoming events',\n 'Use identify_context() within new_context() to associate events with users',\n ],\n },\n};\n","import { boundedGlob, readProjectFile } from '@utils/bounded-fs';\nimport { getUI } from '@ui';\nimport type { WizardRunOptions } from '@utils/types';\nimport { createVersionBucket } from '@utils/semver';\nimport * as path from 'node:path';\n\nexport enum FlaskProjectType {\n STANDARD = 'standard', // Basic Flask app\n RESTFUL = 'restful', // Flask-RESTful API\n RESTX = 'restx', // Flask-RESTX (Swagger docs)\n SMOREST = 'smorest', // flask-smorest (OpenAPI)\n BLUEPRINT = 'blueprint', // Large app with blueprints\n}\n\nconst EXTRA_IGNORE = [\n '**/env/**',\n '**/.env/**',\n '**/migrations/**',\n '**/instance/**',\n];\n\n/** Content probes read at most this many files, one in memory at a time. */\nconst SOURCE_PROBE_LIMIT = 200;\n\n/**\n * Get Flask version bucket for analytics\n */\nexport const getFlaskVersionBucket = createVersionBucket();\n\n/**\n * Extract Flask version from requirements files or pyproject.toml\n */\nexport async function getFlaskVersion(\n options: Pick<WizardRunOptions, 'installDir'>,\n): Promise<string | undefined> {\n const { installDir } = options;\n\n // Check requirements files\n const requirementsFiles = await boundedGlob(\n ['**/requirements*.txt', '**/pyproject.toml', '**/setup.py', '**/Pipfile'],\n {\n cwd: installDir,\n extraIgnore: EXTRA_IGNORE,\n },\n );\n\n for (const reqFile of requirementsFiles) {\n const content = readProjectFile(path.join(installDir, reqFile));\n if (!content) continue;\n\n // Try to extract version from requirements.txt format (Flask==3.0.0 or flask>=2.0)\n const requirementsMatch = content.match(\n /[Ff]lask[=<>~!]+([0-9]+\\.[0-9]+(?:\\.[0-9]+)?)/,\n );\n if (requirementsMatch) {\n return requirementsMatch[1];\n }\n\n // Try to extract from pyproject.toml format\n const pyprojectMatch = content.match(\n /[Ff]lask[\"\\s]*[=<>~!]+\\s*[\"']?([0-9]+\\.[0-9]+(?:\\.[0-9]+)?)/,\n );\n if (pyprojectMatch) {\n return pyprojectMatch[1];\n }\n }\n\n return undefined;\n}\n\n/**\n * Check if Flask-RESTful is installed\n */\nasync function hasFlaskRESTful({\n installDir,\n}: Pick<WizardRunOptions, 'installDir'>): Promise<boolean> {\n const requirementsFiles = await boundedGlob(\n ['**/requirements*.txt', '**/pyproject.toml', '**/Pipfile'],\n {\n cwd: installDir,\n extraIgnore: EXTRA_IGNORE,\n },\n );\n\n for (const reqFile of requirementsFiles) {\n const content = readProjectFile(path.join(installDir, reqFile));\n if (!content) continue;\n if (\n content.includes('flask-restful') ||\n content.includes('Flask-RESTful')\n ) {\n return true;\n }\n }\n\n // Also check imports in Python files\n const pyFiles = await boundedGlob(['**/*.py'], {\n cwd: installDir,\n extraIgnore: EXTRA_IGNORE,\n limit: SOURCE_PROBE_LIMIT,\n });\n\n for (const pyFile of pyFiles) {\n const content = readProjectFile(path.join(installDir, pyFile));\n if (!content) continue;\n if (\n content.includes('from flask_restful import') ||\n content.includes('import flask_restful')\n ) {\n return true;\n }\n }\n\n return false;\n}\n\n/**\n * Check if Flask-RESTX is installed\n */\nasync function hasFlaskRESTX({\n installDir,\n}: Pick<WizardRunOptions, 'installDir'>): Promise<boolean> {\n const requirementsFiles = await boundedGlob(\n ['**/requirements*.txt', '**/pyproject.toml', '**/Pipfile'],\n {\n cwd: installDir,\n extraIgnore: EXTRA_IGNORE,\n },\n );\n\n for (const reqFile of requirementsFiles) {\n const content = readProjectFile(path.join(installDir, reqFile));\n if (!content) continue;\n if (content.includes('flask-restx') || content.includes('Flask-RESTX')) {\n return true;\n }\n }\n\n // Also check imports in Python files\n const pyFiles = await boundedGlob(['**/*.py'], {\n cwd: installDir,\n extraIgnore: EXTRA_IGNORE,\n limit: SOURCE_PROBE_LIMIT,\n });\n\n for (const pyFile of pyFiles) {\n const content = readProjectFile(path.join(installDir, pyFile));\n if (!content) continue;\n if (\n content.includes('from flask_restx import') ||\n content.includes('import flask_restx')\n ) {\n return true;\n }\n }\n\n return false;\n}\n\n/**\n * Check if flask-smorest is installed\n */\nasync function hasFlaskSmorest({\n installDir,\n}: Pick<WizardRunOptions, 'installDir'>): Promise<boolean> {\n const requirementsFiles = await boundedGlob(\n ['**/requirements*.txt', '**/pyproject.toml', '**/Pipfile'],\n {\n cwd: installDir,\n extraIgnore: EXTRA_IGNORE,\n },\n );\n\n for (const reqFile of requirementsFiles) {\n const content = readProjectFile(path.join(installDir, reqFile));\n if (!content) continue;\n if (content.includes('flask-smorest')) {\n return true;\n }\n }\n\n // Also check imports in Python files\n const pyFiles = await boundedGlob(['**/*.py'], {\n cwd: installDir,\n extraIgnore: EXTRA_IGNORE,\n limit: SOURCE_PROBE_LIMIT,\n });\n\n for (const pyFile of pyFiles) {\n const content = readProjectFile(path.join(installDir, pyFile));\n if (!content) continue;\n if (\n content.includes('from flask_smorest import') ||\n content.includes('import flask_smorest')\n ) {\n return true;\n }\n }\n\n return false;\n}\n\n/**\n * Check if app uses Flask Blueprints\n */\nasync function hasBlueprints({\n installDir,\n}: Pick<WizardRunOptions, 'installDir'>): Promise<boolean> {\n const pyFiles = await boundedGlob(['**/*.py'], {\n cwd: installDir,\n extraIgnore: EXTRA_IGNORE,\n limit: SOURCE_PROBE_LIMIT,\n });\n\n for (const pyFile of pyFiles) {\n const content = readProjectFile(path.join(installDir, pyFile));\n if (!content) continue;\n if (\n content.includes('Blueprint(') ||\n content.includes('register_blueprint(') ||\n content.includes('from flask import Blueprint')\n ) {\n return true;\n }\n }\n\n return false;\n}\n\n/**\n * Detect Flask project type\n */\nexport async function getFlaskProjectType(\n options: WizardRunOptions,\n): Promise<FlaskProjectType> {\n const { installDir } = options;\n\n // Check for Flask-RESTX first (most specific - includes Swagger)\n if (await hasFlaskRESTX({ installDir })) {\n getUI().setDetectedFramework('Flask-RESTX');\n return FlaskProjectType.RESTX;\n }\n\n // Check for flask-smorest (OpenAPI-first)\n if (await hasFlaskSmorest({ installDir })) {\n getUI().setDetectedFramework('flask-smorest');\n return FlaskProjectType.SMOREST;\n }\n\n // Check for Flask-RESTful\n if (await hasFlaskRESTful({ installDir })) {\n getUI().setDetectedFramework('Flask-RESTful');\n return FlaskProjectType.RESTFUL;\n }\n\n // Check for Blueprints (large app structure)\n if (await hasBlueprints({ installDir })) {\n getUI().setDetectedFramework('Flask with Blueprints');\n return FlaskProjectType.BLUEPRINT;\n }\n\n // Default to standard Flask\n getUI().setDetectedFramework('Flask');\n return FlaskProjectType.STANDARD;\n}\n\n/**\n * Get human-readable name for Flask project type\n */\nexport function getFlaskProjectTypeName(projectType: FlaskProjectType): string {\n switch (projectType) {\n case FlaskProjectType.STANDARD:\n return 'Standard Flask';\n case FlaskProjectType.RESTFUL:\n return 'Flask-RESTful';\n case FlaskProjectType.RESTX:\n return 'Flask-RESTX';\n case FlaskProjectType.SMOREST:\n return 'flask-smorest';\n case FlaskProjectType.BLUEPRINT:\n return 'Flask with Blueprints';\n }\n}\n\n/**\n * Find the main Flask app file\n */\nexport async function findFlaskAppFile(\n options: Pick<WizardRunOptions, 'installDir'>,\n): Promise<string | undefined> {\n const { installDir } = options;\n\n // Common Flask app file patterns\n const commonPatterns = [\n '**/app.py',\n '**/wsgi.py',\n '**/application.py',\n '**/run.py',\n '**/main.py',\n '**/__init__.py',\n ];\n\n const appFiles = await boundedGlob(commonPatterns, {\n cwd: installDir,\n extraIgnore: EXTRA_IGNORE,\n });\n\n // Look for files with Flask() instantiation or create_app() factory\n for (const appFile of appFiles) {\n const content = readProjectFile(path.join(installDir, appFile));\n if (!content) continue;\n // Check for Flask app instantiation or application factory\n if (\n content.includes('Flask(__name__)') ||\n content.includes('Flask(') ||\n content.includes('def create_app(')\n ) {\n return appFile;\n }\n }\n\n // If no file with Flask() found, check all Python files\n const allPyFiles = await boundedGlob(['**/*.py'], {\n cwd: installDir,\n extraIgnore: EXTRA_IGNORE,\n limit: SOURCE_PROBE_LIMIT,\n });\n\n for (const pyFile of allPyFiles) {\n const content = readProjectFile(path.join(installDir, pyFile));\n if (!content) continue;\n if (\n content.includes('Flask(__name__)') ||\n content.includes('def create_app(')\n ) {\n return pyFile;\n }\n }\n\n // Return first common pattern file if exists\n if (appFiles.length > 0) {\n return appFiles[0];\n }\n\n return undefined;\n}\n","/* Flask wizard using posthog-agent with PostHog MCP */\nimport type { WizardRunOptions } from '@utils/types';\nimport type { FrameworkConfig } from '@lib/framework-config';\nimport { PYTHON_PACKAGE_INSTALLATION } from '@lib/framework-config';\nimport { detectPythonPackageManagers } from '@lib/detection/package-manager';\nimport { Integration } from '@lib/constants';\nimport { boundedGlob, readProjectFile } from '@utils/bounded-fs';\nimport * as path from 'node:path';\nimport {\n getFlaskVersion,\n getFlaskProjectType,\n getFlaskProjectTypeName,\n getFlaskVersionBucket,\n FlaskProjectType,\n findFlaskAppFile,\n} from './utils';\n\nconst EXTRA_IGNORE = ['**/env/**', '**/.env/**'];\n\ntype FlaskContext = {\n projectType?: FlaskProjectType;\n appFile?: string;\n};\n\nexport const FLASK_AGENT_CONFIG: FrameworkConfig<FlaskContext> = {\n metadata: {\n name: 'Flask',\n integration: Integration.flask,\n docsUrl: 'https://posthog.com/docs/libraries/python',\n unsupportedVersionDocsUrl: 'https://posthog.com/docs/libraries/python',\n gatherContext: async (options: WizardRunOptions) => {\n const projectType = await getFlaskProjectType(options);\n const appFile = await findFlaskAppFile(options);\n return { projectType, appFile };\n },\n },\n\n detection: {\n packageName: 'flask',\n packageDisplayName: 'Flask',\n usesPackageJson: false,\n getVersion: () => undefined,\n getVersionBucket: getFlaskVersionBucket,\n minimumVersion: '2.0.0',\n getInstalledVersion: (options: WizardRunOptions) =>\n getFlaskVersion(options),\n detect: async (options) => {\n const { installDir } = options;\n\n const requirementsFiles = await boundedGlob(\n [\n '**/requirements*.txt',\n '**/pyproject.toml',\n '**/setup.py',\n '**/Pipfile',\n ],\n {\n cwd: installDir,\n extraIgnore: EXTRA_IGNORE,\n },\n );\n\n for (const reqFile of requirementsFiles) {\n const content = readProjectFile(path.join(installDir, reqFile));\n if (!content) continue;\n if (\n /^flask([<>=~!]|$|\\s)/im.test(content) ||\n /[\"']flask[\"']/i.test(content)\n ) {\n return true;\n }\n }\n\n const pyFiles = await boundedGlob(\n ['**/app.py', '**/wsgi.py', '**/application.py', '**/__init__.py'],\n {\n cwd: installDir,\n extraIgnore: EXTRA_IGNORE,\n },\n );\n\n for (const pyFile of pyFiles) {\n const content = readProjectFile(path.join(installDir, pyFile));\n if (!content) continue;\n if (\n content.includes('from flask import') ||\n content.includes('import flask') ||\n /Flask\\s*\\(/.test(content)\n ) {\n return true;\n }\n }\n\n return false;\n },\n detectPackageManager: detectPythonPackageManagers,\n },\n\n environment: {\n uploadToHosting: false,\n getEnvVars: (apiKey: string, host: string) => ({\n POSTHOG_PROJECT_TOKEN: apiKey,\n POSTHOG_HOST: host,\n }),\n },\n\n analytics: {\n getTags: (context) => ({\n projectType: context.projectType || 'unknown',\n }),\n },\n\n prompts: {\n packageInstallation: PYTHON_PACKAGE_INSTALLATION,\n projectTypeDetection:\n 'This is a Python/Flask project. Look for requirements.txt, pyproject.toml, setup.py, Pipfile, or app.py/wsgi.py to confirm.',\n getAdditionalContextLines: (context) => {\n const projectTypeName = context.projectType\n ? getFlaskProjectTypeName(context.projectType)\n : 'unknown';\n\n // Map project type to framework ID for MCP docs resource\n const frameworkIdMap: Record<FlaskProjectType, string> = {\n [FlaskProjectType.STANDARD]: 'flask',\n [FlaskProjectType.RESTFUL]: 'flask',\n [FlaskProjectType.RESTX]: 'flask',\n [FlaskProjectType.SMOREST]: 'flask',\n [FlaskProjectType.BLUEPRINT]: 'flask',\n };\n\n const frameworkId = context.projectType\n ? frameworkIdMap[context.projectType]\n : 'flask';\n\n const lines = [\n `Project type: ${projectTypeName}`,\n `Framework docs ID: ${frameworkId} (use posthog://docs/frameworks/${frameworkId} for documentation)`,\n ];\n\n if (context.appFile) {\n lines.push(`App file: ${context.appFile}`);\n }\n\n return lines;\n },\n },\n\n ui: {\n successMessage: 'PostHog integration complete',\n estimatedDurationMinutes: 5,\n getOutroChanges: (context) => {\n const projectTypeName = context.projectType\n ? getFlaskProjectTypeName(context.projectType)\n : 'Flask';\n return [\n `Analyzed your ${projectTypeName} project structure`,\n `Installed the PostHog Python package`,\n `Configured PostHog in your Flask application`,\n `Added PostHog initialization with automatic event tracking`,\n ];\n },\n getOutroNextSteps: () => [\n 'Start your Flask development server to see PostHog in action',\n 'Visit your PostHog dashboard to see incoming events',\n 'Use posthog.identify() to associate events with users',\n ],\n },\n};\n","import { major, minVersion } from 'semver';\nimport { boundedGlob, readProjectFile } from '@utils/bounded-fs';\nimport { getUI } from '@ui';\nimport type { WizardRunOptions } from '@utils/types';\nimport * as path from 'node:path';\n\nexport enum FastAPIProjectType {\n STANDARD = 'standard', // Basic FastAPI app\n ROUTER = 'router', // FastAPI with APIRouter\n FULLSTACK = 'fullstack', // FastAPI with templates (Jinja2)\n}\n\nconst EXTRA_IGNORE = ['**/env/**', '**/.env/**', '**/migrations/**'];\n\n/** Content probes read at most this many files, one in memory at a time. */\nconst SOURCE_PROBE_LIMIT = 200;\n\n/**\n * Get FastAPI version bucket for analytics\n */\nexport function getFastAPIVersionBucket(version: string | undefined): string {\n if (!version) {\n return 'none';\n }\n\n try {\n const minVer = minVersion(version);\n if (!minVer) {\n return 'invalid';\n }\n const majorVersion = major(minVer);\n // FastAPI 0.x is still the common version range\n if (majorVersion === 0) {\n return '0.x';\n }\n return `${majorVersion}.x`;\n } catch {\n return 'unknown';\n }\n}\n\n/**\n * Extract FastAPI version from requirements files or pyproject.toml\n */\nexport async function getFastAPIVersion(\n options: Pick<WizardRunOptions, 'installDir'>,\n): Promise<string | undefined> {\n const { installDir } = options;\n\n // Check requirements files\n const requirementsFiles = await boundedGlob(\n ['**/requirements*.txt', '**/pyproject.toml', '**/setup.py', '**/Pipfile'],\n {\n cwd: installDir,\n extraIgnore: EXTRA_IGNORE,\n },\n );\n\n for (const reqFile of requirementsFiles) {\n const content = readProjectFile(path.join(installDir, reqFile));\n if (!content) continue;\n\n // Try to extract version from requirements.txt format (fastapi==0.109.0 or fastapi>=0.100)\n const requirementsMatch = content.match(\n /[Ff]ast[Aa][Pp][Ii][=<>~!]+([0-9]+\\.[0-9]+(?:\\.[0-9]+)?)/,\n );\n if (requirementsMatch) {\n return requirementsMatch[1];\n }\n\n // Try to extract from pyproject.toml format\n const pyprojectMatch = content.match(\n /[Ff]ast[Aa][Pp][Ii][\"\\s]*[=<>~!]+\\s*[\"']?([0-9]+\\.[0-9]+(?:\\.[0-9]+)?)/,\n );\n if (pyprojectMatch) {\n return pyprojectMatch[1];\n }\n }\n\n return undefined;\n}\n\n/**\n * Check if app uses FastAPI APIRouter\n */\nasync function hasAPIRouter({\n installDir,\n}: Pick<WizardRunOptions, 'installDir'>): Promise<boolean> {\n const pyFiles = await boundedGlob(['**/*.py'], {\n cwd: installDir,\n extraIgnore: EXTRA_IGNORE,\n limit: SOURCE_PROBE_LIMIT,\n });\n\n for (const pyFile of pyFiles) {\n const content = readProjectFile(path.join(installDir, pyFile));\n if (!content) continue;\n if (\n content.includes('APIRouter(') ||\n content.includes('include_router(') ||\n content.includes('from fastapi import APIRouter')\n ) {\n return true;\n }\n }\n\n return false;\n}\n\n/**\n * Check if app uses Jinja2 templates (fullstack pattern)\n */\nasync function hasTemplates({\n installDir,\n}: Pick<WizardRunOptions, 'installDir'>): Promise<boolean> {\n // Check for Jinja2Templates usage in Python files\n const pyFiles = await boundedGlob(['**/*.py'], {\n cwd: installDir,\n extraIgnore: EXTRA_IGNORE,\n limit: SOURCE_PROBE_LIMIT,\n });\n\n for (const pyFile of pyFiles) {\n const content = readProjectFile(path.join(installDir, pyFile));\n if (!content) continue;\n if (\n content.includes('Jinja2Templates') ||\n content.includes('from fastapi.templating import')\n ) {\n return true;\n }\n }\n\n // Check for templates directory\n const templateFiles = await boundedGlob(['**/templates/**'], {\n cwd: installDir,\n extraIgnore: EXTRA_IGNORE,\n limit: 1,\n });\n\n return templateFiles.length > 0;\n}\n\n/**\n * Detect FastAPI project type\n */\nexport async function getFastAPIProjectType(\n options: WizardRunOptions,\n): Promise<FastAPIProjectType> {\n const { installDir } = options;\n\n // Check for fullstack pattern (templates)\n if (await hasTemplates({ installDir })) {\n getUI().setDetectedFramework('FastAPI fullstack with templates');\n return FastAPIProjectType.FULLSTACK;\n }\n\n // Check for APIRouter (modular structure)\n if (await hasAPIRouter({ installDir })) {\n getUI().setDetectedFramework('FastAPI with APIRouter');\n return FastAPIProjectType.ROUTER;\n }\n\n // Default to standard FastAPI\n getUI().setDetectedFramework('FastAPI');\n return FastAPIProjectType.STANDARD;\n}\n\n/**\n * Get human-readable name for FastAPI project type\n */\nexport function getFastAPIProjectTypeName(\n projectType: FastAPIProjectType,\n): string {\n switch (projectType) {\n case FastAPIProjectType.STANDARD:\n return 'Standard FastAPI';\n case FastAPIProjectType.ROUTER:\n return 'FastAPI with APIRouter';\n case FastAPIProjectType.FULLSTACK:\n return 'FastAPI Fullstack';\n }\n}\n\n/**\n * Find the main FastAPI app file\n */\nexport async function findFastAPIAppFile(\n options: Pick<WizardRunOptions, 'installDir'>,\n): Promise<string | undefined> {\n const { installDir } = options;\n\n // Common FastAPI app file patterns\n const commonPatterns = [\n '**/main.py',\n '**/app.py',\n '**/application.py',\n '**/api.py',\n '**/__init__.py',\n ];\n\n const appFiles = await boundedGlob(commonPatterns, {\n cwd: installDir,\n extraIgnore: EXTRA_IGNORE,\n });\n\n // Look for files with FastAPI() instantiation\n for (const appFile of appFiles) {\n const content = readProjectFile(path.join(installDir, appFile));\n if (!content) continue;\n // Check for FastAPI app instantiation\n if (\n content.includes('FastAPI(') ||\n content.includes('from fastapi import FastAPI')\n ) {\n return appFile;\n }\n }\n\n // If no file with FastAPI() found, check all Python files\n const allPyFiles = await boundedGlob(['**/*.py'], {\n cwd: installDir,\n extraIgnore: EXTRA_IGNORE,\n limit: SOURCE_PROBE_LIMIT,\n });\n\n for (const pyFile of allPyFiles) {\n const content = readProjectFile(path.join(installDir, pyFile));\n if (content?.includes('FastAPI(')) {\n return pyFile;\n }\n }\n\n // Return first common pattern file if exists\n if (appFiles.length > 0) {\n return appFiles[0];\n }\n\n return undefined;\n}\n","/* FastAPI wizard using posthog-agent with PostHog MCP */\nimport type { WizardRunOptions } from '@utils/types';\nimport type { FrameworkConfig } from '@lib/framework-config';\nimport { PYTHON_PACKAGE_INSTALLATION } from '@lib/framework-config';\nimport { detectPythonPackageManagers } from '@lib/detection/package-manager';\nimport { Integration } from '@lib/constants';\nimport {\n getFastAPIVersion,\n getFastAPIProjectType,\n getFastAPIProjectTypeName,\n getFastAPIVersionBucket,\n FastAPIProjectType,\n findFastAPIAppFile,\n} from './utils';\nimport { boundedGlob, readProjectFile } from '@utils/bounded-fs';\nimport * as path from 'node:path';\n\nconst EXTRA_IGNORE = ['**/env/**', '**/.env/**'];\n\n/**\n * FastAPI framework configuration for the universal agent runner\n */\n\nexport const FASTAPI_AGENT_CONFIG: FrameworkConfig = {\n metadata: {\n name: 'FastAPI',\n integration: Integration.fastapi,\n docsUrl: 'https://posthog.com/docs/libraries/python',\n unsupportedVersionDocsUrl: 'https://posthog.com/docs/libraries/python',\n gatherContext: async (options: WizardRunOptions) => {\n const projectType = await getFastAPIProjectType(options);\n const appFile = await findFastAPIAppFile(options);\n return { projectType, appFile };\n },\n },\n\n detection: {\n packageName: 'fastapi',\n packageDisplayName: 'FastAPI',\n usesPackageJson: false,\n getVersion: (_packageJson: any) => {\n // For FastAPI, we don't use package.json. Version is extracted separately\n // from requirements.txt or pyproject.toml in the wizard entry point\n return undefined;\n },\n getVersionBucket: getFastAPIVersionBucket,\n getInstalledVersion: getFastAPIVersion,\n detect: async (options) => {\n const { installDir } = options;\n\n // Note: Django and Flask are checked before FastAPI in INTEGRATION_ORDER,\n // so if we get here, the project is not a Django or Flask project.\n\n // Check for FastAPI in requirements files\n const requirementsFiles = await boundedGlob(\n [\n '**/requirements*.txt',\n '**/pyproject.toml',\n '**/setup.py',\n '**/Pipfile',\n ],\n {\n cwd: installDir,\n extraIgnore: EXTRA_IGNORE,\n },\n );\n\n for (const reqFile of requirementsFiles) {\n const content = readProjectFile(path.join(installDir, reqFile));\n if (!content) continue;\n // Check for fastapi package (case-insensitive)\n // Match \"fastapi\" as a standalone package\n if (\n /^fastapi([<>=~!]|$|\\s)/im.test(content) ||\n /[\"']fastapi[\"']/i.test(content)\n ) {\n return true;\n }\n }\n\n // Check for FastAPI app patterns in Python files\n const pyFiles = await boundedGlob(\n ['**/main.py', '**/app.py', '**/application.py', '**/__init__.py'],\n {\n cwd: installDir,\n extraIgnore: EXTRA_IGNORE,\n },\n );\n\n for (const pyFile of pyFiles) {\n const content = readProjectFile(path.join(installDir, pyFile));\n if (!content) continue;\n if (\n content.includes('from fastapi import') ||\n content.includes('import fastapi') ||\n /FastAPI\\s*\\(/.test(content)\n ) {\n return true;\n }\n }\n\n return false;\n },\n detectPackageManager: detectPythonPackageManagers,\n },\n\n environment: {\n uploadToHosting: false,\n getEnvVars: (apiKey: string, host: string) => ({\n POSTHOG_PROJECT_TOKEN: apiKey,\n POSTHOG_HOST: host,\n }),\n },\n\n analytics: {\n getTags: (context: any) => {\n const projectType = context.projectType as FastAPIProjectType;\n return {\n projectType: projectType || 'unknown',\n };\n },\n },\n\n prompts: {\n packageInstallation: PYTHON_PACKAGE_INSTALLATION,\n projectTypeDetection:\n 'This is a Python/FastAPI project. Look for requirements.txt, pyproject.toml, setup.py, Pipfile, or main.py/app.py to confirm.',\n getAdditionalContextLines: (context: any) => {\n const projectType = context.projectType as FastAPIProjectType;\n const projectTypeName = projectType\n ? getFastAPIProjectTypeName(projectType)\n : 'unknown';\n\n // Map project type to framework ID for MCP docs resource\n const frameworkIdMap: Record<FastAPIProjectType, string> = {\n [FastAPIProjectType.STANDARD]: 'fastapi',\n [FastAPIProjectType.ROUTER]: 'fastapi',\n [FastAPIProjectType.FULLSTACK]: 'fastapi',\n };\n\n const frameworkId = projectType ? frameworkIdMap[projectType] : 'fastapi';\n\n const lines = [\n `Project type: ${projectTypeName}`,\n `Framework docs ID: ${frameworkId} (use posthog://docs/frameworks/${frameworkId} for documentation)`,\n ];\n\n if (context.appFile) {\n lines.push(`App file: ${context.appFile}`);\n }\n\n return lines;\n },\n },\n\n ui: {\n successMessage: 'PostHog integration complete',\n estimatedDurationMinutes: 5,\n getOutroChanges: (context: any) => {\n const projectType = context.projectType as FastAPIProjectType;\n const projectTypeName = projectType\n ? getFastAPIProjectTypeName(projectType)\n : 'FastAPI';\n return [\n `Analyzed your ${projectTypeName} project structure`,\n `Installed the PostHog Python package`,\n `Configured PostHog in your FastAPI application`,\n `Added PostHog initialization with lifespan event handling`,\n ];\n },\n getOutroNextSteps: () => [\n 'Start your FastAPI development server to see PostHog in action',\n 'Visit your PostHog dashboard to see incoming events',\n 'Use posthog.identify() to associate events with users',\n ],\n },\n};\n","import { boundedGlob, readProjectFile } from '@utils/bounded-fs';\nimport { getUI } from '@ui';\nimport type { WizardRunOptions } from '@utils/types';\nimport { createVersionBucket } from '@utils/semver';\nimport * as fs from 'node:fs';\nimport * as path from 'node:path';\n\nexport enum LaravelProjectType {\n STANDARD = 'standard', // Basic Laravel app\n INERTIA = 'inertia', // Inertia.js (Vue/React SPA) - may need JS SDK too\n LIVEWIRE = 'livewire', // Livewire (reactive components, includes Filament)\n}\n\nconst EXTRA_IGNORE = [\n '**/storage/**',\n '**/bootstrap/cache/**',\n '**/.phpunit.cache/**',\n '**/public/build/**',\n '**/public/hot/**',\n];\n\n/** Content probes read at most this many files, one in memory at a time. */\nconst SOURCE_PROBE_LIMIT = 200;\n\n/**\n * Get Laravel version bucket for analytics\n */\nexport const getLaravelVersionBucket = createVersionBucket();\n\n/**\n * Read and parse composer.json\n */\nexport function getComposerJson(\n options: Pick<WizardRunOptions, 'installDir'>,\n): Record<string, any> | undefined {\n const { installDir } = options;\n\n const composerPath = path.join(installDir, 'composer.json');\n try {\n const content = fs.readFileSync(composerPath, 'utf-8');\n return JSON.parse(content);\n } catch {\n return undefined;\n }\n}\n\n/**\n * Check if a package is installed (present in composer.json)\n */\nfunction hasComposerPackage(\n packageName: string,\n options: Pick<WizardRunOptions, 'installDir'>,\n): boolean {\n const composer = getComposerJson(options);\n if (!composer) return false;\n\n return !!(\n composer.require?.[packageName] || composer['require-dev']?.[packageName]\n );\n}\n\n/**\n * Extract version for a package from composer.json\n */\nfunction getComposerPackageVersion(\n packageName: string,\n options: Pick<WizardRunOptions, 'installDir'>,\n): string | undefined {\n const composer = getComposerJson(options);\n if (!composer) return undefined;\n\n const version =\n composer.require?.[packageName] || composer['require-dev']?.[packageName];\n if (version) {\n // Clean version string (remove ^, ~, >=, etc.)\n return version.replace(/^[\\^~>=<]+/, '');\n }\n\n return undefined;\n}\n\n/**\n * Check if a pattern exists in PHP source files\n */\nasync function hasLaravelCodePattern(\n pattern: RegExp | string,\n options: Pick<WizardRunOptions, 'installDir'>,\n filePatterns: string[] = ['**/*.php'],\n): Promise<boolean> {\n const { installDir } = options;\n\n const phpFiles = await boundedGlob(filePatterns, {\n cwd: installDir,\n extraIgnore: EXTRA_IGNORE,\n limit: SOURCE_PROBE_LIMIT,\n });\n\n const searchPattern =\n typeof pattern === 'string' ? new RegExp(pattern) : pattern;\n\n for (const phpFile of phpFiles) {\n const content = readProjectFile(path.join(installDir, phpFile));\n if (!content) continue;\n if (searchPattern.test(content)) return true;\n }\n\n return false;\n}\n\n/**\n * Get Laravel version from composer.json\n */\nexport function getLaravelVersion(\n options: Pick<WizardRunOptions, 'installDir'>,\n): string | undefined {\n return getComposerPackageVersion('laravel/framework', options);\n}\n\n/**\n * Get human-readable name for Laravel project type\n */\nexport function getLaravelProjectTypeName(\n projectType: LaravelProjectType,\n): string {\n switch (projectType) {\n case LaravelProjectType.STANDARD:\n return 'Standard Laravel';\n case LaravelProjectType.INERTIA:\n return 'Laravel with Inertia.js';\n case LaravelProjectType.LIVEWIRE:\n return 'Laravel with Livewire';\n default:\n return 'Laravel';\n }\n}\n\n/**\n * Check for Inertia.js\n */\nasync function hasInertia(\n options: Pick<WizardRunOptions, 'installDir'>,\n): Promise<boolean> {\n return (\n hasComposerPackage('inertiajs/inertia-laravel', options) ||\n (await hasLaravelCodePattern(/Inertia::render|inertia\\(/, options))\n );\n}\n\n/**\n * Check for Livewire\n */\nasync function hasLivewire(\n options: Pick<WizardRunOptions, 'installDir'>,\n): Promise<boolean> {\n return (\n hasComposerPackage('livewire/livewire', options) ||\n (await hasLaravelCodePattern(/extends\\s+Component|@livewire/, options))\n );\n}\n\n/**\n * Detect Laravel project type\n */\nexport async function getLaravelProjectType(\n options: WizardRunOptions,\n): Promise<LaravelProjectType> {\n // Check for SPA/Reactive frameworks (important to detect - affects SDK needs)\n if (await hasInertia(options)) {\n getUI().setDetectedFramework('Laravel with Inertia.js');\n return LaravelProjectType.INERTIA;\n }\n if (await hasLivewire(options)) {\n getUI().setDetectedFramework('Laravel with Livewire');\n return LaravelProjectType.LIVEWIRE;\n }\n\n // Default to standard\n getUI().setDetectedFramework('Laravel');\n return LaravelProjectType.STANDARD;\n}\n\n/**\n * Find the main service provider file\n */\nexport async function findLaravelServiceProvider(\n options: Pick<WizardRunOptions, 'installDir'>,\n): Promise<string | undefined> {\n const { installDir } = options;\n\n // Look for AppServiceProvider first (most common place for setup)\n const appServiceProvider = path.join(\n installDir,\n 'app/Providers/AppServiceProvider.php',\n );\n\n if (fs.existsSync(appServiceProvider)) {\n return 'app/Providers/AppServiceProvider.php';\n }\n\n // Fall back to searching for any service provider\n const providers = await boundedGlob(\n ['**/app/Providers/*ServiceProvider.php'],\n {\n cwd: installDir,\n extraIgnore: EXTRA_IGNORE,\n limit: 1,\n },\n );\n\n return providers[0];\n}\n\n/**\n * Find the bootstrap file (differs between Laravel versions)\n */\nexport function findLaravelBootstrapFile(\n options: Pick<WizardRunOptions, 'installDir'>,\n): string | undefined {\n const { installDir } = options;\n\n // Laravel 11+ uses bootstrap/app.php with new structure\n const bootstrapApp = path.join(installDir, 'bootstrap/app.php');\n if (fs.existsSync(bootstrapApp)) {\n return 'bootstrap/app.php';\n }\n\n // Older Laravel uses app/Http/Kernel.php\n const httpKernel = path.join(installDir, 'app/Http/Kernel.php');\n if (fs.existsSync(httpKernel)) {\n return 'app/Http/Kernel.php';\n }\n\n return undefined;\n}\n\n/**\n * Detect Laravel version structure for configuration guidance\n */\nexport function detectLaravelStructure(\n options: Pick<WizardRunOptions, 'installDir'>,\n): 'legacy' | 'modern' | 'latest' {\n const version = getLaravelVersion(options);\n if (!version) return 'modern';\n\n try {\n const majorVersion = parseInt(version.split('.')[0], 10);\n if (majorVersion >= 11) return 'latest'; // Laravel 11+ (new structure)\n if (majorVersion >= 9) return 'modern'; // Laravel 9-10\n return 'legacy'; // Laravel 8 and below\n } catch {\n return 'modern';\n }\n}\n","/* Laravel wizard using posthog-agent with PostHog MCP */\nimport type { WizardRunOptions } from '@utils/types';\nimport type { FrameworkConfig } from '@lib/framework-config';\nimport { composerPackageManager } from '@lib/detection/package-manager';\nimport { Integration } from '@lib/constants';\nimport { boundedGlob } from '@utils/bounded-fs';\nimport * as fs from 'node:fs';\nimport * as path from 'node:path';\nimport {\n getLaravelVersion,\n getLaravelProjectType,\n getLaravelProjectTypeName,\n getLaravelVersionBucket,\n LaravelProjectType,\n findLaravelServiceProvider,\n findLaravelBootstrapFile,\n detectLaravelStructure,\n} from './utils';\n\ntype LaravelContext = {\n projectType?: LaravelProjectType;\n serviceProvider?: string;\n bootstrapFile?: string;\n laravelStructure?: string;\n};\n\nexport const LARAVEL_AGENT_CONFIG: FrameworkConfig<LaravelContext> = {\n metadata: {\n name: 'Laravel',\n integration: Integration.laravel,\n docsUrl: 'https://posthog.com/docs/libraries/php',\n unsupportedVersionDocsUrl: 'https://posthog.com/docs/libraries/php',\n gatherContext: async (options: WizardRunOptions) => {\n const projectType = await getLaravelProjectType(options);\n const serviceProvider = await findLaravelServiceProvider(options);\n const bootstrapFile = findLaravelBootstrapFile(options);\n const laravelStructure = detectLaravelStructure(options);\n\n return {\n projectType,\n serviceProvider,\n bootstrapFile,\n laravelStructure,\n };\n },\n },\n\n detection: {\n packageName: 'laravel/framework',\n packageDisplayName: 'Laravel',\n usesPackageJson: false,\n getVersion: () => undefined,\n getVersionBucket: getLaravelVersionBucket,\n minimumVersion: '9.0.0',\n getInstalledVersion: (options: WizardRunOptions) =>\n Promise.resolve(getLaravelVersion(options)),\n detect: async (options) => {\n const { installDir } = options;\n\n const artisanPath = path.join(installDir, 'artisan');\n if (fs.existsSync(artisanPath)) {\n try {\n const content = fs.readFileSync(artisanPath, 'utf-8');\n if (content.includes('Laravel') || content.includes('Artisan')) {\n return true;\n }\n } catch {\n // Continue to other checks\n }\n }\n\n const composerPath = path.join(installDir, 'composer.json');\n if (fs.existsSync(composerPath)) {\n try {\n const content = fs.readFileSync(composerPath, 'utf-8');\n const composer = JSON.parse(content);\n if (\n composer.require?.['laravel/framework'] ||\n composer['require-dev']?.['laravel/framework']\n ) {\n return true;\n }\n } catch {\n // Continue to other checks\n }\n }\n\n const hasLaravelStructure = await boundedGlob(\n ['**/bootstrap/app.php', '**/app/Http/Kernel.php'],\n { cwd: installDir, limit: 1 },\n );\n\n return hasLaravelStructure.length > 0;\n },\n detectPackageManager: composerPackageManager,\n },\n\n environment: {\n uploadToHosting: false,\n getEnvVars: (apiKey: string, host: string) => ({\n POSTHOG_PROJECT_TOKEN: apiKey,\n POSTHOG_HOST: host,\n }),\n },\n\n analytics: {\n getTags: (context) => ({\n projectType: context.projectType || 'unknown',\n laravelStructure: context.laravelStructure || 'unknown',\n }),\n },\n\n prompts: {\n projectTypeDetection:\n 'This is a PHP/Laravel project. Look for composer.json, artisan CLI, and app/ directory structure to confirm. Check for Laravel-specific packages like laravel/framework.',\n packageInstallation:\n 'Use Composer to install packages. Run `composer require posthog/posthog-php` without pinning a specific version.',\n getAdditionalContextLines: (context) => {\n const projectTypeName = context.projectType\n ? getLaravelProjectTypeName(context.projectType)\n : 'unknown';\n\n const lines = [\n `Project type: ${projectTypeName}`,\n `Framework docs ID: php (use posthog://docs/frameworks/php for documentation)`,\n `Laravel structure: ${context.laravelStructure} (affects where to add configuration)`,\n ];\n\n if (context.serviceProvider) {\n lines.push(`Service provider: ${context.serviceProvider}`);\n }\n\n if (context.bootstrapFile) {\n lines.push(`Bootstrap file: ${context.bootstrapFile}`);\n }\n\n // Add Laravel-specific guidance based on version structure\n if (context.laravelStructure === 'latest') {\n lines.push(\n 'Note: Laravel 11+ uses simplified bootstrap/app.php for middleware and providers',\n );\n } else {\n lines.push(\n 'Note: Use app/Http/Kernel.php for middleware, app/Providers for service providers',\n );\n }\n\n return lines;\n },\n },\n\n ui: {\n successMessage: 'PostHog integration complete',\n estimatedDurationMinutes: 5,\n getOutroChanges: (context) => {\n const projectTypeName = context.projectType\n ? getLaravelProjectTypeName(context.projectType)\n : 'Laravel';\n\n const changes = [\n `Analyzed your ${projectTypeName} project structure`,\n `Installed the PostHog PHP package via Composer`,\n `Configured PostHog in your Laravel application`,\n ];\n\n if (context.laravelStructure === 'latest') {\n changes.push('Added PostHog initialization to bootstrap/app.php');\n } else {\n changes.push('Created a PostHog service provider for initialization');\n }\n\n if (context.projectType === LaravelProjectType.INERTIA) {\n changes.push('Configured PostHog to work with Inertia.js');\n }\n\n if (context.projectType === LaravelProjectType.LIVEWIRE) {\n changes.push('Configured PostHog to work with Livewire');\n }\n\n return changes;\n },\n getOutroNextSteps: () => [\n 'Start your Laravel development server with `php artisan serve`',\n 'Visit your PostHog dashboard to see incoming events',\n 'Use PostHog::capture() to track custom events',\n 'Use PostHog::identify() to associate events with users',\n ],\n },\n};\n","/* SvelteKit wizard using posthog-agent with PostHog MCP */\nimport type { FrameworkConfig } from '@lib/framework-config';\nimport { detectNodePackageManagers } from '@lib/detection/package-manager';\nimport { Integration } from '@lib/constants';\nimport {\n getDeclaredVersion,\n hasDeclaredDependency,\n type PackageJson,\n} from '@utils/package-json';\nimport { tryGetPackageJson } from '@utils/setup-utils';\n\ntype SvelteKitContext = Record<string, unknown>;\n\nexport const SVELTEKIT_AGENT_CONFIG: FrameworkConfig<SvelteKitContext> = {\n metadata: {\n name: 'SvelteKit',\n integration: Integration.sveltekit,\n docsUrl: 'https://posthog.com/docs/libraries/svelte',\n additionalMcpServers: {\n svelte: { url: 'https://mcp.svelte.dev/mcp' },\n },\n },\n\n detection: {\n packageName: '@sveltejs/kit',\n packageDisplayName: 'SvelteKit',\n getVersion: (packageJson: unknown) =>\n getDeclaredVersion('@sveltejs/kit', packageJson as PackageJson),\n detect: async (options) => {\n const packageJson = await tryGetPackageJson(options);\n return packageJson\n ? hasDeclaredDependency('@sveltejs/kit', packageJson)\n : false;\n },\n minimumVersion: '2.0.0',\n detectPackageManager: detectNodePackageManagers,\n },\n\n environment: {\n uploadToHosting: true,\n getEnvVars: (apiKey: string, host: string) => ({\n PUBLIC_POSTHOG_PROJECT_TOKEN: apiKey,\n PUBLIC_POSTHOG_HOST: host,\n }),\n },\n\n analytics: {\n getTags: () => ({}),\n },\n\n prompts: {\n projectTypeDetection:\n 'This is a JavaScript/TypeScript project using SvelteKit. Look for package.json, svelte.config.js, and lockfiles (package-lock.json, yarn.lock, pnpm-lock.yaml, bun.lockb) to confirm.',\n getAdditionalContextLines: () => [\n 'Framework docs ID: sveltekit (use posthog://docs/frameworks/sveltekit for documentation)',\n ],\n },\n\n ui: {\n successMessage: 'PostHog integration complete',\n estimatedDurationMinutes: 8,\n getOutroChanges: () => [\n 'Analyzed your SvelteKit project structure',\n 'Created and configured PostHog initializers',\n 'Integrated PostHog into your application',\n ],\n getOutroNextSteps: () => [\n 'Start your development server to see PostHog in action',\n 'Visit your PostHog dashboard to see incoming events',\n ],\n },\n};\n","/* Flutter wizard using posthog-agent with PostHog MCP */\nimport type { WizardRunOptions } from '@utils/types';\nimport type { FrameworkConfig } from '@lib/framework-config';\nimport { Integration } from '@lib/constants';\nimport * as fs from 'node:fs';\nimport * as path from 'node:path';\nimport { pubPackageManager } from '@lib/detection/package-manager';\n\n/** Platform subtrees `flutter create` scaffolds; each needs its own setup notes. */\nconst FLUTTER_PLATFORM_DIRS = [\n 'android',\n 'ios',\n 'web',\n 'macos',\n 'linux',\n 'windows',\n] as const;\n\ntype FlutterContext = {\n platforms?: string[];\n};\n\nfunction readPubspec(installDir: string): string | undefined {\n const pubspecPath = path.join(installDir, 'pubspec.yaml');\n if (!fs.existsSync(pubspecPath)) return undefined;\n return fs.readFileSync(pubspecPath, 'utf-8');\n}\n\nexport const FLUTTER_AGENT_CONFIG: FrameworkConfig<FlutterContext> = {\n metadata: {\n name: 'Flutter',\n integration: Integration.flutter,\n docsUrl: 'https://posthog.com/docs/libraries/flutter',\n gatherContext: (options: WizardRunOptions) => {\n const platforms = FLUTTER_PLATFORM_DIRS.filter((dir) =>\n fs.existsSync(path.join(options.installDir, dir)),\n );\n return Promise.resolve({ platforms });\n },\n },\n\n detection: {\n packageName: 'posthog_flutter',\n packageDisplayName: 'Flutter',\n usesPackageJson: false,\n getVersion: () => undefined,\n detectPackageManager: pubPackageManager,\n // A pubspec.yaml alone is any Dart project; depending on the Flutter SDK\n // (`sdk: flutter`) is what makes it a Flutter app. Anchored to a key/value\n // line so comments (`# sdk: flutter`) don't match.\n detect: (options) => {\n const pubspec = readPubspec(options.installDir);\n return Promise.resolve(/^\\s*sdk:\\s*flutter\\s*$/m.test(pubspec ?? ''));\n },\n },\n\n environment: {\n uploadToHosting: false,\n getEnvVars: (apiKey: string, host: string) => ({\n POSTHOG_PROJECT_TOKEN: apiKey,\n POSTHOG_HOST: host,\n }),\n },\n\n analytics: {\n getTags: (context) => ({\n ...(context.platforms?.length\n ? { platforms: context.platforms.join(',') }\n : {}),\n }),\n },\n\n prompts: {\n projectTypeDetection:\n 'This is a Flutter project. Look for pubspec.yaml declaring a dependency on the Flutter SDK (flutter: sdk: flutter) and a lib/ directory with Dart source files to confirm.',\n packageInstallation:\n 'Add the PostHog Flutter SDK with `flutter pub add posthog_flutter`. Do not edit pubspec.yaml by hand; the pub tool updates it and resolves the version automatically.',\n getAdditionalContextLines: (context) => {\n const lines = [\n 'Framework docs ID: flutter (use posthog://docs/frameworks/flutter for documentation)',\n 'Prefer manual initialization in Dart (PostHogConfig + Posthog().setup) over the platform auto-init so configuration lives in one place; when doing so, disable auto-init in the Android manifest and iOS Info.plist per the docs.',\n ];\n\n if (context.platforms?.length) {\n lines.push(\n `Enabled target platforms: ${context.platforms.join(\n ', ',\n )}. Apply the platform-specific setup steps from the docs for each (e.g. AndroidManifest.xml on Android, Info.plist on iOS/macOS, the JS snippet in web/index.html for web).`,\n );\n }\n\n return lines;\n },\n },\n\n ui: {\n successMessage: 'PostHog integration complete',\n estimatedDurationMinutes: 5,\n getOutroChanges: () => [\n 'Analyzed your Flutter project structure',\n 'Added the posthog_flutter SDK to your pubspec',\n 'Configured PostHog initialization',\n 'Added event capture and user identification',\n ],\n getOutroNextSteps: () => [\n 'Run your app to see PostHog in action',\n 'Visit your PostHog dashboard to see incoming events',\n 'Check out the PostHog Flutter docs for session replay, feature flags, and more',\n ],\n },\n};\n","import type { WizardRunOptions } from '@utils/types';\nimport { boundedGlob, readProjectFile } from '@utils/bounded-fs';\nimport fg from 'fast-glob';\nimport * as fs from 'node:fs';\nimport * as path from 'node:path';\n\nconst EXTRA_IGNORE = ['**/.build/**', '**/*.xcodeproj/**'];\n\n/** Content probes read at most this many files, one in memory at a time. */\nconst SOURCE_PROBE_LIMIT = 200;\n\nexport enum SwiftProjectType {\n SWIFTUI = 'swiftui',\n UIKIT = 'uikit',\n SPM = 'spm',\n}\n\nexport function getSwiftProjectTypeName(projectType: SwiftProjectType): string {\n switch (projectType) {\n case SwiftProjectType.SWIFTUI:\n return 'SwiftUI';\n case SwiftProjectType.UIKIT:\n return 'UIKit';\n case SwiftProjectType.SPM:\n return 'Swift Package';\n }\n}\n\nexport async function detectSwiftProjectType(\n options: WizardRunOptions,\n): Promise<SwiftProjectType | undefined> {\n const { installDir } = options;\n\n // Pure SPM package: Package.swift with no Xcode project/workspace and no\n // XcodeGen spec (project.yml generates an app's .xcodeproj, often\n // uncommitted) — same app signals as the framework detect glob.\n const hasPackageSwift = fs.existsSync(path.join(installDir, 'Package.swift'));\n const hasXcodeGenSpec = fs.existsSync(path.join(installDir, 'project.yml'));\n const xcodeProjects = await fg('*.{xcodeproj,xcworkspace}', {\n cwd: installDir,\n onlyDirectories: true,\n });\n\n if (hasPackageSwift && xcodeProjects.length === 0 && !hasXcodeGenSpec) {\n return SwiftProjectType.SPM;\n }\n\n // Check Swift source files for SwiftUI vs UIKit imports\n const swiftFiles = await boundedGlob('**/*.swift', {\n cwd: installDir,\n extraIgnore: EXTRA_IGNORE,\n limit: SOURCE_PROBE_LIMIT,\n });\n\n let hasSwiftUI = false;\n let hasUIKit = false;\n\n for (const file of swiftFiles) {\n const content = readProjectFile(path.join(installDir, file));\n if (!content) continue;\n if (content.includes('import SwiftUI')) {\n hasSwiftUI = true;\n }\n if (content.includes('import UIKit')) {\n hasUIKit = true;\n }\n }\n\n if (hasSwiftUI) return SwiftProjectType.SWIFTUI;\n if (hasUIKit) return SwiftProjectType.UIKIT;\n\n return undefined;\n}\n","/* Swift wizard using posthog-agent with PostHog MCP */\nimport type { WizardRunOptions } from '@utils/types';\nimport type { FrameworkConfig } from '@lib/framework-config';\nimport { swiftPackageManager } from '@lib/detection/package-manager';\nimport { Integration } from '@lib/constants';\nimport { boundedGlob } from '@utils/bounded-fs';\nimport fg from 'fast-glob';\nimport * as fs from 'node:fs';\nimport * as path from 'node:path';\nimport {\n detectSwiftProjectType,\n getSwiftProjectTypeName,\n SwiftProjectType,\n} from './utils';\n\ntype SwiftContext = {\n projectType?: SwiftProjectType;\n};\n\nexport const SWIFT_AGENT_CONFIG: FrameworkConfig<SwiftContext> = {\n metadata: {\n name: 'Swift (iOS/macOS)',\n integration: Integration.swift,\n docsUrl: 'https://posthog.com/docs/libraries/ios',\n preRunNotice:\n 'Please close the Xcode project before proceeding. Xcode may overwrite changes the wizard makes to project files.',\n gatherContext: async (options: WizardRunOptions) => {\n const projectType = await detectSwiftProjectType(options);\n return { projectType };\n },\n },\n\n detection: {\n packageName: 'posthog-ios',\n packageDisplayName: 'Swift',\n usesPackageJson: false,\n getVersion: () => undefined,\n detect: async (options) => {\n const { installDir } = options;\n\n // Xcode project/workspace, or an XcodeGen `project.yml` (the generated\n // .xcodeproj is often uncommitted).\n const xcodeProjects = await fg('*.{xcodeproj,xcworkspace}', {\n cwd: installDir,\n onlyDirectories: true,\n });\n const hasXcodeGenSpec = fs.existsSync(\n path.join(installDir, 'project.yml'),\n );\n\n if (xcodeProjects.length > 0 || hasXcodeGenSpec) {\n // Verify it contains Swift source files\n const swiftFiles = await boundedGlob('**/*.swift', {\n cwd: installDir,\n extraIgnore: ['**/.build/**', '**/*.xcodeproj/**'],\n limit: 1,\n });\n if (swiftFiles.length > 0) {\n return true;\n }\n }\n\n // Check for Swift Package Manager project\n const packageSwiftPath = path.join(installDir, 'Package.swift');\n if (fs.existsSync(packageSwiftPath)) {\n return true;\n }\n\n return false;\n },\n detectPackageManager: swiftPackageManager,\n },\n\n environment: {\n uploadToHosting: false,\n getEnvVars: (apiKey: string, host: string) => ({\n POSTHOG_PROJECT_TOKEN: apiKey,\n POSTHOG_HOST: host,\n }),\n },\n\n analytics: {\n getTags: (context) => ({\n projectType: context.projectType || 'unknown',\n }),\n },\n\n prompts: {\n projectTypeDetection:\n 'This is a Swift project. Look for .xcodeproj directories, Package.swift, and .swift source files to confirm. Check for SwiftUI or UIKit imports to determine the UI framework.',\n packageInstallation:\n 'Add the posthog-ios package via Swift Package Manager. For Xcode projects, add XCRemoteSwiftPackageReference and XCSwiftPackageProductDependency to the .pbxproj file. For Swift packages, add the dependency to Package.swift.',\n getAdditionalContextLines: (context) => {\n const projectTypeName = context.projectType\n ? getSwiftProjectTypeName(context.projectType)\n : 'unknown';\n\n const lines = [\n `Project type: ${projectTypeName}`,\n `Framework docs ID: swift (use posthog://docs/frameworks/swift for documentation)`,\n ];\n\n return lines;\n },\n },\n\n ui: {\n successMessage: 'PostHog integration complete',\n estimatedDurationMinutes: 5,\n getOutroChanges: (context) => {\n const projectTypeName = context.projectType\n ? getSwiftProjectTypeName(context.projectType)\n : 'Swift';\n\n const changes = [\n `Analyzed your ${projectTypeName} project structure`,\n `Added the PostHog iOS SDK via Swift Package Manager`,\n `Configured PostHog initialization in your app entry point`,\n `Added event capture and user identification`,\n ];\n\n return changes;\n },\n getOutroNextSteps: () => [\n 'Set POSTHOG_PROJECT_TOKEN and POSTHOG_HOST in your Xcode scheme environment variables',\n 'Build and run your app to see PostHog in action',\n 'Visit your PostHog dashboard to see incoming events',\n ],\n },\n};\n","/* Kotlin Multiplatform (KMP) wizard using posthog-agent with PostHog MCP */\nimport type { FrameworkConfig } from '../../lib/framework-config';\nimport { Integration } from '../../lib/constants';\nimport { gradlePackageManager } from '../../lib/detection/package-manager';\nimport { boundedGlob, readProjectFile } from '@utils/bounded-fs';\nimport * as path from 'node:path';\n\nexport const KMP_AGENT_CONFIG: FrameworkConfig = {\n metadata: {\n name: 'Kotlin Multiplatform',\n integration: Integration.kmp,\n beta: true,\n docsUrl: 'https://posthog.com/docs/libraries/kmp',\n preRunNotice:\n 'The PostHog Kotlin Multiplatform SDK is in early access (0.x pre-release). The API may change between minor versions.',\n },\n\n detection: {\n packageName: 'posthog-kmp',\n packageDisplayName: 'Kotlin Multiplatform',\n usesPackageJson: false,\n getVersion: () => undefined,\n detectPackageManager: gradlePackageManager,\n // KMP is detected before Android/Swift because a KMP project also looks like\n // an Android and/or Swift project. Detection therefore requires the Kotlin\n // Multiplatform Gradle plugin or a `commonMain` source set — signals that a\n // plain Android or Swift project does not have.\n detect: async (options) => {\n const { installDir } = options;\n\n // Strategy 1: a Gradle build file that applies the Kotlin Multiplatform plugin.\n const buildFiles = await boundedGlob(\n ['**/build.gradle', '**/build.gradle.kts'],\n { cwd: installDir },\n );\n\n for (const file of buildFiles) {\n const content = readProjectFile(path.join(installDir, file));\n if (!content) continue;\n if (\n content.includes('kotlin(\"multiplatform\")') ||\n content.includes('org.jetbrains.kotlin.multiplatform') ||\n content.includes('kotlin-multiplatform')\n ) {\n return true;\n }\n }\n\n // Strategy 2: a KMP `commonMain` source set exists.\n const commonMain = await boundedGlob('**/src/commonMain/**', {\n cwd: installDir,\n limit: 1,\n });\n\n return commonMain.length > 0;\n },\n },\n\n environment: {\n uploadToHosting: false,\n getEnvVars: (apiKey: string, host: string) => ({\n POSTHOG_PROJECT_TOKEN: apiKey,\n POSTHOG_HOST: host,\n }),\n },\n\n analytics: {\n getTags: () => ({}),\n },\n\n prompts: {\n projectTypeDetection:\n 'This is a Kotlin Multiplatform (KMP) project. Look for a build.gradle.kts (or build.gradle) that applies the Kotlin Multiplatform plugin (kotlin(\"multiplatform\") or org.jetbrains.kotlin.multiplatform) and a shared module with a src/commonMain source set.',\n packageInstallation:\n 'Add the PostHog KMP SDK to the shared module\\'s commonMain dependencies in build.gradle.kts: within the kotlin { sourceSets { ... } } block, add implementation(\"com.posthog:posthog-kmp:<VERSION>\") to commonMain.dependencies. Match the existing dependency format (Groovy vs Kotlin DSL).',\n getAdditionalContextLines: () => [\n 'Framework docs ID: kmp (use posthog://docs/frameworks/kmp for documentation)',\n 'Initialize once, early in the app lifecycle, from shared code. All PostHog APIs live in the com.posthog.kmp package.',\n 'Setup call: PostHog.setup(config = PostHogConfig(apiKey = \"<POSTHOG_PROJECT_TOKEN>\", host = \"<POSTHOG_HOST>\"), context = PostHogContext())',\n 'PostHogContext is platform-specific: on Android pass the Application via PostHogContext(application); on iOS and Web use the no-argument PostHogContext().',\n 'Imports: com.posthog.kmp.PostHog, com.posthog.kmp.PostHogConfig, com.posthog.kmp.PostHogContext.',\n ],\n },\n\n ui: {\n successMessage: 'PostHog integration complete',\n estimatedDurationMinutes: 5,\n getOutroChanges: () => [\n 'Analyzed your Kotlin Multiplatform project structure',\n 'Added the PostHog KMP SDK to your shared module',\n 'Configured PostHog initialization in your shared code',\n 'Added event capture and user identification',\n ],\n getOutroNextSteps: () => [\n 'Wire up the platform-specific PostHogContext for each target (Android/iOS/Web)',\n 'Build and run your app to see PostHog in action',\n 'Visit your PostHog dashboard to see incoming events',\n 'Check out the PostHog KMP docs for feature flags, session replay, and more',\n ],\n },\n};\n","import type { WizardRunOptions } from '@utils/types';\nimport { createVersionBucket } from '@utils/semver';\nimport { boundedGlob, readProjectFile } from '@utils/bounded-fs';\nimport * as fs from 'node:fs';\nimport * as path from 'node:path';\n\n/**\n * Extract minSdk from the app-level build.gradle(.kts).\n * Returns the value as a semver-like string (e.g. \"24\" from minSdk = 24).\n */\nexport async function getMinSdkVersion(\n options: WizardRunOptions,\n): Promise<string | undefined> {\n const { installDir } = options;\n\n const buildFiles = await boundedGlob(\n ['**/build.gradle', '**/build.gradle.kts'],\n { cwd: installDir },\n );\n\n for (const file of buildFiles) {\n const content = readProjectFile(path.join(installDir, file));\n if (!content) continue;\n // Match: minSdk = 24, minSdkVersion 21, minSdkVersion = 21\n const match = content.match(/minSdk(?:Version)?\\s*=?\\s*(\\d+)/);\n if (match) return match[1];\n }\n\n return undefined;\n}\n\nexport const getKotlinVersionBucket = createVersionBucket();\n\n/**\n * Read the root or app-level build.gradle(.kts) and extract the Kotlin version.\n */\nexport function getKotlinVersion(\n options: WizardRunOptions,\n): string | undefined {\n const { installDir } = options;\n\n for (const name of [\n 'build.gradle',\n 'build.gradle.kts',\n 'gradle/libs.versions.toml',\n ]) {\n const filePath = path.join(installDir, name);\n if (!fs.existsSync(filePath)) continue;\n\n const content = fs.readFileSync(filePath, 'utf-8');\n\n // build.gradle: kotlinVersion = \"2.0.21\" or ext.kotlin_version = '1.9.0'\n const match = content.match(/kotlin[_-]?[Vv]ersion\\s*=\\s*[\"']([^\"']+)[\"']/);\n if (match) return match[1];\n\n // libs.versions.toml: kotlin = \"2.0.21\"\n const tomlMatch = content.match(/^kotlin\\s*=\\s*[\"']([^\"']+)[\"']/m);\n if (tomlMatch) return tomlMatch[1];\n }\n\n return undefined;\n}\n","/* Android (Kotlin) wizard using posthog-agent with PostHog MCP */\nimport type { WizardRunOptions } from '@utils/types';\nimport type { FrameworkConfig } from '@lib/framework-config';\nimport { Integration } from '@lib/constants';\nimport { boundedGlob } from '@utils/bounded-fs';\nimport * as fs from 'node:fs';\nimport * as path from 'node:path';\nimport {\n getKotlinVersion,\n getKotlinVersionBucket,\n getMinSdkVersion,\n} from './utils';\nimport { gradlePackageManager } from '@lib/detection/package-manager';\n\ntype AndroidContext = {\n kotlinVersion?: string;\n};\n\nexport const ANDROID_AGENT_CONFIG: FrameworkConfig<AndroidContext> = {\n metadata: {\n name: 'Android (Kotlin)',\n integration: Integration.android,\n docsUrl: 'https://posthog.com/docs/libraries/android',\n gatherContext: (options: WizardRunOptions) => {\n const kotlinVersion = getKotlinVersion(options);\n return Promise.resolve({ kotlinVersion });\n },\n },\n\n detection: {\n packageName: 'posthog-android',\n packageDisplayName: 'Android (Kotlin)',\n usesPackageJson: false,\n getVersion: () => undefined,\n getVersionBucket: (version: string) => getKotlinVersionBucket(version),\n // This is actually pretty high for a minimum, but android apis aren't super stable.\n minimumVersion: '21.0.0',\n getInstalledVersion: (options: WizardRunOptions) =>\n getMinSdkVersion(options),\n detectPackageManager: gradlePackageManager,\n detect: async (options) => {\n const { installDir } = options;\n\n // pubspec.yaml means Flutter — its android/ subtree would match below.\n if (fs.existsSync(path.join(installDir, 'pubspec.yaml'))) {\n return false;\n }\n\n // Strategy 1: Check for build.gradle(.kts) with Android plugin\n for (const name of ['build.gradle', 'build.gradle.kts']) {\n const buildGradlePath = path.join(installDir, name);\n if (fs.existsSync(buildGradlePath)) {\n const content = fs.readFileSync(buildGradlePath, 'utf-8');\n if (\n content.includes('com.android.application') ||\n content.includes('com.android.library') ||\n content.includes('com.android.tools.build:gradle')\n ) {\n return true;\n }\n }\n }\n\n // Strategy 2: Check for AndroidManifest.xml with Kotlin source files\n // This could be an issue if we have Flutter in the mix, but we'll figure that out later.\n const manifestFiles = await boundedGlob('**/AndroidManifest.xml', {\n cwd: installDir,\n limit: 1,\n });\n\n if (manifestFiles.length > 0) {\n const kotlinFiles = await boundedGlob('**/*.kt', {\n cwd: installDir,\n limit: 1,\n });\n if (kotlinFiles.length > 0) {\n return true;\n }\n }\n\n return false;\n },\n },\n\n environment: {\n uploadToHosting: false,\n getEnvVars: (apiKey: string, host: string) => ({\n POSTHOG_PROJECT_TOKEN: apiKey,\n POSTHOG_HOST: host,\n }),\n },\n\n analytics: {\n getTags: (context) => ({\n ...(context.kotlinVersion\n ? { kotlinVersion: getKotlinVersionBucket(context.kotlinVersion) }\n : {}),\n }),\n },\n\n prompts: {\n projectTypeDetection:\n 'This is an Android/Kotlin project. Look for build.gradle or build.gradle.kts files, AndroidManifest.xml, and Kotlin source files (.kt) to confirm.',\n packageInstallation:\n 'Add the PostHog Android SDK dependency to the app-level build.gradle(.kts) file. Use implementation(\"com.posthog:posthog-android:<VERSION>\"). Check the existing dependency format (Groovy vs Kotlin DSL) and match it.',\n getAdditionalContextLines: (context) => {\n const lines = [\n `Framework docs ID: android (use posthog://docs/frameworks/android for documentation)`,\n ];\n\n if (context.kotlinVersion) {\n lines.push(`Kotlin version: ${context.kotlinVersion}`);\n }\n\n return lines;\n },\n },\n\n ui: {\n successMessage: 'PostHog integration complete',\n estimatedDurationMinutes: 5,\n getOutroChanges: () => [\n `Analyzed your Android project structure`,\n `Added the PostHog Android SDK dependency`,\n `Configured PostHog initialization in your Application class`,\n `Added event capture and user identification`,\n ],\n getOutroNextSteps: () => [\n 'Build and run your app to see PostHog in action',\n 'Visit your PostHog dashboard to see incoming events',\n 'Check out the PostHog Android docs for advanced features like feature flags and session replay',\n ],\n },\n};\n","import fg from 'fast-glob';\nimport { getUI } from '@ui';\nimport type { WizardRunOptions } from '@utils/types';\nimport { createVersionBucket } from '@utils/semver';\nimport * as fs from 'node:fs';\nimport * as path from 'node:path';\n\nexport enum RailsProjectType {\n STANDARD = 'standard', // Traditional Rails app (rails new)\n API = 'api', // Rails API-only (rails new --api)\n}\n\nconst IGNORE_PATTERNS = [\n '**/node_modules/**',\n '**/vendor/**',\n '**/vendor/bundle/**',\n '**/tmp/**',\n '**/log/**',\n '**/storage/**',\n];\n\n/**\n * Get Rails version bucket for analytics\n */\nexport const getRailsVersionBucket = createVersionBucket();\n\n/**\n * Read and parse Gemfile contents\n */\nfunction readGemfile(\n options: Pick<WizardRunOptions, 'installDir'>,\n): string | undefined {\n const { installDir } = options;\n\n const gemfilePath = path.join(installDir, 'Gemfile');\n try {\n return fs.readFileSync(gemfilePath, 'utf-8');\n } catch {\n return undefined;\n }\n}\n\n/**\n * Check if a gem is present in the Gemfile\n */\nexport function hasGem(\n gemName: string,\n options: Pick<WizardRunOptions, 'installDir'>,\n): boolean {\n const content = readGemfile(options);\n if (!content) return false;\n\n // Match gem declarations like: gem 'rails', gem \"rails\", gem 'rails', '~> 7.0'\n const gemPattern = new RegExp(`^\\\\s*gem\\\\s+['\"]${gemName}['\"]`, 'im');\n return gemPattern.test(content);\n}\n\n/**\n * Extract version for a gem from Gemfile\n */\nexport function getGemVersion(\n gemName: string,\n options: Pick<WizardRunOptions, 'installDir'>,\n): string | undefined {\n const content = readGemfile(options);\n if (!content) return undefined;\n\n const versionPattern = new RegExp(\n `^\\\\s*gem\\\\s+['\"]${gemName}['\"]\\\\s*,\\\\s*['\"][^0-9]*([0-9]+\\\\.[0-9]+(?:\\\\.[0-9]+)?)['\"]`,\n 'im',\n );\n const match = content.match(versionPattern);\n return match?.[1];\n}\n\n/**\n * Get Rails version from Gemfile\n */\nexport function getRailsVersion(\n options: Pick<WizardRunOptions, 'installDir'>,\n): string | undefined {\n return getGemVersion('rails', options);\n}\n\n/**\n * Detect Rails project type\n */\nexport function getRailsProjectType(\n options: WizardRunOptions,\n): RailsProjectType {\n const { installDir } = options;\n\n // Check for API-only mode in config/application.rb\n const appConfigPath = path.join(installDir, 'config/application.rb');\n if (fs.existsSync(appConfigPath)) {\n try {\n const content = fs.readFileSync(appConfigPath, 'utf-8');\n if (content.includes('config.api_only = true')) {\n getUI().setDetectedFramework('Rails API-only');\n return RailsProjectType.API;\n }\n } catch {\n // Continue to default\n }\n }\n\n getUI().setDetectedFramework('Rails');\n return RailsProjectType.STANDARD;\n}\n\n/**\n * Get human-readable name for Rails project type\n */\nexport function getRailsProjectTypeName(projectType: RailsProjectType): string {\n switch (projectType) {\n case RailsProjectType.STANDARD:\n return 'Standard Rails';\n case RailsProjectType.API:\n return 'Rails API';\n }\n}\n\n/**\n * Find the Rails initializers directory\n */\nexport function findInitializersDir(\n options: Pick<WizardRunOptions, 'installDir'>,\n): string | undefined {\n const { installDir } = options;\n\n const initializersDir = path.join(installDir, 'config/initializers');\n if (fs.existsSync(initializersDir)) {\n return 'config/initializers';\n }\n\n return undefined;\n}\n\n/**\n * Detect if the project is a Rails project by looking for typical Rails files\n */\nexport async function isRailsProject(\n options: Pick<WizardRunOptions, 'installDir'>,\n): Promise<boolean> {\n const { installDir } = options;\n\n // Check for bin/rails\n const binRailsPath = path.join(installDir, 'bin/rails');\n if (fs.existsSync(binRailsPath)) {\n return true;\n }\n\n // Check for config/application.rb with Rails reference\n const appConfigPath = path.join(installDir, 'config/application.rb');\n if (fs.existsSync(appConfigPath)) {\n try {\n const content = fs.readFileSync(appConfigPath, 'utf-8');\n if (\n content.includes('Rails::Application') ||\n content.includes('require \"rails\"') ||\n content.includes(\"require 'rails'\")\n ) {\n return true;\n }\n } catch {\n // Continue to other checks\n }\n }\n\n // Check Gemfile for rails gem\n if (hasGem('rails', options)) {\n return true;\n }\n\n // Check for typical Rails directory structure\n const railsStructureFiles = await fg(\n ['config/routes.rb', 'config/environment.rb'],\n { cwd: installDir, ignore: IGNORE_PATTERNS },\n );\n\n return railsStructureFiles.length >= 2;\n}\n","/* Ruby on Rails wizard using posthog-agent with PostHog MCP */\nimport type { WizardRunOptions } from '@utils/types';\nimport type { FrameworkConfig } from '@lib/framework-config';\nimport { bundlerPackageManager } from '@lib/detection/package-manager';\nimport { Integration } from '@lib/constants';\nimport {\n getRailsVersion,\n getRailsProjectType,\n getRailsProjectTypeName,\n getRailsVersionBucket,\n RailsProjectType,\n findInitializersDir,\n isRailsProject,\n} from './utils';\n\ntype RailsContext = {\n projectType?: RailsProjectType;\n initializersDir?: string;\n};\n\nexport const RAILS_AGENT_CONFIG: FrameworkConfig<RailsContext> = {\n metadata: {\n name: 'Ruby on Rails',\n integration: Integration.rails,\n docsUrl: 'https://posthog.com/docs/libraries/ruby-on-rails',\n unsupportedVersionDocsUrl: 'https://posthog.com/docs/libraries/ruby',\n gatherContext: (options: WizardRunOptions) => {\n const projectType = getRailsProjectType(options);\n const initializersDir = findInitializersDir(options);\n return Promise.resolve({ projectType, initializersDir });\n },\n },\n\n detection: {\n packageName: 'rails',\n packageDisplayName: 'Ruby on Rails',\n usesPackageJson: false,\n getVersion: () => undefined,\n getVersionBucket: getRailsVersionBucket,\n minimumVersion: '6.0.0',\n getInstalledVersion: (options: WizardRunOptions) =>\n Promise.resolve(getRailsVersion(options)),\n detect: async (options) => isRailsProject(options),\n detectPackageManager: bundlerPackageManager,\n },\n\n environment: {\n uploadToHosting: false,\n getEnvVars: (apiKey: string, host: string) => ({\n POSTHOG_PROJECT_TOKEN: apiKey,\n POSTHOG_HOST: host,\n }),\n },\n\n analytics: {\n getTags: (context) => ({\n projectType: context.projectType || 'unknown',\n }),\n },\n\n prompts: {\n projectTypeDetection:\n 'This is a Ruby on Rails project. Look for Gemfile, config/application.rb, bin/rails, and config/routes.rb to confirm.',\n packageInstallation:\n \"Use Bundler to install gems. Add `gem 'posthog-ruby'` and `gem 'posthog-rails'` to the Gemfile and run `bundle install`. Do not pin specific versions.\",\n getAdditionalContextLines: (context) => {\n const projectTypeName = context.projectType\n ? getRailsProjectTypeName(context.projectType)\n : 'unknown';\n\n const lines = [\n `Project type: ${projectTypeName}`,\n `Framework docs ID: ruby-on-rails (use posthog://docs/frameworks/ruby-on-rails for documentation)`,\n ];\n\n if (context.initializersDir) {\n lines.push(`Initializers directory: ${context.initializersDir}`);\n }\n\n if (context.projectType === RailsProjectType.API) {\n lines.push(\n 'Note: This is an API-only Rails app — skip frontend posthog-js integration',\n );\n }\n\n return lines;\n },\n },\n\n ui: {\n successMessage: 'PostHog integration complete',\n estimatedDurationMinutes: 5,\n getOutroChanges: (context) => {\n const projectTypeName = context.projectType\n ? getRailsProjectTypeName(context.projectType)\n : 'Rails';\n\n const changes = [\n `Analyzed your ${projectTypeName} project structure`,\n `Installed the posthog-ruby and posthog-rails gems via Bundler`,\n `Created PostHog initializer in config/initializers/posthog.rb`,\n `Configured automatic exception capture and ActiveJob instrumentation`,\n ];\n\n if (context.projectType !== RailsProjectType.API) {\n changes.push(\n 'Added posthog-js snippet to the layout template for frontend tracking',\n );\n }\n\n return changes;\n },\n getOutroNextSteps: () => [\n 'Start your Rails development server with `bin/rails server`',\n 'Visit your PostHog dashboard to see incoming events',\n 'Use PostHog.capture() to track custom events',\n 'Use PostHog.identify() to associate events with users',\n 'Define posthog_distinct_id on your User model for automatic user association',\n ],\n },\n};\n","/* Elixir wizard using posthog-agent with PostHog MCP */\nimport * as fs from 'node:fs';\nimport * as path from 'node:path';\nimport type { WizardRunOptions } from '@utils/types';\nimport type { FrameworkConfig } from '@lib/framework-config';\nimport { mixPackageManager } from '@lib/detection/package-manager';\nimport { Integration } from '@lib/constants';\n\ntype ElixirContext = {\n phoenix?: boolean;\n};\n\nfunction readMixExs(installDir: string): string | undefined {\n const mixExsPath = path.join(installDir, 'mix.exs');\n if (!fs.existsSync(mixExsPath)) {\n return undefined;\n }\n return fs.readFileSync(mixExsPath, 'utf-8');\n}\n\n/** Phoenix apps get the Plug integration; plain Elixir apps don't. */\nfunction isPhoenixProject(installDir: string): boolean {\n const mixExs = readMixExs(installDir);\n return !!mixExs && /\\{\\s*:phoenix\\s*,/.test(mixExs);\n}\n\nexport const ELIXIR_AGENT_CONFIG: FrameworkConfig<ElixirContext> = {\n metadata: {\n name: 'Elixir',\n integration: Integration.elixir,\n docsUrl: 'https://posthog.com/docs/libraries/elixir',\n gatherContext: (options: WizardRunOptions) => {\n const phoenix = isPhoenixProject(options.installDir);\n return Promise.resolve({ phoenix });\n },\n },\n\n detection: {\n packageName: 'posthog',\n packageDisplayName: 'Elixir',\n usesPackageJson: false,\n getVersion: () => undefined,\n // A mix.exs defining a project marks a Mix project root; the def project\n // check keeps stray files named mix.exs from claiming the directory.\n detect: (options) => {\n const mixExs = readMixExs(options.installDir);\n return Promise.resolve(!!mixExs && /def\\s+project\\b/.test(mixExs));\n },\n detectPackageManager: mixPackageManager,\n },\n\n environment: {\n uploadToHosting: false,\n getEnvVars: (apiKey: string, host: string) => ({\n POSTHOG_API_KEY: apiKey,\n POSTHOG_HOST: host,\n }),\n },\n\n analytics: {\n getTags: (context) => ({\n projectType: context.phoenix ? 'phoenix' : 'elixir',\n }),\n },\n\n prompts: {\n projectTypeDetection:\n 'This is an Elixir project. Look for mix.exs, mix.lock, config/, lib/, and application.ex to confirm; Phoenix apps also have endpoint and router modules.',\n packageInstallation:\n 'Mix has no single add command. Add `{:posthog, \"~> 2.0\"}` to the deps list in mix.exs, then run `mix deps.get` to fetch it.',\n getAdditionalContextLines: (context) => {\n const lines = [\n `Framework docs ID: elixir (use posthog://docs/frameworks/elixir for documentation)`,\n 'Configure PostHog in application config (api_key, api_host, in_app_otp_apps) reading from environment variables; set test_mode: true in the test environment.',\n ];\n if (context.phoenix) {\n lines.push(\n 'This is a Phoenix app — add PostHog.Integrations.Plug before the router so request context is attached to captured events.',\n );\n }\n return lines;\n },\n },\n\n ui: {\n successMessage: 'PostHog integration complete',\n estimatedDurationMinutes: 5,\n getOutroChanges: (context) => [\n `Analyzed your ${\n context.phoenix ? 'Phoenix' : 'Elixir'\n } project structure`,\n 'Added the posthog Hex package to mix.exs and fetched it with mix deps.get',\n 'Configured PostHog in application config from environment variables',\n 'Instrumented meaningful events with PostHog.capture',\n ],\n getOutroNextSteps: (context) => [\n context.phoenix\n ? 'Start your Phoenix server with `mix phx.server` and trigger the instrumented code paths'\n : 'Run your Elixir application and trigger the instrumented code paths',\n 'Visit your PostHog dashboard to see incoming events',\n 'Use PostHog.capture/2 to track custom events',\n 'Use PostHog.set_context/1 to set a distinct_id once per request or job process',\n ],\n },\n};\n","/* Go wizard using posthog-agent with PostHog MCP */\nimport * as fs from 'node:fs';\nimport * as path from 'node:path';\nimport type { WizardRunOptions } from '@utils/types';\nimport type { FrameworkConfig } from '@lib/framework-config';\nimport { goModulesPackageManager } from '@lib/detection/package-manager';\nimport { Integration } from '@lib/constants';\n\ntype GoContext = {\n goVersion?: string;\n};\n\nfunction readGoMod(installDir: string): string | undefined {\n const goModPath = path.join(installDir, 'go.mod');\n if (!fs.existsSync(goModPath)) {\n return undefined;\n }\n return fs.readFileSync(goModPath, 'utf-8');\n}\n\n/** The `go 1.x` directive from go.mod (the toolchain floor, not a patch version). */\nfunction getGoVersion(installDir: string): string | undefined {\n const goMod = readGoMod(installDir);\n return goMod?.match(/^go\\s+([\\d.]+)/m)?.[1];\n}\n\nexport const GO_AGENT_CONFIG: FrameworkConfig<GoContext> = {\n metadata: {\n name: 'Go',\n integration: Integration.go,\n docsUrl: 'https://posthog.com/docs/libraries/go',\n gatherContext: (options: WizardRunOptions) => {\n const goVersion = getGoVersion(options.installDir);\n return Promise.resolve({ goVersion });\n },\n },\n\n detection: {\n packageName: 'posthog-go',\n packageDisplayName: 'Go',\n usesPackageJson: false,\n getVersion: () => undefined,\n // A go.mod with a module directive marks a Go module root; a bare\n // directory containing .go files without one is not integratable.\n detect: (options) => {\n const goMod = readGoMod(options.installDir);\n return Promise.resolve(!!goMod && /^module\\s+\\S+/m.test(goMod));\n },\n detectPackageManager: goModulesPackageManager,\n },\n\n environment: {\n uploadToHosting: false,\n getEnvVars: (apiKey: string, host: string) => ({\n POSTHOG_API_KEY: apiKey,\n POSTHOG_HOST: host,\n }),\n },\n\n analytics: {\n getTags: (context) => ({\n goVersion: context.goVersion || 'unknown',\n }),\n },\n\n prompts: {\n projectTypeDetection:\n 'This is a Go project. Look for go.mod, go.sum, cmd/, internal/, and main packages to confirm.',\n packageInstallation:\n 'Install the PostHog Go SDK with `go get github.com/posthog/posthog-go`. Do not manually edit go.mod or go.sum; the go tool updates them automatically. Run `go mod tidy` afterwards if imports change.',\n getAdditionalContextLines: (context) => {\n const lines = [\n `Framework docs ID: go (use posthog://docs/frameworks/go for documentation)`,\n ];\n if (context.goVersion) {\n lines.push(`Go version (go.mod directive): ${context.goVersion}`);\n }\n lines.push(\n 'Create one PostHog client per process and close it during graceful shutdown (`defer client.Close()`) so queued events flush.',\n );\n return lines;\n },\n },\n\n ui: {\n successMessage: 'PostHog integration complete',\n estimatedDurationMinutes: 5,\n getOutroChanges: () => [\n 'Analyzed your Go project structure',\n 'Installed the posthog-go SDK via go get',\n 'Initialized a shared PostHog client configured from environment variables',\n 'Instrumented meaningful server events with client.Enqueue(posthog.Capture{...})',\n ],\n getOutroNextSteps: () => [\n 'Run your Go service and trigger the instrumented code paths',\n 'Visit your PostHog dashboard to see incoming events',\n 'Use client.Enqueue(posthog.Capture{...}) to track custom events',\n 'Keep client.Close() in your graceful shutdown path so queued events flush',\n ],\n },\n};\n","/* Java (server) wizard using posthog-agent with PostHog MCP */\nimport fg from 'fast-glob';\nimport * as fs from 'node:fs';\nimport * as path from 'node:path';\nimport type { WizardRunOptions } from '@utils/types';\nimport type { FrameworkConfig } from '@lib/framework-config';\nimport { detectJavaPackageManagers } from '@lib/detection/package-manager';\nimport { Integration } from '@lib/constants';\n\ntype JavaContext = {\n buildTool?: 'maven' | 'gradle';\n};\n\nconst GRADLE_FILES = [\n 'build.gradle',\n 'build.gradle.kts',\n 'settings.gradle',\n 'settings.gradle.kts',\n];\n\nconst ANDROID_GRADLE_MARKERS = [\n 'com.android.application',\n 'com.android.library',\n 'com.android.tools.build:gradle',\n];\n\nconst KMP_GRADLE_MARKERS = [\n 'kotlin(\"multiplatform\")',\n 'org.jetbrains.kotlin.multiplatform',\n 'kotlin-multiplatform',\n];\n\nfunction readRootGradleFiles(installDir: string): string[] {\n return GRADLE_FILES.map((name) => path.join(installDir, name))\n .filter((p) => fs.existsSync(p))\n .map((p) => fs.readFileSync(p, 'utf-8'));\n}\n\nfunction getBuildTool(installDir: string): 'maven' | 'gradle' | undefined {\n if (fs.existsSync(path.join(installDir, 'pom.xml'))) {\n return 'maven';\n }\n if (readRootGradleFiles(installDir).length > 0) {\n return 'gradle';\n }\n return undefined;\n}\n\nexport const JAVA_AGENT_CONFIG: FrameworkConfig<JavaContext> = {\n metadata: {\n name: 'Java',\n integration: Integration.java,\n docsUrl: 'https://posthog.com/docs/libraries/java',\n gatherContext: (options: WizardRunOptions) => {\n const buildTool = getBuildTool(options.installDir);\n return Promise.resolve({ buildTool });\n },\n },\n\n detection: {\n packageName: 'posthog-server',\n packageDisplayName: 'Java',\n usesPackageJson: false,\n getVersion: () => undefined,\n // Maven projects (pom.xml) are unambiguously JVM backends. Gradle\n // projects are only claimed when they are neither Android nor KMP —\n // those detectors are ordered earlier, and this re-check keeps a\n // direct java detect() call from ever claiming their projects.\n detect: async (options) => {\n const { installDir } = options;\n\n // pubspec.yaml means Flutter — its gradle subtree is not a JVM backend.\n if (fs.existsSync(path.join(installDir, 'pubspec.yaml'))) {\n return false;\n }\n\n if (fs.existsSync(path.join(installDir, 'pom.xml'))) {\n return true;\n }\n\n const gradleContents = readRootGradleFiles(installDir);\n if (gradleContents.length === 0) {\n return false;\n }\n const combined = gradleContents.join('\\n');\n if (\n [...ANDROID_GRADLE_MARKERS, ...KMP_GRADLE_MARKERS].some((marker) =>\n combined.includes(marker),\n )\n ) {\n return false;\n }\n\n const manifestFiles = await fg('**/AndroidManifest.xml', {\n cwd: installDir,\n ignore: ['**/build/**', '**/node_modules/**', '**/.gradle/**'],\n });\n return manifestFiles.length === 0;\n },\n detectPackageManager: detectJavaPackageManagers,\n },\n\n environment: {\n uploadToHosting: false,\n getEnvVars: (apiKey: string, host: string) => ({\n POSTHOG_API_KEY: apiKey,\n POSTHOG_HOST: host,\n }),\n },\n\n analytics: {\n getTags: (context) => ({\n buildTool: context.buildTool || 'unknown',\n }),\n },\n\n prompts: {\n projectTypeDetection:\n 'This is a Java server project. Look for pom.xml (Maven) or build.gradle/build.gradle.kts (Gradle), src/main/java/, and the framework in use (Spring Boot, Quarkus, Micronaut, plain servlets) to confirm.',\n packageInstallation:\n 'Neither Maven nor Gradle has a single add command. Add the com.posthog:posthog-server dependency (pinned to the latest release on Maven Central) to pom.xml or build.gradle(.kts), matching the existing dependency format, then run `mvn install` or `gradle build` to resolve it.',\n getAdditionalContextLines: (context) => {\n const lines = [\n `Framework docs ID: java (use posthog://docs/frameworks/java for documentation)`,\n 'Use the posthog-server SDK (com.posthog:posthog-server) — posthog-android is a different library and must not be used on the server.',\n 'Create one PostHog client per process with PostHogConfig.builder(...) and PostHog.with(config); call close() during graceful shutdown, and flush() before returning in serverless handlers.',\n ];\n if (context.buildTool) {\n lines.push(`Build tool: ${context.buildTool}`);\n }\n return lines;\n },\n },\n\n ui: {\n successMessage: 'PostHog integration complete',\n estimatedDurationMinutes: 5,\n getOutroChanges: (context) => [\n 'Analyzed your Java project structure',\n `Added the posthog-server dependency to your ${\n context.buildTool === 'maven' ? 'pom.xml' : 'Gradle build'\n }`,\n 'Initialized a shared PostHog client configured from environment variables',\n 'Instrumented meaningful server events with posthog.capture',\n ],\n getOutroNextSteps: () => [\n 'Run your Java service and trigger the instrumented code paths',\n 'Visit your PostHog dashboard to see incoming events',\n 'Use posthog.capture(distinctId, eventName, options) to track custom events',\n 'Keep posthog.close() in your graceful shutdown path so queued events flush',\n ],\n },\n};\n","/* Rust wizard using posthog-agent with PostHog MCP */\nimport * as fs from 'node:fs';\nimport * as path from 'node:path';\nimport type { WizardRunOptions } from '@utils/types';\nimport type { FrameworkConfig } from '@lib/framework-config';\nimport { cargoPackageManager } from '@lib/detection/package-manager';\nimport { Integration } from '@lib/constants';\n\ntype RustContext = {\n asyncRuntime?: boolean;\n};\n\nfunction readCargoToml(installDir: string): string | undefined {\n const cargoTomlPath = path.join(installDir, 'Cargo.toml');\n if (!fs.existsSync(cargoTomlPath)) {\n return undefined;\n }\n return fs.readFileSync(cargoTomlPath, 'utf-8');\n}\n\n/** posthog-rs defaults to its async client; projects without an async runtime need the blocking one. */\nfunction hasAsyncRuntime(installDir: string): boolean {\n const cargoToml = readCargoToml(installDir);\n return !!cargoToml && /^\\s*(tokio|async-std|smol)\\s*[=.]/m.test(cargoToml);\n}\n\nexport const RUST_AGENT_CONFIG: FrameworkConfig<RustContext> = {\n metadata: {\n name: 'Rust',\n integration: Integration.rust,\n docsUrl: 'https://posthog.com/docs/libraries/rust',\n gatherContext: (options: WizardRunOptions) => {\n const asyncRuntime = hasAsyncRuntime(options.installDir);\n return Promise.resolve({ asyncRuntime });\n },\n },\n\n detection: {\n packageName: 'posthog-rs',\n packageDisplayName: 'Rust',\n usesPackageJson: false,\n getVersion: () => undefined,\n // A Cargo.toml with a [package] section marks a crate root. A\n // workspace-root-only manifest ([workspace], no [package]) falls\n // through — the agentic monorepo scan finds the nested crates.\n detect: (options) => {\n const cargoToml = readCargoToml(options.installDir);\n return Promise.resolve(!!cargoToml && /^\\s*\\[package\\]/m.test(cargoToml));\n },\n detectPackageManager: cargoPackageManager,\n },\n\n environment: {\n uploadToHosting: false,\n getEnvVars: (apiKey: string, host: string) => ({\n POSTHOG_API_KEY: apiKey,\n POSTHOG_HOST: host,\n }),\n },\n\n analytics: {\n getTags: (context) => ({\n asyncRuntime: context.asyncRuntime ? 'true' : 'false',\n }),\n },\n\n prompts: {\n projectTypeDetection:\n 'This is a Rust project. Look for Cargo.toml with a [package] section, src/main.rs or src/lib.rs, and Cargo.lock to confirm.',\n packageInstallation:\n 'Install the PostHog Rust SDK with `cargo add posthog-rs`. Do not manually edit Cargo.toml; cargo updates it automatically.',\n getAdditionalContextLines: (context) => {\n const lines = [\n `Framework docs ID: rust (use posthog://docs/frameworks/rust for documentation)`,\n 'capture() hands events to a background worker — the client must flush() or shutdown() before the process exits or buffered events are lost.',\n ];\n if (context.asyncRuntime) {\n lines.push(\n 'An async runtime is present — use the default async posthog-rs client.',\n );\n } else {\n lines.push(\n 'No async runtime detected — install with `cargo add posthog-rs --no-default-features` and use the blocking client.',\n );\n }\n return lines;\n },\n },\n\n ui: {\n successMessage: 'PostHog integration complete',\n estimatedDurationMinutes: 5,\n getOutroChanges: () => [\n 'Analyzed your Rust project structure',\n 'Installed the posthog-rs crate via cargo add',\n 'Initialized a shared PostHog client configured from environment variables',\n 'Instrumented meaningful events with client.capture',\n ],\n getOutroNextSteps: () => [\n 'Run your Rust application and trigger the instrumented code paths',\n 'Visit your PostHog dashboard to see incoming events',\n 'Use Event::new(event_name, distinct_id) and client.capture to track custom events',\n 'Keep flush()/shutdown() in your exit path so queued events are sent',\n ],\n },\n};\n","/* Generic Python language wizard using posthog-agent with PostHog MCP */\nimport type { WizardRunOptions } from '@utils/types';\nimport type { FrameworkConfig } from '@lib/framework-config';\nimport { PYTHON_PACKAGE_INSTALLATION } from '@lib/framework-config';\nimport { detectPythonPackageManagers } from '@lib/detection/package-manager';\nimport { Integration } from '@lib/constants';\nimport fg from 'fast-glob';\nimport * as fs from 'node:fs';\nimport * as path from 'node:path';\nimport {\n getPythonVersion,\n getPythonVersionBucket,\n detectPackageManager,\n getPackageManagerName,\n PythonPackageManager,\n} from './utils';\n\ntype PythonContext = {\n packageManager?: PythonPackageManager;\n};\n\nexport const PYTHON_AGENT_CONFIG: FrameworkConfig<PythonContext> = {\n metadata: {\n name: 'Python Language',\n integration: Integration.python,\n docsUrl: 'https://posthog.com/docs/libraries/python',\n gatherContext: async (options: WizardRunOptions) => {\n const packageManager = await detectPackageManager(options);\n return { packageManager };\n },\n },\n\n detection: {\n packageName: 'python',\n packageDisplayName: 'Python',\n usesPackageJson: false,\n getVersion: () => undefined,\n getVersionBucket: getPythonVersionBucket,\n minimumVersion: '3.8.0',\n getInstalledVersion: (options: WizardRunOptions) =>\n Promise.resolve(getPythonVersion(options)),\n detect: async (options) => {\n const { installDir } = options;\n\n // Look for Python package management files\n const pythonConfigFiles = await fg(\n [\n '**/requirements*.txt',\n '**/pyproject.toml',\n '**/setup.py',\n '**/Pipfile',\n ],\n {\n cwd: installDir,\n ignore: ['**/venv/**', '**/.venv/**', '**/env/**', '**/.env/**'],\n },\n );\n\n if (pythonConfigFiles.length === 0) {\n return false;\n }\n\n // Make sure this isn't Django or Flask (those should be detected first)\n // Check for Django\n const managePyMatches = await fg('**/manage.py', {\n cwd: installDir,\n ignore: ['**/venv/**', '**/.venv/**', '**/env/**', '**/.env/**'],\n });\n\n for (const match of managePyMatches) {\n try {\n const content = fs.readFileSync(\n path.join(installDir, match),\n 'utf-8',\n );\n if (\n content.includes('django') ||\n content.includes('DJANGO_SETTINGS_MODULE')\n ) {\n return false; // Django detected, use django agent instead\n }\n } catch {\n continue;\n }\n }\n\n // Check for Flask\n for (const configFile of pythonConfigFiles) {\n try {\n const content = fs.readFileSync(\n path.join(installDir, configFile),\n 'utf-8',\n );\n if (\n /^flask([<>=~!]|$|\\s)/im.test(content) ||\n /[\"']flask[\"']/i.test(content)\n ) {\n return false; // Flask detected, use flask agent instead\n }\n } catch {\n continue;\n }\n }\n\n const pyFiles = await fg(\n ['**/app.py', '**/wsgi.py', '**/application.py', '**/__init__.py'],\n {\n cwd: installDir,\n ignore: [\n '**/venv/**',\n '**/.venv/**',\n '**/env/**',\n '**/.env/**',\n '**/__pycache__/**',\n ],\n },\n );\n\n for (const pyFile of pyFiles) {\n try {\n const content = fs.readFileSync(\n path.join(installDir, pyFile),\n 'utf-8',\n );\n if (\n content.includes('from flask import') ||\n content.includes('import flask') ||\n /Flask\\s*\\(/.test(content)\n ) {\n return false; // Flask detected, use flask agent instead\n }\n } catch {\n continue;\n }\n }\n\n // If we have Python config files but it's not Django or Flask, it's a generic Python project\n return true;\n },\n detectPackageManager: detectPythonPackageManagers,\n },\n\n environment: {\n uploadToHosting: false,\n getEnvVars: (apiKey: string, host: string) => ({\n POSTHOG_PROJECT_TOKEN: apiKey,\n POSTHOG_HOST: host,\n }),\n },\n\n analytics: {\n getTags: (context) => {\n const packageManagerName = context.packageManager\n ? getPackageManagerName(context.packageManager)\n : 'unknown';\n return {\n packageManager: packageManagerName,\n };\n },\n },\n\n prompts: {\n packageInstallation: PYTHON_PACKAGE_INSTALLATION,\n projectTypeDetection:\n 'This is a generic Python project. Look for requirements.txt, pyproject.toml, setup.py, or Pipfile to confirm.',\n getAdditionalContextLines: (context) => {\n const packageManagerName = context.packageManager\n ? getPackageManagerName(context.packageManager)\n : 'unknown';\n\n return [\n `Package manager: ${packageManagerName}`,\n `Framework docs ID: python (use posthog://docs/frameworks/python for documentation)`,\n `Project type: Generic Python application (CLI, script, worker, data pipeline, etc.)`,\n ];\n },\n },\n\n ui: {\n successMessage: 'PostHog integration complete',\n estimatedDurationMinutes: 5,\n getOutroChanges: (context) => {\n const packageManagerName = context.packageManager\n ? getPackageManagerName(context.packageManager)\n : 'package manager';\n return [\n `Analyzed your Python project structure`,\n `Installed the PostHog Python package using ${packageManagerName}`,\n `Created PostHog initialization using instance-based API (Posthog class)`,\n `Configured exception autocapture and graceful shutdown`,\n `Added example code for events, feature flags, and error capture (without PII)`,\n ];\n },\n getOutroNextSteps: () => [\n 'Use Posthog() class (not module-level posthog) with enable_exception_autocapture=True',\n 'Call posthog_client.shutdown() on application exit (use atexit.register)',\n 'NEVER send PII in event properties (no emails, names, or user content)',\n 'Use posthog_client.capture() for events and posthog_client.identify() for users',\n 'Visit your PostHog dashboard to see incoming events',\n ],\n },\n};\n","import { boundedGlob } from '@utils/bounded-fs';\nimport type { WizardRunOptions } from '@utils/types';\nimport { createVersionBucket } from '@utils/semver';\nimport * as fs from 'node:fs';\nimport * as path from 'node:path';\n\nexport enum RubyPackageManager {\n BUNDLER = 'bundler',\n MANUAL = 'manual',\n}\n\nconst EXTRA_IGNORE = ['**/tmp/**', '**/log/**'];\n\n/**\n * Get Ruby version bucket for analytics\n */\nexport const getRubyVersionBucket = createVersionBucket();\n\n/**\n * Detect Ruby package manager\n */\nexport function detectPackageManager(\n options: Pick<WizardRunOptions, 'installDir'>,\n): RubyPackageManager {\n const { installDir } = options;\n\n const gemfilePath = path.join(installDir, 'Gemfile');\n if (fs.existsSync(gemfilePath)) {\n return RubyPackageManager.BUNDLER;\n }\n\n return RubyPackageManager.MANUAL;\n}\n\n/**\n * Get human-readable name for package manager\n */\nexport function getPackageManagerName(\n packageManager: RubyPackageManager,\n): string {\n switch (packageManager) {\n case RubyPackageManager.BUNDLER:\n return 'Bundler';\n case RubyPackageManager.MANUAL:\n return 'gem install';\n }\n}\n\n/**\n * Get Ruby version from .ruby-version file or Gemfile\n */\nexport function getRubyVersion(\n options: Pick<WizardRunOptions, 'installDir'>,\n): string | undefined {\n const { installDir } = options;\n\n // Check .ruby-version file\n const rubyVersionPath = path.join(installDir, '.ruby-version');\n try {\n const content = fs.readFileSync(rubyVersionPath, 'utf-8').trim();\n // Remove \"ruby-\" prefix if present\n const version = content.replace(/^ruby-/, '');\n if (/^[0-9]+\\.[0-9]+/.test(version)) {\n return version;\n }\n } catch {\n // Continue to other checks\n }\n\n // Check Gemfile for ruby version declaration\n const gemfilePath = path.join(installDir, 'Gemfile');\n try {\n const content = fs.readFileSync(gemfilePath, 'utf-8');\n const match = content.match(/ruby\\s+['\"]([0-9]+\\.[0-9]+(?:\\.[0-9]+)?)['\"]/);\n if (match) {\n return match[1];\n }\n } catch {\n // No Gemfile\n }\n\n return undefined;\n}\n\n/**\n * Check if the project is a Ruby project (but not Rails)\n */\nexport async function isRubyProject(\n options: Pick<WizardRunOptions, 'installDir'>,\n): Promise<boolean> {\n const { installDir } = options;\n\n // Check for Gemfile\n const gemfilePath = path.join(installDir, 'Gemfile');\n if (fs.existsSync(gemfilePath)) {\n // Make sure this isn't a Rails project (Rails should be detected first)\n try {\n const content = fs.readFileSync(gemfilePath, 'utf-8');\n if (/^\\s*gem\\s+['\"]rails['\"]/im.test(content)) {\n return false; // Rails project, use rails agent instead\n }\n } catch {\n // Continue checking\n }\n return true;\n }\n\n // Check for .ruby-version file\n const rubyVersionPath = path.join(installDir, '.ruby-version');\n if (fs.existsSync(rubyVersionPath)) {\n return true;\n }\n\n // Check for *.gemspec files\n const gemspecFiles = await boundedGlob('*.gemspec', {\n cwd: installDir,\n extraIgnore: EXTRA_IGNORE,\n limit: 1,\n });\n\n if (gemspecFiles.length > 0) {\n return true;\n }\n\n // Check for Ruby source files in the root\n const rubyFiles = await boundedGlob(['*.rb', 'lib/**/*.rb', 'bin/**/*.rb'], {\n cwd: installDir,\n extraIgnore: EXTRA_IGNORE,\n limit: 1,\n });\n\n return rubyFiles.length > 0;\n}\n","/* Generic Ruby language wizard using posthog-agent with PostHog MCP */\nimport type { WizardRunOptions } from '@utils/types';\nimport type { FrameworkConfig } from '@lib/framework-config';\nimport { bundlerPackageManager } from '@lib/detection/package-manager';\nimport { Integration } from '@lib/constants';\nimport {\n getRubyVersion,\n getRubyVersionBucket,\n detectPackageManager,\n getPackageManagerName,\n RubyPackageManager,\n isRubyProject,\n} from './utils';\n\ntype RubyContext = {\n packageManager?: RubyPackageManager;\n};\n\nexport const RUBY_AGENT_CONFIG: FrameworkConfig<RubyContext> = {\n metadata: {\n name: 'Ruby',\n integration: Integration.ruby,\n docsUrl: 'https://posthog.com/docs/libraries/ruby',\n gatherContext: (options: WizardRunOptions) => {\n const packageManager = detectPackageManager(options);\n return Promise.resolve({ packageManager });\n },\n },\n\n detection: {\n packageName: 'ruby',\n packageDisplayName: 'Ruby',\n usesPackageJson: false,\n getVersion: () => undefined,\n getVersionBucket: getRubyVersionBucket,\n minimumVersion: '2.7.0',\n getInstalledVersion: (options: WizardRunOptions) =>\n Promise.resolve(getRubyVersion(options)),\n detect: async (options) => isRubyProject(options),\n detectPackageManager: bundlerPackageManager,\n },\n\n environment: {\n uploadToHosting: false,\n getEnvVars: (apiKey: string, host: string) => ({\n POSTHOG_PROJECT_TOKEN: apiKey,\n POSTHOG_HOST: host,\n }),\n },\n\n analytics: {\n getTags: (context) => {\n const packageManagerName = context.packageManager\n ? getPackageManagerName(context.packageManager)\n : 'unknown';\n return {\n packageManager: packageManagerName,\n };\n },\n },\n\n prompts: {\n projectTypeDetection:\n 'This is a Ruby project. Look for Gemfile, *.gemspec, .ruby-version, or *.rb files to confirm.',\n packageInstallation:\n \"Use Bundler if a Gemfile is present (add `gem 'posthog-ruby'` and run `bundle install`). Otherwise use `gem install posthog-ruby`. Do not pin a specific version.\",\n getAdditionalContextLines: (context) => {\n const packageManagerName = context.packageManager\n ? getPackageManagerName(context.packageManager)\n : 'unknown';\n\n const lines = [\n `Package manager: ${packageManagerName}`,\n `Framework docs ID: ruby (use posthog://docs/frameworks/ruby for documentation)`,\n `Project type: Generic Ruby application (CLI, script, gem, worker, etc.)`,\n ``,\n `## CRITICAL: Ruby PostHog Best Practices`,\n ``,\n `### 1. Gem Name vs Require`,\n `The gem is named posthog-ruby but you require it as 'posthog':`,\n ` gem 'posthog-ruby' # in Gemfile`,\n ` require 'posthog' # in code (NOT require 'posthog-ruby')`,\n ``,\n `### 2. Use Instance-Based API (REQUIRED for scripts/CLIs)`,\n `Use PostHog::Client.new for scripts and standalone applications:`,\n ``,\n `client = PostHog::Client.new(`,\n ` api_key: ENV['POSTHOG_PROJECT_TOKEN'],`,\n ` host: ENV['POSTHOG_HOST'] || 'https://us.i.posthog.com'`,\n `)`,\n ``,\n `### 3. MUST Call shutdown Before Exit`,\n `In scripts and CLIs, you MUST call client.shutdown or events will be lost:`,\n ``,\n `begin`,\n ` client.capture(distinct_id: 'user_123', event: 'my_event')`,\n `ensure`,\n ` client.shutdown`,\n `end`,\n ``,\n `### 4. capture_exception Takes Positional Args`,\n `client.capture_exception(exception, distinct_id, additional_properties)`,\n `Do NOT use keyword arguments for capture_exception.`,\n ``,\n `### 5. NEVER Send PII`,\n `Do NOT include emails, names, phone numbers, or user content in event properties.`,\n ];\n\n return lines;\n },\n },\n\n ui: {\n successMessage: 'PostHog integration complete',\n estimatedDurationMinutes: 5,\n getOutroChanges: (context) => {\n const packageManagerName = context.packageManager\n ? getPackageManagerName(context.packageManager)\n : 'package manager';\n return [\n `Analyzed your Ruby project structure`,\n `Installed the posthog-ruby gem using ${packageManagerName}`,\n `Created PostHog initialization with instance-based API`,\n `Configured shutdown handler for proper event flushing`,\n ];\n },\n getOutroNextSteps: () => [\n 'Use client.capture() for events and client.identify() for users',\n 'Always call client.shutdown() before your application exits',\n 'Visit your PostHog dashboard to see incoming events',\n ],\n },\n};\n","/* Generic Node.js language wizard using posthog-agent with PostHog MCP */\nimport type { FrameworkConfig } from '@lib/framework-config';\nimport { Integration } from '@lib/constants';\nimport { tryGetPackageJson } from '@utils/setup-utils';\nimport { detectNodePackageManagers } from '@lib/detection/package-manager';\n\ntype JavaScriptNodeContext = Record<string, unknown>;\n\nexport const JAVASCRIPT_NODE_AGENT_CONFIG: FrameworkConfig<JavaScriptNodeContext> =\n {\n metadata: {\n name: 'Node.js',\n integration: Integration.javascriptNode,\n docsUrl: 'https://posthog.com/docs/libraries/node',\n },\n\n detection: {\n packageName: 'posthog-node',\n packageDisplayName: 'Node.js',\n usesPackageJson: false,\n getVersion: () => undefined,\n detectPackageManager: detectNodePackageManagers,\n detect: async (options) => {\n const packageJson = await tryGetPackageJson(options);\n return !!packageJson;\n },\n },\n\n environment: {\n uploadToHosting: false,\n getEnvVars: (apiKey: string, host: string) => ({\n POSTHOG_PROJECT_TOKEN: apiKey,\n POSTHOG_HOST: host,\n }),\n },\n\n analytics: {\n getTags: () => ({}),\n },\n\n prompts: {\n projectTypeDetection:\n 'This is a server-side Node.js project. Look for package.json and lockfiles to confirm.',\n packageInstallation:\n 'Use npm, yarn, pnpm, or bun based on the existing lockfile (package-lock.json, yarn.lock, pnpm-lock.yaml, bun.lockb). Install posthog-node as a regular dependency.',\n getAdditionalContextLines: () => [\n `Framework docs ID: javascript_node (use posthog://docs/frameworks/javascript_node for documentation)`,\n ],\n },\n\n ui: {\n successMessage: 'PostHog integration complete',\n estimatedDurationMinutes: 5,\n getOutroChanges: () => [\n `Analyzed your Node.js project structure`,\n `Installed the posthog-node package`,\n `Created PostHog initialization with proper configuration`,\n `Configured graceful shutdown for event flushing`,\n `Added example code for events, feature flags, and error capture`,\n ],\n getOutroNextSteps: () => [\n 'Use the PostHog client instance for all tracking calls',\n 'Call posthog.shutdown() on application exit to flush pending events',\n 'NEVER send PII in event properties (no emails, names, or user content)',\n 'Use posthog.capture() for events and posthog.identify() for users',\n 'Visit your PostHog dashboard to see incoming events',\n ],\n },\n };\n","import * as fs from 'node:fs';\nimport * as path from 'node:path';\nimport { boundedGlob } from '@utils/bounded-fs';\nimport { detectAllPackageManagers } from '@utils/package-manager';\nimport type { WizardRunOptions } from '@utils/types';\n\nexport type JavaScriptContext = {\n packageManagerName?: string;\n hasTypeScript?: boolean;\n hasBundler?: string;\n};\n\nconst INDEX_HTML_MAX_DEPTH = 6;\n\n/**\n * Packages that indicate a specific framework integration exists.\n * If any of these are in package.json, we should NOT match as generic JavaScript.\n *\n * When adding a new JS framework integration to the wizard,\n * add its detection package here too.\n */\nexport const FRAMEWORK_PACKAGES = [\n 'next',\n 'nuxt',\n 'vue',\n 'react-router',\n '@tanstack/react-start',\n '@tanstack/react-router',\n 'react-native',\n '@angular/core',\n 'astro',\n '@sveltejs/kit',\n] as const;\n\n/**\n * Detect the JS package manager for the project by checking lockfiles.\n * Reuses the existing package manager detection infrastructure.\n */\nexport function detectJsPackageManager(\n options: Pick<WizardRunOptions, 'installDir'>,\n): string {\n const detected = detectAllPackageManagers(options);\n if (detected.length > 0) {\n return detected[0].label;\n }\n return 'unknown';\n}\n\n/**\n * Detect the bundler used in the project by checking package.json dependencies.\n */\nexport function detectBundler(\n options: Pick<WizardRunOptions, 'installDir'>,\n): string | undefined {\n try {\n const content = fs.readFileSync(\n path.join(options.installDir, 'package.json'),\n 'utf-8',\n );\n const pkg = JSON.parse(content);\n const allDeps: Record<string, string> = {\n ...pkg.dependencies,\n ...pkg.devDependencies,\n };\n\n if (allDeps['vite']) return 'vite';\n if (allDeps['webpack']) return 'webpack';\n if (allDeps['esbuild']) return 'esbuild';\n if (allDeps['parcel']) return 'parcel';\n if (allDeps['rollup']) return 'rollup';\n return undefined;\n } catch {\n return undefined;\n }\n}\n\n/**\n * Heuristic: check if there is an index.html anywhere in the project,\n * ignoring common build and dependency directories.\n */\nexport async function hasIndexHtml(\n options: Pick<WizardRunOptions, 'installDir'>,\n): Promise<boolean> {\n const matches = await boundedGlob('**/index.html', {\n cwd: options.installDir,\n deep: INDEX_HTML_MAX_DEPTH,\n limit: 1,\n });\n\n return matches.length > 0;\n}\n","/* Generic JavaScript Web (client-side) wizard using posthog-agent with PostHog MCP */\nimport type { WizardRunOptions } from '@utils/types';\nimport type { FrameworkConfig } from '@lib/framework-config';\nimport { Integration } from '@lib/constants';\nimport * as fs from 'node:fs';\nimport * as path from 'node:path';\nimport { hasDeclaredDependency } from '@utils/package-json';\nimport { tryGetPackageJson } from '@utils/setup-utils';\nimport {\n FRAMEWORK_PACKAGES,\n detectJsPackageManager,\n detectBundler,\n hasIndexHtml,\n type JavaScriptContext,\n} from './utils';\nimport { detectNodePackageManagers } from '@lib/detection/package-manager';\n\nexport const JAVASCRIPT_WEB_AGENT_CONFIG: FrameworkConfig<JavaScriptContext> = {\n metadata: {\n name: 'JavaScript (Web)',\n integration: Integration.javascript_web,\n docsUrl: 'https://posthog.com/docs/libraries/js',\n gatherContext: (options: WizardRunOptions) => {\n const packageManagerName = detectJsPackageManager(options);\n const hasTypeScript = fs.existsSync(\n path.join(options.installDir, 'tsconfig.json'),\n );\n const hasBundler = detectBundler(options);\n return Promise.resolve({ packageManagerName, hasTypeScript, hasBundler });\n },\n },\n\n detection: {\n packageName: 'posthog-js',\n packageDisplayName: 'JavaScript (Web)',\n usesPackageJson: false,\n getVersion: () => undefined,\n detectPackageManager: detectNodePackageManagers,\n detect: async (options) => {\n const packageJson = await tryGetPackageJson(options);\n if (!packageJson) {\n return false;\n }\n\n // Exclude projects with known framework packages\n for (const frameworkPkg of FRAMEWORK_PACKAGES) {\n if (hasDeclaredDependency(frameworkPkg, packageJson)) {\n return false;\n }\n }\n\n const { installDir } = options;\n\n // Has (index.html OR has a bundler) AND is a JavaScript project\n const hasIndexHtmlFlag = await hasIndexHtml(options);\n\n const bundler = detectBundler(options);\n const hasBundler = !!bundler;\n\n const hasLockfile = [\n 'package-lock.json',\n 'yarn.lock',\n 'pnpm-lock.yaml',\n 'bun.lockb',\n 'bun.lock',\n 'deno.lock',\n ].some((lockfile) => fs.existsSync(path.join(installDir, lockfile)));\n\n // We only treat this as JS Web if there's BOTH:\n // - a lockfile, and\n // - at least one frontend signal (index.html or bundler)\n if (hasLockfile && (hasIndexHtmlFlag || hasBundler)) {\n return true;\n }\n\n // Otherwise → Node/Backend (handled by javascriptNode fallback)\n return false;\n },\n },\n\n environment: {\n uploadToHosting: false,\n getEnvVars: (apiKey: string, host: string) => ({\n POSTHOG_PROJECT_TOKEN: apiKey,\n POSTHOG_HOST: host,\n }),\n },\n\n analytics: {\n getTags: (context) => {\n const tags: Record<string, string> = {\n packageManager: context.packageManagerName ?? 'unknown',\n };\n if (context.hasBundler) {\n tags.bundler = context.hasBundler;\n }\n return tags;\n },\n },\n\n prompts: {\n projectTypeDetection:\n 'This is a JavaScript/TypeScript project. Look for package.json and lockfiles (package-lock.json, yarn.lock, pnpm-lock.yaml, bun.lockb) to confirm.',\n packageInstallation:\n 'Look for lockfiles to determine the package manager (npm, yarn, pnpm, bun). Do not manually edit package.json.',\n getAdditionalContextLines: (context) => {\n const lines = [\n `Package manager: ${context.packageManagerName ?? 'unknown'}`,\n `Has TypeScript: ${context.hasTypeScript ? 'yes' : 'no'}`,\n `Framework docs ID: js (use posthog://docs/frameworks/js for documentation if available)`,\n `Project type: Generic JavaScript/TypeScript application (no specific framework detected)`,\n ];\n\n if (context.hasBundler) {\n lines.unshift(`Bundler: ${context.hasBundler}`);\n }\n\n return lines;\n },\n },\n\n ui: {\n successMessage: 'PostHog integration complete',\n estimatedDurationMinutes: 5,\n getOutroChanges: (context) => {\n const packageManagerName =\n context.packageManagerName ?? 'package manager';\n return [\n `Analyzed your JavaScript project structure`,\n `Installed the posthog-js package using ${packageManagerName}`,\n `Created PostHog initialization code`,\n `Configured autocapture, error tracking, and event capture`,\n ];\n },\n getOutroNextSteps: () => [\n 'Ensure posthog.init() is called before any capture calls',\n 'Autocapture tracks clicks, form submissions, and pageviews automatically',\n 'Use posthog.capture() for custom events and posthog.identify() for users',\n 'NEVER send PII in event properties (no emails, names, or user content)',\n 'Visit your PostHog dashboard to see incoming events',\n ],\n },\n};\n","import type { FrameworkConfig } from './framework-config';\nimport { Integration } from './constants';\nimport { NEXTJS_AGENT_CONFIG } from '@frameworks/nextjs/nextjs-wizard-agent';\nimport { NUXT_AGENT_CONFIG } from '@frameworks/nuxt/nuxt-wizard-agent';\nimport { VUE_AGENT_CONFIG } from '@frameworks/vue/vue-wizard-agent';\nimport { REACT_ROUTER_AGENT_CONFIG } from '@frameworks/react-router/react-router-wizard-agent';\nimport { TANSTACK_ROUTER_AGENT_CONFIG } from '@frameworks/tanstack-router/tanstack-router-wizard-agent';\nimport { TANSTACK_START_AGENT_CONFIG } from '@frameworks/tanstack-start/tanstack-start-wizard-agent';\nimport { REACT_NATIVE_AGENT_CONFIG } from '@frameworks/react-native/react-native-wizard-agent';\nimport { ANGULAR_AGENT_CONFIG } from '@frameworks/angular/angular-wizard-agent';\nimport { ASTRO_AGENT_CONFIG } from '@frameworks/astro/astro-wizard-agent';\nimport { DJANGO_AGENT_CONFIG } from '@frameworks/django/django-wizard-agent';\nimport { FLASK_AGENT_CONFIG } from '@frameworks/flask/flask-wizard-agent';\nimport { FASTAPI_AGENT_CONFIG } from '@frameworks/fastapi/fastapi-wizard-agent';\nimport { LARAVEL_AGENT_CONFIG } from '@frameworks/laravel/laravel-wizard-agent';\nimport { SVELTEKIT_AGENT_CONFIG } from '@frameworks/svelte/svelte-wizard-agent';\nimport { FLUTTER_AGENT_CONFIG } from '@frameworks/flutter/flutter-wizard-agent';\nimport { SWIFT_AGENT_CONFIG } from '@frameworks/swift/swift-wizard-agent';\nimport { KMP_AGENT_CONFIG } from '@frameworks/kmp/kmp-wizard-agent';\nimport { ANDROID_AGENT_CONFIG } from '@frameworks/android/android-wizard-agent';\nimport { RAILS_AGENT_CONFIG } from '@frameworks/rails/rails-wizard-agent';\nimport { ELIXIR_AGENT_CONFIG } from '@frameworks/elixir/elixir-wizard-agent';\nimport { GO_AGENT_CONFIG } from '@frameworks/go/go-wizard-agent';\nimport { JAVA_AGENT_CONFIG } from '@frameworks/java/java-wizard-agent';\nimport { RUST_AGENT_CONFIG } from '@frameworks/rust/rust-wizard-agent';\nimport { PYTHON_AGENT_CONFIG } from '@frameworks/python/python-wizard-agent';\nimport { RUBY_AGENT_CONFIG } from '@frameworks/ruby/ruby-wizard-agent';\nimport { JAVASCRIPT_NODE_AGENT_CONFIG } from '@frameworks/javascript-node/javascript-node-wizard-agent';\nimport { JAVASCRIPT_WEB_AGENT_CONFIG } from '@frameworks/javascript-web/javascript-web-wizard-agent';\n\nexport const FRAMEWORK_REGISTRY: Record<Integration, FrameworkConfig> = {\n [Integration.nextjs]: NEXTJS_AGENT_CONFIG,\n [Integration.nuxt]: NUXT_AGENT_CONFIG,\n [Integration.vue]: VUE_AGENT_CONFIG,\n [Integration.tanstackStart]: TANSTACK_START_AGENT_CONFIG,\n [Integration.reactRouter]: REACT_ROUTER_AGENT_CONFIG,\n [Integration.tanstackRouter]: TANSTACK_ROUTER_AGENT_CONFIG,\n [Integration.reactNative]: REACT_NATIVE_AGENT_CONFIG,\n [Integration.angular]: ANGULAR_AGENT_CONFIG,\n [Integration.astro]: ASTRO_AGENT_CONFIG,\n [Integration.django]: DJANGO_AGENT_CONFIG,\n [Integration.flask]: FLASK_AGENT_CONFIG,\n [Integration.fastapi]: FASTAPI_AGENT_CONFIG,\n [Integration.laravel]: LARAVEL_AGENT_CONFIG,\n [Integration.sveltekit]: SVELTEKIT_AGENT_CONFIG,\n [Integration.flutter]: FLUTTER_AGENT_CONFIG,\n [Integration.kmp]: KMP_AGENT_CONFIG,\n [Integration.swift]: SWIFT_AGENT_CONFIG,\n [Integration.android]: ANDROID_AGENT_CONFIG,\n [Integration.rails]: RAILS_AGENT_CONFIG,\n [Integration.elixir]: ELIXIR_AGENT_CONFIG,\n [Integration.go]: GO_AGENT_CONFIG,\n [Integration.rust]: RUST_AGENT_CONFIG,\n [Integration.java]: JAVA_AGENT_CONFIG,\n [Integration.python]: PYTHON_AGENT_CONFIG,\n [Integration.ruby]: RUBY_AGENT_CONFIG,\n [Integration.javascriptNode]: JAVASCRIPT_NODE_AGENT_CONFIG,\n [Integration.javascript_web]: JAVASCRIPT_WEB_AGENT_CONFIG,\n};\n"],"mappings":";;;;;;;;;;;;;;AAIA,MAAa,yBAAyB,qBAAqB;AAO3D,MAAaA,oBAAkB,CAAC,eAAe;;;;AAK/C,eAAsB,gBAAgB,EACpC,cACqE;CAOrE,MAAM,eANe,MAAM,YAAY,kCAAkC;EACvE,KAAK;EACL,aAAaA;EACb,OAAO;EACR,CAAC,EAE+B,SAAS;CAQ1C,MAAM,aANa,MAAM,YAAY,qCAAqC;EACxE,KAAK;EACL,aAAaA;EACb,OAAO;EACR,CAAC,EAE2B,SAAS;AAEtC,KAAI,eAAe,CAAC,UAClB,QAAA;AAGF,KAAI,aAAa,CAAC,YAChB,QAAA;AAIF,QAAO;;AAGT,MAAa,uBAAuB,WAAyB;AAC3D,QAAO,WAAA,eAAqC,eAAe;;;;ACxB7D,MAAa,sBAAsD;CACjE,UAAU;EACR,MAAM;EACN,aAAA;EACA,SAAS;EACT,2BAA2B;EAC3B,eAAe,OAAO,YAA8B;GAClD,MAAM,SAAS,MAAM,gBAAgB,QAAQ;AAC7C,OAAI,QAAQ;IACV,MAAM,QACJ,WAAA,eAAqC,OAAc;AACrD,WAAO,CAAC,qBACN,WAAW,oBAAoB,OAAO,CAAC,GAAG,QAC3C;AACD,WAAO,EAAE,QAAQ;;AAEnB,UAAO,EAAE;;EAEX,OAAO,EACL,WAAW,CACT;GACE,KAAK;GACL,SAAS;GACT,SAAS,CACP;IAAE,OAAO;IAAc,OAAA;IAAgC,EACvD;IAAE,OAAO;IAAgB,OAAA;IAAkC,CAC5D;GACD,QAAQ,OAAO,SAAS;AAEtB,WADe,MAAM,gBAAgB,KAAK;;GAG7C,CACF,EACF;EACF;CAED,WAAW;EACT,aAAa;EACb,oBAAoB;EACpB,aAAa,gBACX,mBAAmB,QAAQ,YAA2B;EACxD,kBAAkB;EAClB,gBAAgB;EAChB,sBAAsB,YACpB,QAAQ,QAAQ,2BAA2B,QAAQ,QAAQ,WAAW,CAAC;EACzE,QAAQ,OAAO,YAAY;GACzB,MAAM,cAAc,MAAM,kBAAkB,QAAQ;AACpD,UAAO,cAAc,sBAAsB,QAAQ,YAAY,GAAG;;EAEpE,sBAAsB;EACvB;CAED,aAAa;EACX,iBAAiB;EACjB,aAAa,QAAgB,UAAkB;GAC7C,mCAAmC;GACnC,0BAA0B;GAC3B;EACF;CAED,WAAW,EACT,UAAU,aAAa,EACrB,QAAQ,QAAQ,WAAA,eAAqC,QAAQ,SAC9D,GACF;CAED,SAAS;EACP,sBACE;EACF,4BAA4B,YAAY;AAGtC,UAAO,CAAC,WADN,QAAQ,WAAA,eAAqC,QAAQ,UACvB;;EAEnC;CAED,IAAI;EACF,gBAAgB;EAChB,0BAA0B;EAC1B,kBAAkB,YAAY;AAG5B,UAAO;IACL,4CAFiB,oBADJ,QAAQ,UAAA,aACuB,CAEW;IACvD;IACA;IACD;;EAEH,yBAAyB;AACvB,UAAO,CACL,0DACA,sDACD;;EAEJ;CACF;;;ACzGD,MAAM,uBAAuB,qBAAqB;AAMlD,MAAa,oBAAkD;CAC7D,UAAU;EACR,MAAM;EACN,aAAA;EACA,SAAS;EACT,eAAe,OAAO,YAA8B;GAClD,MAAM,cAAc,MAAM,kBAAkB,QAAQ;AACpD,OAAI,CAAC,YAAa,QAAO,EAAE;AAG3B,UAAO,EAAE,eADa,qBADN,mBAAmB,QAAQ,YAAY,CACJ,EAC3B;;EAE3B;CAED,WAAW;EACT,aAAa;EACb,oBAAoB;EACpB,aAAa,gBACX,mBAAmB,QAAQ,YAA2B;EACxD,kBAAkB;EAClB,sBAAsB,YACpB,QAAQ,QAAQ,2BAA2B,QAAQ,QAAQ,WAAW,CAAC;EACzE,QAAQ,OAAO,YAAY;GACzB,MAAM,cAAc,MAAM,kBAAkB,QAAQ;AACpD,UAAO,cAAc,sBAAsB,QAAQ,YAAY,GAAG;;EAEpE,sBAAsB;EACvB;CAED,aAAa;EACX,iBAAiB;EACjB,aAAa,QAAgB,UAAkB;GAC7C,mCAAmC;GACnC,0BAA0B;GAC3B;EACF;CAED,WAAW,EACT,UAAU,aAAa,EACrB,GAAI,QAAQ,gBACR,EAAE,eAAe,QAAQ,eAAe,GACxC,EAAE,EACP,GACF;CAED,SAAS;EACP,sBACE;EACF,4BAA4B,YAAY;GACtC,MAAM,QAAkB,EAAE;AAC1B,OAAI,QAAQ,cACV,OAAM,KAAK,iBAAiB,QAAQ,gBAAgB;GAEtD,MAAM,cAAc;AACpB,SAAM,KACJ,sBAAsB,YAAY,kCAAkC,YAAY,qBACjF;AACD,UAAO;;EAEV;CAED,IAAI;EACF,gBAAgB;EAChB,0BAA0B;EAC1B,uBAAuB;GACrB;GACA;GACA;GACD;EACD,yBAAyB,CACvB,0DACA,sDACD;EACF;CACF;AC7ED,MAAa,mBAAgD;CAC3D,UAAU;EACR,MAAM;EACN,aAAA;EACA,SAAS;EACV;CAED,WAAW;EACT,aAAa;EACb,oBAAoB;EACpB,aAAa,gBACX,mBAAmB,OAAO,YAA2B;EACvD,kBAhBwB,qBAAqB;EAiB7C,sBAAsB,YACpB,QAAQ,QAAQ,2BAA2B,OAAO,QAAQ,WAAW,CAAC;EACxE,QAAQ,OAAO,YAAY;GACzB,MAAM,cAAc,MAAM,kBAAkB,QAAQ;AACpD,UAAO,cAAc,sBAAsB,OAAO,YAAY,GAAG;;EAEnE,sBAAsB;EACvB;CAED,aAAa;EACX,iBAAiB;EACjB,aAAa,QAAgB,UAAkB;GAC7C,4BAA4B;GAC5B,mBAAmB;GACpB;EACF;CAED,WAAW,EACT,gBAAgB,EAAE,GACnB;CAED,SAAS;EACP,sBACE;EACF,iCAAiC;GAC/B,MAAM,cAAc;AACpB,UAAO,CACL,sBAAsB,YAAY,kCAAkC,YAAY,qBACjF;;EAEJ;CAED,IAAI;EACF,gBAAgB;EAChB,0BAA0B;EAC1B,uBAAuB;GACrB;GACA;GACA;GACD;EACD,yBAAyB,CACvB,0DACA,sDACD;EACF;CACF;;;AC3DD,MAAMC,kBAAe,CAAC,eAAe;AAErC,MAAa,8BAA8B,qBAAqB;;AAGhE,MAAMC,uBAAqB;;AAG3B,MAAM,oBAAoB;CACxB;CACA;CACA;CACD;AAED,eAAe,qBAAqB,EAClC,cACyD;AASzD,SARsB,MAAM,YAC1B,2CACA;EACE,KAAK;EACL,aAAaD;EACb,OAAO;EACR,CACF,EACoB,SAAS;;AAGhC,eAAe,uBAAuB,EACpC,cACyD;CACzD,MAAM,cAAc,MAAM,YAAY,mBAAmB;EACvD,KAAK;EACL,aAAaA;EACb,OAAOC;EACR,CAAC;AAEF,MAAK,MAAM,QAAQ,YAEjB,KADgB,gBAAgBC,OAAK,KAAK,YAAY,KAAK,CAAC,EAC/C,SAAS,sBAAsB,CAC1C,QAAO;AAIX,QAAO;;AAGT,eAAe,qBAAqB,EAClC,cACyD;CACzD,MAAM,cAAc,MAAM,YAAY,mBAAmB;EACvD,KAAK;EACL,aAAaF;EACb,OAAOC;EACR,CAAC;AAEF,MAAK,MAAM,QAAQ,aAAa;EAC9B,MAAM,UAAU,gBAAgBC,OAAK,KAAK,YAAY,KAAK,CAAC;AAC5D,MAAI,CAAC,QAAS;AACd,MACE,QAAQ,SAAS,iBAAiB,IACjC,QAAQ,SAAS,gBAAgB,KAC/B,QAAQ,SAAS,4BAA0B,IAC1C,QAAQ,SAAS,0BAA0B,EAE/C,QAAO;;AAIX,QAAO;;;;;AAMT,eAAsB,mBACpB,SACiC;CACjC,MAAM,EAAE,eAAe;CAEvB,MAAM,cAAc,MAAM,kBAAkB,QAAQ;AACpD,KAAI,CAAC,YAAa,QAAO;CAEzB,MAAM,qBACJ,mBAAmB,oBAAoB,YAAY,IACnD,mBAAmB,gBAAgB,YAAY;AAEjD,KAAI,CAAC,mBACH,QAAO;CAGT,MAAM,iBAAiB,OAAO,OAAO,mBAAmB;CACxD,MAAM,eAAe,iBAAiB,MAAM,eAAe,GAAG;AAE9D,KAAI,iBAAiB,EACnB,QAAA;AAGF,KAAI,iBAAiB,GAAG;AAEtB,MADkB,MAAM,qBAAqB,EAAE,YAAY,CAAC,CAC7C,QAAA;AAGf,MADoB,MAAM,uBAAuB,EAAE,YAAY,CAAC,CAC/C,QAAA;AAGjB,MADuB,MAAM,qBAAqB,EAAE,YAAY,CAAC,CAC7C,QAAA;AAGpB,SAAO;;AAGT,QAAO;;AAGT,SAAgB,uBAAuB,MAA+B;AACpE,SAAQ,MAAR;EACE,KAAA,KACE,QAAO;EACT,KAAA,eACE,QAAO;EACT,KAAA,UACE,QAAO;EACT,KAAA,iBACE,QAAO;;;;;ACpHb,MAAa,4BAAiE;CAC5E,UAAU;EACR,MAAM;EACN,aAAA;EACA,SAAS;EACT,2BAA2B;EAC3B,eAAe,OAAO,YAA8B;GAClD,MAAM,aAAa,MAAM,mBAAmB,QAAQ;AACpD,OAAI,YAAY;AACd,WAAO,CAAC,qBACN,gBAAgB,uBAAuB,WAAW,GACnD;AACD,WAAO,EAAE,YAAY;;AAEvB,UAAO,EAAE;;EAEZ;CAED,WAAW;EACT,aAAa;EACb,oBAAoB;EACpB,aAAa,gBACX,mBAAmB,gBAAgB,YAA2B;EAChE,kBAAkB;EAClB,gBAAgB;EAChB,sBAAsB,YACpB,QAAQ,QACN,2BAA2B,gBAAgB,QAAQ,WAAW,CAC/D;EACH,QAAQ,OAAO,YAAY;GACzB,MAAM,cAAc,MAAM,kBAAkB,QAAQ;AACpD,UAAO,cACH,sBAAsB,gBAAgB,YAAY,GAClD;;EAEN,sBAAsB;EACvB;CAED,aAAa;EACX,iBAAiB;EACjB,aAAa,QAAgB,UAAkB;GAC7C,iCAAiC;GACjC,wBAAwB;GACzB;EACF;CAED,WAAW,EACT,UAAU,aAAa,EACrB,YAAY,QAAQ,cAAc,WACnC,GACF;CAED,SAAS;EACP,sBACE;EACF,4BAA4B,YAAY;GACtC,MAAM,aAAa,QAAQ;GAC3B,MAAM,WAAW,aACb,uBAAuB,WAAW,GAClC;GAUJ,MAAM,cAAc,aAPoC;YAChC;sBACU;iBACL;wBACO;IACnC,CAGkB,cAAA;AAGnB,UAAO,CACL,gBAAgB,YAChB,sBAAsB,YAAY,kCAAkC,YAAY,qBACjF;;EAEJ;CAED,IAAI;EACF,gBAAgB;EAChB,0BAA0B;EAC1B,kBAAkB,YAAY;AAI5B,UAAO;IACL,iDAJe,QAAQ,aACrB,uBAAuB,QAAQ,WAAW,GAC1C,eAEwD;IAC1D;IACA;IACD;;EAEH,yBAAyB,CACvB,0DACA,sDACD;EACF;CACF;;;AC9GD,MAAMC,kBAAe;CAAC;CAAgB;CAAgB;CAAgB;AAEtE,MAAa,iCAAiC,qBAAqB;;AAGnE,MAAMC,uBAAqB;;AAG3B,MAAM,mBAAmB;CACvB;CACA;CACA;CACD;AAED,eAAe,oBAAoB,EACjC,cACyD;AAUzD,MATuB,MAAM,YAC3B,qCACA;EACE,KAAK;EACL,aAAaD;EACb,OAAO;EACR,CACF,EAEkB,SAAS,EAC1B,QAAO;AAGT,KAAI;EACF,MAAM,kBAAkBE,OAAK,KAAK,YAAY,eAAe;EAC7D,MAAM,UAAUC,KAAG,aAAa,iBAAiB,QAAQ;EACzD,MAAM,cAAc,KAAK,MAAM,QAAQ;AAEvC,MACE,sBAAsB,2BAA2B,YAAY,IAC7D,sBAAsB,gCAAgC,YAAY,CAElE,QAAO;SAEH;CAIR,MAAM,cAAc,MAAM,YAAY,kBAAkB;EACtD,KAAK;EACL,aAAaH;EACb,OAAOC;EACR,CAAC;AAEF,MAAK,MAAM,QAAQ,YAEjB,KADgB,gBAAgBC,OAAK,KAAK,YAAY,KAAK,CAAC,EAC/C,SAAS,kBAAkB,CACtC,QAAO;AAIX,QAAO;;AAGT,eAAe,oBAAoB,EACjC,cACyD;CACzD,MAAM,cAAc,MAAM,YAAY,kBAAkB;EACtD,KAAK;EACL,aAAaF;EACb,OAAOC;EACR,CAAC;CAEF,IAAI,iBAAiB;CACrB,IAAI,qBAAqB;AAEzB,MAAK,MAAM,QAAQ,aAAa;EAC9B,MAAM,UAAU,gBAAgBC,OAAK,KAAK,YAAY,KAAK,CAAC;AAC5D,MAAI,CAAC,QAAS;AAEd,MAAI,QAAQ,SAAS,eAAe,CAClC,kBAAiB;AAEnB,MAAI,QAAQ,SAAS,kBAAkB,CACrC,sBAAqB;;AAIzB,QAAO,kBAAkB,CAAC;;;;;AAM5B,eAAsB,sBACpB,SACoC;CACpC,MAAM,EAAE,eAAe;AAGvB,KADoB,MAAM,oBAAoB,EAAE,YAAY,CAAC,CAE3D,QAAA;AAIF,KADoB,MAAM,oBAAoB,EAAE,YAAY,CAAC,CAE3D,QAAA;AAGF,QAAO;;AAGT,SAAgB,0BAA0B,MAAkC;AAC1E,SAAQ,MAAR;EACE,KAAA,aACE,QAAO;EACT,KAAA,aACE,QAAO;;;;;ACtGb,MAAa,+BACX;CACE,UAAU;EACR,MAAM;EACN,aAAA;EACA,SAAS;EACT,eAAe,OAAO,YAA8B;GAClD,MAAM,aAAa,MAAM,sBAAsB,QAAQ;AACvD,OAAI,YAAY;AACd,WAAO,CAAC,qBACN,mBAAmB,0BAA0B,WAAW,GACzD;AACD,WAAO,EAAE,YAAY;;AAEvB,UAAO,EAAE;;EAEZ;CAED,WAAW;EACT,aAAa;EACb,oBAAoB;EACpB,aAAa,gBACX,mBACE,0BACA,YACD;EACH,kBAAkB;EAClB,gBAAgB;EAChB,sBAAsB,YACpB,QAAQ,QACN,2BACE,0BACA,QAAQ,WACT,CACF;EACH,QAAQ,OAAO,YAAY;GACzB,MAAM,cAAc,MAAM,kBAAkB,QAAQ;AACpD,OAAI,CAAC,YACH,QAAO;AAGT,OAAI,sBAAsB,yBAAyB,YAAY,CAC7D,QAAO;AAET,UAAO,sBAAsB,0BAA0B,YAAY;;EAErE,sBAAsB;EACvB;CAED,aAAa;EACX,iBAAiB;EACjB,aAAa,QAAgB,UAAkB;GAC7C,mCAAmC;GACnC,0BAA0B;GAC3B;EACF;CAED,WAAW,EACT,UAAU,aAAa,EACrB,YAAY,QAAQ,cAAc,WACnC,GACF;CAED,SAAS;EACP,sBACE;EACF,4BAA4B,YAAY;GACtC,MAAM,aAAa,QAAQ;GAC3B,MAAM,WAAW,aACb,0BAA0B,WAAW,GACrC;GAQJ,MAAM,cAAc,aALuC;oBACxB;oBACA;IAClC,CAGkB,cACf;AAEJ,UAAO,CACL,gBAAgB,YAChB,sBAAsB,YAAY,kCAAkC,YAAY,qBACjF;;EAEJ;CAED,IAAI;EACF,gBAAgB;EAChB,0BAA0B;EAC1B,kBAAkB,YAAY;AAI5B,UAAO;IACL,4DAJe,QAAQ,aACrB,0BAA0B,QAAQ,WAAW,GAC7C,kBAEmE;IACrE;IACA;IACD;;EAEH,yBAAyB,CACvB,0DACA,sDACD;EACF;CACF;;;AEnHH,MAAa,8BACX;CACE,UAAU;EACR,MAAM;EACN,aAAA;EACA,SAAS;EACV;CAED,WAAW;EACT,aAAa;EACb,oBAAoB;EACpB,aAAa,gBACX,mBAAmB,yBAAyB,YAA2B;EACzE,kBDxBuC,qBAAqB;ECyB5D,gBAAgB;EAChB,sBAAsB,YACpB,QAAQ,QACN,2BACE,yBACA,QAAQ,WACT,CACF;EACH,QAAQ,OAAO,YAAY;GACzB,MAAM,cAAc,MAAM,kBAAkB,QAAQ;AACpD,UAAO,cACH,sBAAsB,yBAAyB,YAAY,GAC3D;;EAEN,sBAAsB;EACvB;CAED,aAAa;EACX,iBAAiB;EACjB,aAAa,QAAgB,UAAkB;GAC7C,mCAAmC;GACnC,0BAA0B;GAC3B;EACF;CAED,WAAW,EACT,gBAAgB,EAAE,GACnB;CAED,SAAS;EACP,sBACE;EACF,iCAAiC;GAE/B,MAAM,cAAc;AAEpB,UAAO,CACL,sBAAsB,YAAY,kCAAkC,YAAY,qBACjF;;EAEJ;CAED,IAAI;EACF,gBAAgB;EAChB,0BAA0B;EAC1B,uBAAuB;GACrB;GACA;GACA;GACD;EACD,yBAAyB,CACvB,0DACA,sDACD;EACF;CACF;;;AC/EH,MAAa,8BAA8B,qBAAqB;AAOhE,SAAgB,0BAA0B,SAAqC;AAC7E,QAAO,YAAA,SAAsC,SAAS;;AAGxD,eAAsB,yBACpB,SAC6B;CAC7B,MAAM,cAAc,MAAM,kBAAkB,QAAQ;AAEpD,KAAI,eAAe,sBAAsB,QAAQ,YAAY,EAAE;AAC7D,SAAO,CAAC,qBACN,GAAG,0BAAA,OAAkD,CAAC,KACvD;AACD,SAAA;;AAGF,QAAO,CAAC,qBACN,GAAG,0BAAA,eAA0D,CAAC,KAC/D;AACD,QAAA;;;;ACTF,MAAa,4BAAiE;CAC5E,UAAU;EACR,MAAM;EACN,aAAA;EACA,SAAS;EACT,eAAe,OAAO,YAA8B;AAElD,UAAO,EAAE,SADO,MAAM,yBAAyB,QAAQ,EACrC;;EAErB;CAED,WAAW;EACT,aAAa;EACb,oBAAoB;EACpB,aAAa,gBACX,mBAAmB,gBAAgB,YAA2B;EAChE,kBAAkB;EAClB,gBAAgB;EAChB,sBAAsB,YACpB,QAAQ,QACN,2BAA2B,gBAAgB,QAAQ,WAAW,CAC/D;EACH,QAAQ,OAAO,YAAY;GACzB,MAAM,cAAc,MAAM,kBAAkB,QAAQ;AACpD,UAAO,cACH,sBAAsB,gBAAgB,YAAY,GAClD;;EAEN,sBAAsB;EACvB;CAED,aAAa;EACX,iBAAiB;EACjB,aAAa,QAAgB,UAAkB;GAC7C,uBAAuB;GACvB,cAAc;GACf;EACF;CAED,WAAW,EACT,UAAU,aAAa,EACrB,SACE,QAAQ,YAAA,SAAsC,SAAS,gBAC1D,GACF;CAED,SAAS;EACP,sBACE;EACF,4BAA4B,YAAY;GACtC,MAAM,SAAS,QAAQ,YAAA;GACvB,MAAM,cAAc;GAEpB,MAAM,QAAQ,CACZ,sBAAsB,YAAY,kCAAkC,YAAY,sBAChF,YAAY,SAAS,SAAS,iBAC/B;AAED,OAAI,OACF,OAAM,KACJ,oDACA,2EACD;OAED,OAAM,KACJ,gFACA,2DACD;AAGH,UAAO;;EAEV;CAED,IAAI;EACF,gBAAgB;EAChB,0BAA0B;EAC1B,kBAAkB,YAAY;AAG5B,UAAO;IACL,iDAFkB,0BADJ,QAAQ,WAAA,eAC8B,CAES;IAC7D;IACA;IACD;;EAEH,oBAAoB,YAAY;GAC9B,MAAM,SAAS,QAAQ,YAAA;GACvB,MAAM,QAAQ,EAAE;AAEhB,OAAI,CAAC,OACH,OAAM,KAAK,oDAAoD;AAGjE,SAAM,KACJ,SACI,iFACA,0DACJ,sDACD;AAED,UAAO;;EAEV;CACF;;;AE/GD,MAAa,uBAAwD;CACnE,UAAU;EACR,MAAM;EACN,aAAA;EACA,SAAS;EACV;CAED,WAAW;EACT,aAAa;EACb,oBAAoB;EACpB,aAAa,gBACX,mBAAmB,iBAAiB,YAA2B;EACjE,kBDvBmC,qBAAqB;ECwBxD,gBAAgB;EAChB,sBAAsB,YACpB,QAAQ,QACN,2BAA2B,iBAAiB,QAAQ,WAAW,CAChE;EACH,QAAQ,OAAO,YAAY;GACzB,MAAM,cAAc,MAAM,kBAAkB,QAAQ;AACpD,UAAO,cACH,sBAAsB,iBAAiB,YAAY,GACnD;;EAEN,sBAAsB;EACvB;CAED,aAAa;EACX,iBAAiB;EACjB,aAAa,QAAgB,UAAkB;GAC7C,8BAA8B;GAC9B,qBAAqB;GACtB;EACF;CAED,WAAW,EACT,gBAAgB,EAAE,GACnB;CAED,SAAS;EACP,sBACE;EACF,iCAAiC;GAC/B,MAAM,cAAc;AAEpB,UAAO;IACL,sBAAsB,YAAY,kCAAkC,YAAY;IAChF;IACA;IACD;;EAEJ;CAED,IAAI;EACF,gBAAgB;EAChB,0BAA0B;EAC1B,uBAAuB;GACrB;GACA;GACA;GACD;EACD,yBAAyB,CACvB,0EACA,sDACD;EACF;CACF;;;AC5ED,MAAa,wBAAwB,qBAAqB;AAS1D,MAAME,iBAAe,CAAC,eAAe;;;;AAKrC,eAAsB,sBAAsB,EAC1C,cACoE;CACpE,MAAM,gBAAgB,MAAM,YAAY,6BAA6B;EACnE,KAAK;EACL,aAAaA;EACb,OAAO;EACR,CAAC;CAEF,IAAI,aAAa;CACjB,IAAI,aAA4B;CAChC,IAAI,sBAAsB;AAE1B,KAAI;EACF,MAAM,kBAAkB,KAAK,KAAK,YAAY,eAAe;EAC7D,MAAM,qBAAqB,MAAM,GAAG,SAAS,iBAAiB,QAAQ;EACtE,MAAM,cAAc,KAAK,MAAM,mBAAmB;EAClD,MAAM,UAAU;GACd,GAAG,YAAY;GACf,GAAG,YAAY;GAChB;AAED,eAAa,OAAO,KAAK,QAAQ,CAAC,MAC/B,QACC,IAAI,WAAW,YAAY,KAC1B,IAAI,SAAS,OAAO,IACnB,IAAI,SAAS,SAAS,IACtB,IAAI,SAAS,UAAU,IACvB,IAAI,SAAS,aAAa,IAC1B,IAAI,SAAS,OAAO,EACzB;SACK;AAIR,KAAI,cAAc,SAAS,EACzB,KAAI;EACF,MAAM,aAAa,KAAK,KAAK,YAAY,cAAc,GAAG;EAE1D,MAAM,eADgB,MAAM,GAAG,SAAS,YAAY,QAAQ,EAC1B,MAAM,0BAA0B;AAClE,MAAI,YACF,cAAa,YAAY;SAErB;CAKV,MAAM,wBAAwB,MAAM,YAClC,+BACA;EACE,KAAK;EACL,aAAaA;EACb,OAAO;EACR,CACF;AAED,MAAK,MAAM,QAAQ,uBAAuB;EACxC,MAAM,UAAU,gBAAgB,KAAK,KAAK,YAAY,KAAK,CAAC;AAC5D,MAAI,CAAC,QAAS;AACd,MACE,QAAQ,SAAS,eAAe,IAChC,QAAQ,SAAS,kBAAkB,IACnC,QAAQ,SAAS,oBAAoB,EACrC;AACA,yBAAsB;AACtB;;;AAIJ,KAAI,oBACF,QAAA;AAGF,KAAI,eAAe,YAAY,WAC7B,QAAA;AAGF,KAAI,WACF,QAAA;AAGF,QAAA;;AAGF,MAAa,6BAA6B,SAAqC;AAC7E,SAAQ,MAAR;EACE,KAAA,SACE,QAAO;EACT,KAAA,mBACE,QAAO;EACT,KAAA,MACE,QAAO;EACT,KAAA,SACE,QAAO;EACT,QACE,QAAO;;;;;AC5Fb,MAAa,qBAAoD;CAC/D,UAAU;EACR,MAAM;EACN,aAAA;EACA,SAAS;EACT,eAAe,OAAO,YAA8B;GAClD,MAAM,gBAAgB,MAAM,sBAAsB,QAAQ;AAC1D,UAAO,CAAC,qBACN,SAAS,0BAA0B,cAAc,GAClD;AACD,UAAO,EAAE,eAAe;;EAE3B;CAED,WAAW;EACT,aAAa;EACb,oBAAoB;EACpB,aAAa,gBACX,mBAAmB,SAAS,YAA2B;EACzD,kBAAkB;EAClB,gBAAgB;EAChB,sBAAsB,YACpB,QAAQ,QAAQ,2BAA2B,SAAS,QAAQ,WAAW,CAAC;EAC1E,QAAQ,OAAO,YAAY;GACzB,MAAM,cAAc,MAAM,kBAAkB,QAAQ;AACpD,UAAO,cAAc,sBAAsB,SAAS,YAAY,GAAG;;EAErE,sBAAsB;EACvB;CAED,aAAa;EACX,iBAAiB;EACjB,aAAa,QAAgB,UAAkB;GAC7C,8BAA8B;GAC9B,qBAAqB;GACtB;EACF;CAED,WAAW,EACT,UAAU,aAAa,EACrB,kBAAkB,QAAQ,iBAAiB,UAC5C,GACF;CAED,SAAS;EACP,sBACE;EACF,4BAA4B,YAAY;GACtC,MAAM,WAAW,0BACf,QAAQ,iBAAA,SACT;GAUD,MAAM,cAPqD;gBAC5B;0BACU;aACb;gBACG;IAC9B,CAGgB,QAAQ,iBAAA;GAEzB,MAAM,QAAQ,CACZ,mBAAmB,YACnB,sBAAsB,YAAY,kCAAkC,YAAY,qBACjF;AAGD,OAAI,QAAQ,kBAAA,oBAAuD;AACjE,UAAM,KACJ,wGACD;AACD,UAAM,KACJ,oFACD;;AAGH,OACE,QAAQ,kBAAA,SACR,QAAQ,kBAAA,UACR;AACA,UAAM,KACJ,qEACD;AACD,UAAM,KACJ,oEACD;;AAGH,UAAO;;EAEV;CAED,IAAI;EACF,gBAAgB;EAChB,0BAA0B;EAC1B,kBAAkB,YAAY;GAI5B,MAAM,UAAU;IACd,0CAJe,0BACf,QAAQ,iBAAA,SACT,CAEoD;IACnD;IACA;IACD;AAED,OACE,QAAQ,kBAAA,SACR,QAAQ,kBAAA,SAER,SAAQ,KAAK,+CAA+C;AAG9D,OAAI,QAAQ,kBAAA,mBACV,SAAQ,KACN,gEACD;AAGH,UAAO;;EAET,yBAAyB;AACvB,UAAO,CACL,0DACA,sDACD;;EAEJ;CACF;;;;;;;;ACID,MAAa,+BACX;AAEF,MAAa,8BACX;;;;AA4DF,MAAa,kBACX;;;AChNF,MAAMC,iBAAe;CAAC;CAAa;CAAc;CAAmB;;;;AAKpE,MAAa,yBAAyB,qBAAqB;;;;AAK3D,eAAsB,iBACpB,SAC6B;CAC7B,MAAM,EAAE,eAAe;CAGvB,MAAM,oBAAoB,MAAM,YAC9B;EAAC;EAAwB;EAAqB;EAAe;EAAa,EAC1E;EACE,KAAK;EACL,aAAaA;EACd,CACF;AAED,MAAK,MAAM,WAAW,mBAAmB;EACvC,MAAM,UAAU,gBAAgBC,OAAK,KAAK,YAAY,QAAQ,CAAC;AAC/D,MAAI,CAAC,QAAS;EAGd,MAAM,oBAAoB,QAAQ,MAChC,iDACD;AACD,MAAI,kBACF,QAAO,kBAAkB;EAI3B,MAAM,iBAAiB,QAAQ,MAC7B,+DACD;AACD,MAAI,eACF,QAAO,eAAe;;;;;;AAU5B,eAAe,OAAO,EACpB,cACyD;CACzD,MAAM,oBAAoB,MAAM,YAC9B;EAAC;EAAwB;EAAqB;EAAa,EAC3D;EACE,KAAK;EACL,aAAaD;EACd,CACF;AAED,MAAK,MAAM,WAAW,kBAEpB,KADgB,gBAAgBC,OAAK,KAAK,YAAY,QAAQ,CAAC,EAClD,SAAS,sBAAsB,CAC1C,QAAO;CAKX,MAAM,gBAAgB,MAAM,YAAY,kBAAkB;EACxD,KAAK;EACL,aAAaD;EACd,CAAC;AAEF,MAAK,MAAM,gBAAgB,cAEzB,KADgB,gBAAgBC,OAAK,KAAK,YAAY,aAAa,CAAC,EACvD,SAAS,iBAAiB,CACrC,QAAO;AAIX,QAAO;;;;;AAMT,eAAe,WAAW,EACxB,cACyD;CACzD,MAAM,oBAAoB,MAAM,YAC9B;EAAC;EAAwB;EAAqB;EAAa,EAC3D;EACE,KAAK;EACL,aAAaD;EACd,CACF;AAED,MAAK,MAAM,WAAW,kBAEpB,KADgB,gBAAgBC,OAAK,KAAK,YAAY,QAAQ,CAAC,EAClD,SAAS,UAAU,CAC9B,QAAO;AAIX,QAAO;;;;;AAMT,eAAe,YAAY,EACzB,cACyD;CACzD,MAAM,oBAAoB,MAAM,YAC9B;EAAC;EAAwB;EAAqB;EAAa,EAC3D;EACE,KAAK;EACL,aAAaD;EACd,CACF;AAED,MAAK,MAAM,WAAW,kBAEpB,KADgB,gBAAgBC,OAAK,KAAK,YAAY,QAAQ,CAAC,EAClD,SAAS,WAAW,CAC/B,QAAO;AAIX,QAAO;;;;;AAMT,eAAsB,qBACpB,SAC4B;CAC5B,MAAM,EAAE,eAAe;AAGvB,KAAI,MAAM,WAAW,EAAE,YAAY,CAAC,EAAE;AACpC,SAAO,CAAC,qBAAqB,0BAA0B;AACvD,SAAA;;AAIF,KAAI,MAAM,OAAO,EAAE,YAAY,CAAC,EAAE;AAChC,SAAO,CAAC,qBAAqB,wBAAwB;AACrD,SAAA;;AAIF,KAAI,MAAM,YAAY,EAAE,YAAY,CAAC,EAAE;AACrC,SAAO,CAAC,qBAAqB,kBAAkB;AAC/C,SAAA;;AAIF,QAAO,CAAC,qBAAqB,SAAS;AACtC,QAAA;;;;;AAMF,SAAgB,yBACd,aACQ;AACR,SAAQ,aAAR;EACE,KAAA,WACE,QAAO;EACT,KAAA,MACE,QAAO;EACT,KAAA,UACE,QAAO;EACT,KAAA,WACE,QAAO;;;;;;AAOb,eAAsB,uBACpB,SAC6B;CAC7B,MAAM,EAAE,eAAe;CAGvB,MAAM,gBAAgB,MAAM,YAAY,kBAAkB;EACxD,KAAK;EACL,aAAaD;EACd,CAAC;AAEF,KAAI,cAAc,WAAW,GAAG;EAE9B,MAAM,qBAAqB,MAAM,YAAY,2BAA2B;GACtE,KAAK;GACL,aAAaA;GACb,OAAO;GACR,CAAC;AAEF,MAAI,mBAAmB,SAAS,EAC9B,QAAO,mBAAmB;AAG5B;;AAIF,KAAI,cAAc,WAAW,EAC3B,QAAO,cAAc;AAIvB,MAAK,MAAM,gBAAgB,cAEzB,KADgB,gBAAgBC,OAAK,KAAK,YAAY,aAAa,CAAC,EACvD,SAAS,eAAe,CACnC,QAAO;AAKX,QAAO,cAAc;;;;AC9NvB,MAAMC,iBAAe,CAAC,aAAa,aAAa;AAOhD,MAAa,sBAAsD;CACjE,UAAU;EACR,MAAM;EACN,aAAA;EACA,SAAS;EACT,2BAA2B;EAC3B,eAAe,OAAO,YAA8B;AAGlD,UAAO;IAAE,aAFW,MAAM,qBAAqB,QAAQ;IAEjC,cADD,MAAM,uBAAuB,QAAQ;IACtB;;EAEvC;CAED,WAAW;EACT,aAAa;EACb,oBAAoB;EACpB,iBAAiB;EACjB,kBAAkB,KAAA;EAClB,kBAAkB;EAClB,gBAAgB;EAChB,sBAAsB,YACpB,iBAAiB,QAAQ;EAC3B,QAAQ,OAAO,YAAY;GACzB,MAAM,EAAE,eAAe;GAEvB,MAAM,kBAAkB,MAAM,YAAY,gBAAgB;IACxD,KAAK;IACL,aAAaA;IACd,CAAC;AAEF,OAAI,gBAAgB,SAAS,EAC3B,MAAK,MAAM,SAAS,iBAAiB;IACnC,MAAM,UAAU,gBAAgBC,OAAK,KAAK,YAAY,MAAM,CAAC;AAC7D,QAAI,CAAC,QAAS;AAEd,QACE,QAAQ,SAAS,cAAc,IAC/B,QAAQ,SAAS,gBAAgB,IACjC,QAAQ,SAAS,yBAAyB,IAC1C,4BAA4B,KAAK,QAAQ,CAEzC,QAAO;;GAKb,MAAM,oBAAoB,MAAM,YAC9B;IAAC;IAAwB;IAAqB;IAAc,EAC5D;IACE,KAAK;IACL,aAAaD;IACd,CACF;AAED,QAAK,MAAM,WAAW,mBAAmB;IACvC,MAAM,UAAU,gBAAgBC,OAAK,KAAK,YAAY,QAAQ,CAAC;AAC/D,QAAI,CAAC,QAAS;AAGd,QACE,yBAAyB,KAAK,QAAQ,IACtC,kBAAkB,KAAK,QAAQ,CAE/B,QAAO;;AAIX,UAAO;;EAET,sBAAsB;EACvB;CAED,aAAa;EACX,iBAAiB;EACjB,aAAa,QAAgB,UAAkB;GAC7C,uBAAuB;GACvB,cAAc;GACf;EACF;CAED,WAAW,EACT,UAAU,aAAa,EACrB,aAAa,QAAQ,eAAe,WACrC,GACF;CAED,SAAS;EACP,qBAAqB;EACrB,sBACE;EACF,4BAA4B,YAAY;GACtC,MAAM,kBAAkB,QAAQ,cAC5B,yBAAyB,QAAQ,YAAY,GAC7C;GAUJ,MAAM,cAAc,QAAQ,cAP8B;kBAC1B;aACL;iBACI;kBACC;IAC/B,CAGkB,QAAQ,eACvB;GAEJ,MAAM,QAAQ,CACZ,iBAAiB,mBACjB,sBAAsB,YAAY,kCAAkC,YAAY,qBACjF;AAED,OAAI,QAAQ,aACV,OAAM,KAAK,kBAAkB,QAAQ,eAAe;AAGtD,UAAO;;EAEV;CAED,IAAI;EACF,gBAAgB;EAChB,0BAA0B;EAC1B,kBAAkB,YAAY;AAI5B,UAAO;IACL,iBAJsB,QAAQ,cAC5B,yBAAyB,QAAQ,YAAY,GAC7C,SAE+B;IACjC;IACA;IACA;IACD;;EAEH,yBAAyB;GACvB;GACA;GACA;GACD;EACF;CACF;;;ACtJD,MAAMC,iBAAe;CACnB;CACA;CACA;CACA;CACD;;AAGD,MAAMC,uBAAqB;;;;AAK3B,MAAa,wBAAwB,qBAAqB;;;;AAK1D,eAAsB,gBACpB,SAC6B;CAC7B,MAAM,EAAE,eAAe;CAGvB,MAAM,oBAAoB,MAAM,YAC9B;EAAC;EAAwB;EAAqB;EAAe;EAAa,EAC1E;EACE,KAAK;EACL,aAAaD;EACd,CACF;AAED,MAAK,MAAM,WAAW,mBAAmB;EACvC,MAAM,UAAU,gBAAgBE,OAAK,KAAK,YAAY,QAAQ,CAAC;AAC/D,MAAI,CAAC,QAAS;EAGd,MAAM,oBAAoB,QAAQ,MAChC,gDACD;AACD,MAAI,kBACF,QAAO,kBAAkB;EAI3B,MAAM,iBAAiB,QAAQ,MAC7B,8DACD;AACD,MAAI,eACF,QAAO,eAAe;;;;;;AAU5B,eAAe,gBAAgB,EAC7B,cACyD;CACzD,MAAM,oBAAoB,MAAM,YAC9B;EAAC;EAAwB;EAAqB;EAAa,EAC3D;EACE,KAAK;EACL,aAAaF;EACd,CACF;AAED,MAAK,MAAM,WAAW,mBAAmB;EACvC,MAAM,UAAU,gBAAgBE,OAAK,KAAK,YAAY,QAAQ,CAAC;AAC/D,MAAI,CAAC,QAAS;AACd,MACE,QAAQ,SAAS,gBAAgB,IACjC,QAAQ,SAAS,gBAAgB,CAEjC,QAAO;;CAKX,MAAM,UAAU,MAAM,YAAY,CAAC,UAAU,EAAE;EAC7C,KAAK;EACL,aAAaF;EACb,OAAOC;EACR,CAAC;AAEF,MAAK,MAAM,UAAU,SAAS;EAC5B,MAAM,UAAU,gBAAgBC,OAAK,KAAK,YAAY,OAAO,CAAC;AAC9D,MAAI,CAAC,QAAS;AACd,MACE,QAAQ,SAAS,4BAA4B,IAC7C,QAAQ,SAAS,uBAAuB,CAExC,QAAO;;AAIX,QAAO;;;;;AAMT,eAAe,cAAc,EAC3B,cACyD;CACzD,MAAM,oBAAoB,MAAM,YAC9B;EAAC;EAAwB;EAAqB;EAAa,EAC3D;EACE,KAAK;EACL,aAAaF;EACd,CACF;AAED,MAAK,MAAM,WAAW,mBAAmB;EACvC,MAAM,UAAU,gBAAgBE,OAAK,KAAK,YAAY,QAAQ,CAAC;AAC/D,MAAI,CAAC,QAAS;AACd,MAAI,QAAQ,SAAS,cAAc,IAAI,QAAQ,SAAS,cAAc,CACpE,QAAO;;CAKX,MAAM,UAAU,MAAM,YAAY,CAAC,UAAU,EAAE;EAC7C,KAAK;EACL,aAAaF;EACb,OAAOC;EACR,CAAC;AAEF,MAAK,MAAM,UAAU,SAAS;EAC5B,MAAM,UAAU,gBAAgBC,OAAK,KAAK,YAAY,OAAO,CAAC;AAC9D,MAAI,CAAC,QAAS;AACd,MACE,QAAQ,SAAS,0BAA0B,IAC3C,QAAQ,SAAS,qBAAqB,CAEtC,QAAO;;AAIX,QAAO;;;;;AAMT,eAAe,gBAAgB,EAC7B,cACyD;CACzD,MAAM,oBAAoB,MAAM,YAC9B;EAAC;EAAwB;EAAqB;EAAa,EAC3D;EACE,KAAK;EACL,aAAaF;EACd,CACF;AAED,MAAK,MAAM,WAAW,mBAAmB;EACvC,MAAM,UAAU,gBAAgBE,OAAK,KAAK,YAAY,QAAQ,CAAC;AAC/D,MAAI,CAAC,QAAS;AACd,MAAI,QAAQ,SAAS,gBAAgB,CACnC,QAAO;;CAKX,MAAM,UAAU,MAAM,YAAY,CAAC,UAAU,EAAE;EAC7C,KAAK;EACL,aAAaF;EACb,OAAOC;EACR,CAAC;AAEF,MAAK,MAAM,UAAU,SAAS;EAC5B,MAAM,UAAU,gBAAgBC,OAAK,KAAK,YAAY,OAAO,CAAC;AAC9D,MAAI,CAAC,QAAS;AACd,MACE,QAAQ,SAAS,4BAA4B,IAC7C,QAAQ,SAAS,uBAAuB,CAExC,QAAO;;AAIX,QAAO;;;;;AAMT,eAAe,cAAc,EAC3B,cACyD;CACzD,MAAM,UAAU,MAAM,YAAY,CAAC,UAAU,EAAE;EAC7C,KAAK;EACL,aAAaF;EACb,OAAOC;EACR,CAAC;AAEF,MAAK,MAAM,UAAU,SAAS;EAC5B,MAAM,UAAU,gBAAgBC,OAAK,KAAK,YAAY,OAAO,CAAC;AAC9D,MAAI,CAAC,QAAS;AACd,MACE,QAAQ,SAAS,aAAa,IAC9B,QAAQ,SAAS,sBAAsB,IACvC,QAAQ,SAAS,8BAA8B,CAE/C,QAAO;;AAIX,QAAO;;;;;AAMT,eAAsB,oBACpB,SAC2B;CAC3B,MAAM,EAAE,eAAe;AAGvB,KAAI,MAAM,cAAc,EAAE,YAAY,CAAC,EAAE;AACvC,SAAO,CAAC,qBAAqB,cAAc;AAC3C,SAAA;;AAIF,KAAI,MAAM,gBAAgB,EAAE,YAAY,CAAC,EAAE;AACzC,SAAO,CAAC,qBAAqB,gBAAgB;AAC7C,SAAA;;AAIF,KAAI,MAAM,gBAAgB,EAAE,YAAY,CAAC,EAAE;AACzC,SAAO,CAAC,qBAAqB,gBAAgB;AAC7C,SAAA;;AAIF,KAAI,MAAM,cAAc,EAAE,YAAY,CAAC,EAAE;AACvC,SAAO,CAAC,qBAAqB,wBAAwB;AACrD,SAAA;;AAIF,QAAO,CAAC,qBAAqB,QAAQ;AACrC,QAAA;;;;;AAMF,SAAgB,wBAAwB,aAAuC;AAC7E,SAAQ,aAAR;EACE,KAAA,WACE,QAAO;EACT,KAAA,UACE,QAAO;EACT,KAAA,QACE,QAAO;EACT,KAAA,UACE,QAAO;EACT,KAAA,YACE,QAAO;;;;;;AAOb,eAAsB,iBACpB,SAC6B;CAC7B,MAAM,EAAE,eAAe;CAYvB,MAAM,WAAW,MAAM,YATA;EACrB;EACA;EACA;EACA;EACA;EACA;EACD,EAEkD;EACjD,KAAK;EACL,aAAaF;EACd,CAAC;AAGF,MAAK,MAAM,WAAW,UAAU;EAC9B,MAAM,UAAU,gBAAgBE,OAAK,KAAK,YAAY,QAAQ,CAAC;AAC/D,MAAI,CAAC,QAAS;AAEd,MACE,QAAQ,SAAS,kBAAkB,IACnC,QAAQ,SAAS,SAAS,IAC1B,QAAQ,SAAS,kBAAkB,CAEnC,QAAO;;CAKX,MAAM,aAAa,MAAM,YAAY,CAAC,UAAU,EAAE;EAChD,KAAK;EACL,aAAaF;EACb,OAAOC;EACR,CAAC;AAEF,MAAK,MAAM,UAAU,YAAY;EAC/B,MAAM,UAAU,gBAAgBC,OAAK,KAAK,YAAY,OAAO,CAAC;AAC9D,MAAI,CAAC,QAAS;AACd,MACE,QAAQ,SAAS,kBAAkB,IACnC,QAAQ,SAAS,kBAAkB,CAEnC,QAAO;;AAKX,KAAI,SAAS,SAAS,EACpB,QAAO,SAAS;;;;ACpUpB,MAAMC,iBAAe,CAAC,aAAa,aAAa;AAOhD,MAAa,qBAAoD;CAC/D,UAAU;EACR,MAAM;EACN,aAAA;EACA,SAAS;EACT,2BAA2B;EAC3B,eAAe,OAAO,YAA8B;AAGlD,UAAO;IAAE,aAFW,MAAM,oBAAoB,QAAQ;IAEhC,SADN,MAAM,iBAAiB,QAAQ;IAChB;;EAElC;CAED,WAAW;EACT,aAAa;EACb,oBAAoB;EACpB,iBAAiB;EACjB,kBAAkB,KAAA;EAClB,kBAAkB;EAClB,gBAAgB;EAChB,sBAAsB,YACpB,gBAAgB,QAAQ;EAC1B,QAAQ,OAAO,YAAY;GACzB,MAAM,EAAE,eAAe;GAEvB,MAAM,oBAAoB,MAAM,YAC9B;IACE;IACA;IACA;IACA;IACD,EACD;IACE,KAAK;IACL,aAAaA;IACd,CACF;AAED,QAAK,MAAM,WAAW,mBAAmB;IACvC,MAAM,UAAU,gBAAgBC,OAAK,KAAK,YAAY,QAAQ,CAAC;AAC/D,QAAI,CAAC,QAAS;AACd,QACE,yBAAyB,KAAK,QAAQ,IACtC,iBAAiB,KAAK,QAAQ,CAE9B,QAAO;;GAIX,MAAM,UAAU,MAAM,YACpB;IAAC;IAAa;IAAc;IAAqB;IAAiB,EAClE;IACE,KAAK;IACL,aAAaD;IACd,CACF;AAED,QAAK,MAAM,UAAU,SAAS;IAC5B,MAAM,UAAU,gBAAgBC,OAAK,KAAK,YAAY,OAAO,CAAC;AAC9D,QAAI,CAAC,QAAS;AACd,QACE,QAAQ,SAAS,oBAAoB,IACrC,QAAQ,SAAS,eAAe,IAChC,aAAa,KAAK,QAAQ,CAE1B,QAAO;;AAIX,UAAO;;EAET,sBAAsB;EACvB;CAED,aAAa;EACX,iBAAiB;EACjB,aAAa,QAAgB,UAAkB;GAC7C,uBAAuB;GACvB,cAAc;GACf;EACF;CAED,WAAW,EACT,UAAU,aAAa,EACrB,aAAa,QAAQ,eAAe,WACrC,GACF;CAED,SAAS;EACP,qBAAqB;EACrB,sBACE;EACF,4BAA4B,YAAY;GACtC,MAAM,kBAAkB,QAAQ,cAC5B,wBAAwB,QAAQ,YAAY,GAC5C;GAWJ,MAAM,cAAc,QAAQ,cAR6B;kBAC1B;iBACD;eACF;iBACE;mBACE;IAC/B,CAGkB,QAAQ,eACvB;GAEJ,MAAM,QAAQ,CACZ,iBAAiB,mBACjB,sBAAsB,YAAY,kCAAkC,YAAY,qBACjF;AAED,OAAI,QAAQ,QACV,OAAM,KAAK,aAAa,QAAQ,UAAU;AAG5C,UAAO;;EAEV;CAED,IAAI;EACF,gBAAgB;EAChB,0BAA0B;EAC1B,kBAAkB,YAAY;AAI5B,UAAO;IACL,iBAJsB,QAAQ,cAC5B,wBAAwB,QAAQ,YAAY,GAC5C,QAE+B;IACjC;IACA;IACA;IACD;;EAEH,yBAAyB;GACvB;GACA;GACA;GACD;EACF;CACF;;;AC3JD,MAAMC,iBAAe;CAAC;CAAa;CAAc;CAAmB;;AAGpE,MAAMC,uBAAqB;;;;AAK3B,SAAgB,wBAAwB,SAAqC;AAC3E,KAAI,CAAC,QACH,QAAO;AAGT,KAAI;EACF,MAAM,SAAS,WAAW,QAAQ;AAClC,MAAI,CAAC,OACH,QAAO;EAET,MAAM,eAAe,MAAM,OAAO;AAElC,MAAI,iBAAiB,EACnB,QAAO;AAET,SAAO,GAAG,aAAa;SACjB;AACN,SAAO;;;;;;AAOX,eAAsB,kBACpB,SAC6B;CAC7B,MAAM,EAAE,eAAe;CAGvB,MAAM,oBAAoB,MAAM,YAC9B;EAAC;EAAwB;EAAqB;EAAe;EAAa,EAC1E;EACE,KAAK;EACL,aAAaD;EACd,CACF;AAED,MAAK,MAAM,WAAW,mBAAmB;EACvC,MAAM,UAAU,gBAAgBE,OAAK,KAAK,YAAY,QAAQ,CAAC;AAC/D,MAAI,CAAC,QAAS;EAGd,MAAM,oBAAoB,QAAQ,MAChC,2DACD;AACD,MAAI,kBACF,QAAO,kBAAkB;EAI3B,MAAM,iBAAiB,QAAQ,MAC7B,yEACD;AACD,MAAI,eACF,QAAO,eAAe;;;;;;AAU5B,eAAe,aAAa,EAC1B,cACyD;CACzD,MAAM,UAAU,MAAM,YAAY,CAAC,UAAU,EAAE;EAC7C,KAAK;EACL,aAAaF;EACb,OAAOC;EACR,CAAC;AAEF,MAAK,MAAM,UAAU,SAAS;EAC5B,MAAM,UAAU,gBAAgBC,OAAK,KAAK,YAAY,OAAO,CAAC;AAC9D,MAAI,CAAC,QAAS;AACd,MACE,QAAQ,SAAS,aAAa,IAC9B,QAAQ,SAAS,kBAAkB,IACnC,QAAQ,SAAS,gCAAgC,CAEjD,QAAO;;AAIX,QAAO;;;;;AAMT,eAAe,aAAa,EAC1B,cACyD;CAEzD,MAAM,UAAU,MAAM,YAAY,CAAC,UAAU,EAAE;EAC7C,KAAK;EACL,aAAaF;EACb,OAAOC;EACR,CAAC;AAEF,MAAK,MAAM,UAAU,SAAS;EAC5B,MAAM,UAAU,gBAAgBC,OAAK,KAAK,YAAY,OAAO,CAAC;AAC9D,MAAI,CAAC,QAAS;AACd,MACE,QAAQ,SAAS,kBAAkB,IACnC,QAAQ,SAAS,iCAAiC,CAElD,QAAO;;AAWX,SANsB,MAAM,YAAY,CAAC,kBAAkB,EAAE;EAC3D,KAAK;EACL,aAAaF;EACb,OAAO;EACR,CAAC,EAEmB,SAAS;;;;;AAMhC,eAAsB,sBACpB,SAC6B;CAC7B,MAAM,EAAE,eAAe;AAGvB,KAAI,MAAM,aAAa,EAAE,YAAY,CAAC,EAAE;AACtC,SAAO,CAAC,qBAAqB,mCAAmC;AAChE,SAAA;;AAIF,KAAI,MAAM,aAAa,EAAE,YAAY,CAAC,EAAE;AACtC,SAAO,CAAC,qBAAqB,yBAAyB;AACtD,SAAA;;AAIF,QAAO,CAAC,qBAAqB,UAAU;AACvC,QAAA;;;;;AAMF,SAAgB,0BACd,aACQ;AACR,SAAQ,aAAR;EACE,KAAA,WACE,QAAO;EACT,KAAA,SACE,QAAO;EACT,KAAA,YACE,QAAO;;;;;;AAOb,eAAsB,mBACpB,SAC6B;CAC7B,MAAM,EAAE,eAAe;CAWvB,MAAM,WAAW,MAAM,YARA;EACrB;EACA;EACA;EACA;EACA;EACD,EAEkD;EACjD,KAAK;EACL,aAAaA;EACd,CAAC;AAGF,MAAK,MAAM,WAAW,UAAU;EAC9B,MAAM,UAAU,gBAAgBE,OAAK,KAAK,YAAY,QAAQ,CAAC;AAC/D,MAAI,CAAC,QAAS;AAEd,MACE,QAAQ,SAAS,WAAW,IAC5B,QAAQ,SAAS,8BAA8B,CAE/C,QAAO;;CAKX,MAAM,aAAa,MAAM,YAAY,CAAC,UAAU,EAAE;EAChD,KAAK;EACL,aAAaF;EACb,OAAOC;EACR,CAAC;AAEF,MAAK,MAAM,UAAU,WAEnB,KADgB,gBAAgBC,OAAK,KAAK,YAAY,OAAO,CAAC,EACjD,SAAS,WAAW,CAC/B,QAAO;AAKX,KAAI,SAAS,SAAS,EACpB,QAAO,SAAS;;;;AC1NpB,MAAMC,iBAAe,CAAC,aAAa,aAAa;;;;AAMhD,MAAa,uBAAwC;CACnD,UAAU;EACR,MAAM;EACN,aAAA;EACA,SAAS;EACT,2BAA2B;EAC3B,eAAe,OAAO,YAA8B;AAGlD,UAAO;IAAE,aAFW,MAAM,sBAAsB,QAAQ;IAElC,SADN,MAAM,mBAAmB,QAAQ;IAClB;;EAElC;CAED,WAAW;EACT,aAAa;EACb,oBAAoB;EACpB,iBAAiB;EACjB,aAAa,iBAAsB;EAKnC,kBAAkB;EAClB,qBAAqB;EACrB,QAAQ,OAAO,YAAY;GACzB,MAAM,EAAE,eAAe;GAMvB,MAAM,oBAAoB,MAAM,YAC9B;IACE;IACA;IACA;IACA;IACD,EACD;IACE,KAAK;IACL,aAAaA;IACd,CACF;AAED,QAAK,MAAM,WAAW,mBAAmB;IACvC,MAAM,UAAU,gBAAgBC,OAAK,KAAK,YAAY,QAAQ,CAAC;AAC/D,QAAI,CAAC,QAAS;AAGd,QACE,2BAA2B,KAAK,QAAQ,IACxC,mBAAmB,KAAK,QAAQ,CAEhC,QAAO;;GAKX,MAAM,UAAU,MAAM,YACpB;IAAC;IAAc;IAAa;IAAqB;IAAiB,EAClE;IACE,KAAK;IACL,aAAaD;IACd,CACF;AAED,QAAK,MAAM,UAAU,SAAS;IAC5B,MAAM,UAAU,gBAAgBC,OAAK,KAAK,YAAY,OAAO,CAAC;AAC9D,QAAI,CAAC,QAAS;AACd,QACE,QAAQ,SAAS,sBAAsB,IACvC,QAAQ,SAAS,iBAAiB,IAClC,eAAe,KAAK,QAAQ,CAE5B,QAAO;;AAIX,UAAO;;EAET,sBAAsB;EACvB;CAED,aAAa;EACX,iBAAiB;EACjB,aAAa,QAAgB,UAAkB;GAC7C,uBAAuB;GACvB,cAAc;GACf;EACF;CAED,WAAW,EACT,UAAU,YAAiB;AAEzB,SAAO,EACL,aAFkB,QAAQ,eAEE,WAC7B;IAEJ;CAED,SAAS;EACP,qBAAqB;EACrB,sBACE;EACF,4BAA4B,YAAiB;GAC3C,MAAM,cAAc,QAAQ;GAC5B,MAAM,kBAAkB,cACpB,0BAA0B,YAAY,GACtC;GASJ,MAAM,cAAc,cANuC;kBAC1B;gBACF;mBACG;IACjC,CAEgD,eAAe;GAEhE,MAAM,QAAQ,CACZ,iBAAiB,mBACjB,sBAAsB,YAAY,kCAAkC,YAAY,qBACjF;AAED,OAAI,QAAQ,QACV,OAAM,KAAK,aAAa,QAAQ,UAAU;AAG5C,UAAO;;EAEV;CAED,IAAI;EACF,gBAAgB;EAChB,0BAA0B;EAC1B,kBAAkB,YAAiB;GACjC,MAAM,cAAc,QAAQ;AAI5B,UAAO;IACL,iBAJsB,cACpB,0BAA0B,YAAY,GACtC,UAE+B;IACjC;IACA;IACA;IACD;;EAEH,yBAAyB;GACvB;GACA;GACA;GACD;EACF;CACF;;;ACnKD,MAAMC,iBAAe;CACnB;CACA;CACA;CACA;CACA;CACD;;AAGD,MAAMC,uBAAqB;;;;AAK3B,MAAa,0BAA0B,qBAAqB;;;;AAK5D,SAAgB,gBACd,SACiC;CACjC,MAAM,EAAE,eAAe;CAEvB,MAAM,eAAeC,OAAK,KAAK,YAAY,gBAAgB;AAC3D,KAAI;EACF,MAAM,UAAUC,KAAG,aAAa,cAAc,QAAQ;AACtD,SAAO,KAAK,MAAM,QAAQ;SACpB;AACN;;;;;;AAOJ,SAAS,mBACP,aACA,SACS;CACT,MAAM,WAAW,gBAAgB,QAAQ;AACzC,KAAI,CAAC,SAAU,QAAO;AAEtB,QAAO,CAAC,EACN,SAAS,UAAU,gBAAgB,SAAS,iBAAiB;;;;;AAOjE,SAAS,0BACP,aACA,SACoB;CACpB,MAAM,WAAW,gBAAgB,QAAQ;AACzC,KAAI,CAAC,SAAU,QAAO,KAAA;CAEtB,MAAM,UACJ,SAAS,UAAU,gBAAgB,SAAS,iBAAiB;AAC/D,KAAI,QAEF,QAAO,QAAQ,QAAQ,cAAc,GAAG;;;;;AAS5C,eAAe,sBACb,SACA,SACA,eAAyB,CAAC,WAAW,EACnB;CAClB,MAAM,EAAE,eAAe;CAEvB,MAAM,WAAW,MAAM,YAAY,cAAc;EAC/C,KAAK;EACL,aAAaH;EACb,OAAOC;EACR,CAAC;CAEF,MAAM,gBACJ,OAAO,YAAY,WAAW,IAAI,OAAO,QAAQ,GAAG;AAEtD,MAAK,MAAM,WAAW,UAAU;EAC9B,MAAM,UAAU,gBAAgBC,OAAK,KAAK,YAAY,QAAQ,CAAC;AAC/D,MAAI,CAAC,QAAS;AACd,MAAI,cAAc,KAAK,QAAQ,CAAE,QAAO;;AAG1C,QAAO;;;;;AAMT,SAAgB,kBACd,SACoB;AACpB,QAAO,0BAA0B,qBAAqB,QAAQ;;;;;AAMhE,SAAgB,0BACd,aACQ;AACR,SAAQ,aAAR;EACE,KAAA,WACE,QAAO;EACT,KAAA,UACE,QAAO;EACT,KAAA,WACE,QAAO;EACT,QACE,QAAO;;;;;;AAOb,eAAe,WACb,SACkB;AAClB,QACE,mBAAmB,6BAA6B,QAAQ,IACvD,MAAM,sBAAsB,6BAA6B,QAAQ;;;;;AAOtE,eAAe,YACb,SACkB;AAClB,QACE,mBAAmB,qBAAqB,QAAQ,IAC/C,MAAM,sBAAsB,iCAAiC,QAAQ;;;;;AAO1E,eAAsB,sBACpB,SAC6B;AAE7B,KAAI,MAAM,WAAW,QAAQ,EAAE;AAC7B,SAAO,CAAC,qBAAqB,0BAA0B;AACvD,SAAA;;AAEF,KAAI,MAAM,YAAY,QAAQ,EAAE;AAC9B,SAAO,CAAC,qBAAqB,wBAAwB;AACrD,SAAA;;AAIF,QAAO,CAAC,qBAAqB,UAAU;AACvC,QAAA;;;;;AAMF,eAAsB,2BACpB,SAC6B;CAC7B,MAAM,EAAE,eAAe;CAGvB,MAAM,qBAAqBA,OAAK,KAC9B,YACA,uCACD;AAED,KAAIC,KAAG,WAAW,mBAAmB,CACnC,QAAO;AAaT,SATkB,MAAM,YACtB,CAAC,wCAAwC,EACzC;EACE,KAAK;EACL,aAAaH;EACb,OAAO;EACR,CACF,EAEgB;;;;;AAMnB,SAAgB,yBACd,SACoB;CACpB,MAAM,EAAE,eAAe;CAGvB,MAAM,eAAeE,OAAK,KAAK,YAAY,oBAAoB;AAC/D,KAAIC,KAAG,WAAW,aAAa,CAC7B,QAAO;CAIT,MAAM,aAAaD,OAAK,KAAK,YAAY,sBAAsB;AAC/D,KAAIC,KAAG,WAAW,WAAW,CAC3B,QAAO;;;;;AASX,SAAgB,uBACd,SACgC;CAChC,MAAM,UAAU,kBAAkB,QAAQ;AAC1C,KAAI,CAAC,QAAS,QAAO;AAErB,KAAI;EACF,MAAM,eAAe,SAAS,QAAQ,MAAM,IAAI,CAAC,IAAI,GAAG;AACxD,MAAI,gBAAgB,GAAI,QAAO;AAC/B,MAAI,gBAAgB,EAAG,QAAO;AAC9B,SAAO;SACD;AACN,SAAO;;;;;AChOX,MAAa,uBAAwD;CACnE,UAAU;EACR,MAAM;EACN,aAAA;EACA,SAAS;EACT,2BAA2B;EAC3B,eAAe,OAAO,YAA8B;AAMlD,UAAO;IACL,aANkB,MAAM,sBAAsB,QAAQ;IAOtD,iBANsB,MAAM,2BAA2B,QAAQ;IAO/D,eANoB,yBAAyB,QAAQ;IAOrD,kBANuB,uBAAuB,QAAQ;IAOvD;;EAEJ;CAED,WAAW;EACT,aAAa;EACb,oBAAoB;EACpB,iBAAiB;EACjB,kBAAkB,KAAA;EAClB,kBAAkB;EAClB,gBAAgB;EAChB,sBAAsB,YACpB,QAAQ,QAAQ,kBAAkB,QAAQ,CAAC;EAC7C,QAAQ,OAAO,YAAY;GACzB,MAAM,EAAE,eAAe;GAEvB,MAAM,cAAcC,OAAK,KAAK,YAAY,UAAU;AACpD,OAAIC,KAAG,WAAW,YAAY,CAC5B,KAAI;IACF,MAAM,UAAUA,KAAG,aAAa,aAAa,QAAQ;AACrD,QAAI,QAAQ,SAAS,UAAU,IAAI,QAAQ,SAAS,UAAU,CAC5D,QAAO;WAEH;GAKV,MAAM,eAAeD,OAAK,KAAK,YAAY,gBAAgB;AAC3D,OAAIC,KAAG,WAAW,aAAa,CAC7B,KAAI;IACF,MAAM,UAAUA,KAAG,aAAa,cAAc,QAAQ;IACtD,MAAM,WAAW,KAAK,MAAM,QAAQ;AACpC,QACE,SAAS,UAAU,wBACnB,SAAS,iBAAiB,qBAE1B,QAAO;WAEH;AAUV,WAL4B,MAAM,YAChC,CAAC,wBAAwB,yBAAyB,EAClD;IAAE,KAAK;IAAY,OAAO;IAAG,CAC9B,EAE0B,SAAS;;EAEtC,sBAAsB;EACvB;CAED,aAAa;EACX,iBAAiB;EACjB,aAAa,QAAgB,UAAkB;GAC7C,uBAAuB;GACvB,cAAc;GACf;EACF;CAED,WAAW,EACT,UAAU,aAAa;EACrB,aAAa,QAAQ,eAAe;EACpC,kBAAkB,QAAQ,oBAAoB;EAC/C,GACF;CAED,SAAS;EACP,sBACE;EACF,qBACE;EACF,4BAA4B,YAAY;GAKtC,MAAM,QAAQ;IACZ,iBALsB,QAAQ,cAC5B,0BAA0B,QAAQ,YAAY,GAC9C;IAIF;IACA,sBAAsB,QAAQ,iBAAiB;IAChD;AAED,OAAI,QAAQ,gBACV,OAAM,KAAK,qBAAqB,QAAQ,kBAAkB;AAG5D,OAAI,QAAQ,cACV,OAAM,KAAK,mBAAmB,QAAQ,gBAAgB;AAIxD,OAAI,QAAQ,qBAAqB,SAC/B,OAAM,KACJ,mFACD;OAED,OAAM,KACJ,oFACD;AAGH,UAAO;;EAEV;CAED,IAAI;EACF,gBAAgB;EAChB,0BAA0B;EAC1B,kBAAkB,YAAY;GAK5B,MAAM,UAAU;IACd,iBALsB,QAAQ,cAC5B,0BAA0B,QAAQ,YAAY,GAC9C,UAG+B;IACjC;IACA;IACD;AAED,OAAI,QAAQ,qBAAqB,SAC/B,SAAQ,KAAK,oDAAoD;OAEjE,SAAQ,KAAK,wDAAwD;AAGvE,OAAI,QAAQ,gBAAA,UACV,SAAQ,KAAK,6CAA6C;AAG5D,OAAI,QAAQ,gBAAA,WACV,SAAQ,KAAK,2CAA2C;AAG1D,UAAO;;EAET,yBAAyB;GACvB;GACA;GACA;GACA;GACD;EACF;CACF;;;AC/KD,MAAa,yBAA4D;CACvE,UAAU;EACR,MAAM;EACN,aAAA;EACA,SAAS;EACT,sBAAsB,EACpB,QAAQ,EAAE,KAAK,8BAA8B,EAC9C;EACF;CAED,WAAW;EACT,aAAa;EACb,oBAAoB;EACpB,aAAa,gBACX,mBAAmB,iBAAiB,YAA2B;EACjE,QAAQ,OAAO,YAAY;GACzB,MAAM,cAAc,MAAM,kBAAkB,QAAQ;AACpD,UAAO,cACH,sBAAsB,iBAAiB,YAAY,GACnD;;EAEN,gBAAgB;EAChB,sBAAsB;EACvB;CAED,aAAa;EACX,iBAAiB;EACjB,aAAa,QAAgB,UAAkB;GAC7C,8BAA8B;GAC9B,qBAAqB;GACtB;EACF;CAED,WAAW,EACT,gBAAgB,EAAE,GACnB;CAED,SAAS;EACP,sBACE;EACF,iCAAiC,CAC/B,2FACD;EACF;CAED,IAAI;EACF,gBAAgB;EAChB,0BAA0B;EAC1B,uBAAuB;GACrB;GACA;GACA;GACD;EACD,yBAAyB,CACvB,0DACA,sDACD;EACF;CACF;;;;AC9DD,MAAM,wBAAwB;CAC5B;CACA;CACA;CACA;CACA;CACA;CACD;AAMD,SAAS,YAAY,YAAwC;CAC3D,MAAM,cAAcC,OAAK,KAAK,YAAY,eAAe;AACzD,KAAI,CAACC,KAAG,WAAW,YAAY,CAAE,QAAO,KAAA;AACxC,QAAOA,KAAG,aAAa,aAAa,QAAQ;;AAG9C,MAAa,uBAAwD;CACnE,UAAU;EACR,MAAM;EACN,aAAA;EACA,SAAS;EACT,gBAAgB,YAA8B;GAC5C,MAAM,YAAY,sBAAsB,QAAQ,QAC9CA,KAAG,WAAWD,OAAK,KAAK,QAAQ,YAAY,IAAI,CAAC,CAClD;AACD,UAAO,QAAQ,QAAQ,EAAE,WAAW,CAAC;;EAExC;CAED,WAAW;EACT,aAAa;EACb,oBAAoB;EACpB,iBAAiB;EACjB,kBAAkB,KAAA;EAClB,sBAAsB;EAItB,SAAS,YAAY;GACnB,MAAM,UAAU,YAAY,QAAQ,WAAW;AAC/C,UAAO,QAAQ,QAAQ,0BAA0B,KAAK,WAAW,GAAG,CAAC;;EAExE;CAED,aAAa;EACX,iBAAiB;EACjB,aAAa,QAAgB,UAAkB;GAC7C,uBAAuB;GACvB,cAAc;GACf;EACF;CAED,WAAW,EACT,UAAU,aAAa,EACrB,GAAI,QAAQ,WAAW,SACnB,EAAE,WAAW,QAAQ,UAAU,KAAK,IAAI,EAAE,GAC1C,EAAE,EACP,GACF;CAED,SAAS;EACP,sBACE;EACF,qBACE;EACF,4BAA4B,YAAY;GACtC,MAAM,QAAQ,CACZ,wFACA,oOACD;AAED,OAAI,QAAQ,WAAW,OACrB,OAAM,KACJ,6BAA6B,QAAQ,UAAU,KAC7C,KACD,CAAC,4KACH;AAGH,UAAO;;EAEV;CAED,IAAI;EACF,gBAAgB;EAChB,0BAA0B;EAC1B,uBAAuB;GACrB;GACA;GACA;GACA;GACD;EACD,yBAAyB;GACvB;GACA;GACA;GACD;EACF;CACF;;;ACxGD,MAAME,iBAAe,CAAC,gBAAgB,oBAAoB;;AAG1D,MAAM,qBAAqB;AAQ3B,SAAgB,wBAAwB,aAAuC;AAC7E,SAAQ,aAAR;EACE,KAAA,UACE,QAAO;EACT,KAAA,QACE,QAAO;EACT,KAAA,MACE,QAAO;;;AAIb,eAAsB,uBACpB,SACuC;CACvC,MAAM,EAAE,eAAe;CAKvB,MAAM,kBAAkBC,KAAG,WAAWC,OAAK,KAAK,YAAY,gBAAgB,CAAC;CAC7E,MAAM,kBAAkBD,KAAG,WAAWC,OAAK,KAAK,YAAY,cAAc,CAAC;CAC3E,MAAM,gBAAgB,MAAM,GAAG,6BAA6B;EAC1D,KAAK;EACL,iBAAiB;EAClB,CAAC;AAEF,KAAI,mBAAmB,cAAc,WAAW,KAAK,CAAC,gBACpD,QAAA;CAIF,MAAM,aAAa,MAAM,YAAY,cAAc;EACjD,KAAK;EACL,aAAaF;EACb,OAAO;EACR,CAAC;CAEF,IAAI,aAAa;CACjB,IAAI,WAAW;AAEf,MAAK,MAAM,QAAQ,YAAY;EAC7B,MAAM,UAAU,gBAAgBE,OAAK,KAAK,YAAY,KAAK,CAAC;AAC5D,MAAI,CAAC,QAAS;AACd,MAAI,QAAQ,SAAS,iBAAiB,CACpC,cAAa;AAEf,MAAI,QAAQ,SAAS,eAAe,CAClC,YAAW;;AAIf,KAAI,WAAY,QAAA;AAChB,KAAI,SAAU,QAAA;;;;AClDhB,MAAa,qBAAoD;CAC/D,UAAU;EACR,MAAM;EACN,aAAA;EACA,SAAS;EACT,cACE;EACF,eAAe,OAAO,YAA8B;AAElD,UAAO,EAAE,aADW,MAAM,uBAAuB,QAAQ,EACnC;;EAEzB;CAED,WAAW;EACT,aAAa;EACb,oBAAoB;EACpB,iBAAiB;EACjB,kBAAkB,KAAA;EAClB,QAAQ,OAAO,YAAY;GACzB,MAAM,EAAE,eAAe;GAIvB,MAAM,gBAAgB,MAAM,GAAG,6BAA6B;IAC1D,KAAK;IACL,iBAAiB;IAClB,CAAC;GACF,MAAM,kBAAkBC,KAAG,WACzBC,OAAK,KAAK,YAAY,cAAc,CACrC;AAED,OAAI,cAAc,SAAS,KAAK;SAEX,MAAM,YAAY,cAAc;KACjD,KAAK;KACL,aAAa,CAAC,gBAAgB,oBAAoB;KAClD,OAAO;KACR,CAAC,EACa,SAAS,EACtB,QAAO;;GAKX,MAAM,mBAAmBA,OAAK,KAAK,YAAY,gBAAgB;AAC/D,OAAID,KAAG,WAAW,iBAAiB,CACjC,QAAO;AAGT,UAAO;;EAET,sBAAsB;EACvB;CAED,aAAa;EACX,iBAAiB;EACjB,aAAa,QAAgB,UAAkB;GAC7C,uBAAuB;GACvB,cAAc;GACf;EACF;CAED,WAAW,EACT,UAAU,aAAa,EACrB,aAAa,QAAQ,eAAe,WACrC,GACF;CAED,SAAS;EACP,sBACE;EACF,qBACE;EACF,4BAA4B,YAAY;AAUtC,UALc,CACZ,iBALsB,QAAQ,cAC5B,wBAAwB,QAAQ,YAAY,GAC5C,aAIF,mFACD;;EAIJ;CAED,IAAI;EACF,gBAAgB;EAChB,0BAA0B;EAC1B,kBAAkB,YAAY;AAY5B,UAPgB;IACd,iBALsB,QAAQ,cAC5B,wBAAwB,QAAQ,YAAY,GAC5C,QAG+B;IACjC;IACA;IACA;IACD;;EAIH,yBAAyB;GACvB;GACA;GACA;GACD;EACF;CACF;;;AC1HD,MAAa,mBAAoC;CAC/C,UAAU;EACR,MAAM;EACN,aAAA;EACA,MAAM;EACN,SAAS;EACT,cACE;EACH;CAED,WAAW;EACT,aAAa;EACb,oBAAoB;EACpB,iBAAiB;EACjB,kBAAkB,KAAA;EAClB,sBAAsB;EAKtB,QAAQ,OAAO,YAAY;GACzB,MAAM,EAAE,eAAe;GAGvB,MAAM,aAAa,MAAM,YACvB,CAAC,mBAAmB,sBAAsB,EAC1C,EAAE,KAAK,YAAY,CACpB;AAED,QAAK,MAAM,QAAQ,YAAY;IAC7B,MAAM,UAAU,gBAAgBE,OAAK,KAAK,YAAY,KAAK,CAAC;AAC5D,QAAI,CAAC,QAAS;AACd,QACE,QAAQ,SAAS,4BAA0B,IAC3C,QAAQ,SAAS,qCAAqC,IACtD,QAAQ,SAAS,uBAAuB,CAExC,QAAO;;AAUX,WALmB,MAAM,YAAY,wBAAwB;IAC3D,KAAK;IACL,OAAO;IACR,CAAC,EAEgB,SAAS;;EAE9B;CAED,aAAa;EACX,iBAAiB;EACjB,aAAa,QAAgB,UAAkB;GAC7C,uBAAuB;GACvB,cAAc;GACf;EACF;CAED,WAAW,EACT,gBAAgB,EAAE,GACnB;CAED,SAAS;EACP,sBACE;EACF,qBACE;EACF,iCAAiC;GAC/B;GACA;GACA;GACA;GACA;GACD;EACF;CAED,IAAI;EACF,gBAAgB;EAChB,0BAA0B;EAC1B,uBAAuB;GACrB;GACA;GACA;GACA;GACD;EACD,yBAAyB;GACvB;GACA;GACA;GACA;GACD;EACF;CACF;;;;;;;AC1FD,eAAsB,iBACpB,SAC6B;CAC7B,MAAM,EAAE,eAAe;CAEvB,MAAM,aAAa,MAAM,YACvB,CAAC,mBAAmB,sBAAsB,EAC1C,EAAE,KAAK,YAAY,CACpB;AAED,MAAK,MAAM,QAAQ,YAAY;EAC7B,MAAM,UAAU,gBAAgBC,OAAK,KAAK,YAAY,KAAK,CAAC;AAC5D,MAAI,CAAC,QAAS;EAEd,MAAM,QAAQ,QAAQ,MAAM,kCAAkC;AAC9D,MAAI,MAAO,QAAO,MAAM;;;AAM5B,MAAa,yBAAyB,qBAAqB;;;;AAK3D,SAAgB,iBACd,SACoB;CACpB,MAAM,EAAE,eAAe;AAEvB,MAAK,MAAM,QAAQ;EACjB;EACA;EACA;EACD,EAAE;EACD,MAAM,WAAWA,OAAK,KAAK,YAAY,KAAK;AAC5C,MAAI,CAACC,KAAG,WAAW,SAAS,CAAE;EAE9B,MAAM,UAAUA,KAAG,aAAa,UAAU,QAAQ;EAGlD,MAAM,QAAQ,QAAQ,MAAM,+CAA+C;AAC3E,MAAI,MAAO,QAAO,MAAM;EAGxB,MAAM,YAAY,QAAQ,MAAM,kCAAkC;AAClE,MAAI,UAAW,QAAO,UAAU;;;;;ACvCpC,MAAa,uBAAwD;CACnE,UAAU;EACR,MAAM;EACN,aAAA;EACA,SAAS;EACT,gBAAgB,YAA8B;GAC5C,MAAM,gBAAgB,iBAAiB,QAAQ;AAC/C,UAAO,QAAQ,QAAQ,EAAE,eAAe,CAAC;;EAE5C;CAED,WAAW;EACT,aAAa;EACb,oBAAoB;EACpB,iBAAiB;EACjB,kBAAkB,KAAA;EAClB,mBAAmB,YAAoB,uBAAuB,QAAQ;EAEtE,gBAAgB;EAChB,sBAAsB,YACpB,iBAAiB,QAAQ;EAC3B,sBAAsB;EACtB,QAAQ,OAAO,YAAY;GACzB,MAAM,EAAE,eAAe;AAGvB,OAAIC,KAAG,WAAWC,OAAK,KAAK,YAAY,eAAe,CAAC,CACtD,QAAO;AAIT,QAAK,MAAM,QAAQ,CAAC,gBAAgB,mBAAmB,EAAE;IACvD,MAAM,kBAAkBA,OAAK,KAAK,YAAY,KAAK;AACnD,QAAID,KAAG,WAAW,gBAAgB,EAAE;KAClC,MAAM,UAAUA,KAAG,aAAa,iBAAiB,QAAQ;AACzD,SACE,QAAQ,SAAS,0BAA0B,IAC3C,QAAQ,SAAS,sBAAsB,IACvC,QAAQ,SAAS,iCAAiC,CAElD,QAAO;;;AAYb,QALsB,MAAM,YAAY,0BAA0B;IAChE,KAAK;IACL,OAAO;IACR,CAAC,EAEgB,SAAS;SACL,MAAM,YAAY,WAAW;KAC/C,KAAK;KACL,OAAO;KACR,CAAC,EACc,SAAS,EACvB,QAAO;;AAIX,UAAO;;EAEV;CAED,aAAa;EACX,iBAAiB;EACjB,aAAa,QAAgB,UAAkB;GAC7C,uBAAuB;GACvB,cAAc;GACf;EACF;CAED,WAAW,EACT,UAAU,aAAa,EACrB,GAAI,QAAQ,gBACR,EAAE,eAAe,uBAAuB,QAAQ,cAAc,EAAE,GAChE,EAAE,EACP,GACF;CAED,SAAS;EACP,sBACE;EACF,qBACE;EACF,4BAA4B,YAAY;GACtC,MAAM,QAAQ,CACZ,uFACD;AAED,OAAI,QAAQ,cACV,OAAM,KAAK,mBAAmB,QAAQ,gBAAgB;AAGxD,UAAO;;EAEV;CAED,IAAI;EACF,gBAAgB;EAChB,0BAA0B;EAC1B,uBAAuB;GACrB;GACA;GACA;GACA;GACD;EACD,yBAAyB;GACvB;GACA;GACA;GACD;EACF;CACF;;;ACzHD,MAAM,kBAAkB;CACtB;CACA;CACA;CACA;CACA;CACA;CACD;;;;AAKD,MAAa,wBAAwB,qBAAqB;;;;AAK1D,SAAS,YACP,SACoB;CACpB,MAAM,EAAE,eAAe;CAEvB,MAAM,cAAcE,OAAK,KAAK,YAAY,UAAU;AACpD,KAAI;AACF,SAAOC,KAAG,aAAa,aAAa,QAAQ;SACtC;AACN;;;;;;AAOJ,SAAgB,OACd,SACA,SACS;CACT,MAAM,UAAU,YAAY,QAAQ;AACpC,KAAI,CAAC,QAAS,QAAO;AAIrB,QADmB,IAAI,OAAO,mBAAmB,QAAQ,OAAO,KAAK,CACnD,KAAK,QAAQ;;;;;AAMjC,SAAgB,cACd,SACA,SACoB;CACpB,MAAM,UAAU,YAAY,QAAQ;AACpC,KAAI,CAAC,QAAS,QAAO,KAAA;CAErB,MAAM,iBAAiB,IAAI,OACzB,mBAAmB,QAAQ,8DAC3B,KACD;AAED,QADc,QAAQ,MAAM,eAAe,GAC5B;;;;;AAMjB,SAAgB,gBACd,SACoB;AACpB,QAAO,cAAc,SAAS,QAAQ;;;;;AAMxC,SAAgB,oBACd,SACkB;CAClB,MAAM,EAAE,eAAe;CAGvB,MAAM,gBAAgBD,OAAK,KAAK,YAAY,wBAAwB;AACpE,KAAIC,KAAG,WAAW,cAAc,CAC9B,KAAI;AAEF,MADgBA,KAAG,aAAa,eAAe,QAAQ,CAC3C,SAAS,yBAAyB,EAAE;AAC9C,UAAO,CAAC,qBAAqB,iBAAiB;AAC9C,UAAA;;SAEI;AAKV,QAAO,CAAC,qBAAqB,QAAQ;AACrC,QAAA;;;;;AAMF,SAAgB,wBAAwB,aAAuC;AAC7E,SAAQ,aAAR;EACE,KAAA,WACE,QAAO;EACT,KAAA,MACE,QAAO;;;;;;AAOb,SAAgB,oBACd,SACoB;CACpB,MAAM,EAAE,eAAe;CAEvB,MAAM,kBAAkBD,OAAK,KAAK,YAAY,sBAAsB;AACpE,KAAIC,KAAG,WAAW,gBAAgB,CAChC,QAAO;;;;;AASX,eAAsB,eACpB,SACkB;CAClB,MAAM,EAAE,eAAe;CAGvB,MAAM,eAAeD,OAAK,KAAK,YAAY,YAAY;AACvD,KAAIC,KAAG,WAAW,aAAa,CAC7B,QAAO;CAIT,MAAM,gBAAgBD,OAAK,KAAK,YAAY,wBAAwB;AACpE,KAAIC,KAAG,WAAW,cAAc,CAC9B,KAAI;EACF,MAAM,UAAUA,KAAG,aAAa,eAAe,QAAQ;AACvD,MACE,QAAQ,SAAS,qBAAqB,IACtC,QAAQ,SAAS,oBAAkB,IACnC,QAAQ,SAAS,kBAAkB,CAEnC,QAAO;SAEH;AAMV,KAAI,OAAO,SAAS,QAAQ,CAC1B,QAAO;AAST,SAL4B,MAAM,GAChC,CAAC,oBAAoB,wBAAwB,EAC7C;EAAE,KAAK;EAAY,QAAQ;EAAiB,CAC7C,EAE0B,UAAU;;;;AChKvC,MAAa,qBAAoD;CAC/D,UAAU;EACR,MAAM;EACN,aAAA;EACA,SAAS;EACT,2BAA2B;EAC3B,gBAAgB,YAA8B;GAC5C,MAAM,cAAc,oBAAoB,QAAQ;GAChD,MAAM,kBAAkB,oBAAoB,QAAQ;AACpD,UAAO,QAAQ,QAAQ;IAAE;IAAa;IAAiB,CAAC;;EAE3D;CAED,WAAW;EACT,aAAa;EACb,oBAAoB;EACpB,iBAAiB;EACjB,kBAAkB,KAAA;EAClB,kBAAkB;EAClB,gBAAgB;EAChB,sBAAsB,YACpB,QAAQ,QAAQ,gBAAgB,QAAQ,CAAC;EAC3C,QAAQ,OAAO,YAAY,eAAe,QAAQ;EAClD,sBAAsB;EACvB;CAED,aAAa;EACX,iBAAiB;EACjB,aAAa,QAAgB,UAAkB;GAC7C,uBAAuB;GACvB,cAAc;GACf;EACF;CAED,WAAW,EACT,UAAU,aAAa,EACrB,aAAa,QAAQ,eAAe,WACrC,GACF;CAED,SAAS;EACP,sBACE;EACF,qBACE;EACF,4BAA4B,YAAY;GAKtC,MAAM,QAAQ,CACZ,iBALsB,QAAQ,cAC5B,wBAAwB,QAAQ,YAAY,GAC5C,aAIF,mGACD;AAED,OAAI,QAAQ,gBACV,OAAM,KAAK,2BAA2B,QAAQ,kBAAkB;AAGlE,OAAI,QAAQ,gBAAA,MACV,OAAM,KACJ,6EACD;AAGH,UAAO;;EAEV;CAED,IAAI;EACF,gBAAgB;EAChB,0BAA0B;EAC1B,kBAAkB,YAAY;GAK5B,MAAM,UAAU;IACd,iBALsB,QAAQ,cAC5B,wBAAwB,QAAQ,YAAY,GAC5C,QAG+B;IACjC;IACA;IACA;IACD;AAED,OAAI,QAAQ,gBAAA,MACV,SAAQ,KACN,wEACD;AAGH,UAAO;;EAET,yBAAyB;GACvB;GACA;GACA;GACA;GACA;GACD;EACF;CACF;;;AC5GD,SAAS,WAAW,YAAwC;CAC1D,MAAM,aAAaC,OAAK,KAAK,YAAY,UAAU;AACnD,KAAI,CAACC,KAAG,WAAW,WAAW,CAC5B;AAEF,QAAOA,KAAG,aAAa,YAAY,QAAQ;;;AAI7C,SAAS,iBAAiB,YAA6B;CACrD,MAAM,SAAS,WAAW,WAAW;AACrC,QAAO,CAAC,CAAC,UAAU,oBAAoB,KAAK,OAAO;;AAGrD,MAAa,sBAAsD;CACjE,UAAU;EACR,MAAM;EACN,aAAA;EACA,SAAS;EACT,gBAAgB,YAA8B;GAC5C,MAAM,UAAU,iBAAiB,QAAQ,WAAW;AACpD,UAAO,QAAQ,QAAQ,EAAE,SAAS,CAAC;;EAEtC;CAED,WAAW;EACT,aAAa;EACb,oBAAoB;EACpB,iBAAiB;EACjB,kBAAkB,KAAA;EAGlB,SAAS,YAAY;GACnB,MAAM,SAAS,WAAW,QAAQ,WAAW;AAC7C,UAAO,QAAQ,QAAQ,CAAC,CAAC,UAAU,kBAAkB,KAAK,OAAO,CAAC;;EAEpE,sBAAsB;EACvB;CAED,aAAa;EACX,iBAAiB;EACjB,aAAa,QAAgB,UAAkB;GAC7C,iBAAiB;GACjB,cAAc;GACf;EACF;CAED,WAAW,EACT,UAAU,aAAa,EACrB,aAAa,QAAQ,UAAU,YAAY,UAC5C,GACF;CAED,SAAS;EACP,sBACE;EACF,qBACE;EACF,4BAA4B,YAAY;GACtC,MAAM,QAAQ,CACZ,sFACA,gKACD;AACD,OAAI,QAAQ,QACV,OAAM,KACJ,6HACD;AAEH,UAAO;;EAEV;CAED,IAAI;EACF,gBAAgB;EAChB,0BAA0B;EAC1B,kBAAkB,YAAY;GAC5B,iBACE,QAAQ,UAAU,YAAY,SAC/B;GACD;GACA;GACA;GACD;EACD,oBAAoB,YAAY;GAC9B,QAAQ,UACJ,4FACA;GACJ;GACA;GACA;GACD;EACF;CACF;;;AC5FD,SAAS,UAAU,YAAwC;CACzD,MAAM,YAAYC,OAAK,KAAK,YAAY,SAAS;AACjD,KAAI,CAACC,KAAG,WAAW,UAAU,CAC3B;AAEF,QAAOA,KAAG,aAAa,WAAW,QAAQ;;;AAI5C,SAAS,aAAa,YAAwC;AAE5D,QADc,UAAU,WAAW,EACrB,MAAM,kBAAkB,GAAG;;AAG3C,MAAa,kBAA8C;CACzD,UAAU;EACR,MAAM;EACN,aAAA;EACA,SAAS;EACT,gBAAgB,YAA8B;GAC5C,MAAM,YAAY,aAAa,QAAQ,WAAW;AAClD,UAAO,QAAQ,QAAQ,EAAE,WAAW,CAAC;;EAExC;CAED,WAAW;EACT,aAAa;EACb,oBAAoB;EACpB,iBAAiB;EACjB,kBAAkB,KAAA;EAGlB,SAAS,YAAY;GACnB,MAAM,QAAQ,UAAU,QAAQ,WAAW;AAC3C,UAAO,QAAQ,QAAQ,CAAC,CAAC,SAAS,iBAAiB,KAAK,MAAM,CAAC;;EAEjE,sBAAsB;EACvB;CAED,aAAa;EACX,iBAAiB;EACjB,aAAa,QAAgB,UAAkB;GAC7C,iBAAiB;GACjB,cAAc;GACf;EACF;CAED,WAAW,EACT,UAAU,aAAa,EACrB,WAAW,QAAQ,aAAa,WACjC,GACF;CAED,SAAS;EACP,sBACE;EACF,qBACE;EACF,4BAA4B,YAAY;GACtC,MAAM,QAAQ,CACZ,6EACD;AACD,OAAI,QAAQ,UACV,OAAM,KAAK,kCAAkC,QAAQ,YAAY;AAEnE,SAAM,KACJ,+HACD;AACD,UAAO;;EAEV;CAED,IAAI;EACF,gBAAgB;EAChB,0BAA0B;EAC1B,uBAAuB;GACrB;GACA;GACA;GACA;GACD;EACD,yBAAyB;GACvB;GACA;GACA;GACA;GACD;EACF;CACF;;;ACvFD,MAAM,eAAe;CACnB;CACA;CACA;CACA;CACD;AAED,MAAM,yBAAyB;CAC7B;CACA;CACA;CACD;AAED,MAAM,qBAAqB;CACzB;CACA;CACA;CACD;AAED,SAAS,oBAAoB,YAA8B;AACzD,QAAO,aAAa,KAAK,SAASC,OAAK,KAAK,YAAY,KAAK,CAAC,CAC3D,QAAQ,MAAMC,KAAG,WAAW,EAAE,CAAC,CAC/B,KAAK,MAAMA,KAAG,aAAa,GAAG,QAAQ,CAAC;;AAG5C,SAAS,aAAa,YAAoD;AACxE,KAAIA,KAAG,WAAWD,OAAK,KAAK,YAAY,UAAU,CAAC,CACjD,QAAO;AAET,KAAI,oBAAoB,WAAW,CAAC,SAAS,EAC3C,QAAO;;AAKX,MAAa,oBAAkD;CAC7D,UAAU;EACR,MAAM;EACN,aAAA;EACA,SAAS;EACT,gBAAgB,YAA8B;GAC5C,MAAM,YAAY,aAAa,QAAQ,WAAW;AAClD,UAAO,QAAQ,QAAQ,EAAE,WAAW,CAAC;;EAExC;CAED,WAAW;EACT,aAAa;EACb,oBAAoB;EACpB,iBAAiB;EACjB,kBAAkB,KAAA;EAKlB,QAAQ,OAAO,YAAY;GACzB,MAAM,EAAE,eAAe;AAGvB,OAAIC,KAAG,WAAWD,OAAK,KAAK,YAAY,eAAe,CAAC,CACtD,QAAO;AAGT,OAAIC,KAAG,WAAWD,OAAK,KAAK,YAAY,UAAU,CAAC,CACjD,QAAO;GAGT,MAAM,iBAAiB,oBAAoB,WAAW;AACtD,OAAI,eAAe,WAAW,EAC5B,QAAO;GAET,MAAM,WAAW,eAAe,KAAK,KAAK;AAC1C,OACE,CAAC,GAAG,wBAAwB,GAAG,mBAAmB,CAAC,MAAM,WACvD,SAAS,SAAS,OAAO,CAC1B,CAED,QAAO;AAOT,WAJsB,MAAM,GAAG,0BAA0B;IACvD,KAAK;IACL,QAAQ;KAAC;KAAe;KAAsB;KAAgB;IAC/D,CAAC,EACmB,WAAW;;EAElC,sBAAsB;EACvB;CAED,aAAa;EACX,iBAAiB;EACjB,aAAa,QAAgB,UAAkB;GAC7C,iBAAiB;GACjB,cAAc;GACf;EACF;CAED,WAAW,EACT,UAAU,aAAa,EACrB,WAAW,QAAQ,aAAa,WACjC,GACF;CAED,SAAS;EACP,sBACE;EACF,qBACE;EACF,4BAA4B,YAAY;GACtC,MAAM,QAAQ;IACZ;IACA;IACA;IACD;AACD,OAAI,QAAQ,UACV,OAAM,KAAK,eAAe,QAAQ,YAAY;AAEhD,UAAO;;EAEV;CAED,IAAI;EACF,gBAAgB;EAChB,0BAA0B;EAC1B,kBAAkB,YAAY;GAC5B;GACA,+CACE,QAAQ,cAAc,UAAU,YAAY;GAE9C;GACA;GACD;EACD,yBAAyB;GACvB;GACA;GACA;GACA;GACD;EACF;CACF;;;AC5ID,SAAS,cAAc,YAAwC;CAC7D,MAAM,gBAAgBE,OAAK,KAAK,YAAY,aAAa;AACzD,KAAI,CAACC,KAAG,WAAW,cAAc,CAC/B;AAEF,QAAOA,KAAG,aAAa,eAAe,QAAQ;;;AAIhD,SAAS,gBAAgB,YAA6B;CACpD,MAAM,YAAY,cAAc,WAAW;AAC3C,QAAO,CAAC,CAAC,aAAa,qCAAqC,KAAK,UAAU;;AAG5E,MAAa,oBAAkD;CAC7D,UAAU;EACR,MAAM;EACN,aAAA;EACA,SAAS;EACT,gBAAgB,YAA8B;GAC5C,MAAM,eAAe,gBAAgB,QAAQ,WAAW;AACxD,UAAO,QAAQ,QAAQ,EAAE,cAAc,CAAC;;EAE3C;CAED,WAAW;EACT,aAAa;EACb,oBAAoB;EACpB,iBAAiB;EACjB,kBAAkB,KAAA;EAIlB,SAAS,YAAY;GACnB,MAAM,YAAY,cAAc,QAAQ,WAAW;AACnD,UAAO,QAAQ,QAAQ,CAAC,CAAC,aAAa,mBAAmB,KAAK,UAAU,CAAC;;EAE3E,sBAAsB;EACvB;CAED,aAAa;EACX,iBAAiB;EACjB,aAAa,QAAgB,UAAkB;GAC7C,iBAAiB;GACjB,cAAc;GACf;EACF;CAED,WAAW,EACT,UAAU,aAAa,EACrB,cAAc,QAAQ,eAAe,SAAS,SAC/C,GACF;CAED,SAAS;EACP,sBACE;EACF,qBACE;EACF,4BAA4B,YAAY;GACtC,MAAM,QAAQ,CACZ,kFACA,8IACD;AACD,OAAI,QAAQ,aACV,OAAM,KACJ,yEACD;OAED,OAAM,KACJ,qHACD;AAEH,UAAO;;EAEV;CAED,IAAI;EACF,gBAAgB;EAChB,0BAA0B;EAC1B,uBAAuB;GACrB;GACA;GACA;GACA;GACD;EACD,yBAAyB;GACvB;GACA;GACA;GACA;GACD;EACF;CACF;;;ACpFD,MAAa,sBAAsD;CACjE,UAAU;EACR,MAAM;EACN,aAAA;EACA,SAAS;EACT,eAAe,OAAO,YAA8B;AAElD,UAAO,EAAE,gBADc,MAAMC,uBAAqB,QAAQ,EACjC;;EAE5B;CAED,WAAW;EACT,aAAa;EACb,oBAAoB;EACpB,iBAAiB;EACjB,kBAAkB,KAAA;EAClB,kBAAkB;EAClB,gBAAgB;EAChB,sBAAsB,YACpB,QAAQ,QAAQ,iBAAiB,QAAQ,CAAC;EAC5C,QAAQ,OAAO,YAAY;GACzB,MAAM,EAAE,eAAe;GAGvB,MAAM,oBAAoB,MAAM,GAC9B;IACE;IACA;IACA;IACA;IACD,EACD;IACE,KAAK;IACL,QAAQ;KAAC;KAAc;KAAe;KAAa;KAAa;IACjE,CACF;AAED,OAAI,kBAAkB,WAAW,EAC/B,QAAO;GAKT,MAAM,kBAAkB,MAAM,GAAG,gBAAgB;IAC/C,KAAK;IACL,QAAQ;KAAC;KAAc;KAAe;KAAa;KAAa;IACjE,CAAC;AAEF,QAAK,MAAM,SAAS,gBAClB,KAAI;IACF,MAAM,UAAUC,KAAG,aACjBC,OAAK,KAAK,YAAY,MAAM,EAC5B,QACD;AACD,QACE,QAAQ,SAAS,SAAS,IAC1B,QAAQ,SAAS,yBAAyB,CAE1C,QAAO;WAEH;AACN;;AAKJ,QAAK,MAAM,cAAc,kBACvB,KAAI;IACF,MAAM,UAAUD,KAAG,aACjBC,OAAK,KAAK,YAAY,WAAW,EACjC,QACD;AACD,QACE,yBAAyB,KAAK,QAAQ,IACtC,iBAAiB,KAAK,QAAQ,CAE9B,QAAO;WAEH;AACN;;GAIJ,MAAM,UAAU,MAAM,GACpB;IAAC;IAAa;IAAc;IAAqB;IAAiB,EAClE;IACE,KAAK;IACL,QAAQ;KACN;KACA;KACA;KACA;KACA;KACD;IACF,CACF;AAED,QAAK,MAAM,UAAU,QACnB,KAAI;IACF,MAAM,UAAUD,KAAG,aACjBC,OAAK,KAAK,YAAY,OAAO,EAC7B,QACD;AACD,QACE,QAAQ,SAAS,oBAAoB,IACrC,QAAQ,SAAS,eAAe,IAChC,aAAa,KAAK,QAAQ,CAE1B,QAAO;WAEH;AACN;;AAKJ,UAAO;;EAET,sBAAsB;EACvB;CAED,aAAa;EACX,iBAAiB;EACjB,aAAa,QAAgB,UAAkB;GAC7C,uBAAuB;GACvB,cAAc;GACf;EACF;CAED,WAAW,EACT,UAAU,YAAY;AAIpB,SAAO,EACL,gBAJyB,QAAQ,iBAC/BC,wBAAsB,QAAQ,eAAe,GAC7C,WAGH;IAEJ;CAED,SAAS;EACP,qBAAqB;EACrB,sBACE;EACF,4BAA4B,YAAY;AAKtC,UAAO;IACL,oBALyB,QAAQ,iBAC/BA,wBAAsB,QAAQ,eAAe,GAC7C;IAIF;IACA;IACD;;EAEJ;CAED,IAAI;EACF,gBAAgB;EAChB,0BAA0B;EAC1B,kBAAkB,YAAY;AAI5B,UAAO;IACL;IACA,8CALyB,QAAQ,iBAC/BA,wBAAsB,QAAQ,eAAe,GAC7C;IAIF;IACA;IACA;IACD;;EAEH,yBAAyB;GACvB;GACA;GACA;GACA;GACA;GACD;EACF;CACF;;;AC9LD,MAAM,eAAe,CAAC,aAAa,YAAY;;;;AAK/C,MAAa,uBAAuB,qBAAqB;;;;AAKzD,SAAgB,qBACd,SACoB;CACpB,MAAM,EAAE,eAAe;CAEvB,MAAM,cAAcC,OAAK,KAAK,YAAY,UAAU;AACpD,KAAIC,KAAG,WAAW,YAAY,CAC5B,QAAA;AAGF,QAAA;;;;;AAMF,SAAgB,sBACd,gBACQ;AACR,SAAQ,gBAAR;EACE,KAAA,UACE,QAAO;EACT,KAAA,SACE,QAAO;;;;;;AAOb,SAAgB,eACd,SACoB;CACpB,MAAM,EAAE,eAAe;CAGvB,MAAM,kBAAkBD,OAAK,KAAK,YAAY,gBAAgB;AAC9D,KAAI;EAGF,MAAM,UAFUC,KAAG,aAAa,iBAAiB,QAAQ,CAAC,MAAM,CAExC,QAAQ,UAAU,GAAG;AAC7C,MAAI,kBAAkB,KAAK,QAAQ,CACjC,QAAO;SAEH;CAKR,MAAM,cAAcD,OAAK,KAAK,YAAY,UAAU;AACpD,KAAI;EAEF,MAAM,QADUC,KAAG,aAAa,aAAa,QAAQ,CAC/B,MAAM,+CAA+C;AAC3E,MAAI,MACF,QAAO,MAAM;SAET;;;;;AAUV,eAAsB,cACpB,SACkB;CAClB,MAAM,EAAE,eAAe;CAGvB,MAAM,cAAcD,OAAK,KAAK,YAAY,UAAU;AACpD,KAAIC,KAAG,WAAW,YAAY,EAAE;AAE9B,MAAI;GACF,MAAM,UAAUA,KAAG,aAAa,aAAa,QAAQ;AACrD,OAAI,4BAA4B,KAAK,QAAQ,CAC3C,QAAO;UAEH;AAGR,SAAO;;CAIT,MAAM,kBAAkBD,OAAK,KAAK,YAAY,gBAAgB;AAC9D,KAAIC,KAAG,WAAW,gBAAgB,CAChC,QAAO;AAUT,MANqB,MAAM,YAAY,aAAa;EAClD,KAAK;EACL,aAAa;EACb,OAAO;EACR,CAAC,EAEe,SAAS,EACxB,QAAO;AAUT,SANkB,MAAM,YAAY;EAAC;EAAQ;EAAe;EAAc,EAAE;EAC1E,KAAK;EACL,aAAa;EACb,OAAO;EACR,CAAC,EAEe,SAAS;;;;ACjH5B,MAAa,oBAAkD;CAC7D,UAAU;EACR,MAAM;EACN,aAAA;EACA,SAAS;EACT,gBAAgB,YAA8B;GAC5C,MAAM,iBAAiB,qBAAqB,QAAQ;AACpD,UAAO,QAAQ,QAAQ,EAAE,gBAAgB,CAAC;;EAE7C;CAED,WAAW;EACT,aAAa;EACb,oBAAoB;EACpB,iBAAiB;EACjB,kBAAkB,KAAA;EAClB,kBAAkB;EAClB,gBAAgB;EAChB,sBAAsB,YACpB,QAAQ,QAAQ,eAAe,QAAQ,CAAC;EAC1C,QAAQ,OAAO,YAAY,cAAc,QAAQ;EACjD,sBAAsB;EACvB;CAED,aAAa;EACX,iBAAiB;EACjB,aAAa,QAAgB,UAAkB;GAC7C,uBAAuB;GACvB,cAAc;GACf;EACF;CAED,WAAW,EACT,UAAU,YAAY;AAIpB,SAAO,EACL,gBAJyB,QAAQ,iBAC/B,sBAAsB,QAAQ,eAAe,GAC7C,WAGH;IAEJ;CAED,SAAS;EACP,sBACE;EACF,qBACE;EACF,4BAA4B,YAAY;AA0CtC,UArCc;IACZ,oBALyB,QAAQ,iBAC/B,sBAAsB,QAAQ,eAAe,GAC7C;IAIF;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACD;;EAIJ;CAED,IAAI;EACF,gBAAgB;EAChB,0BAA0B;EAC1B,kBAAkB,YAAY;AAI5B,UAAO;IACL;IACA,wCALyB,QAAQ,iBAC/B,sBAAsB,QAAQ,eAAe,GAC7C;IAIF;IACA;IACD;;EAEH,yBAAyB;GACvB;GACA;GACA;GACD;EACF;CACF;;;AC5HD,MAAa,+BACX;CACE,UAAU;EACR,MAAM;EACN,aAAA;EACA,SAAS;EACV;CAED,WAAW;EACT,aAAa;EACb,oBAAoB;EACpB,iBAAiB;EACjB,kBAAkB,KAAA;EAClB,sBAAsB;EACtB,QAAQ,OAAO,YAAY;AAEzB,UAAO,CAAC,CADY,MAAM,kBAAkB,QAAQ;;EAGvD;CAED,aAAa;EACX,iBAAiB;EACjB,aAAa,QAAgB,UAAkB;GAC7C,uBAAuB;GACvB,cAAc;GACf;EACF;CAED,WAAW,EACT,gBAAgB,EAAE,GACnB;CAED,SAAS;EACP,sBACE;EACF,qBACE;EACF,iCAAiC,CAC/B,uGACD;EACF;CAED,IAAI;EACF,gBAAgB;EAChB,0BAA0B;EAC1B,uBAAuB;GACrB;GACA;GACA;GACA;GACA;GACD;EACD,yBAAyB;GACvB;GACA;GACA;GACA;GACA;GACD;EACF;CACF;;;ACxDH,MAAM,uBAAuB;;;;;;;;AAS7B,MAAa,qBAAqB;CAChC;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACD;;;;;AAMD,SAAgB,uBACd,SACQ;CACR,MAAM,WAAW,yBAAyB,QAAQ;AAClD,KAAI,SAAS,SAAS,EACpB,QAAO,SAAS,GAAG;AAErB,QAAO;;;;;AAMT,SAAgB,cACd,SACoB;AACpB,KAAI;EACF,MAAM,UAAUC,KAAG,aACjBC,OAAK,KAAK,QAAQ,YAAY,eAAe,EAC7C,QACD;EACD,MAAM,MAAM,KAAK,MAAM,QAAQ;EAC/B,MAAM,UAAkC;GACtC,GAAG,IAAI;GACP,GAAG,IAAI;GACR;AAED,MAAI,QAAQ,QAAS,QAAO;AAC5B,MAAI,QAAQ,WAAY,QAAO;AAC/B,MAAI,QAAQ,WAAY,QAAO;AAC/B,MAAI,QAAQ,UAAW,QAAO;AAC9B,MAAI,QAAQ,UAAW,QAAO;AAC9B;SACM;AACN;;;;;;;AAQJ,eAAsB,aACpB,SACkB;AAOlB,SANgB,MAAM,YAAY,iBAAiB;EACjD,KAAK,QAAQ;EACb,MAAM;EACN,OAAO;EACR,CAAC,EAEa,SAAS;;;;ACxE1B,MAAa,8BAAkE;CAC7E,UAAU;EACR,MAAM;EACN,aAAA;EACA,SAAS;EACT,gBAAgB,YAA8B;GAC5C,MAAM,qBAAqB,uBAAuB,QAAQ;GAC1D,MAAM,gBAAgBC,KAAG,WACvBC,OAAK,KAAK,QAAQ,YAAY,gBAAgB,CAC/C;GACD,MAAM,aAAa,cAAc,QAAQ;AACzC,UAAO,QAAQ,QAAQ;IAAE;IAAoB;IAAe;IAAY,CAAC;;EAE5E;CAED,WAAW;EACT,aAAa;EACb,oBAAoB;EACpB,iBAAiB;EACjB,kBAAkB,KAAA;EAClB,sBAAsB;EACtB,QAAQ,OAAO,YAAY;GACzB,MAAM,cAAc,MAAM,kBAAkB,QAAQ;AACpD,OAAI,CAAC,YACH,QAAO;AAIT,QAAK,MAAM,gBAAgB,mBACzB,KAAI,sBAAsB,cAAc,YAAY,CAClD,QAAO;GAIX,MAAM,EAAE,eAAe;GAGvB,MAAM,mBAAmB,MAAM,aAAa,QAAQ;GAGpD,MAAM,aAAa,CAAC,CADJ,cAAc,QAAQ;AAetC,OAZoB;IAClB;IACA;IACA;IACA;IACA;IACA;IACD,CAAC,MAAM,aAAaD,KAAG,WAAWC,OAAK,KAAK,YAAY,SAAS,CAAC,CAAC,KAKhD,oBAAoB,YACtC,QAAO;AAIT,UAAO;;EAEV;CAED,aAAa;EACX,iBAAiB;EACjB,aAAa,QAAgB,UAAkB;GAC7C,uBAAuB;GACvB,cAAc;GACf;EACF;CAED,WAAW,EACT,UAAU,YAAY;EACpB,MAAM,OAA+B,EACnC,gBAAgB,QAAQ,sBAAsB,WAC/C;AACD,MAAI,QAAQ,WACV,MAAK,UAAU,QAAQ;AAEzB,SAAO;IAEV;CAED,SAAS;EACP,sBACE;EACF,qBACE;EACF,4BAA4B,YAAY;GACtC,MAAM,QAAQ;IACZ,oBAAoB,QAAQ,sBAAsB;IAClD,mBAAmB,QAAQ,gBAAgB,QAAQ;IACnD;IACA;IACD;AAED,OAAI,QAAQ,WACV,OAAM,QAAQ,YAAY,QAAQ,aAAa;AAGjD,UAAO;;EAEV;CAED,IAAI;EACF,gBAAgB;EAChB,0BAA0B;EAC1B,kBAAkB,YAAY;AAG5B,UAAO;IACL;IACA,0CAHA,QAAQ,sBAAsB;IAI9B;IACA;IACD;;EAEH,yBAAyB;GACvB;GACA;GACA;GACA;GACA;GACD;EACF;CACF;;;;AChHD,MAAa,qBAA2D;aAChD;WACF;UACD;qBACU;mBACF;sBACG;mBACH;cACJ;YACF;aACC;YACD;cACE;cACA;gBACE;cACF;UACJ;YACE;cACE;YACF;aACC;SACJ;WACE;WACA;aACE;WACF;sBACU;qBACA;CAC/B"}