@posthog/wizard 1.31.1 → 1.32.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (183) hide show
  1. package/README.md +2 -1
  2. package/dist/bin.js +14 -1
  3. package/dist/bin.js.map +1 -1
  4. package/dist/src/__tests__/run.test.js +5 -5
  5. package/dist/src/__tests__/run.test.js.map +1 -1
  6. package/dist/src/android/android-wizard-agent.d.ts +6 -0
  7. package/dist/src/android/android-wizard-agent.js +140 -0
  8. package/dist/src/android/android-wizard-agent.js.map +1 -0
  9. package/dist/src/android/utils.d.ts +11 -0
  10. package/dist/src/android/utils.js +97 -0
  11. package/dist/src/android/utils.js.map +1 -0
  12. package/dist/src/angular/angular-wizard-agent.d.ts +4 -0
  13. package/dist/src/angular/angular-wizard-agent.js +67 -0
  14. package/dist/src/angular/angular-wizard-agent.js.map +1 -0
  15. package/dist/src/angular/utils.d.ts +4 -0
  16. package/dist/src/angular/utils.js +9 -0
  17. package/dist/src/angular/utils.js.map +1 -0
  18. package/dist/src/astro/astro-wizard-agent.d.ts +7 -0
  19. package/dist/src/astro/astro-wizard-agent.js +102 -0
  20. package/dist/src/astro/astro-wizard-agent.js.map +1 -0
  21. package/dist/src/astro/utils.d.ts +17 -0
  22. package/dist/src/astro/utils.js +163 -0
  23. package/dist/src/astro/utils.js.map +1 -0
  24. package/dist/src/django/django-wizard-agent.d.ts +8 -5
  25. package/dist/src/django/django-wizard-agent.js +62 -51
  26. package/dist/src/django/django-wizard-agent.js.map +1 -1
  27. package/dist/src/django/utils.d.ts +1 -1
  28. package/dist/src/django/utils.js +3 -22
  29. package/dist/src/django/utils.js.map +1 -1
  30. package/dist/src/fastapi/fastapi-wizard-agent.d.ts +7 -0
  31. package/dist/src/fastapi/fastapi-wizard-agent.js +217 -0
  32. package/dist/src/fastapi/fastapi-wizard-agent.js.map +1 -0
  33. package/dist/src/fastapi/utils.d.ts +26 -0
  34. package/dist/src/fastapi/utils.js +258 -0
  35. package/dist/src/fastapi/utils.js.map +1 -0
  36. package/dist/src/flask/flask-wizard-agent.d.ts +8 -5
  37. package/dist/src/flask/flask-wizard-agent.js +67 -51
  38. package/dist/src/flask/flask-wizard-agent.js.map +1 -1
  39. package/dist/src/flask/utils.d.ts +1 -1
  40. package/dist/src/flask/utils.js +3 -22
  41. package/dist/src/flask/utils.js.map +1 -1
  42. package/dist/src/laravel/laravel-wizard-agent.d.ts +10 -5
  43. package/dist/src/laravel/laravel-wizard-agent.js +50 -53
  44. package/dist/src/laravel/laravel-wizard-agent.js.map +1 -1
  45. package/dist/src/laravel/utils.d.ts +1 -1
  46. package/dist/src/laravel/utils.js +3 -22
  47. package/dist/src/laravel/utils.js.map +1 -1
  48. package/dist/src/lib/__tests__/agent-interface.test.js +1 -0
  49. package/dist/src/lib/__tests__/agent-interface.test.js.map +1 -1
  50. package/dist/src/lib/agent-interface.d.ts +4 -1
  51. package/dist/src/lib/agent-interface.js +36 -3
  52. package/dist/src/lib/agent-interface.js.map +1 -1
  53. package/dist/src/lib/agent-runner.js +69 -6
  54. package/dist/src/lib/agent-runner.js.map +1 -1
  55. package/dist/src/lib/api.d.ts +4 -4
  56. package/dist/src/lib/constants.d.ts +15 -14
  57. package/dist/src/lib/constants.js +17 -40
  58. package/dist/src/lib/constants.js.map +1 -1
  59. package/dist/src/lib/env-file-tools.d.ts +11 -0
  60. package/dist/src/lib/env-file-tools.js +154 -0
  61. package/dist/src/lib/env-file-tools.js.map +1 -0
  62. package/dist/src/lib/framework-config.d.ts +34 -16
  63. package/dist/src/lib/framework-config.js.map +1 -1
  64. package/dist/src/lib/registry.d.ts +3 -0
  65. package/dist/src/lib/registry.js +41 -0
  66. package/dist/src/lib/registry.js.map +1 -0
  67. package/dist/src/nextjs/nextjs-wizard-agent.d.ts +7 -5
  68. package/dist/src/nextjs/nextjs-wizard-agent.js +16 -79
  69. package/dist/src/nextjs/nextjs-wizard-agent.js.map +1 -1
  70. package/dist/src/nextjs/utils.d.ts +1 -1
  71. package/dist/src/nextjs/utils.js +3 -22
  72. package/dist/src/nextjs/utils.js.map +1 -1
  73. package/dist/src/nuxt/nuxt-wizard-agent.d.ts +6 -0
  74. package/dist/src/nuxt/nuxt-wizard-agent.js +77 -0
  75. package/dist/src/nuxt/nuxt-wizard-agent.js.map +1 -0
  76. package/dist/src/python/python-wizard-agent.d.ts +7 -0
  77. package/dist/src/python/python-wizard-agent.js +269 -0
  78. package/dist/src/python/python-wizard-agent.js.map +1 -0
  79. package/dist/src/python/utils.d.ts +28 -0
  80. package/dist/src/python/utils.js +147 -0
  81. package/dist/src/python/utils.js.map +1 -0
  82. package/dist/src/react-native/react-native-wizard-agent.d.ts +7 -0
  83. package/dist/src/react-native/react-native-wizard-agent.js +91 -0
  84. package/dist/src/react-native/react-native-wizard-agent.js.map +1 -0
  85. package/dist/src/react-native/utils.d.ts +8 -0
  86. package/dist/src/react-native/utils.js +31 -0
  87. package/dist/src/react-native/utils.js.map +1 -0
  88. package/dist/src/react-router/react-router-wizard-agent.d.ts +7 -5
  89. package/dist/src/react-router/react-router-wizard-agent.js +18 -80
  90. package/dist/src/react-router/react-router-wizard-agent.js.map +1 -1
  91. package/dist/src/react-router/utils.d.ts +1 -1
  92. package/dist/src/react-router/utils.js +3 -21
  93. package/dist/src/react-router/utils.js.map +1 -1
  94. package/dist/src/run.d.ts +1 -0
  95. package/dist/src/run.js +28 -76
  96. package/dist/src/run.js.map +1 -1
  97. package/dist/src/steps/add-mcp-server-to-clients/clients/claude-code.d.ts +6 -6
  98. package/dist/src/steps/add-mcp-server-to-clients/clients/claude.d.ts +6 -6
  99. package/dist/src/steps/add-mcp-server-to-clients/clients/codex.d.ts +6 -6
  100. package/dist/src/steps/add-mcp-server-to-clients/clients/cursor.d.ts +6 -6
  101. package/dist/src/steps/add-mcp-server-to-clients/clients/visual-studio-code.d.ts +6 -6
  102. package/dist/src/steps/add-mcp-server-to-clients/clients/zed.d.ts +6 -6
  103. package/dist/src/steps/add-mcp-server-to-clients/defaults.d.ts +6 -6
  104. package/dist/src/svelte/svelte-wizard-agent.d.ts +4 -0
  105. package/dist/src/svelte/svelte-wizard-agent.js +60 -0
  106. package/dist/src/svelte/svelte-wizard-agent.js.map +1 -0
  107. package/dist/src/swift/swift-wizard-agent.d.ts +7 -0
  108. package/dist/src/swift/swift-wizard-agent.js +141 -0
  109. package/dist/src/swift/swift-wizard-agent.js.map +1 -0
  110. package/dist/src/swift/utils.d.ts +8 -0
  111. package/dist/src/swift/utils.js +105 -0
  112. package/dist/src/swift/utils.js.map +1 -0
  113. package/dist/src/tanstack-router/tanstack-router-wizard-agent.d.ts +7 -0
  114. package/dist/src/tanstack-router/tanstack-router-wizard-agent.js +93 -0
  115. package/dist/src/tanstack-router/tanstack-router-wizard-agent.js.map +1 -0
  116. package/dist/src/tanstack-router/utils.d.ts +17 -0
  117. package/dist/src/tanstack-router/utils.js +192 -0
  118. package/dist/src/tanstack-router/utils.js.map +1 -0
  119. package/dist/src/tanstack-start/tanstack-start-wizard-agent.d.ts +4 -0
  120. package/dist/src/tanstack-start/tanstack-start-wizard-agent.js +66 -0
  121. package/dist/src/tanstack-start/tanstack-start-wizard-agent.js.map +1 -0
  122. package/dist/src/tanstack-start/utils.d.ts +4 -0
  123. package/dist/src/tanstack-start/utils.js +9 -0
  124. package/dist/src/tanstack-start/utils.js.map +1 -0
  125. package/dist/src/utils/__tests__/semver.test.d.ts +1 -0
  126. package/dist/src/utils/__tests__/semver.test.js +117 -0
  127. package/dist/src/utils/__tests__/semver.test.js.map +1 -0
  128. package/dist/src/utils/clack-utils.js +3 -5
  129. package/dist/src/utils/clack-utils.js.map +1 -1
  130. package/dist/src/utils/debug.d.ts +2 -0
  131. package/dist/src/utils/debug.js +17 -5
  132. package/dist/src/utils/debug.js.map +1 -1
  133. package/dist/src/utils/file-utils.d.ts +1 -31
  134. package/dist/src/utils/file-utils.js +0 -163
  135. package/dist/src/utils/file-utils.js.map +1 -1
  136. package/dist/src/utils/semver.d.ts +16 -0
  137. package/dist/src/utils/semver.js +37 -0
  138. package/dist/src/utils/semver.js.map +1 -1
  139. package/dist/src/utils/types.d.ts +4 -0
  140. package/dist/src/utils/types.js.map +1 -1
  141. package/dist/src/vue/vue-wizard-agent.d.ts +4 -0
  142. package/dist/src/vue/vue-wizard-agent.js +64 -0
  143. package/dist/src/vue/vue-wizard-agent.js.map +1 -0
  144. package/package.json +1 -1
  145. package/dist/src/astro/astro-wizard.d.ts +0 -2
  146. package/dist/src/astro/astro-wizard.js +0 -89
  147. package/dist/src/astro/astro-wizard.js.map +0 -1
  148. package/dist/src/astro/docs.d.ts +0 -4
  149. package/dist/src/astro/docs.js +0 -101
  150. package/dist/src/astro/docs.js.map +0 -1
  151. package/dist/src/lib/config.d.ts +0 -104
  152. package/dist/src/lib/config.js +0 -368
  153. package/dist/src/lib/config.js.map +0 -1
  154. package/dist/src/lib/messages.d.ts +0 -16
  155. package/dist/src/lib/messages.js +0 -66
  156. package/dist/src/lib/messages.js.map +0 -1
  157. package/dist/src/lib/prompts.d.ts +0 -16
  158. package/dist/src/lib/prompts.js +0 -83
  159. package/dist/src/lib/prompts.js.map +0 -1
  160. package/dist/src/react/docs.d.ts +0 -4
  161. package/dist/src/react/docs.js +0 -49
  162. package/dist/src/react/docs.js.map +0 -1
  163. package/dist/src/react/react-wizard.d.ts +0 -2
  164. package/dist/src/react/react-wizard.js +0 -121
  165. package/dist/src/react/react-wizard.js.map +0 -1
  166. package/dist/src/react-native/docs.d.ts +0 -5
  167. package/dist/src/react-native/docs.js +0 -31
  168. package/dist/src/react-native/docs.js.map +0 -1
  169. package/dist/src/react-native/react-native-wizard.d.ts +0 -2
  170. package/dist/src/react-native/react-native-wizard.js +0 -128
  171. package/dist/src/react-native/react-native-wizard.js.map +0 -1
  172. package/dist/src/svelte/docs.d.ts +0 -3
  173. package/dist/src/svelte/docs.js +0 -111
  174. package/dist/src/svelte/docs.js.map +0 -1
  175. package/dist/src/svelte/svelte-wizard.d.ts +0 -2
  176. package/dist/src/svelte/svelte-wizard.js +0 -121
  177. package/dist/src/svelte/svelte-wizard.js.map +0 -1
  178. package/dist/src/utils/errors.d.ts +0 -3
  179. package/dist/src/utils/errors.js +0 -11
  180. package/dist/src/utils/errors.js.map +0 -1
  181. package/dist/src/utils/query.d.ts +0 -11
  182. package/dist/src/utils/query.js +0 -115
  183. package/dist/src/utils/query.js.map +0 -1
