@posthog/wizard 1.19.0 → 1.21.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/src/lib/agent-interface.d.ts +36 -1
- package/dist/src/lib/agent-interface.js +119 -4
- package/dist/src/lib/agent-interface.js.map +1 -1
- package/dist/src/lib/agent-runner.d.ts +7 -0
- package/dist/src/lib/agent-runner.js +201 -0
- package/dist/src/lib/agent-runner.js.map +1 -0
- package/dist/src/lib/constants.d.ts +1 -0
- package/dist/src/lib/constants.js +2 -1
- package/dist/src/lib/constants.js.map +1 -1
- package/dist/src/lib/framework-config.d.ts +95 -0
- package/dist/src/lib/framework-config.js +3 -0
- package/dist/src/lib/framework-config.js.map +1 -0
- package/dist/src/nextjs/nextjs-wizard-agent.d.ts +1 -1
- package/dist/src/nextjs/nextjs-wizard-agent.js +69 -133
- package/dist/src/nextjs/nextjs-wizard-agent.js.map +1 -1
- package/dist/src/steps/add-mcp-server-to-clients/MCPClient.d.ts +2 -7
- package/dist/src/steps/add-mcp-server-to-clients/MCPClient.js.map +1 -1
- package/dist/src/steps/add-mcp-server-to-clients/clients/claude-code.d.ts +33 -7
- package/dist/src/steps/add-mcp-server-to-clients/clients/claude-code.js +2 -47
- package/dist/src/steps/add-mcp-server-to-clients/clients/claude-code.js.map +1 -1
- package/dist/src/steps/add-mcp-server-to-clients/clients/claude.d.ts +33 -6
- package/dist/src/steps/add-mcp-server-to-clients/clients/codex.d.ts +33 -6
- package/dist/src/steps/add-mcp-server-to-clients/clients/cursor.d.ts +35 -7
- package/dist/src/steps/add-mcp-server-to-clients/clients/cursor.js +4 -1
- package/dist/src/steps/add-mcp-server-to-clients/clients/cursor.js.map +1 -1
- package/dist/src/steps/add-mcp-server-to-clients/clients/visual-studio-code.d.ts +47 -7
- package/dist/src/steps/add-mcp-server-to-clients/clients/visual-studio-code.js +25 -5
- package/dist/src/steps/add-mcp-server-to-clients/clients/visual-studio-code.js.map +1 -1
- package/dist/src/steps/add-mcp-server-to-clients/clients/zed.d.ts +47 -16
- package/dist/src/steps/add-mcp-server-to-clients/clients/zed.js +22 -11
- package/dist/src/steps/add-mcp-server-to-clients/clients/zed.js.map +1 -1
- package/dist/src/steps/add-mcp-server-to-clients/defaults.d.ts +40 -6
- package/dist/src/steps/add-mcp-server-to-clients/defaults.js +29 -8
- package/dist/src/steps/add-mcp-server-to-clients/defaults.js.map +1 -1
- package/dist/src/utils/__tests__/analytics.test.js +11 -10
- package/dist/src/utils/__tests__/analytics.test.js.map +1 -1
- package/dist/src/utils/analytics.js +1 -1
- package/dist/src/utils/analytics.js.map +1 -1
- package/dist/src/utils/oauth.js +42 -4
- package/dist/src/utils/oauth.js.map +1 -1
- package/package.json +2 -2
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
import type { Integration } from './constants';
|
|
2
|
+
import type { WizardOptions } from '../utils/types';
|
|
3
|
+
/**
|
|
4
|
+
* Configuration interface for framework-specific agent integrations.
|
|
5
|
+
* Each framework exports a FrameworkConfig that the universal runner uses.
|
|
6
|
+
*/
|
|
7
|
+
export interface FrameworkConfig {
|
|
8
|
+
metadata: FrameworkMetadata;
|
|
9
|
+
detection: FrameworkDetection;
|
|
10
|
+
environment: EnvironmentConfig;
|
|
11
|
+
analytics: AnalyticsConfig;
|
|
12
|
+
prompts: PromptConfig;
|
|
13
|
+
ui: UIConfig;
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* Basic framework information and documentation
|
|
17
|
+
*/
|
|
18
|
+
export interface FrameworkMetadata {
|
|
19
|
+
/** Display name (e.g., "Next.js", "React") */
|
|
20
|
+
name: string;
|
|
21
|
+
/** Integration type from constants */
|
|
22
|
+
integration: Integration;
|
|
23
|
+
/** URL to framework-specific PostHog docs */
|
|
24
|
+
docsUrl: string;
|
|
25
|
+
/** Message shown when user declines AI consent */
|
|
26
|
+
abortMessage: string;
|
|
27
|
+
/**
|
|
28
|
+
* Optional function to gather framework-specific context before agent runs.
|
|
29
|
+
* For Next.js: detects router type
|
|
30
|
+
* For React Native: detects Expo vs bare
|
|
31
|
+
*/
|
|
32
|
+
gatherContext?: (options: WizardOptions) => Promise<Record<string, any>>;
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* Framework detection and version handling
|
|
36
|
+
*/
|
|
37
|
+
export interface FrameworkDetection {
|
|
38
|
+
/** Package name to check in package.json (e.g., "next", "react") */
|
|
39
|
+
packageName: string;
|
|
40
|
+
/** Human-readable name for error messages (e.g., "Next.js") */
|
|
41
|
+
packageDisplayName: string;
|
|
42
|
+
/** Extract version from package.json */
|
|
43
|
+
getVersion: (packageJson: any) => string | undefined;
|
|
44
|
+
/** Optional: Convert version to analytics bucket (e.g., "15.x") */
|
|
45
|
+
getVersionBucket?: (version: string) => string;
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* Environment variable configuration
|
|
49
|
+
*/
|
|
50
|
+
export interface EnvironmentConfig {
|
|
51
|
+
/** Whether to upload env vars to hosting providers post-agent */
|
|
52
|
+
uploadToHosting: boolean;
|
|
53
|
+
/**
|
|
54
|
+
* Build the environment variables object for this framework.
|
|
55
|
+
* Returns the exact variable names and values to upload to hosting providers.
|
|
56
|
+
*/
|
|
57
|
+
getEnvVars: (apiKey: string, host: string) => Record<string, string>;
|
|
58
|
+
}
|
|
59
|
+
/**
|
|
60
|
+
* Analytics configuration
|
|
61
|
+
*/
|
|
62
|
+
export interface AnalyticsConfig {
|
|
63
|
+
/** Generate tags from context (e.g., { 'nextjs-version': '15.x', 'router': 'app' }) */
|
|
64
|
+
getTags: (context: any) => Record<string, any>;
|
|
65
|
+
/** Optional: Additional event properties */
|
|
66
|
+
getEventProperties?: (context: any) => Record<string, any>;
|
|
67
|
+
}
|
|
68
|
+
/**
|
|
69
|
+
* Prompt configuration
|
|
70
|
+
*/
|
|
71
|
+
export interface PromptConfig {
|
|
72
|
+
/**
|
|
73
|
+
* Optional: Additional context lines to append to base prompt
|
|
74
|
+
* For Next.js: "- Router: app"
|
|
75
|
+
* For React Native: "- Platform: Expo"
|
|
76
|
+
*/
|
|
77
|
+
getAdditionalContextLines?: (context: any) => string[];
|
|
78
|
+
}
|
|
79
|
+
/**
|
|
80
|
+
* UI messaging configuration
|
|
81
|
+
*/
|
|
82
|
+
export interface UIConfig {
|
|
83
|
+
/** Welcome message for wizard start */
|
|
84
|
+
welcomeMessage: string;
|
|
85
|
+
/** Spinner message while agent runs */
|
|
86
|
+
spinnerMessage: string;
|
|
87
|
+
/** Success message when agent completes */
|
|
88
|
+
successMessage: string;
|
|
89
|
+
/** Estimated time for agent to complete (in minutes) */
|
|
90
|
+
estimatedDurationMinutes: number;
|
|
91
|
+
/** Generate "What the agent did" bullets from context */
|
|
92
|
+
getOutroChanges: (context: any) => string[];
|
|
93
|
+
/** Generate "Next steps" bullets from context */
|
|
94
|
+
getOutroNextSteps: (context: any) => string[];
|
|
95
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"framework-config.js","sourceRoot":"","sources":["../../../src/lib/framework-config.ts"],"names":[],"mappings":"","sourcesContent":["import type { Integration } from './constants';\nimport type { WizardOptions } from '../utils/types';\n\n/**\n * Configuration interface for framework-specific agent integrations.\n * Each framework exports a FrameworkConfig that the universal runner uses.\n */\nexport interface FrameworkConfig {\n metadata: FrameworkMetadata;\n detection: FrameworkDetection;\n environment: EnvironmentConfig;\n analytics: AnalyticsConfig;\n prompts: PromptConfig;\n ui: UIConfig;\n}\n\n/**\n * Basic framework information and documentation\n */\nexport interface FrameworkMetadata {\n /** Display name (e.g., \"Next.js\", \"React\") */\n name: string;\n\n /** Integration type from constants */\n integration: Integration;\n\n /** URL to framework-specific PostHog docs */\n docsUrl: string;\n\n /** Message shown when user declines AI consent */\n abortMessage: string;\n\n /**\n * Optional function to gather framework-specific context before agent runs.\n * For Next.js: detects router type\n * For React Native: detects Expo vs bare\n */\n gatherContext?: (options: WizardOptions) => Promise<Record<string, any>>;\n}\n\n/**\n * Framework detection and version handling\n */\nexport interface FrameworkDetection {\n /** Package name to check in package.json (e.g., \"next\", \"react\") */\n packageName: string;\n\n /** Human-readable name for error messages (e.g., \"Next.js\") */\n packageDisplayName: string;\n\n /** Extract version from package.json */\n getVersion: (packageJson: any) => string | undefined;\n\n /** Optional: Convert version to analytics bucket (e.g., \"15.x\") */\n getVersionBucket?: (version: string) => string;\n}\n\n/**\n * Environment variable configuration\n */\nexport interface EnvironmentConfig {\n /** Whether to upload env vars to hosting providers post-agent */\n uploadToHosting: boolean;\n\n /**\n * Build the environment variables object for this framework.\n * Returns the exact variable names and values to upload to hosting providers.\n */\n getEnvVars: (apiKey: string, host: string) => Record<string, string>;\n}\n\n/**\n * Analytics configuration\n */\nexport interface AnalyticsConfig {\n /** Generate tags from context (e.g., { 'nextjs-version': '15.x', 'router': 'app' }) */\n getTags: (context: any) => Record<string, any>;\n\n /** Optional: Additional event properties */\n getEventProperties?: (context: any) => Record<string, any>;\n}\n\n/**\n * Prompt configuration\n */\nexport interface PromptConfig {\n /**\n * Optional: Additional context lines to append to base prompt\n * For Next.js: \"- Router: app\"\n * For React Native: \"- Platform: Expo\"\n */\n getAdditionalContextLines?: (context: any) => string[];\n}\n\n/**\n * UI messaging configuration\n */\nexport interface UIConfig {\n /** Welcome message for wizard start */\n welcomeMessage: string;\n\n /** Spinner message while agent runs */\n spinnerMessage: string;\n\n /** Success message when agent completes */\n successMessage: string;\n\n /** Estimated time for agent to complete (in minutes) */\n estimatedDurationMinutes: number;\n\n /** Generate \"What the agent did\" bullets from context */\n getOutroChanges: (context: any) => string[];\n\n /** Generate \"Next steps\" bullets from context */\n getOutroNextSteps: (context: any) => string[];\n}\n"]}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { WizardOptions } from '../utils/types';
|
|
2
2
|
/**
|
|
3
|
-
*
|
|
3
|
+
* Next.js wizard powered by the universal agent runner.
|
|
4
4
|
*/
|
|
5
5
|
export declare function runNextjsWizardAgent(options: WizardOptions): Promise<void>;
|
|
@@ -1,146 +1,82 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
-
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
-
};
|
|
5
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
3
|
exports.runNextjsWizardAgent = runNextjsWizardAgent;
|
|
7
|
-
|
|
8
|
-
const
|
|
4
|
+
const debug_1 = require("../utils/debug");
|
|
5
|
+
const agent_runner_1 = require("../lib/agent-runner");
|
|
6
|
+
const constants_1 = require("../lib/constants");
|
|
9
7
|
const package_json_1 = require("../utils/package-json");
|
|
10
8
|
const utils_1 = require("./utils");
|
|
11
|
-
const clack_1 = __importDefault(require("../utils/clack"));
|
|
12
|
-
const constants_1 = require("../lib/constants");
|
|
13
|
-
const analytics_1 = require("../utils/analytics");
|
|
14
|
-
const clack_utils_2 = require("../utils/clack-utils");
|
|
15
|
-
const urls_1 = require("../utils/urls");
|
|
16
|
-
const chalk_1 = __importDefault(require("chalk"));
|
|
17
|
-
const steps_1 = require("../steps");
|
|
18
|
-
const debug_1 = require("../utils/debug");
|
|
19
|
-
const agent_interface_1 = require("../lib/agent-interface");
|
|
20
9
|
/**
|
|
21
|
-
*
|
|
10
|
+
* Next.js framework configuration for the universal agent runner.
|
|
11
|
+
*/
|
|
12
|
+
const NEXTJS_AGENT_CONFIG = {
|
|
13
|
+
metadata: {
|
|
14
|
+
name: 'Next.js',
|
|
15
|
+
integration: constants_1.Integration.nextjs,
|
|
16
|
+
docsUrl: 'https://posthog.com/docs/libraries/next-js',
|
|
17
|
+
abortMessage: 'This wizard uses an LLM agent to intelligently modify your project. Please view the docs to setup Next.js manually instead: https://posthog.com/docs/libraries/next-js',
|
|
18
|
+
gatherContext: async (options) => {
|
|
19
|
+
const router = await (0, utils_1.getNextJsRouter)(options);
|
|
20
|
+
return { router };
|
|
21
|
+
},
|
|
22
|
+
},
|
|
23
|
+
detection: {
|
|
24
|
+
packageName: 'next',
|
|
25
|
+
packageDisplayName: 'Next.js',
|
|
26
|
+
getVersion: (packageJson) => (0, package_json_1.getPackageVersion)('next', packageJson),
|
|
27
|
+
getVersionBucket: utils_1.getNextJsVersionBucket,
|
|
28
|
+
},
|
|
29
|
+
environment: {
|
|
30
|
+
uploadToHosting: true,
|
|
31
|
+
getEnvVars: (apiKey, host) => ({
|
|
32
|
+
NEXT_PUBLIC_POSTHOG_KEY: apiKey,
|
|
33
|
+
NEXT_PUBLIC_POSTHOG_HOST: host,
|
|
34
|
+
}),
|
|
35
|
+
},
|
|
36
|
+
analytics: {
|
|
37
|
+
getTags: (context) => {
|
|
38
|
+
const router = context.router;
|
|
39
|
+
return {
|
|
40
|
+
router: router === utils_1.NextJsRouter.APP_ROUTER ? 'app' : 'pages',
|
|
41
|
+
};
|
|
42
|
+
},
|
|
43
|
+
},
|
|
44
|
+
prompts: {
|
|
45
|
+
getAdditionalContextLines: (context) => {
|
|
46
|
+
const router = context.router;
|
|
47
|
+
const routerType = router === utils_1.NextJsRouter.APP_ROUTER ? 'app' : 'pages';
|
|
48
|
+
return [`Router: ${routerType}`];
|
|
49
|
+
},
|
|
50
|
+
},
|
|
51
|
+
ui: {
|
|
52
|
+
welcomeMessage: 'PostHog Next.js wizard (agent-powered)',
|
|
53
|
+
spinnerMessage: 'Writing your PostHog setup with events, error capture and more...',
|
|
54
|
+
successMessage: 'PostHog integration complete',
|
|
55
|
+
estimatedDurationMinutes: 8,
|
|
56
|
+
getOutroChanges: (context) => {
|
|
57
|
+
const router = context.router;
|
|
58
|
+
const routerName = (0, utils_1.getNextJsRouterName)(router);
|
|
59
|
+
return [
|
|
60
|
+
`Analyzed your Next.js project structure (${routerName})`,
|
|
61
|
+
`Created and configured PostHog initializers`,
|
|
62
|
+
`Integrated PostHog into your application`,
|
|
63
|
+
];
|
|
64
|
+
},
|
|
65
|
+
getOutroNextSteps: () => {
|
|
66
|
+
return [
|
|
67
|
+
'Start your development server to see PostHog in action',
|
|
68
|
+
'Visit your PostHog dashboard to see incoming events',
|
|
69
|
+
];
|
|
70
|
+
},
|
|
71
|
+
},
|
|
72
|
+
};
|
|
73
|
+
/**
|
|
74
|
+
* Next.js wizard powered by the universal agent runner.
|
|
22
75
|
*/
|
|
23
76
|
async function runNextjsWizardAgent(options) {
|
|
24
77
|
if (options.debug) {
|
|
25
78
|
(0, debug_1.enableDebugLogs)();
|
|
26
79
|
}
|
|
27
|
-
(0,
|
|
28
|
-
wizardName: 'PostHog Next.js wizard (agent-powered)',
|
|
29
|
-
});
|
|
30
|
-
clack_1.default.log.info('🧙 The wizard has chosen you to try the next-generation agent integration for Next.js.\n\nStand by for the good stuff, and let me know how it goes:\n\ndanilo@posthog.com');
|
|
31
|
-
const aiConsent = await (0, clack_utils_1.askForAIConsent)(options);
|
|
32
|
-
if (!aiConsent) {
|
|
33
|
-
await (0, clack_utils_1.abort)('This wizard uses an LLM agent to intelligently modify your project. Please view the docs to setup Next.js manually instead: https://posthog.com/docs/libraries/next-js', 0);
|
|
34
|
-
}
|
|
35
|
-
const cloudRegion = options.cloudRegion ?? (await (0, clack_utils_2.askForCloudRegion)());
|
|
36
|
-
const typeScriptDetected = (0, clack_utils_1.isUsingTypeScript)(options);
|
|
37
|
-
await (0, clack_utils_1.confirmContinueIfNoOrDirtyGitRepo)(options);
|
|
38
|
-
const packageJson = await (0, clack_utils_1.getPackageDotJson)(options);
|
|
39
|
-
await (0, clack_utils_1.ensurePackageIsInstalled)(packageJson, 'next', 'Next.js');
|
|
40
|
-
const nextVersion = (0, package_json_1.getPackageVersion)('next', packageJson);
|
|
41
|
-
analytics_1.analytics.setTag('nextjs-version', (0, utils_1.getNextJsVersionBucket)(nextVersion));
|
|
42
|
-
analytics_1.analytics.capture(constants_1.WIZARD_INTERACTION_EVENT_NAME, {
|
|
43
|
-
action: 'started agent integration',
|
|
44
|
-
});
|
|
45
|
-
const { projectApiKey, host, accessToken } = await (0, clack_utils_1.getOrAskForProjectData)({
|
|
46
|
-
...options,
|
|
47
|
-
cloudRegion,
|
|
48
|
-
});
|
|
49
|
-
const router = await (0, utils_1.getNextJsRouter)(options);
|
|
50
|
-
const routerType = router === utils_1.NextJsRouter.APP_ROUTER ? 'app' : 'pages';
|
|
51
|
-
const spinner = clack_1.default.spinner();
|
|
52
|
-
const agent = await (0, agent_interface_1.initializeAgent)({
|
|
53
|
-
workingDirectory: options.installDir,
|
|
54
|
-
posthogMcpUrl: 'https://mcp.posthog.com/mcp',
|
|
55
|
-
posthogApiKey: accessToken,
|
|
56
|
-
debug: false,
|
|
57
|
-
}, options, spinner);
|
|
58
|
-
const integrationPrompt = buildIntegrationPrompt({
|
|
59
|
-
framework: 'Next.js',
|
|
60
|
-
version: nextVersion || 'latest',
|
|
61
|
-
router: routerType,
|
|
62
|
-
typescript: typeScriptDetected,
|
|
63
|
-
projectApiKey,
|
|
64
|
-
host,
|
|
65
|
-
});
|
|
66
|
-
await (0, agent_interface_1.runAgent)(agent, integrationPrompt, options, spinner, {
|
|
67
|
-
estimatedDurationMinutes: 8,
|
|
68
|
-
spinnerMessage: 'Writing your PostHog setup with events, error capture and more...',
|
|
69
|
-
successMessage: 'PostHog integration complete',
|
|
70
|
-
errorMessage: 'Integration failed',
|
|
71
|
-
});
|
|
72
|
-
const { relativeEnvFilePath, addedEnvVariables } = await (0, steps_1.addOrUpdateEnvironmentVariablesStep)({
|
|
73
|
-
variables: {
|
|
74
|
-
NEXT_PUBLIC_POSTHOG_KEY: projectApiKey,
|
|
75
|
-
NEXT_PUBLIC_POSTHOG_HOST: host,
|
|
76
|
-
},
|
|
77
|
-
installDir: options.installDir,
|
|
78
|
-
integration: constants_1.Integration.nextjs,
|
|
79
|
-
});
|
|
80
|
-
const uploadedEnvVars = await (0, steps_1.uploadEnvironmentVariablesStep)({
|
|
81
|
-
NEXT_PUBLIC_POSTHOG_KEY: projectApiKey,
|
|
82
|
-
NEXT_PUBLIC_POSTHOG_HOST: host,
|
|
83
|
-
}, {
|
|
84
|
-
integration: constants_1.Integration.nextjs,
|
|
85
|
-
options,
|
|
86
|
-
});
|
|
87
|
-
await (0, steps_1.addMCPServerToClientsStep)({
|
|
88
|
-
cloudRegion,
|
|
89
|
-
integration: constants_1.Integration.nextjs,
|
|
90
|
-
});
|
|
91
|
-
const continueUrl = options.signup
|
|
92
|
-
? `${(0, urls_1.getCloudUrlFromRegion)(cloudRegion)}/products?source=wizard`
|
|
93
|
-
: undefined;
|
|
94
|
-
const changes = [
|
|
95
|
-
addedEnvVariables
|
|
96
|
-
? `Added your Project API key to your ${relativeEnvFilePath} file`
|
|
97
|
-
: '',
|
|
98
|
-
uploadedEnvVars.length > 0
|
|
99
|
-
? `Uploaded your Project API key to your hosting provider`
|
|
100
|
-
: '',
|
|
101
|
-
].filter(Boolean);
|
|
102
|
-
const nextSteps = [
|
|
103
|
-
uploadedEnvVars.length === 0
|
|
104
|
-
? `Upload your Project API key to your hosting provider`
|
|
105
|
-
: '',
|
|
106
|
-
].filter(Boolean);
|
|
107
|
-
const outroMessage = `
|
|
108
|
-
${chalk_1.default.green('Successfully installed PostHog!')}
|
|
109
|
-
|
|
110
|
-
${chalk_1.default.cyan('What the agent did:')}
|
|
111
|
-
• Analyzed your Next.js project structure (${routerType} router)
|
|
112
|
-
• Created and configured PostHog initializers
|
|
113
|
-
• Integrated PostHog into your application
|
|
114
|
-
${changes.map((change) => `• ${change}`).join('\n')}
|
|
115
|
-
|
|
116
|
-
${chalk_1.default.yellow('Next steps:')}
|
|
117
|
-
• Start your development server to see PostHog in action
|
|
118
|
-
• Visit your PostHog dashboard to see incoming events
|
|
119
|
-
${nextSteps.map((step) => `• ${step}`).join('\n')}
|
|
120
|
-
|
|
121
|
-
Learn more about PostHog + Next.js: ${chalk_1.default.cyan('https://posthog.com/docs/libraries/next-js')}
|
|
122
|
-
${continueUrl ? `\nContinue onboarding: ${chalk_1.default.cyan(continueUrl)}\n` : ``}
|
|
123
|
-
${chalk_1.default.dim('Note: This wizard uses an LLM agent to analyze and modify your project. Please review the changes made.')}
|
|
124
|
-
|
|
125
|
-
${chalk_1.default.dim(`How did this work for you? Drop me a line: danilo@posthog.com`)}`;
|
|
126
|
-
clack_1.default.outro(outroMessage);
|
|
127
|
-
await analytics_1.analytics.shutdown('success');
|
|
128
|
-
}
|
|
129
|
-
function buildIntegrationPrompt(context) {
|
|
130
|
-
return `You have access to the PostHog MCP server which provides an integration resource to integrate PostHog into this ${context.framework} project.
|
|
131
|
-
|
|
132
|
-
Project context:
|
|
133
|
-
- Framework: ${context.framework} ${context.version}
|
|
134
|
-
- Router: ${context.router}
|
|
135
|
-
- TypeScript: ${context.typescript ? 'Yes' : 'No'}
|
|
136
|
-
- PostHog API Key: ${context.projectApiKey}
|
|
137
|
-
- PostHog Host: ${context.host}
|
|
138
|
-
|
|
139
|
-
Instructions:
|
|
140
|
-
1. Call the PostHog MCP's resource for setup: posthog://integration/workflow/setup/begin
|
|
141
|
-
2. Follow all instructions provided
|
|
142
|
-
|
|
143
|
-
The PostHog MCP will provide specific integration code and instructions. Please follow them carefully. Be sure to look for lockfiles to determine the appropriate package manager to use when installing PostHog. Do not manually edit the package.json file.
|
|
144
|
-
`;
|
|
80
|
+
await (0, agent_runner_1.runAgentWizard)(NEXTJS_AGENT_CONFIG, options);
|
|
145
81
|
}
|
|
146
82
|
//# sourceMappingURL=nextjs-wizard-agent.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"nextjs-wizard-agent.js","sourceRoot":"","sources":["../../../src/nextjs/nextjs-wizard-agent.ts"],"names":[],"mappings":";;;;;AA+BA,oDAqJC;AApLD,oEAAoE;AACpE,sDAS8B;AAC9B,wDAA0D;AAC1D,mCAAgF;AAChF,2DAAmC;AACnC,gDAA8E;AAC9E,kDAA+C;AAE/C,sDAAyD;AACzD,wCAAsD;AACtD,kDAA0B;AAC1B,oCAIkB;AAClB,0CAAiD;AACjD,4DAAmE;AAEnE;;GAEG;AACI,KAAK,UAAU,oBAAoB,CACxC,OAAsB;IAEtB,IAAI,OAAO,CAAC,KAAK,EAAE,CAAC;QAClB,IAAA,uBAAe,GAAE,CAAC;IACpB,CAAC;IAED,IAAA,0BAAY,EAAC;QACX,UAAU,EAAE,wCAAwC;KACrD,CAAC,CAAC;IAEH,eAAK,CAAC,GAAG,CAAC,IAAI,CACZ,2KAA2K,CAC5K,CAAC;IAEF,MAAM,SAAS,GAAG,MAAM,IAAA,6BAAe,EAAC,OAAO,CAAC,CAAC;IAEjD,IAAI,CAAC,SAAS,EAAE,CAAC;QACf,MAAM,IAAA,mBAAK,EACT,wKAAwK,EACxK,CAAC,CACF,CAAC;IACJ,CAAC;IAED,MAAM,WAAW,GAAG,OAAO,CAAC,WAAW,IAAI,CAAC,MAAM,IAAA,+BAAiB,GAAE,CAAC,CAAC;IACvE,MAAM,kBAAkB,GAAG,IAAA,+BAAiB,EAAC,OAAO,CAAC,CAAC;IAEtD,MAAM,IAAA,+CAAiC,EAAC,OAAO,CAAC,CAAC;IAEjD,MAAM,WAAW,GAAG,MAAM,IAAA,+BAAiB,EAAC,OAAO,CAAC,CAAC;IACrD,MAAM,IAAA,sCAAwB,EAAC,WAAW,EAAE,MAAM,EAAE,SAAS,CAAC,CAAC;IAE/D,MAAM,WAAW,GAAG,IAAA,gCAAiB,EAAC,MAAM,EAAE,WAAW,CAAC,CAAC;IAC3D,qBAAS,CAAC,MAAM,CAAC,gBAAgB,EAAE,IAAA,8BAAsB,EAAC,WAAW,CAAC,CAAC,CAAC;IAExE,qBAAS,CAAC,OAAO,CAAC,yCAA6B,EAAE;QAC/C,MAAM,EAAE,2BAA2B;KACpC,CAAC,CAAC;IAEH,MAAM,EAAE,aAAa,EAAE,IAAI,EAAE,WAAW,EAAE,GAAG,MAAM,IAAA,oCAAsB,EAAC;QACxE,GAAG,OAAO;QACV,WAAW;KACZ,CAAC,CAAC;IAEH,MAAM,MAAM,GAAG,MAAM,IAAA,uBAAe,EAAC,OAAO,CAAC,CAAC;IAC9C,MAAM,UAAU,GAAG,MAAM,KAAK,oBAAY,CAAC,UAAU,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,OAAO,CAAC;IAExE,MAAM,OAAO,GAAG,eAAK,CAAC,OAAO,EAAE,CAAC;IAEhC,MAAM,KAAK,GAAG,MAAM,IAAA,iCAAe,EACjC;QACE,gBAAgB,EAAE,OAAO,CAAC,UAAU;QACpC,aAAa,EAAE,6BAA6B;QAC5C,aAAa,EAAE,WAAW;QAC1B,KAAK,EAAE,KAAK;KACb,EACD,OAAO,EACP,OAAO,CACR,CAAC;IAEF,MAAM,iBAAiB,GAAG,sBAAsB,CAAC;QAC/C,SAAS,EAAE,SAAS;QACpB,OAAO,EAAE,WAAW,IAAI,QAAQ;QAChC,MAAM,EAAE,UAAU;QAClB,UAAU,EAAE,kBAAkB;QAC9B,aAAa;QACb,IAAI;KACL,CAAC,CAAC;IAEH,MAAM,IAAA,0BAAQ,EAAC,KAAK,EAAE,iBAAiB,EAAE,OAAO,EAAE,OAAO,EAAE;QACzD,wBAAwB,EAAE,CAAC;QAC3B,cAAc,EACZ,mEAAmE;QACrE,cAAc,EAAE,8BAA8B;QAC9C,YAAY,EAAE,oBAAoB;KACnC,CAAC,CAAC;IAEH,MAAM,EAAE,mBAAmB,EAAE,iBAAiB,EAAE,GAC9C,MAAM,IAAA,2CAAmC,EAAC;QACxC,SAAS,EAAE;YACT,uBAAuB,EAAE,aAAa;YACtC,wBAAwB,EAAE,IAAI;SAC/B;QACD,UAAU,EAAE,OAAO,CAAC,UAAU;QAC9B,WAAW,EAAE,uBAAW,CAAC,MAAM;KAChC,CAAC,CAAC;IAEL,MAAM,eAAe,GAAG,MAAM,IAAA,sCAA8B,EAC1D;QACE,uBAAuB,EAAE,aAAa;QACtC,wBAAwB,EAAE,IAAI;KAC/B,EACD;QACE,WAAW,EAAE,uBAAW,CAAC,MAAM;QAC/B,OAAO;KACR,CACF,CAAC;IAEF,MAAM,IAAA,iCAAyB,EAAC;QAC9B,WAAW;QACX,WAAW,EAAE,uBAAW,CAAC,MAAM;KAChC,CAAC,CAAC;IAEH,MAAM,WAAW,GAAG,OAAO,CAAC,MAAM;QAChC,CAAC,CAAC,GAAG,IAAA,4BAAqB,EAAC,WAAW,CAAC,yBAAyB;QAChE,CAAC,CAAC,SAAS,CAAC;IAEd,MAAM,OAAO,GAAG;QACd,iBAAiB;YACf,CAAC,CAAC,sCAAsC,mBAAmB,OAAO;YAClE,CAAC,CAAC,EAAE;QACN,eAAe,CAAC,MAAM,GAAG,CAAC;YACxB,CAAC,CAAC,wDAAwD;YAC1D,CAAC,CAAC,EAAE;KACP,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;IAElB,MAAM,SAAS,GAAG;QAChB,eAAe,CAAC,MAAM,KAAK,CAAC;YAC1B,CAAC,CAAC,sDAAsD;YACxD,CAAC,CAAC,EAAE;KACP,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;IAElB,MAAM,YAAY,GAAG;EACrB,eAAK,CAAC,KAAK,CAAC,iCAAiC,CAAC;;EAE9C,eAAK,CAAC,IAAI,CAAC,qBAAqB,CAAC;6CACU,UAAU;;;EAGrD,OAAO,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,KAAK,MAAM,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC;;EAEjD,eAAK,CAAC,MAAM,CAAC,aAAa,CAAC;;;EAG3B,SAAS,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,KAAK,IAAI,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC;;sCAEX,eAAK,CAAC,IAAI,CAC5C,4CAA4C,CAC7C;EACD,WAAW,CAAC,CAAC,CAAC,0BAA0B,eAAK,CAAC,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE;EACxE,eAAK,CAAC,GAAG,CACT,yGAAyG,CAC1G;;EAEC,eAAK,CAAC,GAAG,CAAC,+DAA+D,CAAC,EAAE,CAAC;IAE7E,eAAK,CAAC,KAAK,CAAC,YAAY,CAAC,CAAC;IAE1B,MAAM,qBAAS,CAAC,QAAQ,CAAC,SAAS,CAAC,CAAC;AACtC,CAAC;AAED,SAAS,sBAAsB,CAAC,OAO/B;IACC,OAAO,mHACL,OAAO,CAAC,SACV;;;eAGa,OAAO,CAAC,SAAS,IAAI,OAAO,CAAC,OAAO;YACvC,OAAO,CAAC,MAAM;gBACV,OAAO,CAAC,UAAU,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI;qBAC5B,OAAO,CAAC,aAAa;kBACxB,OAAO,CAAC,IAAI;;;;;;;CAO7B,CAAC;AACF,CAAC","sourcesContent":["/* Simplified Next.js wizard using posthog-agent with PostHog MCP */\nimport {\n abort,\n askForAIConsent,\n confirmContinueIfNoOrDirtyGitRepo,\n ensurePackageIsInstalled,\n getOrAskForProjectData,\n getPackageDotJson,\n isUsingTypeScript,\n printWelcome,\n} from '../utils/clack-utils';\nimport { getPackageVersion } from '../utils/package-json';\nimport { getNextJsRouter, getNextJsVersionBucket, NextJsRouter } from './utils';\nimport clack from '../utils/clack';\nimport { Integration, WIZARD_INTERACTION_EVENT_NAME } from '../lib/constants';\nimport { analytics } from '../utils/analytics';\nimport type { WizardOptions } from '../utils/types';\nimport { askForCloudRegion } from '../utils/clack-utils';\nimport { getCloudUrlFromRegion } from '../utils/urls';\nimport chalk from 'chalk';\nimport {\n addOrUpdateEnvironmentVariablesStep,\n addMCPServerToClientsStep,\n uploadEnvironmentVariablesStep,\n} from '../steps';\nimport { enableDebugLogs } from '../utils/debug';\nimport { initializeAgent, runAgent } from '../lib/agent-interface';\n\n/**\n * Simplified Next.js wizard that delegates to PostHog MCP's /integrate command\n */\nexport async function runNextjsWizardAgent(\n options: WizardOptions,\n): Promise<void> {\n if (options.debug) {\n enableDebugLogs();\n }\n\n printWelcome({\n wizardName: 'PostHog Next.js wizard (agent-powered)',\n });\n\n clack.log.info(\n '🧙 The wizard has chosen you to try the next-generation agent integration for Next.js.\\n\\nStand by for the good stuff, and let me know how it goes:\\n\\ndanilo@posthog.com',\n );\n\n const aiConsent = await askForAIConsent(options);\n\n if (!aiConsent) {\n await abort(\n 'This wizard uses an LLM agent to intelligently modify your project. 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 const typeScriptDetected = isUsingTypeScript(options);\n\n await confirmContinueIfNoOrDirtyGitRepo(options);\n\n const packageJson = await getPackageDotJson(options);\n await ensurePackageIsInstalled(packageJson, 'next', 'Next.js');\n\n const nextVersion = getPackageVersion('next', packageJson);\n analytics.setTag('nextjs-version', getNextJsVersionBucket(nextVersion));\n\n analytics.capture(WIZARD_INTERACTION_EVENT_NAME, {\n action: 'started agent integration',\n });\n\n const { projectApiKey, host, accessToken } = await getOrAskForProjectData({\n ...options,\n cloudRegion,\n });\n\n const router = await getNextJsRouter(options);\n const routerType = router === NextJsRouter.APP_ROUTER ? 'app' : 'pages';\n\n const spinner = clack.spinner();\n\n const agent = await initializeAgent(\n {\n workingDirectory: options.installDir,\n posthogMcpUrl: 'https://mcp.posthog.com/mcp',\n posthogApiKey: accessToken,\n debug: false,\n },\n options,\n spinner,\n );\n\n const integrationPrompt = buildIntegrationPrompt({\n framework: 'Next.js',\n version: nextVersion || 'latest',\n router: routerType,\n typescript: typeScriptDetected,\n projectApiKey,\n host,\n });\n\n await runAgent(agent, integrationPrompt, options, spinner, {\n estimatedDurationMinutes: 8,\n spinnerMessage:\n 'Writing your PostHog setup with events, error capture and more...',\n successMessage: 'PostHog integration complete',\n errorMessage: 'Integration failed',\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 await addMCPServerToClientsStep({\n cloudRegion,\n integration: Integration.nextjs,\n });\n\n const continueUrl = options.signup\n ? `${getCloudUrlFromRegion(cloudRegion)}/products?source=wizard`\n : undefined;\n\n const changes = [\n addedEnvVariables\n ? `Added your Project API key to your ${relativeEnvFilePath} file`\n : '',\n uploadedEnvVars.length > 0\n ? `Uploaded your Project API key to your hosting provider`\n : '',\n ].filter(Boolean);\n\n const nextSteps = [\n uploadedEnvVars.length === 0\n ? `Upload your Project API key to your hosting provider`\n : '',\n ].filter(Boolean);\n\n const outroMessage = `\n${chalk.green('Successfully installed PostHog!')}\n\n${chalk.cyan('What the agent did:')}\n• Analyzed your Next.js project structure (${routerType} router)\n• Created and configured PostHog initializers\n• Integrated PostHog into your application\n${changes.map((change) => `• ${change}`).join('\\n')}\n\n${chalk.yellow('Next steps:')}\n• Start your development server to see PostHog in action\n• Visit your PostHog dashboard to see incoming events\n${nextSteps.map((step) => `• ${step}`).join('\\n')}\n\nLearn more about PostHog + Next.js: ${chalk.cyan(\n 'https://posthog.com/docs/libraries/next-js',\n )}\n${continueUrl ? `\\nContinue onboarding: ${chalk.cyan(continueUrl)}\\n` : ``}\n${chalk.dim(\n 'Note: This wizard uses an LLM agent to analyze and modify your project. Please review the changes made.',\n)}\n\n${chalk.dim(`How did this work for you? Drop me a line: danilo@posthog.com`)}`;\n\n clack.outro(outroMessage);\n\n await analytics.shutdown('success');\n}\n\nfunction buildIntegrationPrompt(context: {\n framework: string;\n version: string;\n router: string;\n typescript: boolean;\n projectApiKey: string;\n host: string;\n}): string {\n return `You have access to the PostHog MCP server which provides an integration resource to integrate PostHog into this ${\n context.framework\n } project.\n\nProject context:\n- Framework: ${context.framework} ${context.version}\n- Router: ${context.router}\n- TypeScript: ${context.typescript ? 'Yes' : 'No'}\n- PostHog API Key: ${context.projectApiKey}\n- PostHog Host: ${context.host}\n\nInstructions:\n1. Call the PostHog MCP's resource for setup: posthog://integration/workflow/setup/begin\n2. Follow all instructions provided\n\nThe PostHog MCP will provide specific integration code and instructions. Please follow them carefully. Be sure to look for lockfiles to determine the appropriate package manager to use when installing PostHog. Do not manually edit the package.json file.\n`;\n}\n"]}
|
|
1
|
+
{"version":3,"file":"nextjs-wizard-agent.js","sourceRoot":"","sources":["../../../src/nextjs/nextjs-wizard-agent.ts"],"names":[],"mappings":";;AAyFA,oDAQC;AA9FD,0CAAiD;AACjD,sDAAqD;AACrD,gDAA+C;AAC/C,wDAA0D;AAC1D,mCAKiB;AAEjB;;GAEG;AACH,MAAM,mBAAmB,GAAoB;IAC3C,QAAQ,EAAE;QACR,IAAI,EAAE,SAAS;QACf,WAAW,EAAE,uBAAW,CAAC,MAAM;QAC/B,OAAO,EAAE,4CAA4C;QACrD,YAAY,EACV,wKAAwK;QAC1K,aAAa,EAAE,KAAK,EAAE,OAAsB,EAAE,EAAE;YAC9C,MAAM,MAAM,GAAG,MAAM,IAAA,uBAAe,EAAC,OAAO,CAAC,CAAC;YAC9C,OAAO,EAAE,MAAM,EAAE,CAAC;QACpB,CAAC;KACF;IAED,SAAS,EAAE;QACT,WAAW,EAAE,MAAM;QACnB,kBAAkB,EAAE,SAAS;QAC7B,UAAU,EAAE,CAAC,WAAgB,EAAE,EAAE,CAAC,IAAA,gCAAiB,EAAC,MAAM,EAAE,WAAW,CAAC;QACxE,gBAAgB,EAAE,8BAAsB;KACzC;IAED,WAAW,EAAE;QACX,eAAe,EAAE,IAAI;QACrB,UAAU,EAAE,CAAC,MAAM,EAAE,IAAI,EAAE,EAAE,CAAC,CAAC;YAC7B,uBAAuB,EAAE,MAAM;YAC/B,wBAAwB,EAAE,IAAI;SAC/B,CAAC;KACH;IAED,SAAS,EAAE;QACT,OAAO,EAAE,CAAC,OAAY,EAAE,EAAE;YACxB,MAAM,MAAM,GAAG,OAAO,CAAC,MAAsB,CAAC;YAC9C,OAAO;gBACL,MAAM,EAAE,MAAM,KAAK,oBAAY,CAAC,UAAU,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,OAAO;aAC7D,CAAC;QACJ,CAAC;KACF;IAED,OAAO,EAAE;QACP,yBAAyB,EAAE,CAAC,OAAY,EAAE,EAAE;YAC1C,MAAM,MAAM,GAAG,OAAO,CAAC,MAAsB,CAAC;YAC9C,MAAM,UAAU,GAAG,MAAM,KAAK,oBAAY,CAAC,UAAU,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,OAAO,CAAC;YACxE,OAAO,CAAC,WAAW,UAAU,EAAE,CAAC,CAAC;QACnC,CAAC;KACF;IAED,EAAE,EAAE;QACF,cAAc,EAAE,wCAAwC;QACxD,cAAc,EACZ,mEAAmE;QACrE,cAAc,EAAE,8BAA8B;QAC9C,wBAAwB,EAAE,CAAC;QAC3B,eAAe,EAAE,CAAC,OAAY,EAAE,EAAE;YAChC,MAAM,MAAM,GAAG,OAAO,CAAC,MAAsB,CAAC;YAC9C,MAAM,UAAU,GAAG,IAAA,2BAAmB,EAAC,MAAM,CAAC,CAAC;YAC/C,OAAO;gBACL,4CAA4C,UAAU,GAAG;gBACzD,6CAA6C;gBAC7C,0CAA0C;aAC3C,CAAC;QACJ,CAAC;QACD,iBAAiB,EAAE,GAAG,EAAE;YACtB,OAAO;gBACL,wDAAwD;gBACxD,qDAAqD;aACtD,CAAC;QACJ,CAAC;KACF;CACF,CAAC;AAEF;;GAEG;AACI,KAAK,UAAU,oBAAoB,CACxC,OAAsB;IAEtB,IAAI,OAAO,CAAC,KAAK,EAAE,CAAC;QAClB,IAAA,uBAAe,GAAE,CAAC;IACpB,CAAC;IAED,MAAM,IAAA,6BAAc,EAAC,mBAAmB,EAAE,OAAO,CAAC,CAAC;AACrD,CAAC","sourcesContent":["/* Simplified Next.js wizard using posthog-agent with PostHog MCP */\nimport type { WizardOptions } from '../utils/types';\nimport type { FrameworkConfig } from '../lib/framework-config';\nimport { enableDebugLogs } from '../utils/debug';\nimport { runAgentWizard } from '../lib/agent-runner';\nimport { Integration } from '../lib/constants';\nimport { getPackageVersion } from '../utils/package-json';\nimport {\n getNextJsRouter,\n getNextJsVersionBucket,\n getNextJsRouterName,\n NextJsRouter,\n} from './utils';\n\n/**\n * Next.js framework configuration for the universal agent runner.\n */\nconst NEXTJS_AGENT_CONFIG: FrameworkConfig = {\n metadata: {\n name: 'Next.js',\n integration: Integration.nextjs,\n docsUrl: 'https://posthog.com/docs/libraries/next-js',\n abortMessage:\n 'This wizard uses an LLM agent to intelligently modify your project. Please view the docs to setup Next.js manually instead: https://posthog.com/docs/libraries/next-js',\n gatherContext: async (options: WizardOptions) => {\n const router = await getNextJsRouter(options);\n return { router };\n },\n },\n\n detection: {\n packageName: 'next',\n packageDisplayName: 'Next.js',\n getVersion: (packageJson: any) => getPackageVersion('next', packageJson),\n getVersionBucket: getNextJsVersionBucket,\n },\n\n environment: {\n uploadToHosting: true,\n getEnvVars: (apiKey, host) => ({\n NEXT_PUBLIC_POSTHOG_KEY: apiKey,\n NEXT_PUBLIC_POSTHOG_HOST: host,\n }),\n },\n\n analytics: {\n getTags: (context: any) => {\n const router = context.router as NextJsRouter;\n return {\n router: router === NextJsRouter.APP_ROUTER ? 'app' : 'pages',\n };\n },\n },\n\n prompts: {\n getAdditionalContextLines: (context: any) => {\n const router = context.router as NextJsRouter;\n const routerType = router === NextJsRouter.APP_ROUTER ? 'app' : 'pages';\n return [`Router: ${routerType}`];\n },\n },\n\n ui: {\n welcomeMessage: 'PostHog Next.js wizard (agent-powered)',\n spinnerMessage:\n 'Writing your PostHog setup with events, error capture and more...',\n successMessage: 'PostHog integration complete',\n estimatedDurationMinutes: 8,\n getOutroChanges: (context: any) => {\n const router = context.router as NextJsRouter;\n const routerName = getNextJsRouterName(router);\n return [\n `Analyzed your Next.js project structure (${routerName})`,\n `Created and configured PostHog initializers`,\n `Integrated PostHog into your application`,\n ];\n },\n getOutroNextSteps: () => {\n return [\n 'Start your development server to see PostHog in action',\n 'Visit your PostHog dashboard to see incoming events',\n ];\n },\n },\n};\n\n/**\n * Next.js wizard powered by the universal agent runner.\n */\nexport async function runNextjsWizardAgent(\n options: WizardOptions,\n): Promise<void> {\n if (options.debug) {\n enableDebugLogs();\n }\n\n await runAgentWizard(NEXTJS_AGENT_CONFIG, options);\n}\n"]}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
export type MCPServerConfig = Record<string, unknown>;
|
|
1
2
|
export declare abstract class MCPClient {
|
|
2
3
|
name: string;
|
|
3
4
|
abstract getConfigPath(): Promise<string>;
|
|
@@ -15,13 +16,7 @@ export declare abstract class DefaultMCPClient extends MCPClient {
|
|
|
15
16
|
name: string;
|
|
16
17
|
constructor();
|
|
17
18
|
getServerPropertyName(): string;
|
|
18
|
-
getServerConfig(apiKey: string, type: 'sse' | 'streamable-http', selectedFeatures?: string[], local?: boolean):
|
|
19
|
-
command: string;
|
|
20
|
-
args: string[];
|
|
21
|
-
env: {
|
|
22
|
-
POSTHOG_AUTH_HEADER: string;
|
|
23
|
-
};
|
|
24
|
-
};
|
|
19
|
+
getServerConfig(apiKey: string, type: 'sse' | 'streamable-http', selectedFeatures?: string[], local?: boolean): MCPServerConfig;
|
|
25
20
|
isServerInstalled(local?: boolean): Promise<boolean>;
|
|
26
21
|
addServer(apiKey: string, selectedFeatures?: string[], local?: boolean): Promise<{
|
|
27
22
|
success: boolean;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"MCPClient.js","sourceRoot":"","sources":["../../../../src/steps/add-mcp-server-to-clients/MCPClient.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,uCAAyB;AACzB,2CAA6B;AAC7B,oDAAsC;AACtC,yCAAoD;
|
|
1
|
+
{"version":3,"file":"MCPClient.js","sourceRoot":"","sources":["../../../../src/steps/add-mcp-server-to-clients/MCPClient.ts"],"names":[],"mappings":"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","sourcesContent":["import * as fs from 'fs';\nimport * as path from 'path';\nimport * as jsonc from 'jsonc-parser';\nimport { getDefaultServerConfig } from './defaults';\n\nexport type MCPServerConfig = Record<string, unknown>;\n\nexport abstract class MCPClient {\n name: string;\n abstract getConfigPath(): Promise<string>;\n abstract getServerPropertyName(): string;\n abstract isServerInstalled(local?: boolean): Promise<boolean>;\n abstract addServer(\n apiKey: string,\n selectedFeatures?: string[],\n local?: boolean,\n ): Promise<{ success: boolean }>;\n abstract removeServer(local?: boolean): Promise<{ success: boolean }>;\n abstract isClientSupported(): Promise<boolean>;\n}\n\nexport abstract class DefaultMCPClient extends MCPClient {\n name = 'Default';\n\n constructor() {\n super();\n }\n\n getServerPropertyName(): string {\n return 'mcpServers';\n }\n\n getServerConfig(\n apiKey: string,\n type: 'sse' | 'streamable-http',\n selectedFeatures?: string[],\n local?: boolean,\n ): MCPServerConfig {\n return getDefaultServerConfig(apiKey, type, selectedFeatures, local);\n }\n\n async isServerInstalled(local?: boolean): Promise<boolean> {\n try {\n const configPath = await this.getConfigPath();\n\n if (!fs.existsSync(configPath)) {\n return false;\n }\n\n const configContent = await fs.promises.readFile(configPath, 'utf8');\n const config = jsonc.parse(configContent) as Record<string, any>;\n const serverPropertyName = this.getServerPropertyName();\n const serverName = local ? 'posthog-local' : 'posthog';\n\n return (\n serverPropertyName in config && serverName in config[serverPropertyName]\n );\n } catch {\n return false;\n }\n }\n\n async addServer(\n apiKey: string,\n selectedFeatures?: string[],\n local?: boolean,\n ): Promise<{ success: boolean }> {\n return this._addServerType(apiKey, 'sse', selectedFeatures, local);\n }\n\n async _addServerType(\n apiKey: string,\n type: 'sse' | 'streamable-http',\n selectedFeatures?: string[],\n local?: boolean,\n ): Promise<{ success: boolean }> {\n try {\n const configPath = await this.getConfigPath();\n const configDir = path.dirname(configPath);\n\n await fs.promises.mkdir(configDir, { recursive: true });\n\n const serverPropertyName = this.getServerPropertyName();\n let configContent = '';\n let existingConfig = {};\n\n if (fs.existsSync(configPath)) {\n configContent = await fs.promises.readFile(configPath, 'utf8');\n existingConfig = jsonc.parse(configContent) || {};\n }\n\n const newServerConfig = this.getServerConfig(\n apiKey,\n type,\n selectedFeatures,\n local,\n );\n const typedConfig = existingConfig as Record<string, any>;\n if (!typedConfig[serverPropertyName]) {\n typedConfig[serverPropertyName] = {};\n }\n const serverName = local ? 'posthog-local' : 'posthog';\n typedConfig[serverPropertyName][serverName] = newServerConfig;\n\n const edits = jsonc.modify(\n configContent,\n [serverPropertyName, serverName],\n newServerConfig,\n {\n formattingOptions: {\n tabSize: 2,\n insertSpaces: true,\n },\n },\n );\n\n const modifiedContent = jsonc.applyEdits(configContent, edits);\n\n await fs.promises.writeFile(configPath, modifiedContent, 'utf8');\n\n return { success: true };\n } catch {\n return { success: false };\n }\n }\n\n async removeServer(local?: boolean): Promise<{ success: boolean }> {\n try {\n const configPath = await this.getConfigPath();\n\n if (!fs.existsSync(configPath)) {\n return { success: false };\n }\n\n const configContent = await fs.promises.readFile(configPath, 'utf8');\n const config = jsonc.parse(configContent) as Record<string, any>;\n const serverPropertyName = this.getServerPropertyName();\n\n const serverName = local ? 'posthog-local' : 'posthog';\n\n if (\n serverPropertyName in config &&\n serverName in config[serverPropertyName]\n ) {\n const edits = jsonc.modify(\n configContent,\n [serverPropertyName, serverName],\n undefined,\n {\n formattingOptions: {\n tabSize: 2,\n insertSpaces: true,\n },\n },\n );\n\n const modifiedContent = jsonc.applyEdits(configContent, edits);\n\n await fs.promises.writeFile(configPath, modifiedContent, 'utf8');\n\n return { success: true };\n }\n } catch {\n //\n }\n\n return { success: false };\n }\n}\n"]}
|
|
@@ -2,7 +2,7 @@ import { DefaultMCPClient } from '../MCPClient';
|
|
|
2
2
|
import { DefaultMCPClientConfig } from '../defaults';
|
|
3
3
|
import { z } from 'zod';
|
|
4
4
|
export declare const ClaudeCodeMCPConfig: z.ZodObject<{
|
|
5
|
-
mcpServers: z.ZodRecord<z.ZodString, z.ZodObject<{
|
|
5
|
+
mcpServers: z.ZodRecord<z.ZodString, z.ZodUnion<[z.ZodObject<{
|
|
6
6
|
command: z.ZodOptional<z.ZodString>;
|
|
7
7
|
args: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
|
|
8
8
|
env: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
|
|
@@ -14,9 +14,18 @@ export declare const ClaudeCodeMCPConfig: z.ZodObject<{
|
|
|
14
14
|
command?: string | undefined;
|
|
15
15
|
args?: string[] | undefined;
|
|
16
16
|
env?: Record<string, string> | undefined;
|
|
17
|
-
}
|
|
17
|
+
}>, z.ZodObject<{
|
|
18
|
+
url: z.ZodString;
|
|
19
|
+
headers: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
|
|
20
|
+
}, "strip", z.ZodTypeAny, {
|
|
21
|
+
url: string;
|
|
22
|
+
headers?: Record<string, string> | undefined;
|
|
23
|
+
}, {
|
|
24
|
+
url: string;
|
|
25
|
+
headers?: Record<string, string> | undefined;
|
|
26
|
+
}>]>>;
|
|
18
27
|
}, "passthrough", z.ZodTypeAny, z.objectOutputType<{
|
|
19
|
-
mcpServers: z.ZodRecord<z.ZodString, z.ZodObject<{
|
|
28
|
+
mcpServers: z.ZodRecord<z.ZodString, z.ZodUnion<[z.ZodObject<{
|
|
20
29
|
command: z.ZodOptional<z.ZodString>;
|
|
21
30
|
args: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
|
|
22
31
|
env: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
|
|
@@ -28,9 +37,18 @@ export declare const ClaudeCodeMCPConfig: z.ZodObject<{
|
|
|
28
37
|
command?: string | undefined;
|
|
29
38
|
args?: string[] | undefined;
|
|
30
39
|
env?: Record<string, string> | undefined;
|
|
31
|
-
}
|
|
40
|
+
}>, z.ZodObject<{
|
|
41
|
+
url: z.ZodString;
|
|
42
|
+
headers: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
|
|
43
|
+
}, "strip", z.ZodTypeAny, {
|
|
44
|
+
url: string;
|
|
45
|
+
headers?: Record<string, string> | undefined;
|
|
46
|
+
}, {
|
|
47
|
+
url: string;
|
|
48
|
+
headers?: Record<string, string> | undefined;
|
|
49
|
+
}>]>>;
|
|
32
50
|
}, z.ZodTypeAny, "passthrough">, z.objectInputType<{
|
|
33
|
-
mcpServers: z.ZodRecord<z.ZodString, z.ZodObject<{
|
|
51
|
+
mcpServers: z.ZodRecord<z.ZodString, z.ZodUnion<[z.ZodObject<{
|
|
34
52
|
command: z.ZodOptional<z.ZodString>;
|
|
35
53
|
args: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
|
|
36
54
|
env: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
|
|
@@ -42,7 +60,16 @@ export declare const ClaudeCodeMCPConfig: z.ZodObject<{
|
|
|
42
60
|
command?: string | undefined;
|
|
43
61
|
args?: string[] | undefined;
|
|
44
62
|
env?: Record<string, string> | undefined;
|
|
45
|
-
}
|
|
63
|
+
}>, z.ZodObject<{
|
|
64
|
+
url: z.ZodString;
|
|
65
|
+
headers: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
|
|
66
|
+
}, "strip", z.ZodTypeAny, {
|
|
67
|
+
url: string;
|
|
68
|
+
headers?: Record<string, string> | undefined;
|
|
69
|
+
}, {
|
|
70
|
+
url: string;
|
|
71
|
+
headers?: Record<string, string> | undefined;
|
|
72
|
+
}>]>>;
|
|
46
73
|
}, z.ZodTypeAny, "passthrough">>;
|
|
47
74
|
export type ClaudeCodeMCPConfig = z.infer<typeof DefaultMCPClientConfig>;
|
|
48
75
|
export declare class ClaudeCodeMCPClient extends DefaultMCPClient {
|
|
@@ -56,7 +83,6 @@ export declare class ClaudeCodeMCPClient extends DefaultMCPClient {
|
|
|
56
83
|
addServer(apiKey: string, selectedFeatures?: string[], local?: boolean): Promise<{
|
|
57
84
|
success: boolean;
|
|
58
85
|
}>;
|
|
59
|
-
private buildClaudeCodeConfig;
|
|
60
86
|
removeServer(local?: boolean): Promise<{
|
|
61
87
|
success: boolean;
|
|
62
88
|
}>;
|
|
@@ -129,11 +129,9 @@ class ClaudeCodeMCPClient extends MCPClient_1.DefaultMCPClient {
|
|
|
129
129
|
if (!claudeBinary) {
|
|
130
130
|
return Promise.resolve({ success: false });
|
|
131
131
|
}
|
|
132
|
-
// Build Claude Code-specific config
|
|
133
|
-
// Based on getDefaultServerConfig() but with fixes for Claude Code bugs
|
|
134
|
-
const config = this.buildClaudeCodeConfig(apiKey, selectedFeatures, local);
|
|
135
132
|
const serverName = local ? 'posthog-local' : 'posthog';
|
|
136
|
-
const
|
|
133
|
+
const url = (0, defaults_1.buildMCPUrl)('streamable-http', selectedFeatures, local);
|
|
134
|
+
const command = `${claudeBinary} mcp add --transport http ${serverName} ${url} --header "Authorization: Bearer ${apiKey}" -s user`;
|
|
137
135
|
try {
|
|
138
136
|
(0, child_process_1.execSync)(command);
|
|
139
137
|
}
|
|
@@ -143,49 +141,6 @@ class ClaudeCodeMCPClient extends MCPClient_1.DefaultMCPClient {
|
|
|
143
141
|
}
|
|
144
142
|
return Promise.resolve({ success: true });
|
|
145
143
|
}
|
|
146
|
-
buildClaudeCodeConfig(apiKey, selectedFeatures, local) {
|
|
147
|
-
// Replicate getDefaultServerConfig() logic but with Claude Code fixes:
|
|
148
|
-
// 1. Add https:// protocol (mcp-remote requires valid URLs)
|
|
149
|
-
// 2. Embed token directly in Authorization header (env var expansion broken)
|
|
150
|
-
//
|
|
151
|
-
// Claude Code bugs:
|
|
152
|
-
// - https://github.com/anthropics/claude-code/issues/6204
|
|
153
|
-
// - https://github.com/anthropics/claude-code/issues/9427
|
|
154
|
-
// - https://github.com/anthropics/claude-code/issues/10955
|
|
155
|
-
const protocol = local ? 'http://' : 'https://';
|
|
156
|
-
const host = local ? 'localhost:8787' : 'mcp.posthog.com';
|
|
157
|
-
const baseUrl = `${protocol}${host}/sse`;
|
|
158
|
-
const ALL_FEATURE_VALUES = [
|
|
159
|
-
'dashboards',
|
|
160
|
-
'insights',
|
|
161
|
-
'experiments',
|
|
162
|
-
'llm-analytics',
|
|
163
|
-
'error-tracking',
|
|
164
|
-
'flags',
|
|
165
|
-
'workspace',
|
|
166
|
-
'docs',
|
|
167
|
-
];
|
|
168
|
-
const isAllFeaturesSelected = selectedFeatures &&
|
|
169
|
-
selectedFeatures.length === ALL_FEATURE_VALUES.length &&
|
|
170
|
-
ALL_FEATURE_VALUES.every((feature) => selectedFeatures.includes(feature));
|
|
171
|
-
const urlWithFeatures = selectedFeatures && selectedFeatures.length > 0 && !isAllFeaturesSelected
|
|
172
|
-
? `${baseUrl}?features=${selectedFeatures.join(',')}`
|
|
173
|
-
: baseUrl;
|
|
174
|
-
return {
|
|
175
|
-
command: 'npx',
|
|
176
|
-
args: [
|
|
177
|
-
'-y',
|
|
178
|
-
'mcp-remote@latest',
|
|
179
|
-
urlWithFeatures,
|
|
180
|
-
'--header',
|
|
181
|
-
`Authorization:Bearer ${apiKey}`, // Embed token directly (not ${VAR})
|
|
182
|
-
],
|
|
183
|
-
// Keep env block for backward compatibility if bugs get fixed
|
|
184
|
-
env: {
|
|
185
|
-
POSTHOG_AUTH_HEADER: `Bearer ${apiKey}`,
|
|
186
|
-
},
|
|
187
|
-
};
|
|
188
|
-
}
|
|
189
144
|
removeServer(local) {
|
|
190
145
|
const claudeBinary = this.findClaudeBinary();
|
|
191
146
|
if (!claudeBinary) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"claude-code.js","sourceRoot":"","sources":["../../../../../src/steps/add-mcp-server-to-clients/clients/claude-code.ts"],"names":[],"mappings":"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","sourcesContent":["import { DefaultMCPClient } from '../MCPClient';\nimport { DefaultMCPClientConfig } from '../defaults';\nimport { z } from 'zod';\nimport { execSync } from 'child_process';\nimport { analytics } from '../../../utils/analytics';\nimport { debug } from '../../../utils/debug';\nimport * as os from 'os';\nimport * as path from 'path';\nimport * as fs from 'fs';\n\nexport const ClaudeCodeMCPConfig = DefaultMCPClientConfig;\n\nexport type ClaudeCodeMCPConfig = z.infer<typeof DefaultMCPClientConfig>;\n\nexport class ClaudeCodeMCPClient extends DefaultMCPClient {\n name = 'Claude Code';\n private claudeBinaryPath: string | null = null;\n\n constructor() {\n super();\n }\n\n private findClaudeBinary(): string | null {\n if (this.claudeBinaryPath) {\n return this.claudeBinaryPath;\n }\n\n // Common installation paths for Claude Code CLI\n const possiblePaths = [\n path.join(os.homedir(), '.claude', 'local', 'claude'),\n '/usr/local/bin/claude',\n '/opt/homebrew/bin/claude',\n ];\n\n for (const claudePath of possiblePaths) {\n if (fs.existsSync(claudePath)) {\n debug(` Found claude binary at: ${claudePath}`);\n this.claudeBinaryPath = claudePath;\n return claudePath;\n }\n }\n\n // Try PATH as fallback\n try {\n execSync('command -v claude', { stdio: 'pipe' });\n debug(' Found claude in PATH');\n this.claudeBinaryPath = 'claude';\n return 'claude';\n } catch {\n // Not in PATH\n }\n\n return null;\n }\n\n isClientSupported(): Promise<boolean> {\n try {\n debug(' Checking for Claude Code...');\n const claudeBinary = this.findClaudeBinary();\n\n if (!claudeBinary) {\n debug(' Claude Code not found. Installation paths checked:');\n debug(` - ${path.join(os.homedir(), '.claude', 'local', 'claude')}`);\n debug(` - /usr/local/bin/claude`);\n debug(` - /opt/homebrew/bin/claude`);\n debug(` - PATH`);\n return Promise.resolve(false);\n }\n\n const output = execSync(`${claudeBinary} --version`, { stdio: 'pipe' });\n const version = output.toString().trim();\n debug(` Claude Code detected: ${version}`);\n return Promise.resolve(true);\n } catch (error) {\n debug(\n ` Claude Code check failed: ${\n error instanceof Error ? error.message : String(error)\n }`,\n );\n return Promise.resolve(false);\n }\n }\n\n isServerInstalled(local?: boolean): Promise<boolean> {\n try {\n const claudeBinary = this.findClaudeBinary();\n if (!claudeBinary) {\n return Promise.resolve(false);\n }\n\n // check if specific server name exists in output\n const output = execSync(`${claudeBinary} mcp list`, {\n stdio: 'pipe',\n });\n\n const outputStr = output.toString();\n const serverName = local ? 'posthog-local' : 'posthog';\n\n if (outputStr.includes(serverName)) {\n return Promise.resolve(true);\n }\n } catch {\n //\n }\n\n return Promise.resolve(false);\n }\n\n getConfigPath(): Promise<string> {\n throw new Error('Not implemented');\n }\n\n addServer(\n apiKey: string,\n selectedFeatures?: string[],\n local?: boolean,\n ): Promise<{ success: boolean }> {\n const claudeBinary = this.findClaudeBinary();\n if (!claudeBinary) {\n return Promise.resolve({ success: false });\n }\n\n // Build Claude Code-specific config\n // Based on getDefaultServerConfig() but with fixes for Claude Code bugs\n const config = this.buildClaudeCodeConfig(apiKey, selectedFeatures, local);\n const serverName = local ? 'posthog-local' : 'posthog';\n\n const command = `${claudeBinary} mcp add-json ${serverName} -s user '${JSON.stringify(\n config,\n )}'`;\n\n try {\n execSync(command);\n } catch (error) {\n analytics.captureException(\n new Error(\n `Failed to add server to Claude Code: ${\n error instanceof Error ? error.message : String(error)\n }`,\n ),\n );\n return Promise.resolve({ success: false });\n }\n\n return Promise.resolve({ success: true });\n }\n\n private buildClaudeCodeConfig(\n apiKey: string,\n selectedFeatures?: string[],\n local?: boolean,\n ) {\n // Replicate getDefaultServerConfig() logic but with Claude Code fixes:\n // 1. Add https:// protocol (mcp-remote requires valid URLs)\n // 2. Embed token directly in Authorization header (env var expansion broken)\n //\n // Claude Code bugs:\n // - https://github.com/anthropics/claude-code/issues/6204\n // - https://github.com/anthropics/claude-code/issues/9427\n // - https://github.com/anthropics/claude-code/issues/10955\n\n const protocol = local ? 'http://' : 'https://';\n const host = local ? 'localhost:8787' : 'mcp.posthog.com';\n const baseUrl = `${protocol}${host}/sse`;\n\n const ALL_FEATURE_VALUES = [\n 'dashboards',\n 'insights',\n 'experiments',\n 'llm-analytics',\n 'error-tracking',\n 'flags',\n 'workspace',\n 'docs',\n ];\n\n const isAllFeaturesSelected =\n selectedFeatures &&\n selectedFeatures.length === ALL_FEATURE_VALUES.length &&\n ALL_FEATURE_VALUES.every((feature) => selectedFeatures.includes(feature));\n\n const urlWithFeatures =\n selectedFeatures && selectedFeatures.length > 0 && !isAllFeaturesSelected\n ? `${baseUrl}?features=${selectedFeatures.join(',')}`\n : baseUrl;\n\n return {\n command: 'npx',\n args: [\n '-y',\n 'mcp-remote@latest',\n urlWithFeatures,\n '--header',\n `Authorization:Bearer ${apiKey}`, // Embed token directly (not ${VAR})\n ],\n // Keep env block for backward compatibility if bugs get fixed\n env: {\n POSTHOG_AUTH_HEADER: `Bearer ${apiKey}`,\n },\n };\n }\n\n removeServer(local?: boolean): Promise<{ success: boolean }> {\n const claudeBinary = this.findClaudeBinary();\n if (!claudeBinary) {\n return Promise.resolve({ success: false });\n }\n\n const serverName = local ? 'posthog-local' : 'posthog';\n const command = `${claudeBinary} mcp remove --scope user ${serverName}`;\n\n try {\n execSync(command);\n } catch (error) {\n analytics.captureException(\n new Error(\n `Failed to remove server from Claude Code: ${\n error instanceof Error ? error.message : String(error)\n }`,\n ),\n );\n return Promise.resolve({ success: false });\n }\n\n return Promise.resolve({ success: true });\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"claude-code.js","sourceRoot":"","sources":["../../../../../src/steps/add-mcp-server-to-clients/clients/claude-code.ts"],"names":[],"mappings":"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","sourcesContent":["import { DefaultMCPClient } from '../MCPClient';\nimport { buildMCPUrl, DefaultMCPClientConfig } from '../defaults';\nimport { z } from 'zod';\nimport { execSync } from 'child_process';\nimport { analytics } from '../../../utils/analytics';\nimport { debug } from '../../../utils/debug';\nimport * as os from 'os';\nimport * as path from 'path';\nimport * as fs from 'fs';\n\nexport const ClaudeCodeMCPConfig = DefaultMCPClientConfig;\n\nexport type ClaudeCodeMCPConfig = z.infer<typeof DefaultMCPClientConfig>;\n\nexport class ClaudeCodeMCPClient extends DefaultMCPClient {\n name = 'Claude Code';\n private claudeBinaryPath: string | null = null;\n\n constructor() {\n super();\n }\n\n private findClaudeBinary(): string | null {\n if (this.claudeBinaryPath) {\n return this.claudeBinaryPath;\n }\n\n // Common installation paths for Claude Code CLI\n const possiblePaths = [\n path.join(os.homedir(), '.claude', 'local', 'claude'),\n '/usr/local/bin/claude',\n '/opt/homebrew/bin/claude',\n ];\n\n for (const claudePath of possiblePaths) {\n if (fs.existsSync(claudePath)) {\n debug(` Found claude binary at: ${claudePath}`);\n this.claudeBinaryPath = claudePath;\n return claudePath;\n }\n }\n\n // Try PATH as fallback\n try {\n execSync('command -v claude', { stdio: 'pipe' });\n debug(' Found claude in PATH');\n this.claudeBinaryPath = 'claude';\n return 'claude';\n } catch {\n // Not in PATH\n }\n\n return null;\n }\n\n isClientSupported(): Promise<boolean> {\n try {\n debug(' Checking for Claude Code...');\n const claudeBinary = this.findClaudeBinary();\n\n if (!claudeBinary) {\n debug(' Claude Code not found. Installation paths checked:');\n debug(` - ${path.join(os.homedir(), '.claude', 'local', 'claude')}`);\n debug(` - /usr/local/bin/claude`);\n debug(` - /opt/homebrew/bin/claude`);\n debug(` - PATH`);\n return Promise.resolve(false);\n }\n\n const output = execSync(`${claudeBinary} --version`, { stdio: 'pipe' });\n const version = output.toString().trim();\n debug(` Claude Code detected: ${version}`);\n return Promise.resolve(true);\n } catch (error) {\n debug(\n ` Claude Code check failed: ${\n error instanceof Error ? error.message : String(error)\n }`,\n );\n return Promise.resolve(false);\n }\n }\n\n isServerInstalled(local?: boolean): Promise<boolean> {\n try {\n const claudeBinary = this.findClaudeBinary();\n if (!claudeBinary) {\n return Promise.resolve(false);\n }\n\n // check if specific server name exists in output\n const output = execSync(`${claudeBinary} mcp list`, {\n stdio: 'pipe',\n });\n\n const outputStr = output.toString();\n const serverName = local ? 'posthog-local' : 'posthog';\n\n if (outputStr.includes(serverName)) {\n return Promise.resolve(true);\n }\n } catch {\n //\n }\n\n return Promise.resolve(false);\n }\n\n getConfigPath(): Promise<string> {\n throw new Error('Not implemented');\n }\n\n addServer(\n apiKey: string,\n selectedFeatures?: string[],\n local?: boolean,\n ): Promise<{ success: boolean }> {\n const claudeBinary = this.findClaudeBinary();\n if (!claudeBinary) {\n return Promise.resolve({ success: false });\n }\n\n const serverName = local ? 'posthog-local' : 'posthog';\n const url = buildMCPUrl('streamable-http', selectedFeatures, local);\n\n const command = `${claudeBinary} mcp add --transport http ${serverName} ${url} --header \"Authorization: Bearer ${apiKey}\" -s user`;\n\n try {\n execSync(command);\n } catch (error) {\n analytics.captureException(\n new Error(\n `Failed to add server to Claude Code: ${\n error instanceof Error ? error.message : String(error)\n }`,\n ),\n );\n return Promise.resolve({ success: false });\n }\n\n return Promise.resolve({ success: true });\n }\n\n removeServer(local?: boolean): Promise<{ success: boolean }> {\n const claudeBinary = this.findClaudeBinary();\n if (!claudeBinary) {\n return Promise.resolve({ success: false });\n }\n\n const serverName = local ? 'posthog-local' : 'posthog';\n const command = `${claudeBinary} mcp remove --scope user ${serverName}`;\n\n try {\n execSync(command);\n } catch (error) {\n analytics.captureException(\n new Error(\n `Failed to remove server from Claude Code: ${\n error instanceof Error ? error.message : String(error)\n }`,\n ),\n );\n return Promise.resolve({ success: false });\n }\n\n return Promise.resolve({ success: true });\n }\n}\n"]}
|