@posthog/wizard 1.32.1 → 1.34.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/dist/src/android/android-wizard-agent.js +2 -0
- package/dist/src/android/android-wizard-agent.js.map +1 -1
- package/dist/src/angular/angular-wizard-agent.js +2 -1
- package/dist/src/angular/angular-wizard-agent.js.map +1 -1
- package/dist/src/astro/astro-wizard-agent.js +2 -1
- package/dist/src/astro/astro-wizard-agent.js.map +1 -1
- package/dist/src/django/django-wizard-agent.js +4 -1
- package/dist/src/django/django-wizard-agent.js.map +1 -1
- package/dist/src/fastapi/fastapi-wizard-agent.js +4 -1
- package/dist/src/fastapi/fastapi-wizard-agent.js.map +1 -1
- package/dist/src/flask/flask-wizard-agent.js +4 -1
- package/dist/src/flask/flask-wizard-agent.js.map +1 -1
- package/dist/src/laravel/laravel-wizard-agent.js +2 -0
- package/dist/src/laravel/laravel-wizard-agent.js.map +1 -1
- package/dist/src/lib/__tests__/package-manager-detection.test.d.ts +1 -0
- package/dist/src/lib/__tests__/package-manager-detection.test.js +195 -0
- package/dist/src/lib/__tests__/package-manager-detection.test.js.map +1 -0
- package/dist/src/lib/__tests__/wizard-tools.test.d.ts +1 -0
- package/dist/src/lib/__tests__/wizard-tools.test.js +200 -0
- package/dist/src/lib/__tests__/wizard-tools.test.js.map +1 -0
- package/dist/src/lib/agent-interface.d.ts +2 -0
- package/dist/src/lib/agent-interface.js +12 -9
- package/dist/src/lib/agent-interface.js.map +1 -1
- package/dist/src/lib/agent-runner.js +7 -4
- package/dist/src/lib/agent-runner.js.map +1 -1
- package/dist/src/lib/constants.d.ts +3 -1
- package/dist/src/lib/constants.js +2 -0
- package/dist/src/lib/constants.js.map +1 -1
- package/dist/src/lib/framework-config.d.ts +15 -2
- package/dist/src/lib/framework-config.js +8 -1
- package/dist/src/lib/framework-config.js.map +1 -1
- package/dist/src/lib/package-manager-detection.d.ts +37 -0
- package/dist/src/lib/package-manager-detection.js +183 -0
- package/dist/src/lib/package-manager-detection.js.map +1 -0
- package/dist/src/lib/registry.js +4 -0
- package/dist/src/lib/registry.js.map +1 -1
- package/dist/src/lib/wizard-tools.d.ts +40 -0
- package/dist/src/lib/{env-file-tools.js → wizard-tools.js} +95 -46
- package/dist/src/lib/wizard-tools.js.map +1 -0
- package/dist/src/nextjs/nextjs-wizard-agent.js +2 -1
- package/dist/src/nextjs/nextjs-wizard-agent.js.map +1 -1
- package/dist/src/nuxt/nuxt-wizard-agent.js +2 -1
- package/dist/src/nuxt/nuxt-wizard-agent.js.map +1 -1
- package/dist/src/python/python-wizard-agent.js +4 -1
- package/dist/src/python/python-wizard-agent.js.map +1 -1
- package/dist/src/rails/rails-wizard-agent.d.ts +8 -0
- package/dist/src/rails/rails-wizard-agent.js +90 -0
- package/dist/src/rails/rails-wizard-agent.js.map +1 -0
- package/dist/src/rails/utils.d.ts +37 -0
- package/dist/src/rails/utils.js +187 -0
- package/dist/src/rails/utils.js.map +1 -0
- package/dist/src/react-native/react-native-wizard-agent.js +2 -1
- package/dist/src/react-native/react-native-wizard-agent.js.map +1 -1
- package/dist/src/react-router/react-router-wizard-agent.js +2 -1
- package/dist/src/react-router/react-router-wizard-agent.js.map +1 -1
- package/dist/src/ruby/ruby-wizard-agent.d.ts +7 -0
- package/dist/src/ruby/ruby-wizard-agent.js +113 -0
- package/dist/src/ruby/ruby-wizard-agent.js.map +1 -0
- package/dist/src/ruby/utils.d.ts +25 -0
- package/dist/src/ruby/utils.js +158 -0
- package/dist/src/ruby/utils.js.map +1 -0
- package/dist/src/run.js +13 -3
- package/dist/src/run.js.map +1 -1
- package/dist/src/svelte/svelte-wizard-agent.js +2 -1
- package/dist/src/svelte/svelte-wizard-agent.js.map +1 -1
- package/dist/src/swift/swift-wizard-agent.js +2 -0
- package/dist/src/swift/swift-wizard-agent.js.map +1 -1
- package/dist/src/tanstack-router/tanstack-router-wizard-agent.js +2 -1
- package/dist/src/tanstack-router/tanstack-router-wizard-agent.js.map +1 -1
- package/dist/src/tanstack-start/tanstack-start-wizard-agent.js +2 -1
- package/dist/src/tanstack-start/tanstack-start-wizard-agent.js.map +1 -1
- package/dist/src/vue/vue-wizard-agent.js +2 -1
- package/dist/src/vue/vue-wizard-agent.js.map +1 -1
- package/package.json +1 -1
- package/dist/src/lib/env-file-tools.d.ts +0 -11
- package/dist/src/lib/env-file-tools.js.map +0 -1
|
@@ -37,6 +37,8 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
37
37
|
};
|
|
38
38
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
39
39
|
exports.PYTHON_AGENT_CONFIG = void 0;
|
|
40
|
+
const framework_config_1 = require("../lib/framework-config");
|
|
41
|
+
const package_manager_detection_1 = require("../lib/package-manager-detection");
|
|
40
42
|
const constants_1 = require("../lib/constants");
|
|
41
43
|
const fast_glob_1 = __importDefault(require("fast-glob"));
|
|
42
44
|
const fs = __importStar(require("node:fs"));
|
|
@@ -133,6 +135,7 @@ exports.PYTHON_AGENT_CONFIG = {
|
|
|
133
135
|
// If we have Python config files but it's not Django or Flask, it's a generic Python project
|
|
134
136
|
return true;
|
|
135
137
|
},
|
|
138
|
+
detectPackageManager: package_manager_detection_1.detectPythonPackageManagers,
|
|
136
139
|
},
|
|
137
140
|
environment: {
|
|
138
141
|
uploadToHosting: false,
|
|
@@ -152,8 +155,8 @@ exports.PYTHON_AGENT_CONFIG = {
|
|
|
152
155
|
},
|
|
153
156
|
},
|
|
154
157
|
prompts: {
|
|
158
|
+
packageInstallation: framework_config_1.PYTHON_PACKAGE_INSTALLATION,
|
|
155
159
|
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
160
|
getAdditionalContextLines: (context) => {
|
|
158
161
|
const packageManagerName = context.packageManager
|
|
159
162
|
? (0, utils_1.getPackageManagerName)(context.packageManager)
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"python-wizard-agent.js","sourceRoot":"","sources":["../../../src/python/python-wizard-agent.ts"],"names":[],"mappings":"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","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"]}
|
|
1
|
+
{"version":3,"file":"python-wizard-agent.js","sourceRoot":"","sources":["../../../src/python/python-wizard-agent.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAGA,8DAAsE;AACtE,gFAA+E;AAC/E,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;QACD,oBAAoB,EAAE,uDAA2B;KAClD;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,mBAAmB,EAAE,8CAA2B;QAChD,oBAAoB,EAClB,+GAA+G;QACjH,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 { PYTHON_PACKAGE_INSTALLATION } from '../lib/framework-config';\nimport { detectPythonPackageManagers } from '../lib/package-manager-detection';\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 detectPackageManager: detectPythonPackageManagers,\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 packageInstallation: PYTHON_PACKAGE_INSTALLATION,\n projectTypeDetection:\n 'This is a generic Python project. Look for requirements.txt, pyproject.toml, setup.py, or Pipfile to confirm.',\n getAdditionalContextLines: (context) => {\n const packageManagerName = context.packageManager\n ? getPackageManagerName(context.packageManager)\n : 'unknown';\n\n 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,8 @@
|
|
|
1
|
+
import type { FrameworkConfig } from '../lib/framework-config';
|
|
2
|
+
import { RailsProjectType } from './utils';
|
|
3
|
+
type RailsContext = {
|
|
4
|
+
projectType?: RailsProjectType;
|
|
5
|
+
initializersDir?: string;
|
|
6
|
+
};
|
|
7
|
+
export declare const RAILS_AGENT_CONFIG: FrameworkConfig<RailsContext>;
|
|
8
|
+
export {};
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.RAILS_AGENT_CONFIG = void 0;
|
|
4
|
+
const package_manager_detection_1 = require("../lib/package-manager-detection");
|
|
5
|
+
const constants_1 = require("../lib/constants");
|
|
6
|
+
const utils_1 = require("./utils");
|
|
7
|
+
exports.RAILS_AGENT_CONFIG = {
|
|
8
|
+
metadata: {
|
|
9
|
+
name: 'Ruby on Rails',
|
|
10
|
+
integration: constants_1.Integration.rails,
|
|
11
|
+
beta: true,
|
|
12
|
+
docsUrl: 'https://posthog.com/docs/libraries/ruby-on-rails',
|
|
13
|
+
unsupportedVersionDocsUrl: 'https://posthog.com/docs/libraries/ruby',
|
|
14
|
+
gatherContext: (options) => {
|
|
15
|
+
const projectType = (0, utils_1.getRailsProjectType)(options);
|
|
16
|
+
const initializersDir = (0, utils_1.findInitializersDir)(options);
|
|
17
|
+
return Promise.resolve({ projectType, initializersDir });
|
|
18
|
+
},
|
|
19
|
+
},
|
|
20
|
+
detection: {
|
|
21
|
+
packageName: 'rails',
|
|
22
|
+
packageDisplayName: 'Ruby on Rails',
|
|
23
|
+
usesPackageJson: false,
|
|
24
|
+
getVersion: () => undefined,
|
|
25
|
+
getVersionBucket: utils_1.getRailsVersionBucket,
|
|
26
|
+
minimumVersion: '6.0.0',
|
|
27
|
+
getInstalledVersion: (options) => Promise.resolve((0, utils_1.getRailsVersion)(options)),
|
|
28
|
+
detect: async (options) => (0, utils_1.isRailsProject)(options),
|
|
29
|
+
detectPackageManager: package_manager_detection_1.bundlerPackageManager,
|
|
30
|
+
},
|
|
31
|
+
environment: {
|
|
32
|
+
uploadToHosting: false,
|
|
33
|
+
getEnvVars: (apiKey, host) => ({
|
|
34
|
+
POSTHOG_API_KEY: apiKey,
|
|
35
|
+
POSTHOG_HOST: host,
|
|
36
|
+
}),
|
|
37
|
+
},
|
|
38
|
+
analytics: {
|
|
39
|
+
getTags: (context) => ({
|
|
40
|
+
projectType: context.projectType || 'unknown',
|
|
41
|
+
}),
|
|
42
|
+
},
|
|
43
|
+
prompts: {
|
|
44
|
+
projectTypeDetection: 'This is a Ruby on Rails project. Look for Gemfile, config/application.rb, bin/rails, and config/routes.rb to confirm.',
|
|
45
|
+
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.",
|
|
46
|
+
getAdditionalContextLines: (context) => {
|
|
47
|
+
const projectTypeName = context.projectType
|
|
48
|
+
? (0, utils_1.getRailsProjectTypeName)(context.projectType)
|
|
49
|
+
: 'unknown';
|
|
50
|
+
const lines = [
|
|
51
|
+
`Project type: ${projectTypeName}`,
|
|
52
|
+
`Framework docs ID: ruby-on-rails (use posthog://docs/frameworks/ruby-on-rails for documentation)`,
|
|
53
|
+
];
|
|
54
|
+
if (context.initializersDir) {
|
|
55
|
+
lines.push(`Initializers directory: ${context.initializersDir}`);
|
|
56
|
+
}
|
|
57
|
+
if (context.projectType === utils_1.RailsProjectType.API) {
|
|
58
|
+
lines.push('Note: This is an API-only Rails app — skip frontend posthog-js integration');
|
|
59
|
+
}
|
|
60
|
+
return lines;
|
|
61
|
+
},
|
|
62
|
+
},
|
|
63
|
+
ui: {
|
|
64
|
+
successMessage: 'PostHog integration complete',
|
|
65
|
+
estimatedDurationMinutes: 5,
|
|
66
|
+
getOutroChanges: (context) => {
|
|
67
|
+
const projectTypeName = context.projectType
|
|
68
|
+
? (0, utils_1.getRailsProjectTypeName)(context.projectType)
|
|
69
|
+
: 'Rails';
|
|
70
|
+
const changes = [
|
|
71
|
+
`Analyzed your ${projectTypeName} project structure`,
|
|
72
|
+
`Installed the posthog-ruby and posthog-rails gems via Bundler`,
|
|
73
|
+
`Created PostHog initializer in config/initializers/posthog.rb`,
|
|
74
|
+
`Configured automatic exception capture and ActiveJob instrumentation`,
|
|
75
|
+
];
|
|
76
|
+
if (context.projectType !== utils_1.RailsProjectType.API) {
|
|
77
|
+
changes.push('Added posthog-js snippet to the layout template for frontend tracking');
|
|
78
|
+
}
|
|
79
|
+
return changes;
|
|
80
|
+
},
|
|
81
|
+
getOutroNextSteps: () => [
|
|
82
|
+
'Start your Rails development server with `bin/rails server`',
|
|
83
|
+
'Visit your PostHog dashboard to see incoming events',
|
|
84
|
+
'Use PostHog.capture() to track custom events',
|
|
85
|
+
'Use PostHog.identify() to associate events with users',
|
|
86
|
+
'Define posthog_distinct_id on your User model for automatic user association',
|
|
87
|
+
],
|
|
88
|
+
},
|
|
89
|
+
};
|
|
90
|
+
//# sourceMappingURL=rails-wizard-agent.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"rails-wizard-agent.js","sourceRoot":"","sources":["../../../src/rails/rails-wizard-agent.ts"],"names":[],"mappings":"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","sourcesContent":["/* Ruby on Rails wizard using posthog-agent with PostHog MCP */\nimport type { WizardOptions } from '../utils/types';\nimport type { FrameworkConfig } from '../lib/framework-config';\nimport { bundlerPackageManager } from '../lib/package-manager-detection';\nimport { Integration } from '../lib/constants';\nimport {\n getRailsVersion,\n getRailsProjectType,\n getRailsProjectTypeName,\n getRailsVersionBucket,\n RailsProjectType,\n findInitializersDir,\n isRailsProject,\n} from './utils';\n\ntype RailsContext = {\n projectType?: RailsProjectType;\n initializersDir?: string;\n};\n\nexport const RAILS_AGENT_CONFIG: FrameworkConfig<RailsContext> = {\n metadata: {\n name: 'Ruby on Rails',\n integration: Integration.rails,\n beta: true,\n docsUrl: 'https://posthog.com/docs/libraries/ruby-on-rails',\n unsupportedVersionDocsUrl: 'https://posthog.com/docs/libraries/ruby',\n gatherContext: (options: WizardOptions) => {\n const projectType = getRailsProjectType(options);\n const initializersDir = findInitializersDir(options);\n return Promise.resolve({ projectType, initializersDir });\n },\n },\n\n detection: {\n packageName: 'rails',\n packageDisplayName: 'Ruby on Rails',\n usesPackageJson: false,\n getVersion: () => undefined,\n getVersionBucket: getRailsVersionBucket,\n minimumVersion: '6.0.0',\n getInstalledVersion: (options: WizardOptions) =>\n Promise.resolve(getRailsVersion(options)),\n detect: async (options) => isRailsProject(options),\n detectPackageManager: bundlerPackageManager,\n },\n\n environment: {\n uploadToHosting: false,\n getEnvVars: (apiKey: string, host: string) => ({\n POSTHOG_API_KEY: apiKey,\n POSTHOG_HOST: host,\n }),\n },\n\n analytics: {\n getTags: (context) => ({\n projectType: context.projectType || 'unknown',\n }),\n },\n\n prompts: {\n projectTypeDetection:\n 'This is a Ruby on Rails project. Look for Gemfile, config/application.rb, bin/rails, and config/routes.rb to confirm.',\n packageInstallation:\n \"Use Bundler to install gems. Add `gem 'posthog-ruby'` and `gem 'posthog-rails'` to the Gemfile and run `bundle install`. Do not pin specific versions.\",\n getAdditionalContextLines: (context) => {\n const projectTypeName = context.projectType\n ? getRailsProjectTypeName(context.projectType)\n : 'unknown';\n\n const lines = [\n `Project type: ${projectTypeName}`,\n `Framework docs ID: ruby-on-rails (use posthog://docs/frameworks/ruby-on-rails for documentation)`,\n ];\n\n if (context.initializersDir) {\n lines.push(`Initializers directory: ${context.initializersDir}`);\n }\n\n if (context.projectType === RailsProjectType.API) {\n lines.push(\n 'Note: This is an API-only Rails app — skip frontend posthog-js integration',\n );\n }\n\n return lines;\n },\n },\n\n ui: {\n successMessage: 'PostHog integration complete',\n estimatedDurationMinutes: 5,\n getOutroChanges: (context) => {\n const projectTypeName = context.projectType\n ? getRailsProjectTypeName(context.projectType)\n : 'Rails';\n\n const changes = [\n `Analyzed your ${projectTypeName} project structure`,\n `Installed the posthog-ruby and posthog-rails gems via Bundler`,\n `Created PostHog initializer in config/initializers/posthog.rb`,\n `Configured automatic exception capture and ActiveJob instrumentation`,\n ];\n\n if (context.projectType !== RailsProjectType.API) {\n changes.push(\n 'Added posthog-js snippet to the layout template for frontend tracking',\n );\n }\n\n return changes;\n },\n getOutroNextSteps: () => [\n 'Start your Rails development server with `bin/rails server`',\n 'Visit your PostHog dashboard to see incoming events',\n 'Use PostHog.capture() to track custom events',\n 'Use PostHog.identify() to associate events with users',\n 'Define posthog_distinct_id on your User model for automatic user association',\n ],\n },\n};\n"]}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import type { WizardOptions } from '../utils/types';
|
|
2
|
+
export declare enum RailsProjectType {
|
|
3
|
+
STANDARD = "standard",// Traditional Rails app (rails new)
|
|
4
|
+
API = "api"
|
|
5
|
+
}
|
|
6
|
+
/**
|
|
7
|
+
* Get Rails version bucket for analytics
|
|
8
|
+
*/
|
|
9
|
+
export declare const getRailsVersionBucket: (version: string | undefined) => string;
|
|
10
|
+
/**
|
|
11
|
+
* Check if a gem is present in the Gemfile
|
|
12
|
+
*/
|
|
13
|
+
export declare function hasGem(gemName: string, options: Pick<WizardOptions, 'installDir'>): boolean;
|
|
14
|
+
/**
|
|
15
|
+
* Extract version for a gem from Gemfile
|
|
16
|
+
*/
|
|
17
|
+
export declare function getGemVersion(gemName: string, options: Pick<WizardOptions, 'installDir'>): string | undefined;
|
|
18
|
+
/**
|
|
19
|
+
* Get Rails version from Gemfile
|
|
20
|
+
*/
|
|
21
|
+
export declare function getRailsVersion(options: Pick<WizardOptions, 'installDir'>): string | undefined;
|
|
22
|
+
/**
|
|
23
|
+
* Detect Rails project type
|
|
24
|
+
*/
|
|
25
|
+
export declare function getRailsProjectType(options: WizardOptions): RailsProjectType;
|
|
26
|
+
/**
|
|
27
|
+
* Get human-readable name for Rails project type
|
|
28
|
+
*/
|
|
29
|
+
export declare function getRailsProjectTypeName(projectType: RailsProjectType): string;
|
|
30
|
+
/**
|
|
31
|
+
* Find the Rails initializers directory
|
|
32
|
+
*/
|
|
33
|
+
export declare function findInitializersDir(options: Pick<WizardOptions, 'installDir'>): string | undefined;
|
|
34
|
+
/**
|
|
35
|
+
* Detect if the project is a Rails project by looking for typical Rails files
|
|
36
|
+
*/
|
|
37
|
+
export declare function isRailsProject(options: Pick<WizardOptions, 'installDir'>): Promise<boolean>;
|
|
@@ -0,0 +1,187 @@
|
|
|
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.getRailsVersionBucket = exports.RailsProjectType = void 0;
|
|
40
|
+
exports.hasGem = hasGem;
|
|
41
|
+
exports.getGemVersion = getGemVersion;
|
|
42
|
+
exports.getRailsVersion = getRailsVersion;
|
|
43
|
+
exports.getRailsProjectType = getRailsProjectType;
|
|
44
|
+
exports.getRailsProjectTypeName = getRailsProjectTypeName;
|
|
45
|
+
exports.findInitializersDir = findInitializersDir;
|
|
46
|
+
exports.isRailsProject = isRailsProject;
|
|
47
|
+
const fast_glob_1 = __importDefault(require("fast-glob"));
|
|
48
|
+
const clack_1 = __importDefault(require("../utils/clack"));
|
|
49
|
+
const semver_1 = require("../utils/semver");
|
|
50
|
+
const fs = __importStar(require("node:fs"));
|
|
51
|
+
const path = __importStar(require("node:path"));
|
|
52
|
+
var RailsProjectType;
|
|
53
|
+
(function (RailsProjectType) {
|
|
54
|
+
RailsProjectType["STANDARD"] = "standard";
|
|
55
|
+
RailsProjectType["API"] = "api";
|
|
56
|
+
})(RailsProjectType || (exports.RailsProjectType = RailsProjectType = {}));
|
|
57
|
+
const IGNORE_PATTERNS = [
|
|
58
|
+
'**/node_modules/**',
|
|
59
|
+
'**/vendor/**',
|
|
60
|
+
'**/vendor/bundle/**',
|
|
61
|
+
'**/tmp/**',
|
|
62
|
+
'**/log/**',
|
|
63
|
+
'**/storage/**',
|
|
64
|
+
];
|
|
65
|
+
/**
|
|
66
|
+
* Get Rails version bucket for analytics
|
|
67
|
+
*/
|
|
68
|
+
exports.getRailsVersionBucket = (0, semver_1.createVersionBucket)();
|
|
69
|
+
/**
|
|
70
|
+
* Read and parse Gemfile contents
|
|
71
|
+
*/
|
|
72
|
+
function readGemfile(options) {
|
|
73
|
+
const { installDir } = options;
|
|
74
|
+
const gemfilePath = path.join(installDir, 'Gemfile');
|
|
75
|
+
try {
|
|
76
|
+
return fs.readFileSync(gemfilePath, 'utf-8');
|
|
77
|
+
}
|
|
78
|
+
catch {
|
|
79
|
+
return undefined;
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
/**
|
|
83
|
+
* Check if a gem is present in the Gemfile
|
|
84
|
+
*/
|
|
85
|
+
function hasGem(gemName, options) {
|
|
86
|
+
const content = readGemfile(options);
|
|
87
|
+
if (!content)
|
|
88
|
+
return false;
|
|
89
|
+
// Match gem declarations like: gem 'rails', gem "rails", gem 'rails', '~> 7.0'
|
|
90
|
+
const gemPattern = new RegExp(`^\\s*gem\\s+['"]${gemName}['"]`, 'im');
|
|
91
|
+
return gemPattern.test(content);
|
|
92
|
+
}
|
|
93
|
+
/**
|
|
94
|
+
* Extract version for a gem from Gemfile
|
|
95
|
+
*/
|
|
96
|
+
function getGemVersion(gemName, options) {
|
|
97
|
+
const content = readGemfile(options);
|
|
98
|
+
if (!content)
|
|
99
|
+
return undefined;
|
|
100
|
+
const versionPattern = new RegExp(`^\\s*gem\\s+['"]${gemName}['"]\\s*,\\s*['"][^0-9]*([0-9]+\\.[0-9]+(?:\\.[0-9]+)?)['"]`, 'im');
|
|
101
|
+
const match = content.match(versionPattern);
|
|
102
|
+
return match?.[1];
|
|
103
|
+
}
|
|
104
|
+
/**
|
|
105
|
+
* Get Rails version from Gemfile
|
|
106
|
+
*/
|
|
107
|
+
function getRailsVersion(options) {
|
|
108
|
+
return getGemVersion('rails', options);
|
|
109
|
+
}
|
|
110
|
+
/**
|
|
111
|
+
* Detect Rails project type
|
|
112
|
+
*/
|
|
113
|
+
function getRailsProjectType(options) {
|
|
114
|
+
const { installDir } = options;
|
|
115
|
+
// Check for API-only mode in config/application.rb
|
|
116
|
+
const appConfigPath = path.join(installDir, 'config/application.rb');
|
|
117
|
+
if (fs.existsSync(appConfigPath)) {
|
|
118
|
+
try {
|
|
119
|
+
const content = fs.readFileSync(appConfigPath, 'utf-8');
|
|
120
|
+
if (content.includes('config.api_only = true')) {
|
|
121
|
+
clack_1.default.log.info('Detected Rails API-only project');
|
|
122
|
+
return RailsProjectType.API;
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
catch {
|
|
126
|
+
// Continue to default
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
clack_1.default.log.info('Detected standard Rails project');
|
|
130
|
+
return RailsProjectType.STANDARD;
|
|
131
|
+
}
|
|
132
|
+
/**
|
|
133
|
+
* Get human-readable name for Rails project type
|
|
134
|
+
*/
|
|
135
|
+
function getRailsProjectTypeName(projectType) {
|
|
136
|
+
switch (projectType) {
|
|
137
|
+
case RailsProjectType.STANDARD:
|
|
138
|
+
return 'Standard Rails';
|
|
139
|
+
case RailsProjectType.API:
|
|
140
|
+
return 'Rails API';
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
/**
|
|
144
|
+
* Find the Rails initializers directory
|
|
145
|
+
*/
|
|
146
|
+
function findInitializersDir(options) {
|
|
147
|
+
const { installDir } = options;
|
|
148
|
+
const initializersDir = path.join(installDir, 'config/initializers');
|
|
149
|
+
if (fs.existsSync(initializersDir)) {
|
|
150
|
+
return 'config/initializers';
|
|
151
|
+
}
|
|
152
|
+
return undefined;
|
|
153
|
+
}
|
|
154
|
+
/**
|
|
155
|
+
* Detect if the project is a Rails project by looking for typical Rails files
|
|
156
|
+
*/
|
|
157
|
+
async function isRailsProject(options) {
|
|
158
|
+
const { installDir } = options;
|
|
159
|
+
// Check for bin/rails
|
|
160
|
+
const binRailsPath = path.join(installDir, 'bin/rails');
|
|
161
|
+
if (fs.existsSync(binRailsPath)) {
|
|
162
|
+
return true;
|
|
163
|
+
}
|
|
164
|
+
// Check for config/application.rb with Rails reference
|
|
165
|
+
const appConfigPath = path.join(installDir, 'config/application.rb');
|
|
166
|
+
if (fs.existsSync(appConfigPath)) {
|
|
167
|
+
try {
|
|
168
|
+
const content = fs.readFileSync(appConfigPath, 'utf-8');
|
|
169
|
+
if (content.includes('Rails::Application') ||
|
|
170
|
+
content.includes('require "rails"') ||
|
|
171
|
+
content.includes("require 'rails'")) {
|
|
172
|
+
return true;
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
catch {
|
|
176
|
+
// Continue to other checks
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
// Check Gemfile for rails gem
|
|
180
|
+
if (hasGem('rails', options)) {
|
|
181
|
+
return true;
|
|
182
|
+
}
|
|
183
|
+
// Check for typical Rails directory structure
|
|
184
|
+
const railsStructureFiles = await (0, fast_glob_1.default)(['config/routes.rb', 'config/environment.rb'], { cwd: installDir, ignore: IGNORE_PATTERNS });
|
|
185
|
+
return railsStructureFiles.length >= 2;
|
|
186
|
+
}
|
|
187
|
+
//# sourceMappingURL=utils.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"utils.js","sourceRoot":"","sources":["../../../src/rails/utils.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA6CA,wBAUC;AAKD,sCAaC;AAKD,0CAIC;AAKD,kDAmBC;AAKD,0DAOC;AAKD,kDAWC;AAKD,wCAwCC;AAnLD,0DAA2B;AAC3B,2DAAmC;AAEnC,4CAAsD;AACtD,4CAA8B;AAC9B,gDAAkC;AAElC,IAAY,gBAGX;AAHD,WAAY,gBAAgB;IAC1B,yCAAqB,CAAA;IACrB,+BAAW,CAAA;AACb,CAAC,EAHW,gBAAgB,gCAAhB,gBAAgB,QAG3B;AAED,MAAM,eAAe,GAAG;IACtB,oBAAoB;IACpB,cAAc;IACd,qBAAqB;IACrB,WAAW;IACX,WAAW;IACX,eAAe;CAChB,CAAC;AAEF;;GAEG;AACU,QAAA,qBAAqB,GAAG,IAAA,4BAAmB,GAAE,CAAC;AAE3D;;GAEG;AACH,SAAS,WAAW,CAClB,OAA0C;IAE1C,MAAM,EAAE,UAAU,EAAE,GAAG,OAAO,CAAC;IAE/B,MAAM,WAAW,GAAG,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,SAAS,CAAC,CAAC;IACrD,IAAI,CAAC;QACH,OAAO,EAAE,CAAC,YAAY,CAAC,WAAW,EAAE,OAAO,CAAC,CAAC;IAC/C,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,SAAS,CAAC;IACnB,CAAC;AACH,CAAC;AAED;;GAEG;AACH,SAAgB,MAAM,CACpB,OAAe,EACf,OAA0C;IAE1C,MAAM,OAAO,GAAG,WAAW,CAAC,OAAO,CAAC,CAAC;IACrC,IAAI,CAAC,OAAO;QAAE,OAAO,KAAK,CAAC;IAE3B,+EAA+E;IAC/E,MAAM,UAAU,GAAG,IAAI,MAAM,CAAC,mBAAmB,OAAO,MAAM,EAAE,IAAI,CAAC,CAAC;IACtE,OAAO,UAAU,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;AAClC,CAAC;AAED;;GAEG;AACH,SAAgB,aAAa,CAC3B,OAAe,EACf,OAA0C;IAE1C,MAAM,OAAO,GAAG,WAAW,CAAC,OAAO,CAAC,CAAC;IACrC,IAAI,CAAC,OAAO;QAAE,OAAO,SAAS,CAAC;IAE/B,MAAM,cAAc,GAAG,IAAI,MAAM,CAC/B,mBAAmB,OAAO,6DAA6D,EACvF,IAAI,CACL,CAAC;IACF,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC,cAAc,CAAC,CAAC;IAC5C,OAAO,KAAK,EAAE,CAAC,CAAC,CAAC,CAAC;AACpB,CAAC;AAED;;GAEG;AACH,SAAgB,eAAe,CAC7B,OAA0C;IAE1C,OAAO,aAAa,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;AACzC,CAAC;AAED;;GAEG;AACH,SAAgB,mBAAmB,CAAC,OAAsB;IACxD,MAAM,EAAE,UAAU,EAAE,GAAG,OAAO,CAAC;IAE/B,mDAAmD;IACnD,MAAM,aAAa,GAAG,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,uBAAuB,CAAC,CAAC;IACrE,IAAI,EAAE,CAAC,UAAU,CAAC,aAAa,CAAC,EAAE,CAAC;QACjC,IAAI,CAAC;YACH,MAAM,OAAO,GAAG,EAAE,CAAC,YAAY,CAAC,aAAa,EAAE,OAAO,CAAC,CAAC;YACxD,IAAI,OAAO,CAAC,QAAQ,CAAC,wBAAwB,CAAC,EAAE,CAAC;gBAC/C,eAAK,CAAC,GAAG,CAAC,IAAI,CAAC,iCAAiC,CAAC,CAAC;gBAClD,OAAO,gBAAgB,CAAC,GAAG,CAAC;YAC9B,CAAC;QACH,CAAC;QAAC,MAAM,CAAC;YACP,sBAAsB;QACxB,CAAC;IACH,CAAC;IAED,eAAK,CAAC,GAAG,CAAC,IAAI,CAAC,iCAAiC,CAAC,CAAC;IAClD,OAAO,gBAAgB,CAAC,QAAQ,CAAC;AACnC,CAAC;AAED;;GAEG;AACH,SAAgB,uBAAuB,CAAC,WAA6B;IACnE,QAAQ,WAAW,EAAE,CAAC;QACpB,KAAK,gBAAgB,CAAC,QAAQ;YAC5B,OAAO,gBAAgB,CAAC;QAC1B,KAAK,gBAAgB,CAAC,GAAG;YACvB,OAAO,WAAW,CAAC;IACvB,CAAC;AACH,CAAC;AAED;;GAEG;AACH,SAAgB,mBAAmB,CACjC,OAA0C;IAE1C,MAAM,EAAE,UAAU,EAAE,GAAG,OAAO,CAAC;IAE/B,MAAM,eAAe,GAAG,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,qBAAqB,CAAC,CAAC;IACrE,IAAI,EAAE,CAAC,UAAU,CAAC,eAAe,CAAC,EAAE,CAAC;QACnC,OAAO,qBAAqB,CAAC;IAC/B,CAAC;IAED,OAAO,SAAS,CAAC;AACnB,CAAC;AAED;;GAEG;AACI,KAAK,UAAU,cAAc,CAClC,OAA0C;IAE1C,MAAM,EAAE,UAAU,EAAE,GAAG,OAAO,CAAC;IAE/B,sBAAsB;IACtB,MAAM,YAAY,GAAG,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,WAAW,CAAC,CAAC;IACxD,IAAI,EAAE,CAAC,UAAU,CAAC,YAAY,CAAC,EAAE,CAAC;QAChC,OAAO,IAAI,CAAC;IACd,CAAC;IAED,uDAAuD;IACvD,MAAM,aAAa,GAAG,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,uBAAuB,CAAC,CAAC;IACrE,IAAI,EAAE,CAAC,UAAU,CAAC,aAAa,CAAC,EAAE,CAAC;QACjC,IAAI,CAAC;YACH,MAAM,OAAO,GAAG,EAAE,CAAC,YAAY,CAAC,aAAa,EAAE,OAAO,CAAC,CAAC;YACxD,IACE,OAAO,CAAC,QAAQ,CAAC,oBAAoB,CAAC;gBACtC,OAAO,CAAC,QAAQ,CAAC,iBAAiB,CAAC;gBACnC,OAAO,CAAC,QAAQ,CAAC,iBAAiB,CAAC,EACnC,CAAC;gBACD,OAAO,IAAI,CAAC;YACd,CAAC;QACH,CAAC;QAAC,MAAM,CAAC;YACP,2BAA2B;QAC7B,CAAC;IACH,CAAC;IAED,8BAA8B;IAC9B,IAAI,MAAM,CAAC,OAAO,EAAE,OAAO,CAAC,EAAE,CAAC;QAC7B,OAAO,IAAI,CAAC;IACd,CAAC;IAED,8CAA8C;IAC9C,MAAM,mBAAmB,GAAG,MAAM,IAAA,mBAAE,EAClC,CAAC,kBAAkB,EAAE,uBAAuB,CAAC,EAC7C,EAAE,GAAG,EAAE,UAAU,EAAE,MAAM,EAAE,eAAe,EAAE,CAC7C,CAAC;IAEF,OAAO,mBAAmB,CAAC,MAAM,IAAI,CAAC,CAAC;AACzC,CAAC","sourcesContent":["import fg from 'fast-glob';\nimport clack from '../utils/clack';\nimport type { WizardOptions } from '../utils/types';\nimport { createVersionBucket } from '../utils/semver';\nimport * as fs from 'node:fs';\nimport * as path from 'node:path';\n\nexport enum RailsProjectType {\n STANDARD = 'standard', // Traditional Rails app (rails new)\n API = 'api', // Rails API-only (rails new --api)\n}\n\nconst IGNORE_PATTERNS = [\n '**/node_modules/**',\n '**/vendor/**',\n '**/vendor/bundle/**',\n '**/tmp/**',\n '**/log/**',\n '**/storage/**',\n];\n\n/**\n * Get Rails version bucket for analytics\n */\nexport const getRailsVersionBucket = createVersionBucket();\n\n/**\n * Read and parse Gemfile contents\n */\nfunction readGemfile(\n options: Pick<WizardOptions, 'installDir'>,\n): string | undefined {\n const { installDir } = options;\n\n const gemfilePath = path.join(installDir, 'Gemfile');\n try {\n return fs.readFileSync(gemfilePath, 'utf-8');\n } catch {\n return undefined;\n }\n}\n\n/**\n * Check if a gem is present in the Gemfile\n */\nexport function hasGem(\n gemName: string,\n options: Pick<WizardOptions, 'installDir'>,\n): boolean {\n const content = readGemfile(options);\n if (!content) return false;\n\n // Match gem declarations like: gem 'rails', gem \"rails\", gem 'rails', '~> 7.0'\n const gemPattern = new RegExp(`^\\\\s*gem\\\\s+['\"]${gemName}['\"]`, 'im');\n return gemPattern.test(content);\n}\n\n/**\n * Extract version for a gem from Gemfile\n */\nexport function getGemVersion(\n gemName: string,\n options: Pick<WizardOptions, 'installDir'>,\n): string | undefined {\n const content = readGemfile(options);\n if (!content) return undefined;\n\n const versionPattern = new RegExp(\n `^\\\\s*gem\\\\s+['\"]${gemName}['\"]\\\\s*,\\\\s*['\"][^0-9]*([0-9]+\\\\.[0-9]+(?:\\\\.[0-9]+)?)['\"]`,\n 'im',\n );\n const match = content.match(versionPattern);\n return match?.[1];\n}\n\n/**\n * Get Rails version from Gemfile\n */\nexport function getRailsVersion(\n options: Pick<WizardOptions, 'installDir'>,\n): string | undefined {\n return getGemVersion('rails', options);\n}\n\n/**\n * Detect Rails project type\n */\nexport function getRailsProjectType(options: WizardOptions): RailsProjectType {\n const { installDir } = options;\n\n // Check for API-only mode in config/application.rb\n const appConfigPath = path.join(installDir, 'config/application.rb');\n if (fs.existsSync(appConfigPath)) {\n try {\n const content = fs.readFileSync(appConfigPath, 'utf-8');\n if (content.includes('config.api_only = true')) {\n clack.log.info('Detected Rails API-only project');\n return RailsProjectType.API;\n }\n } catch {\n // Continue to default\n }\n }\n\n clack.log.info('Detected standard Rails project');\n return RailsProjectType.STANDARD;\n}\n\n/**\n * Get human-readable name for Rails project type\n */\nexport function getRailsProjectTypeName(projectType: RailsProjectType): string {\n switch (projectType) {\n case RailsProjectType.STANDARD:\n return 'Standard Rails';\n case RailsProjectType.API:\n return 'Rails API';\n }\n}\n\n/**\n * Find the Rails initializers directory\n */\nexport function findInitializersDir(\n options: Pick<WizardOptions, 'installDir'>,\n): string | undefined {\n const { installDir } = options;\n\n const initializersDir = path.join(installDir, 'config/initializers');\n if (fs.existsSync(initializersDir)) {\n return 'config/initializers';\n }\n\n return undefined;\n}\n\n/**\n * Detect if the project is a Rails project by looking for typical Rails files\n */\nexport async function isRailsProject(\n options: Pick<WizardOptions, 'installDir'>,\n): Promise<boolean> {\n const { installDir } = options;\n\n // Check for bin/rails\n const binRailsPath = path.join(installDir, 'bin/rails');\n if (fs.existsSync(binRailsPath)) {\n return true;\n }\n\n // Check for config/application.rb with Rails reference\n const appConfigPath = path.join(installDir, 'config/application.rb');\n if (fs.existsSync(appConfigPath)) {\n try {\n const content = fs.readFileSync(appConfigPath, 'utf-8');\n if (\n content.includes('Rails::Application') ||\n content.includes('require \"rails\"') ||\n content.includes(\"require 'rails'\")\n ) {\n return true;\n }\n } catch {\n // Continue to other checks\n }\n }\n\n // Check Gemfile for rails gem\n if (hasGem('rails', options)) {\n return true;\n }\n\n // Check for typical Rails directory structure\n const railsStructureFiles = await fg(\n ['config/routes.rb', 'config/environment.rb'],\n { cwd: installDir, ignore: IGNORE_PATTERNS },\n );\n\n return railsStructureFiles.length >= 2;\n}\n"]}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.REACT_NATIVE_AGENT_CONFIG = void 0;
|
|
4
|
+
const package_manager_detection_1 = require("../lib/package-manager-detection");
|
|
4
5
|
const constants_1 = require("../lib/constants");
|
|
5
6
|
const package_json_1 = require("../utils/package-json");
|
|
6
7
|
const clack_utils_1 = require("../utils/clack-utils");
|
|
@@ -31,6 +32,7 @@ exports.REACT_NATIVE_AGENT_CONFIG = {
|
|
|
31
32
|
? (0, package_json_1.hasPackageInstalled)('react-native', packageJson)
|
|
32
33
|
: false;
|
|
33
34
|
},
|
|
35
|
+
detectPackageManager: package_manager_detection_1.detectNodePackageManagers,
|
|
34
36
|
},
|
|
35
37
|
environment: {
|
|
36
38
|
uploadToHosting: false,
|
|
@@ -46,7 +48,6 @@ exports.REACT_NATIVE_AGENT_CONFIG = {
|
|
|
46
48
|
},
|
|
47
49
|
prompts: {
|
|
48
50
|
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
51
|
getAdditionalContextLines: (context) => {
|
|
51
52
|
const isExpo = context.variant === utils_1.ReactNativeVariant.EXPO;
|
|
52
53
|
const frameworkId = 'react-native';
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"react-native-wizard-agent.js","sourceRoot":"","sources":["../../../src/react-native/react-native-wizard-agent.ts"],"names":[],"mappings":";;;AAGA,gDAA+C;AAC/C,wDAI+B;AAC/B,sDAA4E;AAC5E,mCAKiB;AAMJ,QAAA,yBAAyB,GAAwC;IAC5E,QAAQ,EAAE;QACR,IAAI,EAAE,cAAc;QACpB,WAAW,EAAE,uBAAW,CAAC,WAAW;QACpC,OAAO,EAAE,iDAAiD;QAC1D,aAAa,EAAE,KAAK,EAAE,OAAsB,EAAE,EAAE;YAC9C,MAAM,OAAO,GAAG,MAAM,IAAA,gCAAwB,EAAC,OAAO,CAAC,CAAC;YACxD,OAAO,EAAE,OAAO,EAAE,CAAC;QACrB,CAAC;KACF;IAED,SAAS,EAAE;QACT,WAAW,EAAE,cAAc;QAC3B,kBAAkB,EAAE,cAAc;QAClC,UAAU,EAAE,CAAC,WAAoB,EAAE,EAAE,CACnC,IAAA,gCAAiB,EAAC,cAAc,EAAE,WAA6B,CAAC;QAClE,gBAAgB,EAAE,mCAA2B;QAC7C,cAAc,EAAE,QAAQ;QACxB,mBAAmB,EAAE,KAAK,EAAE,OAAsB,EAAE,EAAE;YACpD,MAAM,WAAW,GAAG,MAAM,IAAA,+BAAiB,EAAC,OAAO,CAAC,CAAC;YACrD,OAAO,IAAA,gCAAiB,EAAC,cAAc,EAAE,WAAW,CAAC,CAAC;QACxD,CAAC;QACD,MAAM,EAAE,KAAK,EAAE,OAAO,EAAE,EAAE;YACxB,MAAM,WAAW,GAAG,MAAM,IAAA,+BAAiB,EAAC,OAAO,CAAC,CAAC;YACrD,OAAO,WAAW;gBAChB,CAAC,CAAC,IAAA,kCAAmB,EAAC,cAAc,EAAE,WAAW,CAAC;gBAClD,CAAC,CAAC,KAAK,CAAC;QACZ,CAAC;
|
|
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 { detectNodePackageManagers } from '../lib/package-manager-detection';\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 detectPackageManager: detectNodePackageManagers,\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 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"]}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.REACT_ROUTER_AGENT_CONFIG = void 0;
|
|
4
|
+
const package_manager_detection_1 = require("../lib/package-manager-detection");
|
|
4
5
|
const constants_1 = require("../lib/constants");
|
|
5
6
|
const package_json_1 = require("../utils/package-json");
|
|
6
7
|
const clack_utils_1 = require("../utils/clack-utils");
|
|
@@ -32,6 +33,7 @@ exports.REACT_ROUTER_AGENT_CONFIG = {
|
|
|
32
33
|
? (0, package_json_1.hasPackageInstalled)('react-router', packageJson)
|
|
33
34
|
: false;
|
|
34
35
|
},
|
|
36
|
+
detectPackageManager: package_manager_detection_1.detectNodePackageManagers,
|
|
35
37
|
},
|
|
36
38
|
environment: {
|
|
37
39
|
uploadToHosting: false,
|
|
@@ -47,7 +49,6 @@ exports.REACT_ROUTER_AGENT_CONFIG = {
|
|
|
47
49
|
},
|
|
48
50
|
prompts: {
|
|
49
51
|
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.',
|
|
50
|
-
packageInstallation: 'Look for lockfiles to determine the package manager (npm, yarn, pnpm, bun). Do not manually edit package.json.',
|
|
51
52
|
getAdditionalContextLines: (context) => {
|
|
52
53
|
const routerMode = context.routerMode;
|
|
53
54
|
const modeName = routerMode
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"react-router-wizard-agent.js","sourceRoot":"","sources":["../../../src/react-router/react-router-wizard-agent.ts"],"names":[],"mappings":";;;AAGA,gDAA+C;AAC/C,wDAI+B;AAC/B,sDAA4E;AAC5E,mCAKiB;AAMJ,QAAA,yBAAyB,GAAwC;IAC5E,QAAQ,EAAE;QACR,IAAI,EAAE,cAAc;QACpB,WAAW,EAAE,uBAAW,CAAC,WAAW;QACpC,OAAO,EAAE,0CAA0C;QACnD,yBAAyB,EAAE,0CAA0C;QACrE,aAAa,EAAE,KAAK,EAAE,OAAsB,EAAE,EAAE;YAC9C,MAAM,UAAU,GAAG,MAAM,IAAA,0BAAkB,EAAC,OAAO,CAAC,CAAC;YACrD,OAAO,EAAE,UAAU,EAAE,CAAC;QACxB,CAAC;KACF;IAED,SAAS,EAAE;QACT,WAAW,EAAE,cAAc;QAC3B,kBAAkB,EAAE,cAAc;QAClC,UAAU,EAAE,CAAC,WAAoB,EAAE,EAAE,CACnC,IAAA,gCAAiB,EAAC,cAAc,EAAE,WAA6B,CAAC;QAClE,gBAAgB,EAAE,mCAA2B;QAC7C,cAAc,EAAE,OAAO;QACvB,mBAAmB,EAAE,KAAK,EAAE,OAAsB,EAAE,EAAE;YACpD,MAAM,WAAW,GAAG,MAAM,IAAA,+BAAiB,EAAC,OAAO,CAAC,CAAC;YACrD,OAAO,IAAA,gCAAiB,EAAC,cAAc,EAAE,WAAW,CAAC,CAAC;QACxD,CAAC;QACD,MAAM,EAAE,KAAK,EAAE,OAAO,EAAE,EAAE;YACxB,MAAM,WAAW,GAAG,MAAM,IAAA,+BAAiB,EAAC,OAAO,CAAC,CAAC;YACrD,OAAO,WAAW;gBAChB,CAAC,CAAC,IAAA,kCAAmB,EAAC,cAAc,EAAE,WAAW,CAAC;gBAClD,CAAC,CAAC,KAAK,CAAC;QACZ,CAAC;
|
|
1
|
+
{"version":3,"file":"react-router-wizard-agent.js","sourceRoot":"","sources":["../../../src/react-router/react-router-wizard-agent.ts"],"names":[],"mappings":"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","sourcesContent":["/* React Router wizard using posthog-agent with PostHog MCP */\nimport type { WizardOptions } from '../utils/types';\nimport type { FrameworkConfig } from '../lib/framework-config';\nimport { detectNodePackageManagers } from '../lib/package-manager-detection';\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 getReactRouterMode,\n getReactRouterModeName,\n getReactRouterVersionBucket,\n ReactRouterMode,\n} from './utils';\n\ntype ReactRouterContext = {\n routerMode?: ReactRouterMode;\n};\n\nexport const REACT_ROUTER_AGENT_CONFIG: FrameworkConfig<ReactRouterContext> = {\n metadata: {\n name: 'React Router',\n integration: Integration.reactRouter,\n docsUrl: 'https://posthog.com/docs/libraries/react',\n unsupportedVersionDocsUrl: 'https://posthog.com/docs/libraries/react',\n gatherContext: async (options: WizardOptions) => {\n const routerMode = await getReactRouterMode(options);\n return { routerMode };\n },\n },\n\n detection: {\n packageName: 'react-router',\n packageDisplayName: 'React Router',\n getVersion: (packageJson: unknown) =>\n getPackageVersion('react-router', packageJson as PackageDotJson),\n getVersionBucket: getReactRouterVersionBucket,\n minimumVersion: '6.0.0',\n getInstalledVersion: async (options: WizardOptions) => {\n const packageJson = await getPackageDotJson(options);\n return getPackageVersion('react-router', packageJson);\n },\n detect: async (options) => {\n const packageJson = await tryGetPackageJson(options);\n return packageJson\n ? hasPackageInstalled('react-router', packageJson)\n : false;\n },\n detectPackageManager: detectNodePackageManagers,\n },\n\n environment: {\n uploadToHosting: false,\n getEnvVars: (apiKey: string, host: string) => ({\n REACT_APP_POSTHOG_KEY: apiKey,\n REACT_APP_POSTHOG_HOST: host,\n }),\n },\n\n analytics: {\n getTags: (context) => ({\n routerMode: context.routerMode || 'unknown',\n }),\n },\n\n prompts: {\n projectTypeDetection:\n 'This is a JavaScript/TypeScript project. Look for package.json and lockfiles (package-lock.json, yarn.lock, pnpm-lock.yaml, bun.lockb) to confirm.',\n getAdditionalContextLines: (context) => {\n const routerMode = context.routerMode;\n const modeName = routerMode\n ? getReactRouterModeName(routerMode)\n : 'unknown';\n\n // Map router mode to framework ID for MCP docs resource\n const frameworkIdMap: Record<ReactRouterMode, string> = {\n [ReactRouterMode.V6]: 'react-react-router-6',\n [ReactRouterMode.V7_FRAMEWORK]: 'react-react-router-7-framework',\n [ReactRouterMode.V7_DATA]: 'react-react-router-7-data',\n [ReactRouterMode.V7_DECLARATIVE]: 'react-react-router-7-declarative',\n };\n\n const frameworkId = routerMode\n ? frameworkIdMap[routerMode]\n : ReactRouterMode.V7_FRAMEWORK;\n\n return [\n `Router mode: ${modeName}`,\n `Framework docs ID: ${frameworkId} (use posthog://docs/frameworks/${frameworkId} for documentation)`,\n ];\n },\n },\n\n ui: {\n successMessage: 'PostHog integration complete',\n estimatedDurationMinutes: 8,\n getOutroChanges: (context) => {\n const modeName = context.routerMode\n ? getReactRouterModeName(context.routerMode)\n : 'React Router';\n return [\n `Analyzed your React Router project structure (${modeName})`,\n `Created and configured PostHog initializers`,\n `Integrated PostHog into your application`,\n ];\n },\n getOutroNextSteps: () => [\n 'Start your development server to see PostHog in action',\n 'Visit your PostHog dashboard to see incoming events',\n ],\n },\n};\n"]}
|