@posthog/wizard 1.33.0 → 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.
@@ -18,7 +18,9 @@ export declare enum Integration {
18
18
  sveltekit = "sveltekit",
19
19
  swift = "swift",
20
20
  android = "android",
21
- python = "python"
21
+ rails = "rails",
22
+ python = "python",
23
+ ruby = "ruby"
22
24
  }
23
25
  export interface Args {
24
26
  debug: boolean;
@@ -23,8 +23,10 @@ var Integration;
23
23
  Integration["sveltekit"] = "sveltekit";
24
24
  Integration["swift"] = "swift";
25
25
  Integration["android"] = "android";
26
+ Integration["rails"] = "rails";
26
27
  // Language fallbacks
27
28
  Integration["python"] = "python";
29
+ Integration["ruby"] = "ruby";
28
30
  })(Integration || (exports.Integration = Integration = {}));
29
31
  exports.IS_DEV = ['test', 'development'].includes(process.env.NODE_ENV ?? '');
30
32
  exports.DEBUG = false;
@@ -1 +1 @@
1
- {"version":3,"file":"constants.js","sourceRoot":"","sources":["../../../src/lib/constants.ts"],"names":[],"mappings":";;;AAAA;;GAEG;AACH,IAAY,WAqBX;AArBD,WAAY,WAAW;IACrB,aAAa;IACb,gCAAiB,CAAA;IACjB,4BAAa,CAAA;IACb,0BAAW,CAAA;IACX,2CAA4B,CAAA;IAC5B,+CAAgC,CAAA;IAChC,iDAAkC,CAAA;IAClC,2CAA4B,CAAA;IAC5B,kCAAmB,CAAA;IACnB,8BAAe,CAAA;IACf,gCAAiB,CAAA;IACjB,8BAAe,CAAA;IACf,kCAAmB,CAAA;IACnB,kCAAmB,CAAA;IACnB,sCAAuB,CAAA;IACvB,8BAAe,CAAA;IACf,kCAAmB,CAAA;IAEnB,qBAAqB;IACrB,gCAAiB,CAAA;AACnB,CAAC,EArBW,WAAW,2BAAX,WAAW,QAqBtB;AAMY,QAAA,MAAM,GAAG,CAAC,MAAM,EAAE,aAAa,CAAC,CAAC,QAAQ,CACpD,OAAO,CAAC,GAAG,CAAC,QAAQ,IAAI,EAAE,CAC3B,CAAC;AAEW,QAAA,KAAK,GAAG,KAAK,CAAC;AAEd,QAAA,WAAW,GAAG,cAAM;IAC/B,CAAC,CAAC,uBAAuB;IACzB,CAAC,CAAC,wBAAwB,CAAC;AAChB,QAAA,UAAU,GAAG,0CAA0C,CAAC;AACxD,QAAA,gBAAgB,GAAG,cAAM;IACpC,CAAC,CAAC,uBAAuB;IACzB,CAAC,CAAC,0BAA0B,CAAC;AAClB,QAAA,0CAA0C,GAAG,gBAAgB,CAAC;AAC9D,QAAA,kBAAkB,GAAG,gCAAgC,CAAC;AACtD,QAAA,kBAAkB,GAAG,iBAAiB,CAAC;AACvC,QAAA,qBAAqB,GAAG,gCAAgC,CAAC;AAEzD,QAAA,oBAAoB,GAAG,0CAA0C,CAAC;AAClE,QAAA,oBAAoB,GAAG,0CAA0C,CAAC;AAClE,QAAA,qBAAqB,GAAG,0CAA0C,CAAC;AACnE,QAAA,UAAU,GAAG,IAAI,CAAC;AAElB,QAAA,6BAA6B,GAAG,oBAAoB,CAAC;AACrD,QAAA,wBAAwB,GAAG,eAAe,CAAC","sourcesContent":["/**\n * Detection order matters: put framework-specific integrations BEFORE basic language fallbacks\n */\nexport enum Integration {\n // Frameworks\n nextjs = 'nextjs',\n nuxt = 'nuxt',\n vue = 'vue',\n reactRouter = 'react-router',\n tanstackStart = 'tanstack-start',\n tanstackRouter = 'tanstack-router',\n reactNative = 'react-native',\n angular = 'angular',\n astro = 'astro',\n django = 'django',\n flask = 'flask',\n fastapi = 'fastapi',\n laravel = 'laravel',\n sveltekit = 'sveltekit',\n swift = 'swift',\n android = 'android',\n\n // Language fallbacks\n python = 'python',\n}\nexport interface Args {\n debug: boolean;\n integration: Integration;\n}\n\nexport const IS_DEV = ['test', 'development'].includes(\n process.env.NODE_ENV ?? '',\n);\n\nexport const DEBUG = false;\n\nexport const DEFAULT_URL = IS_DEV\n ? 'http://localhost:8010'\n : 'https://us.posthog.com';\nexport const ISSUES_URL = 'https://github.com/posthog/wizard/issues';\nexport const DEFAULT_HOST_URL = IS_DEV\n ? 'http://localhost:8010'\n : 'https://us.i.posthog.com';\nexport const ANALYTICS_POSTHOG_PUBLIC_PROJECT_WRITE_KEY = 'sTMFPsFhdP1Ssg';\nexport const ANALYTICS_HOST_URL = 'https://internal-j.posthog.com';\nexport const ANALYTICS_TEAM_TAG = 'docs-and-wizard';\nexport const DUMMY_PROJECT_API_KEY = '_YOUR_POSTHOG_PROJECT_API_KEY_';\n\nexport const POSTHOG_US_CLIENT_ID = 'c4Rdw8DIxgtQfA80IiSnGKlNX8QN00cFWF00QQhM';\nexport const POSTHOG_EU_CLIENT_ID = 'bx2C5sZRN03TkdjraCcetvQFPGH6N2Y9vRLkcKEy';\nexport const POSTHOG_DEV_CLIENT_ID = 'DC5uRLVbGI02YQ82grxgnK6Qn12SXWpCqdPb60oZ';\nexport const OAUTH_PORT = 8239;\n\nexport const WIZARD_INTERACTION_EVENT_NAME = 'wizard interaction';\nexport const WIZARD_REMARK_EVENT_NAME = 'wizard remark';\n"]}
1
+ {"version":3,"file":"constants.js","sourceRoot":"","sources":["../../../src/lib/constants.ts"],"names":[],"mappings":";;;AAAA;;GAEG;AACH,IAAY,WAuBX;AAvBD,WAAY,WAAW;IACrB,aAAa;IACb,gCAAiB,CAAA;IACjB,4BAAa,CAAA;IACb,0BAAW,CAAA;IACX,2CAA4B,CAAA;IAC5B,+CAAgC,CAAA;IAChC,iDAAkC,CAAA;IAClC,2CAA4B,CAAA;IAC5B,kCAAmB,CAAA;IACnB,8BAAe,CAAA;IACf,gCAAiB,CAAA;IACjB,8BAAe,CAAA;IACf,kCAAmB,CAAA;IACnB,kCAAmB,CAAA;IACnB,sCAAuB,CAAA;IACvB,8BAAe,CAAA;IACf,kCAAmB,CAAA;IACnB,8BAAe,CAAA;IAEf,qBAAqB;IACrB,gCAAiB,CAAA;IACjB,4BAAa,CAAA;AACf,CAAC,EAvBW,WAAW,2BAAX,WAAW,QAuBtB;AAMY,QAAA,MAAM,GAAG,CAAC,MAAM,EAAE,aAAa,CAAC,CAAC,QAAQ,CACpD,OAAO,CAAC,GAAG,CAAC,QAAQ,IAAI,EAAE,CAC3B,CAAC;AAEW,QAAA,KAAK,GAAG,KAAK,CAAC;AAEd,QAAA,WAAW,GAAG,cAAM;IAC/B,CAAC,CAAC,uBAAuB;IACzB,CAAC,CAAC,wBAAwB,CAAC;AAChB,QAAA,UAAU,GAAG,0CAA0C,CAAC;AACxD,QAAA,gBAAgB,GAAG,cAAM;IACpC,CAAC,CAAC,uBAAuB;IACzB,CAAC,CAAC,0BAA0B,CAAC;AAClB,QAAA,0CAA0C,GAAG,gBAAgB,CAAC;AAC9D,QAAA,kBAAkB,GAAG,gCAAgC,CAAC;AACtD,QAAA,kBAAkB,GAAG,iBAAiB,CAAC;AACvC,QAAA,qBAAqB,GAAG,gCAAgC,CAAC;AAEzD,QAAA,oBAAoB,GAAG,0CAA0C,CAAC;AAClE,QAAA,oBAAoB,GAAG,0CAA0C,CAAC;AAClE,QAAA,qBAAqB,GAAG,0CAA0C,CAAC;AACnE,QAAA,UAAU,GAAG,IAAI,CAAC;AAElB,QAAA,6BAA6B,GAAG,oBAAoB,CAAC;AACrD,QAAA,wBAAwB,GAAG,eAAe,CAAC","sourcesContent":["/**\n * Detection order matters: put framework-specific integrations BEFORE basic language fallbacks\n */\nexport enum Integration {\n // Frameworks\n nextjs = 'nextjs',\n nuxt = 'nuxt',\n vue = 'vue',\n reactRouter = 'react-router',\n tanstackStart = 'tanstack-start',\n tanstackRouter = 'tanstack-router',\n reactNative = 'react-native',\n angular = 'angular',\n astro = 'astro',\n django = 'django',\n flask = 'flask',\n fastapi = 'fastapi',\n laravel = 'laravel',\n sveltekit = 'sveltekit',\n swift = 'swift',\n android = 'android',\n rails = 'rails',\n\n // Language fallbacks\n python = 'python',\n ruby = 'ruby',\n}\nexport interface Args {\n debug: boolean;\n integration: Integration;\n}\n\nexport const IS_DEV = ['test', 'development'].includes(\n process.env.NODE_ENV ?? '',\n);\n\nexport const DEBUG = false;\n\nexport const DEFAULT_URL = IS_DEV\n ? 'http://localhost:8010'\n : 'https://us.posthog.com';\nexport const ISSUES_URL = 'https://github.com/posthog/wizard/issues';\nexport const DEFAULT_HOST_URL = IS_DEV\n ? 'http://localhost:8010'\n : 'https://us.i.posthog.com';\nexport const ANALYTICS_POSTHOG_PUBLIC_PROJECT_WRITE_KEY = 'sTMFPsFhdP1Ssg';\nexport const ANALYTICS_HOST_URL = 'https://internal-j.posthog.com';\nexport const ANALYTICS_TEAM_TAG = 'docs-and-wizard';\nexport const DUMMY_PROJECT_API_KEY = '_YOUR_POSTHOG_PROJECT_API_KEY_';\n\nexport const POSTHOG_US_CLIENT_ID = 'c4Rdw8DIxgtQfA80IiSnGKlNX8QN00cFWF00QQhM';\nexport const POSTHOG_EU_CLIENT_ID = 'bx2C5sZRN03TkdjraCcetvQFPGH6N2Y9vRLkcKEy';\nexport const POSTHOG_DEV_CLIENT_ID = 'DC5uRLVbGI02YQ82grxgnK6Qn12SXWpCqdPb60oZ';\nexport const OAUTH_PORT = 8239;\n\nexport const WIZARD_INTERACTION_EVENT_NAME = 'wizard interaction';\nexport const WIZARD_REMARK_EVENT_NAME = 'wizard remark';\n"]}
@@ -33,4 +33,5 @@ export declare function detectNodePackageManagers(installDir: string): Promise<P
33
33
  export declare function detectPythonPackageManagers(installDir: string): Promise<PackageManagerInfo>;