@@ -0,0 +1,269 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ var __importDefault = (this && this.__importDefault) || function (mod) {
36
+ return (mod && mod.__esModule) ? mod : { "default": mod };
37
+ };
38
+ Object.defineProperty(exports, "__esModule", { value: true });
39
+ exports.PYTHON_AGENT_CONFIG = void 0;
40
+ const constants_1 = require("../lib/constants");
41
+ const fast_glob_1 = __importDefault(require("fast-glob"));
42
+ const fs = __importStar(require("node:fs"));
43
+ const path = __importStar(require("node:path"));
44
+ const utils_1 = require("./utils");
45
+ exports.PYTHON_AGENT_CONFIG = {
46
+ metadata: {
47
+ name: 'Python Language',
48
+ integration: constants_1.Integration.python,
49
+ beta: true,
50
+ docsUrl: 'https://posthog.com/docs/libraries/python',
51
+ gatherContext: async (options) => {
52
+ const packageManager = await (0, utils_1.detectPackageManager)(options);
53
+ return { packageManager };
54
+ },
55
+ },
56
+ detection: {
57
+ packageName: 'python',
58
+ packageDisplayName: 'Python',
59
+ usesPackageJson: false,
60
+ getVersion: () => undefined,
61
+ getVersionBucket: utils_1.getPythonVersionBucket,
62
+ minimumVersion: '3.8.0',
63
+ getInstalledVersion: (options) => Promise.resolve((0, utils_1.getPythonVersion)(options)),
64
+ detect: async (options) => {
65
+ const { installDir } = options;
66
+ // Look for Python package management files
67
+ const pythonConfigFiles = await (0, fast_glob_1.default)([
68
+ '**/requirements*.txt',
69
+ '**/pyproject.toml',
70
+ '**/setup.py',
71
+ '**/Pipfile',
72
+ ], {
73
+ cwd: installDir,
74
+ ignore: ['**/venv/**', '**/.venv/**', '**/env/**', '**/.env/**'],
75
+ });
76
+ if (pythonConfigFiles.length === 0) {
77
+ return false;
78
+ }
79
+ // Make sure this isn't Django or Flask (those should be detected first)
80
+ // Check for Django
81
+ const managePyMatches = await (0, fast_glob_1.default)('**/manage.py', {
82
+ cwd: installDir,
83
+ ignore: ['**/venv/**', '**/.venv/**', '**/env/**', '**/.env/**'],
84
+ });
85
+ for (const match of managePyMatches) {
86
+ try {
87
+ const content = fs.readFileSync(path.join(installDir, match), 'utf-8');
88
+ if (content.includes('django') ||
89
+ content.includes('DJANGO_SETTINGS_MODULE')) {
90
+ return false; // Django detected, use django agent instead
91
+ }
92
+ }
93
+ catch {
94
+ continue;
95
+ }
96
+ }
97
+ // Check for Flask
98
+ for (const configFile of pythonConfigFiles) {
99
+ try {
100
+ const content = fs.readFileSync(path.join(installDir, configFile), 'utf-8');
101
+ if (/^flask([<>=~!]|$|\s)/im.test(content) ||
102
+ /["']flask["']/i.test(content)) {
103
+ return false; // Flask detected, use flask agent instead
104
+ }
105
+ }
106
+ catch {
107
+ continue;
108
+ }
109
+ }
110
+ const pyFiles = await (0, fast_glob_1.default)(['**/app.py', '**/wsgi.py', '**/application.py', '**/__init__.py'], {
111
+ cwd: installDir,
112
+ ignore: [
113
+ '**/venv/**',
114
+ '**/.venv/**',
115
+ '**/env/**',
116
+ '**/.env/**',
117
+ '**/__pycache__/**',
118
+ ],
119
+ });
120
+ for (const pyFile of pyFiles) {
121
+ try {
122
+ const content = fs.readFileSync(path.join(installDir, pyFile), 'utf-8');
123
+ if (content.includes('from flask import') ||
124
+ content.includes('import flask') ||
125
+ /Flask\s*\(/.test(content)) {
126
+ return false; // Flask detected, use flask agent instead
127
+ }
128
+ }
129
+ catch {
130
+ continue;
131
+ }
132
+ }
133
+ // If we have Python config files but it's not Django or Flask, it's a generic Python project
134
+ return true;
135
+ },
136
+ },
137
+ environment: {
138
+ uploadToHosting: false,
139
+ getEnvVars: (apiKey, host) => ({
140
+ POSTHOG_API_KEY: apiKey,
141
+ POSTHOG_HOST: host,
142
+ }),
143
+ },
144
+ analytics: {
145
+ getTags: (context) => {
146
+ const packageManagerName = context.packageManager
147
+ ? (0, utils_1.getPackageManagerName)(context.packageManager)
148
+ : 'unknown';
149
+ return {
150
+ packageManager: packageManagerName,
151
+ };
152
+ },
153
+ },
154
+ prompts: {
155
+ projectTypeDetection: 'This is a generic Python project. Look for requirements.txt, pyproject.toml, setup.py, or Pipfile to confirm.',
156
+ packageInstallation: 'Use pip, poetry, or pipenv based on existing config files (requirements.txt, pyproject.toml, Pipfile). Do not pin the posthog version - just add "posthog" without version constraints.',
157
+ getAdditionalContextLines: (context) => {
158
+ const packageManagerName = context.packageManager
159
+ ? (0, utils_1.getPackageManagerName)(context.packageManager)
160
+ : 'unknown';
161
+ const lines = [
162
+ `Package manager: ${packageManagerName}`,
163
+ `Framework docs ID: python (use posthog://docs/frameworks/python for documentation)`,
164
+ `Project type: Generic Python application (CLI, script, worker, data pipeline, etc.)`,
165
+ ``,
166
+ `## CRITICAL: Python PostHog Best Practices`,
167
+ ``,
168
+ `### 1. Use Instance-Based API (REQUIRED)`,
169
+ `Always use the Posthog() class constructor instead of module-level posthog:`,
170
+ ``,
171
+ `CORRECT:`,
172
+ `from posthog import Posthog`,
173
+ `posthog_client = Posthog(`,
174
+ ` api_key="your_api_key",`,
175
+ ` host="https://us.i.posthog.com",`,
176
+ ` debug=False,`,
177
+ ` enable_exception_autocapture=True, # Auto-capture exceptions`,
178
+ `)`,
179
+ ``,
180
+ `INCORRECT (DO NOT USE):`,
181
+ `import posthog`,
182
+ `posthog.api_key = "your_api_key" # Don't use module-level config`,
183
+ ``,
184
+ `### 2. Enable Exception Autocapture`,
185
+ `ALWAYS include enable_exception_autocapture=True in the Posthog() initialization to automatically track exceptions.`,
186
+ ``,
187
+ `### 3. NEVER Send PII (Personally Identifiable Information)`,
188
+ `DO NOT include in event properties:`,
189
+ `- Email addresses`,
190
+ `- Full names`,
191
+ `- Phone numbers`,
192
+ `- Physical addresses`,
193
+ `- IP addresses`,
194
+ `- Any user-generated content (messages, comments, form submissions)`,
195
+ ``,
196
+ `SAFE event properties:`,
197
+ `posthog_client.capture('contact_form_submitted', properties={`,
198
+ ` 'message_length': len(message), # Metadata is OK`,
199
+ ` 'has_email': bool(email), # Boolean flags are OK`,
200
+ ` 'form_type': 'contact' # Categories are OK`,
201
+ `})`,
202
+ ``,
203
+ `UNSAFE (DO NOT DO THIS):`,
204
+ `posthog_client.capture('form_submitted', properties={`,
205
+ ` 'email': user_email, # NEVER send actual email`,
206
+ ` 'message': message_content, # NEVER send user content`,
207
+ ` 'name': user_name # NEVER send names`,
208
+ `})`,
209
+ ``,
210
+ `### 4. Implement Graceful Shutdown`,
211
+ `ALWAYS call posthog_client.shutdown() when your application exits to ensure all events are flushed:`,
212
+ ``,
213
+ `import atexit`,
214
+ `atexit.register(posthog_client.shutdown) # Ensures events are sent on exit`,
215
+ ``,
216
+ `For Django, use AppConfig.ready() to register the shutdown handler.`,
217
+ `For Flask, use @app.teardown_appcontext or atexit.`,
218
+ `For scripts/workers, call shutdown() explicitly or use atexit.`,
219
+ ``,
220
+ `### 5. For Django Projects`,
221
+ `Initialize PostHog in your AppConfig.ready() method:`,
222
+ ``,
223
+ `from django.apps import AppConfig`,
224
+ `from posthog import Posthog`,
225
+ ``,
226
+ `class YourAppConfig(AppConfig):`,
227
+ ` posthog_client = None`,
228
+ ` `,
229
+ ` def ready(self):`,
230
+ ` if YourAppConfig.posthog_client is None:`,
231
+ ` YourAppConfig.posthog_client = Posthog(`,
232
+ ` settings.POSTHOG_API_KEY,`,
233
+ ` host=settings.POSTHOG_HOST,`,
234
+ ` debug=settings.DEBUG,`,
235
+ ` enable_exception_autocapture=True,`,
236
+ ` )`,
237
+ ` import atexit`,
238
+ ` atexit.register(YourAppConfig.posthog_client.shutdown)`,
239
+ ``,
240
+ `IMPORTANT: These best practices are MANDATORY. The implementation will fail review if they are not followed.`,
241
+ ];
242
+ return lines;
243
+ },
244
+ },
245
+ ui: {
246
+ successMessage: 'PostHog integration complete',
247
+ estimatedDurationMinutes: 5,
248
+ getOutroChanges: (context) => {
249
+ const packageManagerName = context.packageManager
250
+ ? (0, utils_1.getPackageManagerName)(context.packageManager)
251
+ : 'package manager';
252
+ return [
253
+ `Analyzed your Python project structure`,
254
+ `Installed the PostHog Python package using ${packageManagerName}`,
255
+ `Created PostHog initialization using instance-based API (Posthog class)`,
256
+ `Configured exception autocapture and graceful shutdown`,
257
+ `Added example code for events, feature flags, and error capture (without PII)`,
258
+ ];
259
+ },
260
+ getOutroNextSteps: () => [
261
+ 'Use Posthog() class (not module-level posthog) with enable_exception_autocapture=True',
262
+ 'Call posthog_client.shutdown() on application exit (use atexit.register)',
263
+ 'NEVER send PII in event properties (no emails, names, or user content)',
264
+ 'Use posthog_client.capture() for events and posthog_client.identify() for users',
265
+ 'Visit your PostHog dashboard to see incoming events',
266
+ ],
267
+ },
268
+ };
269
+ //# sourceMappingURL=python-wizard-agent.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"python-wizard-agent.js","sourceRoot":"","sources":["../../../src/python/python-wizard-agent.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAGA,gDAA+C;AAC/C,0DAA2B;AAC3B,4CAA8B;AAC9B,gDAAkC;AAClC,mCAMiB;AAMJ,QAAA,mBAAmB,GAAmC;IACjE,QAAQ,EAAE;QACR,IAAI,EAAE,iBAAiB;QACvB,WAAW,EAAE,uBAAW,CAAC,MAAM;QAC/B,IAAI,EAAE,IAAI;QACV,OAAO,EAAE,2CAA2C;QACpD,aAAa,EAAE,KAAK,EAAE,OAAsB,EAAE,EAAE;YAC9C,MAAM,cAAc,GAAG,MAAM,IAAA,4BAAoB,EAAC,OAAO,CAAC,CAAC;YAC3D,OAAO,EAAE,cAAc,EAAE,CAAC;QAC5B,CAAC;KACF;IAED,SAAS,EAAE;QACT,WAAW,EAAE,QAAQ;QACrB,kBAAkB,EAAE,QAAQ;QAC5B,eAAe,EAAE,KAAK;QACtB,UAAU,EAAE,GAAG,EAAE,CAAC,SAAS;QAC3B,gBAAgB,EAAE,8BAAsB;QACxC,cAAc,EAAE,OAAO;QACvB,mBAAmB,EAAE,CAAC,OAAsB,EAAE,EAAE,CAC9C,OAAO,CAAC,OAAO,CAAC,IAAA,wBAAgB,EAAC,OAAO,CAAC,CAAC;QAC5C,MAAM,EAAE,KAAK,EAAE,OAAO,EAAE,EAAE;YACxB,MAAM,EAAE,UAAU,EAAE,GAAG,OAAO,CAAC;YAE/B,2CAA2C;YAC3C,MAAM,iBAAiB,GAAG,MAAM,IAAA,mBAAE,EAChC;gBACE,sBAAsB;gBACtB,mBAAmB;gBACnB,aAAa;gBACb,YAAY;aACb,EACD;gBACE,GAAG,EAAE,UAAU;gBACf,MAAM,EAAE,CAAC,YAAY,EAAE,aAAa,EAAE,WAAW,EAAE,YAAY,CAAC;aACjE,CACF,CAAC;YAEF,IAAI,iBAAiB,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;gBACnC,OAAO,KAAK,CAAC;YACf,CAAC;YAED,wEAAwE;YACxE,mBAAmB;YACnB,MAAM,eAAe,GAAG,MAAM,IAAA,mBAAE,EAAC,cAAc,EAAE;gBAC/C,GAAG,EAAE,UAAU;gBACf,MAAM,EAAE,CAAC,YAAY,EAAE,aAAa,EAAE,WAAW,EAAE,YAAY,CAAC;aACjE,CAAC,CAAC;YAEH,KAAK,MAAM,KAAK,IAAI,eAAe,EAAE,CAAC;gBACpC,IAAI,CAAC;oBACH,MAAM,OAAO,GAAG,EAAE,CAAC,YAAY,CAC7B,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,KAAK,CAAC,EAC5B,OAAO,CACR,CAAC;oBACF,IACE,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAC;wBAC1B,OAAO,CAAC,QAAQ,CAAC,wBAAwB,CAAC,EAC1C,CAAC;wBACD,OAAO,KAAK,CAAC,CAAC,4CAA4C;oBAC5D,CAAC;gBACH,CAAC;gBAAC,MAAM,CAAC;oBACP,SAAS;gBACX,CAAC;YACH,CAAC;YAED,kBAAkB;YAClB,KAAK,MAAM,UAAU,IAAI,iBAAiB,EAAE,CAAC;gBAC3C,IAAI,CAAC;oBACH,MAAM,OAAO,GAAG,EAAE,CAAC,YAAY,CAC7B,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,UAAU,CAAC,EACjC,OAAO,CACR,CAAC;oBACF,IACE,wBAAwB,CAAC,IAAI,CAAC,OAAO,CAAC;wBACtC,gBAAgB,CAAC,IAAI,CAAC,OAAO,CAAC,EAC9B,CAAC;wBACD,OAAO,KAAK,CAAC,CAAC,0CAA0C;oBAC1D,CAAC;gBACH,CAAC;gBAAC,MAAM,CAAC;oBACP,SAAS;gBACX,CAAC;YACH,CAAC;YAED,MAAM,OAAO,GAAG,MAAM,IAAA,mBAAE,EACtB,CAAC,WAAW,EAAE,YAAY,EAAE,mBAAmB,EAAE,gBAAgB,CAAC,EAClE;gBACE,GAAG,EAAE,UAAU;gBACf,MAAM,EAAE;oBACN,YAAY;oBACZ,aAAa;oBACb,WAAW;oBACX,YAAY;oBACZ,mBAAmB;iBACpB;aACF,CACF,CAAC;YAEF,KAAK,MAAM,MAAM,IAAI,OAAO,EAAE,CAAC;gBAC7B,IAAI,CAAC;oBACH,MAAM,OAAO,GAAG,EAAE,CAAC,YAAY,CAC7B,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,MAAM,CAAC,EAC7B,OAAO,CACR,CAAC;oBACF,IACE,OAAO,CAAC,QAAQ,CAAC,mBAAmB,CAAC;wBACrC,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAC;wBAChC,YAAY,CAAC,IAAI,CAAC,OAAO,CAAC,EAC1B,CAAC;wBACD,OAAO,KAAK,CAAC,CAAC,0CAA0C;oBAC1D,CAAC;gBACH,CAAC;gBAAC,MAAM,CAAC;oBACP,SAAS;gBACX,CAAC;YACH,CAAC;YAED,6FAA6F;YAC7F,OAAO,IAAI,CAAC;QACd,CAAC;KACF;IAED,WAAW,EAAE;QACX,eAAe,EAAE,KAAK;QACtB,UAAU,EAAE,CAAC,MAAc,EAAE,IAAY,EAAE,EAAE,CAAC,CAAC;YAC7C,eAAe,EAAE,MAAM;YACvB,YAAY,EAAE,IAAI;SACnB,CAAC;KACH;IAED,SAAS,EAAE;QACT,OAAO,EAAE,CAAC,OAAO,EAAE,EAAE;YACnB,MAAM,kBAAkB,GAAG,OAAO,CAAC,cAAc;gBAC/C,CAAC,CAAC,IAAA,6BAAqB,EAAC,OAAO,CAAC,cAAc,CAAC;gBAC/C,CAAC,CAAC,SAAS,CAAC;YACd,OAAO;gBACL,cAAc,EAAE,kBAAkB;aACnC,CAAC;QACJ,CAAC;KACF;IAED,OAAO,EAAE;QACP,oBAAoB,EAClB,+GAA+G;QACjH,mBAAmB,EACjB,yLAAyL;QAC3L,yBAAyB,EAAE,CAAC,OAAO,EAAE,EAAE;YACrC,MAAM,kBAAkB,GAAG,OAAO,CAAC,cAAc;gBAC/C,CAAC,CAAC,IAAA,6BAAqB,EAAC,OAAO,CAAC,cAAc,CAAC;gBAC/C,CAAC,CAAC,SAAS,CAAC;YAEd,MAAM,KAAK,GAAG;gBACZ,oBAAoB,kBAAkB,EAAE;gBACxC,oFAAoF;gBACpF,qFAAqF;gBACrF,EAAE;gBACF,4CAA4C;gBAC5C,EAAE;gBACF,0CAA0C;gBAC1C,6EAA6E;gBAC7E,EAAE;gBACF,UAAU;gBACV,6BAA6B;gBAC7B,2BAA2B;gBAC3B,6BAA6B;gBAC7B,sCAAsC;gBACtC,kBAAkB;gBAClB,mEAAmE;gBACnE,GAAG;gBACH,EAAE;gBACF,yBAAyB;gBACzB,gBAAgB;gBAChB,mEAAmE;gBACnE,EAAE;gBACF,qCAAqC;gBACrC,qHAAqH;gBACrH,EAAE;gBACF,6DAA6D;gBAC7D,qCAAqC;gBACrC,mBAAmB;gBACnB,cAAc;gBACd,iBAAiB;gBACjB,sBAAsB;gBACtB,gBAAgB;gBAChB,qEAAqE;gBACrE,EAAE;gBACF,wBAAwB;gBACxB,+DAA+D;gBAC/D,uDAAuD;gBACvD,uDAAuD;gBACvD,iDAAiD;gBACjD,IAAI;gBACJ,EAAE;gBACF,0BAA0B;gBAC1B,uDAAuD;gBACvD,qDAAqD;gBACrD,4DAA4D;gBAC5D,2CAA2C;gBAC3C,IAAI;gBACJ,EAAE;gBACF,oCAAoC;gBACpC,qGAAqG;gBACrG,EAAE;gBACF,eAAe;gBACf,6EAA6E;gBAC7E,EAAE;gBACF,qEAAqE;gBACrE,oDAAoD;gBACpD,gEAAgE;gBAChE,EAAE;gBACF,4BAA4B;gBAC5B,sDAAsD;gBACtD,EAAE;gBACF,mCAAmC;gBACnC,6BAA6B;gBAC7B,EAAE;gBACF,iCAAiC;gBACjC,2BAA2B;gBAC3B,MAAM;gBACN,sBAAsB;gBACtB,kDAAkD;gBAClD,qDAAqD;gBACrD,2CAA2C;gBAC3C,6CAA6C;gBAC7C,uCAAuC;gBACvC,oDAAoD;gBACpD,eAAe;gBACf,2BAA2B;gBAC3B,oEAAoE;gBACpE,EAAE;gBACF,8GAA8G;aAC/G,CAAC;YAEF,OAAO,KAAK,CAAC;QACf,CAAC;KACF;IAED,EAAE,EAAE;QACF,cAAc,EAAE,8BAA8B;QAC9C,wBAAwB,EAAE,CAAC;QAC3B,eAAe,EAAE,CAAC,OAAO,EAAE,EAAE;YAC3B,MAAM,kBAAkB,GAAG,OAAO,CAAC,cAAc;gBAC/C,CAAC,CAAC,IAAA,6BAAqB,EAAC,OAAO,CAAC,cAAc,CAAC;gBAC/C,CAAC,CAAC,iBAAiB,CAAC;YACtB,OAAO;gBACL,wCAAwC;gBACxC,8CAA8C,kBAAkB,EAAE;gBAClE,yEAAyE;gBACzE,wDAAwD;gBACxD,+EAA+E;aAChF,CAAC;QACJ,CAAC;QACD,iBAAiB,EAAE,GAAG,EAAE,CAAC;YACvB,uFAAuF;YACvF,0EAA0E;YAC1E,wEAAwE;YACxE,iFAAiF;YACjF,qDAAqD;SACtD;KACF;CACF,CAAC","sourcesContent":["/* Generic Python language wizard using posthog-agent with PostHog MCP */\nimport type { WizardOptions } from '../utils/types';\nimport type { FrameworkConfig } from '../lib/framework-config';\nimport { Integration } from '../lib/constants';\nimport fg from 'fast-glob';\nimport * as fs from 'node:fs';\nimport * as path from 'node:path';\nimport {\n getPythonVersion,\n getPythonVersionBucket,\n detectPackageManager,\n getPackageManagerName,\n PythonPackageManager,\n} from './utils';\n\ntype PythonContext = {\n packageManager?: PythonPackageManager;\n};\n\nexport const PYTHON_AGENT_CONFIG: FrameworkConfig<PythonContext> = {\n metadata: {\n name: 'Python Language',\n integration: Integration.python,\n beta: true,\n docsUrl: 'https://posthog.com/docs/libraries/python',\n gatherContext: async (options: WizardOptions) => {\n const packageManager = await detectPackageManager(options);\n return { packageManager };\n },\n },\n\n detection: {\n packageName: 'python',\n packageDisplayName: 'Python',\n usesPackageJson: false,\n getVersion: () => undefined,\n getVersionBucket: getPythonVersionBucket,\n minimumVersion: '3.8.0',\n getInstalledVersion: (options: WizardOptions) =>\n Promise.resolve(getPythonVersion(options)),\n detect: async (options) => {\n const { installDir } = options;\n\n // Look for Python package management files\n const pythonConfigFiles = await fg(\n [\n '**/requirements*.txt',\n '**/pyproject.toml',\n '**/setup.py',\n '**/Pipfile',\n ],\n {\n cwd: installDir,\n ignore: ['**/venv/**', '**/.venv/**', '**/env/**', '**/.env/**'],\n },\n );\n\n if (pythonConfigFiles.length === 0) {\n return false;\n }\n\n // Make sure this isn't Django or Flask (those should be detected first)\n // Check for Django\n const managePyMatches = await fg('**/manage.py', {\n cwd: installDir,\n ignore: ['**/venv/**', '**/.venv/**', '**/env/**', '**/.env/**'],\n });\n\n for (const match of managePyMatches) {\n try {\n const content = fs.readFileSync(\n path.join(installDir, match),\n 'utf-8',\n );\n if (\n content.includes('django') ||\n content.includes('DJANGO_SETTINGS_MODULE')\n ) {\n return false; // Django detected, use django agent instead\n }\n } catch {\n continue;\n }\n }\n\n // Check for Flask\n for (const configFile of pythonConfigFiles) {\n try {\n const content = fs.readFileSync(\n path.join(installDir, configFile),\n 'utf-8',\n );\n if (\n /^flask([<>=~!]|$|\\s)/im.test(content) ||\n /[\"']flask[\"']/i.test(content)\n ) {\n return false; // Flask detected, use flask agent instead\n }\n } catch {\n continue;\n }\n }\n\n const pyFiles = await fg(\n ['**/app.py', '**/wsgi.py', '**/application.py', '**/__init__.py'],\n {\n cwd: installDir,\n ignore: [\n '**/venv/**',\n '**/.venv/**',\n '**/env/**',\n '**/.env/**',\n '**/__pycache__/**',\n ],\n },\n );\n\n for (const pyFile of pyFiles) {\n try {\n const content = fs.readFileSync(\n path.join(installDir, pyFile),\n 'utf-8',\n );\n if (\n content.includes('from flask import') ||\n content.includes('import flask') ||\n /Flask\\s*\\(/.test(content)\n ) {\n return false; // Flask detected, use flask agent instead\n }\n } catch {\n continue;\n }\n }\n\n // If we have Python config files but it's not Django or Flask, it's a generic Python project\n return true;\n },\n },\n\n environment: {\n uploadToHosting: false,\n getEnvVars: (apiKey: string, host: string) => ({\n POSTHOG_API_KEY: apiKey,\n POSTHOG_HOST: host,\n }),\n },\n\n analytics: {\n getTags: (context) => {\n const packageManagerName = context.packageManager\n ? getPackageManagerName(context.packageManager)\n : 'unknown';\n return {\n packageManager: packageManagerName,\n };\n },\n },\n\n prompts: {\n projectTypeDetection:\n 'This is a generic Python project. Look for requirements.txt, pyproject.toml, setup.py, or Pipfile to confirm.',\n packageInstallation:\n 'Use pip, poetry, or pipenv based on existing config files (requirements.txt, pyproject.toml, Pipfile). Do not pin the posthog version - just add \"posthog\" without version constraints.',\n getAdditionalContextLines: (context) => {\n const packageManagerName = context.packageManager\n ? getPackageManagerName(context.packageManager)\n : 'unknown';\n\n const lines = [\n `Package manager: ${packageManagerName}`,\n `Framework docs ID: python (use posthog://docs/frameworks/python for documentation)`,\n `Project type: Generic Python application (CLI, script, worker, data pipeline, etc.)`,\n ``,\n `## CRITICAL: Python PostHog Best Practices`,\n ``,\n `### 1. Use Instance-Based API (REQUIRED)`,\n `Always use the Posthog() class constructor instead of module-level posthog:`,\n ``,\n `CORRECT:`,\n `from posthog import Posthog`,\n `posthog_client = Posthog(`,\n ` api_key=\"your_api_key\",`,\n ` host=\"https://us.i.posthog.com\",`,\n ` debug=False,`,\n ` enable_exception_autocapture=True, # Auto-capture exceptions`,\n `)`,\n ``,\n `INCORRECT (DO NOT USE):`,\n `import posthog`,\n `posthog.api_key = \"your_api_key\" # Don't use module-level config`,\n ``,\n `### 2. Enable Exception Autocapture`,\n `ALWAYS include enable_exception_autocapture=True in the Posthog() initialization to automatically track exceptions.`,\n ``,\n `### 3. NEVER Send PII (Personally Identifiable Information)`,\n `DO NOT include in event properties:`,\n `- Email addresses`,\n `- Full names`,\n `- Phone numbers`,\n `- Physical addresses`,\n `- IP addresses`,\n `- Any user-generated content (messages, comments, form submissions)`,\n ``,\n `SAFE event properties:`,\n `posthog_client.capture('contact_form_submitted', properties={`,\n ` 'message_length': len(message), # Metadata is OK`,\n ` 'has_email': bool(email), # Boolean flags are OK`,\n ` 'form_type': 'contact' # Categories are OK`,\n `})`,\n ``,\n `UNSAFE (DO NOT DO THIS):`,\n `posthog_client.capture('form_submitted', properties={`,\n ` 'email': user_email, # NEVER send actual email`,\n ` 'message': message_content, # NEVER send user content`,\n ` 'name': user_name # NEVER send names`,\n `})`,\n ``,\n `### 4. Implement Graceful Shutdown`,\n `ALWAYS call posthog_client.shutdown() when your application exits to ensure all events are flushed:`,\n ``,\n `import atexit`,\n `atexit.register(posthog_client.shutdown) # Ensures events are sent on exit`,\n ``,\n `For Django, use AppConfig.ready() to register the shutdown handler.`,\n `For Flask, use @app.teardown_appcontext or atexit.`,\n `For scripts/workers, call shutdown() explicitly or use atexit.`,\n ``,\n `### 5. For Django Projects`,\n `Initialize PostHog in your AppConfig.ready() method:`,\n ``,\n `from django.apps import AppConfig`,\n `from posthog import Posthog`,\n ``,\n `class YourAppConfig(AppConfig):`,\n ` posthog_client = None`,\n ` `,\n ` def ready(self):`,\n ` if YourAppConfig.posthog_client is None:`,\n ` YourAppConfig.posthog_client = Posthog(`,\n ` settings.POSTHOG_API_KEY,`,\n ` host=settings.POSTHOG_HOST,`,\n ` debug=settings.DEBUG,`,\n ` enable_exception_autocapture=True,`,\n ` )`,\n ` import atexit`,\n ` atexit.register(YourAppConfig.posthog_client.shutdown)`,\n ``,\n `IMPORTANT: These best practices are MANDATORY. The implementation will fail review if they are not followed.`,\n ];\n\n return lines;\n },\n },\n\n ui: {\n successMessage: 'PostHog integration complete',\n estimatedDurationMinutes: 5,\n getOutroChanges: (context) => {\n const packageManagerName = context.packageManager\n ? getPackageManagerName(context.packageManager)\n : 'package manager';\n return [\n `Analyzed your Python project structure`,\n `Installed the PostHog Python package using ${packageManagerName}`,\n `Created PostHog initialization using instance-based API (Posthog class)`,\n `Configured exception autocapture and graceful shutdown`,\n `Added example code for events, feature flags, and error capture (without PII)`,\n ];\n },\n getOutroNextSteps: () => [\n 'Use Posthog() class (not module-level posthog) with enable_exception_autocapture=True',\n 'Call posthog_client.shutdown() on application exit (use atexit.register)',\n 'NEVER send PII in event properties (no emails, names, or user content)',\n 'Use posthog_client.capture() for events and posthog_client.identify() for users',\n 'Visit your PostHog dashboard to see incoming events',\n ],\n },\n};\n"]}
@@ -0,0 +1,28 @@
1
+ import type { WizardOptions } from '../utils/types';
2
+ export declare enum PythonPackageManager {
3
+ UV = "uv",
4
+ POETRY = "poetry",
5
+ PDM = "pdm",
6
+ HATCH = "hatch",
7
+ RYE = "rye",
8
+ PIPENV = "pipenv",
9
+ CONDA = "conda",
10
+ PIP = "pip",
11
+ UNKNOWN = "unknown"
12
+ }
13
+ /**
14
+ * Get the installed Python version
15
+ */
16
+ export declare function getPythonVersion(options: WizardOptions): string | undefined;
17
+ /**
18
+ * Bucket Python version for analytics (e.g., "3.11.x" -> "3.11")
19
+ */
20
+ export declare function getPythonVersionBucket(version: string): string;
21
+ /**
22
+ * Detect which package manager the project uses
23
+ */
24
+ export declare function detectPackageManager(options: WizardOptions): Promise<PythonPackageManager>;
25
+ /**
26
+ * Get package manager display name
27
+ */
28
+ export declare function getPackageManagerName(packageManager: PythonPackageManager): string;
@@ -0,0 +1,147 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.PythonPackageManager = void 0;
4
+ exports.getPythonVersion = getPythonVersion;
5
+ exports.getPythonVersionBucket = getPythonVersionBucket;
6
+ exports.detectPackageManager = detectPackageManager;
7
+ exports.getPackageManagerName = getPackageManagerName;
8
+ const node_child_process_1 = require("node:child_process");
9
+ var PythonPackageManager;
10
+ (function (PythonPackageManager) {
11
+ PythonPackageManager["UV"] = "uv";
12
+ PythonPackageManager["POETRY"] = "poetry";
13
+ PythonPackageManager["PDM"] = "pdm";
14
+ PythonPackageManager["HATCH"] = "hatch";
15
+ PythonPackageManager["RYE"] = "rye";
16
+ PythonPackageManager["PIPENV"] = "pipenv";
17
+ PythonPackageManager["CONDA"] = "conda";
18
+ PythonPackageManager["PIP"] = "pip";
19
+ PythonPackageManager["UNKNOWN"] = "unknown";
20
+ })(PythonPackageManager || (exports.PythonPackageManager = PythonPackageManager = {}));
21
+ /**
22
+ * Get the installed Python version
23
+ */
24
+ function getPythonVersion(options) {
25
+ try {
26
+ const version = (0, node_child_process_1.execSync)('python --version || python3 --version', {
27
+ cwd: options.installDir,
28
+ encoding: 'utf-8',
29
+ })
30
+ .trim()
31
+ .replace('Python ', '');
32
+ return version;
33
+ }
34
+ catch {
35
+ return undefined;
36
+ }
37
+ }
38
+ /**
39
+ * Bucket Python version for analytics (e.g., "3.11.x" -> "3.11")
40
+ */
41
+ function getPythonVersionBucket(version) {
42
+ const match = version.match(/^(\d+\.\d+)/);
43
+ return match ? match[1] : version;
44
+ }
45
+ /**
46
+ * Detect which package manager the project uses
47
+ */
48
+ async function detectPackageManager(options) {
49
+ const { installDir } = options;
50
+ const fs = await import('node:fs');
51
+ const path = await import('node:path');
52
+ // Check for uv (uv.lock)
53
+ if (fs.existsSync(path.join(installDir, 'uv.lock'))) {
54
+ return PythonPackageManager.UV;
55
+ }
56
+ // Check pyproject.toml for various tools
57
+ if (fs.existsSync(path.join(installDir, 'pyproject.toml'))) {
58
+ try {
59
+ const content = fs.readFileSync(path.join(installDir, 'pyproject.toml'), 'utf-8');
60
+ // Check for Poetry
61
+ if (content.includes('[tool.poetry]')) {
62
+ return PythonPackageManager.POETRY;
63
+ }
64
+ // Check for PDM
65
+ if (content.includes('[tool.pdm]')) {
66
+ return PythonPackageManager.PDM;
67
+ }
68
+ // Check for Hatch
69
+ if (content.includes('[tool.hatch]')) {
70
+ return PythonPackageManager.HATCH;
71
+ }
72
+ // Check for Rye
73
+ if (content.includes('[tool.rye]')) {
74
+ return PythonPackageManager.RYE;
75
+ }
76
+ }
77
+ catch {
78
+ // Continue checking
79
+ }
80
+ }
81
+ // Check for Poetry lock file
82
+ if (fs.existsSync(path.join(installDir, 'poetry.lock'))) {
83
+ return PythonPackageManager.POETRY;
84
+ }
85
+ // Check for PDM lock file
86
+ if (fs.existsSync(path.join(installDir, 'pdm.lock'))) {
87
+ return PythonPackageManager.PDM;
88
+ }
89
+ // Check for Pipenv (Pipfile or Pipfile.lock)
90
+ if (fs.existsSync(path.join(installDir, 'Pipfile')) ||
91
+ fs.existsSync(path.join(installDir, 'Pipfile.lock'))) {
92
+ return PythonPackageManager.PIPENV;
93
+ }
94
+ // Check for Conda (environment.yml or environment.yaml)
95
+ if (fs.existsSync(path.join(installDir, 'environment.yml')) ||
96
+ fs.existsSync(path.join(installDir, 'environment.yaml'))) {
97
+ return PythonPackageManager.CONDA;
98
+ }
99
+ // Check for pip (requirements.txt, setup.py, setup.cfg, or pyproject.toml)
100
+ if (fs.existsSync(path.join(installDir, 'requirements.txt')) ||
101
+ fs.existsSync(path.join(installDir, 'setup.py')) ||
102
+ fs.existsSync(path.join(installDir, 'setup.cfg')) ||
103
+ fs.existsSync(path.join(installDir, 'pyproject.toml'))) {
104
+ return PythonPackageManager.PIP;
105
+ }
106
+ // Check for requirements directory
107
+ try {
108
+ const requirementsDir = path.join(installDir, 'requirements');
109
+ if (fs.existsSync(requirementsDir) &&
110
+ fs.statSync(requirementsDir).isDirectory()) {
111
+ const files = fs.readdirSync(requirementsDir);
112
+ if (files.some((f) => f.endsWith('.txt'))) {
113
+ return PythonPackageManager.PIP;
114
+ }
115
+ }
116
+ }
117
+ catch {
118
+ // Continue
119
+ }
120
+ return PythonPackageManager.UNKNOWN;
121
+ }
122
+ /**
123
+ * Get package manager display name
124
+ */
125
+ function getPackageManagerName(packageManager) {
126
+ switch (packageManager) {
127
+ case PythonPackageManager.UV:
128
+ return 'uv';
129
+ case PythonPackageManager.POETRY:
130
+ return 'Poetry';
131
+ case PythonPackageManager.PDM:
132
+ return 'PDM';
133
+ case PythonPackageManager.HATCH:
134
+ return 'Hatch';
135
+ case PythonPackageManager.RYE:
136
+ return 'Rye';
137
+ case PythonPackageManager.PIPENV:
138
+ return 'Pipenv';
139
+ case PythonPackageManager.CONDA:
140
+ return 'Conda';
141
+ case PythonPackageManager.PIP:
142
+ return 'pip';
143
+ case PythonPackageManager.UNKNOWN:
144
+ return 'unknown';
145
+ }
146
+ }
147
+ //# sourceMappingURL=utils.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"utils.js","sourceRoot":"","sources":["../../../src/python/utils.ts"],"names":[],"mappings":"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","sourcesContent":["import { execSync } from 'node:child_process';\nimport type { WizardOptions } from '../utils/types';\n\nexport enum PythonPackageManager {\n UV = 'uv',\n POETRY = 'poetry',\n PDM = 'pdm',\n HATCH = 'hatch',\n RYE = 'rye',\n PIPENV = 'pipenv',\n CONDA = 'conda',\n PIP = 'pip',\n UNKNOWN = 'unknown',\n}\n\n/**\n * Get the installed Python version\n */\nexport function getPythonVersion(options: WizardOptions): string | undefined {\n try {\n const version = execSync('python --version || python3 --version', {\n cwd: options.installDir,\n encoding: 'utf-8',\n })\n .trim()\n .replace('Python ', '');\n return version;\n } catch {\n return undefined;\n }\n}\n\n/**\n * Bucket Python version for analytics (e.g., \"3.11.x\" -> \"3.11\")\n */\nexport function getPythonVersionBucket(version: string): string {\n const match = version.match(/^(\\d+\\.\\d+)/);\n return match ? match[1] : version;\n}\n\n/**\n * Detect which package manager the project uses\n */\nexport async function detectPackageManager(\n options: WizardOptions,\n): Promise<PythonPackageManager> {\n const { installDir } = options;\n const fs = await import('node:fs');\n const path = await import('node:path');\n\n // Check for uv (uv.lock)\n if (fs.existsSync(path.join(installDir, 'uv.lock'))) {\n return PythonPackageManager.UV;\n }\n\n // Check pyproject.toml for various tools\n if (fs.existsSync(path.join(installDir, 'pyproject.toml'))) {\n try {\n const content = fs.readFileSync(\n path.join(installDir, 'pyproject.toml'),\n 'utf-8',\n );\n\n // Check for Poetry\n if (content.includes('[tool.poetry]')) {\n return PythonPackageManager.POETRY;\n }\n\n // Check for PDM\n if (content.includes('[tool.pdm]')) {\n return PythonPackageManager.PDM;\n }\n\n // Check for Hatch\n if (content.includes('[tool.hatch]')) {\n return PythonPackageManager.HATCH;\n }\n\n // Check for Rye\n if (content.includes('[tool.rye]')) {\n return PythonPackageManager.RYE;\n }\n } catch {\n // Continue checking\n }\n }\n\n // Check for Poetry lock file\n if (fs.existsSync(path.join(installDir, 'poetry.lock'))) {\n return PythonPackageManager.POETRY;\n }\n\n // Check for PDM lock file\n if (fs.existsSync(path.join(installDir, 'pdm.lock'))) {\n return PythonPackageManager.PDM;\n }\n\n // Check for Pipenv (Pipfile or Pipfile.lock)\n if (\n fs.existsSync(path.join(installDir, 'Pipfile')) ||\n fs.existsSync(path.join(installDir, 'Pipfile.lock'))\n ) {\n return PythonPackageManager.PIPENV;\n }\n\n // Check for Conda (environment.yml or environment.yaml)\n if (\n fs.existsSync(path.join(installDir, 'environment.yml')) ||\n fs.existsSync(path.join(installDir, 'environment.yaml'))\n ) {\n return PythonPackageManager.CONDA;\n }\n\n // Check for pip (requirements.txt, setup.py, setup.cfg, or pyproject.toml)\n if (\n fs.existsSync(path.join(installDir, 'requirements.txt')) ||\n fs.existsSync(path.join(installDir, 'setup.py')) ||\n fs.existsSync(path.join(installDir, 'setup.cfg')) ||\n fs.existsSync(path.join(installDir, 'pyproject.toml'))\n ) {\n return PythonPackageManager.PIP;\n }\n\n // Check for requirements directory\n try {\n const requirementsDir = path.join(installDir, 'requirements');\n if (\n fs.existsSync(requirementsDir) &&\n fs.statSync(requirementsDir).isDirectory()\n ) {\n const files = fs.readdirSync(requirementsDir);\n if (files.some((f) => f.endsWith('.txt'))) {\n return PythonPackageManager.PIP;\n }\n }\n } catch {\n // Continue\n }\n\n return PythonPackageManager.UNKNOWN;\n}\n\n/**\n * Get package manager display name\n */\nexport function getPackageManagerName(\n packageManager: PythonPackageManager,\n): string {\n switch (packageManager) {\n case PythonPackageManager.UV:\n return 'uv';\n case PythonPackageManager.POETRY:\n return 'Poetry';\n case PythonPackageManager.PDM:\n return 'PDM';\n case PythonPackageManager.HATCH:\n return 'Hatch';\n case PythonPackageManager.RYE:\n return 'Rye';\n case PythonPackageManager.PIPENV:\n return 'Pipenv';\n case PythonPackageManager.CONDA:\n return 'Conda';\n case PythonPackageManager.PIP:\n return 'pip';\n case PythonPackageManager.UNKNOWN:\n return 'unknown';\n }\n}\n"]}
@@ -0,0 +1,7 @@
1
+ import type { FrameworkConfig } from '../lib/framework-config';
2
+ import { ReactNativeVariant } from './utils';
3
+ type ReactNativeContext = {
4
+ variant?: ReactNativeVariant;
5
+ };
6
+ export declare const REACT_NATIVE_AGENT_CONFIG: FrameworkConfig<ReactNativeContext>;
7
+ export {};
@@ -0,0 +1,91 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.REACT_NATIVE_AGENT_CONFIG = void 0;
4
+ const constants_1 = require("../lib/constants");
5
+ const package_json_1 = require("../utils/package-json");
6
+ const clack_utils_1 = require("../utils/clack-utils");
7
+ const utils_1 = require("./utils");
8
+ exports.REACT_NATIVE_AGENT_CONFIG = {
9
+ metadata: {
10
+ name: 'React Native',
11
+ integration: constants_1.Integration.reactNative,
12
+ docsUrl: 'https://posthog.com/docs/libraries/react-native',
13
+ gatherContext: async (options) => {
14
+ const variant = await (0, utils_1.detectReactNativeVariant)(options);
15
+ return { variant };
16
+ },
17
+ },
18
+ detection: {
19
+ packageName: 'react-native',
20
+ packageDisplayName: 'React Native',
21
+ getVersion: (packageJson) => (0, package_json_1.getPackageVersion)('react-native', packageJson),
22
+ getVersionBucket: utils_1.getReactNativeVersionBucket,
23
+ minimumVersion: '0.73.0',
24
+ getInstalledVersion: async (options) => {
25
+ const packageJson = await (0, clack_utils_1.getPackageDotJson)(options);
26
+ return (0, package_json_1.getPackageVersion)('react-native', packageJson);
27
+ },
28
+ detect: async (options) => {
29
+ const packageJson = await (0, clack_utils_1.tryGetPackageJson)(options);
30
+ return packageJson
31
+ ? (0, package_json_1.hasPackageInstalled)('react-native', packageJson)
32
+ : false;
33
+ },
34
+ },
35
+ environment: {
36
+ uploadToHosting: false,
37
+ getEnvVars: (apiKey, host) => ({
38
+ POSTHOG_API_KEY: apiKey,
39
+ POSTHOG_HOST: host,
40
+ }),
41
+ },
42
+ analytics: {
43
+ getTags: (context) => ({
44
+ variant: context.variant === utils_1.ReactNativeVariant.EXPO ? 'expo' : 'react-native',
45
+ }),
46
+ },
47
+ prompts: {
48
+ 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.',
49
+ packageInstallation: 'Look for lockfiles to determine the package manager (npm, yarn, pnpm). Do not manually edit package.json.',
50
+ getAdditionalContextLines: (context) => {
51
+ const isExpo = context.variant === utils_1.ReactNativeVariant.EXPO;
52
+ const frameworkId = 'react-native';
53
+ const lines = [
54
+ `Framework docs ID: ${frameworkId} (use posthog://docs/frameworks/${frameworkId} for documentation)`,
55
+ `Variant: ${isExpo ? 'Expo' : 'React Native'}`,
56
+ ];
57
+ if (isExpo) {
58
+ lines.push('Use `npx expo install` for package installation.', 'Use EXPO_PUBLIC_ prefix for environment variables exposed to the client.');
59
+ }
60
+ else {
61
+ lines.push('This is a React Native project without Expo. Native linking may be required.', 'For iOS, ensure pods are installed after adding PostHog.');
62
+ }
63
+ return lines;
64
+ },
65
+ },
66
+ ui: {
67
+ successMessage: 'PostHog integration complete',
68
+ estimatedDurationMinutes: 10,
69
+ getOutroChanges: (context) => {
70
+ const variant = context.variant ?? utils_1.ReactNativeVariant.REACT_NATIVE;
71
+ const variantName = (0, utils_1.getReactNativeVariantName)(variant);
72
+ return [
73
+ `Analyzed your React Native project structure (${variantName})`,
74
+ `Installed and configured the PostHog React Native SDK`,
75
+ `Integrated PostHog into your application`,
76
+ ];
77
+ },
78
+ getOutroNextSteps: (context) => {
79
+ const isExpo = context.variant === utils_1.ReactNativeVariant.EXPO;
80
+ const steps = [];
81
+ if (!isExpo) {
82
+ steps.push('Run `npx pod-install` to install iOS dependencies');
83
+ }
84
+ steps.push(isExpo
85
+ ? 'Start your development server with `npx expo start` to see PostHog in action'
86
+ : 'Start your development server to see PostHog in action', 'Visit your PostHog dashboard to see incoming events');
87
+ return steps;
88
+ },
89
+ },
90
+ };
91
+ //# sourceMappingURL=react-native-wizard-agent.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"react-native-wizard-agent.js","sourceRoot":"","sources":["../../../src/react-native/react-native-wizard-agent.ts"],"names":[],"mappings":"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","sourcesContent":["/* React Native wizard using posthog-agent with PostHog MCP */\nimport type { WizardOptions } from '../utils/types';\nimport type { FrameworkConfig } from '../lib/framework-config';\nimport { Integration } from '../lib/constants';\nimport {\n getPackageVersion,\n hasPackageInstalled,\n type PackageDotJson,\n} from '../utils/package-json';\nimport { getPackageDotJson, tryGetPackageJson } from '../utils/clack-utils';\nimport {\n detectReactNativeVariant,\n getReactNativeVariantName,\n getReactNativeVersionBucket,\n ReactNativeVariant,\n} from './utils';\n\ntype ReactNativeContext = {\n variant?: ReactNativeVariant;\n};\n\nexport const REACT_NATIVE_AGENT_CONFIG: FrameworkConfig<ReactNativeContext> = {\n metadata: {\n name: 'React Native',\n integration: Integration.reactNative,\n docsUrl: 'https://posthog.com/docs/libraries/react-native',\n gatherContext: async (options: WizardOptions) => {\n const variant = await detectReactNativeVariant(options);\n return { variant };\n },\n },\n\n detection: {\n packageName: 'react-native',\n packageDisplayName: 'React Native',\n getVersion: (packageJson: unknown) =>\n getPackageVersion('react-native', packageJson as PackageDotJson),\n getVersionBucket: getReactNativeVersionBucket,\n minimumVersion: '0.73.0',\n getInstalledVersion: async (options: WizardOptions) => {\n const packageJson = await getPackageDotJson(options);\n return getPackageVersion('react-native', packageJson);\n },\n detect: async (options) => {\n const packageJson = await tryGetPackageJson(options);\n return packageJson\n ? hasPackageInstalled('react-native', packageJson)\n : false;\n },\n },\n\n environment: {\n uploadToHosting: false,\n getEnvVars: (apiKey: string, host: string) => ({\n POSTHOG_API_KEY: apiKey,\n POSTHOG_HOST: host,\n }),\n },\n\n analytics: {\n getTags: (context) => ({\n variant:\n context.variant === ReactNativeVariant.EXPO ? 'expo' : 'react-native',\n }),\n },\n\n prompts: {\n projectTypeDetection:\n 'This is a React Native project. Look for package.json, android/ and ios/ directories, and lockfiles to confirm. Check for expo in package.json to determine the variant.',\n packageInstallation:\n 'Look for lockfiles to determine the package manager (npm, yarn, pnpm). Do not manually edit package.json.',\n getAdditionalContextLines: (context) => {\n const isExpo = context.variant === ReactNativeVariant.EXPO;\n const frameworkId = 'react-native';\n\n const lines = [\n `Framework docs ID: ${frameworkId} (use posthog://docs/frameworks/${frameworkId} for documentation)`,\n `Variant: ${isExpo ? 'Expo' : 'React Native'}`,\n ];\n\n if (isExpo) {\n lines.push(\n 'Use `npx expo install` for package installation.',\n 'Use EXPO_PUBLIC_ prefix for environment variables exposed to the client.',\n );\n } else {\n lines.push(\n 'This is a React Native project without Expo. Native linking may be required.',\n 'For iOS, ensure pods are installed after adding PostHog.',\n );\n }\n\n return lines;\n },\n },\n\n ui: {\n successMessage: 'PostHog integration complete',\n estimatedDurationMinutes: 10,\n getOutroChanges: (context) => {\n const variant = context.variant ?? ReactNativeVariant.REACT_NATIVE;\n const variantName = getReactNativeVariantName(variant);\n return [\n `Analyzed your React Native project structure (${variantName})`,\n `Installed and configured the PostHog React Native SDK`,\n `Integrated PostHog into your application`,\n ];\n },\n getOutroNextSteps: (context) => {\n const isExpo = context.variant === ReactNativeVariant.EXPO;\n const steps = [];\n\n if (!isExpo) {\n steps.push('Run `npx pod-install` to install iOS dependencies');\n }\n\n steps.push(\n isExpo\n ? 'Start your development server with `npx expo start` to see PostHog in action'\n : 'Start your development server to see PostHog in action',\n 'Visit your PostHog dashboard to see incoming events',\n );\n\n return steps;\n },\n },\n};\n"]}
@@ -0,0 +1,8 @@
1
+ import type { WizardOptions } from '../utils/types';
2
+ export declare const getReactNativeVersionBucket: (version: string | undefined) => string;
3
+ export declare enum ReactNativeVariant {
4
+ EXPO = "expo",
5
+ REACT_NATIVE = "react-native"
6
+ }
7
+ export declare function getReactNativeVariantName(variant: ReactNativeVariant): string;
8
+ export declare function detectReactNativeVariant(options: Pick<WizardOptions, 'installDir'>): Promise<ReactNativeVariant>;