@posthog/wizard 1.8.7 → 1.10.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/bin.js CHANGED
@@ -8,6 +8,7 @@ const semver_1 = require("semver");
8
8
  const logging_1 = require("./src/utils/logging");
9
9
  const yargs_1 = __importDefault(require("yargs"));
10
10
  const helpers_1 = require("yargs/helpers");
11
+ const chalk_1 = __importDefault(require("chalk"));
11
12
  const NODE_VERSION_RANGE = '>=18.17.0';
12
13
  // Have to run this above the other imports because they are importing clack that
13
14
  // has the problematic imports.
@@ -17,6 +18,17 @@ if (!(0, semver_1.satisfies)(process.version, NODE_VERSION_RANGE)) {
17
18
  }
18
19
  const mcp_1 = require("./src/mcp");
19
20
  const run_1 = require("./src/run");
21
+ const event_setup_1 = require("./src/nextjs/event-setup");
22
+ const environment_1 = require("./src/utils/environment");
23
+ const path_1 = __importDefault(require("path"));
24
+ const clack_1 = __importDefault(require("./src/utils/clack"));
25
+ if ((0, environment_1.isNonInteractiveEnvironment)()) {
26
+ clack_1.default.intro(chalk_1.default.inverse(`PostHog Wizard`));
27
+ clack_1.default.log.error('This installer requires an interactive terminal (TTY) to run.\n' +
28
+ 'It appears you are running in a non-interactive environment.\n' +
29
+ 'Please run the wizard in an interactive terminal.');
30
+ process.exit(1);
31
+ }
20
32
  if (process.env.NODE_ENV === 'test') {
21
33
  void (async () => {
22
34
  try {
@@ -75,6 +87,40 @@ if (process.env.NODE_ENV === 'test') {
75
87
  }, (argv) => {
76
88
  const options = { ...argv };
77
89
  void (0, run_1.runWizard)(options);
90
+ })
91
+ .command('event-setup', 'Run the event setup wizard', (yargs) => {
92
+ return yargs.options({
93
+ 'install-dir': {
94
+ describe: 'Directory to run the wizard in\nenv: POSTHOG_WIZARD_INSTALL_DIR',
95
+ type: 'string',
96
+ },
97
+ });
98
+ }, (argv) => {
99
+ const finalArgs = {
100
+ ...argv,
101
+ ...(0, environment_1.readEnvironment)(),
102
+ };
103
+ let resolvedInstallDir;
104
+ if (finalArgs.installDir) {
105
+ if (path_1.default.isAbsolute(finalArgs.installDir)) {
106
+ resolvedInstallDir = finalArgs.installDir;
107
+ }
108
+ else {
109
+ resolvedInstallDir = path_1.default.join(process.cwd(), finalArgs.installDir);
110
+ }
111
+ }
112
+ else {
113
+ resolvedInstallDir = process.cwd();
114
+ }
115
+ const wizardOptions = {
116
+ debug: finalArgs.debug ?? false,
117
+ installDir: resolvedInstallDir,
118
+ cloudRegion: finalArgs.region,
119
+ default: finalArgs.default ?? false,
120
+ signup: finalArgs.signup ?? false,
121
+ forceInstall: false,
122
+ };
123
+ void (0, event_setup_1.runEventSetupWizard)(wizardOptions);
78
124
  })
79
125
  .command('mcp <command>', 'MCP server management commands', (yargs) => {
80
126
  return yargs
package/dist/bin.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"bin.js","sourceRoot":"","sources":["../bin.ts"],"names":[],"mappings":"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","sourcesContent":["#!/usr/bin/env node\nimport { satisfies } from 'semver';\nimport { red } from './src/utils/logging';\n\nimport yargs from 'yargs';\nimport { hideBin } from 'yargs/helpers';\n\nconst NODE_VERSION_RANGE = '>=18.17.0';\n\n// Have to run this above the other imports because they are importing clack that\n// has the problematic imports.\nif (!satisfies(process.version, NODE_VERSION_RANGE)) {\n red(\n `PostHog wizard requires Node.js ${NODE_VERSION_RANGE}. You are using Node.js ${process.version}. Please upgrade your Node.js version.`,\n );\n process.exit(1);\n}\n\nimport { runMCPInstall, runMCPRemove } from './src/mcp';\nimport type { CloudRegion, WizardOptions } from './src/utils/types';\nimport { runWizard } from './src/run';\n\nif (process.env.NODE_ENV === 'test') {\n void (async () => {\n try {\n const { server } = await import('./e2e-tests/mocks/server.js');\n server.listen({\n onUnhandledRequest: 'bypass',\n });\n } catch (error) {\n // Mock server import failed - this can happen during non-E2E tests\n }\n })();\n}\n\nyargs(hideBin(process.argv))\n .env('POSTHOG_WIZARD')\n // global options\n .options({\n debug: {\n default: false,\n describe: 'Enable verbose logging\\nenv: POSTHOG_WIZARD_DEBUG',\n type: 'boolean',\n },\n region: {\n describe: 'PostHog cloud region\\nenv: POSTHOG_WIZARD_REGION',\n choices: ['us', 'eu'],\n type: 'string',\n },\n default: {\n default: true,\n describe:\n 'Use default options for all prompts\\nenv: POSTHOG_WIZARD_DEFAULT',\n type: 'boolean',\n },\n signup: {\n default: false,\n describe:\n 'Create a new PostHog account during setup\\nenv: POSTHOG_WIZARD_SIGNUP',\n type: 'boolean',\n },\n })\n .command(\n ['$0'],\n 'Run the PostHog setup wizard',\n (yargs) => {\n return yargs.options({\n 'force-install': {\n default: false,\n describe:\n 'Force install packages even if peer dependency checks fail\\nenv: POSTHOG_WIZARD_FORCE_INSTALL',\n type: 'boolean',\n },\n 'install-dir': {\n describe:\n 'Directory to install PostHog in\\nenv: POSTHOG_WIZARD_INSTALL_DIR',\n type: 'string',\n },\n integration: {\n describe: 'Integration to set up',\n choices: ['nextjs', 'astro', 'react', 'svelte', 'react-native'],\n type: 'string',\n },\n });\n },\n (argv) => {\n const options = { ...argv };\n void runWizard(options as unknown as WizardOptions);\n },\n )\n .command('mcp <command>', 'MCP server management commands', (yargs) => {\n return yargs\n .command(\n 'add',\n 'Install PostHog MCP server to supported clients',\n (yargs) => {\n return yargs.options({});\n },\n (argv) => {\n const options = { ...argv };\n void runMCPInstall(\n options as unknown as { signup: boolean; region?: CloudRegion },\n );\n },\n )\n .command(\n 'remove',\n 'Remove PostHog MCP server from supported clients',\n (yargs) => {\n return yargs.options({});\n },\n () => {\n void runMCPRemove();\n },\n )\n .demandCommand(1, 'You must specify a subcommand (add or remove)')\n .help();\n })\n .help()\n .alias('help', 'h')\n .version()\n .alias('version', 'v')\n .wrap(process.stdout.isTTY ? yargs.terminalWidth() : 80).argv;\n"]}
1
+ {"version":3,"file":"bin.js","sourceRoot":"","sources":["../bin.ts"],"names":[],"mappings":"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","sourcesContent":["#!/usr/bin/env node\nimport { satisfies } from 'semver';\nimport { red } from './src/utils/logging';\n\nimport yargs from 'yargs';\nimport { hideBin } from 'yargs/helpers';\nimport chalk from 'chalk';\n\nconst NODE_VERSION_RANGE = '>=18.17.0';\n\n// Have to run this above the other imports because they are importing clack that\n// has the problematic imports.\nif (!satisfies(process.version, NODE_VERSION_RANGE)) {\n red(\n `PostHog wizard requires Node.js ${NODE_VERSION_RANGE}. You are using Node.js ${process.version}. Please upgrade your Node.js version.`,\n );\n process.exit(1);\n}\n\nimport { runMCPInstall, runMCPRemove } from './src/mcp';\nimport type { CloudRegion, WizardOptions } from './src/utils/types';\nimport { runWizard } from './src/run';\nimport { runEventSetupWizard } from './src/nextjs/event-setup';\nimport {\n readEnvironment,\n isNonInteractiveEnvironment,\n} from './src/utils/environment';\nimport path from 'path';\nimport clack from './src/utils/clack';\n\nif (isNonInteractiveEnvironment()) {\n clack.intro(chalk.inverse(`PostHog Wizard`));\n\n clack.log.error(\n 'This installer requires an interactive terminal (TTY) to run.\\n' +\n 'It appears you are running in a non-interactive environment.\\n' +\n 'Please run the wizard in an interactive terminal.',\n );\n process.exit(1);\n}\n\nif (process.env.NODE_ENV === 'test') {\n void (async () => {\n try {\n const { server } = await import('./e2e-tests/mocks/server.js');\n server.listen({\n onUnhandledRequest: 'bypass',\n });\n } catch (error) {\n // Mock server import failed - this can happen during non-E2E tests\n }\n })();\n}\n\nyargs(hideBin(process.argv))\n .env('POSTHOG_WIZARD')\n // global options\n .options({\n debug: {\n default: false,\n describe: 'Enable verbose logging\\nenv: POSTHOG_WIZARD_DEBUG',\n type: 'boolean',\n },\n region: {\n describe: 'PostHog cloud region\\nenv: POSTHOG_WIZARD_REGION',\n choices: ['us', 'eu'],\n type: 'string',\n },\n default: {\n default: true,\n describe:\n 'Use default options for all prompts\\nenv: POSTHOG_WIZARD_DEFAULT',\n type: 'boolean',\n },\n signup: {\n default: false,\n describe:\n 'Create a new PostHog account during setup\\nenv: POSTHOG_WIZARD_SIGNUP',\n type: 'boolean',\n },\n })\n .command(\n ['$0'],\n 'Run the PostHog setup wizard',\n (yargs) => {\n return yargs.options({\n 'force-install': {\n default: false,\n describe:\n 'Force install packages even if peer dependency checks fail\\nenv: POSTHOG_WIZARD_FORCE_INSTALL',\n type: 'boolean',\n },\n 'install-dir': {\n describe:\n 'Directory to install PostHog in\\nenv: POSTHOG_WIZARD_INSTALL_DIR',\n type: 'string',\n },\n integration: {\n describe: 'Integration to set up',\n choices: ['nextjs', 'astro', 'react', 'svelte', 'react-native'],\n type: 'string',\n },\n });\n },\n (argv) => {\n const options = { ...argv };\n void runWizard(options as unknown as WizardOptions);\n },\n )\n .command(\n 'event-setup',\n 'Run the event setup wizard',\n (yargs) => {\n return yargs.options({\n 'install-dir': {\n describe:\n 'Directory to run the wizard in\\nenv: POSTHOG_WIZARD_INSTALL_DIR',\n type: 'string',\n },\n });\n },\n (argv) => {\n const finalArgs = {\n ...argv,\n ...readEnvironment(),\n } as any;\n\n let resolvedInstallDir: string;\n if (finalArgs.installDir) {\n if (path.isAbsolute(finalArgs.installDir)) {\n resolvedInstallDir = finalArgs.installDir;\n } else {\n resolvedInstallDir = path.join(process.cwd(), finalArgs.installDir);\n }\n } else {\n resolvedInstallDir = process.cwd();\n }\n\n const wizardOptions: WizardOptions = {\n debug: finalArgs.debug ?? false,\n installDir: resolvedInstallDir,\n cloudRegion: finalArgs.region as CloudRegion | undefined,\n default: finalArgs.default ?? false,\n signup: finalArgs.signup ?? false,\n forceInstall: false,\n };\n\n void runEventSetupWizard(wizardOptions);\n },\n )\n .command('mcp <command>', 'MCP server management commands', (yargs) => {\n return yargs\n .command(\n 'add',\n 'Install PostHog MCP server to supported clients',\n (yargs) => {\n return yargs.options({});\n },\n (argv) => {\n const options = { ...argv };\n void runMCPInstall(\n options as unknown as { signup: boolean; region?: CloudRegion },\n );\n },\n )\n .command(\n 'remove',\n 'Remove PostHog MCP server from supported clients',\n (yargs) => {\n return yargs.options({});\n },\n () => {\n void runMCPRemove();\n },\n )\n .demandCommand(1, 'You must specify a subcommand (add or remove)')\n .help();\n })\n .help()\n .alias('help', 'h')\n .version()\n .alias('version', 'v')\n .wrap(process.stdout.isTTY ? yargs.terminalWidth() : 80).argv;\n"]}
@@ -0,0 +1,2 @@
1
+ import { WizardOptions } from '../utils/types';
2
+ export declare function runEventSetupWizard(options: WizardOptions): Promise<void>;
@@ -0,0 +1,388 @@
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.runEventSetupWizard = runEventSetupWizard;
40
+ const clack_utils_1 = require("../utils/clack-utils");
41
+ const clack_1 = __importDefault(require("../utils/clack"));
42
+ const fs = __importStar(require("fs/promises"));
43
+ const path = __importStar(require("path"));
44
+ const chalk_1 = __importDefault(require("chalk"));
45
+ const query_1 = require("../utils/query");
46
+ const zod_1 = require("zod");
47
+ const file_utils_1 = require("../utils/file-utils");
48
+ const package_json_1 = require("../utils/package-json");
49
+ const semver = __importStar(require("semver"));
50
+ const debug_1 = require("../utils/debug");
51
+ const analytics_1 = require("../utils/analytics");
52
+ // Analytics constants
53
+ const WIZARD_INTERACTION = 'wizard interaction';
54
+ const INTEGRATION_NAME = 'event-setup';
55
+ // Schema for file selection from AI
56
+ const FileSelectionSchema = zod_1.z.object({
57
+ files: zod_1.z.array(zod_1.z.string()).max(10),
58
+ });
59
+ // Schema for enhanced file with events
60
+ const EnhancedFileSchema = zod_1.z.object({
61
+ filePath: zod_1.z.string(),
62
+ content: zod_1.z.string(),
63
+ events: zod_1.z.array(zod_1.z.object({
64
+ name: zod_1.z.string(),
65
+ description: zod_1.z.string(),
66
+ })),
67
+ });
68
+ async function runEventSetupWizard(options) {
69
+ if (options.debug) {
70
+ (0, debug_1.enableDebugLogs)();
71
+ }
72
+ clack_1.default.intro(`Let's do a first pass on PostHog event tracking for your project.
73
+
74
+ We'll start by analyzing your project structure, then choose up to ten files to enhance. Use git to discard any events you're not happy with.
75
+
76
+ This will give you a starting point, then you can add any events that we missed.
77
+ `);
78
+ // Check for uncommitted changes
79
+ if ((0, clack_utils_1.isInGitRepo)()) {
80
+ const uncommittedOrUntrackedFiles = (0, clack_utils_1.getUncommittedOrUntrackedFiles)();
81
+ if (uncommittedOrUntrackedFiles.length) {
82
+ clack_1.default.log.warn(`You have uncommitted or untracked files in your repo:
83
+
84
+ ${uncommittedOrUntrackedFiles.join('\n')}
85
+
86
+ The event setup wizard will modify multiple files. For the best experience, commit or stash your changes first.`);
87
+ const continueWithDirtyRepo = await (0, clack_utils_1.abortIfCancelled)(clack_1.default.confirm({
88
+ message: 'Do you want to continue anyway?',
89
+ }));
90
+ if (!continueWithDirtyRepo) {
91
+ analytics_1.analytics.capture(WIZARD_INTERACTION, {
92
+ action: 'aborted due to uncommitted changes',
93
+ integration: INTEGRATION_NAME,
94
+ });
95
+ return (0, clack_utils_1.abort)('Please commit your changes and try again.', 0);
96
+ }
97
+ analytics_1.analytics.capture(WIZARD_INTERACTION, {
98
+ action: 'continued with uncommitted changes',
99
+ integration: INTEGRATION_NAME,
100
+ });
101
+ }
102
+ }
103
+ const cloudRegion = options.cloudRegion ?? (await (0, clack_utils_1.askForCloudRegion)());
104
+ const { wizardHash } = await (0, clack_utils_1.getOrAskForProjectData)({
105
+ ...options,
106
+ cloudRegion,
107
+ });
108
+ // Check if this is a Next.js 15.3+ project with instrumentation-client
109
+ const packageJson = await (0, clack_utils_1.getPackageDotJson)(options);
110
+ const isNextJs = (0, package_json_1.hasPackageInstalled)('next', packageJson);
111
+ if (!isNextJs) {
112
+ return (0, clack_utils_1.abort)('This feature is only available for Next.js projects.');
113
+ }
114
+ const nextVersion = (0, package_json_1.getPackageVersion)('next', packageJson);
115
+ const isNext15_3Plus = nextVersion && semver.gte(nextVersion, '15.3.0');
116
+ analytics_1.analytics.setTag('nextjs-version', nextVersion);
117
+ if (!isNext15_3Plus) {
118
+ analytics_1.analytics.capture(WIZARD_INTERACTION, {
119
+ action: 'aborted due to nextjs version',
120
+ integration: INTEGRATION_NAME,
121
+ nextjsVersion: nextVersion,
122
+ });
123
+ return (0, clack_utils_1.abort)('This feature requires Next.js 15.3.0 or higher.');
124
+ }
125
+ // Check for instrumentation-client file
126
+ const allFiles = await (0, file_utils_1.getAllFilesInProject)(options.installDir);
127
+ const instrumentationFiles = allFiles.filter((f) => f.includes('instrumentation') &&
128
+ (f.endsWith('.ts') || f.endsWith('.js')) &&
129
+ (f.includes('client') || f.includes('Client')));
130
+ if (instrumentationFiles.length === 0) {
131
+ analytics_1.analytics.capture(WIZARD_INTERACTION, {
132
+ action: 'aborted due to missing instrumentation-client',
133
+ integration: INTEGRATION_NAME,
134
+ });
135
+ return (0, clack_utils_1.abort)('No instrumentation-client file found. Please set up Next.js instrumentation-client first. Try using this wizard to do it!');
136
+ }
137
+ analytics_1.analytics.capture(WIZARD_INTERACTION, {
138
+ action: 'started event setup',
139
+ integration: INTEGRATION_NAME,
140
+ instrumentationFilesCount: instrumentationFiles.length,
141
+ });
142
+ // Get the project file tree
143
+ const s = clack_1.default.spinner();
144
+ s.start('Analyzing your project structure');
145
+ const projectFiles = await (0, file_utils_1.getAllFilesInProject)(options.installDir);
146
+ const relativeFiles = projectFiles
147
+ .map((f) => path.relative(options.installDir, f))
148
+ .filter((f) => {
149
+ // Exclude instrumentation files and next.config
150
+ const isInstrumentation = f.includes('instrumentation') &&
151
+ (f.endsWith('.ts') || f.endsWith('.js'));
152
+ const isNextConfig = f.startsWith('next.config.') || f === 'next.config';
153
+ return !isInstrumentation && !isNextConfig;
154
+ });
155
+ (0, debug_1.debug)('Total files found:', projectFiles.length);
156
+ (0, debug_1.debug)('Files after filtering:', relativeFiles.length);
157
+ s.stop('Project structure analyzed');
158
+ analytics_1.analytics.capture(WIZARD_INTERACTION, {
159
+ action: 'analyzed project structure',
160
+ integration: INTEGRATION_NAME,
161
+ totalFiles: projectFiles.length,
162
+ eligibleFiles: relativeFiles.length,
163
+ });
164
+ // Send file tree to AI to get 10 most useful files
165
+ s.start('Selecting some files to enhance with events...');
166
+ const fileSelectionPrompt = `Given this Next.js 15.3+ project structure and package.json, select up to 10 CLIENT-SIDE FILES for adding PostHog analytics events.
167
+
168
+ IMPORTANT: Only select files that:
169
+ - Have "use client" directive at the top, OR
170
+ - Use React hooks (useState, useEffect, etc.), OR
171
+ - Have event handlers (onClick, onSubmit, onChange)
172
+
173
+ DO NOT select:
174
+ - API routes (files in /api/ or route.ts/route.js files)
175
+ - Server Components (files without "use client" and no hooks/handlers)
176
+ - Layout files (layout.tsx/layout.js)
177
+ - Configuration files
178
+ - Pure utility files
179
+
180
+ Focus on:
181
+ - User interaction points (buttons, forms, navigation)
182
+ - Key user flows (auth, checkout, main features)
183
+ - Business-critical paths
184
+ - Files that represent important user actions
185
+
186
+ Package.json:
187
+ ${JSON.stringify(packageJson, null, 2)}
188
+
189
+ Project files:
190
+ ${relativeFiles.join('\n')}
191
+
192
+ Return file paths for client-side files ONLY that would benefit most from analytics tracking. If there are fewer than 10 suitable client files, return only those.`;
193
+ let selectedFiles = [];
194
+ try {
195
+ const response = await (0, query_1.query)({
196
+ message: fileSelectionPrompt,
197
+ model: 'gemini-2.5-flash',
198
+ region: cloudRegion,
199
+ schema: FileSelectionSchema,
200
+ wizardHash,
201
+ });
202
+ selectedFiles = response.files;
203
+ s.stop(`Selected ${selectedFiles.length} files for event tracking`);
204
+ analytics_1.analytics.capture(WIZARD_INTERACTION, {
205
+ action: 'selected files for tracking',
206
+ integration: INTEGRATION_NAME,
207
+ filesSelected: selectedFiles.length,
208
+ });
209
+ }
210
+ catch (error) {
211
+ s.stop('Failed to select files');
212
+ analytics_1.analytics.capture(WIZARD_INTERACTION, {
213
+ action: 'file selection failed',
214
+ integration: INTEGRATION_NAME,
215
+ error: error instanceof Error ? error.message : 'Unknown error',
216
+ });
217
+ return (0, clack_utils_1.abort)('Could not analyze project structure. Please try again.');
218
+ }
219
+ // Read the selected files and enhance them with events
220
+ clack_1.default.log.info('Files selected for event tracking:');
221
+ selectedFiles.forEach((file, index) => {
222
+ clack_1.default.log.info(` ${index + 1}. ${file}`);
223
+ });
224
+ const enhancedFiles = [];
225
+ clack_1.default.log.info("\nEnhancing files with event tracking. Changes will be applied as they come in. Use your git interface to review new events. Feel free to toss anything you don't like...");
226
+ for (const filePath of selectedFiles) {
227
+ const fileSpinner = clack_1.default.spinner();
228
+ fileSpinner.start(`Analyzing ${filePath}`);
229
+ try {
230
+ const fullPath = path.join(options.installDir, filePath);
231
+ const fileContent = await fs.readFile(fullPath, 'utf8');
232
+ const enhancePrompt = `You are enhancing a REAL production, client-side Next.js file with PostHog analytics. This is NOT an example or tutorial - add events to the ACTUAL code provided.
233
+
234
+ - REQUIRED: import posthog from 'posthog-js'
235
+ - Track events with: posthog.capture('event-name', { property: 'value' })
236
+ - NEVER import PostHogClient from '@/app/posthog'
237
+ - NEVER create functions with 'use server'
238
+
239
+ CRITICAL INSTRUCTIONS:
240
+ - This is a REAL file from a production codebase
241
+ - DO NOT add placeholder comments like "// In a real app..." or "// This is an example..."
242
+ - DO NOT modify the existing business logic or add simulation code
243
+ - DO NOT add any tutorial-style comments
244
+ - ONLY add PostHog event tracking to the existing, real functionality
245
+ - DO NOT create wrapper functions around existing functions just to add tracking
246
+ - Add tracking code directly inside existing functions where appropriate
247
+ - NEVER import new packages or libraries that aren't already used in the file
248
+ - ONLY use imports that already exist in the file or the PostHog imports specified
249
+ - DO NOT assume any authentication library (Clerk, Auth.js, etc.) is available
250
+
251
+ FORBIDDEN - NEVER DO THESE:
252
+ - NEVER add 'use client' or 'use server' directives at the top of the file, or in functions
253
+ - NEVER define new server actions (functions with "use server") in Client Components
254
+ - NEVER create inline "use server" functions in files that have "use client"
255
+ - NEVER use useEffect to track page views or component renders
256
+ - NEVER track events like "page_viewed", "form_viewed", "component_rendered", "flow_started", "page_opened" etc
257
+ - NEVER track that someone simply arrived at or viewed a page
258
+ - NEVER change the file's existing client/server architecture
259
+ - NEVER add events on component mount or render - only on actual user interactions
260
+ - Track events on user interactions like clicks, form submissions, etc.
261
+
262
+ Technical Rules:
263
+ - This is a client-side file suitable for event tracking
264
+ - REQUIRED IMPORT: import posthog from 'posthog-js'
265
+ - Use the existing posthog instance for all tracking
266
+ - Example: posthog.capture('button-clicked', { buttonId: 'submit' })
267
+ - Focus on tracking user interactions in the UI components
268
+ - Track events like button clicks, form submissions, navigation, etc.
269
+ - Add 1-2 high-value events that track the ACTUAL user actions in this file
270
+ - Use descriptive event names (lowercase-hyphenated) based on what the code ACTUALLY does
271
+ - Include properties that capture REAL data from the existing code
272
+ - For user identification: ONLY use user data that's already available in the code
273
+ - DO NOT add code to fetch user IDs or authentication state if not already available in the file
274
+ - Do not change the formatting of the file; only add events
275
+ - Do not set timestamps on events; PostHog will do this automatically
276
+ - Always return the entire file content, not just the changes
277
+ - NEVER add events that correspond to page views; PostHog tracks these automatically
278
+ - NEVER INSERT "use client" or "use server" directives
279
+
280
+ File path: ${filePath}
281
+ File content:
282
+ ${fileContent}
283
+
284
+ IMPORTANT: If this file only renders UI without any user interactions (no buttons, forms, or actions),
285
+ or if the only possible events would be pageview-like (e.g., "form-viewed", "page-opened", "flow-started"),
286
+ then SKIP THIS FILE by returning the original content unchanged. We only want to track actual user actions,
287
+ not that someone looked at a page.
288
+
289
+ Return the enhanced file with PostHog tracking added to the EXISTING functionality. List the events you added.`;
290
+ const response = await (0, query_1.query)({
291
+ message: enhancePrompt,
292
+ model: 'gemini-2.5-pro',
293
+ region: cloudRegion,
294
+ schema: EnhancedFileSchema,
295
+ wizardHash,
296
+ });
297
+ // Apply changes immediately
298
+ if (response.content !== fileContent) {
299
+ await (0, file_utils_1.updateFile)({
300
+ filePath,
301
+ oldContent: fileContent,
302
+ newContent: response.content,
303
+ }, options);
304
+ enhancedFiles.push({
305
+ filePath,
306
+ events: response.events,
307
+ });
308
+ fileSpinner.stop(`✓ Enhanced ${filePath} with ${response.events.length} events`);
309
+ analytics_1.analytics.capture(WIZARD_INTERACTION, {
310
+ action: 'enhanced file',
311
+ integration: INTEGRATION_NAME,
312
+ filePath,
313
+ eventsAdded: response.events.length,
314
+ });
315
+ }
316
+ else {
317
+ fileSpinner.stop(`No changes needed for ${filePath}`);
318
+ analytics_1.analytics.capture(WIZARD_INTERACTION, {
319
+ action: 'file skipped',
320
+ integration: INTEGRATION_NAME,
321
+ filePath,
322
+ reason: 'no events to add',
323
+ });
324
+ }
325
+ }
326
+ catch (error) {
327
+ fileSpinner.stop(`✗ Failed to enhance ${filePath}`);
328
+ (0, debug_1.debug)('Error enhancing file:', error);
329
+ analytics_1.analytics.capture(WIZARD_INTERACTION, {
330
+ action: 'file enhancement failed',
331
+ integration: INTEGRATION_NAME,
332
+ filePath,
333
+ error: error instanceof Error ? error.message : 'Unknown error',
334
+ });
335
+ }
336
+ }
337
+ // Generate event tracking report
338
+ const generateMarkdown = () => {
339
+ let md = `# Event tracking report\n\n`;
340
+ md += `This document lists all PostHog events that have been automatically added to your Next.js application.\n\n`;
341
+ md += `## Events by File\n\n`;
342
+ enhancedFiles.forEach((file) => {
343
+ if (file.events.length > 0) {
344
+ md += `### ${file.filePath}\n\n`;
345
+ file.events.forEach((event) => {
346
+ md += `- **${event.name}**: ${event.description}\n`;
347
+ });
348
+ md += `\n`;
349
+ }
350
+ });
351
+ md += `\n## Events still awaiting implementation\n`;
352
+ md += `- (human: you can fill these in)`;
353
+ md += `\n---\n\n`;
354
+ md += `## Next Steps\n\n`;
355
+ md += `1. Review the changes made to your files\n`;
356
+ md += `2. Test that events are being captured correctly\n`;
357
+ md += `3. Create insights and dashboards in PostHog\n`;
358
+ md += `4. Make a list of events we missed above. Knock them out yourself, or give this file to an agent.\n\n`;
359
+ md += `Learn more about what to measure with PostHog and why: https://posthog.com/docs/new-to-posthog/getting-hogpilled\n`;
360
+ return md;
361
+ };
362
+ const markdownContent = generateMarkdown();
363
+ const fileName = 'event-tracking-report.md';
364
+ const filePath = path.join(options.installDir, fileName);
365
+ await fs.writeFile(filePath, markdownContent);
366
+ // Summary
367
+ const totalEvents = enhancedFiles.reduce((sum, file) => sum + file.events.length, 0);
368
+ analytics_1.analytics.capture(WIZARD_INTERACTION, {
369
+ action: 'event setup completed',
370
+ integration: INTEGRATION_NAME,
371
+ totalEvents,
372
+ filesEnhanced: enhancedFiles.length,
373
+ filesProcessed: selectedFiles.length,
374
+ });
375
+ analytics_1.analytics.setTag('event-setup-total-events', totalEvents);
376
+ analytics_1.analytics.setTag('event-setup-files-enhanced', enhancedFiles.length);
377
+ clack_1.default.outro(`Success! Added ${chalk_1.default.bold(totalEvents.toString())} events across ${chalk_1.default.bold(enhancedFiles.length.toString())} files.
378
+
379
+ Event tracking plan saved to: ${chalk_1.default.cyan(fileName)}
380
+
381
+ Next steps:
382
+ 1. Review changes with your favorite git tool
383
+ 2. Revert unwanted changes with ${chalk_1.default.bold('git checkout <file>')}
384
+ 3. Test that events are being captured in your PostHog project
385
+ 4. Create insights in PostHog
386
+ `);
387
+ }
388
+ //# sourceMappingURL=event-setup.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"event-setup.js","sourceRoot":"","sources":["../../../src/nextjs/event-setup.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA2CA,kDAkYC;AA7aD,sDAQ8B;AAC9B,2DAAmC;AAEnC,gDAAkC;AAClC,2CAA6B;AAC7B,kDAA0B;AAC1B,0CAAuC;AACvC,6BAAwB;AACxB,oDAAuE;AACvE,wDAA+E;AAC/E,+CAAiC;AACjC,0CAAwD;AACxD,kDAA+C;AAE/C,sBAAsB;AACtB,MAAM,kBAAkB,GAAG,oBAAoB,CAAC;AAChD,MAAM,gBAAgB,GAAG,aAAa,CAAC;AAEvC,oCAAoC;AACpC,MAAM,mBAAmB,GAAG,OAAC,CAAC,MAAM,CAAC;IACnC,KAAK,EAAE,OAAC,CAAC,KAAK,CAAC,OAAC,CAAC,MAAM,EAAE,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC;CACnC,CAAC,CAAC;AAEH,uCAAuC;AACvC,MAAM,kBAAkB,GAAG,OAAC,CAAC,MAAM,CAAC;IAClC,QAAQ,EAAE,OAAC,CAAC,MAAM,EAAE;IACpB,OAAO,EAAE,OAAC,CAAC,MAAM,EAAE;IACnB,MAAM,EAAE,OAAC,CAAC,KAAK,CACb,OAAC,CAAC,MAAM,CAAC;QACP,IAAI,EAAE,OAAC,CAAC,MAAM,EAAE;QAChB,WAAW,EAAE,OAAC,CAAC,MAAM,EAAE;KACxB,CAAC,CACH;CACF,CAAC,CAAC;AAEI,KAAK,UAAU,mBAAmB,CACvC,OAAsB;IAEtB,IAAI,OAAO,CAAC,KAAK,EAAE,CAAC;QAClB,IAAA,uBAAe,GAAE,CAAC;IACpB,CAAC;IAED,eAAK,CAAC,KAAK,CACT;;;;;KAKC,CACF,CAAC;IAEF,gCAAgC;IAChC,IAAI,IAAA,yBAAW,GAAE,EAAE,CAAC;QAClB,MAAM,2BAA2B,GAAG,IAAA,4CAA8B,GAAE,CAAC;QACrE,IAAI,2BAA2B,CAAC,MAAM,EAAE,CAAC;YACvC,eAAK,CAAC,GAAG,CAAC,IAAI,CACZ;;EAEN,2BAA2B,CAAC,IAAI,CAAC,IAAI,CAAC;;gHAEwE,CACzG,CAAC;YACF,MAAM,qBAAqB,GAAG,MAAM,IAAA,8BAAgB,EAClD,eAAK,CAAC,OAAO,CAAC;gBACZ,OAAO,EAAE,iCAAiC;aAC3C,CAAC,CACH,CAAC;YACF,IAAI,CAAC,qBAAqB,EAAE,CAAC;gBAC3B,qBAAS,CAAC,OAAO,CAAC,kBAAkB,EAAE;oBACpC,MAAM,EAAE,oCAAoC;oBAC5C,WAAW,EAAE,gBAAgB;iBAC9B,CAAC,CAAC;gBACH,OAAO,IAAA,mBAAK,EAAC,2CAA2C,EAAE,CAAC,CAAC,CAAC;YAC/D,CAAC;YACD,qBAAS,CAAC,OAAO,CAAC,kBAAkB,EAAE;gBACpC,MAAM,EAAE,oCAAoC;gBAC5C,WAAW,EAAE,gBAAgB;aAC9B,CAAC,CAAC;QACL,CAAC;IACH,CAAC;IAED,MAAM,WAAW,GAAG,OAAO,CAAC,WAAW,IAAI,CAAC,MAAM,IAAA,+BAAiB,GAAE,CAAC,CAAC;IAEvE,MAAM,EAAE,UAAU,EAAE,GAAG,MAAM,IAAA,oCAAsB,EAAC;QAClD,GAAG,OAAO;QACV,WAAW;KACZ,CAAC,CAAC;IAEH,uEAAuE;IACvE,MAAM,WAAW,GAAG,MAAM,IAAA,+BAAiB,EAAC,OAAO,CAAC,CAAC;IACrD,MAAM,QAAQ,GAAG,IAAA,kCAAmB,EAAC,MAAM,EAAE,WAAW,CAAC,CAAC;IAE1D,IAAI,CAAC,QAAQ,EAAE,CAAC;QACd,OAAO,IAAA,mBAAK,EAAC,sDAAsD,CAAC,CAAC;IACvE,CAAC;IAED,MAAM,WAAW,GAAG,IAAA,gCAAiB,EAAC,MAAM,EAAE,WAAW,CAAC,CAAC;IAC3D,MAAM,cAAc,GAAG,WAAW,IAAI,MAAM,CAAC,GAAG,CAAC,WAAW,EAAE,QAAQ,CAAC,CAAC;IAExE,qBAAS,CAAC,MAAM,CAAC,gBAAgB,EAAE,WAAW,CAAC,CAAC;IAEhD,IAAI,CAAC,cAAc,EAAE,CAAC;QACpB,qBAAS,CAAC,OAAO,CAAC,kBAAkB,EAAE;YACpC,MAAM,EAAE,+BAA+B;YACvC,WAAW,EAAE,gBAAgB;YAC7B,aAAa,EAAE,WAAW;SAC3B,CAAC,CAAC;QACH,OAAO,IAAA,mBAAK,EAAC,iDAAiD,CAAC,CAAC;IAClE,CAAC;IAED,wCAAwC;IACxC,MAAM,QAAQ,GAAG,MAAM,IAAA,iCAAoB,EAAC,OAAO,CAAC,UAAU,CAAC,CAAC;IAChE,MAAM,oBAAoB,GAAG,QAAQ,CAAC,MAAM,CAC1C,CAAC,CAAC,EAAE,EAAE,CACJ,CAAC,CAAC,QAAQ,CAAC,iBAAiB,CAAC;QAC7B,CAAC,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC;QACxC,CAAC,CAAC,CAAC,QAAQ,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC,CACjD,CAAC;IAEF,IAAI,oBAAoB,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACtC,qBAAS,CAAC,OAAO,CAAC,kBAAkB,EAAE;YACpC,MAAM,EAAE,+CAA+C;YACvD,WAAW,EAAE,gBAAgB;SAC9B,CAAC,CAAC;QACH,OAAO,IAAA,mBAAK,EACV,2HAA2H,CAC5H,CAAC;IACJ,CAAC;IAED,qBAAS,CAAC,OAAO,CAAC,kBAAkB,EAAE;QACpC,MAAM,EAAE,qBAAqB;QAC7B,WAAW,EAAE,gBAAgB;QAC7B,yBAAyB,EAAE,oBAAoB,CAAC,MAAM;KACvD,CAAC,CAAC;IAEH,4BAA4B;IAC5B,MAAM,CAAC,GAAG,eAAK,CAAC,OAAO,EAAE,CAAC;IAC1B,CAAC,CAAC,KAAK,CAAC,kCAAkC,CAAC,CAAC;IAE5C,MAAM,YAAY,GAAG,MAAM,IAAA,iCAAoB,EAAC,OAAO,CAAC,UAAU,CAAC,CAAC;IACpE,MAAM,aAAa,GAAG,YAAY;SAC/B,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC,UAAU,EAAE,CAAC,CAAC,CAAC;SAChD,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE;QACZ,gDAAgD;QAChD,MAAM,iBAAiB,GACrB,CAAC,CAAC,QAAQ,CAAC,iBAAiB,CAAC;YAC7B,CAAC,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC;QAC3C,MAAM,YAAY,GAAG,CAAC,CAAC,UAAU,CAAC,cAAc,CAAC,IAAI,CAAC,KAAK,aAAa,CAAC;QACzE,OAAO,CAAC,iBAAiB,IAAI,CAAC,YAAY,CAAC;IAC7C,CAAC,CAAC,CAAC;IAEL,IAAA,aAAK,EAAC,oBAAoB,EAAE,YAAY,CAAC,MAAM,CAAC,CAAC;IACjD,IAAA,aAAK,EAAC,wBAAwB,EAAE,aAAa,CAAC,MAAM,CAAC,CAAC;IACtD,CAAC,CAAC,IAAI,CAAC,4BAA4B,CAAC,CAAC;IAErC,qBAAS,CAAC,OAAO,CAAC,kBAAkB,EAAE;QACpC,MAAM,EAAE,4BAA4B;QACpC,WAAW,EAAE,gBAAgB;QAC7B,UAAU,EAAE,YAAY,CAAC,MAAM;QAC/B,aAAa,EAAE,aAAa,CAAC,MAAM;KACpC,CAAC,CAAC;IAEH,mDAAmD;IACnD,CAAC,CAAC,KAAK,CAAC,gDAAgD,CAAC,CAAC;IAE1D,MAAM,mBAAmB,GAAG;;;;;;;;;;;;;;;;;;;;;IAqB1B,IAAI,CAAC,SAAS,CAAC,WAAW,EAAE,IAAI,EAAE,CAAC,CAAC;;;IAGpC,aAAa,CAAC,IAAI,CAAC,IAAI,CAAC;;qKAEyI,CAAC;IAEpK,IAAI,aAAa,GAAa,EAAE,CAAC;IACjC,IAAI,CAAC;QACH,MAAM,QAAQ,GAAG,MAAM,IAAA,aAAK,EAAC;YAC3B,OAAO,EAAE,mBAAmB;YAC5B,KAAK,EAAE,kBAAkB;YACzB,MAAM,EAAE,WAAW;YACnB,MAAM,EAAE,mBAAmB;YAC3B,UAAU;SACX,CAAC,CAAC;QACH,aAAa,GAAG,QAAQ,CAAC,KAAK,CAAC;QAC/B,CAAC,CAAC,IAAI,CAAC,YAAY,aAAa,CAAC,MAAM,2BAA2B,CAAC,CAAC;QACpE,qBAAS,CAAC,OAAO,CAAC,kBAAkB,EAAE;YACpC,MAAM,EAAE,6BAA6B;YACrC,WAAW,EAAE,gBAAgB;YAC7B,aAAa,EAAE,aAAa,CAAC,MAAM;SACpC,CAAC,CAAC;IACL,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,CAAC,CAAC,IAAI,CAAC,wBAAwB,CAAC,CAAC;QACjC,qBAAS,CAAC,OAAO,CAAC,kBAAkB,EAAE;YACpC,MAAM,EAAE,uBAAuB;YAC/B,WAAW,EAAE,gBAAgB;YAC7B,KAAK,EAAE,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,eAAe;SAChE,CAAC,CAAC;QACH,OAAO,IAAA,mBAAK,EAAC,wDAAwD,CAAC,CAAC;IACzE,CAAC;IAED,uDAAuD;IACvD,eAAK,CAAC,GAAG,CAAC,IAAI,CAAC,oCAAoC,CAAC,CAAC;IACrD,aAAa,CAAC,OAAO,CAAC,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE;QACpC,eAAK,CAAC,GAAG,CAAC,IAAI,CAAC,KAAK,KAAK,GAAG,CAAC,KAAK,IAAI,EAAE,CAAC,CAAC;IAC5C,CAAC,CAAC,CAAC;IAEH,MAAM,aAAa,GAGd,EAAE,CAAC;IAER,eAAK,CAAC,GAAG,CAAC,IAAI,CACZ,2KAA2K,CAC5K,CAAC;IAEF,KAAK,MAAM,QAAQ,IAAI,aAAa,EAAE,CAAC;QACrC,MAAM,WAAW,GAAG,eAAK,CAAC,OAAO,EAAE,CAAC;QACpC,WAAW,CAAC,KAAK,CAAC,aAAa,QAAQ,EAAE,CAAC,CAAC;QAE3C,IAAI,CAAC;YACH,MAAM,QAAQ,GAAG,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,UAAU,EAAE,QAAQ,CAAC,CAAC;YACzD,MAAM,WAAW,GAAG,MAAM,EAAE,CAAC,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC;YAExD,MAAM,aAAa,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;mBAgDT,QAAQ;;QAEnB,WAAW;;;;;;;qHAOkG,CAAC;YAEhH,MAAM,QAAQ,GAAG,MAAM,IAAA,aAAK,EAAC;gBAC3B,OAAO,EAAE,aAAa;gBACtB,KAAK,EAAE,gBAAgB;gBACvB,MAAM,EAAE,WAAW;gBACnB,MAAM,EAAE,kBAAkB;gBAC1B,UAAU;aACX,CAAC,CAAC;YAEH,4BAA4B;YAC5B,IAAI,QAAQ,CAAC,OAAO,KAAK,WAAW,EAAE,CAAC;gBACrC,MAAM,IAAA,uBAAU,EACd;oBACE,QAAQ;oBACR,UAAU,EAAE,WAAW;oBACvB,UAAU,EAAE,QAAQ,CAAC,OAAO;iBAC7B,EACD,OAAO,CACR,CAAC;gBAEF,aAAa,CAAC,IAAI,CAAC;oBACjB,QAAQ;oBACR,MAAM,EAAE,QAAQ,CAAC,MAAM;iBACxB,CAAC,CAAC;gBAEH,WAAW,CAAC,IAAI,CACd,cAAc,QAAQ,SAAS,QAAQ,CAAC,MAAM,CAAC,MAAM,SAAS,CAC/D,CAAC;gBACF,qBAAS,CAAC,OAAO,CAAC,kBAAkB,EAAE;oBACpC,MAAM,EAAE,eAAe;oBACvB,WAAW,EAAE,gBAAgB;oBAC7B,QAAQ;oBACR,WAAW,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM;iBACpC,CAAC,CAAC;YACL,CAAC;iBAAM,CAAC;gBACN,WAAW,CAAC,IAAI,CAAC,yBAAyB,QAAQ,EAAE,CAAC,CAAC;gBACtD,qBAAS,CAAC,OAAO,CAAC,kBAAkB,EAAE;oBACpC,MAAM,EAAE,cAAc;oBACtB,WAAW,EAAE,gBAAgB;oBAC7B,QAAQ;oBACR,MAAM,EAAE,kBAAkB;iBAC3B,CAAC,CAAC;YACL,CAAC;QACH,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,WAAW,CAAC,IAAI,CAAC,uBAAuB,QAAQ,EAAE,CAAC,CAAC;YACpD,IAAA,aAAK,EAAC,uBAAuB,EAAE,KAAK,CAAC,CAAC;YACtC,qBAAS,CAAC,OAAO,CAAC,kBAAkB,EAAE;gBACpC,MAAM,EAAE,yBAAyB;gBACjC,WAAW,EAAE,gBAAgB;gBAC7B,QAAQ;gBACR,KAAK,EAAE,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,eAAe;aAChE,CAAC,CAAC;QACL,CAAC;IACH,CAAC;IAED,iCAAiC;IACjC,MAAM,gBAAgB,GAAG,GAAG,EAAE;QAC5B,IAAI,EAAE,GAAG,6BAA6B,CAAC;QACvC,EAAE,IAAI,4GAA4G,CAAC;QACnH,EAAE,IAAI,uBAAuB,CAAC;QAE9B,aAAa,CAAC,OAAO,CAAC,CAAC,IAAI,EAAE,EAAE;YAC7B,IAAI,IAAI,CAAC,MAAM,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;gBAC3B,EAAE,IAAI,OAAO,IAAI,CAAC,QAAQ,MAAM,CAAC;gBACjC,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,KAAK,EAAE,EAAE;oBAC5B,EAAE,IAAI,OAAO,KAAK,CAAC,IAAI,OAAO,KAAK,CAAC,WAAW,IAAI,CAAC;gBACtD,CAAC,CAAC,CAAC;gBACH,EAAE,IAAI,IAAI,CAAC;YACb,CAAC;QACH,CAAC,CAAC,CAAC;QAEH,EAAE,IAAI,6CAA6C,CAAC;QACpD,EAAE,IAAI,kCAAkC,CAAC;QAEzC,EAAE,IAAI,WAAW,CAAC;QAClB,EAAE,IAAI,mBAAmB,CAAC;QAC1B,EAAE,IAAI,4CAA4C,CAAC;QACnD,EAAE,IAAI,oDAAoD,CAAC;QAC3D,EAAE,IAAI,gDAAgD,CAAC;QACvD,EAAE,IAAI,uGAAuG,CAAC;QAC9G,EAAE,IAAI,oHAAoH,CAAC;QAC3H,OAAO,EAAE,CAAC;IACZ,CAAC,CAAC;IAEF,MAAM,eAAe,GAAG,gBAAgB,EAAE,CAAC;IAC3C,MAAM,QAAQ,GAAG,0BAA0B,CAAC;IAC5C,MAAM,QAAQ,GAAG,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,UAAU,EAAE,QAAQ,CAAC,CAAC;IAEzD,MAAM,EAAE,CAAC,SAAS,CAAC,QAAQ,EAAE,eAAe,CAAC,CAAC;IAE9C,UAAU;IACV,MAAM,WAAW,GAAG,aAAa,CAAC,MAAM,CACtC,CAAC,GAAG,EAAE,IAAI,EAAE,EAAE,CAAC,GAAG,GAAG,IAAI,CAAC,MAAM,CAAC,MAAM,EACvC,CAAC,CACF,CAAC;IAEF,qBAAS,CAAC,OAAO,CAAC,kBAAkB,EAAE;QACpC,MAAM,EAAE,uBAAuB;QAC/B,WAAW,EAAE,gBAAgB;QAC7B,WAAW;QACX,aAAa,EAAE,aAAa,CAAC,MAAM;QACnC,cAAc,EAAE,aAAa,CAAC,MAAM;KACrC,CAAC,CAAC;IAEH,qBAAS,CAAC,MAAM,CAAC,0BAA0B,EAAE,WAAW,CAAC,CAAC;IAC1D,qBAAS,CAAC,MAAM,CAAC,4BAA4B,EAAE,aAAa,CAAC,MAAM,CAAC,CAAC;IAErE,eAAK,CAAC,KAAK,CACT,kBAAkB,eAAK,CAAC,IAAI,CAC1B,WAAW,CAAC,QAAQ,EAAE,CACvB,kBAAkB,eAAK,CAAC,IAAI,CAAC,aAAa,CAAC,MAAM,CAAC,QAAQ,EAAE,CAAC;;oCAE9B,eAAK,CAAC,IAAI,CAAC,QAAQ,CAAC;;;;sCAIlB,eAAK,CAAC,IAAI,CAAC,qBAAqB,CAAC;;;KAGlE,CACF,CAAC;AACJ,CAAC","sourcesContent":["import {\n abort,\n getOrAskForProjectData,\n askForCloudRegion,\n getPackageDotJson,\n getUncommittedOrUntrackedFiles,\n isInGitRepo,\n abortIfCancelled,\n} from '../utils/clack-utils';\nimport clack from '../utils/clack';\nimport { WizardOptions } from '../utils/types';\nimport * as fs from 'fs/promises';\nimport * as path from 'path';\nimport chalk from 'chalk';\nimport { query } from '../utils/query';\nimport { z } from 'zod';\nimport { getAllFilesInProject, updateFile } from '../utils/file-utils';\nimport { getPackageVersion, hasPackageInstalled } from '../utils/package-json';\nimport * as semver from 'semver';\nimport { enableDebugLogs, debug } from '../utils/debug';\nimport { analytics } from '../utils/analytics';\n\n// Analytics constants\nconst WIZARD_INTERACTION = 'wizard interaction';\nconst INTEGRATION_NAME = 'event-setup';\n\n// Schema for file selection from AI\nconst FileSelectionSchema = z.object({\n files: z.array(z.string()).max(10),\n});\n\n// Schema for enhanced file with events\nconst EnhancedFileSchema = z.object({\n filePath: z.string(),\n content: z.string(),\n events: z.array(\n z.object({\n name: z.string(),\n description: z.string(),\n }),\n ),\n});\n\nexport async function runEventSetupWizard(\n options: WizardOptions,\n): Promise<void> {\n if (options.debug) {\n enableDebugLogs();\n }\n\n clack.intro(\n `Let's do a first pass on PostHog event tracking for your project.\n \n We'll start by analyzing your project structure, then choose up to ten files to enhance. Use git to discard any events you're not happy with.\n\n This will give you a starting point, then you can add any events that we missed.\n `,\n );\n\n // Check for uncommitted changes\n if (isInGitRepo()) {\n const uncommittedOrUntrackedFiles = getUncommittedOrUntrackedFiles();\n if (uncommittedOrUntrackedFiles.length) {\n clack.log.warn(\n `You have uncommitted or untracked files in your repo:\n\n${uncommittedOrUntrackedFiles.join('\\n')}\n\nThe event setup wizard will modify multiple files. For the best experience, commit or stash your changes first.`,\n );\n const continueWithDirtyRepo = await abortIfCancelled(\n clack.confirm({\n message: 'Do you want to continue anyway?',\n }),\n );\n if (!continueWithDirtyRepo) {\n analytics.capture(WIZARD_INTERACTION, {\n action: 'aborted due to uncommitted changes',\n integration: INTEGRATION_NAME,\n });\n return abort('Please commit your changes and try again.', 0);\n }\n analytics.capture(WIZARD_INTERACTION, {\n action: 'continued with uncommitted changes',\n integration: INTEGRATION_NAME,\n });\n }\n }\n\n const cloudRegion = options.cloudRegion ?? (await askForCloudRegion());\n\n const { wizardHash } = await getOrAskForProjectData({\n ...options,\n cloudRegion,\n });\n\n // Check if this is a Next.js 15.3+ project with instrumentation-client\n const packageJson = await getPackageDotJson(options);\n const isNextJs = hasPackageInstalled('next', packageJson);\n\n if (!isNextJs) {\n return abort('This feature is only available for Next.js projects.');\n }\n\n const nextVersion = getPackageVersion('next', packageJson);\n const isNext15_3Plus = nextVersion && semver.gte(nextVersion, '15.3.0');\n\n analytics.setTag('nextjs-version', nextVersion);\n\n if (!isNext15_3Plus) {\n analytics.capture(WIZARD_INTERACTION, {\n action: 'aborted due to nextjs version',\n integration: INTEGRATION_NAME,\n nextjsVersion: nextVersion,\n });\n return abort('This feature requires Next.js 15.3.0 or higher.');\n }\n\n // Check for instrumentation-client file\n const allFiles = await getAllFilesInProject(options.installDir);\n const instrumentationFiles = allFiles.filter(\n (f) =>\n f.includes('instrumentation') &&\n (f.endsWith('.ts') || f.endsWith('.js')) &&\n (f.includes('client') || f.includes('Client')),\n );\n\n if (instrumentationFiles.length === 0) {\n analytics.capture(WIZARD_INTERACTION, {\n action: 'aborted due to missing instrumentation-client',\n integration: INTEGRATION_NAME,\n });\n return abort(\n 'No instrumentation-client file found. Please set up Next.js instrumentation-client first. Try using this wizard to do it!',\n );\n }\n\n analytics.capture(WIZARD_INTERACTION, {\n action: 'started event setup',\n integration: INTEGRATION_NAME,\n instrumentationFilesCount: instrumentationFiles.length,\n });\n\n // Get the project file tree\n const s = clack.spinner();\n s.start('Analyzing your project structure');\n\n const projectFiles = await getAllFilesInProject(options.installDir);\n const relativeFiles = projectFiles\n .map((f) => path.relative(options.installDir, f))\n .filter((f) => {\n // Exclude instrumentation files and next.config\n const isInstrumentation =\n f.includes('instrumentation') &&\n (f.endsWith('.ts') || f.endsWith('.js'));\n const isNextConfig = f.startsWith('next.config.') || f === 'next.config';\n return !isInstrumentation && !isNextConfig;\n });\n\n debug('Total files found:', projectFiles.length);\n debug('Files after filtering:', relativeFiles.length);\n s.stop('Project structure analyzed');\n\n analytics.capture(WIZARD_INTERACTION, {\n action: 'analyzed project structure',\n integration: INTEGRATION_NAME,\n totalFiles: projectFiles.length,\n eligibleFiles: relativeFiles.length,\n });\n\n // Send file tree to AI to get 10 most useful files\n s.start('Selecting some files to enhance with events...');\n\n const fileSelectionPrompt = `Given this Next.js 15.3+ project structure and package.json, select up to 10 CLIENT-SIDE FILES for adding PostHog analytics events.\n \n IMPORTANT: Only select files that:\n - Have \"use client\" directive at the top, OR\n - Use React hooks (useState, useEffect, etc.), OR \n - Have event handlers (onClick, onSubmit, onChange)\n \n DO NOT select:\n - API routes (files in /api/ or route.ts/route.js files)\n - Server Components (files without \"use client\" and no hooks/handlers)\n - Layout files (layout.tsx/layout.js)\n - Configuration files\n - Pure utility files\n \n Focus on:\n - User interaction points (buttons, forms, navigation)\n - Key user flows (auth, checkout, main features)\n - Business-critical paths\n - Files that represent important user actions\n \n Package.json:\n ${JSON.stringify(packageJson, null, 2)}\n \n Project files:\n ${relativeFiles.join('\\n')}\n \n Return file paths for client-side files ONLY that would benefit most from analytics tracking. If there are fewer than 10 suitable client files, return only those.`;\n\n let selectedFiles: string[] = [];\n try {\n const response = await query({\n message: fileSelectionPrompt,\n model: 'gemini-2.5-flash',\n region: cloudRegion,\n schema: FileSelectionSchema,\n wizardHash,\n });\n selectedFiles = response.files;\n s.stop(`Selected ${selectedFiles.length} files for event tracking`);\n analytics.capture(WIZARD_INTERACTION, {\n action: 'selected files for tracking',\n integration: INTEGRATION_NAME,\n filesSelected: selectedFiles.length,\n });\n } catch (error) {\n s.stop('Failed to select files');\n analytics.capture(WIZARD_INTERACTION, {\n action: 'file selection failed',\n integration: INTEGRATION_NAME,\n error: error instanceof Error ? error.message : 'Unknown error',\n });\n return abort('Could not analyze project structure. Please try again.');\n }\n\n // Read the selected files and enhance them with events\n clack.log.info('Files selected for event tracking:');\n selectedFiles.forEach((file, index) => {\n clack.log.info(` ${index + 1}. ${file}`);\n });\n\n const enhancedFiles: Array<{\n filePath: string;\n events: Array<{ name: string; description: string }>;\n }> = [];\n\n clack.log.info(\n \"\\nEnhancing files with event tracking. Changes will be applied as they come in. Use your git interface to review new events. Feel free to toss anything you don't like...\",\n );\n\n for (const filePath of selectedFiles) {\n const fileSpinner = clack.spinner();\n fileSpinner.start(`Analyzing ${filePath}`);\n\n try {\n const fullPath = path.join(options.installDir, filePath);\n const fileContent = await fs.readFile(fullPath, 'utf8');\n\n const enhancePrompt = `You are enhancing a REAL production, client-side Next.js file with PostHog analytics. This is NOT an example or tutorial - add events to the ACTUAL code provided.\n \n - REQUIRED: import posthog from 'posthog-js'\n - Track events with: posthog.capture('event-name', { property: 'value' })\n - NEVER import PostHogClient from '@/app/posthog'\n - NEVER create functions with 'use server'\n\n CRITICAL INSTRUCTIONS:\n - This is a REAL file from a production codebase\n - DO NOT add placeholder comments like \"// In a real app...\" or \"// This is an example...\"\n - DO NOT modify the existing business logic or add simulation code\n - DO NOT add any tutorial-style comments\n - ONLY add PostHog event tracking to the existing, real functionality\n - DO NOT create wrapper functions around existing functions just to add tracking\n - Add tracking code directly inside existing functions where appropriate\n - NEVER import new packages or libraries that aren't already used in the file\n - ONLY use imports that already exist in the file or the PostHog imports specified\n - DO NOT assume any authentication library (Clerk, Auth.js, etc.) is available\n \n FORBIDDEN - NEVER DO THESE:\n - NEVER add 'use client' or 'use server' directives at the top of the file, or in functions\n - NEVER define new server actions (functions with \"use server\") in Client Components\n - NEVER create inline \"use server\" functions in files that have \"use client\"\n - NEVER use useEffect to track page views or component renders\n - NEVER track events like \"page_viewed\", \"form_viewed\", \"component_rendered\", \"flow_started\", \"page_opened\" etc\n - NEVER track that someone simply arrived at or viewed a page\n - NEVER change the file's existing client/server architecture\n - NEVER add events on component mount or render - only on actual user interactions\n - Track events on user interactions like clicks, form submissions, etc.\n \n Technical Rules:\n - This is a client-side file suitable for event tracking\n - REQUIRED IMPORT: import posthog from 'posthog-js'\n - Use the existing posthog instance for all tracking\n - Example: posthog.capture('button-clicked', { buttonId: 'submit' })\n - Focus on tracking user interactions in the UI components\n - Track events like button clicks, form submissions, navigation, etc.\n - Add 1-2 high-value events that track the ACTUAL user actions in this file\n - Use descriptive event names (lowercase-hyphenated) based on what the code ACTUALLY does\n - Include properties that capture REAL data from the existing code\n - For user identification: ONLY use user data that's already available in the code\n - DO NOT add code to fetch user IDs or authentication state if not already available in the file\n - Do not change the formatting of the file; only add events\n - Do not set timestamps on events; PostHog will do this automatically\n - Always return the entire file content, not just the changes\n - NEVER add events that correspond to page views; PostHog tracks these automatically\n - NEVER INSERT \"use client\" or \"use server\" directives\n \n File path: ${filePath}\n File content:\n ${fileContent}\n \n IMPORTANT: If this file only renders UI without any user interactions (no buttons, forms, or actions), \n or if the only possible events would be pageview-like (e.g., \"form-viewed\", \"page-opened\", \"flow-started\"),\n then SKIP THIS FILE by returning the original content unchanged. We only want to track actual user actions,\n not that someone looked at a page.\n \n Return the enhanced file with PostHog tracking added to the EXISTING functionality. List the events you added.`;\n\n const response = await query({\n message: enhancePrompt,\n model: 'gemini-2.5-pro',\n region: cloudRegion,\n schema: EnhancedFileSchema,\n wizardHash,\n });\n\n // Apply changes immediately\n if (response.content !== fileContent) {\n await updateFile(\n {\n filePath,\n oldContent: fileContent,\n newContent: response.content,\n },\n options,\n );\n\n enhancedFiles.push({\n filePath,\n events: response.events,\n });\n\n fileSpinner.stop(\n `✓ Enhanced ${filePath} with ${response.events.length} events`,\n );\n analytics.capture(WIZARD_INTERACTION, {\n action: 'enhanced file',\n integration: INTEGRATION_NAME,\n filePath,\n eventsAdded: response.events.length,\n });\n } else {\n fileSpinner.stop(`No changes needed for ${filePath}`);\n analytics.capture(WIZARD_INTERACTION, {\n action: 'file skipped',\n integration: INTEGRATION_NAME,\n filePath,\n reason: 'no events to add',\n });\n }\n } catch (error) {\n fileSpinner.stop(`✗ Failed to enhance ${filePath}`);\n debug('Error enhancing file:', error);\n analytics.capture(WIZARD_INTERACTION, {\n action: 'file enhancement failed',\n integration: INTEGRATION_NAME,\n filePath,\n error: error instanceof Error ? error.message : 'Unknown error',\n });\n }\n }\n\n // Generate event tracking report\n const generateMarkdown = () => {\n let md = `# Event tracking report\\n\\n`;\n md += `This document lists all PostHog events that have been automatically added to your Next.js application.\\n\\n`;\n md += `## Events by File\\n\\n`;\n\n enhancedFiles.forEach((file) => {\n if (file.events.length > 0) {\n md += `### ${file.filePath}\\n\\n`;\n file.events.forEach((event) => {\n md += `- **${event.name}**: ${event.description}\\n`;\n });\n md += `\\n`;\n }\n });\n\n md += `\\n## Events still awaiting implementation\\n`;\n md += `- (human: you can fill these in)`;\n\n md += `\\n---\\n\\n`;\n md += `## Next Steps\\n\\n`;\n md += `1. Review the changes made to your files\\n`;\n md += `2. Test that events are being captured correctly\\n`;\n md += `3. Create insights and dashboards in PostHog\\n`;\n md += `4. Make a list of events we missed above. Knock them out yourself, or give this file to an agent.\\n\\n`;\n md += `Learn more about what to measure with PostHog and why: https://posthog.com/docs/new-to-posthog/getting-hogpilled\\n`;\n return md;\n };\n\n const markdownContent = generateMarkdown();\n const fileName = 'event-tracking-report.md';\n const filePath = path.join(options.installDir, fileName);\n\n await fs.writeFile(filePath, markdownContent);\n\n // Summary\n const totalEvents = enhancedFiles.reduce(\n (sum, file) => sum + file.events.length,\n 0,\n );\n\n analytics.capture(WIZARD_INTERACTION, {\n action: 'event setup completed',\n integration: INTEGRATION_NAME,\n totalEvents,\n filesEnhanced: enhancedFiles.length,\n filesProcessed: selectedFiles.length,\n });\n\n analytics.setTag('event-setup-total-events', totalEvents);\n analytics.setTag('event-setup-files-enhanced', enhancedFiles.length);\n\n clack.outro(\n `Success! Added ${chalk.bold(\n totalEvents.toString(),\n )} events across ${chalk.bold(enhancedFiles.length.toString())} files.\n \n Event tracking plan saved to: ${chalk.cyan(fileName)}\n \n Next steps:\n 1. Review changes with your favorite git tool\n 2. Revert unwanted changes with ${chalk.bold('git checkout <file>')}\n 3. Test that events are being captured in your PostHog project\n 4. Create insights in PostHog\n `,\n );\n}\n"]}
@@ -165,6 +165,7 @@ async function runNextjsWizard(options) {
165
165
  uploadedEnvVars,
166
166
  });
167
167
  clack_1.default.outro(outroMessage);
168
+ clack_1.default.outro('Want to try our experimental event instrumentation? Run the wizard again with this argument: npx @posthog/wizard@latest event-setup');
168
169
  await analytics_1.analytics.shutdown('success');
169
170
  }
170
171
  function instrumentationFileAvailable(nextVersion) {
@@ -1 +1 @@
1
- {"version":3,"file":"nextjs-wizard.js","sourceRoot":"","sources":["../../../src/nextjs/nextjs-wizard.ts"],"names":[],"mappings":"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","sourcesContent":["/* eslint-disable max-lines */\nimport {\n abort,\n askForAIConsent,\n confirmContinueIfNoOrDirtyGitRepo,\n ensurePackageIsInstalled,\n getOrAskForProjectData,\n getPackageDotJson,\n getPackageManager,\n installPackage,\n isUsingTypeScript,\n printWelcome,\n} from '../utils/clack-utils';\nimport { getPackageVersion, hasPackageInstalled } from '../utils/package-json';\nimport {\n getNextJsRouter,\n getNextJsRouterName,\n getNextJsVersionBucket,\n NextJsRouter,\n} from './utils';\nimport clack from '../utils/clack';\nimport { Integration } from '../lib/constants';\nimport {\n getNextjsAppRouterDocs,\n getNextjsPagesRouterDocs,\n getModernNextjsDocs,\n} from './docs';\nimport { analytics } from '../utils/analytics';\nimport {\n generateFileChangesForIntegration,\n getFilesToChange,\n getRelevantFilesForIntegration,\n} from '../utils/file-utils';\nimport type { WizardOptions } from '../utils/types';\nimport { askForCloudRegion } from '../utils/clack-utils';\nimport { getOutroMessage } from '../lib/messages';\nimport {\n addEditorRulesStep,\n addOrUpdateEnvironmentVariablesStep,\n runPrettierStep,\n addMCPServerToClientsStep,\n uploadEnvironmentVariablesStep,\n} from '../steps';\n\nimport * as semver from 'semver';\n\nexport async function runNextjsWizard(options: WizardOptions): Promise<void> {\n printWelcome({\n wizardName: 'PostHog Next.js wizard',\n });\n\n const aiConsent = await askForAIConsent(options);\n\n if (!aiConsent) {\n await abort(\n 'The Next.js wizard requires AI to get setup right now. Please view the docs to setup Next.js manually instead: https://posthog.com/docs/libraries/next-js',\n 0,\n );\n }\n\n const cloudRegion = options.cloudRegion ?? (await askForCloudRegion());\n\n const typeScriptDetected = isUsingTypeScript(options);\n\n await confirmContinueIfNoOrDirtyGitRepo(options);\n\n const packageJson = await getPackageDotJson(options);\n\n await ensurePackageIsInstalled(packageJson, 'next', 'Next.js');\n\n const nextVersion = getPackageVersion('next', packageJson);\n\n analytics.setTag('nextjs-version', getNextJsVersionBucket(nextVersion));\n\n const { projectApiKey, wizardHash, host } = await getOrAskForProjectData({\n ...options,\n cloudRegion,\n });\n\n const sdkAlreadyInstalled = hasPackageInstalled('posthog-js', packageJson);\n\n analytics.setTag('sdk-already-installed', sdkAlreadyInstalled);\n\n const { packageManager: packageManagerFromInstallStep } =\n await installPackage({\n packageName: 'posthog-js',\n packageNameDisplayLabel: 'posthog-js',\n alreadyInstalled: !!packageJson?.dependencies?.['posthog-js'],\n forceInstall: options.forceInstall,\n askBeforeUpdating: false,\n installDir: options.installDir,\n integration: Integration.nextjs,\n });\n\n await installPackage({\n packageName: 'posthog-node',\n packageNameDisplayLabel: 'posthog-node',\n packageManager: packageManagerFromInstallStep,\n alreadyInstalled: !!packageJson?.dependencies?.['posthog-node'],\n forceInstall: options.forceInstall,\n askBeforeUpdating: false,\n installDir: options.installDir,\n integration: Integration.nextjs,\n });\n\n const relevantFiles = await getRelevantFilesForIntegration({\n installDir: options.installDir,\n integration: Integration.nextjs,\n });\n\n let installationDocumentation; // Documentation for the installation of the PostHog SDK\n\n if (instrumentationFileAvailable(nextVersion)) {\n installationDocumentation = getModernNextjsDocs({\n host,\n language: typeScriptDetected ? 'typescript' : 'javascript',\n });\n\n clack.log.info(`Reviewing PostHog documentation for Next.js`);\n } else {\n const router = await getNextJsRouter(options);\n\n installationDocumentation = getInstallationDocumentation({\n router,\n host,\n language: typeScriptDetected ? 'typescript' : 'javascript',\n });\n\n clack.log.info(\n `Reviewing PostHog documentation for ${getNextJsRouterName(router)}`,\n );\n }\n\n const filesToChange = await getFilesToChange({\n integration: Integration.nextjs,\n relevantFiles,\n documentation: installationDocumentation,\n wizardHash,\n cloudRegion,\n });\n\n await generateFileChangesForIntegration({\n integration: Integration.nextjs,\n filesToChange,\n wizardHash,\n installDir: options.installDir,\n documentation: installationDocumentation,\n cloudRegion,\n });\n\n const packageManagerForOutro =\n packageManagerFromInstallStep ?? (await getPackageManager(options));\n\n await runPrettierStep({\n installDir: options.installDir,\n integration: Integration.nextjs,\n });\n\n const { relativeEnvFilePath, addedEnvVariables } =\n await addOrUpdateEnvironmentVariablesStep({\n variables: {\n NEXT_PUBLIC_POSTHOG_KEY: projectApiKey,\n NEXT_PUBLIC_POSTHOG_HOST: host,\n },\n installDir: options.installDir,\n integration: Integration.nextjs,\n });\n\n const uploadedEnvVars = await uploadEnvironmentVariablesStep(\n {\n NEXT_PUBLIC_POSTHOG_KEY: projectApiKey,\n NEXT_PUBLIC_POSTHOG_HOST: host,\n },\n {\n integration: Integration.nextjs,\n options,\n },\n );\n\n const addedEditorRules = await addEditorRulesStep({\n rulesName: 'next-rules.md',\n installDir: options.installDir,\n integration: Integration.nextjs,\n });\n\n await addMCPServerToClientsStep({\n cloudRegion,\n integration: Integration.nextjs,\n });\n\n const outroMessage = getOutroMessage({\n options,\n integration: Integration.nextjs,\n cloudRegion,\n addedEditorRules,\n packageManager: packageManagerForOutro,\n envFileChanged: addedEnvVariables ? relativeEnvFilePath : undefined,\n uploadedEnvVars,\n });\n\n clack.outro(outroMessage);\n\n await analytics.shutdown('success');\n}\n\nfunction instrumentationFileAvailable(\n nextVersion: string | undefined,\n): boolean {\n const minimumVersion = '15.3.0'; //instrumentation-client.js|ts was introduced in 15.3\n\n if (!nextVersion) {\n return false;\n }\n const coercedNextVersion = semver.coerce(nextVersion);\n if (!coercedNextVersion) {\n return false; // Unable to parse nextVersion\n }\n return semver.gte(coercedNextVersion, minimumVersion);\n}\n\nfunction getInstallationDocumentation({\n router,\n host,\n language,\n}: {\n router: NextJsRouter;\n host: string;\n language: 'typescript' | 'javascript';\n}) {\n if (router === NextJsRouter.PAGES_ROUTER) {\n return getNextjsPagesRouterDocs({ host, language });\n }\n\n return getNextjsAppRouterDocs({ host, language });\n}\n"]}
1
+ {"version":3,"file":"nextjs-wizard.js","sourceRoot":"","sources":["../../../src/nextjs/nextjs-wizard.ts"],"names":[],"mappings":"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","sourcesContent":["/* eslint-disable max-lines */\nimport {\n abort,\n askForAIConsent,\n confirmContinueIfNoOrDirtyGitRepo,\n ensurePackageIsInstalled,\n getOrAskForProjectData,\n getPackageDotJson,\n getPackageManager,\n installPackage,\n isUsingTypeScript,\n printWelcome,\n} from '../utils/clack-utils';\nimport { getPackageVersion, hasPackageInstalled } from '../utils/package-json';\nimport {\n getNextJsRouter,\n getNextJsRouterName,\n getNextJsVersionBucket,\n NextJsRouter,\n} from './utils';\nimport clack from '../utils/clack';\nimport { Integration } from '../lib/constants';\nimport {\n getNextjsAppRouterDocs,\n getNextjsPagesRouterDocs,\n getModernNextjsDocs,\n} from './docs';\nimport { analytics } from '../utils/analytics';\nimport {\n generateFileChangesForIntegration,\n getFilesToChange,\n getRelevantFilesForIntegration,\n} from '../utils/file-utils';\nimport type { WizardOptions } from '../utils/types';\nimport { askForCloudRegion } from '../utils/clack-utils';\nimport { getOutroMessage } from '../lib/messages';\nimport {\n addEditorRulesStep,\n addOrUpdateEnvironmentVariablesStep,\n runPrettierStep,\n addMCPServerToClientsStep,\n uploadEnvironmentVariablesStep,\n} from '../steps';\n\nimport * as semver from 'semver';\n\nexport async function runNextjsWizard(options: WizardOptions): Promise<void> {\n printWelcome({\n wizardName: 'PostHog Next.js wizard',\n });\n\n const aiConsent = await askForAIConsent(options);\n\n if (!aiConsent) {\n await abort(\n 'The Next.js wizard requires AI to get setup right now. Please view the docs to setup Next.js manually instead: https://posthog.com/docs/libraries/next-js',\n 0,\n );\n }\n\n const cloudRegion = options.cloudRegion ?? (await askForCloudRegion());\n\n const typeScriptDetected = isUsingTypeScript(options);\n\n await confirmContinueIfNoOrDirtyGitRepo(options);\n\n const packageJson = await getPackageDotJson(options);\n\n await ensurePackageIsInstalled(packageJson, 'next', 'Next.js');\n\n const nextVersion = getPackageVersion('next', packageJson);\n\n analytics.setTag('nextjs-version', getNextJsVersionBucket(nextVersion));\n\n const { projectApiKey, wizardHash, host } = await getOrAskForProjectData({\n ...options,\n cloudRegion,\n });\n\n const sdkAlreadyInstalled = hasPackageInstalled('posthog-js', packageJson);\n\n analytics.setTag('sdk-already-installed', sdkAlreadyInstalled);\n\n const { packageManager: packageManagerFromInstallStep } =\n await installPackage({\n packageName: 'posthog-js',\n packageNameDisplayLabel: 'posthog-js',\n alreadyInstalled: !!packageJson?.dependencies?.['posthog-js'],\n forceInstall: options.forceInstall,\n askBeforeUpdating: false,\n installDir: options.installDir,\n integration: Integration.nextjs,\n });\n\n await installPackage({\n packageName: 'posthog-node',\n packageNameDisplayLabel: 'posthog-node',\n packageManager: packageManagerFromInstallStep,\n alreadyInstalled: !!packageJson?.dependencies?.['posthog-node'],\n forceInstall: options.forceInstall,\n askBeforeUpdating: false,\n installDir: options.installDir,\n integration: Integration.nextjs,\n });\n\n const relevantFiles = await getRelevantFilesForIntegration({\n installDir: options.installDir,\n integration: Integration.nextjs,\n });\n\n let installationDocumentation; // Documentation for the installation of the PostHog SDK\n\n if (instrumentationFileAvailable(nextVersion)) {\n installationDocumentation = getModernNextjsDocs({\n host,\n language: typeScriptDetected ? 'typescript' : 'javascript',\n });\n\n clack.log.info(`Reviewing PostHog documentation for Next.js`);\n } else {\n const router = await getNextJsRouter(options);\n\n installationDocumentation = getInstallationDocumentation({\n router,\n host,\n language: typeScriptDetected ? 'typescript' : 'javascript',\n });\n\n clack.log.info(\n `Reviewing PostHog documentation for ${getNextJsRouterName(router)}`,\n );\n }\n\n const filesToChange = await getFilesToChange({\n integration: Integration.nextjs,\n relevantFiles,\n documentation: installationDocumentation,\n wizardHash,\n cloudRegion,\n });\n\n await generateFileChangesForIntegration({\n integration: Integration.nextjs,\n filesToChange,\n wizardHash,\n installDir: options.installDir,\n documentation: installationDocumentation,\n cloudRegion,\n });\n\n const packageManagerForOutro =\n packageManagerFromInstallStep ?? (await getPackageManager(options));\n\n await runPrettierStep({\n installDir: options.installDir,\n integration: Integration.nextjs,\n });\n\n const { relativeEnvFilePath, addedEnvVariables } =\n await addOrUpdateEnvironmentVariablesStep({\n variables: {\n NEXT_PUBLIC_POSTHOG_KEY: projectApiKey,\n NEXT_PUBLIC_POSTHOG_HOST: host,\n },\n installDir: options.installDir,\n integration: Integration.nextjs,\n });\n\n const uploadedEnvVars = await uploadEnvironmentVariablesStep(\n {\n NEXT_PUBLIC_POSTHOG_KEY: projectApiKey,\n NEXT_PUBLIC_POSTHOG_HOST: host,\n },\n {\n integration: Integration.nextjs,\n options,\n },\n );\n\n const addedEditorRules = await addEditorRulesStep({\n rulesName: 'next-rules.md',\n installDir: options.installDir,\n integration: Integration.nextjs,\n });\n\n await addMCPServerToClientsStep({\n cloudRegion,\n integration: Integration.nextjs,\n });\n\n const outroMessage = getOutroMessage({\n options,\n integration: Integration.nextjs,\n cloudRegion,\n addedEditorRules,\n packageManager: packageManagerForOutro,\n envFileChanged: addedEnvVariables ? relativeEnvFilePath : undefined,\n uploadedEnvVars,\n });\n\n clack.outro(outroMessage);\n\n clack.outro(\n 'Want to try our experimental event instrumentation? Run the wizard again with this argument: npx @posthog/wizard@latest event-setup',\n );\n\n await analytics.shutdown('success');\n}\n\nfunction instrumentationFileAvailable(\n nextVersion: string | undefined,\n): boolean {\n const minimumVersion = '15.3.0'; //instrumentation-client.js|ts was introduced in 15.3\n\n if (!nextVersion) {\n return false;\n }\n const coercedNextVersion = semver.coerce(nextVersion);\n if (!coercedNextVersion) {\n return false; // Unable to parse nextVersion\n }\n return semver.gte(coercedNextVersion, minimumVersion);\n}\n\nfunction getInstallationDocumentation({\n router,\n host,\n language,\n}: {\n router: NextJsRouter;\n host: string;\n language: 'typescript' | 'javascript';\n}) {\n if (router === NextJsRouter.PAGES_ROUTER) {\n return getNextjsPagesRouterDocs({ host, language });\n }\n\n return getNextjsAppRouterDocs({ host, language });\n}\n"]}
@@ -1,3 +1,4 @@
1
1
  import type { WizardOptions } from './types';
2
+ export declare function isNonInteractiveEnvironment(): boolean;
2
3
  export declare function readEnvironment(): Record<string, unknown>;
3
4
  export declare function detectEnvVarPrefix(options: WizardOptions): Promise<string>;
@@ -3,11 +3,22 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
3
3
  return (mod && mod.__esModule) ? mod : { "default": mod };
4
4
  };
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.isNonInteractiveEnvironment = isNonInteractiveEnvironment;
6
7
  exports.readEnvironment = readEnvironment;
7
8
  exports.detectEnvVarPrefix = detectEnvVarPrefix;
8
9
  const read_env_1 = __importDefault(require("read-env"));
9
10
  const clack_utils_1 = require("./clack-utils");
10
11
  const fast_glob_1 = __importDefault(require("fast-glob"));
12
+ const constants_1 = require("../lib/constants");
13
+ function isNonInteractiveEnvironment() {
14
+ if (constants_1.IS_DEV) {
15
+ return false;
16
+ }
17
+ if (!process.stdout.isTTY || !process.stderr.isTTY) {
18
+ return true;
19
+ }
20
+ return false;
21
+ }
11
22
  function readEnvironment() {
12
23
  const result = (0, read_env_1.default)('POSTHOG_WIZARD');
13
24
  return result;
@@ -1 +1 @@
1
- {"version":3,"file":"environment.js","sourceRoot":"","sources":["../../../src/utils/environment.ts"],"names":[],"mappings":";;;;;AAKA,0CAIC;AAED,gDAiEC;AA5ED,wDAA+B;AAC/B,+CAAkD;AAElD,0DAA2B;AAE3B,SAAgB,eAAe;IAC7B,MAAM,MAAM,GAAG,IAAA,kBAAO,EAAC,gBAAgB,CAAC,CAAC;IAEzC,OAAO,MAAM,CAAC;AAChB,CAAC;AAEM,KAAK,UAAU,kBAAkB,CACtC,OAAsB;IAEtB,MAAM,WAAW,GAAG,MAAM,IAAA,+BAAiB,EAAC,OAAO,CAAC,CAAC;IAErD,MAAM,IAAI,GAAG,EAAE,GAAG,WAAW,CAAC,YAAY,EAAE,GAAG,WAAW,CAAC,eAAe,EAAE,CAAC;IAC7E,MAAM,GAAG,GAAG,CAAC,IAAY,EAAE,EAAE,CAAC,IAAI,IAAI,IAAI,CAAC;IAC3C,MAAM,UAAU,GAAG,KAAK,EAAE,QAAkB,EAAE,EAAE;QAC9C,MAAM,OAAO,GAAG,MAAM,IAAA,mBAAE,EAAC,QAAQ,EAAE;YACjC,GAAG,EAAE,OAAO,CAAC,UAAU;YACvB,QAAQ,EAAE,KAAK;YACf,SAAS,EAAE,IAAI;YACf,MAAM,EAAE,CAAC,oBAAoB,CAAC;SAC/B,CAAC,CAAC;QACH,OAAO,OAAO,CAAC,MAAM,GAAG,CAAC,CAAC;IAC5B,CAAC,CAAC;IAEF,cAAc;IACd,IAAI,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,MAAM,UAAU,CAAC,CAAC,gCAAgC,CAAC,CAAC,CAAC,EAAE,CAAC;QAC1E,OAAO,cAAc,CAAC;IACxB,CAAC;IAED,uBAAuB;IACvB,IACE,GAAG,CAAC,eAAe,CAAC;QACpB,GAAG,CAAC,kBAAkB,CAAC;QACvB,CAAC,MAAM,UAAU,CAAC,CAAC,wBAAwB,CAAC,CAAC,CAAC,EAC9C,CAAC;QACD,OAAO,YAAY,CAAC;IACtB,CAAC;IAED,4CAA4C;IAC5C,wHAAwH;IACxH,IAAI,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,MAAM,UAAU,CAAC,CAAC,gCAAgC,CAAC,CAAC,CAAC,EAAE,CAAC;QAC1E,OAAO,cAAc,CAAC;IACxB,CAAC;IAED,gBAAgB;IAChB,IACE,GAAG,CAAC,eAAe,CAAC;QACpB,CAAC,MAAM,UAAU,CAAC,CAAC,0BAA0B,CAAC,CAAC,CAAC,EAChD,CAAC;QACD,OAAO,SAAS,CAAC;IACnB,CAAC;IAED,iCAAiC;IACjC,IACE,GAAG,CAAC,iBAAiB,CAAC;QACtB,CAAC,MAAM,UAAU,CAAC,CAAC,4BAA4B,CAAC,CAAC,CAAC,EAClD,CAAC;QACD,OAAO,cAAc,CAAC;IACxB,CAAC;IAED,6BAA6B;IAC7B,IAAI,GAAG,CAAC,aAAa,CAAC,IAAI,CAAC,MAAM,UAAU,CAAC,CAAC,yBAAyB,CAAC,CAAC,CAAC,EAAE,CAAC;QAC1E,OAAO,cAAc,CAAC;IACxB,CAAC;IAED,YAAY;IACZ,IAAI,GAAG,CAAC,OAAO,CAAC,IAAI,CAAC,MAAM,UAAU,CAAC,CAAC,6BAA6B,CAAC,CAAC,CAAC,EAAE,CAAC;QACxE,OAAO,SAAS,CAAC;IACnB,CAAC;IAED,iGAAiG;IACjG,OAAO,cAAc,CAAC;AACxB,CAAC","sourcesContent":["import readEnv from 'read-env';\nimport { getPackageDotJson } from './clack-utils';\nimport type { WizardOptions } from './types';\nimport fg from 'fast-glob';\n\nexport function readEnvironment(): Record<string, unknown> {\n const result = readEnv('POSTHOG_WIZARD');\n\n return result;\n}\n\nexport async function detectEnvVarPrefix(\n options: WizardOptions,\n): Promise<string> {\n const packageJson = await getPackageDotJson(options);\n\n const deps = { ...packageJson.dependencies, ...packageJson.devDependencies };\n const has = (name: string) => name in deps;\n const hasAnyFile = async (patterns: string[]) => {\n const matches = await fg(patterns, {\n cwd: options.installDir,\n absolute: false,\n onlyFiles: true,\n ignore: ['**/node_modules/**'],\n });\n return matches.length > 0;\n };\n\n // --- Next.js\n if (has('next') || (await hasAnyFile(['**/next.config.{js,ts,mjs,cjs}']))) {\n return 'NEXT_PUBLIC_';\n }\n\n // --- Create React App\n if (\n has('react-scripts') ||\n has('create-react-app') ||\n (await hasAnyFile(['**/config-overrides.js']))\n ) {\n return 'REACT_APP_';\n }\n\n // --- Vite (vanilla, TanStack, Solid, etc.)\n // Note: Vite does not need PUBLIC_ but we use it to follow the docs, to improve the chances of an LLM getting it right.\n if (has('vite') || (await hasAnyFile(['**/vite.config.{js,ts,mjs,cjs}']))) {\n return 'VITE_PUBLIC_';\n }\n\n // --- SvelteKit\n if (\n has('@sveltejs/kit') ||\n (await hasAnyFile(['**/svelte.config.{js,ts}']))\n ) {\n return 'PUBLIC_';\n }\n\n // --- TanStack Start (uses Vite)\n if (\n has('@tanstack/start') ||\n (await hasAnyFile(['**/tanstack.config.{js,ts}']))\n ) {\n return 'VITE_PUBLIC_';\n }\n\n // --- SolidStart (uses Vite)\n if (has('solid-start') || (await hasAnyFile(['**/solid.config.{js,ts}']))) {\n return 'VITE_PUBLIC_';\n }\n\n // --- Astro\n if (has('astro') || (await hasAnyFile(['**/astro.config.{js,ts,mjs}']))) {\n return 'PUBLIC_';\n }\n\n // We default to Vite if we can't detect a specific framework, since it's the most commonly used.\n return 'VITE_PUBLIC_';\n}\n"]}
1
+ {"version":3,"file":"environment.js","sourceRoot":"","sources":["../../../src/utils/environment.ts"],"names":[],"mappings":";;;;;AAMA,kEAUC;AAED,0CAIC;AAED,gDAiEC;AAzFD,wDAA+B;AAC/B,+CAAkD;AAElD,0DAA2B;AAC3B,gDAA0C;AAE1C,SAAgB,2BAA2B;IACzC,IAAI,kBAAM,EAAE,CAAC;QACX,OAAO,KAAK,CAAC;IACf,CAAC;IAED,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,KAAK,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,KAAK,EAAE,CAAC;QACnD,OAAO,IAAI,CAAC;IACd,CAAC;IAED,OAAO,KAAK,CAAC;AACf,CAAC;AAED,SAAgB,eAAe;IAC7B,MAAM,MAAM,GAAG,IAAA,kBAAO,EAAC,gBAAgB,CAAC,CAAC;IAEzC,OAAO,MAAM,CAAC;AAChB,CAAC;AAEM,KAAK,UAAU,kBAAkB,CACtC,OAAsB;IAEtB,MAAM,WAAW,GAAG,MAAM,IAAA,+BAAiB,EAAC,OAAO,CAAC,CAAC;IAErD,MAAM,IAAI,GAAG,EAAE,GAAG,WAAW,CAAC,YAAY,EAAE,GAAG,WAAW,CAAC,eAAe,EAAE,CAAC;IAC7E,MAAM,GAAG,GAAG,CAAC,IAAY,EAAE,EAAE,CAAC,IAAI,IAAI,IAAI,CAAC;IAC3C,MAAM,UAAU,GAAG,KAAK,EAAE,QAAkB,EAAE,EAAE;QAC9C,MAAM,OAAO,GAAG,MAAM,IAAA,mBAAE,EAAC,QAAQ,EAAE;YACjC,GAAG,EAAE,OAAO,CAAC,UAAU;YACvB,QAAQ,EAAE,KAAK;YACf,SAAS,EAAE,IAAI;YACf,MAAM,EAAE,CAAC,oBAAoB,CAAC;SAC/B,CAAC,CAAC;QACH,OAAO,OAAO,CAAC,MAAM,GAAG,CAAC,CAAC;IAC5B,CAAC,CAAC;IAEF,cAAc;IACd,IAAI,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,MAAM,UAAU,CAAC,CAAC,gCAAgC,CAAC,CAAC,CAAC,EAAE,CAAC;QAC1E,OAAO,cAAc,CAAC;IACxB,CAAC;IAED,uBAAuB;IACvB,IACE,GAAG,CAAC,eAAe,CAAC;QACpB,GAAG,CAAC,kBAAkB,CAAC;QACvB,CAAC,MAAM,UAAU,CAAC,CAAC,wBAAwB,CAAC,CAAC,CAAC,EAC9C,CAAC;QACD,OAAO,YAAY,CAAC;IACtB,CAAC;IAED,4CAA4C;IAC5C,wHAAwH;IACxH,IAAI,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,MAAM,UAAU,CAAC,CAAC,gCAAgC,CAAC,CAAC,CAAC,EAAE,CAAC;QAC1E,OAAO,cAAc,CAAC;IACxB,CAAC;IAED,gBAAgB;IAChB,IACE,GAAG,CAAC,eAAe,CAAC;QACpB,CAAC,MAAM,UAAU,CAAC,CAAC,0BAA0B,CAAC,CAAC,CAAC,EAChD,CAAC;QACD,OAAO,SAAS,CAAC;IACnB,CAAC;IAED,iCAAiC;IACjC,IACE,GAAG,CAAC,iBAAiB,CAAC;QACtB,CAAC,MAAM,UAAU,CAAC,CAAC,4BAA4B,CAAC,CAAC,CAAC,EAClD,CAAC;QACD,OAAO,cAAc,CAAC;IACxB,CAAC;IAED,6BAA6B;IAC7B,IAAI,GAAG,CAAC,aAAa,CAAC,IAAI,CAAC,MAAM,UAAU,CAAC,CAAC,yBAAyB,CAAC,CAAC,CAAC,EAAE,CAAC;QAC1E,OAAO,cAAc,CAAC;IACxB,CAAC;IAED,YAAY;IACZ,IAAI,GAAG,CAAC,OAAO,CAAC,IAAI,CAAC,MAAM,UAAU,CAAC,CAAC,6BAA6B,CAAC,CAAC,CAAC,EAAE,CAAC;QACxE,OAAO,SAAS,CAAC;IACnB,CAAC;IAED,iGAAiG;IACjG,OAAO,cAAc,CAAC;AACxB,CAAC","sourcesContent":["import readEnv from 'read-env';\nimport { getPackageDotJson } from './clack-utils';\nimport type { WizardOptions } from './types';\nimport fg from 'fast-glob';\nimport { IS_DEV } from '../lib/constants';\n\nexport function isNonInteractiveEnvironment(): boolean {\n if (IS_DEV) {\n return false;\n }\n\n if (!process.stdout.isTTY || !process.stderr.isTTY) {\n return true;\n }\n\n return false;\n}\n\nexport function readEnvironment(): Record<string, unknown> {\n const result = readEnv('POSTHOG_WIZARD');\n\n return result;\n}\n\nexport async function detectEnvVarPrefix(\n options: WizardOptions,\n): Promise<string> {\n const packageJson = await getPackageDotJson(options);\n\n const deps = { ...packageJson.dependencies, ...packageJson.devDependencies };\n const has = (name: string) => name in deps;\n const hasAnyFile = async (patterns: string[]) => {\n const matches = await fg(patterns, {\n cwd: options.installDir,\n absolute: false,\n onlyFiles: true,\n ignore: ['**/node_modules/**'],\n });\n return matches.length > 0;\n };\n\n // --- Next.js\n if (has('next') || (await hasAnyFile(['**/next.config.{js,ts,mjs,cjs}']))) {\n return 'NEXT_PUBLIC_';\n }\n\n // --- Create React App\n if (\n has('react-scripts') ||\n has('create-react-app') ||\n (await hasAnyFile(['**/config-overrides.js']))\n ) {\n return 'REACT_APP_';\n }\n\n // --- Vite (vanilla, TanStack, Solid, etc.)\n // Note: Vite does not need PUBLIC_ but we use it to follow the docs, to improve the chances of an LLM getting it right.\n if (has('vite') || (await hasAnyFile(['**/vite.config.{js,ts,mjs,cjs}']))) {\n return 'VITE_PUBLIC_';\n }\n\n // --- SvelteKit\n if (\n has('@sveltejs/kit') ||\n (await hasAnyFile(['**/svelte.config.{js,ts}']))\n ) {\n return 'PUBLIC_';\n }\n\n // --- TanStack Start (uses Vite)\n if (\n has('@tanstack/start') ||\n (await hasAnyFile(['**/tanstack.config.{js,ts}']))\n ) {\n return 'VITE_PUBLIC_';\n }\n\n // --- SolidStart (uses Vite)\n if (has('solid-start') || (await hasAnyFile(['**/solid.config.{js,ts}']))) {\n return 'VITE_PUBLIC_';\n }\n\n // --- Astro\n if (has('astro') || (await hasAnyFile(['**/astro.config.{js,ts,mjs}']))) {\n return 'PUBLIC_';\n }\n\n // We default to Vite if we can't detect a specific framework, since it's the most commonly used.\n return 'VITE_PUBLIC_';\n}\n"]}
@@ -9,8 +9,17 @@ const zod_to_json_schema_1 = require("zod-to-json-schema");
9
9
  const urls_1 = require("./urls");
10
10
  const analytics_1 = require("./analytics");
11
11
  const axios_2 = require("axios");
12
+ const debug_1 = require("./debug");
12
13
  const query = async ({ message, model = 'o4-mini', region, schema, wizardHash, }) => {
13
- const jsonSchema = (0, zod_to_json_schema_1.zodToJsonSchema)(schema, 'schema').definitions;
14
+ const fullSchema = (0, zod_to_json_schema_1.zodToJsonSchema)(schema, 'schema');
15
+ const jsonSchema = fullSchema.definitions;
16
+ (0, debug_1.debug)('Full schema:', JSON.stringify(fullSchema, null, 2));
17
+ (0, debug_1.debug)('Query request:', {
18
+ url: `${(0, urls_1.getCloudUrlFromRegion)(region)}/api/wizard/query`,
19
+ wizardHash,
20
+ message: message.substring(0, 100) + '...',
21
+ json_schema: { ...jsonSchema, name: 'schema', strict: true },
22
+ });
14
23
  const response = await axios_1.default
15
24
  .post(`${(0, urls_1.getCloudUrlFromRegion)(region)}/api/wizard/query`, {
16
25
  message,
@@ -25,6 +34,7 @@ const query = async ({ message, model = 'o4-mini', region, schema, wizardHash, }
25
34
  },
26
35
  })
27
36
  .catch((error) => {
37
+ (0, debug_1.debug)('Query error:', error);
28
38
  if (error instanceof axios_2.AxiosError) {
29
39
  analytics_1.analytics.captureException(error, {
30
40
  response_status_code: error.response?.status,
@@ -36,8 +46,13 @@ const query = async ({ message, model = 'o4-mini', region, schema, wizardHash, }
36
46
  }
37
47
  throw error;
38
48
  });
49
+ (0, debug_1.debug)('Query response:', {
50
+ status: response.status,
51
+ data: response.data,
52
+ });
39
53
  const validation = schema.safeParse(response.data.data);
40
54
  if (!validation.success) {
55
+ (0, debug_1.debug)('Validation error:', validation.error);
41
56
  throw new Error(`Invalid response from wizard: ${validation.error.message}`);
42
57
  }
43
58
  if (process.env.NODE_ENV === 'test') {
@@ -1 +1 @@
1
- {"version":3,"file":"query.js","sourceRoot":"","sources":["../../../src/utils/query.ts"],"names":[],"mappings":";;;;;;AAAA,kDAA0B;AAE1B,2DAAqD;AAErD,iCAA+C;AAC/C,2CAAwC;AACxC,iCAAmC;AAU5B,MAAM,KAAK,GAAG,KAAK,EAAK,EAC7B,OAAO,EACP,KAAK,GAAG,SAAS,EACjB,MAAM,EACN,MAAM,EACN,UAAU,GACM,EAAc,EAAE;IAChC,MAAM,UAAU,GAAG,IAAA,oCAAe,EAAC,MAAM,EAAE,QAAQ,CAAC,CAAC,WAAW,CAAC;IAEjE,MAAM,QAAQ,GAAG,MAAM,eAAK;SACzB,IAAI,CACH,GAAG,IAAA,4BAAqB,EAAC,MAAM,CAAC,mBAAmB,EACnD;QACE,OAAO;QACP,KAAK;QACL,WAAW,EAAE,EAAE,GAAG,UAAU,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,EAAE,IAAI,EAAE;KAC7D,EACD;QACE,OAAO,EAAE;YACP,uBAAuB,EAAE,UAAU;YACnC,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,eAAe,KAAK,MAAM;gBACxC,CAAC,CAAC,EAAE,qCAAqC,EAAE,IAAI,EAAE;gBACjD,CAAC,CAAC,EAAE,CAAC;SACR;KACF,CACF;SACA,KAAK,CAAC,CAAC,KAAK,EAAE,EAAE;QACf,IAAI,KAAK,YAAY,kBAAU,EAAE,CAAC;YAChC,qBAAS,CAAC,gBAAgB,CAAC,KAAK,EAAE;gBAChC,oBAAoB,EAAE,KAAK,CAAC,QAAQ,EAAE,MAAM;gBAC5C,OAAO;gBACP,KAAK;gBACL,WAAW,EAAE,UAAU;gBACvB,IAAI,EAAE,oBAAoB;aAC3B,CAAC,CAAC;QACL,CAAC;QAED,MAAM,KAAK,CAAC;IACd,CAAC,CAAC,CAAC;IAEL,MAAM,UAAU,GAAG,MAAM,CAAC,SAAS,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAExD,IAAI,CAAC,UAAU,CAAC,OAAO,EAAE,CAAC;QACxB,MAAM,IAAI,KAAK,CACb,iCAAiC,UAAU,CAAC,KAAK,CAAC,OAAO,EAAE,CAC5D,CAAC;IACJ,CAAC;IAED,IAAI,OAAO,CAAC,GAAG,CAAC,QAAQ,KAAK,MAAM,EAAE,CAAC;QACpC,MAAM,EAAE,cAAc,EAAE,GAAG,MAAM,MAAM,CACrC,0CAA0C,CAC3C,CAAC;QAEF,MAAM,WAAW,GAAG,IAAI,CAAC,SAAS,CAAC;YACjC,OAAO;YACP,KAAK;YACL,WAAW,EAAE,EAAE,GAAG,UAAU,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,EAAE,IAAI,EAAE;SAC7D,CAAC,CAAC;QAEH,cAAc,CAAC,gBAAgB,CAAC,WAAW,EAAE,UAAU,CAAC,IAAI,CAAC,CAAC;IAChE,CAAC;IAED,OAAO,UAAU,CAAC,IAAI,CAAC;AACzB,CAAC,CAAC;AA/DW,QAAA,KAAK,SA+DhB","sourcesContent":["import axios from 'axios';\nimport type { ZodSchema } from 'zod';\nimport { zodToJsonSchema } from 'zod-to-json-schema';\nimport type { AIModel, CloudRegion } from './types';\nimport { getCloudUrlFromRegion } from './urls';\nimport { analytics } from './analytics';\nimport { AxiosError } from 'axios';\n\nexport interface QueryOptions<S> {\n message: string;\n model?: AIModel;\n region: CloudRegion;\n schema: ZodSchema<S>;\n wizardHash: string;\n}\n\nexport const query = async <S>({\n message,\n model = 'o4-mini',\n region,\n schema,\n wizardHash,\n}: QueryOptions<S>): Promise<S> => {\n const jsonSchema = zodToJsonSchema(schema, 'schema').definitions;\n\n const response = await axios\n .post<{ data: unknown }>(\n `${getCloudUrlFromRegion(region)}/api/wizard/query`,\n {\n message,\n model,\n json_schema: { ...jsonSchema, name: 'schema', strict: true },\n },\n {\n headers: {\n 'X-PostHog-Wizard-Hash': wizardHash,\n ...(process.env.RECORD_FIXTURES === 'true'\n ? { 'X-PostHog-Wizard-Fixture-Generation': true }\n : {}),\n },\n },\n )\n .catch((error) => {\n if (error instanceof AxiosError) {\n analytics.captureException(error, {\n response_status_code: error.response?.status,\n message,\n model,\n json_schema: jsonSchema,\n type: 'wizard_query_error',\n });\n }\n\n throw error;\n });\n\n const validation = schema.safeParse(response.data.data);\n\n if (!validation.success) {\n throw new Error(\n `Invalid response from wizard: ${validation.error.message}`,\n );\n }\n\n if (process.env.NODE_ENV === 'test') {\n const { fixtureTracker } = await import(\n '../../e2e-tests/mocks/fixture-tracker.js'\n );\n\n const requestBody = JSON.stringify({\n message,\n model,\n json_schema: { ...jsonSchema, name: 'schema', strict: true },\n });\n\n fixtureTracker.saveQueryFixture(requestBody, validation.data);\n }\n\n return validation.data;\n};\n"]}
1
+ {"version":3,"file":"query.js","sourceRoot":"","sources":["../../../src/utils/query.ts"],"names":[],"mappings":"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","sourcesContent":["import axios from 'axios';\nimport type { ZodSchema } from 'zod';\nimport { zodToJsonSchema } from 'zod-to-json-schema';\nimport type { AIModel, CloudRegion } from './types';\nimport { getCloudUrlFromRegion } from './urls';\nimport { analytics } from './analytics';\nimport { AxiosError } from 'axios';\nimport { debug } from './debug';\n\nexport interface QueryOptions<S> {\n message: string;\n model?: AIModel;\n region: CloudRegion;\n schema: ZodSchema<S>;\n wizardHash: string;\n}\n\nexport const query = async <S>({\n message,\n model = 'o4-mini',\n region,\n schema,\n wizardHash,\n}: QueryOptions<S>): Promise<S> => {\n const fullSchema = zodToJsonSchema(schema, 'schema');\n const jsonSchema = fullSchema.definitions;\n\n debug('Full schema:', JSON.stringify(fullSchema, null, 2));\n debug('Query request:', {\n url: `${getCloudUrlFromRegion(region)}/api/wizard/query`,\n wizardHash,\n message: message.substring(0, 100) + '...',\n json_schema: { ...jsonSchema, name: 'schema', strict: true },\n });\n\n const response = await axios\n .post<{ data: unknown }>(\n `${getCloudUrlFromRegion(region)}/api/wizard/query`,\n {\n message,\n model,\n json_schema: { ...jsonSchema, name: 'schema', strict: true },\n },\n {\n headers: {\n 'X-PostHog-Wizard-Hash': wizardHash,\n ...(process.env.RECORD_FIXTURES === 'true'\n ? { 'X-PostHog-Wizard-Fixture-Generation': true }\n : {}),\n },\n },\n )\n .catch((error) => {\n debug('Query error:', error);\n\n if (error instanceof AxiosError) {\n analytics.captureException(error, {\n response_status_code: error.response?.status,\n message,\n model,\n json_schema: jsonSchema,\n type: 'wizard_query_error',\n });\n }\n\n throw error;\n });\n\n debug('Query response:', {\n status: response.status,\n data: response.data,\n });\n\n const validation = schema.safeParse(response.data.data);\n\n if (!validation.success) {\n debug('Validation error:', validation.error);\n throw new Error(\n `Invalid response from wizard: ${validation.error.message}`,\n );\n }\n\n if (process.env.NODE_ENV === 'test') {\n const { fixtureTracker } = await import(\n '../../e2e-tests/mocks/fixture-tracker.js'\n );\n\n const requestBody = JSON.stringify({\n message,\n model,\n json_schema: { ...jsonSchema, name: 'schema', strict: true },\n });\n\n fixtureTracker.saveQueryFixture(requestBody, validation.data);\n }\n\n return validation.data;\n};\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@posthog/wizard",
3
- "version": "1.8.7",
3
+ "version": "1.10.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",