34
34
  export declare function composerPackageManager(): Promise<PackageManagerInfo>;
35
35
  export declare function swiftPackageManager(): Promise<PackageManagerInfo>;
36
+ export declare function bundlerPackageManager(): Promise<PackageManagerInfo>;
36
37
  export declare function gradlePackageManager(): Promise<PackageManagerInfo>;
@@ -12,6 +12,7 @@ exports.detectNodePackageManagers = detectNodePackageManagers;
12
12
  exports.detectPythonPackageManagers = detectPythonPackageManagers;
13
13
  exports.composerPackageManager = composerPackageManager;
14
14
  exports.swiftPackageManager = swiftPackageManager;
15
+ exports.bundlerPackageManager = bundlerPackageManager;
15
16
  exports.gradlePackageManager = gradlePackageManager;
16
17
  const package_manager_1 = require("../utils/package-manager");
17
18
  const utils_1 = require("../python/utils");
@@ -149,6 +150,22 @@ function swiftPackageManager() {
149
150
  });
150
151
  }
151
152
  // ---------------------------------------------------------------------------
153
+ // Ruby (Bundler) helper
154
+ // ---------------------------------------------------------------------------
155
+ const BUNDLER = {
156
+ name: 'bundler',
157
+ label: 'Bundler',
158
+ installCommand: 'bundle add',
159
+ runCommand: 'bundle exec',
160
+ };
161
+ function bundlerPackageManager() {
162
+ return Promise.resolve({
163
+ detected: [BUNDLER],
164
+ primary: BUNDLER,
165
+ recommendation: 'Use Bundler (bundle add). Run commands with bundle exec.',
166
+ });
167
+ }
168
+ // ---------------------------------------------------------------------------
152
169
  // Android (Gradle) helper
153
170
  // ---------------------------------------------------------------------------
