@posthog/wizard 2.9.1 → 2.10.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +40 -0
- package/dist/McpScreen-BmHapIaP.js +3357 -0
- package/dist/McpScreen-BmHapIaP.js.map +1 -0
- package/dist/add-mcp-server-to-clients-DZtISNrs.js +455 -0
- package/dist/add-mcp-server-to-clients-DZtISNrs.js.map +1 -0
- package/dist/agent-runner-CGwrcr57.js +1112 -0
- package/dist/agent-runner-CGwrcr57.js.map +1 -0
- package/dist/agent-skill-BVjJqol6.js +59 -0
- package/dist/agent-skill-BVjJqol6.js.map +1 -0
- package/dist/analytics-C4jO5Qda.js +207 -0
- package/dist/analytics-C4jO5Qda.js.map +1 -0
- package/dist/analytics-CpjaBpx6.js +2 -0
- package/dist/bin.d.ts +1 -2
- package/dist/bin.js +635 -521
- package/dist/bin.js.map +1 -1
- package/dist/craft-pre-release.sh +10 -0
- package/dist/debug-CIyf0ZGx.js +2 -0
- package/dist/debug-CyJ_3dTP.js +201 -0
- package/dist/debug-CyJ_3dTP.js.map +1 -0
- package/dist/defaults-DoVkE0gW.js +234 -0
- package/dist/defaults-DoVkE0gW.js.map +1 -0
- package/dist/detection-CkLpxBCD.js +122 -0
- package/dist/detection-CkLpxBCD.js.map +1 -0
- package/dist/env-api-key-K8TdTDII.js +20 -0
- package/dist/env-api-key-K8TdTDII.js.map +1 -0
- package/dist/file-utils-BWneZy6p.js +38 -0
- package/dist/file-utils-BWneZy6p.js.map +1 -0
- package/dist/generate-version.cjs +11 -0
- package/dist/package-json-BQgl5C3Z.js +2 -0
- package/dist/package-json-Ctq6LSl8.js +25 -0
- package/dist/package-json-Ctq6LSl8.js.map +1 -0
- package/dist/package-manager-nUQ-ebjr.js +222 -0
- package/dist/package-manager-nUQ-ebjr.js.map +1 -0
- package/dist/posthog-integration-BzxdDK4z.js +230 -0
- package/dist/posthog-integration-BzxdDK4z.js.map +1 -0
- package/dist/readiness-Dn7eq8NE.js +2156 -0
- package/dist/readiness-Dn7eq8NE.js.map +1 -0
- package/dist/registry-s55_iuJT.js +2922 -0
- package/dist/registry-s55_iuJT.js.map +1 -0
- package/dist/rolldown-runtime-B_-DWIq7.js +15 -0
- package/dist/router-D5A1Sb4p.js +141 -0
- package/dist/router-D5A1Sb4p.js.map +1 -0
- package/dist/setup-utils-CdDnllRW.js +928 -0
- package/dist/setup-utils-CdDnllRW.js.map +1 -0
- package/dist/smoke-test-ci.sh +165 -0
- package/dist/start-playground-B8qCLu7U.js +1005 -0
- package/dist/start-playground-B8qCLu7U.js.map +1 -0
- package/dist/start-tui-PygiIyNC.js +1887 -0
- package/dist/start-tui-PygiIyNC.js.map +1 -0
- package/dist/steps-CySv8XdD.js +146 -0
- package/dist/steps-CySv8XdD.js.map +1 -0
- package/dist/telemetry-Ct_GGkSO.js +13 -0
- package/dist/telemetry-Ct_GGkSO.js.map +1 -0
- package/dist/wizard-abort-7HUIsqv1.js +39 -0
- package/dist/wizard-abort-7HUIsqv1.js.map +1 -0
- package/dist/wizard-abort-Dhjb2o08.js +2 -0
- package/dist/wizard-session-Db6R023m.js +62 -0
- package/dist/wizard-session-Db6R023m.js.map +1 -0
- package/dist/wizard-session-y7nf6aKH.js +2 -0
- package/npm-shrinkwrap.json +2 -2
- package/package.json +16 -8
- package/dist/src/__tests__/cli.test.d.ts +0 -1
- package/dist/src/__tests__/cli.test.js +0 -256
- package/dist/src/__tests__/cli.test.js.map +0 -1
- package/dist/src/__tests__/package-json.test.d.ts +0 -1
- package/dist/src/__tests__/package-json.test.js +0 -173
- package/dist/src/__tests__/package-json.test.js.map +0 -1
- package/dist/src/__tests__/wizard-abort.test.d.ts +0 -1
- package/dist/src/__tests__/wizard-abort.test.js +0 -148
- package/dist/src/__tests__/wizard-abort.test.js.map +0 -1
- package/dist/src/frameworks/android/android-wizard-agent.d.ts +0 -6
- package/dist/src/frameworks/android/android-wizard-agent.js +0 -142
- package/dist/src/frameworks/android/android-wizard-agent.js.map +0 -1
- package/dist/src/frameworks/android/utils.d.ts +0 -11
- package/dist/src/frameworks/android/utils.js +0 -97
- package/dist/src/frameworks/android/utils.js.map +0 -1
- package/dist/src/frameworks/angular/angular-wizard-agent.d.ts +0 -4
- package/dist/src/frameworks/angular/angular-wizard-agent.js +0 -65
- package/dist/src/frameworks/angular/angular-wizard-agent.js.map +0 -1
- package/dist/src/frameworks/angular/utils.d.ts +0 -4
- package/dist/src/frameworks/angular/utils.js +0 -9
- package/dist/src/frameworks/angular/utils.js.map +0 -1
- package/dist/src/frameworks/astro/astro-wizard-agent.d.ts +0 -7
- package/dist/src/frameworks/astro/astro-wizard-agent.js +0 -102
- package/dist/src/frameworks/astro/astro-wizard-agent.js.map +0 -1
- package/dist/src/frameworks/astro/utils.d.ts +0 -14
- package/dist/src/frameworks/astro/utils.js +0 -114
- package/dist/src/frameworks/astro/utils.js.map +0 -1
- package/dist/src/frameworks/django/django-wizard-agent.d.ts +0 -8
- package/dist/src/frameworks/django/django-wizard-agent.js +0 -173
- package/dist/src/frameworks/django/django-wizard-agent.js.map +0 -1
- package/dist/src/frameworks/django/utils.d.ts +0 -31
- package/dist/src/frameworks/django/utils.js +0 -306
- package/dist/src/frameworks/django/utils.js.map +0 -1
- package/dist/src/frameworks/fastapi/fastapi-wizard-agent.d.ts +0 -5
- package/dist/src/frameworks/fastapi/fastapi-wizard-agent.js +0 -191
- package/dist/src/frameworks/fastapi/fastapi-wizard-agent.js.map +0 -1
- package/dist/src/frameworks/fastapi/utils.d.ts +0 -26
- package/dist/src/frameworks/fastapi/utils.js +0 -258
- package/dist/src/frameworks/fastapi/utils.js.map +0 -1
- package/dist/src/frameworks/flask/flask-wizard-agent.d.ts +0 -8
- package/dist/src/frameworks/flask/flask-wizard-agent.js +0 -179
- package/dist/src/frameworks/flask/flask-wizard-agent.js.map +0 -1
- package/dist/src/frameworks/flask/utils.d.ts +0 -28
- package/dist/src/frameworks/flask/utils.js +0 -344
- package/dist/src/frameworks/flask/utils.js.map +0 -1
- package/dist/src/frameworks/javascript-node/javascript-node-wizard-agent.d.ts +0 -4
- package/dist/src/frameworks/javascript-node/javascript-node-wizard-agent.js +0 -61
- package/dist/src/frameworks/javascript-node/javascript-node-wizard-agent.js.map +0 -1
- package/dist/src/frameworks/javascript-web/javascript-web-wizard-agent.d.ts +0 -3
- package/dist/src/frameworks/javascript-web/javascript-web-wizard-agent.js +0 -152
- package/dist/src/frameworks/javascript-web/javascript-web-wizard-agent.js.map +0 -1
- package/dist/src/frameworks/javascript-web/utils.d.ts +0 -28
- package/dist/src/frameworks/javascript-web/utils.js +0 -147
- package/dist/src/frameworks/javascript-web/utils.js.map +0 -1
- package/dist/src/frameworks/laravel/laravel-wizard-agent.d.ts +0 -10
- package/dist/src/frameworks/laravel/laravel-wizard-agent.js +0 -182
- package/dist/src/frameworks/laravel/laravel-wizard-agent.js.map +0 -1
- package/dist/src/frameworks/laravel/utils.d.ts +0 -38
- package/dist/src/frameworks/laravel/utils.js +0 -238
- package/dist/src/frameworks/laravel/utils.js.map +0 -1
- package/dist/src/frameworks/nextjs/nextjs-wizard-agent.d.ts +0 -7
- package/dist/src/frameworks/nextjs/nextjs-wizard-agent.js +0 -94
- package/dist/src/frameworks/nextjs/nextjs-wizard-agent.js.map +0 -1
- package/dist/src/frameworks/nextjs/utils.d.ts +0 -12
- package/dist/src/frameworks/nextjs/utils.js +0 -52
- package/dist/src/frameworks/nextjs/utils.js.map +0 -1
- package/dist/src/frameworks/nuxt/nuxt-wizard-agent.d.ts +0 -6
- package/dist/src/frameworks/nuxt/nuxt-wizard-agent.js +0 -77
- package/dist/src/frameworks/nuxt/nuxt-wizard-agent.js.map +0 -1
- package/dist/src/frameworks/python/python-wizard-agent.d.ts +0 -7
- package/dist/src/frameworks/python/python-wizard-agent.js +0 -195
- package/dist/src/frameworks/python/python-wizard-agent.js.map +0 -1
- package/dist/src/frameworks/python/utils.d.ts +0 -28
- package/dist/src/frameworks/python/utils.js +0 -147
- package/dist/src/frameworks/python/utils.js.map +0 -1
- package/dist/src/frameworks/rails/rails-wizard-agent.d.ts +0 -8
- package/dist/src/frameworks/rails/rails-wizard-agent.js +0 -90
- package/dist/src/frameworks/rails/rails-wizard-agent.js.map +0 -1
- package/dist/src/frameworks/rails/utils.d.ts +0 -37
- package/dist/src/frameworks/rails/utils.js +0 -187
- package/dist/src/frameworks/rails/utils.js.map +0 -1
- package/dist/src/frameworks/react-native/react-native-wizard-agent.d.ts +0 -7
- package/dist/src/frameworks/react-native/react-native-wizard-agent.js +0 -89
- package/dist/src/frameworks/react-native/react-native-wizard-agent.js.map +0 -1
- package/dist/src/frameworks/react-native/utils.d.ts +0 -8
- package/dist/src/frameworks/react-native/utils.js +0 -28
- package/dist/src/frameworks/react-native/utils.js.map +0 -1
- package/dist/src/frameworks/react-router/react-router-wizard-agent.d.ts +0 -7
- package/dist/src/frameworks/react-router/react-router-wizard-agent.js +0 -94
- package/dist/src/frameworks/react-router/react-router-wizard-agent.js.map +0 -1
- package/dist/src/frameworks/react-router/utils.d.ts +0 -13
- package/dist/src/frameworks/react-router/utils.js +0 -161
- package/dist/src/frameworks/react-router/utils.js.map +0 -1
- package/dist/src/frameworks/ruby/ruby-wizard-agent.d.ts +0 -7
- package/dist/src/frameworks/ruby/ruby-wizard-agent.js +0 -113
- package/dist/src/frameworks/ruby/ruby-wizard-agent.js.map +0 -1
- package/dist/src/frameworks/ruby/utils.d.ts +0 -25
- package/dist/src/frameworks/ruby/utils.js +0 -158
- package/dist/src/frameworks/ruby/utils.js.map +0 -1
- package/dist/src/frameworks/svelte/svelte-wizard-agent.d.ts +0 -4
- package/dist/src/frameworks/svelte/svelte-wizard-agent.js +0 -61
- package/dist/src/frameworks/svelte/svelte-wizard-agent.js.map +0 -1
- package/dist/src/frameworks/swift/swift-wizard-agent.d.ts +0 -7
- package/dist/src/frameworks/swift/swift-wizard-agent.js +0 -143
- package/dist/src/frameworks/swift/swift-wizard-agent.js.map +0 -1
- package/dist/src/frameworks/swift/utils.d.ts +0 -8
- package/dist/src/frameworks/swift/utils.js +0 -105
- package/dist/src/frameworks/swift/utils.js.map +0 -1
- package/dist/src/frameworks/tanstack-router/tanstack-router-wizard-agent.d.ts +0 -7
- package/dist/src/frameworks/tanstack-router/tanstack-router-wizard-agent.js +0 -96
- package/dist/src/frameworks/tanstack-router/tanstack-router-wizard-agent.js.map +0 -1
- package/dist/src/frameworks/tanstack-router/utils.d.ts +0 -11
- package/dist/src/frameworks/tanstack-router/utils.js +0 -149
- package/dist/src/frameworks/tanstack-router/utils.js.map +0 -1
- package/dist/src/frameworks/tanstack-start/tanstack-start-wizard-agent.d.ts +0 -4
- package/dist/src/frameworks/tanstack-start/tanstack-start-wizard-agent.js +0 -64
- package/dist/src/frameworks/tanstack-start/tanstack-start-wizard-agent.js.map +0 -1
- package/dist/src/frameworks/tanstack-start/utils.d.ts +0 -4
- package/dist/src/frameworks/tanstack-start/utils.js +0 -9
- package/dist/src/frameworks/tanstack-start/utils.js.map +0 -1
- package/dist/src/frameworks/vue/vue-wizard-agent.d.ts +0 -4
- package/dist/src/frameworks/vue/vue-wizard-agent.js +0 -62
- package/dist/src/frameworks/vue/vue-wizard-agent.js.map +0 -1
- package/dist/src/lib/__tests__/agent-interface.test.d.ts +0 -1
- package/dist/src/lib/__tests__/agent-interface.test.js +0 -317
- package/dist/src/lib/__tests__/agent-interface.test.js.map +0 -1
- package/dist/src/lib/__tests__/cloudflare-detection.test.d.ts +0 -1
- package/dist/src/lib/__tests__/cloudflare-detection.test.js +0 -119
- package/dist/src/lib/__tests__/cloudflare-detection.test.js.map +0 -1
- package/dist/src/lib/__tests__/wizard-tools.test.d.ts +0 -1
- package/dist/src/lib/__tests__/wizard-tools.test.js +0 -200
- package/dist/src/lib/__tests__/wizard-tools.test.js.map +0 -1
- package/dist/src/lib/__tests__/yara-hooks.test.d.ts +0 -1
- package/dist/src/lib/__tests__/yara-hooks.test.js +0 -432
- package/dist/src/lib/__tests__/yara-hooks.test.js.map +0 -1
- package/dist/src/lib/__tests__/yara-scanner.test.d.ts +0 -1
- package/dist/src/lib/__tests__/yara-scanner.test.js +0 -613
- package/dist/src/lib/__tests__/yara-scanner.test.js.map +0 -1
- package/dist/src/lib/agent/__tests__/agent-prompt.test.d.ts +0 -1
- package/dist/src/lib/agent/__tests__/agent-prompt.test.js +0 -57
- package/dist/src/lib/agent/__tests__/agent-prompt.test.js.map +0 -1
- package/dist/src/lib/agent/agent-interface.d.ts +0 -171
- package/dist/src/lib/agent/agent-interface.js +0 -1082
- package/dist/src/lib/agent/agent-interface.js.map +0 -1
- package/dist/src/lib/agent/agent-prompt.d.ts +0 -23
- package/dist/src/lib/agent/agent-prompt.js +0 -47
- package/dist/src/lib/agent/agent-prompt.js.map +0 -1
- package/dist/src/lib/agent/agent-runner.d.ts +0 -78
- package/dist/src/lib/agent/agent-runner.js +0 -325
- package/dist/src/lib/agent/agent-runner.js.map +0 -1
- package/dist/src/lib/agent/commandments.d.ts +0 -1
- package/dist/src/lib/agent/commandments.js +0 -26
- package/dist/src/lib/agent/commandments.js.map +0 -1
- package/dist/src/lib/api.d.ts +0 -75
- package/dist/src/lib/api.js +0 -105
- package/dist/src/lib/api.js.map +0 -1
- package/dist/src/lib/cloudflare-detection.d.ts +0 -14
- package/dist/src/lib/cloudflare-detection.js +0 -74
- package/dist/src/lib/cloudflare-detection.js.map +0 -1
- package/dist/src/lib/constants.d.ts +0 -74
- package/dist/src/lib/constants.js +0 -98
- package/dist/src/lib/constants.js.map +0 -1
- package/dist/src/lib/detection/__tests__/context.test.d.ts +0 -1
- package/dist/src/lib/detection/__tests__/context.test.js +0 -72
- package/dist/src/lib/detection/__tests__/context.test.js.map +0 -1
- package/dist/src/lib/detection/__tests__/features.test.d.ts +0 -1
- package/dist/src/lib/detection/__tests__/features.test.js +0 -75
- package/dist/src/lib/detection/__tests__/features.test.js.map +0 -1
- package/dist/src/lib/detection/__tests__/package-manager.test.d.ts +0 -1
- package/dist/src/lib/detection/__tests__/package-manager.test.js +0 -195
- package/dist/src/lib/detection/__tests__/package-manager.test.js.map +0 -1
- package/dist/src/lib/detection/context.d.ts +0 -31
- package/dist/src/lib/detection/context.js +0 -92
- package/dist/src/lib/detection/context.js.map +0 -1
- package/dist/src/lib/detection/features.d.ts +0 -16
- package/dist/src/lib/detection/features.js +0 -56
- package/dist/src/lib/detection/features.js.map +0 -1
- package/dist/src/lib/detection/framework.d.ts +0 -14
- package/dist/src/lib/detection/framework.js +0 -35
- package/dist/src/lib/detection/framework.js.map +0 -1
- package/dist/src/lib/detection/index.d.ts +0 -3
- package/dist/src/lib/detection/index.js +0 -11
- package/dist/src/lib/detection/index.js.map +0 -1
- package/dist/src/lib/detection/package-manager.d.ts +0 -37
- package/dist/src/lib/detection/package-manager.js +0 -183
- package/dist/src/lib/detection/package-manager.js.map +0 -1
- package/dist/src/lib/framework-config.d.ts +0 -175
- package/dist/src/lib/framework-config.js +0 -22
- package/dist/src/lib/framework-config.js.map +0 -1
- package/dist/src/lib/health-checks/__tests__/health-checks.test.d.ts +0 -18
- package/dist/src/lib/health-checks/__tests__/health-checks.test.js +0 -759
- package/dist/src/lib/health-checks/__tests__/health-checks.test.js.map +0 -1
- package/dist/src/lib/health-checks/endpoints.d.ts +0 -4
- package/dist/src/lib/health-checks/endpoints.js +0 -49
- package/dist/src/lib/health-checks/endpoints.js.map +0 -1
- package/dist/src/lib/health-checks/index.d.ts +0 -4
- package/dist/src/lib/health-checks/index.js +0 -24
- package/dist/src/lib/health-checks/index.js.map +0 -1
- package/dist/src/lib/health-checks/readiness.d.ts +0 -29
- package/dist/src/lib/health-checks/readiness.js +0 -188
- package/dist/src/lib/health-checks/readiness.js.map +0 -1
- package/dist/src/lib/health-checks/statuspage.d.ts +0 -9
- package/dist/src/lib/health-checks/statuspage.js +0 -105
- package/dist/src/lib/health-checks/statuspage.js.map +0 -1
- package/dist/src/lib/health-checks/types.d.ts +0 -32
- package/dist/src/lib/health-checks/types.js +0 -10
- package/dist/src/lib/health-checks/types.js.map +0 -1
- package/dist/src/lib/helper-functions.d.ts +0 -1
- package/dist/src/lib/helper-functions.js +0 -6
- package/dist/src/lib/helper-functions.js.map +0 -1
- package/dist/src/lib/middleware/benchmark.d.ts +0 -54
- package/dist/src/lib/middleware/benchmark.js +0 -45
- package/dist/src/lib/middleware/benchmark.js.map +0 -1
- package/dist/src/lib/middleware/benchmarks/cache-tracker.d.ts +0 -44
- package/dist/src/lib/middleware/benchmarks/cache-tracker.js +0 -81
- package/dist/src/lib/middleware/benchmarks/cache-tracker.js.map +0 -1
- package/dist/src/lib/middleware/benchmarks/compaction-tracker.d.ts +0 -29
- package/dist/src/lib/middleware/benchmarks/compaction-tracker.js +0 -60
- package/dist/src/lib/middleware/benchmarks/compaction-tracker.js.map +0 -1
- package/dist/src/lib/middleware/benchmarks/context-size-tracker.d.ts +0 -26
- package/dist/src/lib/middleware/benchmarks/context-size-tracker.js +0 -56
- package/dist/src/lib/middleware/benchmarks/context-size-tracker.js.map +0 -1
- package/dist/src/lib/middleware/benchmarks/cost-tracker.d.ts +0 -16
- package/dist/src/lib/middleware/benchmarks/cost-tracker.js +0 -76
- package/dist/src/lib/middleware/benchmarks/cost-tracker.js.map +0 -1
- package/dist/src/lib/middleware/benchmarks/duration-tracker.d.ts +0 -20
- package/dist/src/lib/middleware/benchmarks/duration-tracker.js +0 -40
- package/dist/src/lib/middleware/benchmarks/duration-tracker.js.map +0 -1
- package/dist/src/lib/middleware/benchmarks/index.d.ts +0 -9
- package/dist/src/lib/middleware/benchmarks/index.js +0 -60
- package/dist/src/lib/middleware/benchmarks/index.js.map +0 -1
- package/dist/src/lib/middleware/benchmarks/json-writer.d.ts +0 -15
- package/dist/src/lib/middleware/benchmarks/json-writer.js +0 -144
- package/dist/src/lib/middleware/benchmarks/json-writer.js.map +0 -1
- package/dist/src/lib/middleware/benchmarks/summary.d.ts +0 -9
- package/dist/src/lib/middleware/benchmarks/summary.js +0 -102
- package/dist/src/lib/middleware/benchmarks/summary.js.map +0 -1
- package/dist/src/lib/middleware/benchmarks/token-tracker.d.ts +0 -40
- package/dist/src/lib/middleware/benchmarks/token-tracker.js +0 -77
- package/dist/src/lib/middleware/benchmarks/token-tracker.js.map +0 -1
- package/dist/src/lib/middleware/benchmarks/turn-counter.d.ts +0 -34
- package/dist/src/lib/middleware/benchmarks/turn-counter.js +0 -59
- package/dist/src/lib/middleware/benchmarks/turn-counter.js.map +0 -1
- package/dist/src/lib/middleware/config.d.ts +0 -24
- package/dist/src/lib/middleware/config.js +0 -78
- package/dist/src/lib/middleware/config.js.map +0 -1
- package/dist/src/lib/middleware/index.d.ts +0 -11
- package/dist/src/lib/middleware/index.js +0 -18
- package/dist/src/lib/middleware/index.js.map +0 -1
- package/dist/src/lib/middleware/phase-detector.d.ts +0 -7
- package/dist/src/lib/middleware/phase-detector.js +0 -64
- package/dist/src/lib/middleware/phase-detector.js.map +0 -1
- package/dist/src/lib/middleware/pipeline.d.ts +0 -29
- package/dist/src/lib/middleware/pipeline.js +0 -82
- package/dist/src/lib/middleware/pipeline.js.map +0 -1
- package/dist/src/lib/middleware/types.d.ts +0 -40
- package/dist/src/lib/middleware/types.js +0 -9
- package/dist/src/lib/middleware/types.js.map +0 -1
- package/dist/src/lib/registry.d.ts +0 -3
- package/dist/src/lib/registry.js +0 -49
- package/dist/src/lib/registry.js.map +0 -1
- package/dist/src/lib/safe-tools.d.ts +0 -2
- package/dist/src/lib/safe-tools.js +0 -215
- package/dist/src/lib/safe-tools.js.map +0 -1
- package/dist/src/lib/skill-install.d.ts +0 -10
- package/dist/src/lib/skill-install.js +0 -23
- package/dist/src/lib/skill-install.js.map +0 -1
- package/dist/src/lib/version.d.ts +0 -1
- package/dist/src/lib/version.js +0 -6
- package/dist/src/lib/version.js.map +0 -1
- package/dist/src/lib/wizard-session.d.ts +0 -146
- package/dist/src/lib/wizard-session.js +0 -116
- package/dist/src/lib/wizard-session.js.map +0 -1
- package/dist/src/lib/wizard-tools.d.ts +0 -91
- package/dist/src/lib/wizard-tools.js +0 -389
- package/dist/src/lib/wizard-tools.js.map +0 -1
- package/dist/src/lib/workflows/__tests__/agent-skill.test.d.ts +0 -1
- package/dist/src/lib/workflows/__tests__/agent-skill.test.js +0 -73
- package/dist/src/lib/workflows/__tests__/agent-skill.test.js.map +0 -1
- package/dist/src/lib/workflows/__tests__/revenue-analytics-detect.test.d.ts +0 -1
- package/dist/src/lib/workflows/__tests__/revenue-analytics-detect.test.js +0 -101
- package/dist/src/lib/workflows/__tests__/revenue-analytics-detect.test.js.map +0 -1
- package/dist/src/lib/workflows/__tests__/workflow-registry.test.d.ts +0 -1
- package/dist/src/lib/workflows/__tests__/workflow-registry.test.js +0 -32
- package/dist/src/lib/workflows/__tests__/workflow-registry.test.js.map +0 -1
- package/dist/src/lib/workflows/__tests__/workflow-step.test.d.ts +0 -1
- package/dist/src/lib/workflows/__tests__/workflow-step.test.js +0 -54
- package/dist/src/lib/workflows/__tests__/workflow-step.test.js.map +0 -1
- package/dist/src/lib/workflows/agent-skill/index.d.ts +0 -44
- package/dist/src/lib/workflows/agent-skill/index.js +0 -47
- package/dist/src/lib/workflows/agent-skill/index.js.map +0 -1
- package/dist/src/lib/workflows/agent-skill/steps.d.ts +0 -8
- package/dist/src/lib/workflows/agent-skill/steps.js +0 -43
- package/dist/src/lib/workflows/agent-skill/steps.js.map +0 -1
- package/dist/src/lib/workflows/posthog-integration/detect.d.ts +0 -12
- package/dist/src/lib/workflows/posthog-integration/detect.js +0 -57
- package/dist/src/lib/workflows/posthog-integration/detect.js.map +0 -1
- package/dist/src/lib/workflows/posthog-integration/index.d.ts +0 -3
- package/dist/src/lib/workflows/posthog-integration/index.js +0 -152
- package/dist/src/lib/workflows/posthog-integration/index.js.map +0 -1
- package/dist/src/lib/workflows/posthog-integration/steps.d.ts +0 -9
- package/dist/src/lib/workflows/posthog-integration/steps.js +0 -100
- package/dist/src/lib/workflows/posthog-integration/steps.js.map +0 -1
- package/dist/src/lib/workflows/revenue-analytics/detect.d.ts +0 -40
- package/dist/src/lib/workflows/revenue-analytics/detect.js +0 -156
- package/dist/src/lib/workflows/revenue-analytics/detect.js.map +0 -1
- package/dist/src/lib/workflows/revenue-analytics/index.d.ts +0 -4
- package/dist/src/lib/workflows/revenue-analytics/index.js +0 -30
- package/dist/src/lib/workflows/revenue-analytics/index.js.map +0 -1
- package/dist/src/lib/workflows/revenue-analytics/steps.d.ts +0 -8
- package/dist/src/lib/workflows/revenue-analytics/steps.js +0 -53
- package/dist/src/lib/workflows/revenue-analytics/steps.js.map +0 -1
- package/dist/src/lib/workflows/workflow-registry.d.ts +0 -18
- package/dist/src/lib/workflows/workflow-registry.js +0 -32
- package/dist/src/lib/workflows/workflow-registry.js.map +0 -1
- package/dist/src/lib/workflows/workflow-step.d.ts +0 -126
- package/dist/src/lib/workflows/workflow-step.js +0 -28
- package/dist/src/lib/workflows/workflow-step.js.map +0 -1
- package/dist/src/lib/yara-hooks.d.ts +0 -44
- package/dist/src/lib/yara-hooks.js +0 -377
- package/dist/src/lib/yara-hooks.js.map +0 -1
- package/dist/src/lib/yara-scanner.d.ts +0 -61
- package/dist/src/lib/yara-scanner.js +0 -328
- package/dist/src/lib/yara-scanner.js.map +0 -1
- package/dist/src/steps/add-mcp-server-to-clients/MCPClient.d.ts +0 -30
- package/dist/src/steps/add-mcp-server-to-clients/MCPClient.js +0 -138
- package/dist/src/steps/add-mcp-server-to-clients/MCPClient.js.map +0 -1
- package/dist/src/steps/add-mcp-server-to-clients/__tests__/defaults.test.d.ts +0 -1
- package/dist/src/steps/add-mcp-server-to-clients/__tests__/defaults.test.js +0 -72
- package/dist/src/steps/add-mcp-server-to-clients/__tests__/defaults.test.js.map +0 -1
- package/dist/src/steps/add-mcp-server-to-clients/clients/__tests__/claude.test.d.ts +0 -1
- package/dist/src/steps/add-mcp-server-to-clients/clients/__tests__/claude.test.js +0 -341
- package/dist/src/steps/add-mcp-server-to-clients/clients/__tests__/claude.test.js.map +0 -1
- package/dist/src/steps/add-mcp-server-to-clients/clients/__tests__/codex.test.d.ts +0 -1
- package/dist/src/steps/add-mcp-server-to-clients/clients/__tests__/codex.test.js +0 -108
- package/dist/src/steps/add-mcp-server-to-clients/clients/__tests__/codex.test.js.map +0 -1
- package/dist/src/steps/add-mcp-server-to-clients/clients/claude-code.d.ts +0 -89
- package/dist/src/steps/add-mcp-server-to-clients/clients/claude-code.js +0 -169
- package/dist/src/steps/add-mcp-server-to-clients/clients/claude-code.js.map +0 -1
- package/dist/src/steps/add-mcp-server-to-clients/clients/claude.d.ts +0 -80
- package/dist/src/steps/add-mcp-server-to-clients/clients/claude.js +0 -64
- package/dist/src/steps/add-mcp-server-to-clients/clients/claude.js.map +0 -1
- package/dist/src/steps/add-mcp-server-to-clients/clients/codex.d.ts +0 -88
- package/dist/src/steps/add-mcp-server-to-clients/clients/codex.js +0 -76
- package/dist/src/steps/add-mcp-server-to-clients/clients/codex.js.map +0 -1
- package/dist/src/steps/add-mcp-server-to-clients/clients/cursor.d.ts +0 -84
- package/dist/src/steps/add-mcp-server-to-clients/clients/cursor.js +0 -61
- package/dist/src/steps/add-mcp-server-to-clients/clients/cursor.js.map +0 -1
- package/dist/src/steps/add-mcp-server-to-clients/clients/visual-studio-code.d.ts +0 -92
- package/dist/src/steps/add-mcp-server-to-clients/clients/visual-studio-code.js +0 -101
- package/dist/src/steps/add-mcp-server-to-clients/clients/visual-studio-code.js.map +0 -1
- package/dist/src/steps/add-mcp-server-to-clients/clients/zed.d.ts +0 -110
- package/dist/src/steps/add-mcp-server-to-clients/clients/zed.js +0 -102
- package/dist/src/steps/add-mcp-server-to-clients/clients/zed.js.map +0 -1
- package/dist/src/steps/add-mcp-server-to-clients/defaults.d.ts +0 -119
- package/dist/src/steps/add-mcp-server-to-clients/defaults.js +0 -239
- package/dist/src/steps/add-mcp-server-to-clients/defaults.js.map +0 -1
- package/dist/src/steps/add-mcp-server-to-clients/index.d.ts +0 -23
- package/dist/src/steps/add-mcp-server-to-clients/index.js +0 -111
- package/dist/src/steps/add-mcp-server-to-clients/index.js.map +0 -1
- package/dist/src/steps/add-or-update-environment-variables.d.ts +0 -10
- package/dist/src/steps/add-or-update-environment-variables.js +0 -188
- package/dist/src/steps/add-or-update-environment-variables.js.map +0 -1
- package/dist/src/steps/index.d.ts +0 -4
- package/dist/src/steps/index.js +0 -21
- package/dist/src/steps/index.js.map +0 -1
- package/dist/src/steps/run-prettier.d.ts +0 -5
- package/dist/src/steps/run-prettier.js +0 -91
- package/dist/src/steps/run-prettier.js.map +0 -1
- package/dist/src/steps/upload-environment-variables/EnvironmentProvider.d.ts +0 -11
- package/dist/src/steps/upload-environment-variables/EnvironmentProvider.js +0 -12
- package/dist/src/steps/upload-environment-variables/EnvironmentProvider.js.map +0 -1
- package/dist/src/steps/upload-environment-variables/index.d.ts +0 -6
- package/dist/src/steps/upload-environment-variables/index.js +0 -38
- package/dist/src/steps/upload-environment-variables/index.js.map +0 -1
- package/dist/src/steps/upload-environment-variables/providers/__tests__/vercel.test.d.ts +0 -1
- package/dist/src/steps/upload-environment-variables/providers/__tests__/vercel.test.js +0 -117
- package/dist/src/steps/upload-environment-variables/providers/__tests__/vercel.test.js.map +0 -1
- package/dist/src/steps/upload-environment-variables/providers/vercel.d.ts +0 -15
- package/dist/src/steps/upload-environment-variables/providers/vercel.js +0 -142
- package/dist/src/steps/upload-environment-variables/providers/vercel.js.map +0 -1
- package/dist/src/telemetry.d.ts +0 -2
- package/dist/src/telemetry.js +0 -13
- package/dist/src/telemetry.js.map +0 -1
- package/dist/src/ui/index.d.ts +0 -8
- package/dist/src/ui/index.js +0 -17
- package/dist/src/ui/index.js.map +0 -1
- package/dist/src/ui/logging-ui.d.ts +0 -52
- package/dist/src/ui/logging-ui.js +0 -121
- package/dist/src/ui/logging-ui.js.map +0 -1
- package/dist/src/ui/tui/App.d.ts +0 -6
- package/dist/src/ui/tui/App.js +0 -10
- package/dist/src/ui/tui/App.js.map +0 -1
- package/dist/src/ui/tui/__tests__/flows.test.d.ts +0 -1
- package/dist/src/ui/tui/__tests__/flows.test.js +0 -115
- package/dist/src/ui/tui/__tests__/flows.test.js.map +0 -1
- package/dist/src/ui/tui/__tests__/layout-helpers.test.d.ts +0 -1
- package/dist/src/ui/tui/__tests__/layout-helpers.test.js +0 -68
- package/dist/src/ui/tui/__tests__/layout-helpers.test.js.map +0 -1
- package/dist/src/ui/tui/__tests__/router.test.d.ts +0 -1
- package/dist/src/ui/tui/__tests__/router.test.js +0 -87
- package/dist/src/ui/tui/__tests__/router.test.js.map +0 -1
- package/dist/src/ui/tui/__tests__/store.test.d.ts +0 -1
- package/dist/src/ui/tui/__tests__/store.test.js +0 -935
- package/dist/src/ui/tui/__tests__/store.test.js.map +0 -1
- package/dist/src/ui/tui/components/LearnCard.d.ts +0 -10
- package/dist/src/ui/tui/components/LearnCard.js +0 -217
- package/dist/src/ui/tui/components/LearnCard.js.map +0 -1
- package/dist/src/ui/tui/components/ServiceHealthList.d.ts +0 -15
- package/dist/src/ui/tui/components/ServiceHealthList.js +0 -57
- package/dist/src/ui/tui/components/ServiceHealthList.js.map +0 -1
- package/dist/src/ui/tui/components/TipsCard.d.ts +0 -9
- package/dist/src/ui/tui/components/TipsCard.js +0 -55
- package/dist/src/ui/tui/components/TipsCard.js.map +0 -1
- package/dist/src/ui/tui/components/TitleBar.d.ts +0 -6
- package/dist/src/ui/tui/components/TitleBar.js +0 -17
- package/dist/src/ui/tui/components/TitleBar.js.map +0 -1
- package/dist/src/ui/tui/flows.d.ts +0 -52
- package/dist/src/ui/tui/flows.js +0 -76
- package/dist/src/ui/tui/flows.js.map +0 -1
- package/dist/src/ui/tui/hooks/useStdoutDimensions.d.ts +0 -9
- package/dist/src/ui/tui/hooks/useStdoutDimensions.js +0 -37
- package/dist/src/ui/tui/hooks/useStdoutDimensions.js.map +0 -1
- package/dist/src/ui/tui/ink-ui.d.ts +0 -58
- package/dist/src/ui/tui/ink-ui.js +0 -125
- package/dist/src/ui/tui/ink-ui.js.map +0 -1
- package/dist/src/ui/tui/package.json +0 -1
- package/dist/src/ui/tui/playground/PlaygroundApp.d.ts +0 -12
- package/dist/src/ui/tui/playground/PlaygroundApp.js +0 -50
- package/dist/src/ui/tui/playground/PlaygroundApp.js.map +0 -1
- package/dist/src/ui/tui/playground/demos/HealthCheckDemo.d.ts +0 -11
- package/dist/src/ui/tui/playground/demos/HealthCheckDemo.js +0 -57
- package/dist/src/ui/tui/playground/demos/HealthCheckDemo.js.map +0 -1
- package/dist/src/ui/tui/playground/demos/InputDemo.d.ts +0 -4
- package/dist/src/ui/tui/playground/demos/InputDemo.js +0 -53
- package/dist/src/ui/tui/playground/demos/InputDemo.js.map +0 -1
- package/dist/src/ui/tui/playground/demos/LayoutDemo.d.ts +0 -5
- package/dist/src/ui/tui/playground/demos/LayoutDemo.js +0 -25
- package/dist/src/ui/tui/playground/demos/LayoutDemo.js.map +0 -1
- package/dist/src/ui/tui/playground/demos/LogDemo.d.ts +0 -5
- package/dist/src/ui/tui/playground/demos/LogDemo.js +0 -53
- package/dist/src/ui/tui/playground/demos/LogDemo.js.map +0 -1
- package/dist/src/ui/tui/playground/demos/McpDemo.d.ts +0 -12
- package/dist/src/ui/tui/playground/demos/McpDemo.js +0 -27
- package/dist/src/ui/tui/playground/demos/McpDemo.js.map +0 -1
- package/dist/src/ui/tui/playground/demos/ModalDemo.d.ts +0 -6
- package/dist/src/ui/tui/playground/demos/ModalDemo.js +0 -13
- package/dist/src/ui/tui/playground/demos/ModalDemo.js.map +0 -1
- package/dist/src/ui/tui/playground/demos/ProgressDemo.d.ts +0 -5
- package/dist/src/ui/tui/playground/demos/ProgressDemo.js +0 -58
- package/dist/src/ui/tui/playground/demos/ProgressDemo.js.map +0 -1
- package/dist/src/ui/tui/playground/demos/RunScreenDemo.d.ts +0 -11
- package/dist/src/ui/tui/playground/demos/RunScreenDemo.js +0 -159
- package/dist/src/ui/tui/playground/demos/RunScreenDemo.js.map +0 -1
- package/dist/src/ui/tui/playground/demos/WelcomeDemo.d.ts +0 -9
- package/dist/src/ui/tui/playground/demos/WelcomeDemo.js +0 -15
- package/dist/src/ui/tui/playground/demos/WelcomeDemo.js.map +0 -1
- package/dist/src/ui/tui/playground/start-playground.d.ts +0 -4
- package/dist/src/ui/tui/playground/start-playground.js +0 -24
- package/dist/src/ui/tui/playground/start-playground.js.map +0 -1
- package/dist/src/ui/tui/primitives/CardLayout.d.ts +0 -12
- package/dist/src/ui/tui/primitives/CardLayout.js +0 -10
- package/dist/src/ui/tui/primitives/CardLayout.js.map +0 -1
- package/dist/src/ui/tui/primitives/ConfirmationInput.d.ts +0 -13
- package/dist/src/ui/tui/primitives/ConfirmationInput.js +0 -35
- package/dist/src/ui/tui/primitives/ConfirmationInput.js.map +0 -1
- package/dist/src/ui/tui/primitives/ContentSequencer.d.ts +0 -42
- package/dist/src/ui/tui/primitives/ContentSequencer.js +0 -137
- package/dist/src/ui/tui/primitives/ContentSequencer.js.map +0 -1
- package/dist/src/ui/tui/primitives/DissolveTransition.d.ts +0 -21
- package/dist/src/ui/tui/primitives/DissolveTransition.js +0 -149
- package/dist/src/ui/tui/primitives/DissolveTransition.js.map +0 -1
- package/dist/src/ui/tui/primitives/Divider.d.ts +0 -6
- package/dist/src/ui/tui/primitives/Divider.js +0 -15
- package/dist/src/ui/tui/primitives/Divider.js.map +0 -1
- package/dist/src/ui/tui/primitives/EventPlanViewer.d.ts +0 -9
- package/dist/src/ui/tui/primitives/EventPlanViewer.js +0 -9
- package/dist/src/ui/tui/primitives/EventPlanViewer.js.map +0 -1
- package/dist/src/ui/tui/primitives/GroupedPickerMenu.d.ts +0 -23
- package/dist/src/ui/tui/primitives/GroupedPickerMenu.js +0 -182
- package/dist/src/ui/tui/primitives/GroupedPickerMenu.js.map +0 -1
- package/dist/src/ui/tui/primitives/HNViewer.d.ts +0 -7
- package/dist/src/ui/tui/primitives/HNViewer.js +0 -63
- package/dist/src/ui/tui/primitives/HNViewer.js.map +0 -1
- package/dist/src/ui/tui/primitives/LinesBlock.d.ts +0 -16
- package/dist/src/ui/tui/primitives/LinesBlock.js +0 -37
- package/dist/src/ui/tui/primitives/LinesBlock.js.map +0 -1
- package/dist/src/ui/tui/primitives/LoadingBox.d.ts +0 -8
- package/dist/src/ui/tui/primitives/LoadingBox.js +0 -10
- package/dist/src/ui/tui/primitives/LoadingBox.js.map +0 -1
- package/dist/src/ui/tui/primitives/LogViewer.d.ts +0 -11
- package/dist/src/ui/tui/primitives/LogViewer.js +0 -55
- package/dist/src/ui/tui/primitives/LogViewer.js.map +0 -1
- package/dist/src/ui/tui/primitives/ModalOverlay.d.ts +0 -25
- package/dist/src/ui/tui/primitives/ModalOverlay.js +0 -7
- package/dist/src/ui/tui/primitives/ModalOverlay.js.map +0 -1
- package/dist/src/ui/tui/primitives/NodeBlock.d.ts +0 -13
- package/dist/src/ui/tui/primitives/NodeBlock.js +0 -17
- package/dist/src/ui/tui/primitives/NodeBlock.js.map +0 -1
- package/dist/src/ui/tui/primitives/PickerMenu.d.ts +0 -20
- package/dist/src/ui/tui/primitives/PickerMenu.js +0 -143
- package/dist/src/ui/tui/primitives/PickerMenu.js.map +0 -1
- package/dist/src/ui/tui/primitives/ProgressList.d.ts +0 -15
- package/dist/src/ui/tui/primitives/ProgressList.js +0 -32
- package/dist/src/ui/tui/primitives/ProgressList.js.map +0 -1
- package/dist/src/ui/tui/primitives/PromptLabel.d.ts +0 -11
- package/dist/src/ui/tui/primitives/PromptLabel.js +0 -13
- package/dist/src/ui/tui/primitives/PromptLabel.js.map +0 -1
- package/dist/src/ui/tui/primitives/ScreenContainer.d.ts +0 -16
- package/dist/src/ui/tui/primitives/ScreenContainer.js +0 -36
- package/dist/src/ui/tui/primitives/ScreenContainer.js.map +0 -1
- package/dist/src/ui/tui/primitives/ScreenErrorBoundary.d.ts +0 -22
- package/dist/src/ui/tui/primitives/ScreenErrorBoundary.js +0 -35
- package/dist/src/ui/tui/primitives/ScreenErrorBoundary.js.map +0 -1
- package/dist/src/ui/tui/primitives/SplitView.d.ts +0 -11
- package/dist/src/ui/tui/primitives/SplitView.js +0 -9
- package/dist/src/ui/tui/primitives/SplitView.js.map +0 -1
- package/dist/src/ui/tui/primitives/TabContainer.d.ts +0 -23
- package/dist/src/ui/tui/primitives/TabContainer.js +0 -45
- package/dist/src/ui/tui/primitives/TabContainer.js.map +0 -1
- package/dist/src/ui/tui/primitives/TextBlock.d.ts +0 -41
- package/dist/src/ui/tui/primitives/TextBlock.js +0 -144
- package/dist/src/ui/tui/primitives/TextBlock.js.map +0 -1
- package/dist/src/ui/tui/primitives/content-types.d.ts +0 -37
- package/dist/src/ui/tui/primitives/content-types.js +0 -19
- package/dist/src/ui/tui/primitives/content-types.js.map +0 -1
- package/dist/src/ui/tui/primitives/index.d.ts +0 -27
- package/dist/src/ui/tui/primitives/index.js +0 -24
- package/dist/src/ui/tui/primitives/index.js.map +0 -1
- package/dist/src/ui/tui/primitives/layout-helpers.d.ts +0 -36
- package/dist/src/ui/tui/primitives/layout-helpers.js +0 -95
- package/dist/src/ui/tui/primitives/layout-helpers.js.map +0 -1
- package/dist/src/ui/tui/primitives/text-helpers.d.ts +0 -10
- package/dist/src/ui/tui/primitives/text-helpers.js +0 -43
- package/dist/src/ui/tui/primitives/text-helpers.js.map +0 -1
- package/dist/src/ui/tui/router.d.ts +0 -58
- package/dist/src/ui/tui/router.js +0 -96
- package/dist/src/ui/tui/router.js.map +0 -1
- package/dist/src/ui/tui/screen-registry.d.ts +0 -19
- package/dist/src/ui/tui/screen-registry.js +0 -46
- package/dist/src/ui/tui/screen-registry.js.map +0 -1
- package/dist/src/ui/tui/screens/AgentSkillIntroScreen.d.ts +0 -12
- package/dist/src/ui/tui/screens/AgentSkillIntroScreen.js +0 -75
- package/dist/src/ui/tui/screens/AgentSkillIntroScreen.js.map +0 -1
- package/dist/src/ui/tui/screens/AuthErrorScreen.d.ts +0 -7
- package/dist/src/ui/tui/screens/AuthErrorScreen.js +0 -16
- package/dist/src/ui/tui/screens/AuthErrorScreen.js.map +0 -1
- package/dist/src/ui/tui/screens/AuthScreen.d.ts +0 -13
- package/dist/src/ui/tui/screens/AuthScreen.js +0 -20
- package/dist/src/ui/tui/screens/AuthScreen.js.map +0 -1
- package/dist/src/ui/tui/screens/IntroScreenLayout.d.ts +0 -46
- package/dist/src/ui/tui/screens/IntroScreenLayout.js +0 -33
- package/dist/src/ui/tui/screens/IntroScreenLayout.js.map +0 -1
- package/dist/src/ui/tui/screens/KeepSkillsScreen.d.ts +0 -14
- package/dist/src/ui/tui/screens/KeepSkillsScreen.js +0 -74
- package/dist/src/ui/tui/screens/KeepSkillsScreen.js.map +0 -1
- package/dist/src/ui/tui/screens/ManagedSettingsScreen.d.ts +0 -13
- package/dist/src/ui/tui/screens/ManagedSettingsScreen.js +0 -32
- package/dist/src/ui/tui/screens/ManagedSettingsScreen.js.map +0 -1
- package/dist/src/ui/tui/screens/McpScreen.d.ts +0 -24
- package/dist/src/ui/tui/screens/McpScreen.js +0 -130
- package/dist/src/ui/tui/screens/McpScreen.js.map +0 -1
- package/dist/src/ui/tui/screens/OutroScreen.d.ts +0 -11
- package/dist/src/ui/tui/screens/OutroScreen.js +0 -22
- package/dist/src/ui/tui/screens/OutroScreen.js.map +0 -1
- package/dist/src/ui/tui/screens/PortConflictScreen.d.ts +0 -11
- package/dist/src/ui/tui/screens/PortConflictScreen.js +0 -30
- package/dist/src/ui/tui/screens/PortConflictScreen.js.map +0 -1
- package/dist/src/ui/tui/screens/PostHogIntegrationIntroScreen.d.ts +0 -15
- package/dist/src/ui/tui/screens/PostHogIntegrationIntroScreen.js +0 -135
- package/dist/src/ui/tui/screens/PostHogIntegrationIntroScreen.js.map +0 -1
- package/dist/src/ui/tui/screens/RevenueIntroScreen.d.ts +0 -16
- package/dist/src/ui/tui/screens/RevenueIntroScreen.js +0 -89
- package/dist/src/ui/tui/screens/RevenueIntroScreen.js.map +0 -1
- package/dist/src/ui/tui/screens/RunScreen.d.ts +0 -16
- package/dist/src/ui/tui/screens/RunScreen.js +0 -73
- package/dist/src/ui/tui/screens/RunScreen.js.map +0 -1
- package/dist/src/ui/tui/screens/SettingsOverrideScreen.d.ts +0 -6
- package/dist/src/ui/tui/screens/SettingsOverrideScreen.js +0 -30
- package/dist/src/ui/tui/screens/SettingsOverrideScreen.js.map +0 -1
- package/dist/src/ui/tui/screens/SetupScreen.d.ts +0 -13
- package/dist/src/ui/tui/screens/SetupScreen.js +0 -74
- package/dist/src/ui/tui/screens/SetupScreen.js.map +0 -1
- package/dist/src/ui/tui/screens/health/HealthCheckScreen.d.ts +0 -14
- package/dist/src/ui/tui/screens/health/HealthCheckScreen.js +0 -77
- package/dist/src/ui/tui/screens/health/HealthCheckScreen.js.map +0 -1
- package/dist/src/ui/tui/services/mcp-installer.d.ts +0 -21
- package/dist/src/ui/tui/services/mcp-installer.js +0 -58
- package/dist/src/ui/tui/services/mcp-installer.js.map +0 -1
- package/dist/src/ui/tui/start-tui.d.ts +0 -9
- package/dist/src/ui/tui/start-tui.js +0 -41
- package/dist/src/ui/tui/start-tui.js.map +0 -1
- package/dist/src/ui/tui/store.d.ts +0 -190
- package/dist/src/ui/tui/store.js +0 -474
- package/dist/src/ui/tui/store.js.map +0 -1
- package/dist/src/ui/tui/styles.d.ts +0 -32
- package/dist/src/ui/tui/styles.js +0 -35
- package/dist/src/ui/tui/styles.js.map +0 -1
- package/dist/src/ui/wizard-ui.d.ts +0 -81
- package/dist/src/ui/wizard-ui.js +0 -19
- package/dist/src/ui/wizard-ui.js.map +0 -1
- package/dist/src/utils/__tests__/analytics.test.d.ts +0 -1
- package/dist/src/utils/__tests__/analytics.test.js +0 -136
- package/dist/src/utils/__tests__/analytics.test.js.map +0 -1
- package/dist/src/utils/__tests__/provisioning.test.d.ts +0 -1
- package/dist/src/utils/__tests__/provisioning.test.js +0 -192
- package/dist/src/utils/__tests__/provisioning.test.js.map +0 -1
- package/dist/src/utils/__tests__/semver.test.d.ts +0 -1
- package/dist/src/utils/__tests__/semver.test.js +0 -159
- package/dist/src/utils/__tests__/semver.test.js.map +0 -1
- package/dist/src/utils/__tests__/setup-utils.test.d.ts +0 -1
- package/dist/src/utils/__tests__/setup-utils.test.js +0 -138
- package/dist/src/utils/__tests__/setup-utils.test.js.map +0 -1
- package/dist/src/utils/analytics.d.ts +0 -33
- package/dist/src/utils/analytics.js +0 -137
- package/dist/src/utils/analytics.js.map +0 -1
- package/dist/src/utils/anthropic-status.d.ts +0 -17
- package/dist/src/utils/anthropic-status.js +0 -49
- package/dist/src/utils/anthropic-status.js.map +0 -1
- package/dist/src/utils/bash.d.ts +0 -2
- package/dist/src/utils/bash.js +0 -54
- package/dist/src/utils/bash.js.map +0 -1
- package/dist/src/utils/custom-headers.d.ts +0 -9
- package/dist/src/utils/custom-headers.js +0 -24
- package/dist/src/utils/custom-headers.js.map +0 -1
- package/dist/src/utils/debug.d.ts +0 -29
- package/dist/src/utils/debug.js +0 -87
- package/dist/src/utils/debug.js.map +0 -1
- package/dist/src/utils/env-api-key.d.ts +0 -5
- package/dist/src/utils/env-api-key.js +0 -57
- package/dist/src/utils/env-api-key.js.map +0 -1
- package/dist/src/utils/environment.d.ts +0 -4
- package/dist/src/utils/environment.js +0 -77
- package/dist/src/utils/environment.js.map +0 -1
- package/dist/src/utils/file-utils.d.ts +0 -10
- package/dist/src/utils/file-utils.js +0 -49
- package/dist/src/utils/file-utils.js.map +0 -1
- package/dist/src/utils/logging.d.ts +0 -9
- package/dist/src/utils/logging.js +0 -47
- package/dist/src/utils/logging.js.map +0 -1
- package/dist/src/utils/oauth.d.ts +0 -33
- package/dist/src/utils/oauth.js +0 -288
- package/dist/src/utils/oauth.js.map +0 -1
- package/dist/src/utils/package-json.d.ts +0 -30
- package/dist/src/utils/package-json.js +0 -47
- package/dist/src/utils/package-json.js.map +0 -1
- package/dist/src/utils/package-manager.d.ts +0 -21
- package/dist/src/utils/package-manager.js +0 -210
- package/dist/src/utils/package-manager.js.map +0 -1
- package/dist/src/utils/provisioning.d.ts +0 -25
- package/dist/src/utils/provisioning.js +0 -191
- package/dist/src/utils/provisioning.js.map +0 -1
- package/dist/src/utils/rules/astro-rules.md +0 -44
- package/dist/src/utils/rules/next-rules.md +0 -9
- package/dist/src/utils/rules/react-native-rules.md +0 -7
- package/dist/src/utils/rules/react-rules.md +0 -7
- package/dist/src/utils/rules/svelte-rules.md +0 -7
- package/dist/src/utils/rules/universal.md +0 -32
- package/dist/src/utils/semver.d.ts +0 -21
- package/dist/src/utils/semver.js +0 -87
- package/dist/src/utils/semver.js.map +0 -1
- package/dist/src/utils/setup-utils.d.ts +0 -79
- package/dist/src/utils/setup-utils.js +0 -406
- package/dist/src/utils/setup-utils.js.map +0 -1
- package/dist/src/utils/string.d.ts +0 -1
- package/dist/src/utils/string.js +0 -9
- package/dist/src/utils/string.js.map +0 -1
- package/dist/src/utils/types.d.ts +0 -85
- package/dist/src/utils/types.js +0 -3
- package/dist/src/utils/types.js.map +0 -1
- package/dist/src/utils/urls.d.ts +0 -7
- package/dist/src/utils/urls.js +0 -78
- package/dist/src/utils/urls.js.map +0 -1
- package/dist/src/utils/vendor/is-unicorn-supported.d.ts +0 -1
- package/dist/src/utils/vendor/is-unicorn-supported.js +0 -24
- package/dist/src/utils/vendor/is-unicorn-supported.js.map +0 -1
- package/dist/src/utils/wizard-abort.d.ts +0 -16
- package/dist/src/utils/wizard-abort.js +0 -59
- package/dist/src/utils/wizard-abort.js.map +0 -1
|
@@ -0,0 +1,2922 @@
|
|
|
1
|
+
import { t as __exportAll } from "./rolldown-runtime-B_-DWIq7.js";
|
|
2
|
+
import { c as getUI } from "./debug-CyJ_3dTP.js";
|
|
3
|
+
import "./analytics-C4jO5Qda.js";
|
|
4
|
+
import { i as createVersionBucket, r as tryGetPackageJson, s as detectAllPackageManagers } from "./setup-utils-CdDnllRW.js";
|
|
5
|
+
import { n as getPackageVersion, r as hasPackageInstalled, t as getInstalledPackageVersion } from "./package-json-Ctq6LSl8.js";
|
|
6
|
+
import { a as gradlePackageManager, c as getPackageManagerName$1, i as detectPythonPackageManagers, l as getPythonVersion, n as composerPackageManager, o as swiftPackageManager, r as detectNodePackageManagers, s as detectPackageManager$1, t as bundlerPackageManager, u as getPythonVersionBucket } from "./package-manager-nUQ-ebjr.js";
|
|
7
|
+
import * as semver from "semver";
|
|
8
|
+
import { major, minVersion } from "semver";
|
|
9
|
+
import * as fs$1 from "node:fs";
|
|
10
|
+
import * as path$1 from "node:path";
|
|
11
|
+
import path from "path";
|
|
12
|
+
import fg from "fast-glob";
|
|
13
|
+
import fs from "fs/promises";
|
|
14
|
+
//#region src/lib/framework-config.ts
|
|
15
|
+
/**
|
|
16
|
+
* Default package installation instruction used when frameworks don't
|
|
17
|
+
* provide their own. Frameworks with specific needs (e.g., Swift SPM,
|
|
18
|
+
* Composer) override this in their config.
|
|
19
|
+
*/
|
|
20
|
+
const DEFAULT_PACKAGE_INSTALLATION = "Use the detect_package_manager tool to determine the package manager. Do not manually edit package.json; the package manager handles it automatically.";
|
|
21
|
+
const PYTHON_PACKAGE_INSTALLATION = "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.";
|
|
22
|
+
/**
|
|
23
|
+
* Shared spinner message for all frameworks
|
|
24
|
+
*/
|
|
25
|
+
const SPINNER_MESSAGE = "Writing your PostHog setup with events, error capture and more...";
|
|
26
|
+
//#endregion
|
|
27
|
+
//#region src/frameworks/nextjs/utils.ts
|
|
28
|
+
const getNextJsVersionBucket = createVersionBucket();
|
|
29
|
+
const IGNORE_PATTERNS$9 = [
|
|
30
|
+
"**/node_modules/**",
|
|
31
|
+
"**/dist/**",
|
|
32
|
+
"**/build/**",
|
|
33
|
+
"**/public/**",
|
|
34
|
+
"**/.next/**"
|
|
35
|
+
];
|
|
36
|
+
/**
|
|
37
|
+
* Detect Next.js router type. Pure — returns null if ambiguous.
|
|
38
|
+
*/
|
|
39
|
+
async function getNextJsRouter({ installDir }) {
|
|
40
|
+
const hasPagesDir = (await fg("**/pages/_app.@(ts|tsx|js|jsx)", {
|
|
41
|
+
dot: true,
|
|
42
|
+
cwd: installDir,
|
|
43
|
+
ignore: IGNORE_PATTERNS$9
|
|
44
|
+
})).length > 0;
|
|
45
|
+
const hasAppDir = (await fg("**/app/**/layout.@(ts|tsx|js|jsx)", {
|
|
46
|
+
dot: true,
|
|
47
|
+
cwd: installDir,
|
|
48
|
+
ignore: IGNORE_PATTERNS$9
|
|
49
|
+
})).length > 0;
|
|
50
|
+
if (hasPagesDir && !hasAppDir) return "pages-router";
|
|
51
|
+
if (hasAppDir && !hasPagesDir) return "app-router";
|
|
52
|
+
return null;
|
|
53
|
+
}
|
|
54
|
+
const getNextJsRouterName = (router) => {
|
|
55
|
+
return router === "app-router" ? "app router" : "pages router";
|
|
56
|
+
};
|
|
57
|
+
//#endregion
|
|
58
|
+
//#region src/frameworks/nextjs/nextjs-wizard-agent.ts
|
|
59
|
+
const NEXTJS_AGENT_CONFIG = {
|
|
60
|
+
metadata: {
|
|
61
|
+
name: "Next.js",
|
|
62
|
+
integration: "nextjs",
|
|
63
|
+
docsUrl: "https://posthog.com/docs/libraries/next-js",
|
|
64
|
+
unsupportedVersionDocsUrl: "https://posthog.com/docs/libraries/next-js",
|
|
65
|
+
gatherContext: async (options) => {
|
|
66
|
+
const router = await getNextJsRouter(options);
|
|
67
|
+
if (router) {
|
|
68
|
+
const emoji = router === "app-router" ? "📱" : "📃";
|
|
69
|
+
getUI().setDetectedFramework(`Next.js ${getNextJsRouterName(router)} ${emoji}`);
|
|
70
|
+
return { router };
|
|
71
|
+
}
|
|
72
|
+
return {};
|
|
73
|
+
},
|
|
74
|
+
setup: { questions: [{
|
|
75
|
+
key: "router",
|
|
76
|
+
message: "Which Next.js router are you using?",
|
|
77
|
+
options: [{
|
|
78
|
+
label: "App Router",
|
|
79
|
+
value: "app-router"
|
|
80
|
+
}, {
|
|
81
|
+
label: "Pages Router",
|
|
82
|
+
value: "pages-router"
|
|
83
|
+
}],
|
|
84
|
+
detect: async (opts) => {
|
|
85
|
+
return await getNextJsRouter(opts);
|
|
86
|
+
}
|
|
87
|
+
}] }
|
|
88
|
+
},
|
|
89
|
+
detection: {
|
|
90
|
+
packageName: "next",
|
|
91
|
+
packageDisplayName: "Next.js",
|
|
92
|
+
getVersion: (packageJson) => getPackageVersion("next", packageJson),
|
|
93
|
+
getVersionBucket: getNextJsVersionBucket,
|
|
94
|
+
minimumVersion: "15.3.0",
|
|
95
|
+
getInstalledVersion: (options) => Promise.resolve(getInstalledPackageVersion("next", options.installDir)),
|
|
96
|
+
detect: async (options) => {
|
|
97
|
+
const packageJson = await tryGetPackageJson(options);
|
|
98
|
+
return packageJson ? hasPackageInstalled("next", packageJson) : false;
|
|
99
|
+
},
|
|
100
|
+
detectPackageManager: detectNodePackageManagers
|
|
101
|
+
},
|
|
102
|
+
environment: {
|
|
103
|
+
uploadToHosting: true,
|
|
104
|
+
getEnvVars: (apiKey, host) => ({
|
|
105
|
+
NEXT_PUBLIC_POSTHOG_PROJECT_TOKEN: apiKey,
|
|
106
|
+
NEXT_PUBLIC_POSTHOG_HOST: host
|
|
107
|
+
})
|
|
108
|
+
},
|
|
109
|
+
analytics: { getTags: (context) => ({ router: context.router === "app-router" ? "app" : "pages" }) },
|
|
110
|
+
prompts: {
|
|
111
|
+
projectTypeDetection: "This is a JavaScript/TypeScript project. Look for package.json and lockfiles (package-lock.json, yarn.lock, pnpm-lock.yaml, bun.lockb) to confirm.",
|
|
112
|
+
getAdditionalContextLines: (context) => {
|
|
113
|
+
return [`Router: ${context.router === "app-router" ? "app" : "pages"}`];
|
|
114
|
+
}
|
|
115
|
+
},
|
|
116
|
+
ui: {
|
|
117
|
+
successMessage: "PostHog integration complete",
|
|
118
|
+
estimatedDurationMinutes: 8,
|
|
119
|
+
getOutroChanges: (context) => {
|
|
120
|
+
return [
|
|
121
|
+
`Analyzed your Next.js project structure (${getNextJsRouterName(context.router ?? "app-router")})`,
|
|
122
|
+
`Created and configured PostHog initializers`,
|
|
123
|
+
`Integrated PostHog into your application`
|
|
124
|
+
];
|
|
125
|
+
},
|
|
126
|
+
getOutroNextSteps: () => {
|
|
127
|
+
return ["Start your development server to see PostHog in action", "Visit your PostHog dashboard to see incoming events"];
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
};
|
|
131
|
+
//#endregion
|
|
132
|
+
//#region src/frameworks/nuxt/nuxt-wizard-agent.ts
|
|
133
|
+
const getNuxtVersionBucket = createVersionBucket();
|
|
134
|
+
const NUXT_AGENT_CONFIG = {
|
|
135
|
+
metadata: {
|
|
136
|
+
name: "Nuxt",
|
|
137
|
+
integration: "nuxt",
|
|
138
|
+
docsUrl: "https://posthog.com/docs/libraries/nuxt",
|
|
139
|
+
beta: true,
|
|
140
|
+
gatherContext: async (options) => {
|
|
141
|
+
const packageJson = await tryGetPackageJson(options);
|
|
142
|
+
if (!packageJson) return {};
|
|
143
|
+
return { versionBucket: getNuxtVersionBucket(getPackageVersion("nuxt", packageJson)) };
|
|
144
|
+
}
|
|
145
|
+
},
|
|
146
|
+
detection: {
|
|
147
|
+
packageName: "nuxt",
|
|
148
|
+
packageDisplayName: "Nuxt",
|
|
149
|
+
getVersion: (packageJson) => getPackageVersion("nuxt", packageJson),
|
|
150
|
+
getVersionBucket: getNuxtVersionBucket,
|
|
151
|
+
getInstalledVersion: (options) => Promise.resolve(getInstalledPackageVersion("nuxt", options.installDir)),
|
|
152
|
+
detect: async (options) => {
|
|
153
|
+
const packageJson = await tryGetPackageJson(options);
|
|
154
|
+
return packageJson ? hasPackageInstalled("nuxt", packageJson) : false;
|
|
155
|
+
},
|
|
156
|
+
detectPackageManager: detectNodePackageManagers
|
|
157
|
+
},
|
|
158
|
+
environment: {
|
|
159
|
+
uploadToHosting: true,
|
|
160
|
+
getEnvVars: (apiKey, host) => ({
|
|
161
|
+
NUXT_PUBLIC_POSTHOG_PROJECT_TOKEN: apiKey,
|
|
162
|
+
NUXT_PUBLIC_POSTHOG_HOST: host
|
|
163
|
+
})
|
|
164
|
+
},
|
|
165
|
+
analytics: { getTags: (context) => ({ ...context.versionBucket ? { versionBucket: context.versionBucket } : {} }) },
|
|
166
|
+
prompts: {
|
|
167
|
+
projectTypeDetection: "This is a JavaScript/TypeScript project. Look for package.json and lockfiles (package-lock.json, yarn.lock, pnpm-lock.yaml, bun.lockb) to confirm.",
|
|
168
|
+
getAdditionalContextLines: (context) => {
|
|
169
|
+
const lines = [];
|
|
170
|
+
if (context.versionBucket) lines.push(`Nuxt version: ${context.versionBucket}`);
|
|
171
|
+
const frameworkId = "nuxt";
|
|
172
|
+
lines.push(`Framework docs ID: ${frameworkId} (use posthog://docs/frameworks/${frameworkId} for documentation)`);
|
|
173
|
+
return lines;
|
|
174
|
+
}
|
|
175
|
+
},
|
|
176
|
+
ui: {
|
|
177
|
+
successMessage: "PostHog integration complete",
|
|
178
|
+
estimatedDurationMinutes: 5,
|
|
179
|
+
getOutroChanges: () => [
|
|
180
|
+
"Analyzed your Nuxt project structure",
|
|
181
|
+
"Configured PostHog module/plugin",
|
|
182
|
+
"Integrated PostHog into your application"
|
|
183
|
+
],
|
|
184
|
+
getOutroNextSteps: () => ["Start your development server to see PostHog in action", "Visit your PostHog dashboard to see incoming events"]
|
|
185
|
+
}
|
|
186
|
+
};
|
|
187
|
+
const VUE_AGENT_CONFIG = {
|
|
188
|
+
metadata: {
|
|
189
|
+
name: "Vue",
|
|
190
|
+
integration: "vue",
|
|
191
|
+
docsUrl: "https://posthog.com/docs/libraries/vue",
|
|
192
|
+
beta: true
|
|
193
|
+
},
|
|
194
|
+
detection: {
|
|
195
|
+
packageName: "vue",
|
|
196
|
+
packageDisplayName: "Vue",
|
|
197
|
+
getVersion: (packageJson) => getPackageVersion("vue", packageJson),
|
|
198
|
+
getVersionBucket: createVersionBucket(),
|
|
199
|
+
getInstalledVersion: (options) => Promise.resolve(getInstalledPackageVersion("vue", options.installDir)),
|
|
200
|
+
detect: async (options) => {
|
|
201
|
+
const packageJson = await tryGetPackageJson(options);
|
|
202
|
+
return packageJson ? hasPackageInstalled("vue", packageJson) : false;
|
|
203
|
+
},
|
|
204
|
+
detectPackageManager: detectNodePackageManagers
|
|
205
|
+
},
|
|
206
|
+
environment: {
|
|
207
|
+
uploadToHosting: true,
|
|
208
|
+
getEnvVars: (apiKey, host) => ({
|
|
209
|
+
VITE_POSTHOG_PROJECT_TOKEN: apiKey,
|
|
210
|
+
VITE_POSTHOG_HOST: host
|
|
211
|
+
})
|
|
212
|
+
},
|
|
213
|
+
analytics: { getTags: () => ({}) },
|
|
214
|
+
prompts: {
|
|
215
|
+
projectTypeDetection: "This is a JavaScript/TypeScript project. Look for package.json and lockfiles (package-lock.json, yarn.lock, pnpm-lock.yaml, bun.lockb) to confirm.",
|
|
216
|
+
getAdditionalContextLines: () => {
|
|
217
|
+
const frameworkId = "vue";
|
|
218
|
+
return [`Framework docs ID: ${frameworkId} (use posthog://docs/frameworks/${frameworkId} for documentation)`];
|
|
219
|
+
}
|
|
220
|
+
},
|
|
221
|
+
ui: {
|
|
222
|
+
successMessage: "PostHog integration complete",
|
|
223
|
+
estimatedDurationMinutes: 5,
|
|
224
|
+
getOutroChanges: () => [
|
|
225
|
+
"Analyzed your Vue project structure",
|
|
226
|
+
"Created and configured PostHog initializers",
|
|
227
|
+
"Integrated PostHog into your application"
|
|
228
|
+
],
|
|
229
|
+
getOutroNextSteps: () => ["Start your development server to see PostHog in action", "Visit your PostHog dashboard to see incoming events"]
|
|
230
|
+
}
|
|
231
|
+
};
|
|
232
|
+
//#endregion
|
|
233
|
+
//#region src/frameworks/react-router/utils.ts
|
|
234
|
+
const IGNORE_PATTERNS$8 = [
|
|
235
|
+
"**/node_modules/**",
|
|
236
|
+
"**/dist/**",
|
|
237
|
+
"**/build/**",
|
|
238
|
+
"**/public/**",
|
|
239
|
+
"**/.next/**"
|
|
240
|
+
];
|
|
241
|
+
const getReactRouterVersionBucket = createVersionBucket();
|
|
242
|
+
async function hasReactRouterConfig({ installDir }) {
|
|
243
|
+
return (await fg("**/react-router.config.@(ts|js|tsx|jsx)", {
|
|
244
|
+
dot: true,
|
|
245
|
+
cwd: installDir,
|
|
246
|
+
ignore: IGNORE_PATTERNS$8
|
|
247
|
+
})).length > 0;
|
|
248
|
+
}
|
|
249
|
+
async function hasCreateBrowserRouter({ installDir }) {
|
|
250
|
+
const sourceFiles = await fg("**/*.@(ts|tsx|js|jsx)", {
|
|
251
|
+
dot: true,
|
|
252
|
+
cwd: installDir,
|
|
253
|
+
ignore: IGNORE_PATTERNS$8
|
|
254
|
+
});
|
|
255
|
+
for (const file of sourceFiles) try {
|
|
256
|
+
const filePath = path$1.join(installDir, file);
|
|
257
|
+
if (fs$1.readFileSync(filePath, "utf-8").includes("createBrowserRouter")) return true;
|
|
258
|
+
} catch {
|
|
259
|
+
continue;
|
|
260
|
+
}
|
|
261
|
+
return false;
|
|
262
|
+
}
|
|
263
|
+
async function hasDeclarativeRouter({ installDir }) {
|
|
264
|
+
const sourceFiles = await fg("**/*.@(ts|tsx|js|jsx)", {
|
|
265
|
+
dot: true,
|
|
266
|
+
cwd: installDir,
|
|
267
|
+
ignore: IGNORE_PATTERNS$8
|
|
268
|
+
});
|
|
269
|
+
for (const file of sourceFiles) try {
|
|
270
|
+
const filePath = path$1.join(installDir, file);
|
|
271
|
+
const content = fs$1.readFileSync(filePath, "utf-8");
|
|
272
|
+
if (content.includes("<BrowserRouter") || content.includes("BrowserRouter") && (content.includes("from \"react-router-dom\"") || content.includes("from 'react-router-dom'"))) return true;
|
|
273
|
+
} catch {
|
|
274
|
+
continue;
|
|
275
|
+
}
|
|
276
|
+
return false;
|
|
277
|
+
}
|
|
278
|
+
/**
|
|
279
|
+
* Detect React Router mode. Pure — returns null if ambiguous.
|
|
280
|
+
*/
|
|
281
|
+
async function getReactRouterMode(options) {
|
|
282
|
+
const { installDir } = options;
|
|
283
|
+
const packageJson = await tryGetPackageJson(options);
|
|
284
|
+
if (!packageJson) return null;
|
|
285
|
+
const reactRouterVersion = getPackageVersion("react-router-dom", packageJson) || getPackageVersion("react-router", packageJson);
|
|
286
|
+
if (!reactRouterVersion) return null;
|
|
287
|
+
const coercedVersion = semver.coerce(reactRouterVersion);
|
|
288
|
+
const majorVersion = coercedVersion ? major(coercedVersion) : null;
|
|
289
|
+
if (majorVersion === 6) return "v6";
|
|
290
|
+
if (majorVersion === 7) {
|
|
291
|
+
if (await hasReactRouterConfig({ installDir })) return "v7-framework";
|
|
292
|
+
if (await hasCreateBrowserRouter({ installDir })) return "v7-data";
|
|
293
|
+
if (await hasDeclarativeRouter({ installDir })) return "v7-declarative";
|
|
294
|
+
return null;
|
|
295
|
+
}
|
|
296
|
+
return null;
|
|
297
|
+
}
|
|
298
|
+
function getReactRouterModeName(mode) {
|
|
299
|
+
switch (mode) {
|
|
300
|
+
case "v6": return "v6";
|
|
301
|
+
case "v7-framework": return "v7 Framework mode";
|
|
302
|
+
case "v7-data": return "v7 Data mode";
|
|
303
|
+
case "v7-declarative": return "v7 Declarative mode";
|
|
304
|
+
}
|
|
305
|
+
}
|
|
306
|
+
//#endregion
|
|
307
|
+
//#region src/frameworks/react-router/react-router-wizard-agent.ts
|
|
308
|
+
const REACT_ROUTER_AGENT_CONFIG = {
|
|
309
|
+
metadata: {
|
|
310
|
+
name: "React Router",
|
|
311
|
+
integration: "react-router",
|
|
312
|
+
docsUrl: "https://posthog.com/docs/libraries/react",
|
|
313
|
+
unsupportedVersionDocsUrl: "https://posthog.com/docs/libraries/react",
|
|
314
|
+
gatherContext: async (options) => {
|
|
315
|
+
const routerMode = await getReactRouterMode(options);
|
|
316
|
+
if (routerMode) {
|
|
317
|
+
getUI().setDetectedFramework(`React Router ${getReactRouterModeName(routerMode)}`);
|
|
318
|
+
return { routerMode };
|
|
319
|
+
}
|
|
320
|
+
return {};
|
|
321
|
+
}
|
|
322
|
+
},
|
|
323
|
+
detection: {
|
|
324
|
+
packageName: "react-router",
|
|
325
|
+
packageDisplayName: "React Router",
|
|
326
|
+
getVersion: (packageJson) => getPackageVersion("react-router", packageJson),
|
|
327
|
+
getVersionBucket: getReactRouterVersionBucket,
|
|
328
|
+
minimumVersion: "6.0.0",
|
|
329
|
+
getInstalledVersion: (options) => Promise.resolve(getInstalledPackageVersion("react-router", options.installDir)),
|
|
330
|
+
detect: async (options) => {
|
|
331
|
+
const packageJson = await tryGetPackageJson(options);
|
|
332
|
+
return packageJson ? hasPackageInstalled("react-router", packageJson) : false;
|
|
333
|
+
},
|
|
334
|
+
detectPackageManager: detectNodePackageManagers
|
|
335
|
+
},
|
|
336
|
+
environment: {
|
|
337
|
+
uploadToHosting: false,
|
|
338
|
+
getEnvVars: (apiKey, host) => ({
|
|
339
|
+
REACT_APP_POSTHOG_PROJECT_TOKEN: apiKey,
|
|
340
|
+
REACT_APP_POSTHOG_HOST: host
|
|
341
|
+
})
|
|
342
|
+
},
|
|
343
|
+
analytics: { getTags: (context) => ({ routerMode: context.routerMode || "unknown" }) },
|
|
344
|
+
prompts: {
|
|
345
|
+
projectTypeDetection: "This is a JavaScript/TypeScript project. Look for package.json and lockfiles (package-lock.json, yarn.lock, pnpm-lock.yaml, bun.lockb) to confirm.",
|
|
346
|
+
getAdditionalContextLines: (context) => {
|
|
347
|
+
const routerMode = context.routerMode;
|
|
348
|
+
const modeName = routerMode ? getReactRouterModeName(routerMode) : "unknown";
|
|
349
|
+
const frameworkId = routerMode ? {
|
|
350
|
+
["v6"]: "react-react-router-6",
|
|
351
|
+
["v7-framework"]: "react-react-router-7-framework",
|
|
352
|
+
["v7-data"]: "react-react-router-7-data",
|
|
353
|
+
["v7-declarative"]: "react-react-router-7-declarative"
|
|
354
|
+
}[routerMode] : "v7-framework";
|
|
355
|
+
return [`Router mode: ${modeName}`, `Framework docs ID: ${frameworkId} (use posthog://docs/frameworks/${frameworkId} for documentation)`];
|
|
356
|
+
}
|
|
357
|
+
},
|
|
358
|
+
ui: {
|
|
359
|
+
successMessage: "PostHog integration complete",
|
|
360
|
+
estimatedDurationMinutes: 8,
|
|
361
|
+
getOutroChanges: (context) => {
|
|
362
|
+
return [
|
|
363
|
+
`Analyzed your React Router project structure (${context.routerMode ? getReactRouterModeName(context.routerMode) : "React Router"})`,
|
|
364
|
+
`Created and configured PostHog initializers`,
|
|
365
|
+
`Integrated PostHog into your application`
|
|
366
|
+
];
|
|
367
|
+
},
|
|
368
|
+
getOutroNextSteps: () => ["Start your development server to see PostHog in action", "Visit your PostHog dashboard to see incoming events"]
|
|
369
|
+
}
|
|
370
|
+
};
|
|
371
|
+
//#endregion
|
|
372
|
+
//#region src/frameworks/tanstack-router/utils.ts
|
|
373
|
+
const IGNORE_PATTERNS$7 = [
|
|
374
|
+
"**/node_modules/**",
|
|
375
|
+
"**/dist/**",
|
|
376
|
+
"**/build/**",
|
|
377
|
+
"**/public/**",
|
|
378
|
+
"**/.vinxi/**",
|
|
379
|
+
"**/.output/**"
|
|
380
|
+
];
|
|
381
|
+
const getTanStackRouterVersionBucket = createVersionBucket();
|
|
382
|
+
async function hasFileBasedRouting({ installDir }) {
|
|
383
|
+
if ((await fg("**/routeTree.gen.@(ts|tsx|js|jsx)", {
|
|
384
|
+
dot: true,
|
|
385
|
+
cwd: installDir,
|
|
386
|
+
ignore: IGNORE_PATTERNS$7
|
|
387
|
+
})).length > 0) return true;
|
|
388
|
+
try {
|
|
389
|
+
const packageJsonPath = path$1.join(installDir, "package.json");
|
|
390
|
+
const content = fs$1.readFileSync(packageJsonPath, "utf-8");
|
|
391
|
+
const packageJson = JSON.parse(content);
|
|
392
|
+
if (hasPackageInstalled("@tanstack/router-plugin", packageJson) || hasPackageInstalled("@tanstack/router-vite-plugin", packageJson)) return true;
|
|
393
|
+
} catch {}
|
|
394
|
+
const sourceFiles = await fg("**/*.@(ts|tsx|js|jsx)", {
|
|
395
|
+
dot: true,
|
|
396
|
+
cwd: installDir,
|
|
397
|
+
ignore: IGNORE_PATTERNS$7
|
|
398
|
+
});
|
|
399
|
+
for (const file of sourceFiles) try {
|
|
400
|
+
const filePath = path$1.join(installDir, file);
|
|
401
|
+
if (fs$1.readFileSync(filePath, "utf-8").includes("createFileRoute")) return true;
|
|
402
|
+
} catch {
|
|
403
|
+
continue;
|
|
404
|
+
}
|
|
405
|
+
return false;
|
|
406
|
+
}
|
|
407
|
+
async function hasCodeBasedRouting({ installDir }) {
|
|
408
|
+
const sourceFiles = await fg("**/*.@(ts|tsx|js|jsx)", {
|
|
409
|
+
dot: true,
|
|
410
|
+
cwd: installDir,
|
|
411
|
+
ignore: IGNORE_PATTERNS$7
|
|
412
|
+
});
|
|
413
|
+
let hasCreateRoute = false;
|
|
414
|
+
let hasCreateFileRoute = false;
|
|
415
|
+
for (const file of sourceFiles) try {
|
|
416
|
+
const filePath = path$1.join(installDir, file);
|
|
417
|
+
const content = fs$1.readFileSync(filePath, "utf-8");
|
|
418
|
+
if (content.includes("createRoute(")) hasCreateRoute = true;
|
|
419
|
+
if (content.includes("createFileRoute")) hasCreateFileRoute = true;
|
|
420
|
+
} catch {
|
|
421
|
+
continue;
|
|
422
|
+
}
|
|
423
|
+
return hasCreateRoute && !hasCreateFileRoute;
|
|
424
|
+
}
|
|
425
|
+
/**
|
|
426
|
+
* Detect TanStack Router mode. Pure — returns null if ambiguous.
|
|
427
|
+
*/
|
|
428
|
+
async function getTanStackRouterMode(options) {
|
|
429
|
+
const { installDir } = options;
|
|
430
|
+
if (await hasFileBasedRouting({ installDir })) return "file-based";
|
|
431
|
+
if (await hasCodeBasedRouting({ installDir })) return "code-based";
|
|
432
|
+
return null;
|
|
433
|
+
}
|
|
434
|
+
function getTanStackRouterModeName(mode) {
|
|
435
|
+
switch (mode) {
|
|
436
|
+
case "file-based": return "File-based routing";
|
|
437
|
+
case "code-based": return "Code-based routing";
|
|
438
|
+
}
|
|
439
|
+
}
|
|
440
|
+
//#endregion
|
|
441
|
+
//#region src/frameworks/tanstack-router/tanstack-router-wizard-agent.ts
|
|
442
|
+
const TANSTACK_ROUTER_AGENT_CONFIG = {
|
|
443
|
+
metadata: {
|
|
444
|
+
name: "React (TanStack Router)",
|
|
445
|
+
integration: "tanstack-router",
|
|
446
|
+
docsUrl: "https://posthog.com/docs/libraries/react",
|
|
447
|
+
gatherContext: async (options) => {
|
|
448
|
+
const routerMode = await getTanStackRouterMode(options);
|
|
449
|
+
if (routerMode) {
|
|
450
|
+
getUI().setDetectedFramework(`TanStack Router ${getTanStackRouterModeName(routerMode)}`);
|
|
451
|
+
return { routerMode };
|
|
452
|
+
}
|
|
453
|
+
return {};
|
|
454
|
+
}
|
|
455
|
+
},
|
|
456
|
+
detection: {
|
|
457
|
+
packageName: "@tanstack/react-router",
|
|
458
|
+
packageDisplayName: "TanStack Router",
|
|
459
|
+
getVersion: (packageJson) => getPackageVersion("@tanstack/react-router", packageJson),
|
|
460
|
+
getVersionBucket: getTanStackRouterVersionBucket,
|
|
461
|
+
minimumVersion: "1.0.0",
|
|
462
|
+
getInstalledVersion: (options) => Promise.resolve(getInstalledPackageVersion("@tanstack/react-router", options.installDir)),
|
|
463
|
+
detect: async (options) => {
|
|
464
|
+
const packageJson = await tryGetPackageJson(options);
|
|
465
|
+
if (!packageJson) return false;
|
|
466
|
+
if (hasPackageInstalled("@tanstack/react-start", packageJson)) return false;
|
|
467
|
+
return hasPackageInstalled("@tanstack/react-router", packageJson);
|
|
468
|
+
},
|
|
469
|
+
detectPackageManager: detectNodePackageManagers
|
|
470
|
+
},
|
|
471
|
+
environment: {
|
|
472
|
+
uploadToHosting: false,
|
|
473
|
+
getEnvVars: (apiKey, host) => ({
|
|
474
|
+
VITE_PUBLIC_POSTHOG_PROJECT_TOKEN: apiKey,
|
|
475
|
+
VITE_PUBLIC_POSTHOG_HOST: host
|
|
476
|
+
})
|
|
477
|
+
},
|
|
478
|
+
analytics: { getTags: (context) => ({ routerMode: context.routerMode || "unknown" }) },
|
|
479
|
+
prompts: {
|
|
480
|
+
projectTypeDetection: "This is a JavaScript/TypeScript project. Look for package.json and lockfiles (package-lock.json, yarn.lock, pnpm-lock.yaml, bun.lockb) to confirm.",
|
|
481
|
+
getAdditionalContextLines: (context) => {
|
|
482
|
+
const routerMode = context.routerMode;
|
|
483
|
+
const modeName = routerMode ? getTanStackRouterModeName(routerMode) : "unknown";
|
|
484
|
+
const frameworkId = routerMode ? {
|
|
485
|
+
["file-based"]: "react-tanstack-router-file-based",
|
|
486
|
+
["code-based"]: "react-tanstack-router-code-based"
|
|
487
|
+
}[routerMode] : "react-tanstack-router-file-based";
|
|
488
|
+
return [`Router mode: ${modeName}`, `Framework docs ID: ${frameworkId} (use posthog://docs/frameworks/${frameworkId} for documentation)`];
|
|
489
|
+
}
|
|
490
|
+
},
|
|
491
|
+
ui: {
|
|
492
|
+
successMessage: "PostHog integration complete",
|
|
493
|
+
estimatedDurationMinutes: 8,
|
|
494
|
+
getOutroChanges: (context) => {
|
|
495
|
+
return [
|
|
496
|
+
`Analyzed your React (TanStack Router) project structure (${context.routerMode ? getTanStackRouterModeName(context.routerMode) : "TanStack Router"})`,
|
|
497
|
+
`Created and configured PostHog initializers`,
|
|
498
|
+
`Integrated PostHog into your application`
|
|
499
|
+
];
|
|
500
|
+
},
|
|
501
|
+
getOutroNextSteps: () => ["Start your development server to see PostHog in action", "Visit your PostHog dashboard to see incoming events"]
|
|
502
|
+
}
|
|
503
|
+
};
|
|
504
|
+
//#endregion
|
|
505
|
+
//#region src/frameworks/tanstack-start/tanstack-start-wizard-agent.ts
|
|
506
|
+
const TANSTACK_START_AGENT_CONFIG = {
|
|
507
|
+
metadata: {
|
|
508
|
+
name: "TanStack Start",
|
|
509
|
+
integration: "tanstack-start",
|
|
510
|
+
docsUrl: "https://posthog.com/docs/libraries/react"
|
|
511
|
+
},
|
|
512
|
+
detection: {
|
|
513
|
+
packageName: "@tanstack/react-start",
|
|
514
|
+
packageDisplayName: "TanStack Start",
|
|
515
|
+
getVersion: (packageJson) => getPackageVersion("@tanstack/react-start", packageJson),
|
|
516
|
+
getVersionBucket: createVersionBucket(),
|
|
517
|
+
minimumVersion: "1.0.0",
|
|
518
|
+
getInstalledVersion: (options) => Promise.resolve(getInstalledPackageVersion("@tanstack/react-start", options.installDir)),
|
|
519
|
+
detect: async (options) => {
|
|
520
|
+
const packageJson = await tryGetPackageJson(options);
|
|
521
|
+
return packageJson ? hasPackageInstalled("@tanstack/react-start", packageJson) : false;
|
|
522
|
+
},
|
|
523
|
+
detectPackageManager: detectNodePackageManagers
|
|
524
|
+
},
|
|
525
|
+
environment: {
|
|
526
|
+
uploadToHosting: false,
|
|
527
|
+
getEnvVars: (apiKey, host) => ({
|
|
528
|
+
VITE_PUBLIC_POSTHOG_PROJECT_TOKEN: apiKey,
|
|
529
|
+
VITE_PUBLIC_POSTHOG_HOST: host
|
|
530
|
+
})
|
|
531
|
+
},
|
|
532
|
+
analytics: { getTags: () => ({}) },
|
|
533
|
+
prompts: {
|
|
534
|
+
projectTypeDetection: "This is a JavaScript/TypeScript project. Look for package.json and lockfiles (package-lock.json, yarn.lock, pnpm-lock.yaml, bun.lockb) to confirm.",
|
|
535
|
+
getAdditionalContextLines: () => {
|
|
536
|
+
const frameworkId = "react-tanstack-start";
|
|
537
|
+
return [`Framework docs ID: ${frameworkId} (use posthog://docs/frameworks/${frameworkId} for documentation)`];
|
|
538
|
+
}
|
|
539
|
+
},
|
|
540
|
+
ui: {
|
|
541
|
+
successMessage: "PostHog integration complete",
|
|
542
|
+
estimatedDurationMinutes: 8,
|
|
543
|
+
getOutroChanges: () => [
|
|
544
|
+
`Analyzed your TanStack Start project structure`,
|
|
545
|
+
`Created and configured PostHog initializers`,
|
|
546
|
+
`Integrated PostHog into your application`
|
|
547
|
+
],
|
|
548
|
+
getOutroNextSteps: () => ["Start your development server to see PostHog in action", "Visit your PostHog dashboard to see incoming events"]
|
|
549
|
+
}
|
|
550
|
+
};
|
|
551
|
+
//#endregion
|
|
552
|
+
//#region src/frameworks/react-native/utils.ts
|
|
553
|
+
const getReactNativeVersionBucket = createVersionBucket();
|
|
554
|
+
function getReactNativeVariantName(variant) {
|
|
555
|
+
return variant === "expo" ? "Expo" : "React Native";
|
|
556
|
+
}
|
|
557
|
+
async function detectReactNativeVariant(options) {
|
|
558
|
+
const packageJson = await tryGetPackageJson(options);
|
|
559
|
+
if (packageJson && hasPackageInstalled("expo", packageJson)) {
|
|
560
|
+
getUI().setDetectedFramework(`${getReactNativeVariantName("expo")} 📱`);
|
|
561
|
+
return "expo";
|
|
562
|
+
}
|
|
563
|
+
getUI().setDetectedFramework(`${getReactNativeVariantName("react-native")} 📱`);
|
|
564
|
+
return "react-native";
|
|
565
|
+
}
|
|
566
|
+
//#endregion
|
|
567
|
+
//#region src/frameworks/react-native/react-native-wizard-agent.ts
|
|
568
|
+
const REACT_NATIVE_AGENT_CONFIG = {
|
|
569
|
+
metadata: {
|
|
570
|
+
name: "React Native",
|
|
571
|
+
integration: "react-native",
|
|
572
|
+
docsUrl: "https://posthog.com/docs/libraries/react-native",
|
|
573
|
+
gatherContext: async (options) => {
|
|
574
|
+
return { variant: await detectReactNativeVariant(options) };
|
|
575
|
+
}
|
|
576
|
+
},
|
|
577
|
+
detection: {
|
|
578
|
+
packageName: "react-native",
|
|
579
|
+
packageDisplayName: "React Native",
|
|
580
|
+
getVersion: (packageJson) => getPackageVersion("react-native", packageJson),
|
|
581
|
+
getVersionBucket: getReactNativeVersionBucket,
|
|
582
|
+
minimumVersion: "0.73.0",
|
|
583
|
+
getInstalledVersion: (options) => Promise.resolve(getInstalledPackageVersion("react-native", options.installDir)),
|
|
584
|
+
detect: async (options) => {
|
|
585
|
+
const packageJson = await tryGetPackageJson(options);
|
|
586
|
+
return packageJson ? hasPackageInstalled("react-native", packageJson) : false;
|
|
587
|
+
},
|
|
588
|
+
detectPackageManager: detectNodePackageManagers
|
|
589
|
+
},
|
|
590
|
+
environment: {
|
|
591
|
+
uploadToHosting: false,
|
|
592
|
+
getEnvVars: (apiKey, host) => ({
|
|
593
|
+
POSTHOG_PROJECT_TOKEN: apiKey,
|
|
594
|
+
POSTHOG_HOST: host
|
|
595
|
+
})
|
|
596
|
+
},
|
|
597
|
+
analytics: { getTags: (context) => ({ variant: context.variant === "expo" ? "expo" : "react-native" }) },
|
|
598
|
+
prompts: {
|
|
599
|
+
projectTypeDetection: "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.",
|
|
600
|
+
getAdditionalContextLines: (context) => {
|
|
601
|
+
const isExpo = context.variant === "expo";
|
|
602
|
+
const frameworkId = "react-native";
|
|
603
|
+
const lines = [`Framework docs ID: ${frameworkId} (use posthog://docs/frameworks/${frameworkId} for documentation)`, `Variant: ${isExpo ? "Expo" : "React Native"}`];
|
|
604
|
+
if (isExpo) lines.push("Use `npx expo install` for package installation.", "Use EXPO_PUBLIC_ prefix for environment variables exposed to the client.");
|
|
605
|
+
else lines.push("This is a React Native project without Expo. Native linking may be required.", "For iOS, ensure pods are installed after adding PostHog.");
|
|
606
|
+
return lines;
|
|
607
|
+
}
|
|
608
|
+
},
|
|
609
|
+
ui: {
|
|
610
|
+
successMessage: "PostHog integration complete",
|
|
611
|
+
estimatedDurationMinutes: 10,
|
|
612
|
+
getOutroChanges: (context) => {
|
|
613
|
+
return [
|
|
614
|
+
`Analyzed your React Native project structure (${getReactNativeVariantName(context.variant ?? "react-native")})`,
|
|
615
|
+
`Installed and configured the PostHog React Native SDK`,
|
|
616
|
+
`Integrated PostHog into your application`
|
|
617
|
+
];
|
|
618
|
+
},
|
|
619
|
+
getOutroNextSteps: (context) => {
|
|
620
|
+
const isExpo = context.variant === "expo";
|
|
621
|
+
const steps = [];
|
|
622
|
+
if (!isExpo) steps.push("Run `npx pod-install` to install iOS dependencies");
|
|
623
|
+
steps.push(isExpo ? "Start your development server with `npx expo start` to see PostHog in action" : "Start your development server to see PostHog in action", "Visit your PostHog dashboard to see incoming events");
|
|
624
|
+
return steps;
|
|
625
|
+
}
|
|
626
|
+
}
|
|
627
|
+
};
|
|
628
|
+
//#endregion
|
|
629
|
+
//#region src/frameworks/angular/angular-wizard-agent.ts
|
|
630
|
+
const ANGULAR_AGENT_CONFIG = {
|
|
631
|
+
metadata: {
|
|
632
|
+
name: "Angular",
|
|
633
|
+
integration: "angular",
|
|
634
|
+
docsUrl: "https://posthog.com/docs/libraries/angular"
|
|
635
|
+
},
|
|
636
|
+
detection: {
|
|
637
|
+
packageName: "@angular/core",
|
|
638
|
+
packageDisplayName: "Angular",
|
|
639
|
+
getVersion: (packageJson) => getPackageVersion("@angular/core", packageJson),
|
|
640
|
+
getVersionBucket: createVersionBucket(),
|
|
641
|
+
minimumVersion: "19.0.0",
|
|
642
|
+
getInstalledVersion: (options) => Promise.resolve(getInstalledPackageVersion("@angular/core", options.installDir)),
|
|
643
|
+
detect: async (options) => {
|
|
644
|
+
const packageJson = await tryGetPackageJson(options);
|
|
645
|
+
return packageJson ? hasPackageInstalled("@angular/core", packageJson) : false;
|
|
646
|
+
},
|
|
647
|
+
detectPackageManager: detectNodePackageManagers
|
|
648
|
+
},
|
|
649
|
+
environment: {
|
|
650
|
+
uploadToHosting: false,
|
|
651
|
+
getEnvVars: (apiKey, host) => ({
|
|
652
|
+
NG_APP_POSTHOG_PROJECT_TOKEN: apiKey,
|
|
653
|
+
NG_APP_POSTHOG_HOST: host
|
|
654
|
+
})
|
|
655
|
+
},
|
|
656
|
+
analytics: { getTags: () => ({}) },
|
|
657
|
+
prompts: {
|
|
658
|
+
projectTypeDetection: "This is an Angular project. Look for package.json, angular.json, and lockfiles (package-lock.json, yarn.lock, pnpm-lock.yaml) to confirm.",
|
|
659
|
+
getAdditionalContextLines: () => {
|
|
660
|
+
const frameworkId = "angular";
|
|
661
|
+
return [
|
|
662
|
+
`Framework docs ID: ${frameworkId} (use posthog://docs/frameworks/${frameworkId} for documentation)`,
|
|
663
|
+
"Angular uses dependency injection for services. PostHog should be initialized as a service.",
|
|
664
|
+
"For standalone components, ensure PostHog is properly provided in the application config."
|
|
665
|
+
];
|
|
666
|
+
}
|
|
667
|
+
},
|
|
668
|
+
ui: {
|
|
669
|
+
successMessage: "PostHog integration complete",
|
|
670
|
+
estimatedDurationMinutes: 8,
|
|
671
|
+
getOutroChanges: () => [
|
|
672
|
+
`Analyzed your Angular project structure`,
|
|
673
|
+
`Created and configured PostHog service`,
|
|
674
|
+
`Integrated PostHog into your application`
|
|
675
|
+
],
|
|
676
|
+
getOutroNextSteps: () => ["Start your development server with `ng serve` to see PostHog in action", "Visit your PostHog dashboard to see incoming events"]
|
|
677
|
+
}
|
|
678
|
+
};
|
|
679
|
+
//#endregion
|
|
680
|
+
//#region src/frameworks/astro/utils.ts
|
|
681
|
+
const getAstroVersionBucket = createVersionBucket();
|
|
682
|
+
const IGNORE_PATTERNS$6 = [
|
|
683
|
+
"**/node_modules/**",
|
|
684
|
+
"**/dist/**",
|
|
685
|
+
"**/.astro/**"
|
|
686
|
+
];
|
|
687
|
+
/**
|
|
688
|
+
* Detect the Astro rendering mode. Pure — always resolves (Astro detection is reliable).
|
|
689
|
+
*/
|
|
690
|
+
async function getAstroRenderingMode({ installDir }) {
|
|
691
|
+
const configMatches = await fg("astro.config.@(mjs|ts|js)", {
|
|
692
|
+
dot: true,
|
|
693
|
+
cwd: installDir,
|
|
694
|
+
ignore: IGNORE_PATTERNS$6
|
|
695
|
+
});
|
|
696
|
+
let hasAdapter = false;
|
|
697
|
+
let outputMode = null;
|
|
698
|
+
let usesViewTransitions = false;
|
|
699
|
+
try {
|
|
700
|
+
const packageJsonPath = path.join(installDir, "package.json");
|
|
701
|
+
const packageJsonContent = await fs.readFile(packageJsonPath, "utf-8");
|
|
702
|
+
const packageJson = JSON.parse(packageJsonContent);
|
|
703
|
+
const allDeps = {
|
|
704
|
+
...packageJson.dependencies,
|
|
705
|
+
...packageJson.devDependencies
|
|
706
|
+
};
|
|
707
|
+
hasAdapter = Object.keys(allDeps).some((dep) => dep.startsWith("@astrojs/") && (dep.includes("node") || dep.includes("vercel") || dep.includes("netlify") || dep.includes("cloudflare") || dep.includes("deno")));
|
|
708
|
+
} catch {}
|
|
709
|
+
if (configMatches.length > 0) try {
|
|
710
|
+
const configPath = path.join(installDir, configMatches[0]);
|
|
711
|
+
const outputMatch = (await fs.readFile(configPath, "utf-8")).match(/output:\s*['"](\w+)['"]/);
|
|
712
|
+
if (outputMatch) outputMode = outputMatch[1];
|
|
713
|
+
} catch {}
|
|
714
|
+
const viewTransitionMatches = await fg("**/*.@(astro|ts|tsx|js|jsx)", {
|
|
715
|
+
dot: true,
|
|
716
|
+
cwd: installDir,
|
|
717
|
+
ignore: IGNORE_PATTERNS$6
|
|
718
|
+
});
|
|
719
|
+
for (const file of viewTransitionMatches.slice(0, 20)) try {
|
|
720
|
+
const filePath = path.join(installDir, file);
|
|
721
|
+
const content = await fs.readFile(filePath, "utf-8");
|
|
722
|
+
if (content.includes("ClientRouter") || content.includes("ViewTransitions") || content.includes("astro:transitions")) {
|
|
723
|
+
usesViewTransitions = true;
|
|
724
|
+
break;
|
|
725
|
+
}
|
|
726
|
+
} catch {}
|
|
727
|
+
if (usesViewTransitions) return "view-transitions";
|
|
728
|
+
if (outputMode === "server" && hasAdapter) return "ssr";
|
|
729
|
+
if (hasAdapter) return "hybrid";
|
|
730
|
+
return "static";
|
|
731
|
+
}
|
|
732
|
+
const getAstroRenderingModeName = (mode) => {
|
|
733
|
+
switch (mode) {
|
|
734
|
+
case "static": return "Static (SSG)";
|
|
735
|
+
case "view-transitions": return "View Transitions";
|
|
736
|
+
case "ssr": return "Server (SSR)";
|
|
737
|
+
case "hybrid": return "Hybrid";
|
|
738
|
+
default: return "Static";
|
|
739
|
+
}
|
|
740
|
+
};
|
|
741
|
+
//#endregion
|
|
742
|
+
//#region src/frameworks/astro/astro-wizard-agent.ts
|
|
743
|
+
const ASTRO_AGENT_CONFIG = {
|
|
744
|
+
metadata: {
|
|
745
|
+
name: "Astro",
|
|
746
|
+
integration: "astro",
|
|
747
|
+
docsUrl: "https://posthog.com/docs/libraries/astro",
|
|
748
|
+
gatherContext: async (options) => {
|
|
749
|
+
const renderingMode = await getAstroRenderingMode(options);
|
|
750
|
+
getUI().setDetectedFramework(`Astro ${getAstroRenderingModeName(renderingMode)}`);
|
|
751
|
+
return { renderingMode };
|
|
752
|
+
}
|
|
753
|
+
},
|
|
754
|
+
detection: {
|
|
755
|
+
packageName: "astro",
|
|
756
|
+
packageDisplayName: "Astro",
|
|
757
|
+
getVersion: (packageJson) => getPackageVersion("astro", packageJson),
|
|
758
|
+
getVersionBucket: getAstroVersionBucket,
|
|
759
|
+
minimumVersion: "4.0.0",
|
|
760
|
+
getInstalledVersion: (options) => Promise.resolve(getInstalledPackageVersion("astro", options.installDir)),
|
|
761
|
+
detect: async (options) => {
|
|
762
|
+
const packageJson = await tryGetPackageJson(options);
|
|
763
|
+
return packageJson ? hasPackageInstalled("astro", packageJson) : false;
|
|
764
|
+
},
|
|
765
|
+
detectPackageManager: detectNodePackageManagers
|
|
766
|
+
},
|
|
767
|
+
environment: {
|
|
768
|
+
uploadToHosting: true,
|
|
769
|
+
getEnvVars: (apiKey, host) => ({
|
|
770
|
+
PUBLIC_POSTHOG_PROJECT_TOKEN: apiKey,
|
|
771
|
+
PUBLIC_POSTHOG_HOST: host
|
|
772
|
+
})
|
|
773
|
+
},
|
|
774
|
+
analytics: { getTags: (context) => ({ "rendering-mode": context.renderingMode ?? "static" }) },
|
|
775
|
+
prompts: {
|
|
776
|
+
projectTypeDetection: "This is a JavaScript/TypeScript project. Look for package.json and lockfiles (package-lock.json, yarn.lock, pnpm-lock.yaml, bun.lockb) to confirm.",
|
|
777
|
+
getAdditionalContextLines: (context) => {
|
|
778
|
+
const modeName = getAstroRenderingModeName(context.renderingMode ?? "static");
|
|
779
|
+
const frameworkId = {
|
|
780
|
+
["static"]: "astro-static",
|
|
781
|
+
["view-transitions"]: "astro-view-transitions",
|
|
782
|
+
["ssr"]: "astro-ssr",
|
|
783
|
+
["hybrid"]: "astro-hybrid"
|
|
784
|
+
}[context.renderingMode ?? "static"];
|
|
785
|
+
const lines = [`Rendering mode: ${modeName}`, `Framework docs ID: ${frameworkId} (use posthog://docs/frameworks/${frameworkId} for documentation)`];
|
|
786
|
+
if (context.renderingMode === "view-transitions") {
|
|
787
|
+
lines.push("IMPORTANT: Use window.__posthog_initialized guard to prevent re-initialization during soft navigation");
|
|
788
|
+
lines.push("IMPORTANT: Set capture_pageview: 'history_change' for automatic pageview tracking");
|
|
789
|
+
}
|
|
790
|
+
if (context.renderingMode === "ssr" || context.renderingMode === "hybrid") {
|
|
791
|
+
lines.push("IMPORTANT: Use posthog-node for server-side tracking in API routes");
|
|
792
|
+
lines.push("IMPORTANT: Create a singleton pattern for the posthog-node client");
|
|
793
|
+
}
|
|
794
|
+
return lines;
|
|
795
|
+
}
|
|
796
|
+
},
|
|
797
|
+
ui: {
|
|
798
|
+
successMessage: "PostHog integration complete",
|
|
799
|
+
estimatedDurationMinutes: 6,
|
|
800
|
+
getOutroChanges: (context) => {
|
|
801
|
+
const changes = [
|
|
802
|
+
`Analyzed your Astro project structure (${getAstroRenderingModeName(context.renderingMode ?? "static")})`,
|
|
803
|
+
`Created PostHog component with is:inline script`,
|
|
804
|
+
`Integrated PostHog into your layout`
|
|
805
|
+
];
|
|
806
|
+
if (context.renderingMode === "ssr" || context.renderingMode === "hybrid") changes.push(`Set up posthog-node for server-side tracking`);
|
|
807
|
+
if (context.renderingMode === "view-transitions") changes.push(`Added initialization guard for view transitions compatibility`);
|
|
808
|
+
return changes;
|
|
809
|
+
},
|
|
810
|
+
getOutroNextSteps: () => {
|
|
811
|
+
return ["Start your development server to see PostHog in action", "Visit your PostHog dashboard to see incoming events"];
|
|
812
|
+
}
|
|
813
|
+
}
|
|
814
|
+
};
|
|
815
|
+
//#endregion
|
|
816
|
+
//#region src/frameworks/django/utils.ts
|
|
817
|
+
const IGNORE_PATTERNS$5 = [
|
|
818
|
+
"**/node_modules/**",
|
|
819
|
+
"**/dist/**",
|
|
820
|
+
"**/build/**",
|
|
821
|
+
"**/venv/**",
|
|
822
|
+
"**/.venv/**",
|
|
823
|
+
"**/env/**",
|
|
824
|
+
"**/.env/**",
|
|
825
|
+
"**/__pycache__/**",
|
|
826
|
+
"**/migrations/**"
|
|
827
|
+
];
|
|
828
|
+
/**
|
|
829
|
+
* Get Django version bucket for analytics
|
|
830
|
+
*/
|
|
831
|
+
const getDjangoVersionBucket = createVersionBucket();
|
|
832
|
+
/**
|
|
833
|
+
* Extract Django version from requirements files or pyproject.toml
|
|
834
|
+
*/
|
|
835
|
+
async function getDjangoVersion(options) {
|
|
836
|
+
const { installDir } = options;
|
|
837
|
+
const requirementsFiles = await fg([
|
|
838
|
+
"**/requirements*.txt",
|
|
839
|
+
"**/pyproject.toml",
|
|
840
|
+
"**/setup.py",
|
|
841
|
+
"**/Pipfile"
|
|
842
|
+
], {
|
|
843
|
+
cwd: installDir,
|
|
844
|
+
ignore: IGNORE_PATTERNS$5
|
|
845
|
+
});
|
|
846
|
+
for (const reqFile of requirementsFiles) try {
|
|
847
|
+
const content = fs$1.readFileSync(path$1.join(installDir, reqFile), "utf-8");
|
|
848
|
+
const requirementsMatch = content.match(/[Dd]jango[=<>~!]+([0-9]+\.[0-9]+(?:\.[0-9]+)?)/);
|
|
849
|
+
if (requirementsMatch) return requirementsMatch[1];
|
|
850
|
+
const pyprojectMatch = content.match(/[Dd]jango["\s]*[=<>~!]+\s*["']?([0-9]+\.[0-9]+(?:\.[0-9]+)?)/);
|
|
851
|
+
if (pyprojectMatch) return pyprojectMatch[1];
|
|
852
|
+
} catch {
|
|
853
|
+
continue;
|
|
854
|
+
}
|
|
855
|
+
}
|
|
856
|
+
/**
|
|
857
|
+
* Check if Django REST Framework is installed
|
|
858
|
+
*/
|
|
859
|
+
async function hasDRF({ installDir }) {
|
|
860
|
+
const requirementsFiles = await fg([
|
|
861
|
+
"**/requirements*.txt",
|
|
862
|
+
"**/pyproject.toml",
|
|
863
|
+
"**/Pipfile"
|
|
864
|
+
], {
|
|
865
|
+
cwd: installDir,
|
|
866
|
+
ignore: IGNORE_PATTERNS$5
|
|
867
|
+
});
|
|
868
|
+
for (const reqFile of requirementsFiles) try {
|
|
869
|
+
if (fs$1.readFileSync(path$1.join(installDir, reqFile), "utf-8").includes("djangorestframework")) return true;
|
|
870
|
+
} catch {
|
|
871
|
+
continue;
|
|
872
|
+
}
|
|
873
|
+
const settingsFiles = await fg("**/settings.py", {
|
|
874
|
+
cwd: installDir,
|
|
875
|
+
ignore: IGNORE_PATTERNS$5
|
|
876
|
+
});
|
|
877
|
+
for (const settingsFile of settingsFiles) try {
|
|
878
|
+
if (fs$1.readFileSync(path$1.join(installDir, settingsFile), "utf-8").includes("rest_framework")) return true;
|
|
879
|
+
} catch {
|
|
880
|
+
continue;
|
|
881
|
+
}
|
|
882
|
+
return false;
|
|
883
|
+
}
|
|
884
|
+
/**
|
|
885
|
+
* Check if Wagtail is installed
|
|
886
|
+
*/
|
|
887
|
+
async function hasWagtail({ installDir }) {
|
|
888
|
+
const requirementsFiles = await fg([
|
|
889
|
+
"**/requirements*.txt",
|
|
890
|
+
"**/pyproject.toml",
|
|
891
|
+
"**/Pipfile"
|
|
892
|
+
], {
|
|
893
|
+
cwd: installDir,
|
|
894
|
+
ignore: IGNORE_PATTERNS$5
|
|
895
|
+
});
|
|
896
|
+
for (const reqFile of requirementsFiles) try {
|
|
897
|
+
if (fs$1.readFileSync(path$1.join(installDir, reqFile), "utf-8").includes("wagtail")) return true;
|
|
898
|
+
} catch {
|
|
899
|
+
continue;
|
|
900
|
+
}
|
|
901
|
+
return false;
|
|
902
|
+
}
|
|
903
|
+
/**
|
|
904
|
+
* Check if Django Channels is installed
|
|
905
|
+
*/
|
|
906
|
+
async function hasChannels({ installDir }) {
|
|
907
|
+
const requirementsFiles = await fg([
|
|
908
|
+
"**/requirements*.txt",
|
|
909
|
+
"**/pyproject.toml",
|
|
910
|
+
"**/Pipfile"
|
|
911
|
+
], {
|
|
912
|
+
cwd: installDir,
|
|
913
|
+
ignore: IGNORE_PATTERNS$5
|
|
914
|
+
});
|
|
915
|
+
for (const reqFile of requirementsFiles) try {
|
|
916
|
+
if (fs$1.readFileSync(path$1.join(installDir, reqFile), "utf-8").includes("channels")) return true;
|
|
917
|
+
} catch {
|
|
918
|
+
continue;
|
|
919
|
+
}
|
|
920
|
+
return false;
|
|
921
|
+
}
|
|
922
|
+
/**
|
|
923
|
+
* Detect Django project type
|
|
924
|
+
*/
|
|
925
|
+
async function getDjangoProjectType(options) {
|
|
926
|
+
const { installDir } = options;
|
|
927
|
+
if (await hasWagtail({ installDir })) {
|
|
928
|
+
getUI().setDetectedFramework("Django with Wagtail CMS");
|
|
929
|
+
return "wagtail";
|
|
930
|
+
}
|
|
931
|
+
if (await hasDRF({ installDir })) {
|
|
932
|
+
getUI().setDetectedFramework("Django REST Framework");
|
|
933
|
+
return "drf";
|
|
934
|
+
}
|
|
935
|
+
if (await hasChannels({ installDir })) {
|
|
936
|
+
getUI().setDetectedFramework("Django Channels");
|
|
937
|
+
return "channels";
|
|
938
|
+
}
|
|
939
|
+
getUI().setDetectedFramework("Django");
|
|
940
|
+
return "standard";
|
|
941
|
+
}
|
|
942
|
+
/**
|
|
943
|
+
* Get human-readable name for Django project type
|
|
944
|
+
*/
|
|
945
|
+
function getDjangoProjectTypeName(projectType) {
|
|
946
|
+
switch (projectType) {
|
|
947
|
+
case "standard": return "Standard Django";
|
|
948
|
+
case "drf": return "Django REST Framework";
|
|
949
|
+
case "wagtail": return "Wagtail CMS";
|
|
950
|
+
case "channels": return "Django Channels";
|
|
951
|
+
}
|
|
952
|
+
}
|
|
953
|
+
/**
|
|
954
|
+
* Find the main Django settings file
|
|
955
|
+
*/
|
|
956
|
+
async function findDjangoSettingsFile(options) {
|
|
957
|
+
const { installDir } = options;
|
|
958
|
+
const settingsFiles = await fg("**/settings.py", {
|
|
959
|
+
cwd: installDir,
|
|
960
|
+
ignore: IGNORE_PATTERNS$5
|
|
961
|
+
});
|
|
962
|
+
if (settingsFiles.length === 0) {
|
|
963
|
+
const splitSettingsFiles = await fg("**/settings/__init__.py", {
|
|
964
|
+
cwd: installDir,
|
|
965
|
+
ignore: IGNORE_PATTERNS$5
|
|
966
|
+
});
|
|
967
|
+
if (splitSettingsFiles.length > 0) return splitSettingsFiles[0];
|
|
968
|
+
return;
|
|
969
|
+
}
|
|
970
|
+
if (settingsFiles.length === 1) return settingsFiles[0];
|
|
971
|
+
for (const settingsFile of settingsFiles) try {
|
|
972
|
+
if (fs$1.readFileSync(path$1.join(installDir, settingsFile), "utf-8").includes("ROOT_URLCONF")) return settingsFile;
|
|
973
|
+
} catch {
|
|
974
|
+
continue;
|
|
975
|
+
}
|
|
976
|
+
return settingsFiles[0];
|
|
977
|
+
}
|
|
978
|
+
//#endregion
|
|
979
|
+
//#region src/frameworks/django/django-wizard-agent.ts
|
|
980
|
+
const DJANGO_AGENT_CONFIG = {
|
|
981
|
+
metadata: {
|
|
982
|
+
name: "Django",
|
|
983
|
+
integration: "django",
|
|
984
|
+
beta: true,
|
|
985
|
+
docsUrl: "https://posthog.com/docs/libraries/django",
|
|
986
|
+
unsupportedVersionDocsUrl: "https://posthog.com/docs/libraries/python",
|
|
987
|
+
gatherContext: async (options) => {
|
|
988
|
+
return {
|
|
989
|
+
projectType: await getDjangoProjectType(options),
|
|
990
|
+
settingsFile: await findDjangoSettingsFile(options)
|
|
991
|
+
};
|
|
992
|
+
}
|
|
993
|
+
},
|
|
994
|
+
detection: {
|
|
995
|
+
packageName: "django",
|
|
996
|
+
packageDisplayName: "Django",
|
|
997
|
+
usesPackageJson: false,
|
|
998
|
+
getVersion: () => void 0,
|
|
999
|
+
getVersionBucket: getDjangoVersionBucket,
|
|
1000
|
+
minimumVersion: "3.0.0",
|
|
1001
|
+
getInstalledVersion: (options) => getDjangoVersion(options),
|
|
1002
|
+
detect: async (options) => {
|
|
1003
|
+
const { installDir } = options;
|
|
1004
|
+
const managePyMatches = await fg("**/manage.py", {
|
|
1005
|
+
cwd: installDir,
|
|
1006
|
+
ignore: [
|
|
1007
|
+
"**/venv/**",
|
|
1008
|
+
"**/.venv/**",
|
|
1009
|
+
"**/env/**",
|
|
1010
|
+
"**/.env/**"
|
|
1011
|
+
]
|
|
1012
|
+
});
|
|
1013
|
+
if (managePyMatches.length > 0) for (const match of managePyMatches) try {
|
|
1014
|
+
const content = fs$1.readFileSync(path$1.join(installDir, match), "utf-8");
|
|
1015
|
+
if (content.includes("from django") || content.includes("import django") || content.includes("DJANGO_SETTINGS_MODULE") || /execute_from_command_line/.test(content)) return true;
|
|
1016
|
+
} catch {
|
|
1017
|
+
continue;
|
|
1018
|
+
}
|
|
1019
|
+
const requirementsFiles = await fg([
|
|
1020
|
+
"**/requirements*.txt",
|
|
1021
|
+
"**/pyproject.toml",
|
|
1022
|
+
"**/setup.py"
|
|
1023
|
+
], {
|
|
1024
|
+
cwd: installDir,
|
|
1025
|
+
ignore: [
|
|
1026
|
+
"**/venv/**",
|
|
1027
|
+
"**/.venv/**",
|
|
1028
|
+
"**/env/**",
|
|
1029
|
+
"**/.env/**"
|
|
1030
|
+
]
|
|
1031
|
+
});
|
|
1032
|
+
for (const reqFile of requirementsFiles) try {
|
|
1033
|
+
const content = fs$1.readFileSync(path$1.join(installDir, reqFile), "utf-8");
|
|
1034
|
+
if (/^django([>=~!<\s]|$)/im.test(content) || /["']django["']/i.test(content)) return true;
|
|
1035
|
+
} catch {
|
|
1036
|
+
continue;
|
|
1037
|
+
}
|
|
1038
|
+
return false;
|
|
1039
|
+
},
|
|
1040
|
+
detectPackageManager: detectPythonPackageManagers
|
|
1041
|
+
},
|
|
1042
|
+
environment: {
|
|
1043
|
+
uploadToHosting: false,
|
|
1044
|
+
getEnvVars: (apiKey, host) => ({
|
|
1045
|
+
POSTHOG_PROJECT_TOKEN: apiKey,
|
|
1046
|
+
POSTHOG_HOST: host
|
|
1047
|
+
})
|
|
1048
|
+
},
|
|
1049
|
+
analytics: { getTags: (context) => ({ projectType: context.projectType || "unknown" }) },
|
|
1050
|
+
prompts: {
|
|
1051
|
+
packageInstallation: PYTHON_PACKAGE_INSTALLATION,
|
|
1052
|
+
projectTypeDetection: "This is a Python/Django project. Look for requirements.txt, pyproject.toml, setup.py, Pipfile, or manage.py to confirm.",
|
|
1053
|
+
getAdditionalContextLines: (context) => {
|
|
1054
|
+
const projectTypeName = context.projectType ? getDjangoProjectTypeName(context.projectType) : "unknown";
|
|
1055
|
+
const frameworkId = context.projectType ? {
|
|
1056
|
+
["standard"]: "django",
|
|
1057
|
+
["drf"]: "django",
|
|
1058
|
+
["wagtail"]: "django",
|
|
1059
|
+
["channels"]: "django"
|
|
1060
|
+
}[context.projectType] : "django";
|
|
1061
|
+
const lines = [`Project type: ${projectTypeName}`, `Framework docs ID: ${frameworkId} (use posthog://docs/frameworks/${frameworkId} for documentation)`];
|
|
1062
|
+
if (context.settingsFile) lines.push(`Settings file: ${context.settingsFile}`);
|
|
1063
|
+
return lines;
|
|
1064
|
+
}
|
|
1065
|
+
},
|
|
1066
|
+
ui: {
|
|
1067
|
+
successMessage: "PostHog integration complete",
|
|
1068
|
+
estimatedDurationMinutes: 5,
|
|
1069
|
+
getOutroChanges: (context) => {
|
|
1070
|
+
return [
|
|
1071
|
+
`Analyzed your ${context.projectType ? getDjangoProjectTypeName(context.projectType) : "Django"} project structure`,
|
|
1072
|
+
`Installed the PostHog Python package`,
|
|
1073
|
+
`Configured PostHog in your Django settings`,
|
|
1074
|
+
`Added PostHog middleware for automatic event tracking`
|
|
1075
|
+
];
|
|
1076
|
+
},
|
|
1077
|
+
getOutroNextSteps: () => [
|
|
1078
|
+
"Start your Django development server to see PostHog in action",
|
|
1079
|
+
"Visit your PostHog dashboard to see incoming events",
|
|
1080
|
+
"Use identify_context() within new_context() to associate events with users"
|
|
1081
|
+
]
|
|
1082
|
+
}
|
|
1083
|
+
};
|
|
1084
|
+
//#endregion
|
|
1085
|
+
//#region src/frameworks/flask/utils.ts
|
|
1086
|
+
const IGNORE_PATTERNS$4 = [
|
|
1087
|
+
"**/node_modules/**",
|
|
1088
|
+
"**/dist/**",
|
|
1089
|
+
"**/build/**",
|
|
1090
|
+
"**/venv/**",
|
|
1091
|
+
"**/.venv/**",
|
|
1092
|
+
"**/env/**",
|
|
1093
|
+
"**/.env/**",
|
|
1094
|
+
"**/__pycache__/**",
|
|
1095
|
+
"**/migrations/**",
|
|
1096
|
+
"**/instance/**"
|
|
1097
|
+
];
|
|
1098
|
+
/**
|
|
1099
|
+
* Get Flask version bucket for analytics
|
|
1100
|
+
*/
|
|
1101
|
+
const getFlaskVersionBucket = createVersionBucket();
|
|
1102
|
+
/**
|
|
1103
|
+
* Extract Flask version from requirements files or pyproject.toml
|
|
1104
|
+
*/
|
|
1105
|
+
async function getFlaskVersion(options) {
|
|
1106
|
+
const { installDir } = options;
|
|
1107
|
+
const requirementsFiles = await fg([
|
|
1108
|
+
"**/requirements*.txt",
|
|
1109
|
+
"**/pyproject.toml",
|
|
1110
|
+
"**/setup.py",
|
|
1111
|
+
"**/Pipfile"
|
|
1112
|
+
], {
|
|
1113
|
+
cwd: installDir,
|
|
1114
|
+
ignore: IGNORE_PATTERNS$4
|
|
1115
|
+
});
|
|
1116
|
+
for (const reqFile of requirementsFiles) try {
|
|
1117
|
+
const content = fs$1.readFileSync(path$1.join(installDir, reqFile), "utf-8");
|
|
1118
|
+
const requirementsMatch = content.match(/[Ff]lask[=<>~!]+([0-9]+\.[0-9]+(?:\.[0-9]+)?)/);
|
|
1119
|
+
if (requirementsMatch) return requirementsMatch[1];
|
|
1120
|
+
const pyprojectMatch = content.match(/[Ff]lask["\s]*[=<>~!]+\s*["']?([0-9]+\.[0-9]+(?:\.[0-9]+)?)/);
|
|
1121
|
+
if (pyprojectMatch) return pyprojectMatch[1];
|
|
1122
|
+
} catch {
|
|
1123
|
+
continue;
|
|
1124
|
+
}
|
|
1125
|
+
}
|
|
1126
|
+
/**
|
|
1127
|
+
* Check if Flask-RESTful is installed
|
|
1128
|
+
*/
|
|
1129
|
+
async function hasFlaskRESTful({ installDir }) {
|
|
1130
|
+
const requirementsFiles = await fg([
|
|
1131
|
+
"**/requirements*.txt",
|
|
1132
|
+
"**/pyproject.toml",
|
|
1133
|
+
"**/Pipfile"
|
|
1134
|
+
], {
|
|
1135
|
+
cwd: installDir,
|
|
1136
|
+
ignore: IGNORE_PATTERNS$4
|
|
1137
|
+
});
|
|
1138
|
+
for (const reqFile of requirementsFiles) try {
|
|
1139
|
+
const content = fs$1.readFileSync(path$1.join(installDir, reqFile), "utf-8");
|
|
1140
|
+
if (content.includes("flask-restful") || content.includes("Flask-RESTful")) return true;
|
|
1141
|
+
} catch {
|
|
1142
|
+
continue;
|
|
1143
|
+
}
|
|
1144
|
+
const pyFiles = await fg(["**/*.py"], {
|
|
1145
|
+
cwd: installDir,
|
|
1146
|
+
ignore: IGNORE_PATTERNS$4
|
|
1147
|
+
});
|
|
1148
|
+
for (const pyFile of pyFiles) try {
|
|
1149
|
+
const content = fs$1.readFileSync(path$1.join(installDir, pyFile), "utf-8");
|
|
1150
|
+
if (content.includes("from flask_restful import") || content.includes("import flask_restful")) return true;
|
|
1151
|
+
} catch {
|
|
1152
|
+
continue;
|
|
1153
|
+
}
|
|
1154
|
+
return false;
|
|
1155
|
+
}
|
|
1156
|
+
/**
|
|
1157
|
+
* Check if Flask-RESTX is installed
|
|
1158
|
+
*/
|
|
1159
|
+
async function hasFlaskRESTX({ installDir }) {
|
|
1160
|
+
const requirementsFiles = await fg([
|
|
1161
|
+
"**/requirements*.txt",
|
|
1162
|
+
"**/pyproject.toml",
|
|
1163
|
+
"**/Pipfile"
|
|
1164
|
+
], {
|
|
1165
|
+
cwd: installDir,
|
|
1166
|
+
ignore: IGNORE_PATTERNS$4
|
|
1167
|
+
});
|
|
1168
|
+
for (const reqFile of requirementsFiles) try {
|
|
1169
|
+
const content = fs$1.readFileSync(path$1.join(installDir, reqFile), "utf-8");
|
|
1170
|
+
if (content.includes("flask-restx") || content.includes("Flask-RESTX")) return true;
|
|
1171
|
+
} catch {
|
|
1172
|
+
continue;
|
|
1173
|
+
}
|
|
1174
|
+
const pyFiles = await fg(["**/*.py"], {
|
|
1175
|
+
cwd: installDir,
|
|
1176
|
+
ignore: IGNORE_PATTERNS$4
|
|
1177
|
+
});
|
|
1178
|
+
for (const pyFile of pyFiles) try {
|
|
1179
|
+
const content = fs$1.readFileSync(path$1.join(installDir, pyFile), "utf-8");
|
|
1180
|
+
if (content.includes("from flask_restx import") || content.includes("import flask_restx")) return true;
|
|
1181
|
+
} catch {
|
|
1182
|
+
continue;
|
|
1183
|
+
}
|
|
1184
|
+
return false;
|
|
1185
|
+
}
|
|
1186
|
+
/**
|
|
1187
|
+
* Check if flask-smorest is installed
|
|
1188
|
+
*/
|
|
1189
|
+
async function hasFlaskSmorest({ installDir }) {
|
|
1190
|
+
const requirementsFiles = await fg([
|
|
1191
|
+
"**/requirements*.txt",
|
|
1192
|
+
"**/pyproject.toml",
|
|
1193
|
+
"**/Pipfile"
|
|
1194
|
+
], {
|
|
1195
|
+
cwd: installDir,
|
|
1196
|
+
ignore: IGNORE_PATTERNS$4
|
|
1197
|
+
});
|
|
1198
|
+
for (const reqFile of requirementsFiles) try {
|
|
1199
|
+
if (fs$1.readFileSync(path$1.join(installDir, reqFile), "utf-8").includes("flask-smorest")) return true;
|
|
1200
|
+
} catch {
|
|
1201
|
+
continue;
|
|
1202
|
+
}
|
|
1203
|
+
const pyFiles = await fg(["**/*.py"], {
|
|
1204
|
+
cwd: installDir,
|
|
1205
|
+
ignore: IGNORE_PATTERNS$4
|
|
1206
|
+
});
|
|
1207
|
+
for (const pyFile of pyFiles) try {
|
|
1208
|
+
const content = fs$1.readFileSync(path$1.join(installDir, pyFile), "utf-8");
|
|
1209
|
+
if (content.includes("from flask_smorest import") || content.includes("import flask_smorest")) return true;
|
|
1210
|
+
} catch {
|
|
1211
|
+
continue;
|
|
1212
|
+
}
|
|
1213
|
+
return false;
|
|
1214
|
+
}
|
|
1215
|
+
/**
|
|
1216
|
+
* Check if app uses Flask Blueprints
|
|
1217
|
+
*/
|
|
1218
|
+
async function hasBlueprints({ installDir }) {
|
|
1219
|
+
const pyFiles = await fg(["**/*.py"], {
|
|
1220
|
+
cwd: installDir,
|
|
1221
|
+
ignore: IGNORE_PATTERNS$4
|
|
1222
|
+
});
|
|
1223
|
+
for (const pyFile of pyFiles) try {
|
|
1224
|
+
const content = fs$1.readFileSync(path$1.join(installDir, pyFile), "utf-8");
|
|
1225
|
+
if (content.includes("Blueprint(") || content.includes("register_blueprint(") || content.includes("from flask import Blueprint")) return true;
|
|
1226
|
+
} catch {
|
|
1227
|
+
continue;
|
|
1228
|
+
}
|
|
1229
|
+
return false;
|
|
1230
|
+
}
|
|
1231
|
+
/**
|
|
1232
|
+
* Detect Flask project type
|
|
1233
|
+
*/
|
|
1234
|
+
async function getFlaskProjectType(options) {
|
|
1235
|
+
const { installDir } = options;
|
|
1236
|
+
if (await hasFlaskRESTX({ installDir })) {
|
|
1237
|
+
getUI().setDetectedFramework("Flask-RESTX");
|
|
1238
|
+
return "restx";
|
|
1239
|
+
}
|
|
1240
|
+
if (await hasFlaskSmorest({ installDir })) {
|
|
1241
|
+
getUI().setDetectedFramework("flask-smorest");
|
|
1242
|
+
return "smorest";
|
|
1243
|
+
}
|
|
1244
|
+
if (await hasFlaskRESTful({ installDir })) {
|
|
1245
|
+
getUI().setDetectedFramework("Flask-RESTful");
|
|
1246
|
+
return "restful";
|
|
1247
|
+
}
|
|
1248
|
+
if (await hasBlueprints({ installDir })) {
|
|
1249
|
+
getUI().setDetectedFramework("Flask with Blueprints");
|
|
1250
|
+
return "blueprint";
|
|
1251
|
+
}
|
|
1252
|
+
getUI().setDetectedFramework("Flask");
|
|
1253
|
+
return "standard";
|
|
1254
|
+
}
|
|
1255
|
+
/**
|
|
1256
|
+
* Get human-readable name for Flask project type
|
|
1257
|
+
*/
|
|
1258
|
+
function getFlaskProjectTypeName(projectType) {
|
|
1259
|
+
switch (projectType) {
|
|
1260
|
+
case "standard": return "Standard Flask";
|
|
1261
|
+
case "restful": return "Flask-RESTful";
|
|
1262
|
+
case "restx": return "Flask-RESTX";
|
|
1263
|
+
case "smorest": return "flask-smorest";
|
|
1264
|
+
case "blueprint": return "Flask with Blueprints";
|
|
1265
|
+
}
|
|
1266
|
+
}
|
|
1267
|
+
/**
|
|
1268
|
+
* Find the main Flask app file
|
|
1269
|
+
*/
|
|
1270
|
+
async function findFlaskAppFile(options) {
|
|
1271
|
+
const { installDir } = options;
|
|
1272
|
+
const appFiles = await fg([
|
|
1273
|
+
"**/app.py",
|
|
1274
|
+
"**/wsgi.py",
|
|
1275
|
+
"**/application.py",
|
|
1276
|
+
"**/run.py",
|
|
1277
|
+
"**/main.py",
|
|
1278
|
+
"**/__init__.py"
|
|
1279
|
+
], {
|
|
1280
|
+
cwd: installDir,
|
|
1281
|
+
ignore: IGNORE_PATTERNS$4
|
|
1282
|
+
});
|
|
1283
|
+
for (const appFile of appFiles) try {
|
|
1284
|
+
const content = fs$1.readFileSync(path$1.join(installDir, appFile), "utf-8");
|
|
1285
|
+
if (content.includes("Flask(__name__)") || content.includes("Flask(") || content.includes("def create_app(")) return appFile;
|
|
1286
|
+
} catch {
|
|
1287
|
+
continue;
|
|
1288
|
+
}
|
|
1289
|
+
const allPyFiles = await fg(["**/*.py"], {
|
|
1290
|
+
cwd: installDir,
|
|
1291
|
+
ignore: IGNORE_PATTERNS$4
|
|
1292
|
+
});
|
|
1293
|
+
for (const pyFile of allPyFiles) try {
|
|
1294
|
+
const content = fs$1.readFileSync(path$1.join(installDir, pyFile), "utf-8");
|
|
1295
|
+
if (content.includes("Flask(__name__)") || content.includes("def create_app(")) return pyFile;
|
|
1296
|
+
} catch {
|
|
1297
|
+
continue;
|
|
1298
|
+
}
|
|
1299
|
+
if (appFiles.length > 0) return appFiles[0];
|
|
1300
|
+
}
|
|
1301
|
+
//#endregion
|
|
1302
|
+
//#region src/frameworks/flask/flask-wizard-agent.ts
|
|
1303
|
+
const FLASK_AGENT_CONFIG = {
|
|
1304
|
+
metadata: {
|
|
1305
|
+
name: "Flask",
|
|
1306
|
+
integration: "flask",
|
|
1307
|
+
beta: true,
|
|
1308
|
+
docsUrl: "https://posthog.com/docs/libraries/python",
|
|
1309
|
+
unsupportedVersionDocsUrl: "https://posthog.com/docs/libraries/python",
|
|
1310
|
+
gatherContext: async (options) => {
|
|
1311
|
+
return {
|
|
1312
|
+
projectType: await getFlaskProjectType(options),
|
|
1313
|
+
appFile: await findFlaskAppFile(options)
|
|
1314
|
+
};
|
|
1315
|
+
}
|
|
1316
|
+
},
|
|
1317
|
+
detection: {
|
|
1318
|
+
packageName: "flask",
|
|
1319
|
+
packageDisplayName: "Flask",
|
|
1320
|
+
usesPackageJson: false,
|
|
1321
|
+
getVersion: () => void 0,
|
|
1322
|
+
getVersionBucket: getFlaskVersionBucket,
|
|
1323
|
+
minimumVersion: "2.0.0",
|
|
1324
|
+
getInstalledVersion: (options) => getFlaskVersion(options),
|
|
1325
|
+
detect: async (options) => {
|
|
1326
|
+
const { installDir } = options;
|
|
1327
|
+
const requirementsFiles = await fg([
|
|
1328
|
+
"**/requirements*.txt",
|
|
1329
|
+
"**/pyproject.toml",
|
|
1330
|
+
"**/setup.py",
|
|
1331
|
+
"**/Pipfile"
|
|
1332
|
+
], {
|
|
1333
|
+
cwd: installDir,
|
|
1334
|
+
ignore: [
|
|
1335
|
+
"**/venv/**",
|
|
1336
|
+
"**/.venv/**",
|
|
1337
|
+
"**/env/**",
|
|
1338
|
+
"**/.env/**"
|
|
1339
|
+
]
|
|
1340
|
+
});
|
|
1341
|
+
for (const reqFile of requirementsFiles) try {
|
|
1342
|
+
const content = fs$1.readFileSync(path$1.join(installDir, reqFile), "utf-8");
|
|
1343
|
+
if (/^flask([<>=~!]|$|\s)/im.test(content) || /["']flask["']/i.test(content)) return true;
|
|
1344
|
+
} catch {
|
|
1345
|
+
continue;
|
|
1346
|
+
}
|
|
1347
|
+
const pyFiles = await fg([
|
|
1348
|
+
"**/app.py",
|
|
1349
|
+
"**/wsgi.py",
|
|
1350
|
+
"**/application.py",
|
|
1351
|
+
"**/__init__.py"
|
|
1352
|
+
], {
|
|
1353
|
+
cwd: installDir,
|
|
1354
|
+
ignore: [
|
|
1355
|
+
"**/venv/**",
|
|
1356
|
+
"**/.venv/**",
|
|
1357
|
+
"**/env/**",
|
|
1358
|
+
"**/.env/**",
|
|
1359
|
+
"**/__pycache__/**"
|
|
1360
|
+
]
|
|
1361
|
+
});
|
|
1362
|
+
for (const pyFile of pyFiles) try {
|
|
1363
|
+
const content = fs$1.readFileSync(path$1.join(installDir, pyFile), "utf-8");
|
|
1364
|
+
if (content.includes("from flask import") || content.includes("import flask") || /Flask\s*\(/.test(content)) return true;
|
|
1365
|
+
} catch {
|
|
1366
|
+
continue;
|
|
1367
|
+
}
|
|
1368
|
+
return false;
|
|
1369
|
+
},
|
|
1370
|
+
detectPackageManager: detectPythonPackageManagers
|
|
1371
|
+
},
|
|
1372
|
+
environment: {
|
|
1373
|
+
uploadToHosting: false,
|
|
1374
|
+
getEnvVars: (apiKey, host) => ({
|
|
1375
|
+
POSTHOG_PROJECT_TOKEN: apiKey,
|
|
1376
|
+
POSTHOG_HOST: host
|
|
1377
|
+
})
|
|
1378
|
+
},
|
|
1379
|
+
analytics: { getTags: (context) => ({ projectType: context.projectType || "unknown" }) },
|
|
1380
|
+
prompts: {
|
|
1381
|
+
packageInstallation: PYTHON_PACKAGE_INSTALLATION,
|
|
1382
|
+
projectTypeDetection: "This is a Python/Flask project. Look for requirements.txt, pyproject.toml, setup.py, Pipfile, or app.py/wsgi.py to confirm.",
|
|
1383
|
+
getAdditionalContextLines: (context) => {
|
|
1384
|
+
const projectTypeName = context.projectType ? getFlaskProjectTypeName(context.projectType) : "unknown";
|
|
1385
|
+
const frameworkId = context.projectType ? {
|
|
1386
|
+
["standard"]: "flask",
|
|
1387
|
+
["restful"]: "flask",
|
|
1388
|
+
["restx"]: "flask",
|
|
1389
|
+
["smorest"]: "flask",
|
|
1390
|
+
["blueprint"]: "flask"
|
|
1391
|
+
}[context.projectType] : "flask";
|
|
1392
|
+
const lines = [`Project type: ${projectTypeName}`, `Framework docs ID: ${frameworkId} (use posthog://docs/frameworks/${frameworkId} for documentation)`];
|
|
1393
|
+
if (context.appFile) lines.push(`App file: ${context.appFile}`);
|
|
1394
|
+
return lines;
|
|
1395
|
+
}
|
|
1396
|
+
},
|
|
1397
|
+
ui: {
|
|
1398
|
+
successMessage: "PostHog integration complete",
|
|
1399
|
+
estimatedDurationMinutes: 5,
|
|
1400
|
+
getOutroChanges: (context) => {
|
|
1401
|
+
return [
|
|
1402
|
+
`Analyzed your ${context.projectType ? getFlaskProjectTypeName(context.projectType) : "Flask"} project structure`,
|
|
1403
|
+
`Installed the PostHog Python package`,
|
|
1404
|
+
`Configured PostHog in your Flask application`,
|
|
1405
|
+
`Added PostHog initialization with automatic event tracking`
|
|
1406
|
+
];
|
|
1407
|
+
},
|
|
1408
|
+
getOutroNextSteps: () => [
|
|
1409
|
+
"Start your Flask development server to see PostHog in action",
|
|
1410
|
+
"Visit your PostHog dashboard to see incoming events",
|
|
1411
|
+
"Use posthog.identify() to associate events with users"
|
|
1412
|
+
]
|
|
1413
|
+
}
|
|
1414
|
+
};
|
|
1415
|
+
//#endregion
|
|
1416
|
+
//#region src/frameworks/fastapi/utils.ts
|
|
1417
|
+
const IGNORE_PATTERNS$3 = [
|
|
1418
|
+
"**/node_modules/**",
|
|
1419
|
+
"**/dist/**",
|
|
1420
|
+
"**/build/**",
|
|
1421
|
+
"**/venv/**",
|
|
1422
|
+
"**/.venv/**",
|
|
1423
|
+
"**/env/**",
|
|
1424
|
+
"**/.env/**",
|
|
1425
|
+
"**/__pycache__/**",
|
|
1426
|
+
"**/migrations/**"
|
|
1427
|
+
];
|
|
1428
|
+
/**
|
|
1429
|
+
* Get FastAPI version bucket for analytics
|
|
1430
|
+
*/
|
|
1431
|
+
function getFastAPIVersionBucket(version) {
|
|
1432
|
+
if (!version) return "none";
|
|
1433
|
+
try {
|
|
1434
|
+
const minVer = minVersion(version);
|
|
1435
|
+
if (!minVer) return "invalid";
|
|
1436
|
+
const majorVersion = major(minVer);
|
|
1437
|
+
if (majorVersion === 0) return "0.x";
|
|
1438
|
+
return `${majorVersion}.x`;
|
|
1439
|
+
} catch {
|
|
1440
|
+
return "unknown";
|
|
1441
|
+
}
|
|
1442
|
+
}
|
|
1443
|
+
/**
|
|
1444
|
+
* Extract FastAPI version from requirements files or pyproject.toml
|
|
1445
|
+
*/
|
|
1446
|
+
async function getFastAPIVersion(options) {
|
|
1447
|
+
const { installDir } = options;
|
|
1448
|
+
const requirementsFiles = await fg([
|
|
1449
|
+
"**/requirements*.txt",
|
|
1450
|
+
"**/pyproject.toml",
|
|
1451
|
+
"**/setup.py",
|
|
1452
|
+
"**/Pipfile"
|
|
1453
|
+
], {
|
|
1454
|
+
cwd: installDir,
|
|
1455
|
+
ignore: IGNORE_PATTERNS$3
|
|
1456
|
+
});
|
|
1457
|
+
for (const reqFile of requirementsFiles) try {
|
|
1458
|
+
const content = fs$1.readFileSync(path$1.join(installDir, reqFile), "utf-8");
|
|
1459
|
+
const requirementsMatch = content.match(/[Ff]ast[Aa][Pp][Ii][=<>~!]+([0-9]+\.[0-9]+(?:\.[0-9]+)?)/);
|
|
1460
|
+
if (requirementsMatch) return requirementsMatch[1];
|
|
1461
|
+
const pyprojectMatch = content.match(/[Ff]ast[Aa][Pp][Ii]["\s]*[=<>~!]+\s*["']?([0-9]+\.[0-9]+(?:\.[0-9]+)?)/);
|
|
1462
|
+
if (pyprojectMatch) return pyprojectMatch[1];
|
|
1463
|
+
} catch {
|
|
1464
|
+
continue;
|
|
1465
|
+
}
|
|
1466
|
+
}
|
|
1467
|
+
/**
|
|
1468
|
+
* Check if app uses FastAPI APIRouter
|
|
1469
|
+
*/
|
|
1470
|
+
async function hasAPIRouter({ installDir }) {
|
|
1471
|
+
const pyFiles = await fg(["**/*.py"], {
|
|
1472
|
+
cwd: installDir,
|
|
1473
|
+
ignore: IGNORE_PATTERNS$3
|
|
1474
|
+
});
|
|
1475
|
+
for (const pyFile of pyFiles) try {
|
|
1476
|
+
const content = fs$1.readFileSync(path$1.join(installDir, pyFile), "utf-8");
|
|
1477
|
+
if (content.includes("APIRouter(") || content.includes("include_router(") || content.includes("from fastapi import APIRouter")) return true;
|
|
1478
|
+
} catch {
|
|
1479
|
+
continue;
|
|
1480
|
+
}
|
|
1481
|
+
return false;
|
|
1482
|
+
}
|
|
1483
|
+
/**
|
|
1484
|
+
* Check if app uses Jinja2 templates (fullstack pattern)
|
|
1485
|
+
*/
|
|
1486
|
+
async function hasTemplates({ installDir }) {
|
|
1487
|
+
const pyFiles = await fg(["**/*.py"], {
|
|
1488
|
+
cwd: installDir,
|
|
1489
|
+
ignore: IGNORE_PATTERNS$3
|
|
1490
|
+
});
|
|
1491
|
+
for (const pyFile of pyFiles) try {
|
|
1492
|
+
const content = fs$1.readFileSync(path$1.join(installDir, pyFile), "utf-8");
|
|
1493
|
+
if (content.includes("Jinja2Templates") || content.includes("from fastapi.templating import")) return true;
|
|
1494
|
+
} catch {
|
|
1495
|
+
continue;
|
|
1496
|
+
}
|
|
1497
|
+
return (await fg(["**/templates"], {
|
|
1498
|
+
cwd: installDir,
|
|
1499
|
+
ignore: IGNORE_PATTERNS$3,
|
|
1500
|
+
onlyDirectories: true
|
|
1501
|
+
})).length > 0;
|
|
1502
|
+
}
|
|
1503
|
+
/**
|
|
1504
|
+
* Detect FastAPI project type
|
|
1505
|
+
*/
|
|
1506
|
+
async function getFastAPIProjectType(options) {
|
|
1507
|
+
const { installDir } = options;
|
|
1508
|
+
if (await hasTemplates({ installDir })) {
|
|
1509
|
+
getUI().setDetectedFramework("FastAPI fullstack with templates");
|
|
1510
|
+
return "fullstack";
|
|
1511
|
+
}
|
|
1512
|
+
if (await hasAPIRouter({ installDir })) {
|
|
1513
|
+
getUI().setDetectedFramework("FastAPI with APIRouter");
|
|
1514
|
+
return "router";
|
|
1515
|
+
}
|
|
1516
|
+
getUI().setDetectedFramework("FastAPI");
|
|
1517
|
+
return "standard";
|
|
1518
|
+
}
|
|
1519
|
+
/**
|
|
1520
|
+
* Get human-readable name for FastAPI project type
|
|
1521
|
+
*/
|
|
1522
|
+
function getFastAPIProjectTypeName(projectType) {
|
|
1523
|
+
switch (projectType) {
|
|
1524
|
+
case "standard": return "Standard FastAPI";
|
|
1525
|
+
case "router": return "FastAPI with APIRouter";
|
|
1526
|
+
case "fullstack": return "FastAPI Fullstack";
|
|
1527
|
+
}
|
|
1528
|
+
}
|
|
1529
|
+
/**
|
|
1530
|
+
* Find the main FastAPI app file
|
|
1531
|
+
*/
|
|
1532
|
+
async function findFastAPIAppFile(options) {
|
|
1533
|
+
const { installDir } = options;
|
|
1534
|
+
const appFiles = await fg([
|
|
1535
|
+
"**/main.py",
|
|
1536
|
+
"**/app.py",
|
|
1537
|
+
"**/application.py",
|
|
1538
|
+
"**/api.py",
|
|
1539
|
+
"**/__init__.py"
|
|
1540
|
+
], {
|
|
1541
|
+
cwd: installDir,
|
|
1542
|
+
ignore: IGNORE_PATTERNS$3
|
|
1543
|
+
});
|
|
1544
|
+
for (const appFile of appFiles) try {
|
|
1545
|
+
const content = fs$1.readFileSync(path$1.join(installDir, appFile), "utf-8");
|
|
1546
|
+
if (content.includes("FastAPI(") || content.includes("from fastapi import FastAPI")) return appFile;
|
|
1547
|
+
} catch {
|
|
1548
|
+
continue;
|
|
1549
|
+
}
|
|
1550
|
+
const allPyFiles = await fg(["**/*.py"], {
|
|
1551
|
+
cwd: installDir,
|
|
1552
|
+
ignore: IGNORE_PATTERNS$3
|
|
1553
|
+
});
|
|
1554
|
+
for (const pyFile of allPyFiles) try {
|
|
1555
|
+
if (fs$1.readFileSync(path$1.join(installDir, pyFile), "utf-8").includes("FastAPI(")) return pyFile;
|
|
1556
|
+
} catch {
|
|
1557
|
+
continue;
|
|
1558
|
+
}
|
|
1559
|
+
if (appFiles.length > 0) return appFiles[0];
|
|
1560
|
+
}
|
|
1561
|
+
//#endregion
|
|
1562
|
+
//#region src/frameworks/fastapi/fastapi-wizard-agent.ts
|
|
1563
|
+
/**
|
|
1564
|
+
* FastAPI framework configuration for the universal agent runner
|
|
1565
|
+
*/
|
|
1566
|
+
const FASTAPI_AGENT_CONFIG = {
|
|
1567
|
+
metadata: {
|
|
1568
|
+
name: "FastAPI",
|
|
1569
|
+
integration: "fastapi",
|
|
1570
|
+
docsUrl: "https://posthog.com/docs/libraries/python",
|
|
1571
|
+
unsupportedVersionDocsUrl: "https://posthog.com/docs/libraries/python",
|
|
1572
|
+
gatherContext: async (options) => {
|
|
1573
|
+
return {
|
|
1574
|
+
projectType: await getFastAPIProjectType(options),
|
|
1575
|
+
appFile: await findFastAPIAppFile(options)
|
|
1576
|
+
};
|
|
1577
|
+
}
|
|
1578
|
+
},
|
|
1579
|
+
detection: {
|
|
1580
|
+
packageName: "fastapi",
|
|
1581
|
+
packageDisplayName: "FastAPI",
|
|
1582
|
+
usesPackageJson: false,
|
|
1583
|
+
getVersion: (_packageJson) => {},
|
|
1584
|
+
getVersionBucket: getFastAPIVersionBucket,
|
|
1585
|
+
getInstalledVersion: getFastAPIVersion,
|
|
1586
|
+
detect: async (options) => {
|
|
1587
|
+
const { installDir } = options;
|
|
1588
|
+
const requirementsFiles = await fg([
|
|
1589
|
+
"**/requirements*.txt",
|
|
1590
|
+
"**/pyproject.toml",
|
|
1591
|
+
"**/setup.py",
|
|
1592
|
+
"**/Pipfile"
|
|
1593
|
+
], {
|
|
1594
|
+
cwd: installDir,
|
|
1595
|
+
ignore: [
|
|
1596
|
+
"**/venv/**",
|
|
1597
|
+
"**/.venv/**",
|
|
1598
|
+
"**/env/**",
|
|
1599
|
+
"**/.env/**"
|
|
1600
|
+
]
|
|
1601
|
+
});
|
|
1602
|
+
for (const reqFile of requirementsFiles) try {
|
|
1603
|
+
const content = fs$1.readFileSync(path$1.join(installDir, reqFile), "utf-8");
|
|
1604
|
+
if (/^fastapi([<>=~!]|$|\s)/im.test(content) || /["']fastapi["']/i.test(content)) return true;
|
|
1605
|
+
} catch {
|
|
1606
|
+
continue;
|
|
1607
|
+
}
|
|
1608
|
+
const pyFiles = await fg([
|
|
1609
|
+
"**/main.py",
|
|
1610
|
+
"**/app.py",
|
|
1611
|
+
"**/application.py",
|
|
1612
|
+
"**/__init__.py"
|
|
1613
|
+
], {
|
|
1614
|
+
cwd: installDir,
|
|
1615
|
+
ignore: [
|
|
1616
|
+
"**/venv/**",
|
|
1617
|
+
"**/.venv/**",
|
|
1618
|
+
"**/env/**",
|
|
1619
|
+
"**/.env/**",
|
|
1620
|
+
"**/__pycache__/**"
|
|
1621
|
+
]
|
|
1622
|
+
});
|
|
1623
|
+
for (const pyFile of pyFiles) try {
|
|
1624
|
+
const content = fs$1.readFileSync(path$1.join(installDir, pyFile), "utf-8");
|
|
1625
|
+
if (content.includes("from fastapi import") || content.includes("import fastapi") || /FastAPI\s*\(/.test(content)) return true;
|
|
1626
|
+
} catch {
|
|
1627
|
+
continue;
|
|
1628
|
+
}
|
|
1629
|
+
return false;
|
|
1630
|
+
},
|
|
1631
|
+
detectPackageManager: detectPythonPackageManagers
|
|
1632
|
+
},
|
|
1633
|
+
environment: {
|
|
1634
|
+
uploadToHosting: false,
|
|
1635
|
+
getEnvVars: (apiKey, host) => ({
|
|
1636
|
+
POSTHOG_PROJECT_TOKEN: apiKey,
|
|
1637
|
+
POSTHOG_HOST: host
|
|
1638
|
+
})
|
|
1639
|
+
},
|
|
1640
|
+
analytics: { getTags: (context) => {
|
|
1641
|
+
return { projectType: context.projectType || "unknown" };
|
|
1642
|
+
} },
|
|
1643
|
+
prompts: {
|
|
1644
|
+
packageInstallation: PYTHON_PACKAGE_INSTALLATION,
|
|
1645
|
+
projectTypeDetection: "This is a Python/FastAPI project. Look for requirements.txt, pyproject.toml, setup.py, Pipfile, or main.py/app.py to confirm.",
|
|
1646
|
+
getAdditionalContextLines: (context) => {
|
|
1647
|
+
const projectType = context.projectType;
|
|
1648
|
+
const projectTypeName = projectType ? getFastAPIProjectTypeName(projectType) : "unknown";
|
|
1649
|
+
const frameworkId = projectType ? {
|
|
1650
|
+
["standard"]: "fastapi",
|
|
1651
|
+
["router"]: "fastapi",
|
|
1652
|
+
["fullstack"]: "fastapi"
|
|
1653
|
+
}[projectType] : "fastapi";
|
|
1654
|
+
const lines = [`Project type: ${projectTypeName}`, `Framework docs ID: ${frameworkId} (use posthog://docs/frameworks/${frameworkId} for documentation)`];
|
|
1655
|
+
if (context.appFile) lines.push(`App file: ${context.appFile}`);
|
|
1656
|
+
return lines;
|
|
1657
|
+
}
|
|
1658
|
+
},
|
|
1659
|
+
ui: {
|
|
1660
|
+
successMessage: "PostHog integration complete",
|
|
1661
|
+
estimatedDurationMinutes: 5,
|
|
1662
|
+
getOutroChanges: (context) => {
|
|
1663
|
+
const projectType = context.projectType;
|
|
1664
|
+
return [
|
|
1665
|
+
`Analyzed your ${projectType ? getFastAPIProjectTypeName(projectType) : "FastAPI"} project structure`,
|
|
1666
|
+
`Installed the PostHog Python package`,
|
|
1667
|
+
`Configured PostHog in your FastAPI application`,
|
|
1668
|
+
`Added PostHog initialization with lifespan event handling`
|
|
1669
|
+
];
|
|
1670
|
+
},
|
|
1671
|
+
getOutroNextSteps: () => [
|
|
1672
|
+
"Start your FastAPI development server to see PostHog in action",
|
|
1673
|
+
"Visit your PostHog dashboard to see incoming events",
|
|
1674
|
+
"Use posthog.identify() to associate events with users"
|
|
1675
|
+
]
|
|
1676
|
+
}
|
|
1677
|
+
};
|
|
1678
|
+
//#endregion
|
|
1679
|
+
//#region src/frameworks/laravel/utils.ts
|
|
1680
|
+
/**
|
|
1681
|
+
* Ignore patterns for Laravel projects
|
|
1682
|
+
*/
|
|
1683
|
+
const LARAVEL_IGNORE_PATTERNS = [
|
|
1684
|
+
"**/node_modules/**",
|
|
1685
|
+
"**/vendor/**",
|
|
1686
|
+
"**/storage/**",
|
|
1687
|
+
"**/bootstrap/cache/**",
|
|
1688
|
+
"**/.phpunit.cache/**",
|
|
1689
|
+
"**/public/build/**",
|
|
1690
|
+
"**/public/hot/**"
|
|
1691
|
+
];
|
|
1692
|
+
/**
|
|
1693
|
+
* Get Laravel version bucket for analytics
|
|
1694
|
+
*/
|
|
1695
|
+
const getLaravelVersionBucket = createVersionBucket();
|
|
1696
|
+
/**
|
|
1697
|
+
* Read and parse composer.json
|
|
1698
|
+
*/
|
|
1699
|
+
function getComposerJson(options) {
|
|
1700
|
+
const { installDir } = options;
|
|
1701
|
+
const composerPath = path$1.join(installDir, "composer.json");
|
|
1702
|
+
try {
|
|
1703
|
+
const content = fs$1.readFileSync(composerPath, "utf-8");
|
|
1704
|
+
return JSON.parse(content);
|
|
1705
|
+
} catch {
|
|
1706
|
+
return;
|
|
1707
|
+
}
|
|
1708
|
+
}
|
|
1709
|
+
/**
|
|
1710
|
+
* Check if a package is installed (present in composer.json)
|
|
1711
|
+
*/
|
|
1712
|
+
function hasComposerPackage(packageName, options) {
|
|
1713
|
+
const composer = getComposerJson(options);
|
|
1714
|
+
if (!composer) return false;
|
|
1715
|
+
return !!(composer.require?.[packageName] || composer["require-dev"]?.[packageName]);
|
|
1716
|
+
}
|
|
1717
|
+
/**
|
|
1718
|
+
* Extract version for a package from composer.json
|
|
1719
|
+
*/
|
|
1720
|
+
function getComposerPackageVersion(packageName, options) {
|
|
1721
|
+
const composer = getComposerJson(options);
|
|
1722
|
+
if (!composer) return void 0;
|
|
1723
|
+
const version = composer.require?.[packageName] || composer["require-dev"]?.[packageName];
|
|
1724
|
+
if (version) return version.replace(/^[\^~>=<]+/, "");
|
|
1725
|
+
}
|
|
1726
|
+
/**
|
|
1727
|
+
* Check if a pattern exists in PHP source files
|
|
1728
|
+
*/
|
|
1729
|
+
async function hasLaravelCodePattern(pattern, options, filePatterns = ["**/*.php"]) {
|
|
1730
|
+
const { installDir } = options;
|
|
1731
|
+
const phpFiles = await fg(filePatterns, {
|
|
1732
|
+
cwd: installDir,
|
|
1733
|
+
ignore: LARAVEL_IGNORE_PATTERNS
|
|
1734
|
+
});
|
|
1735
|
+
const searchPattern = typeof pattern === "string" ? new RegExp(pattern) : pattern;
|
|
1736
|
+
for (const phpFile of phpFiles) try {
|
|
1737
|
+
const content = fs$1.readFileSync(path$1.join(installDir, phpFile), "utf-8");
|
|
1738
|
+
if (searchPattern.test(content)) return true;
|
|
1739
|
+
} catch {
|
|
1740
|
+
continue;
|
|
1741
|
+
}
|
|
1742
|
+
return false;
|
|
1743
|
+
}
|
|
1744
|
+
/**
|
|
1745
|
+
* Get Laravel version from composer.json
|
|
1746
|
+
*/
|
|
1747
|
+
function getLaravelVersion(options) {
|
|
1748
|
+
return getComposerPackageVersion("laravel/framework", options);
|
|
1749
|
+
}
|
|
1750
|
+
/**
|
|
1751
|
+
* Get human-readable name for Laravel project type
|
|
1752
|
+
*/
|
|
1753
|
+
function getLaravelProjectTypeName(projectType) {
|
|
1754
|
+
switch (projectType) {
|
|
1755
|
+
case "standard": return "Standard Laravel";
|
|
1756
|
+
case "inertia": return "Laravel with Inertia.js";
|
|
1757
|
+
case "livewire": return "Laravel with Livewire";
|
|
1758
|
+
default: return "Laravel";
|
|
1759
|
+
}
|
|
1760
|
+
}
|
|
1761
|
+
/**
|
|
1762
|
+
* Check for Inertia.js
|
|
1763
|
+
*/
|
|
1764
|
+
async function hasInertia(options) {
|
|
1765
|
+
return hasComposerPackage("inertiajs/inertia-laravel", options) || await hasLaravelCodePattern(/Inertia::render|inertia\(/, options);
|
|
1766
|
+
}
|
|
1767
|
+
/**
|
|
1768
|
+
* Check for Livewire
|
|
1769
|
+
*/
|
|
1770
|
+
async function hasLivewire(options) {
|
|
1771
|
+
return hasComposerPackage("livewire/livewire", options) || await hasLaravelCodePattern(/extends\s+Component|@livewire/, options);
|
|
1772
|
+
}
|
|
1773
|
+
/**
|
|
1774
|
+
* Detect Laravel project type
|
|
1775
|
+
*/
|
|
1776
|
+
async function getLaravelProjectType(options) {
|
|
1777
|
+
if (await hasInertia(options)) {
|
|
1778
|
+
getUI().setDetectedFramework("Laravel with Inertia.js");
|
|
1779
|
+
return "inertia";
|
|
1780
|
+
}
|
|
1781
|
+
if (await hasLivewire(options)) {
|
|
1782
|
+
getUI().setDetectedFramework("Laravel with Livewire");
|
|
1783
|
+
return "livewire";
|
|
1784
|
+
}
|
|
1785
|
+
getUI().setDetectedFramework("Laravel");
|
|
1786
|
+
return "standard";
|
|
1787
|
+
}
|
|
1788
|
+
/**
|
|
1789
|
+
* Find the main service provider file
|
|
1790
|
+
*/
|
|
1791
|
+
async function findLaravelServiceProvider(options) {
|
|
1792
|
+
const { installDir } = options;
|
|
1793
|
+
const appServiceProvider = path$1.join(installDir, "app/Providers/AppServiceProvider.php");
|
|
1794
|
+
if (fs$1.existsSync(appServiceProvider)) return "app/Providers/AppServiceProvider.php";
|
|
1795
|
+
return (await fg(["**/app/Providers/*ServiceProvider.php"], {
|
|
1796
|
+
cwd: installDir,
|
|
1797
|
+
ignore: LARAVEL_IGNORE_PATTERNS
|
|
1798
|
+
}))[0];
|
|
1799
|
+
}
|
|
1800
|
+
/**
|
|
1801
|
+
* Find the bootstrap file (differs between Laravel versions)
|
|
1802
|
+
*/
|
|
1803
|
+
function findLaravelBootstrapFile(options) {
|
|
1804
|
+
const { installDir } = options;
|
|
1805
|
+
const bootstrapApp = path$1.join(installDir, "bootstrap/app.php");
|
|
1806
|
+
if (fs$1.existsSync(bootstrapApp)) return "bootstrap/app.php";
|
|
1807
|
+
const httpKernel = path$1.join(installDir, "app/Http/Kernel.php");
|
|
1808
|
+
if (fs$1.existsSync(httpKernel)) return "app/Http/Kernel.php";
|
|
1809
|
+
}
|
|
1810
|
+
/**
|
|
1811
|
+
* Detect Laravel version structure for configuration guidance
|
|
1812
|
+
*/
|
|
1813
|
+
function detectLaravelStructure(options) {
|
|
1814
|
+
const version = getLaravelVersion(options);
|
|
1815
|
+
if (!version) return "modern";
|
|
1816
|
+
try {
|
|
1817
|
+
const majorVersion = parseInt(version.split(".")[0], 10);
|
|
1818
|
+
if (majorVersion >= 11) return "latest";
|
|
1819
|
+
if (majorVersion >= 9) return "modern";
|
|
1820
|
+
return "legacy";
|
|
1821
|
+
} catch {
|
|
1822
|
+
return "modern";
|
|
1823
|
+
}
|
|
1824
|
+
}
|
|
1825
|
+
//#endregion
|
|
1826
|
+
//#region src/frameworks/laravel/laravel-wizard-agent.ts
|
|
1827
|
+
const LARAVEL_AGENT_CONFIG = {
|
|
1828
|
+
metadata: {
|
|
1829
|
+
name: "Laravel",
|
|
1830
|
+
integration: "laravel",
|
|
1831
|
+
beta: true,
|
|
1832
|
+
docsUrl: "https://posthog.com/docs/libraries/php",
|
|
1833
|
+
unsupportedVersionDocsUrl: "https://posthog.com/docs/libraries/php",
|
|
1834
|
+
gatherContext: async (options) => {
|
|
1835
|
+
return {
|
|
1836
|
+
projectType: await getLaravelProjectType(options),
|
|
1837
|
+
serviceProvider: await findLaravelServiceProvider(options),
|
|
1838
|
+
bootstrapFile: findLaravelBootstrapFile(options),
|
|
1839
|
+
laravelStructure: detectLaravelStructure(options)
|
|
1840
|
+
};
|
|
1841
|
+
}
|
|
1842
|
+
},
|
|
1843
|
+
detection: {
|
|
1844
|
+
packageName: "laravel/framework",
|
|
1845
|
+
packageDisplayName: "Laravel",
|
|
1846
|
+
usesPackageJson: false,
|
|
1847
|
+
getVersion: () => void 0,
|
|
1848
|
+
getVersionBucket: getLaravelVersionBucket,
|
|
1849
|
+
minimumVersion: "9.0.0",
|
|
1850
|
+
getInstalledVersion: (options) => Promise.resolve(getLaravelVersion(options)),
|
|
1851
|
+
detect: async (options) => {
|
|
1852
|
+
const { installDir } = options;
|
|
1853
|
+
const artisanPath = path$1.join(installDir, "artisan");
|
|
1854
|
+
if (fs$1.existsSync(artisanPath)) try {
|
|
1855
|
+
const content = fs$1.readFileSync(artisanPath, "utf-8");
|
|
1856
|
+
if (content.includes("Laravel") || content.includes("Artisan")) return true;
|
|
1857
|
+
} catch {}
|
|
1858
|
+
const composerPath = path$1.join(installDir, "composer.json");
|
|
1859
|
+
if (fs$1.existsSync(composerPath)) try {
|
|
1860
|
+
const content = fs$1.readFileSync(composerPath, "utf-8");
|
|
1861
|
+
const composer = JSON.parse(content);
|
|
1862
|
+
if (composer.require?.["laravel/framework"] || composer["require-dev"]?.["laravel/framework"]) return true;
|
|
1863
|
+
} catch {}
|
|
1864
|
+
return (await fg(["**/bootstrap/app.php", "**/app/Http/Kernel.php"], {
|
|
1865
|
+
cwd: installDir,
|
|
1866
|
+
ignore: ["**/vendor/**"]
|
|
1867
|
+
})).length > 0;
|
|
1868
|
+
},
|
|
1869
|
+
detectPackageManager: composerPackageManager
|
|
1870
|
+
},
|
|
1871
|
+
environment: {
|
|
1872
|
+
uploadToHosting: false,
|
|
1873
|
+
getEnvVars: (apiKey, host) => ({
|
|
1874
|
+
POSTHOG_PROJECT_TOKEN: apiKey,
|
|
1875
|
+
POSTHOG_HOST: host
|
|
1876
|
+
})
|
|
1877
|
+
},
|
|
1878
|
+
analytics: { getTags: (context) => ({
|
|
1879
|
+
projectType: context.projectType || "unknown",
|
|
1880
|
+
laravelStructure: context.laravelStructure || "unknown"
|
|
1881
|
+
}) },
|
|
1882
|
+
prompts: {
|
|
1883
|
+
projectTypeDetection: "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.",
|
|
1884
|
+
packageInstallation: "Use Composer to install packages. Run `composer require posthog/posthog-php` without pinning a specific version.",
|
|
1885
|
+
getAdditionalContextLines: (context) => {
|
|
1886
|
+
const lines = [
|
|
1887
|
+
`Project type: ${context.projectType ? getLaravelProjectTypeName(context.projectType) : "unknown"}`,
|
|
1888
|
+
`Framework docs ID: php (use posthog://docs/frameworks/php for documentation)`,
|
|
1889
|
+
`Laravel structure: ${context.laravelStructure} (affects where to add configuration)`
|
|
1890
|
+
];
|
|
1891
|
+
if (context.serviceProvider) lines.push(`Service provider: ${context.serviceProvider}`);
|
|
1892
|
+
if (context.bootstrapFile) lines.push(`Bootstrap file: ${context.bootstrapFile}`);
|
|
1893
|
+
if (context.laravelStructure === "latest") lines.push("Note: Laravel 11+ uses simplified bootstrap/app.php for middleware and providers");
|
|
1894
|
+
else lines.push("Note: Use app/Http/Kernel.php for middleware, app/Providers for service providers");
|
|
1895
|
+
return lines;
|
|
1896
|
+
}
|
|
1897
|
+
},
|
|
1898
|
+
ui: {
|
|
1899
|
+
successMessage: "PostHog integration complete",
|
|
1900
|
+
estimatedDurationMinutes: 5,
|
|
1901
|
+
getOutroChanges: (context) => {
|
|
1902
|
+
const changes = [
|
|
1903
|
+
`Analyzed your ${context.projectType ? getLaravelProjectTypeName(context.projectType) : "Laravel"} project structure`,
|
|
1904
|
+
`Installed the PostHog PHP package via Composer`,
|
|
1905
|
+
`Configured PostHog in your Laravel application`
|
|
1906
|
+
];
|
|
1907
|
+
if (context.laravelStructure === "latest") changes.push("Added PostHog initialization to bootstrap/app.php");
|
|
1908
|
+
else changes.push("Created a PostHog service provider for initialization");
|
|
1909
|
+
if (context.projectType === "inertia") changes.push("Configured PostHog to work with Inertia.js");
|
|
1910
|
+
if (context.projectType === "livewire") changes.push("Configured PostHog to work with Livewire");
|
|
1911
|
+
return changes;
|
|
1912
|
+
},
|
|
1913
|
+
getOutroNextSteps: () => [
|
|
1914
|
+
"Start your Laravel development server with `php artisan serve`",
|
|
1915
|
+
"Visit your PostHog dashboard to see incoming events",
|
|
1916
|
+
"Use PostHog::capture() to track custom events",
|
|
1917
|
+
"Use PostHog::identify() to associate events with users"
|
|
1918
|
+
]
|
|
1919
|
+
}
|
|
1920
|
+
};
|
|
1921
|
+
//#endregion
|
|
1922
|
+
//#region src/frameworks/svelte/svelte-wizard-agent.ts
|
|
1923
|
+
const SVELTEKIT_AGENT_CONFIG = {
|
|
1924
|
+
metadata: {
|
|
1925
|
+
name: "SvelteKit",
|
|
1926
|
+
integration: "sveltekit",
|
|
1927
|
+
docsUrl: "https://posthog.com/docs/libraries/svelte",
|
|
1928
|
+
beta: true,
|
|
1929
|
+
additionalMcpServers: { svelte: { url: "https://mcp.svelte.dev/mcp" } }
|
|
1930
|
+
},
|
|
1931
|
+
detection: {
|
|
1932
|
+
packageName: "@sveltejs/kit",
|
|
1933
|
+
packageDisplayName: "SvelteKit",
|
|
1934
|
+
getVersion: (packageJson) => getPackageVersion("@sveltejs/kit", packageJson),
|
|
1935
|
+
detect: async (options) => {
|
|
1936
|
+
const packageJson = await tryGetPackageJson(options);
|
|
1937
|
+
return packageJson ? hasPackageInstalled("@sveltejs/kit", packageJson) : false;
|
|
1938
|
+
},
|
|
1939
|
+
minimumVersion: "2.0.0",
|
|
1940
|
+
detectPackageManager: detectNodePackageManagers
|
|
1941
|
+
},
|
|
1942
|
+
environment: {
|
|
1943
|
+
uploadToHosting: true,
|
|
1944
|
+
getEnvVars: (apiKey, host) => ({
|
|
1945
|
+
PUBLIC_POSTHOG_PROJECT_TOKEN: apiKey,
|
|
1946
|
+
PUBLIC_POSTHOG_HOST: host
|
|
1947
|
+
})
|
|
1948
|
+
},
|
|
1949
|
+
analytics: { getTags: () => ({}) },
|
|
1950
|
+
prompts: {
|
|
1951
|
+
projectTypeDetection: "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.",
|
|
1952
|
+
getAdditionalContextLines: () => ["Framework docs ID: sveltekit (use posthog://docs/frameworks/sveltekit for documentation)"]
|
|
1953
|
+
},
|
|
1954
|
+
ui: {
|
|
1955
|
+
successMessage: "PostHog integration complete",
|
|
1956
|
+
estimatedDurationMinutes: 8,
|
|
1957
|
+
getOutroChanges: () => [
|
|
1958
|
+
"Analyzed your SvelteKit project structure",
|
|
1959
|
+
"Created and configured PostHog initializers",
|
|
1960
|
+
"Integrated PostHog into your application"
|
|
1961
|
+
],
|
|
1962
|
+
getOutroNextSteps: () => ["Start your development server to see PostHog in action", "Visit your PostHog dashboard to see incoming events"]
|
|
1963
|
+
}
|
|
1964
|
+
};
|
|
1965
|
+
//#endregion
|
|
1966
|
+
//#region src/frameworks/swift/utils.ts
|
|
1967
|
+
function getSwiftProjectTypeName(projectType) {
|
|
1968
|
+
switch (projectType) {
|
|
1969
|
+
case "swiftui": return "SwiftUI";
|
|
1970
|
+
case "uikit": return "UIKit";
|
|
1971
|
+
case "spm": return "Swift Package";
|
|
1972
|
+
}
|
|
1973
|
+
}
|
|
1974
|
+
async function detectSwiftProjectType(options) {
|
|
1975
|
+
const { installDir } = options;
|
|
1976
|
+
const hasPackageSwift = fs$1.existsSync(path$1.join(installDir, "Package.swift"));
|
|
1977
|
+
const xcodeProjects = await fg("*.xcodeproj", {
|
|
1978
|
+
cwd: installDir,
|
|
1979
|
+
onlyDirectories: true
|
|
1980
|
+
});
|
|
1981
|
+
if (hasPackageSwift && xcodeProjects.length === 0) return "spm";
|
|
1982
|
+
const swiftFiles = await fg("**/*.swift", {
|
|
1983
|
+
cwd: installDir,
|
|
1984
|
+
ignore: [
|
|
1985
|
+
"**/.build/**",
|
|
1986
|
+
"**/DerivedData/**",
|
|
1987
|
+
"**/build/**",
|
|
1988
|
+
"**/*.xcodeproj/**",
|
|
1989
|
+
"**/Pods/**"
|
|
1990
|
+
]
|
|
1991
|
+
});
|
|
1992
|
+
let hasSwiftUI = false;
|
|
1993
|
+
let hasUIKit = false;
|
|
1994
|
+
for (const file of swiftFiles) try {
|
|
1995
|
+
const content = fs$1.readFileSync(path$1.join(installDir, file), "utf-8");
|
|
1996
|
+
if (content.includes("import SwiftUI")) hasSwiftUI = true;
|
|
1997
|
+
if (content.includes("import UIKit")) hasUIKit = true;
|
|
1998
|
+
} catch {
|
|
1999
|
+
continue;
|
|
2000
|
+
}
|
|
2001
|
+
if (hasSwiftUI) return "swiftui";
|
|
2002
|
+
if (hasUIKit) return "uikit";
|
|
2003
|
+
}
|
|
2004
|
+
//#endregion
|
|
2005
|
+
//#region src/frameworks/swift/swift-wizard-agent.ts
|
|
2006
|
+
const SWIFT_AGENT_CONFIG = {
|
|
2007
|
+
metadata: {
|
|
2008
|
+
name: "Swift (iOS/macOS)",
|
|
2009
|
+
integration: "swift",
|
|
2010
|
+
beta: true,
|
|
2011
|
+
docsUrl: "https://posthog.com/docs/libraries/ios",
|
|
2012
|
+
preRunNotice: "Please close the Xcode project before proceeding. Xcode may overwrite changes the wizard makes to project files.",
|
|
2013
|
+
gatherContext: async (options) => {
|
|
2014
|
+
return { projectType: await detectSwiftProjectType(options) };
|
|
2015
|
+
}
|
|
2016
|
+
},
|
|
2017
|
+
detection: {
|
|
2018
|
+
packageName: "posthog-ios",
|
|
2019
|
+
packageDisplayName: "Swift",
|
|
2020
|
+
usesPackageJson: false,
|
|
2021
|
+
getVersion: () => void 0,
|
|
2022
|
+
detect: async (options) => {
|
|
2023
|
+
const { installDir } = options;
|
|
2024
|
+
if ((await fg("*.xcodeproj", {
|
|
2025
|
+
cwd: installDir,
|
|
2026
|
+
onlyDirectories: true
|
|
2027
|
+
})).length > 0) {
|
|
2028
|
+
if ((await fg("**/*.swift", {
|
|
2029
|
+
cwd: installDir,
|
|
2030
|
+
ignore: [
|
|
2031
|
+
"**/.build/**",
|
|
2032
|
+
"**/DerivedData/**",
|
|
2033
|
+
"**/build/**",
|
|
2034
|
+
"**/*.xcodeproj/**",
|
|
2035
|
+
"**/Pods/**"
|
|
2036
|
+
]
|
|
2037
|
+
})).length > 0) return true;
|
|
2038
|
+
}
|
|
2039
|
+
const packageSwiftPath = path$1.join(installDir, "Package.swift");
|
|
2040
|
+
if (fs$1.existsSync(packageSwiftPath)) return true;
|
|
2041
|
+
return false;
|
|
2042
|
+
},
|
|
2043
|
+
detectPackageManager: swiftPackageManager
|
|
2044
|
+
},
|
|
2045
|
+
environment: {
|
|
2046
|
+
uploadToHosting: false,
|
|
2047
|
+
getEnvVars: (apiKey, host) => ({
|
|
2048
|
+
POSTHOG_PROJECT_TOKEN: apiKey,
|
|
2049
|
+
POSTHOG_HOST: host
|
|
2050
|
+
})
|
|
2051
|
+
},
|
|
2052
|
+
analytics: { getTags: (context) => ({ projectType: context.projectType || "unknown" }) },
|
|
2053
|
+
prompts: {
|
|
2054
|
+
projectTypeDetection: "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.",
|
|
2055
|
+
packageInstallation: "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.",
|
|
2056
|
+
getAdditionalContextLines: (context) => {
|
|
2057
|
+
return [`Project type: ${context.projectType ? getSwiftProjectTypeName(context.projectType) : "unknown"}`, `Framework docs ID: swift (use posthog://docs/frameworks/swift for documentation)`];
|
|
2058
|
+
}
|
|
2059
|
+
},
|
|
2060
|
+
ui: {
|
|
2061
|
+
successMessage: "PostHog integration complete",
|
|
2062
|
+
estimatedDurationMinutes: 5,
|
|
2063
|
+
getOutroChanges: (context) => {
|
|
2064
|
+
return [
|
|
2065
|
+
`Analyzed your ${context.projectType ? getSwiftProjectTypeName(context.projectType) : "Swift"} project structure`,
|
|
2066
|
+
`Added the PostHog iOS SDK via Swift Package Manager`,
|
|
2067
|
+
`Configured PostHog initialization in your app entry point`,
|
|
2068
|
+
`Added event capture and user identification`
|
|
2069
|
+
];
|
|
2070
|
+
},
|
|
2071
|
+
getOutroNextSteps: () => [
|
|
2072
|
+
"Set POSTHOG_PROJECT_TOKEN and POSTHOG_HOST in your Xcode scheme environment variables",
|
|
2073
|
+
"Build and run your app to see PostHog in action",
|
|
2074
|
+
"Visit your PostHog dashboard to see incoming events"
|
|
2075
|
+
]
|
|
2076
|
+
}
|
|
2077
|
+
};
|
|
2078
|
+
//#endregion
|
|
2079
|
+
//#region src/frameworks/android/utils.ts
|
|
2080
|
+
const IGNORE_PATTERNS$2 = [
|
|
2081
|
+
"**/build/**",
|
|
2082
|
+
"**/.gradle/**",
|
|
2083
|
+
"**/node_modules/**"
|
|
2084
|
+
];
|
|
2085
|
+
/**
|
|
2086
|
+
* Extract minSdk from the app-level build.gradle(.kts).
|
|
2087
|
+
* Returns the value as a semver-like string (e.g. "24" from minSdk = 24).
|
|
2088
|
+
*/
|
|
2089
|
+
async function getMinSdkVersion(options) {
|
|
2090
|
+
const { installDir } = options;
|
|
2091
|
+
const buildFiles = await fg(["**/build.gradle", "**/build.gradle.kts"], {
|
|
2092
|
+
cwd: installDir,
|
|
2093
|
+
ignore: IGNORE_PATTERNS$2
|
|
2094
|
+
});
|
|
2095
|
+
for (const file of buildFiles) try {
|
|
2096
|
+
const match = fs$1.readFileSync(path$1.join(installDir, file), "utf-8").match(/minSdk(?:Version)?\s*=?\s*(\d+)/);
|
|
2097
|
+
if (match) return match[1];
|
|
2098
|
+
} catch {
|
|
2099
|
+
continue;
|
|
2100
|
+
}
|
|
2101
|
+
}
|
|
2102
|
+
const getKotlinVersionBucket = createVersionBucket();
|
|
2103
|
+
/**
|
|
2104
|
+
* Read the root or app-level build.gradle(.kts) and extract the Kotlin version.
|
|
2105
|
+
*/
|
|
2106
|
+
function getKotlinVersion(options) {
|
|
2107
|
+
const { installDir } = options;
|
|
2108
|
+
for (const name of [
|
|
2109
|
+
"build.gradle",
|
|
2110
|
+
"build.gradle.kts",
|
|
2111
|
+
"gradle/libs.versions.toml"
|
|
2112
|
+
]) {
|
|
2113
|
+
const filePath = path$1.join(installDir, name);
|
|
2114
|
+
if (!fs$1.existsSync(filePath)) continue;
|
|
2115
|
+
const content = fs$1.readFileSync(filePath, "utf-8");
|
|
2116
|
+
const match = content.match(/kotlin[_-]?[Vv]ersion\s*=\s*["']([^"']+)["']/);
|
|
2117
|
+
if (match) return match[1];
|
|
2118
|
+
const tomlMatch = content.match(/^kotlin\s*=\s*["']([^"']+)["']/m);
|
|
2119
|
+
if (tomlMatch) return tomlMatch[1];
|
|
2120
|
+
}
|
|
2121
|
+
}
|
|
2122
|
+
//#endregion
|
|
2123
|
+
//#region src/frameworks/android/android-wizard-agent.ts
|
|
2124
|
+
const ANDROID_AGENT_CONFIG = {
|
|
2125
|
+
metadata: {
|
|
2126
|
+
name: "Android (Kotlin)",
|
|
2127
|
+
integration: "android",
|
|
2128
|
+
beta: true,
|
|
2129
|
+
docsUrl: "https://posthog.com/docs/libraries/android",
|
|
2130
|
+
gatherContext: (options) => {
|
|
2131
|
+
const kotlinVersion = getKotlinVersion(options);
|
|
2132
|
+
return Promise.resolve({ kotlinVersion });
|
|
2133
|
+
}
|
|
2134
|
+
},
|
|
2135
|
+
detection: {
|
|
2136
|
+
packageName: "posthog-android",
|
|
2137
|
+
packageDisplayName: "Android (Kotlin)",
|
|
2138
|
+
usesPackageJson: false,
|
|
2139
|
+
getVersion: () => void 0,
|
|
2140
|
+
getVersionBucket: (version) => getKotlinVersionBucket(version),
|
|
2141
|
+
minimumVersion: "21.0.0",
|
|
2142
|
+
getInstalledVersion: (options) => getMinSdkVersion(options),
|
|
2143
|
+
detectPackageManager: gradlePackageManager,
|
|
2144
|
+
detect: async (options) => {
|
|
2145
|
+
const { installDir } = options;
|
|
2146
|
+
for (const name of ["build.gradle", "build.gradle.kts"]) {
|
|
2147
|
+
const buildGradlePath = path$1.join(installDir, name);
|
|
2148
|
+
if (fs$1.existsSync(buildGradlePath)) {
|
|
2149
|
+
const content = fs$1.readFileSync(buildGradlePath, "utf-8");
|
|
2150
|
+
if (content.includes("com.android.application") || content.includes("com.android.library") || content.includes("com.android.tools.build:gradle")) return true;
|
|
2151
|
+
}
|
|
2152
|
+
}
|
|
2153
|
+
if ((await fg("**/AndroidManifest.xml", {
|
|
2154
|
+
cwd: installDir,
|
|
2155
|
+
ignore: [
|
|
2156
|
+
"**/build/**",
|
|
2157
|
+
"**/node_modules/**",
|
|
2158
|
+
"**/.gradle/**"
|
|
2159
|
+
]
|
|
2160
|
+
})).length > 0) {
|
|
2161
|
+
if ((await fg("**/*.kt", {
|
|
2162
|
+
cwd: installDir,
|
|
2163
|
+
ignore: [
|
|
2164
|
+
"**/build/**",
|
|
2165
|
+
"**/node_modules/**",
|
|
2166
|
+
"**/.gradle/**"
|
|
2167
|
+
]
|
|
2168
|
+
})).length > 0) return true;
|
|
2169
|
+
}
|
|
2170
|
+
return false;
|
|
2171
|
+
}
|
|
2172
|
+
},
|
|
2173
|
+
environment: {
|
|
2174
|
+
uploadToHosting: false,
|
|
2175
|
+
getEnvVars: (apiKey, host) => ({
|
|
2176
|
+
POSTHOG_PROJECT_TOKEN: apiKey,
|
|
2177
|
+
POSTHOG_HOST: host
|
|
2178
|
+
})
|
|
2179
|
+
},
|
|
2180
|
+
analytics: { getTags: (context) => ({ ...context.kotlinVersion ? { kotlinVersion: getKotlinVersionBucket(context.kotlinVersion) } : {} }) },
|
|
2181
|
+
prompts: {
|
|
2182
|
+
projectTypeDetection: "This is an Android/Kotlin project. Look for build.gradle or build.gradle.kts files, AndroidManifest.xml, and Kotlin source files (.kt) to confirm.",
|
|
2183
|
+
packageInstallation: "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.",
|
|
2184
|
+
getAdditionalContextLines: (context) => {
|
|
2185
|
+
const lines = [`Framework docs ID: android (use posthog://docs/frameworks/android for documentation)`];
|
|
2186
|
+
if (context.kotlinVersion) lines.push(`Kotlin version: ${context.kotlinVersion}`);
|
|
2187
|
+
return lines;
|
|
2188
|
+
}
|
|
2189
|
+
},
|
|
2190
|
+
ui: {
|
|
2191
|
+
successMessage: "PostHog integration complete",
|
|
2192
|
+
estimatedDurationMinutes: 5,
|
|
2193
|
+
getOutroChanges: () => [
|
|
2194
|
+
`Analyzed your Android project structure`,
|
|
2195
|
+
`Added the PostHog Android SDK dependency`,
|
|
2196
|
+
`Configured PostHog initialization in your Application class`,
|
|
2197
|
+
`Added event capture and user identification`
|
|
2198
|
+
],
|
|
2199
|
+
getOutroNextSteps: () => [
|
|
2200
|
+
"Build and run your app to see PostHog in action",
|
|
2201
|
+
"Visit your PostHog dashboard to see incoming events",
|
|
2202
|
+
"Check out the PostHog Android docs for advanced features like feature flags and session replay"
|
|
2203
|
+
]
|
|
2204
|
+
}
|
|
2205
|
+
};
|
|
2206
|
+
//#endregion
|
|
2207
|
+
//#region src/frameworks/rails/utils.ts
|
|
2208
|
+
const IGNORE_PATTERNS$1 = [
|
|
2209
|
+
"**/node_modules/**",
|
|
2210
|
+
"**/vendor/**",
|
|
2211
|
+
"**/vendor/bundle/**",
|
|
2212
|
+
"**/tmp/**",
|
|
2213
|
+
"**/log/**",
|
|
2214
|
+
"**/storage/**"
|
|
2215
|
+
];
|
|
2216
|
+
/**
|
|
2217
|
+
* Get Rails version bucket for analytics
|
|
2218
|
+
*/
|
|
2219
|
+
const getRailsVersionBucket = createVersionBucket();
|
|
2220
|
+
/**
|
|
2221
|
+
* Read and parse Gemfile contents
|
|
2222
|
+
*/
|
|
2223
|
+
function readGemfile(options) {
|
|
2224
|
+
const { installDir } = options;
|
|
2225
|
+
const gemfilePath = path$1.join(installDir, "Gemfile");
|
|
2226
|
+
try {
|
|
2227
|
+
return fs$1.readFileSync(gemfilePath, "utf-8");
|
|
2228
|
+
} catch {
|
|
2229
|
+
return;
|
|
2230
|
+
}
|
|
2231
|
+
}
|
|
2232
|
+
/**
|
|
2233
|
+
* Check if a gem is present in the Gemfile
|
|
2234
|
+
*/
|
|
2235
|
+
function hasGem(gemName, options) {
|
|
2236
|
+
const content = readGemfile(options);
|
|
2237
|
+
if (!content) return false;
|
|
2238
|
+
return new RegExp(`^\\s*gem\\s+['"]${gemName}['"]`, "im").test(content);
|
|
2239
|
+
}
|
|
2240
|
+
/**
|
|
2241
|
+
* Extract version for a gem from Gemfile
|
|
2242
|
+
*/
|
|
2243
|
+
function getGemVersion(gemName, options) {
|
|
2244
|
+
const content = readGemfile(options);
|
|
2245
|
+
if (!content) return void 0;
|
|
2246
|
+
const versionPattern = new RegExp(`^\\s*gem\\s+['"]${gemName}['"]\\s*,\\s*['"][^0-9]*([0-9]+\\.[0-9]+(?:\\.[0-9]+)?)['"]`, "im");
|
|
2247
|
+
return content.match(versionPattern)?.[1];
|
|
2248
|
+
}
|
|
2249
|
+
/**
|
|
2250
|
+
* Get Rails version from Gemfile
|
|
2251
|
+
*/
|
|
2252
|
+
function getRailsVersion(options) {
|
|
2253
|
+
return getGemVersion("rails", options);
|
|
2254
|
+
}
|
|
2255
|
+
/**
|
|
2256
|
+
* Detect Rails project type
|
|
2257
|
+
*/
|
|
2258
|
+
function getRailsProjectType(options) {
|
|
2259
|
+
const { installDir } = options;
|
|
2260
|
+
const appConfigPath = path$1.join(installDir, "config/application.rb");
|
|
2261
|
+
if (fs$1.existsSync(appConfigPath)) try {
|
|
2262
|
+
if (fs$1.readFileSync(appConfigPath, "utf-8").includes("config.api_only = true")) {
|
|
2263
|
+
getUI().setDetectedFramework("Rails API-only");
|
|
2264
|
+
return "api";
|
|
2265
|
+
}
|
|
2266
|
+
} catch {}
|
|
2267
|
+
getUI().setDetectedFramework("Rails");
|
|
2268
|
+
return "standard";
|
|
2269
|
+
}
|
|
2270
|
+
/**
|
|
2271
|
+
* Get human-readable name for Rails project type
|
|
2272
|
+
*/
|
|
2273
|
+
function getRailsProjectTypeName(projectType) {
|
|
2274
|
+
switch (projectType) {
|
|
2275
|
+
case "standard": return "Standard Rails";
|
|
2276
|
+
case "api": return "Rails API";
|
|
2277
|
+
}
|
|
2278
|
+
}
|
|
2279
|
+
/**
|
|
2280
|
+
* Find the Rails initializers directory
|
|
2281
|
+
*/
|
|
2282
|
+
function findInitializersDir(options) {
|
|
2283
|
+
const { installDir } = options;
|
|
2284
|
+
const initializersDir = path$1.join(installDir, "config/initializers");
|
|
2285
|
+
if (fs$1.existsSync(initializersDir)) return "config/initializers";
|
|
2286
|
+
}
|
|
2287
|
+
/**
|
|
2288
|
+
* Detect if the project is a Rails project by looking for typical Rails files
|
|
2289
|
+
*/
|
|
2290
|
+
async function isRailsProject(options) {
|
|
2291
|
+
const { installDir } = options;
|
|
2292
|
+
const binRailsPath = path$1.join(installDir, "bin/rails");
|
|
2293
|
+
if (fs$1.existsSync(binRailsPath)) return true;
|
|
2294
|
+
const appConfigPath = path$1.join(installDir, "config/application.rb");
|
|
2295
|
+
if (fs$1.existsSync(appConfigPath)) try {
|
|
2296
|
+
const content = fs$1.readFileSync(appConfigPath, "utf-8");
|
|
2297
|
+
if (content.includes("Rails::Application") || content.includes("require \"rails\"") || content.includes("require 'rails'")) return true;
|
|
2298
|
+
} catch {}
|
|
2299
|
+
if (hasGem("rails", options)) return true;
|
|
2300
|
+
return (await fg(["config/routes.rb", "config/environment.rb"], {
|
|
2301
|
+
cwd: installDir,
|
|
2302
|
+
ignore: IGNORE_PATTERNS$1
|
|
2303
|
+
})).length >= 2;
|
|
2304
|
+
}
|
|
2305
|
+
//#endregion
|
|
2306
|
+
//#region src/frameworks/rails/rails-wizard-agent.ts
|
|
2307
|
+
const RAILS_AGENT_CONFIG = {
|
|
2308
|
+
metadata: {
|
|
2309
|
+
name: "Ruby on Rails",
|
|
2310
|
+
integration: "rails",
|
|
2311
|
+
beta: true,
|
|
2312
|
+
docsUrl: "https://posthog.com/docs/libraries/ruby-on-rails",
|
|
2313
|
+
unsupportedVersionDocsUrl: "https://posthog.com/docs/libraries/ruby",
|
|
2314
|
+
gatherContext: (options) => {
|
|
2315
|
+
const projectType = getRailsProjectType(options);
|
|
2316
|
+
const initializersDir = findInitializersDir(options);
|
|
2317
|
+
return Promise.resolve({
|
|
2318
|
+
projectType,
|
|
2319
|
+
initializersDir
|
|
2320
|
+
});
|
|
2321
|
+
}
|
|
2322
|
+
},
|
|
2323
|
+
detection: {
|
|
2324
|
+
packageName: "rails",
|
|
2325
|
+
packageDisplayName: "Ruby on Rails",
|
|
2326
|
+
usesPackageJson: false,
|
|
2327
|
+
getVersion: () => void 0,
|
|
2328
|
+
getVersionBucket: getRailsVersionBucket,
|
|
2329
|
+
minimumVersion: "6.0.0",
|
|
2330
|
+
getInstalledVersion: (options) => Promise.resolve(getRailsVersion(options)),
|
|
2331
|
+
detect: async (options) => isRailsProject(options),
|
|
2332
|
+
detectPackageManager: bundlerPackageManager
|
|
2333
|
+
},
|
|
2334
|
+
environment: {
|
|
2335
|
+
uploadToHosting: false,
|
|
2336
|
+
getEnvVars: (apiKey, host) => ({
|
|
2337
|
+
POSTHOG_PROJECT_TOKEN: apiKey,
|
|
2338
|
+
POSTHOG_HOST: host
|
|
2339
|
+
})
|
|
2340
|
+
},
|
|
2341
|
+
analytics: { getTags: (context) => ({ projectType: context.projectType || "unknown" }) },
|
|
2342
|
+
prompts: {
|
|
2343
|
+
projectTypeDetection: "This is a Ruby on Rails project. Look for Gemfile, config/application.rb, bin/rails, and config/routes.rb to confirm.",
|
|
2344
|
+
packageInstallation: "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.",
|
|
2345
|
+
getAdditionalContextLines: (context) => {
|
|
2346
|
+
const lines = [`Project type: ${context.projectType ? getRailsProjectTypeName(context.projectType) : "unknown"}`, `Framework docs ID: ruby-on-rails (use posthog://docs/frameworks/ruby-on-rails for documentation)`];
|
|
2347
|
+
if (context.initializersDir) lines.push(`Initializers directory: ${context.initializersDir}`);
|
|
2348
|
+
if (context.projectType === "api") lines.push("Note: This is an API-only Rails app — skip frontend posthog-js integration");
|
|
2349
|
+
return lines;
|
|
2350
|
+
}
|
|
2351
|
+
},
|
|
2352
|
+
ui: {
|
|
2353
|
+
successMessage: "PostHog integration complete",
|
|
2354
|
+
estimatedDurationMinutes: 5,
|
|
2355
|
+
getOutroChanges: (context) => {
|
|
2356
|
+
const changes = [
|
|
2357
|
+
`Analyzed your ${context.projectType ? getRailsProjectTypeName(context.projectType) : "Rails"} project structure`,
|
|
2358
|
+
`Installed the posthog-ruby and posthog-rails gems via Bundler`,
|
|
2359
|
+
`Created PostHog initializer in config/initializers/posthog.rb`,
|
|
2360
|
+
`Configured automatic exception capture and ActiveJob instrumentation`
|
|
2361
|
+
];
|
|
2362
|
+
if (context.projectType !== "api") changes.push("Added posthog-js snippet to the layout template for frontend tracking");
|
|
2363
|
+
return changes;
|
|
2364
|
+
},
|
|
2365
|
+
getOutroNextSteps: () => [
|
|
2366
|
+
"Start your Rails development server with `bin/rails server`",
|
|
2367
|
+
"Visit your PostHog dashboard to see incoming events",
|
|
2368
|
+
"Use PostHog.capture() to track custom events",
|
|
2369
|
+
"Use PostHog.identify() to associate events with users",
|
|
2370
|
+
"Define posthog_distinct_id on your User model for automatic user association"
|
|
2371
|
+
]
|
|
2372
|
+
}
|
|
2373
|
+
};
|
|
2374
|
+
//#endregion
|
|
2375
|
+
//#region src/frameworks/python/python-wizard-agent.ts
|
|
2376
|
+
const PYTHON_AGENT_CONFIG = {
|
|
2377
|
+
metadata: {
|
|
2378
|
+
name: "Python Language",
|
|
2379
|
+
integration: "python",
|
|
2380
|
+
beta: true,
|
|
2381
|
+
docsUrl: "https://posthog.com/docs/libraries/python",
|
|
2382
|
+
gatherContext: async (options) => {
|
|
2383
|
+
return { packageManager: await detectPackageManager$1(options) };
|
|
2384
|
+
}
|
|
2385
|
+
},
|
|
2386
|
+
detection: {
|
|
2387
|
+
packageName: "python",
|
|
2388
|
+
packageDisplayName: "Python",
|
|
2389
|
+
usesPackageJson: false,
|
|
2390
|
+
getVersion: () => void 0,
|
|
2391
|
+
getVersionBucket: getPythonVersionBucket,
|
|
2392
|
+
minimumVersion: "3.8.0",
|
|
2393
|
+
getInstalledVersion: (options) => Promise.resolve(getPythonVersion(options)),
|
|
2394
|
+
detect: async (options) => {
|
|
2395
|
+
const { installDir } = options;
|
|
2396
|
+
const pythonConfigFiles = await fg([
|
|
2397
|
+
"**/requirements*.txt",
|
|
2398
|
+
"**/pyproject.toml",
|
|
2399
|
+
"**/setup.py",
|
|
2400
|
+
"**/Pipfile"
|
|
2401
|
+
], {
|
|
2402
|
+
cwd: installDir,
|
|
2403
|
+
ignore: [
|
|
2404
|
+
"**/venv/**",
|
|
2405
|
+
"**/.venv/**",
|
|
2406
|
+
"**/env/**",
|
|
2407
|
+
"**/.env/**"
|
|
2408
|
+
]
|
|
2409
|
+
});
|
|
2410
|
+
if (pythonConfigFiles.length === 0) return false;
|
|
2411
|
+
const managePyMatches = await fg("**/manage.py", {
|
|
2412
|
+
cwd: installDir,
|
|
2413
|
+
ignore: [
|
|
2414
|
+
"**/venv/**",
|
|
2415
|
+
"**/.venv/**",
|
|
2416
|
+
"**/env/**",
|
|
2417
|
+
"**/.env/**"
|
|
2418
|
+
]
|
|
2419
|
+
});
|
|
2420
|
+
for (const match of managePyMatches) try {
|
|
2421
|
+
const content = fs$1.readFileSync(path$1.join(installDir, match), "utf-8");
|
|
2422
|
+
if (content.includes("django") || content.includes("DJANGO_SETTINGS_MODULE")) return false;
|
|
2423
|
+
} catch {
|
|
2424
|
+
continue;
|
|
2425
|
+
}
|
|
2426
|
+
for (const configFile of pythonConfigFiles) try {
|
|
2427
|
+
const content = fs$1.readFileSync(path$1.join(installDir, configFile), "utf-8");
|
|
2428
|
+
if (/^flask([<>=~!]|$|\s)/im.test(content) || /["']flask["']/i.test(content)) return false;
|
|
2429
|
+
} catch {
|
|
2430
|
+
continue;
|
|
2431
|
+
}
|
|
2432
|
+
const pyFiles = await fg([
|
|
2433
|
+
"**/app.py",
|
|
2434
|
+
"**/wsgi.py",
|
|
2435
|
+
"**/application.py",
|
|
2436
|
+
"**/__init__.py"
|
|
2437
|
+
], {
|
|
2438
|
+
cwd: installDir,
|
|
2439
|
+
ignore: [
|
|
2440
|
+
"**/venv/**",
|
|
2441
|
+
"**/.venv/**",
|
|
2442
|
+
"**/env/**",
|
|
2443
|
+
"**/.env/**",
|
|
2444
|
+
"**/__pycache__/**"
|
|
2445
|
+
]
|
|
2446
|
+
});
|
|
2447
|
+
for (const pyFile of pyFiles) try {
|
|
2448
|
+
const content = fs$1.readFileSync(path$1.join(installDir, pyFile), "utf-8");
|
|
2449
|
+
if (content.includes("from flask import") || content.includes("import flask") || /Flask\s*\(/.test(content)) return false;
|
|
2450
|
+
} catch {
|
|
2451
|
+
continue;
|
|
2452
|
+
}
|
|
2453
|
+
return true;
|
|
2454
|
+
},
|
|
2455
|
+
detectPackageManager: detectPythonPackageManagers
|
|
2456
|
+
},
|
|
2457
|
+
environment: {
|
|
2458
|
+
uploadToHosting: false,
|
|
2459
|
+
getEnvVars: (apiKey, host) => ({
|
|
2460
|
+
POSTHOG_PROJECT_TOKEN: apiKey,
|
|
2461
|
+
POSTHOG_HOST: host
|
|
2462
|
+
})
|
|
2463
|
+
},
|
|
2464
|
+
analytics: { getTags: (context) => {
|
|
2465
|
+
return { packageManager: context.packageManager ? getPackageManagerName$1(context.packageManager) : "unknown" };
|
|
2466
|
+
} },
|
|
2467
|
+
prompts: {
|
|
2468
|
+
packageInstallation: PYTHON_PACKAGE_INSTALLATION,
|
|
2469
|
+
projectTypeDetection: "This is a generic Python project. Look for requirements.txt, pyproject.toml, setup.py, or Pipfile to confirm.",
|
|
2470
|
+
getAdditionalContextLines: (context) => {
|
|
2471
|
+
return [
|
|
2472
|
+
`Package manager: ${context.packageManager ? getPackageManagerName$1(context.packageManager) : "unknown"}`,
|
|
2473
|
+
`Framework docs ID: python (use posthog://docs/frameworks/python for documentation)`,
|
|
2474
|
+
`Project type: Generic Python application (CLI, script, worker, data pipeline, etc.)`
|
|
2475
|
+
];
|
|
2476
|
+
}
|
|
2477
|
+
},
|
|
2478
|
+
ui: {
|
|
2479
|
+
successMessage: "PostHog integration complete",
|
|
2480
|
+
estimatedDurationMinutes: 5,
|
|
2481
|
+
getOutroChanges: (context) => {
|
|
2482
|
+
return [
|
|
2483
|
+
`Analyzed your Python project structure`,
|
|
2484
|
+
`Installed the PostHog Python package using ${context.packageManager ? getPackageManagerName$1(context.packageManager) : "package manager"}`,
|
|
2485
|
+
`Created PostHog initialization using instance-based API (Posthog class)`,
|
|
2486
|
+
`Configured exception autocapture and graceful shutdown`,
|
|
2487
|
+
`Added example code for events, feature flags, and error capture (without PII)`
|
|
2488
|
+
];
|
|
2489
|
+
},
|
|
2490
|
+
getOutroNextSteps: () => [
|
|
2491
|
+
"Use Posthog() class (not module-level posthog) with enable_exception_autocapture=True",
|
|
2492
|
+
"Call posthog_client.shutdown() on application exit (use atexit.register)",
|
|
2493
|
+
"NEVER send PII in event properties (no emails, names, or user content)",
|
|
2494
|
+
"Use posthog_client.capture() for events and posthog_client.identify() for users",
|
|
2495
|
+
"Visit your PostHog dashboard to see incoming events"
|
|
2496
|
+
]
|
|
2497
|
+
}
|
|
2498
|
+
};
|
|
2499
|
+
//#endregion
|
|
2500
|
+
//#region src/frameworks/ruby/utils.ts
|
|
2501
|
+
const IGNORE_PATTERNS = [
|
|
2502
|
+
"**/node_modules/**",
|
|
2503
|
+
"**/vendor/**",
|
|
2504
|
+
"**/vendor/bundle/**",
|
|
2505
|
+
"**/tmp/**",
|
|
2506
|
+
"**/log/**"
|
|
2507
|
+
];
|
|
2508
|
+
/**
|
|
2509
|
+
* Get Ruby version bucket for analytics
|
|
2510
|
+
*/
|
|
2511
|
+
const getRubyVersionBucket = createVersionBucket();
|
|
2512
|
+
/**
|
|
2513
|
+
* Detect Ruby package manager
|
|
2514
|
+
*/
|
|
2515
|
+
function detectPackageManager(options) {
|
|
2516
|
+
const { installDir } = options;
|
|
2517
|
+
const gemfilePath = path$1.join(installDir, "Gemfile");
|
|
2518
|
+
if (fs$1.existsSync(gemfilePath)) return "bundler";
|
|
2519
|
+
return "manual";
|
|
2520
|
+
}
|
|
2521
|
+
/**
|
|
2522
|
+
* Get human-readable name for package manager
|
|
2523
|
+
*/
|
|
2524
|
+
function getPackageManagerName(packageManager) {
|
|
2525
|
+
switch (packageManager) {
|
|
2526
|
+
case "bundler": return "Bundler";
|
|
2527
|
+
case "manual": return "gem install";
|
|
2528
|
+
}
|
|
2529
|
+
}
|
|
2530
|
+
/**
|
|
2531
|
+
* Get Ruby version from .ruby-version file or Gemfile
|
|
2532
|
+
*/
|
|
2533
|
+
function getRubyVersion(options) {
|
|
2534
|
+
const { installDir } = options;
|
|
2535
|
+
const rubyVersionPath = path$1.join(installDir, ".ruby-version");
|
|
2536
|
+
try {
|
|
2537
|
+
const version = fs$1.readFileSync(rubyVersionPath, "utf-8").trim().replace(/^ruby-/, "");
|
|
2538
|
+
if (/^[0-9]+\.[0-9]+/.test(version)) return version;
|
|
2539
|
+
} catch {}
|
|
2540
|
+
const gemfilePath = path$1.join(installDir, "Gemfile");
|
|
2541
|
+
try {
|
|
2542
|
+
const match = fs$1.readFileSync(gemfilePath, "utf-8").match(/ruby\s+['"]([0-9]+\.[0-9]+(?:\.[0-9]+)?)['"]/);
|
|
2543
|
+
if (match) return match[1];
|
|
2544
|
+
} catch {}
|
|
2545
|
+
}
|
|
2546
|
+
/**
|
|
2547
|
+
* Check if the project is a Ruby project (but not Rails)
|
|
2548
|
+
*/
|
|
2549
|
+
async function isRubyProject(options) {
|
|
2550
|
+
const { installDir } = options;
|
|
2551
|
+
const gemfilePath = path$1.join(installDir, "Gemfile");
|
|
2552
|
+
if (fs$1.existsSync(gemfilePath)) {
|
|
2553
|
+
try {
|
|
2554
|
+
const content = fs$1.readFileSync(gemfilePath, "utf-8");
|
|
2555
|
+
if (/^\s*gem\s+['"]rails['"]/im.test(content)) return false;
|
|
2556
|
+
} catch {}
|
|
2557
|
+
return true;
|
|
2558
|
+
}
|
|
2559
|
+
const rubyVersionPath = path$1.join(installDir, ".ruby-version");
|
|
2560
|
+
if (fs$1.existsSync(rubyVersionPath)) return true;
|
|
2561
|
+
if ((await fg("*.gemspec", {
|
|
2562
|
+
cwd: installDir,
|
|
2563
|
+
ignore: IGNORE_PATTERNS
|
|
2564
|
+
})).length > 0) return true;
|
|
2565
|
+
return (await fg([
|
|
2566
|
+
"*.rb",
|
|
2567
|
+
"lib/**/*.rb",
|
|
2568
|
+
"bin/**/*.rb"
|
|
2569
|
+
], {
|
|
2570
|
+
cwd: installDir,
|
|
2571
|
+
ignore: IGNORE_PATTERNS
|
|
2572
|
+
})).length > 0;
|
|
2573
|
+
}
|
|
2574
|
+
//#endregion
|
|
2575
|
+
//#region src/frameworks/ruby/ruby-wizard-agent.ts
|
|
2576
|
+
const RUBY_AGENT_CONFIG = {
|
|
2577
|
+
metadata: {
|
|
2578
|
+
name: "Ruby",
|
|
2579
|
+
integration: "ruby",
|
|
2580
|
+
beta: true,
|
|
2581
|
+
docsUrl: "https://posthog.com/docs/libraries/ruby",
|
|
2582
|
+
gatherContext: (options) => {
|
|
2583
|
+
const packageManager = detectPackageManager(options);
|
|
2584
|
+
return Promise.resolve({ packageManager });
|
|
2585
|
+
}
|
|
2586
|
+
},
|
|
2587
|
+
detection: {
|
|
2588
|
+
packageName: "ruby",
|
|
2589
|
+
packageDisplayName: "Ruby",
|
|
2590
|
+
usesPackageJson: false,
|
|
2591
|
+
getVersion: () => void 0,
|
|
2592
|
+
getVersionBucket: getRubyVersionBucket,
|
|
2593
|
+
minimumVersion: "2.7.0",
|
|
2594
|
+
getInstalledVersion: (options) => Promise.resolve(getRubyVersion(options)),
|
|
2595
|
+
detect: async (options) => isRubyProject(options),
|
|
2596
|
+
detectPackageManager: bundlerPackageManager
|
|
2597
|
+
},
|
|
2598
|
+
environment: {
|
|
2599
|
+
uploadToHosting: false,
|
|
2600
|
+
getEnvVars: (apiKey, host) => ({
|
|
2601
|
+
POSTHOG_PROJECT_TOKEN: apiKey,
|
|
2602
|
+
POSTHOG_HOST: host
|
|
2603
|
+
})
|
|
2604
|
+
},
|
|
2605
|
+
analytics: { getTags: (context) => {
|
|
2606
|
+
return { packageManager: context.packageManager ? getPackageManagerName(context.packageManager) : "unknown" };
|
|
2607
|
+
} },
|
|
2608
|
+
prompts: {
|
|
2609
|
+
projectTypeDetection: "This is a Ruby project. Look for Gemfile, *.gemspec, .ruby-version, or *.rb files to confirm.",
|
|
2610
|
+
packageInstallation: "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.",
|
|
2611
|
+
getAdditionalContextLines: (context) => {
|
|
2612
|
+
return [
|
|
2613
|
+
`Package manager: ${context.packageManager ? getPackageManagerName(context.packageManager) : "unknown"}`,
|
|
2614
|
+
`Framework docs ID: ruby (use posthog://docs/frameworks/ruby for documentation)`,
|
|
2615
|
+
`Project type: Generic Ruby application (CLI, script, gem, worker, etc.)`,
|
|
2616
|
+
``,
|
|
2617
|
+
`## CRITICAL: Ruby PostHog Best Practices`,
|
|
2618
|
+
``,
|
|
2619
|
+
`### 1. Gem Name vs Require`,
|
|
2620
|
+
`The gem is named posthog-ruby but you require it as 'posthog':`,
|
|
2621
|
+
` gem 'posthog-ruby' # in Gemfile`,
|
|
2622
|
+
` require 'posthog' # in code (NOT require 'posthog-ruby')`,
|
|
2623
|
+
``,
|
|
2624
|
+
`### 2. Use Instance-Based API (REQUIRED for scripts/CLIs)`,
|
|
2625
|
+
`Use PostHog::Client.new for scripts and standalone applications:`,
|
|
2626
|
+
``,
|
|
2627
|
+
`client = PostHog::Client.new(`,
|
|
2628
|
+
` api_key: ENV['POSTHOG_PROJECT_TOKEN'],`,
|
|
2629
|
+
` host: ENV['POSTHOG_HOST'] || 'https://us.i.posthog.com'`,
|
|
2630
|
+
`)`,
|
|
2631
|
+
``,
|
|
2632
|
+
`### 3. MUST Call shutdown Before Exit`,
|
|
2633
|
+
`In scripts and CLIs, you MUST call client.shutdown or events will be lost:`,
|
|
2634
|
+
``,
|
|
2635
|
+
`begin`,
|
|
2636
|
+
` client.capture(distinct_id: 'user_123', event: 'my_event')`,
|
|
2637
|
+
`ensure`,
|
|
2638
|
+
` client.shutdown`,
|
|
2639
|
+
`end`,
|
|
2640
|
+
``,
|
|
2641
|
+
`### 4. capture_exception Takes Positional Args`,
|
|
2642
|
+
`client.capture_exception(exception, distinct_id, additional_properties)`,
|
|
2643
|
+
`Do NOT use keyword arguments for capture_exception.`,
|
|
2644
|
+
``,
|
|
2645
|
+
`### 5. NEVER Send PII`,
|
|
2646
|
+
`Do NOT include emails, names, phone numbers, or user content in event properties.`
|
|
2647
|
+
];
|
|
2648
|
+
}
|
|
2649
|
+
},
|
|
2650
|
+
ui: {
|
|
2651
|
+
successMessage: "PostHog integration complete",
|
|
2652
|
+
estimatedDurationMinutes: 5,
|
|
2653
|
+
getOutroChanges: (context) => {
|
|
2654
|
+
return [
|
|
2655
|
+
`Analyzed your Ruby project structure`,
|
|
2656
|
+
`Installed the posthog-ruby gem using ${context.packageManager ? getPackageManagerName(context.packageManager) : "package manager"}`,
|
|
2657
|
+
`Created PostHog initialization with instance-based API`,
|
|
2658
|
+
`Configured shutdown handler for proper event flushing`
|
|
2659
|
+
];
|
|
2660
|
+
},
|
|
2661
|
+
getOutroNextSteps: () => [
|
|
2662
|
+
"Use client.capture() for events and client.identify() for users",
|
|
2663
|
+
"Always call client.shutdown() before your application exits",
|
|
2664
|
+
"Visit your PostHog dashboard to see incoming events"
|
|
2665
|
+
]
|
|
2666
|
+
}
|
|
2667
|
+
};
|
|
2668
|
+
//#endregion
|
|
2669
|
+
//#region src/frameworks/javascript-node/javascript-node-wizard-agent.ts
|
|
2670
|
+
const JAVASCRIPT_NODE_AGENT_CONFIG = {
|
|
2671
|
+
metadata: {
|
|
2672
|
+
name: "Node.js",
|
|
2673
|
+
integration: "javascript_node",
|
|
2674
|
+
beta: true,
|
|
2675
|
+
docsUrl: "https://posthog.com/docs/libraries/node"
|
|
2676
|
+
},
|
|
2677
|
+
detection: {
|
|
2678
|
+
packageName: "posthog-node",
|
|
2679
|
+
packageDisplayName: "Node.js",
|
|
2680
|
+
usesPackageJson: false,
|
|
2681
|
+
getVersion: () => void 0,
|
|
2682
|
+
detectPackageManager: detectNodePackageManagers,
|
|
2683
|
+
detect: async (options) => {
|
|
2684
|
+
return !!await tryGetPackageJson(options);
|
|
2685
|
+
}
|
|
2686
|
+
},
|
|
2687
|
+
environment: {
|
|
2688
|
+
uploadToHosting: false,
|
|
2689
|
+
getEnvVars: (apiKey, host) => ({
|
|
2690
|
+
POSTHOG_PROJECT_TOKEN: apiKey,
|
|
2691
|
+
POSTHOG_HOST: host
|
|
2692
|
+
})
|
|
2693
|
+
},
|
|
2694
|
+
analytics: { getTags: () => ({}) },
|
|
2695
|
+
prompts: {
|
|
2696
|
+
projectTypeDetection: "This is a server-side Node.js project. Look for package.json and lockfiles to confirm.",
|
|
2697
|
+
packageInstallation: "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.",
|
|
2698
|
+
getAdditionalContextLines: () => [`Framework docs ID: javascript_node (use posthog://docs/frameworks/javascript_node for documentation)`]
|
|
2699
|
+
},
|
|
2700
|
+
ui: {
|
|
2701
|
+
successMessage: "PostHog integration complete",
|
|
2702
|
+
estimatedDurationMinutes: 5,
|
|
2703
|
+
getOutroChanges: () => [
|
|
2704
|
+
`Analyzed your Node.js project structure`,
|
|
2705
|
+
`Installed the posthog-node package`,
|
|
2706
|
+
`Created PostHog initialization with proper configuration`,
|
|
2707
|
+
`Configured graceful shutdown for event flushing`,
|
|
2708
|
+
`Added example code for events, feature flags, and error capture`
|
|
2709
|
+
],
|
|
2710
|
+
getOutroNextSteps: () => [
|
|
2711
|
+
"Use the PostHog client instance for all tracking calls",
|
|
2712
|
+
"Call posthog.shutdown() on application exit to flush pending events",
|
|
2713
|
+
"NEVER send PII in event properties (no emails, names, or user content)",
|
|
2714
|
+
"Use posthog.capture() for events and posthog.identify() for users",
|
|
2715
|
+
"Visit your PostHog dashboard to see incoming events"
|
|
2716
|
+
]
|
|
2717
|
+
}
|
|
2718
|
+
};
|
|
2719
|
+
//#endregion
|
|
2720
|
+
//#region src/frameworks/javascript-web/utils.ts
|
|
2721
|
+
const INDEX_HTML_MAX_DEPTH = 6;
|
|
2722
|
+
const INDEX_HTML_IGNORE_DIRS = new Set([
|
|
2723
|
+
"node_modules",
|
|
2724
|
+
".git",
|
|
2725
|
+
".next",
|
|
2726
|
+
"dist",
|
|
2727
|
+
"build",
|
|
2728
|
+
".turbo",
|
|
2729
|
+
".cache"
|
|
2730
|
+
]);
|
|
2731
|
+
/**
|
|
2732
|
+
* Packages that indicate a specific framework integration exists.
|
|
2733
|
+
* If any of these are in package.json, we should NOT match as generic JavaScript.
|
|
2734
|
+
*
|
|
2735
|
+
* When adding a new JS framework integration to the wizard,
|
|
2736
|
+
* add its detection package here too.
|
|
2737
|
+
*/
|
|
2738
|
+
const FRAMEWORK_PACKAGES = [
|
|
2739
|
+
"next",
|
|
2740
|
+
"nuxt",
|
|
2741
|
+
"vue",
|
|
2742
|
+
"react-router",
|
|
2743
|
+
"@tanstack/react-start",
|
|
2744
|
+
"@tanstack/react-router",
|
|
2745
|
+
"react-native",
|
|
2746
|
+
"@angular/core",
|
|
2747
|
+
"astro",
|
|
2748
|
+
"@sveltejs/kit"
|
|
2749
|
+
];
|
|
2750
|
+
/**
|
|
2751
|
+
* Detect the JS package manager for the project by checking lockfiles.
|
|
2752
|
+
* Reuses the existing package manager detection infrastructure.
|
|
2753
|
+
*/
|
|
2754
|
+
function detectJsPackageManager(options) {
|
|
2755
|
+
const detected = detectAllPackageManagers(options);
|
|
2756
|
+
if (detected.length > 0) return detected[0].label;
|
|
2757
|
+
return "unknown";
|
|
2758
|
+
}
|
|
2759
|
+
/**
|
|
2760
|
+
* Detect the bundler used in the project by checking package.json dependencies.
|
|
2761
|
+
*/
|
|
2762
|
+
function detectBundler(options) {
|
|
2763
|
+
try {
|
|
2764
|
+
const content = fs$1.readFileSync(path$1.join(options.installDir, "package.json"), "utf-8");
|
|
2765
|
+
const pkg = JSON.parse(content);
|
|
2766
|
+
const allDeps = {
|
|
2767
|
+
...pkg.dependencies,
|
|
2768
|
+
...pkg.devDependencies
|
|
2769
|
+
};
|
|
2770
|
+
if (allDeps["vite"]) return "vite";
|
|
2771
|
+
if (allDeps["webpack"]) return "webpack";
|
|
2772
|
+
if (allDeps["esbuild"]) return "esbuild";
|
|
2773
|
+
if (allDeps["parcel"]) return "parcel";
|
|
2774
|
+
if (allDeps["rollup"]) return "rollup";
|
|
2775
|
+
return;
|
|
2776
|
+
} catch {
|
|
2777
|
+
return;
|
|
2778
|
+
}
|
|
2779
|
+
}
|
|
2780
|
+
/**
|
|
2781
|
+
* Heuristic: check if there is an index.html anywhere in the project,
|
|
2782
|
+
* ignoring common build and dependency directories.
|
|
2783
|
+
*/
|
|
2784
|
+
function hasIndexHtml(options) {
|
|
2785
|
+
const root = options.installDir;
|
|
2786
|
+
function search(dir, depth) {
|
|
2787
|
+
if (depth > INDEX_HTML_MAX_DEPTH) return false;
|
|
2788
|
+
const base = path$1.basename(dir);
|
|
2789
|
+
if (INDEX_HTML_IGNORE_DIRS.has(base)) return false;
|
|
2790
|
+
let entries;
|
|
2791
|
+
try {
|
|
2792
|
+
entries = fs$1.readdirSync(dir, { withFileTypes: true });
|
|
2793
|
+
} catch {
|
|
2794
|
+
return false;
|
|
2795
|
+
}
|
|
2796
|
+
for (const entry of entries) if (entry.isFile() && entry.name.toLowerCase() === "index.html") return true;
|
|
2797
|
+
for (const entry of entries) if (entry.isDirectory()) {
|
|
2798
|
+
if (search(path$1.join(dir, entry.name), depth + 1)) return true;
|
|
2799
|
+
}
|
|
2800
|
+
return false;
|
|
2801
|
+
}
|
|
2802
|
+
return search(root, 0);
|
|
2803
|
+
}
|
|
2804
|
+
//#endregion
|
|
2805
|
+
//#region src/frameworks/javascript-web/javascript-web-wizard-agent.ts
|
|
2806
|
+
const JAVASCRIPT_WEB_AGENT_CONFIG = {
|
|
2807
|
+
metadata: {
|
|
2808
|
+
name: "JavaScript (Web)",
|
|
2809
|
+
integration: "javascript_web",
|
|
2810
|
+
beta: true,
|
|
2811
|
+
docsUrl: "https://posthog.com/docs/libraries/js",
|
|
2812
|
+
gatherContext: (options) => {
|
|
2813
|
+
const packageManagerName = detectJsPackageManager(options);
|
|
2814
|
+
const hasTypeScript = fs$1.existsSync(path$1.join(options.installDir, "tsconfig.json"));
|
|
2815
|
+
const hasBundler = detectBundler(options);
|
|
2816
|
+
return Promise.resolve({
|
|
2817
|
+
packageManagerName,
|
|
2818
|
+
hasTypeScript,
|
|
2819
|
+
hasBundler
|
|
2820
|
+
});
|
|
2821
|
+
}
|
|
2822
|
+
},
|
|
2823
|
+
detection: {
|
|
2824
|
+
packageName: "posthog-js",
|
|
2825
|
+
packageDisplayName: "JavaScript (Web)",
|
|
2826
|
+
usesPackageJson: false,
|
|
2827
|
+
getVersion: () => void 0,
|
|
2828
|
+
detectPackageManager: detectNodePackageManagers,
|
|
2829
|
+
detect: async (options) => {
|
|
2830
|
+
const packageJson = await tryGetPackageJson(options);
|
|
2831
|
+
if (!packageJson) return false;
|
|
2832
|
+
for (const frameworkPkg of FRAMEWORK_PACKAGES) if (hasPackageInstalled(frameworkPkg, packageJson)) return false;
|
|
2833
|
+
const { installDir } = options;
|
|
2834
|
+
const hasIndexHtmlFlag = hasIndexHtml(options);
|
|
2835
|
+
const hasBundler = !!detectBundler(options);
|
|
2836
|
+
if ([
|
|
2837
|
+
"package-lock.json",
|
|
2838
|
+
"yarn.lock",
|
|
2839
|
+
"pnpm-lock.yaml",
|
|
2840
|
+
"bun.lockb",
|
|
2841
|
+
"bun.lock",
|
|
2842
|
+
"deno.lock"
|
|
2843
|
+
].some((lockfile) => fs$1.existsSync(path$1.join(installDir, lockfile))) && (hasIndexHtmlFlag || hasBundler)) return true;
|
|
2844
|
+
return false;
|
|
2845
|
+
}
|
|
2846
|
+
},
|
|
2847
|
+
environment: {
|
|
2848
|
+
uploadToHosting: false,
|
|
2849
|
+
getEnvVars: (apiKey, host) => ({
|
|
2850
|
+
POSTHOG_PROJECT_TOKEN: apiKey,
|
|
2851
|
+
POSTHOG_HOST: host
|
|
2852
|
+
})
|
|
2853
|
+
},
|
|
2854
|
+
analytics: { getTags: (context) => {
|
|
2855
|
+
const tags = { packageManager: context.packageManagerName ?? "unknown" };
|
|
2856
|
+
if (context.hasBundler) tags.bundler = context.hasBundler;
|
|
2857
|
+
return tags;
|
|
2858
|
+
} },
|
|
2859
|
+
prompts: {
|
|
2860
|
+
projectTypeDetection: "This is a JavaScript/TypeScript project. Look for package.json and lockfiles (package-lock.json, yarn.lock, pnpm-lock.yaml, bun.lockb) to confirm.",
|
|
2861
|
+
packageInstallation: "Look for lockfiles to determine the package manager (npm, yarn, pnpm, bun). Do not manually edit package.json.",
|
|
2862
|
+
getAdditionalContextLines: (context) => {
|
|
2863
|
+
const lines = [
|
|
2864
|
+
`Package manager: ${context.packageManagerName ?? "unknown"}`,
|
|
2865
|
+
`Has TypeScript: ${context.hasTypeScript ? "yes" : "no"}`,
|
|
2866
|
+
`Framework docs ID: js (use posthog://docs/frameworks/js for documentation if available)`,
|
|
2867
|
+
`Project type: Generic JavaScript/TypeScript application (no specific framework detected)`
|
|
2868
|
+
];
|
|
2869
|
+
if (context.hasBundler) lines.unshift(`Bundler: ${context.hasBundler}`);
|
|
2870
|
+
return lines;
|
|
2871
|
+
}
|
|
2872
|
+
},
|
|
2873
|
+
ui: {
|
|
2874
|
+
successMessage: "PostHog integration complete",
|
|
2875
|
+
estimatedDurationMinutes: 5,
|
|
2876
|
+
getOutroChanges: (context) => {
|
|
2877
|
+
return [
|
|
2878
|
+
`Analyzed your JavaScript project structure`,
|
|
2879
|
+
`Installed the posthog-js package using ${context.packageManagerName ?? "package manager"}`,
|
|
2880
|
+
`Created PostHog initialization code`,
|
|
2881
|
+
`Configured autocapture, error tracking, and event capture`
|
|
2882
|
+
];
|
|
2883
|
+
},
|
|
2884
|
+
getOutroNextSteps: () => [
|
|
2885
|
+
"Ensure posthog.init() is called before any capture calls",
|
|
2886
|
+
"Autocapture tracks clicks, form submissions, and pageviews automatically",
|
|
2887
|
+
"Use posthog.capture() for custom events and posthog.identify() for users",
|
|
2888
|
+
"NEVER send PII in event properties (no emails, names, or user content)",
|
|
2889
|
+
"Visit your PostHog dashboard to see incoming events"
|
|
2890
|
+
]
|
|
2891
|
+
}
|
|
2892
|
+
};
|
|
2893
|
+
//#endregion
|
|
2894
|
+
//#region src/lib/registry.ts
|
|
2895
|
+
var registry_exports = /* @__PURE__ */ __exportAll({ FRAMEWORK_REGISTRY: () => FRAMEWORK_REGISTRY });
|
|
2896
|
+
const FRAMEWORK_REGISTRY = {
|
|
2897
|
+
["nextjs"]: NEXTJS_AGENT_CONFIG,
|
|
2898
|
+
["nuxt"]: NUXT_AGENT_CONFIG,
|
|
2899
|
+
["vue"]: VUE_AGENT_CONFIG,
|
|
2900
|
+
["tanstack-start"]: TANSTACK_START_AGENT_CONFIG,
|
|
2901
|
+
["react-router"]: REACT_ROUTER_AGENT_CONFIG,
|
|
2902
|
+
["tanstack-router"]: TANSTACK_ROUTER_AGENT_CONFIG,
|
|
2903
|
+
["react-native"]: REACT_NATIVE_AGENT_CONFIG,
|
|
2904
|
+
["angular"]: ANGULAR_AGENT_CONFIG,
|
|
2905
|
+
["astro"]: ASTRO_AGENT_CONFIG,
|
|
2906
|
+
["django"]: DJANGO_AGENT_CONFIG,
|
|
2907
|
+
["flask"]: FLASK_AGENT_CONFIG,
|
|
2908
|
+
["fastapi"]: FASTAPI_AGENT_CONFIG,
|
|
2909
|
+
["laravel"]: LARAVEL_AGENT_CONFIG,
|
|
2910
|
+
["sveltekit"]: SVELTEKIT_AGENT_CONFIG,
|
|
2911
|
+
["swift"]: SWIFT_AGENT_CONFIG,
|
|
2912
|
+
["android"]: ANDROID_AGENT_CONFIG,
|
|
2913
|
+
["rails"]: RAILS_AGENT_CONFIG,
|
|
2914
|
+
["python"]: PYTHON_AGENT_CONFIG,
|
|
2915
|
+
["ruby"]: RUBY_AGENT_CONFIG,
|
|
2916
|
+
["javascript_node"]: JAVASCRIPT_NODE_AGENT_CONFIG,
|
|
2917
|
+
["javascript_web"]: JAVASCRIPT_WEB_AGENT_CONFIG
|
|
2918
|
+
};
|
|
2919
|
+
//#endregion
|
|
2920
|
+
export { SPINNER_MESSAGE as i, registry_exports as n, DEFAULT_PACKAGE_INSTALLATION as r, FRAMEWORK_REGISTRY as t };
|
|
2921
|
+
|
|
2922
|
+
//# sourceMappingURL=registry-s55_iuJT.js.map
|