154
171
  const GRADLE = {
@@ -1 +1 @@
1
- {"version":3,"file":"package-manager-detection.js","sourceRoot":"","sources":["../../../src/lib/package-manager-detection.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Cross-ecosystem package manager detection.\n *\n * Provides a common interface (PackageManagerDetector) that each FrameworkConfig\n * implements, plus shared helpers for Node.js, Python, PHP, and Swift ecosystems.\n * The MCP tool in wizard-tools.ts delegates to whatever detector the\n * current framework supplies.\n */\n\nimport {\n detectAllPackageManagers,\n type PackageManager,\n} from '../utils/package-manager';\nimport {\n detectPackageManager as detectPythonPM,\n PythonPackageManager,\n} from '../python/utils';\n\n// ---------------------------------------------------------------------------\n// Common types\n// ---------------------------------------------------------------------------\n\n/** Structured package manager info the agent can act on */\nexport interface DetectedPackageManager {\n name: string;\n label: string;\n installCommand: string;\n runCommand?: string;\n}\n\n/** Result returned by every detector */\nexport interface PackageManagerInfo {\n detected: DetectedPackageManager[];\n primary: DetectedPackageManager | null;\n recommendation: string;\n}\n\n/** Signature each framework implements */\nexport type PackageManagerDetector = (\n installDir: string,\n) => Promise<PackageManagerInfo>;\n\n// ---------------------------------------------------------------------------\n// Node.js helper\n// ---------------------------------------------------------------------------\n\nfunction serializeNodePM(pm: PackageManager): DetectedPackageManager {\n return {\n name: pm.name,\n label: pm.label,\n installCommand: pm.installCommand,\n runCommand: pm.runScriptCommand,\n };\n}\n\n/**\n * Detect Node.js package managers via lockfiles.\n * Wraps the existing detectAllPackageManagers() from utils/package-manager.ts.\n */\nexport function detectNodePackageManagers(\n installDir: string,\n): Promise<PackageManagerInfo> {\n const detected = detectAllPackageManagers({ installDir }).map(\n serializeNodePM,\n );\n\n if (detected.length === 0) {\n return Promise.resolve({\n detected: [],\n primary: null,\n recommendation: 'No lockfile found. Default to npm (npm add, npm run).',\n });\n }\n\n const primary = detected[0];\n return Promise.resolve({\n detected,\n primary,\n recommendation:\n detected.length === 1\n ? `Use ${primary.label} (${primary.installCommand}).`\n : `Multiple package managers detected. Prefer ${primary.label} (${primary.installCommand}).`,\n });\n}\n\n// ---------------------------------------------------------------------------\n// Python helper\n// ---------------------------------------------------------------------------\n\nconst PYTHON_PM_INFO: Record<PythonPackageManager, DetectedPackageManager> = {\n [PythonPackageManager.UV]: {\n name: 'uv',\n label: 'uv',\n installCommand: 'uv add',\n runCommand: 'uv run',\n },\n [PythonPackageManager.POETRY]: {\n name: 'poetry',\n label: 'Poetry',\n installCommand: 'poetry add',\n runCommand: 'poetry run',\n },\n [PythonPackageManager.PDM]: {\n name: 'pdm',\n label: 'PDM',\n installCommand: 'pdm add',\n runCommand: 'pdm run',\n },\n [PythonPackageManager.HATCH]: {\n name: 'hatch',\n label: 'Hatch',\n installCommand: 'hatch add',\n runCommand: 'hatch run',\n },\n [PythonPackageManager.RYE]: {\n name: 'rye',\n label: 'Rye',\n installCommand: 'rye add',\n runCommand: 'rye run',\n },\n [PythonPackageManager.PIPENV]: {\n name: 'pipenv',\n label: 'Pipenv',\n installCommand: 'pipenv install',\n runCommand: 'pipenv run',\n },\n [PythonPackageManager.CONDA]: {\n name: 'conda',\n label: 'Conda',\n installCommand: 'conda install',\n runCommand: 'conda run',\n },\n [PythonPackageManager.PIP]: {\n name: 'pip',\n label: 'pip',\n installCommand: 'pip install',\n },\n [PythonPackageManager.UNKNOWN]: {\n name: 'pip',\n label: 'pip (default)',\n installCommand: 'pip install',\n },\n};\n\n/**\n * Detect Python package managers via lockfiles and config files.\n * Wraps the existing detectPackageManager() from python/utils.ts.\n */\nexport async function detectPythonPackageManagers(\n installDir: string,\n): Promise<PackageManagerInfo> {\n const pm = await detectPythonPM({ installDir } as any);\n const info = PYTHON_PM_INFO[pm];\n\n return {\n detected: [info],\n primary: info,\n recommendation: `Use ${info.label} (${info.installCommand}).`,\n };\n}\n\n// ---------------------------------------------------------------------------\n// PHP (Composer) helper\n// ---------------------------------------------------------------------------\n\nconst COMPOSER: DetectedPackageManager = {\n name: 'composer',\n label: 'Composer',\n installCommand: 'composer require',\n};\n\nexport function composerPackageManager(): Promise<PackageManagerInfo> {\n return Promise.resolve({\n detected: [COMPOSER],\n primary: COMPOSER,\n recommendation: 'Use Composer (composer require).',\n });\n}\n\n// ---------------------------------------------------------------------------\n// Swift (SPM) helper\n// ---------------------------------------------------------------------------\n\nconst SPM: DetectedPackageManager = {\n name: 'spm',\n label: 'Swift Package Manager',\n installCommand: 'swift package add-dependency',\n};\n\nexport function swiftPackageManager(): Promise<PackageManagerInfo> {\n return Promise.resolve({\n detected: [SPM],\n primary: SPM,\n recommendation:\n 'Use Swift Package Manager. Add the dependency to Package.swift or via Xcode.',\n });\n}\n\n// ---------------------------------------------------------------------------\n// Android (Gradle) helper\n// ---------------------------------------------------------------------------\n\nconst GRADLE: DetectedPackageManager = {\n name: 'gradle',\n label: 'Gradle',\n installCommand: 'implementation',\n};\n\nexport function gradlePackageManager(): Promise<PackageManagerInfo> {\n return Promise.resolve({\n detected: [GRADLE],\n primary: GRADLE,\n recommendation:\n 'Add dependencies to build.gradle(.kts) using implementation().',\n });\n}\n"]}
1
+ {"version":3,"file":"package-manager-detection.js","sourceRoot":"","sources":["../../../src/lib/package-manager-detection.ts"],"names":[],"mappings":";AAAA;;;;;;;GAOG;;AAoDH,8DAwBC;AAiED,kEAWC;AAYD,wDAMC;AAYD,kDAOC;AAaD,sDAMC;AAYD,oDAOC;AAjOD,8DAGkC;AAClC,2CAGyB;AA0BzB,8EAA8E;AAC9E,iBAAiB;AACjB,8EAA8E;AAE9E,SAAS,eAAe,CAAC,EAAkB;IACzC,OAAO;QACL,IAAI,EAAE,EAAE,CAAC,IAAI;QACb,KAAK,EAAE,EAAE,CAAC,KAAK;QACf,cAAc,EAAE,EAAE,CAAC,cAAc;QACjC,UAAU,EAAE,EAAE,CAAC,gBAAgB;KAChC,CAAC;AACJ,CAAC;AAED;;;GAGG;AACH,SAAgB,yBAAyB,CACvC,UAAkB;IAElB,MAAM,QAAQ,GAAG,IAAA,0CAAwB,EAAC,EAAE,UAAU,EAAE,CAAC,CAAC,GAAG,CAC3D,eAAe,CAChB,CAAC;IAEF,IAAI,QAAQ,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC1B,OAAO,OAAO,CAAC,OAAO,CAAC;YACrB,QAAQ,EAAE,EAAE;YACZ,OAAO,EAAE,IAAI;YACb,cAAc,EAAE,uDAAuD;SACxE,CAAC,CAAC;IACL,CAAC;IAED,MAAM,OAAO,GAAG,QAAQ,CAAC,CAAC,CAAC,CAAC;IAC5B,OAAO,OAAO,CAAC,OAAO,CAAC;QACrB,QAAQ;QACR,OAAO;QACP,cAAc,EACZ,QAAQ,CAAC,MAAM,KAAK,CAAC;YACnB,CAAC,CAAC,OAAO,OAAO,CAAC,KAAK,KAAK,OAAO,CAAC,cAAc,IAAI;YACrD,CAAC,CAAC,8CAA8C,OAAO,CAAC,KAAK,KAAK,OAAO,CAAC,cAAc,IAAI;KACjG,CAAC,CAAC;AACL,CAAC;AAED,8EAA8E;AAC9E,gBAAgB;AAChB,8EAA8E;AAE9E,MAAM,cAAc,GAAyD;IAC3E,CAAC,4BAAoB,CAAC,EAAE,CAAC,EAAE;QACzB,IAAI,EAAE,IAAI;QACV,KAAK,EAAE,IAAI;QACX,cAAc,EAAE,QAAQ;QACxB,UAAU,EAAE,QAAQ;KACrB;IACD,CAAC,4BAAoB,CAAC,MAAM,CAAC,EAAE;QAC7B,IAAI,EAAE,QAAQ;QACd,KAAK,EAAE,QAAQ;QACf,cAAc,EAAE,YAAY;QAC5B,UAAU,EAAE,YAAY;KACzB;IACD,CAAC,4BAAoB,CAAC,GAAG,CAAC,EAAE;QAC1B,IAAI,EAAE,KAAK;QACX,KAAK,EAAE,KAAK;QACZ,cAAc,EAAE,SAAS;QACzB,UAAU,EAAE,SAAS;KACtB;IACD,CAAC,4BAAoB,CAAC,KAAK,CAAC,EAAE;QAC5B,IAAI,EAAE,OAAO;QACb,KAAK,EAAE,OAAO;QACd,cAAc,EAAE,WAAW;QAC3B,UAAU,EAAE,WAAW;KACxB;IACD,CAAC,4BAAoB,CAAC,GAAG,CAAC,EAAE;QAC1B,IAAI,EAAE,KAAK;QACX,KAAK,EAAE,KAAK;QACZ,cAAc,EAAE,SAAS;QACzB,UAAU,EAAE,SAAS;KACtB;IACD,CAAC,4BAAoB,CAAC,MAAM,CAAC,EAAE;QAC7B,IAAI,EAAE,QAAQ;QACd,KAAK,EAAE,QAAQ;QACf,cAAc,EAAE,gBAAgB;QAChC,UAAU,EAAE,YAAY;KACzB;IACD,CAAC,4BAAoB,CAAC,KAAK,CAAC,EAAE;QAC5B,IAAI,EAAE,OAAO;QACb,KAAK,EAAE,OAAO;QACd,cAAc,EAAE,eAAe;QAC/B,UAAU,EAAE,WAAW;KACxB;IACD,CAAC,4BAAoB,CAAC,GAAG,CAAC,EAAE;QAC1B,IAAI,EAAE,KAAK;QACX,KAAK,EAAE,KAAK;QACZ,cAAc,EAAE,aAAa;KAC9B;IACD,CAAC,4BAAoB,CAAC,OAAO,CAAC,EAAE;QAC9B,IAAI,EAAE,KAAK;QACX,KAAK,EAAE,eAAe;QACtB,cAAc,EAAE,aAAa;KAC9B;CACF,CAAC;AAEF;;;GAGG;AACI,KAAK,UAAU,2BAA2B,CAC/C,UAAkB;IAElB,MAAM,EAAE,GAAG,MAAM,IAAA,4BAAc,EAAC,EAAE,UAAU,EAAS,CAAC,CAAC;IACvD,MAAM,IAAI,GAAG,cAAc,CAAC,EAAE,CAAC,CAAC;IAEhC,OAAO;QACL,QAAQ,EAAE,CAAC,IAAI,CAAC;QAChB,OAAO,EAAE,IAAI;QACb,cAAc,EAAE,OAAO,IAAI,CAAC,KAAK,KAAK,IAAI,CAAC,cAAc,IAAI;KAC9D,CAAC;AACJ,CAAC;AAED,8EAA8E;AAC9E,wBAAwB;AACxB,8EAA8E;AAE9E,MAAM,QAAQ,GAA2B;IACvC,IAAI,EAAE,UAAU;IAChB,KAAK,EAAE,UAAU;IACjB,cAAc,EAAE,kBAAkB;CACnC,CAAC;AAEF,SAAgB,sBAAsB;IACpC,OAAO,OAAO,CAAC,OAAO,CAAC;QACrB,QAAQ,EAAE,CAAC,QAAQ,CAAC;QACpB,OAAO,EAAE,QAAQ;QACjB,cAAc,EAAE,kCAAkC;KACnD,CAAC,CAAC;AACL,CAAC;AAED,8EAA8E;AAC9E,qBAAqB;AACrB,8EAA8E;AAE9E,MAAM,GAAG,GAA2B;IAClC,IAAI,EAAE,KAAK;IACX,KAAK,EAAE,uBAAuB;IAC9B,cAAc,EAAE,8BAA8B;CAC/C,CAAC;AAEF,SAAgB,mBAAmB;IACjC,OAAO,OAAO,CAAC,OAAO,CAAC;QACrB,QAAQ,EAAE,CAAC,GAAG,CAAC;QACf,OAAO,EAAE,GAAG;QACZ,cAAc,EACZ,8EAA8E;KACjF,CAAC,CAAC;AACL,CAAC;AAED,8EAA8E;AAC9E,wBAAwB;AACxB,8EAA8E;AAE9E,MAAM,OAAO,GAA2B;IACtC,IAAI,EAAE,SAAS;IACf,KAAK,EAAE,SAAS;IAChB,cAAc,EAAE,YAAY;IAC5B,UAAU,EAAE,aAAa;CAC1B,CAAC;AAEF,SAAgB,qBAAqB;IACnC,OAAO,OAAO,CAAC,OAAO,CAAC;QACrB,QAAQ,EAAE,CAAC,OAAO,CAAC;QACnB,OAAO,EAAE,OAAO;QAChB,cAAc,EAAE,0DAA0D;KAC3E,CAAC,CAAC;AACL,CAAC;AAED,8EAA8E;AAC9E,0BAA0B;AAC1B,8EAA8E;AAE9E,MAAM,MAAM,GAA2B;IACrC,IAAI,EAAE,QAAQ;IACd,KAAK,EAAE,QAAQ;IACf,cAAc,EAAE,gBAAgB;CACjC,CAAC;AAEF,SAAgB,oBAAoB;IAClC,OAAO,OAAO,CAAC,OAAO,CAAC;QACrB,QAAQ,EAAE,CAAC,MAAM,CAAC;QAClB,OAAO,EAAE,MAAM;QACf,cAAc,EACZ,gEAAgE;KACnE,CAAC,CAAC;AACL,CAAC","sourcesContent":["/**\n * Cross-ecosystem package manager detection.\n *\n * Provides a common interface (PackageManagerDetector) that each FrameworkConfig\n * implements, plus shared helpers for Node.js, Python, PHP, and Swift ecosystems.\n * The MCP tool in wizard-tools.ts delegates to whatever detector the\n * current framework supplies.\n */\n\nimport {\n detectAllPackageManagers,\n type PackageManager,\n} from '../utils/package-manager';\nimport {\n detectPackageManager as detectPythonPM,\n PythonPackageManager,\n} from '../python/utils';\n\n// ---------------------------------------------------------------------------\n// Common types\n// ---------------------------------------------------------------------------\n\n/** Structured package manager info the agent can act on */\nexport interface DetectedPackageManager {\n name: string;\n label: string;\n installCommand: string;\n runCommand?: string;\n}\n\n/** Result returned by every detector */\nexport interface PackageManagerInfo {\n detected: DetectedPackageManager[];\n primary: DetectedPackageManager | null;\n recommendation: string;\n}\n\n/** Signature each framework implements */\nexport type PackageManagerDetector = (\n installDir: string,\n) => Promise<PackageManagerInfo>;\n\n// ---------------------------------------------------------------------------\n// Node.js helper\n// ---------------------------------------------------------------------------\n\nfunction serializeNodePM(pm: PackageManager): DetectedPackageManager {\n return {\n name: pm.name,\n label: pm.label,\n installCommand: pm.installCommand,\n runCommand: pm.runScriptCommand,\n };\n}\n\n/**\n * Detect Node.js package managers via lockfiles.\n * Wraps the existing detectAllPackageManagers() from utils/package-manager.ts.\n */\nexport function detectNodePackageManagers(\n installDir: string,\n): Promise<PackageManagerInfo> {\n const detected = detectAllPackageManagers({ installDir }).map(\n serializeNodePM,\n );\n\n if (detected.length === 0) {\n return Promise.resolve({\n detected: [],\n primary: null,\n recommendation: 'No lockfile found. Default to npm (npm add, npm run).',\n });\n }\n\n const primary = detected[0];\n return Promise.resolve({\n detected,\n primary,\n recommendation:\n detected.length === 1\n ? `Use ${primary.label} (${primary.installCommand}).`\n : `Multiple package managers detected. Prefer ${primary.label} (${primary.installCommand}).`,\n });\n}\n\n// ---------------------------------------------------------------------------\n// Python helper\n// ---------------------------------------------------------------------------\n\nconst PYTHON_PM_INFO: Record<PythonPackageManager, DetectedPackageManager> = {\n [PythonPackageManager.UV]: {\n name: 'uv',\n label: 'uv',\n installCommand: 'uv add',\n runCommand: 'uv run',\n },\n [PythonPackageManager.POETRY]: {\n name: 'poetry',\n label: 'Poetry',\n installCommand: 'poetry add',\n runCommand: 'poetry run',\n },\n [PythonPackageManager.PDM]: {\n name: 'pdm',\n label: 'PDM',\n installCommand: 'pdm add',\n runCommand: 'pdm run',\n },\n [PythonPackageManager.HATCH]: {\n name: 'hatch',\n label: 'Hatch',\n installCommand: 'hatch add',\n runCommand: 'hatch run',\n },\n [PythonPackageManager.RYE]: {\n name: 'rye',\n label: 'Rye',\n installCommand: 'rye add',\n runCommand: 'rye run',\n },\n [PythonPackageManager.PIPENV]: {\n name: 'pipenv',\n label: 'Pipenv',\n installCommand: 'pipenv install',\n runCommand: 'pipenv run',\n },\n [PythonPackageManager.CONDA]: {\n name: 'conda',\n label: 'Conda',\n installCommand: 'conda install',\n runCommand: 'conda run',\n },\n [PythonPackageManager.PIP]: {\n name: 'pip',\n label: 'pip',\n installCommand: 'pip install',\n },\n [PythonPackageManager.UNKNOWN]: {\n name: 'pip',\n label: 'pip (default)',\n installCommand: 'pip install',\n },\n};\n\n/**\n * Detect Python package managers via lockfiles and config files.\n * Wraps the existing detectPackageManager() from python/utils.ts.\n */\nexport async function detectPythonPackageManagers(\n installDir: string,\n): Promise<PackageManagerInfo> {\n const pm = await detectPythonPM({ installDir } as any);\n const info = PYTHON_PM_INFO[pm];\n\n return {\n detected: [info],\n primary: info,\n recommendation: `Use ${info.label} (${info.installCommand}).`,\n };\n}\n\n// ---------------------------------------------------------------------------\n// PHP (Composer) helper\n// ---------------------------------------------------------------------------\n\nconst COMPOSER: DetectedPackageManager = {\n name: 'composer',\n label: 'Composer',\n installCommand: 'composer require',\n};\n\nexport function composerPackageManager(): Promise<PackageManagerInfo> {\n return Promise.resolve({\n detected: [COMPOSER],\n primary: COMPOSER,\n recommendation: 'Use Composer (composer require).',\n });\n}\n\n// ---------------------------------------------------------------------------\n// Swift (SPM) helper\n// ---------------------------------------------------------------------------\n\nconst SPM: DetectedPackageManager = {\n name: 'spm',\n label: 'Swift Package Manager',\n installCommand: 'swift package add-dependency',\n};\n\nexport function swiftPackageManager(): Promise<PackageManagerInfo> {\n return Promise.resolve({\n detected: [SPM],\n primary: SPM,\n recommendation:\n 'Use Swift Package Manager. Add the dependency to Package.swift or via Xcode.',\n });\n}\n\n// ---------------------------------------------------------------------------\n// Ruby (Bundler) helper\n// ---------------------------------------------------------------------------\n\nconst BUNDLER: DetectedPackageManager = {\n name: 'bundler',\n label: 'Bundler',\n installCommand: 'bundle add',\n runCommand: 'bundle exec',\n};\n\nexport function bundlerPackageManager(): Promise<PackageManagerInfo> {\n return Promise.resolve({\n detected: [BUNDLER],\n primary: BUNDLER,\n recommendation: 'Use Bundler (bundle add). Run commands with bundle exec.',\n });\n}\n\n// ---------------------------------------------------------------------------\n// Android (Gradle) helper\n// ---------------------------------------------------------------------------\n\nconst GRADLE: DetectedPackageManager = {\n name: 'gradle',\n label: 'Gradle',\n installCommand: 'implementation',\n};\n\nexport function gradlePackageManager(): Promise<PackageManagerInfo> {\n return Promise.resolve({\n detected: [GRADLE],\n primary: GRADLE,\n recommendation:\n 'Add dependencies to build.gradle(.kts) using implementation().',\n });\n}\n"]}
@@ -18,7 +18,9 @@ const laravel_wizard_agent_1 = require("../laravel/laravel-wizard-agent");
18
18
  const svelte_wizard_agent_1 = require("../svelte/svelte-wizard-agent");
19
19
  const swift_wizard_agent_1 = require("../swift/swift-wizard-agent");
20
20
  const android_wizard_agent_1 = require("../android/android-wizard-agent");
21
+ const rails_wizard_agent_1 = require("../rails/rails-wizard-agent");
21
22
  const python_wizard_agent_1 = require("../python/python-wizard-agent");
23
+ const ruby_wizard_agent_1 = require("../ruby/ruby-wizard-agent");
22
24
  exports.FRAMEWORK_REGISTRY = {
23
25
  [constants_1.Integration.nextjs]: nextjs_wizard_agent_1.NEXTJS_AGENT_CONFIG,
24
26
  [constants_1.Integration.nuxt]: nuxt_wizard_agent_1.NUXT_AGENT_CONFIG,
@@ -36,6 +38,8 @@ exports.FRAMEWORK_REGISTRY = {
36
38
  [constants_1.Integration.sveltekit]: svelte_wizard_agent_1.SVELTEKIT_AGENT_CONFIG,
37
39
  [constants_1.Integration.swift]: swift_wizard_agent_1.SWIFT_AGENT_CONFIG,
38
40
  [constants_1.Integration.android]: android_wizard_agent_1.ANDROID_AGENT_CONFIG,
41
+ [constants_1.Integration.rails]: rails_wizard_agent_1.RAILS_AGENT_CONFIG,
39
42
  [constants_1.Integration.python]: python_wizard_agent_1.PYTHON_AGENT_CONFIG,
43
+ [constants_1.Integration.ruby]: ruby_wizard_agent_1.RUBY_AGENT_CONFIG,
40
44
  };
41
45
  //# sourceMappingURL=registry.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"registry.js","sourceRoot":"","sources":["../../../src/lib/registry.ts"],"names":[],"mappings":";;;AACA,2CAA0C;AAC1C,uEAAoE;AACpE,iEAA8D;AAC9D,8DAA2D;AAC3D,yFAAsF;AACtF,kGAA+F;AAC/F,+FAA4F;AAC5F,yFAAsF;AACtF,0EAAuE;AACvE,oEAAiE;AACjE,uEAAoE;AACpE,oEAAiE;AACjE,0EAAuE;AACvE,0EAAuE;AACvE,uEAAuE;AACvE,oEAAiE;AACjE,0EAAuE;AACvE,uEAAoE;AAEvD,QAAA,kBAAkB,GAAyC;IACtE,CAAC,uBAAW,CAAC,MAAM,CAAC,EAAE,yCAAmB;IACzC,CAAC,uBAAW,CAAC,IAAI,CAAC,EAAE,qCAAiB;IACrC,CAAC,uBAAW,CAAC,GAAG,CAAC,EAAE,mCAAgB;IACnC,CAAC,uBAAW,CAAC,aAAa,CAAC,EAAE,yDAA2B;IACxD,CAAC,uBAAW,CAAC,WAAW,CAAC,EAAE,qDAAyB;IACpD,CAAC,uBAAW,CAAC,cAAc,CAAC,EAAE,2DAA4B;IAC1D,CAAC,uBAAW,CAAC,WAAW,CAAC,EAAE,qDAAyB;IACpD,CAAC,uBAAW,CAAC,OAAO,CAAC,EAAE,2CAAoB;IAC3C,CAAC,uBAAW,CAAC,KAAK,CAAC,EAAE,uCAAkB;IACvC,CAAC,uBAAW,CAAC,MAAM,CAAC,EAAE,yCAAmB;IACzC,CAAC,uBAAW,CAAC,KAAK,CAAC,EAAE,uCAAkB;IACvC,CAAC,uBAAW,CAAC,OAAO,CAAC,EAAE,2CAAoB;IAC3C,CAAC,uBAAW,CAAC,OAAO,CAAC,EAAE,2CAAoB;IAC3C,CAAC,uBAAW,CAAC,SAAS,CAAC,EAAE,4CAAsB;IAC/C,CAAC,uBAAW,CAAC,KAAK,CAAC,EAAE,uCAAkB;IACvC,CAAC,uBAAW,CAAC,OAAO,CAAC,EAAE,2CAAoB;IAC3C,CAAC,uBAAW,CAAC,MAAM,CAAC,EAAE,yCAAmB;CAC1C,CAAC","sourcesContent":["import type { FrameworkConfig } from './framework-config';\nimport { Integration } from './constants';\nimport { NEXTJS_AGENT_CONFIG } from '../nextjs/nextjs-wizard-agent';\nimport { NUXT_AGENT_CONFIG } from '../nuxt/nuxt-wizard-agent';\nimport { VUE_AGENT_CONFIG } from '../vue/vue-wizard-agent';\nimport { REACT_ROUTER_AGENT_CONFIG } from '../react-router/react-router-wizard-agent';\nimport { TANSTACK_ROUTER_AGENT_CONFIG } from '../tanstack-router/tanstack-router-wizard-agent';\nimport { TANSTACK_START_AGENT_CONFIG } from '../tanstack-start/tanstack-start-wizard-agent';\nimport { REACT_NATIVE_AGENT_CONFIG } from '../react-native/react-native-wizard-agent';\nimport { ANGULAR_AGENT_CONFIG } from '../angular/angular-wizard-agent';\nimport { ASTRO_AGENT_CONFIG } from '../astro/astro-wizard-agent';\nimport { DJANGO_AGENT_CONFIG } from '../django/django-wizard-agent';\nimport { FLASK_AGENT_CONFIG } from '../flask/flask-wizard-agent';\nimport { FASTAPI_AGENT_CONFIG } from '../fastapi/fastapi-wizard-agent';\nimport { LARAVEL_AGENT_CONFIG } from '../laravel/laravel-wizard-agent';\nimport { SVELTEKIT_AGENT_CONFIG } from '../svelte/svelte-wizard-agent';\nimport { SWIFT_AGENT_CONFIG } from '../swift/swift-wizard-agent';\nimport { ANDROID_AGENT_CONFIG } from '../android/android-wizard-agent';\nimport { PYTHON_AGENT_CONFIG } from '../python/python-wizard-agent';\n\nexport const FRAMEWORK_REGISTRY: Record<Integration, FrameworkConfig> = {\n [Integration.nextjs]: NEXTJS_AGENT_CONFIG,\n [Integration.nuxt]: NUXT_AGENT_CONFIG,\n [Integration.vue]: VUE_AGENT_CONFIG,\n [Integration.tanstackStart]: TANSTACK_START_AGENT_CONFIG,\n [Integration.reactRouter]: REACT_ROUTER_AGENT_CONFIG,\n [Integration.tanstackRouter]: TANSTACK_ROUTER_AGENT_CONFIG,\n [Integration.reactNative]: REACT_NATIVE_AGENT_CONFIG,\n [Integration.angular]: ANGULAR_AGENT_CONFIG,\n [Integration.astro]: ASTRO_AGENT_CONFIG,\n [Integration.django]: DJANGO_AGENT_CONFIG,\n [Integration.flask]: FLASK_AGENT_CONFIG,\n [Integration.fastapi]: FASTAPI_AGENT_CONFIG,\n [Integration.laravel]: LARAVEL_AGENT_CONFIG,\n [Integration.sveltekit]: SVELTEKIT_AGENT_CONFIG,\n [Integration.swift]: SWIFT_AGENT_CONFIG,\n [Integration.android]: ANDROID_AGENT_CONFIG,\n [Integration.python]: PYTHON_AGENT_CONFIG,\n};\n"]}
1
+ {"version":3,"file":"registry.js","sourceRoot":"","sources":["../../../src/lib/registry.ts"],"names":[],"mappings":";;;AACA,2CAA0C;AAC1C,uEAAoE;AACpE,iEAA8D;AAC9D,8DAA2D;AAC3D,yFAAsF;AACtF,kGAA+F;AAC/F,+FAA4F;AAC5F,yFAAsF;AACtF,0EAAuE;AACvE,oEAAiE;AACjE,uEAAoE;AACpE,oEAAiE;AACjE,0EAAuE;AACvE,0EAAuE;AACvE,uEAAuE;AACvE,oEAAiE;AACjE,0EAAuE;AACvE,oEAAiE;AACjE,uEAAoE;AACpE,iEAA8D;AAEjD,QAAA,kBAAkB,GAAyC;IACtE,CAAC,uBAAW,CAAC,MAAM,CAAC,EAAE,yCAAmB;IACzC,CAAC,uBAAW,CAAC,IAAI,CAAC,EAAE,qCAAiB;IACrC,CAAC,uBAAW,CAAC,GAAG,CAAC,EAAE,mCAAgB;IACnC,CAAC,uBAAW,CAAC,aAAa,CAAC,EAAE,yDAA2B;IACxD,CAAC,uBAAW,CAAC,WAAW,CAAC,EAAE,qDAAyB;IACpD,CAAC,uBAAW,CAAC,cAAc,CAAC,EAAE,2DAA4B;IAC1D,CAAC,uBAAW,CAAC,WAAW,CAAC,EAAE,qDAAyB;IACpD,CAAC,uBAAW,CAAC,OAAO,CAAC,EAAE,2CAAoB;IAC3C,CAAC,uBAAW,CAAC,KAAK,CAAC,EAAE,uCAAkB;IACvC,CAAC,uBAAW,CAAC,MAAM,CAAC,EAAE,yCAAmB;IACzC,CAAC,uBAAW,CAAC,KAAK,CAAC,EAAE,uCAAkB;IACvC,CAAC,uBAAW,CAAC,OAAO,CAAC,EAAE,2CAAoB;IAC3C,CAAC,uBAAW,CAAC,OAAO,CAAC,EAAE,2CAAoB;IAC3C,CAAC,uBAAW,CAAC,SAAS,CAAC,EAAE,4CAAsB;IAC/C,CAAC,uBAAW,CAAC,KAAK,CAAC,EAAE,uCAAkB;IACvC,CAAC,uBAAW,CAAC,OAAO,CAAC,EAAE,2CAAoB;IAC3C,CAAC,uBAAW,CAAC,KAAK,CAAC,EAAE,uCAAkB;IACvC,CAAC,uBAAW,CAAC,MAAM,CAAC,EAAE,yCAAmB;IACzC,CAAC,uBAAW,CAAC,IAAI,CAAC,EAAE,qCAAiB;CACtC,CAAC","sourcesContent":["import type { FrameworkConfig } from './framework-config';\nimport { Integration } from './constants';\nimport { NEXTJS_AGENT_CONFIG } from '../nextjs/nextjs-wizard-agent';\nimport { NUXT_AGENT_CONFIG } from '../nuxt/nuxt-wizard-agent';\nimport { VUE_AGENT_CONFIG } from '../vue/vue-wizard-agent';\nimport { REACT_ROUTER_AGENT_CONFIG } from '../react-router/react-router-wizard-agent';\nimport { TANSTACK_ROUTER_AGENT_CONFIG } from '../tanstack-router/tanstack-router-wizard-agent';\nimport { TANSTACK_START_AGENT_CONFIG } from '../tanstack-start/tanstack-start-wizard-agent';\nimport { REACT_NATIVE_AGENT_CONFIG } from '../react-native/react-native-wizard-agent';\nimport { ANGULAR_AGENT_CONFIG } from '../angular/angular-wizard-agent';\nimport { ASTRO_AGENT_CONFIG } from '../astro/astro-wizard-agent';\nimport { DJANGO_AGENT_CONFIG } from '../django/django-wizard-agent';\nimport { FLASK_AGENT_CONFIG } from '../flask/flask-wizard-agent';\nimport { FASTAPI_AGENT_CONFIG } from '../fastapi/fastapi-wizard-agent';\nimport { LARAVEL_AGENT_CONFIG } from '../laravel/laravel-wizard-agent';\nimport { SVELTEKIT_AGENT_CONFIG } from '../svelte/svelte-wizard-agent';\nimport { SWIFT_AGENT_CONFIG } from '../swift/swift-wizard-agent';\nimport { ANDROID_AGENT_CONFIG } from '../android/android-wizard-agent';\nimport { RAILS_AGENT_CONFIG } from '../rails/rails-wizard-agent';\nimport { PYTHON_AGENT_CONFIG } from '../python/python-wizard-agent';\nimport { RUBY_AGENT_CONFIG } from '../ruby/ruby-wizard-agent';\n\nexport const FRAMEWORK_REGISTRY: Record<Integration, FrameworkConfig> = {\n [Integration.nextjs]: NEXTJS_AGENT_CONFIG,\n [Integration.nuxt]: NUXT_AGENT_CONFIG,\n [Integration.vue]: VUE_AGENT_CONFIG,\n [Integration.tanstackStart]: TANSTACK_START_AGENT_CONFIG,\n [Integration.reactRouter]: REACT_ROUTER_AGENT_CONFIG,\n [Integration.tanstackRouter]: TANSTACK_ROUTER_AGENT_CONFIG,\n [Integration.reactNative]: REACT_NATIVE_AGENT_CONFIG,\n [Integration.angular]: ANGULAR_AGENT_CONFIG,\n [Integration.astro]: ASTRO_AGENT_CONFIG,\n [Integration.django]: DJANGO_AGENT_CONFIG,\n [Integration.flask]: FLASK_AGENT_CONFIG,\n [Integration.fastapi]: FASTAPI_AGENT_CONFIG,\n [Integration.laravel]: LARAVEL_AGENT_CONFIG,\n [Integration.sveltekit]: SVELTEKIT_AGENT_CONFIG,\n [Integration.swift]: SWIFT_AGENT_CONFIG,\n [Integration.android]: ANDROID_AGENT_CONFIG,\n [Integration.rails]: RAILS_AGENT_CONFIG,\n [Integration.python]: PYTHON_AGENT_CONFIG,\n [Integration.ruby]: RUBY_AGENT_CONFIG,\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":";;;AAGA,gFAAyE;AACzE,gDAA+C;AAC/C,mCAQiB;AAOJ,QAAA,kBAAkB,GAAkC;IAC/D,QAAQ,EAAE;QACR,IAAI,EAAE,eAAe;QACrB,WAAW,EAAE,uBAAW,CAAC,KAAK;QAC9B,IAAI,EAAE,IAAI;QACV,OAAO,EAAE,kDAAkD;QAC3D,yBAAyB,EAAE,yCAAyC;QACpE,aAAa,EAAE,CAAC,OAAsB,EAAE,EAAE;YACxC,MAAM,WAAW,GAAG,IAAA,2BAAmB,EAAC,OAAO,CAAC,CAAC;YACjD,MAAM,eAAe,GAAG,IAAA,2BAAmB,EAAC,OAAO,CAAC,CAAC;YACrD,OAAO,OAAO,CAAC,OAAO,CAAC,EAAE,WAAW,EAAE,eAAe,EAAE,CAAC,CAAC;QAC3D,CAAC;KACF;IAED,SAAS,EAAE;QACT,WAAW,EAAE,OAAO;QACpB,kBAAkB,EAAE,eAAe;QACnC,eAAe,EAAE,KAAK;QACtB,UAAU,EAAE,GAAG,EAAE,CAAC,SAAS;QAC3B,gBAAgB,EAAE,6BAAqB;QACvC,cAAc,EAAE,OAAO;QACvB,mBAAmB,EAAE,CAAC,OAAsB,EAAE,EAAE,CAC9C,OAAO,CAAC,OAAO,CAAC,IAAA,uBAAe,EAAC,OAAO,CAAC,CAAC;QAC3C,MAAM,EAAE,KAAK,EAAE,OAAO,EAAE,EAAE,CAAC,IAAA,sBAAc,EAAC,OAAO,CAAC;QAClD,oBAAoB,EAAE,iDAAqB;KAC5C;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,CAAC,CAAC;YACrB,WAAW,EAAE,OAAO,CAAC,WAAW,IAAI,SAAS;SAC9C,CAAC;KACH;IAED,OAAO,EAAE;QACP,oBAAoB,EAClB,uHAAuH;QACzH,mBAAmB,EACjB,wJAAwJ;QAC1J,yBAAyB,EAAE,CAAC,OAAO,EAAE,EAAE;YACrC,MAAM,eAAe,GAAG,OAAO,CAAC,WAAW;gBACzC,CAAC,CAAC,IAAA,+BAAuB,EAAC,OAAO,CAAC,WAAW,CAAC;gBAC9C,CAAC,CAAC,SAAS,CAAC;YAEd,MAAM,KAAK,GAAG;gBACZ,iBAAiB,eAAe,EAAE;gBAClC,kGAAkG;aACnG,CAAC;YAEF,IAAI,OAAO,CAAC,eAAe,EAAE,CAAC;gBAC5B,KAAK,CAAC,IAAI,CAAC,2BAA2B,OAAO,CAAC,eAAe,EAAE,CAAC,CAAC;YACnE,CAAC;YAED,IAAI,OAAO,CAAC,WAAW,KAAK,wBAAgB,CAAC,GAAG,EAAE,CAAC;gBACjD,KAAK,CAAC,IAAI,CACR,4EAA4E,CAC7E,CAAC;YACJ,CAAC;YAED,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,eAAe,GAAG,OAAO,CAAC,WAAW;gBACzC,CAAC,CAAC,IAAA,+BAAuB,EAAC,OAAO,CAAC,WAAW,CAAC;gBAC9C,CAAC,CAAC,OAAO,CAAC;YAEZ,MAAM,OAAO,GAAG;gBACd,iBAAiB,eAAe,oBAAoB;gBACpD,+DAA+D;gBAC/D,+DAA+D;gBAC/D,sEAAsE;aACvE,CAAC;YAEF,IAAI,OAAO,CAAC,WAAW,KAAK,wBAAgB,CAAC,GAAG,EAAE,CAAC;gBACjD,OAAO,CAAC,IAAI,CACV,uEAAuE,CACxE,CAAC;YACJ,CAAC;YAED,OAAO,OAAO,CAAC;QACjB,CAAC;QACD,iBAAiB,EAAE,GAAG,EAAE,CAAC;YACvB,6DAA6D;YAC7D,qDAAqD;YACrD,8CAA8C;YAC9C,uDAAuD;YACvD,8EAA8E;SAC/E;KACF;CACF,CAAC","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":"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","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"]}
@@ -0,0 +1,7 @@
1
+ import type { FrameworkConfig } from '../lib/framework-config';
2
+ import { RubyPackageManager } from './utils';
3
+ type RubyContext = {
4
+ packageManager?: RubyPackageManager;
5
+ };
6
+ export declare const RUBY_AGENT_CONFIG: FrameworkConfig<RubyContext>;
7
+ export {};
@@ -0,0 +1,113 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.RUBY_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.RUBY_AGENT_CONFIG = {
8
+ metadata: {
9
+ name: 'Ruby',
10
+ integration: constants_1.Integration.ruby,
11
+ beta: true,
12
+ docsUrl: 'https://posthog.com/docs/libraries/ruby',
13
+ gatherContext: (options) => {
14
+ const packageManager = (0, utils_1.detectPackageManager)(options);
15
+ return Promise.resolve({ packageManager });
16
+ },
17
+ },
18
+ detection: {
19
+ packageName: 'ruby',
20
+ packageDisplayName: 'Ruby',
21
+ usesPackageJson: false,
22
+ getVersion: () => undefined,
23
+ getVersionBucket: utils_1.getRubyVersionBucket,
24
+ minimumVersion: '2.7.0',
25
+ getInstalledVersion: (options) => Promise.resolve((0, utils_1.getRubyVersion)(options)),
26
+ detect: async (options) => (0, utils_1.isRubyProject)(options),
27
+ detectPackageManager: package_manager_detection_1.bundlerPackageManager,
28
+ },
29
+ environment: {
30
+ uploadToHosting: false,
31
+ getEnvVars: (apiKey, host) => ({
32
+ POSTHOG_API_KEY: apiKey,
33
+ POSTHOG_HOST: host,
34
+ }),
35
+ },
36
+ analytics: {
37
+ getTags: (context) => {
38
+ const packageManagerName = context.packageManager
39
+ ? (0, utils_1.getPackageManagerName)(context.packageManager)
40
+ : 'unknown';
41
+ return {
42
+ packageManager: packageManagerName,
43
+ };
44
+ },
45
+ },
46
+ prompts: {
47
+ projectTypeDetection: 'This is a Ruby project. Look for Gemfile, *.gemspec, .ruby-version, or *.rb files to confirm.',
48
+ packageInstallation: "Use Bundler if a Gemfile is present (add `gem 'posthog-ruby'` and run `bundle install`). Otherwise use `gem install posthog-ruby`. Do not pin a specific version.",
49
+ getAdditionalContextLines: (context) => {
50
+ const packageManagerName = context.packageManager
51
+ ? (0, utils_1.getPackageManagerName)(context.packageManager)
52
+ : 'unknown';
53
+ const lines = [
54
+ `Package manager: ${packageManagerName}`,
55
+ `Framework docs ID: ruby (use posthog://docs/frameworks/ruby for documentation)`,
56
+ `Project type: Generic Ruby application (CLI, script, gem, worker, etc.)`,
57
+ ``,
58
+ `## CRITICAL: Ruby PostHog Best Practices`,
59
+ ``,
60
+ `### 1. Gem Name vs Require`,
61
+ `The gem is named posthog-ruby but you require it as 'posthog':`,
62
+ ` gem 'posthog-ruby' # in Gemfile`,
63
+ ` require 'posthog' # in code (NOT require 'posthog-ruby')`,
64
+ ``,
65
+ `### 2. Use Instance-Based API (REQUIRED for scripts/CLIs)`,
66
+ `Use PostHog::Client.new for scripts and standalone applications:`,
67
+ ``,
68
+ `client = PostHog::Client.new(`,
69
+ ` api_key: ENV['POSTHOG_API_KEY'],`,
70
+ ` host: ENV['POSTHOG_HOST'] || 'https://us.i.posthog.com'`,
71
+ `)`,
72
+ ``,
73
+ `### 3. MUST Call shutdown Before Exit`,
74
+ `In scripts and CLIs, you MUST call client.shutdown or events will be lost:`,
75
+ ``,
76
+ `begin`,
77
+ ` client.capture(distinct_id: 'user_123', event: 'my_event')`,
78
+ `ensure`,
79
+ ` client.shutdown`,
80
+ `end`,
81
+ ``,
82
+ `### 4. capture_exception Takes Positional Args`,
83
+ `client.capture_exception(exception, distinct_id, additional_properties)`,
84
+ `Do NOT use keyword arguments for capture_exception.`,
85
+ ``,
86
+ `### 5. NEVER Send PII`,
87
+ `Do NOT include emails, names, phone numbers, or user content in event properties.`,
88
+ ];
89
+ return lines;
90
+ },
91
+ },
92
+ ui: {
93
+ successMessage: 'PostHog integration complete',
94
+ estimatedDurationMinutes: 5,
95
+ getOutroChanges: (context) => {
96
+ const packageManagerName = context.packageManager
97
+ ? (0, utils_1.getPackageManagerName)(context.packageManager)
98
+ : 'package manager';
99
+ return [
100
+ `Analyzed your Ruby project structure`,
101
+ `Installed the posthog-ruby gem using ${packageManagerName}`,
102
+ `Created PostHog initialization with instance-based API`,
103
+ `Configured shutdown handler for proper event flushing`,
104
+ ];
105
+ },
106
+ getOutroNextSteps: () => [
107
+ 'Use client.capture() for events and client.identify() for users',
108
+ 'Always call client.shutdown() before your application exits',
109
+ 'Visit your PostHog dashboard to see incoming events',
110
+ ],
111
+ },
112
+ };
113
+ //# sourceMappingURL=ruby-wizard-agent.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ruby-wizard-agent.js","sourceRoot":"","sources":["../../../src/ruby/ruby-wizard-agent.ts"],"names":[],"mappings":"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","sourcesContent":["/* Generic Ruby language 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 getRubyVersion,\n getRubyVersionBucket,\n detectPackageManager,\n getPackageManagerName,\n RubyPackageManager,\n isRubyProject,\n} from './utils';\n\ntype RubyContext = {\n packageManager?: RubyPackageManager;\n};\n\nexport const RUBY_AGENT_CONFIG: FrameworkConfig<RubyContext> = {\n metadata: {\n name: 'Ruby',\n integration: Integration.ruby,\n beta: true,\n docsUrl: 'https://posthog.com/docs/libraries/ruby',\n gatherContext: (options: WizardOptions) => {\n const packageManager = detectPackageManager(options);\n return Promise.resolve({ packageManager });\n },\n },\n\n detection: {\n packageName: 'ruby',\n packageDisplayName: 'Ruby',\n usesPackageJson: false,\n getVersion: () => undefined,\n getVersionBucket: getRubyVersionBucket,\n minimumVersion: '2.7.0',\n getInstalledVersion: (options: WizardOptions) =>\n Promise.resolve(getRubyVersion(options)),\n detect: async (options) => isRubyProject(options),\n detectPackageManager: bundlerPackageManager,\n },\n\n environment: {\n uploadToHosting: false,\n getEnvVars: (apiKey: string, host: string) => ({\n POSTHOG_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 Ruby project. Look for Gemfile, *.gemspec, .ruby-version, or *.rb files to confirm.',\n packageInstallation:\n \"Use Bundler if a Gemfile is present (add `gem 'posthog-ruby'` and run `bundle install`). Otherwise use `gem install posthog-ruby`. Do not pin a specific version.\",\n getAdditionalContextLines: (context) => {\n const packageManagerName = context.packageManager\n ? getPackageManagerName(context.packageManager)\n : 'unknown';\n\n const lines = [\n `Package manager: ${packageManagerName}`,\n `Framework docs ID: ruby (use posthog://docs/frameworks/ruby for documentation)`,\n `Project type: Generic Ruby application (CLI, script, gem, worker, etc.)`,\n ``,\n `## CRITICAL: Ruby PostHog Best Practices`,\n ``,\n `### 1. Gem Name vs Require`,\n `The gem is named posthog-ruby but you require it as 'posthog':`,\n ` gem 'posthog-ruby' # in Gemfile`,\n ` require 'posthog' # in code (NOT require 'posthog-ruby')`,\n ``,\n `### 2. Use Instance-Based API (REQUIRED for scripts/CLIs)`,\n `Use PostHog::Client.new for scripts and standalone applications:`,\n ``,\n `client = PostHog::Client.new(`,\n ` api_key: ENV['POSTHOG_API_KEY'],`,\n ` host: ENV['POSTHOG_HOST'] || 'https://us.i.posthog.com'`,\n `)`,\n ``,\n `### 3. MUST Call shutdown Before Exit`,\n `In scripts and CLIs, you MUST call client.shutdown or events will be lost:`,\n ``,\n `begin`,\n ` client.capture(distinct_id: 'user_123', event: 'my_event')`,\n `ensure`,\n ` client.shutdown`,\n `end`,\n ``,\n `### 4. capture_exception Takes Positional Args`,\n `client.capture_exception(exception, distinct_id, additional_properties)`,\n `Do NOT use keyword arguments for capture_exception.`,\n ``,\n `### 5. NEVER Send PII`,\n `Do NOT include emails, names, phone numbers, or user content in event properties.`,\n ];\n\n return lines;\n },\n },\n\n ui: {\n successMessage: 'PostHog integration complete',\n estimatedDurationMinutes: 5,\n getOutroChanges: (context) => {\n const packageManagerName = context.packageManager\n ? getPackageManagerName(context.packageManager)\n : 'package manager';\n return [\n `Analyzed your Ruby project structure`,\n `Installed the posthog-ruby gem using ${packageManagerName}`,\n `Created PostHog initialization with instance-based API`,\n `Configured shutdown handler for proper event flushing`,\n ];\n },\n getOutroNextSteps: () => [\n 'Use client.capture() for events and client.identify() for users',\n 'Always call client.shutdown() before your application exits',\n 'Visit your PostHog dashboard to see incoming events',\n ],\n },\n};\n"]}
@@ -0,0 +1,25 @@
1
+ import type { WizardOptions } from '../utils/types';
2
+ export declare enum RubyPackageManager {
3
+ BUNDLER = "bundler",
4
+ MANUAL = "manual"
5
+ }
6
+ /**
7
+ * Get Ruby version bucket for analytics
8
+ */
9
+ export declare const getRubyVersionBucket: (version: string | undefined) => string;
10
+ /**
11
+ * Detect Ruby package manager
12
+ */
13
+ export declare function detectPackageManager(options: Pick<WizardOptions, 'installDir'>): RubyPackageManager;
14
+ /**
15
+ * Get human-readable name for package manager
16
+ */
17
+ export declare function getPackageManagerName(packageManager: RubyPackageManager): string;
18
+ /**
19
+ * Get Ruby version from .ruby-version file or Gemfile
20
+ */
21
+ export declare function getRubyVersion(options: Pick<WizardOptions, 'installDir'>): string | undefined;
22
+ /**
23
+ * Check if the project is a Ruby project (but not Rails)
24
+ */
25
+ export declare function isRubyProject(options: Pick<WizardOptions, 'installDir'>): Promise<boolean>;
@@ -0,0 +1,158 @@
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.getRubyVersionBucket = exports.RubyPackageManager = void 0;
40
+ exports.detectPackageManager = detectPackageManager;
41
+ exports.getPackageManagerName = getPackageManagerName;
42
+ exports.getRubyVersion = getRubyVersion;
43
+ exports.isRubyProject = isRubyProject;
44
+ const fast_glob_1 = __importDefault(require("fast-glob"));
45
+ const semver_1 = require("../utils/semver");
46
+ const fs = __importStar(require("node:fs"));
47
+ const path = __importStar(require("node:path"));
48
+ var RubyPackageManager;
49
+ (function (RubyPackageManager) {
50
+ RubyPackageManager["BUNDLER"] = "bundler";
51
+ RubyPackageManager["MANUAL"] = "manual";
52
+ })(RubyPackageManager || (exports.RubyPackageManager = RubyPackageManager = {}));
53
+ const IGNORE_PATTERNS = [
54
+ '**/node_modules/**',
55
+ '**/vendor/**',
56
+ '**/vendor/bundle/**',
57
+ '**/tmp/**',
58
+ '**/log/**',
59
+ ];
60
+ /**
61
+ * Get Ruby version bucket for analytics
62
+ */
63
+ exports.getRubyVersionBucket = (0, semver_1.createVersionBucket)();
64
+ /**
65
+ * Detect Ruby package manager
66
+ */
67
+ function detectPackageManager(options) {
68
+ const { installDir } = options;
69
+ const gemfilePath = path.join(installDir, 'Gemfile');
70
+ if (fs.existsSync(gemfilePath)) {
71
+ return RubyPackageManager.BUNDLER;
72
+ }
73
+ return RubyPackageManager.MANUAL;
74
+ }
75
+ /**
76
+ * Get human-readable name for package manager
77
+ */
78
+ function getPackageManagerName(packageManager) {
79
+ switch (packageManager) {
80
+ case RubyPackageManager.BUNDLER:
81
+ return 'Bundler';
82
+ case RubyPackageManager.MANUAL:
83
+ return 'gem install';
84
+ }
85
+ }
86
+ /**
87
+ * Get Ruby version from .ruby-version file or Gemfile
88
+ */
89
+ function getRubyVersion(options) {
90
+ const { installDir } = options;
91
+ // Check .ruby-version file
92
+ const rubyVersionPath = path.join(installDir, '.ruby-version');
93
+ try {
94
+ const content = fs.readFileSync(rubyVersionPath, 'utf-8').trim();
95
+ // Remove "ruby-" prefix if present
96
+ const version = content.replace(/^ruby-/, '');
97
+ if (/^[0-9]+\.[0-9]+/.test(version)) {
98
+ return version;
99
+ }
100
+ }
101
+ catch {
102
+ // Continue to other checks
103
+ }
104
+ // Check Gemfile for ruby version declaration
105
+ const gemfilePath = path.join(installDir, 'Gemfile');
106
+ try {
107
+ const content = fs.readFileSync(gemfilePath, 'utf-8');
108
+ const match = content.match(/ruby\s+['"]([0-9]+\.[0-9]+(?:\.[0-9]+)?)['"]/);
109
+ if (match) {
110
+ return match[1];
111
+ }
112
+ }
113
+ catch {
114
+ // No Gemfile
115
+ }
116
+ return undefined;
117
+ }
118
+ /**
119
+ * Check if the project is a Ruby project (but not Rails)
120
+ */
121
+ async function isRubyProject(options) {
122
+ const { installDir } = options;
123
+ // Check for Gemfile
124
+ const gemfilePath = path.join(installDir, 'Gemfile');
125
+ if (fs.existsSync(gemfilePath)) {
126
+ // Make sure this isn't a Rails project (Rails should be detected first)
127
+ try {
128
+ const content = fs.readFileSync(gemfilePath, 'utf-8');
129
+ if (/^\s*gem\s+['"]rails['"]/im.test(content)) {
130
+ return false; // Rails project, use rails agent instead
131
+ }
132
+ }
133
+ catch {
134
+ // Continue checking
135
+ }
136
+ return true;
137
+ }
138
+ // Check for .ruby-version file
139
+ const rubyVersionPath = path.join(installDir, '.ruby-version');
140
+ if (fs.existsSync(rubyVersionPath)) {
141
+ return true;
142
+ }
143
+ // Check for *.gemspec files
144
+ const gemspecFiles = await (0, fast_glob_1.default)('*.gemspec', {
145
+ cwd: installDir,
146
+ ignore: IGNORE_PATTERNS,
147
+ });
148
+ if (gemspecFiles.length > 0) {
149
+ return true;
150
+ }
151
+ // Check for Ruby source files in the root
152
+ const rubyFiles = await (0, fast_glob_1.default)(['*.rb', 'lib/**/*.rb', 'bin/**/*.rb'], {
153
+ cwd: installDir,
154
+ ignore: IGNORE_PATTERNS,
155
+ });
156
+ return rubyFiles.length > 0;
157
+ }
158
+ //# sourceMappingURL=utils.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"utils.js","sourceRoot":"","sources":["../../../src/ruby/utils.ts"],"names":[],"mappings":"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","sourcesContent":["import fg from 'fast-glob';\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 RubyPackageManager {\n BUNDLER = 'bundler',\n MANUAL = 'manual',\n}\n\nconst IGNORE_PATTERNS = [\n '**/node_modules/**',\n '**/vendor/**',\n '**/vendor/bundle/**',\n '**/tmp/**',\n '**/log/**',\n];\n\n/**\n * Get Ruby version bucket for analytics\n */\nexport const getRubyVersionBucket = createVersionBucket();\n\n/**\n * Detect Ruby package manager\n */\nexport function detectPackageManager(\n options: Pick<WizardOptions, 'installDir'>,\n): RubyPackageManager {\n const { installDir } = options;\n\n const gemfilePath = path.join(installDir, 'Gemfile');\n if (fs.existsSync(gemfilePath)) {\n return RubyPackageManager.BUNDLER;\n }\n\n return RubyPackageManager.MANUAL;\n}\n\n/**\n * Get human-readable name for package manager\n */\nexport function getPackageManagerName(\n packageManager: RubyPackageManager,\n): string {\n switch (packageManager) {\n case RubyPackageManager.BUNDLER:\n return 'Bundler';\n case RubyPackageManager.MANUAL:\n return 'gem install';\n }\n}\n\n/**\n * Get Ruby version from .ruby-version file or Gemfile\n */\nexport function getRubyVersion(\n options: Pick<WizardOptions, 'installDir'>,\n): string | undefined {\n const { installDir } = options;\n\n // Check .ruby-version file\n const rubyVersionPath = path.join(installDir, '.ruby-version');\n try {\n const content = fs.readFileSync(rubyVersionPath, 'utf-8').trim();\n // Remove \"ruby-\" prefix if present\n const version = content.replace(/^ruby-/, '');\n if (/^[0-9]+\\.[0-9]+/.test(version)) {\n return version;\n }\n } catch {\n // Continue to other checks\n }\n\n // Check Gemfile for ruby version declaration\n const gemfilePath = path.join(installDir, 'Gemfile');\n try {\n const content = fs.readFileSync(gemfilePath, 'utf-8');\n const match = content.match(/ruby\\s+['\"]([0-9]+\\.[0-9]+(?:\\.[0-9]+)?)['\"]/);\n if (match) {\n return match[1];\n }\n } catch {\n // No Gemfile\n }\n\n return undefined;\n}\n\n/**\n * Check if the project is a Ruby project (but not Rails)\n */\nexport async function isRubyProject(\n options: Pick<WizardOptions, 'installDir'>,\n): Promise<boolean> {\n const { installDir } = options;\n\n // Check for Gemfile\n const gemfilePath = path.join(installDir, 'Gemfile');\n if (fs.existsSync(gemfilePath)) {\n // Make sure this isn't a Rails project (Rails should be detected first)\n try {\n const content = fs.readFileSync(gemfilePath, 'utf-8');\n if (/^\\s*gem\\s+['\"]rails['\"]/im.test(content)) {\n return false; // Rails project, use rails agent instead\n }\n } catch {\n // Continue checking\n }\n return true;\n }\n\n // Check for .ruby-version file\n const rubyVersionPath = path.join(installDir, '.ruby-version');\n if (fs.existsSync(rubyVersionPath)) {\n return true;\n }\n\n // Check for *.gemspec files\n const gemspecFiles = await fg('*.gemspec', {\n cwd: installDir,\n ignore: IGNORE_PATTERNS,\n });\n\n if (gemspecFiles.length > 0) {\n return true;\n }\n\n // Check for Ruby source files in the root\n const rubyFiles = await fg(['*.rb', 'lib/**/*.rb', 'bin/**/*.rb'], {\n cwd: installDir,\n ignore: IGNORE_PATTERNS,\n });\n\n return rubyFiles.length > 0;\n}\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@posthog/wizard",
3
- "version": "1.33.0",
3
+ "version": "1.34.0",
4
4
  "homepage": "https://github.com/PostHog/wizard",
5
5
  "repository": "https://github.com/PostHog/wizard",
6
6
  "description": "The PostHog wizard helps you to configure your project",