@posthog/wizard 2.19.0 → 2.20.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/README.md +11 -0
- package/dist/{add-mcp-server-to-clients-CjnvTVj0.js → add-mcp-server-to-clients-iV7BuQpD.js} +4 -4
- package/dist/{add-mcp-server-to-clients-CjnvTVj0.js.map → add-mcp-server-to-clients-iV7BuQpD.js.map} +1 -1
- package/dist/{agent-interface-CQU6x4Hj.js → agent-interface-B-LAvrNL.js} +163 -52
- package/dist/agent-interface-B-LAvrNL.js.map +1 -0
- package/dist/{agent-runner-Cj7saDkL.js → agent-runner-w2Qu9M13.js} +10 -9
- package/dist/{agent-runner-Cj7saDkL.js.map → agent-runner-w2Qu9M13.js.map} +1 -1
- package/dist/{analytics-Df-Xb81i.js → analytics-C8lJzXjY.js} +2 -2
- package/dist/{analytics-Df-Xb81i.js.map → analytics-C8lJzXjY.js.map} +1 -1
- package/dist/{api-Dw6_orDE.js → api-eUlUinVy.js} +25 -4
- package/dist/{api-Dw6_orDE.js.map → api-eUlUinVy.js.map} +1 -1
- package/dist/bin.js +74 -47
- package/dist/bin.js.map +1 -1
- package/dist/check-screens.tsx +124 -0
- package/dist/{ci-install-BKAvFfK6.js → ci-install-CSo7Q1pK.js} +4 -4
- package/dist/{ci-install-BKAvFfK6.js.map → ci-install-CSo7Q1pK.js.map} +1 -1
- package/dist/{debug-DnMO6O8O.js → debug-BJu_sS4l.js} +2 -2
- package/dist/{debug-DnMO6O8O.js.map → debug-BJu_sS4l.js.map} +1 -1
- package/dist/{debug-Cp_wNn8i.js → debug-CTViFiF-.js} +1 -1
- package/dist/{environment-Ls0H9ljT.js → environment-Dk_dWk3t.js} +3 -3
- package/dist/{environment-Ls0H9ljT.js.map → environment-Dk_dWk3t.js.map} +1 -1
- package/dist/{interactive-D15byhpc.js → interactive-BS2rIf1v.js} +2 -2
- package/dist/{interactive-D15byhpc.js.map → interactive-BS2rIf1v.js.map} +1 -1
- package/dist/{mcp-prompt-streaming-DQOTQfW1.js → mcp-prompt-streaming-BiMrlLl0.js} +4 -4
- package/dist/{mcp-prompt-streaming-DQOTQfW1.js.map → mcp-prompt-streaming-BiMrlLl0.js.map} +1 -1
- package/dist/{non-interactive-DcFLJtl_.js → non-interactive-C39d_KIp.js} +2 -2
- package/dist/{non-interactive-DcFLJtl_.js.map → non-interactive-C39d_KIp.js.map} +1 -1
- package/dist/{package-manager-DUPgLGpQ.js → package-manager-BfOTvFt-.js} +2 -2
- package/dist/{package-manager-DUPgLGpQ.js.map → package-manager-BfOTvFt-.js.map} +1 -1
- package/dist/{playground-BZ0hGjbL.js → playground-3OeRB7JU.js} +15 -9
- package/dist/playground-3OeRB7JU.js.map +1 -0
- package/dist/{posthog-integration-C8qhJnI3.js → posthog-integration-8iTgqy2J.js} +17 -11
- package/dist/posthog-integration-8iTgqy2J.js.map +1 -0
- package/dist/{provisioning-C-2ExcqY.js → provisioning-DxaT7bWw.js} +3 -3
- package/dist/{provisioning-C-2ExcqY.js.map → provisioning-DxaT7bWw.js.map} +1 -1
- package/dist/{registry-hBUgaWFx.js → registry-apQfB3rf.js} +4 -4
- package/dist/{registry-hBUgaWFx.js.map → registry-apQfB3rf.js.map} +1 -1
- package/dist/{setup-utils-DetnhXo0.js → setup-utils-B9xqAXXl.js} +10 -9
- package/dist/setup-utils-B9xqAXXl.js.map +1 -0
- package/dist/{slides-mT2s9wM_.js → slides-BEshbXqG.js} +290 -122
- package/dist/slides-BEshbXqG.js.map +1 -0
- package/dist/{start-tui-BfXoErKg.js → start-tui-CCpKnZOY.js} +243 -56
- package/dist/start-tui-CCpKnZOY.js.map +1 -0
- package/dist/{steps-SoDXSUxe.js → steps-DKbDDnVH.js} +6 -6
- package/dist/{steps-SoDXSUxe.js.map → steps-DKbDDnVH.js.map} +1 -1
- package/dist/{task-stream-CZRj6auI.js → task-stream-CZawuzlz.js} +2 -2
- package/dist/{task-stream-CZRj6auI.js.map → task-stream-CZawuzlz.js.map} +1 -1
- package/dist/{telemetry-CPcMFxcO.js → telemetry-DUeOcmpo.js} +2 -2
- package/dist/{telemetry-CPcMFxcO.js.map → telemetry-DUeOcmpo.js.map} +1 -1
- package/dist/{urls-BO7doNJG.js → urls-B6wBIwr1.js} +2 -2
- package/dist/{urls-BO7doNJG.js.map → urls-B6wBIwr1.js.map} +1 -1
- package/dist/wizard-abort-D8XZdVAR.js +2 -0
- package/dist/{wizard-abort-CDXufkqJ.js → wizard-abort-DhGgTlUA.js} +12 -7
- package/dist/wizard-abort-DhGgTlUA.js.map +1 -0
- package/dist/{wizard-session-d27JGRGi.js → wizard-session-G3VWD6hv.js} +3 -1
- package/dist/{wizard-session-d27JGRGi.js.map → wizard-session-G3VWD6hv.js.map} +1 -1
- package/dist/{wizard-session-y304gEEI.js → wizard-session-wPJtNl4c.js} +1 -1
- package/dist/wizard-ui-YdGFRyu_.js.map +1 -1
- package/package.json +4 -2
- package/dist/agent-interface-CQU6x4Hj.js.map +0 -1
- package/dist/playground-BZ0hGjbL.js.map +0 -1
- package/dist/posthog-integration-C8qhJnI3.js.map +0 -1
- package/dist/setup-utils-DetnhXo0.js.map +0 -1
- package/dist/slides-mT2s9wM_.js.map +0 -1
- package/dist/start-tui-BfXoErKg.js.map +0 -1
- package/dist/wizard-abort-CDXufkqJ.js.map +0 -1
- package/dist/wizard-abort-CtMY57ZE.js +0 -2
package/README.md
CHANGED
|
@@ -146,6 +146,17 @@ When creating your personal API key, ensure it has the following scopes enabled:
|
|
|
146
146
|
- `dashboard:write` - Required to create dashboards
|
|
147
147
|
- `insight:write` - Required to create insights
|
|
148
148
|
|
|
149
|
+
### OAuth app scope ceiling
|
|
150
|
+
|
|
151
|
+
The wizard's OAuth app on the PostHog side caps the scopes its tokens may
|
|
152
|
+
carry (`OAuthApplication.scopes`). Any scope requested in this repo (see
|
|
153
|
+
`src/lib/oauth/program-scopes.ts`) must be present in that list. Current
|
|
154
|
+
ceiling, for bookkeeping:
|
|
155
|
+
|
|
156
|
+
```
|
|
157
|
+
user:read,project:read,llm_gateway:read,dashboard:read,dashboard:write,insight:read,insight:write,query:read,notebook:read,notebook:write,health_issue:read,wizard_session:read,wizard_session:write,feature_flag:read,experiment:read,experiment_saved_metric:read,survey:read,session_recording:read,error_tracking:read,web_analytics:read,llm_analytics:read,cohort:read,person:read,annotation:read,annotation:write,activity_log:read,property_definition:read,event_definition:read,action:read,warehouse_table:read,warehouse_view:read,alert:read,subscription:read,feature_flag:write,integration:read
|
|
158
|
+
```
|
|
159
|
+
|
|
149
160
|
# Steal this code
|
|
150
161
|
|
|
151
162
|
While the wizard works great on its own, we also find the approach used by this
|
package/dist/{add-mcp-server-to-clients-CjnvTVj0.js → add-mcp-server-to-clients-iV7BuQpD.js}
RENAMED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { t as __exportAll } from "./rolldown-runtime-B_-DWIq7.js";
|
|
2
|
-
import { X as runtimeEnv, p as getUI, r as debug } from "./debug-
|
|
3
|
-
import { t as analytics } from "./analytics-
|
|
4
|
-
import { t as withProgress } from "./telemetry-
|
|
2
|
+
import { X as runtimeEnv, p as getUI, r as debug } from "./debug-BJu_sS4l.js";
|
|
3
|
+
import { t as analytics } from "./analytics-C8lJzXjY.js";
|
|
4
|
+
import { t as withProgress } from "./telemetry-DUeOcmpo.js";
|
|
5
5
|
import { a as getNativeHTTPServerConfig, i as getDefaultServerConfig, r as buildMCPUrl, t as ALL_FEATURE_VALUES } from "./defaults-BNWIWzjc.js";
|
|
6
6
|
import { execSync, spawnSync } from "node:child_process";
|
|
7
7
|
import * as fs$1 from "node:fs";
|
|
@@ -557,4 +557,4 @@ const removeMCPServer = async (clients, local) => {
|
|
|
557
557
|
//#endregion
|
|
558
558
|
export { getSupportedClients as a, removeMCPServer as c, getInstalledClients as i, removeMCPServerFromClientsStep as l, addMCPServerToClientsStep as n, getSupportedPluginClients as o, add_mcp_server_to_clients_exports as r, installPlugins as s, addMCPServer as t, isPluginCapable as u };
|
|
559
559
|
|
|
560
|
-
//# sourceMappingURL=add-mcp-server-to-clients-
|
|
560
|
+
//# sourceMappingURL=add-mcp-server-to-clients-iV7BuQpD.js.map
|
package/dist/{add-mcp-server-to-clients-CjnvTVj0.js.map → add-mcp-server-to-clients-iV7BuQpD.js.map}
RENAMED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"add-mcp-server-to-clients-CjnvTVj0.js","names":["fs","path","path","os","path","os","fs","execSync","z","os","path","z","os","path","path","fs"],"sources":["../src/steps/add-mcp-server-to-clients/MCPClient.ts","../src/steps/add-mcp-server-to-clients/clients/cursor.ts","../src/steps/add-mcp-server-to-clients/clients/claude-code.ts","../src/steps/add-mcp-server-to-clients/clients/claude-web.ts","../src/steps/add-mcp-server-to-clients/clients/visual-studio-code.ts","../src/steps/add-mcp-server-to-clients/clients/zed.ts","../src/steps/add-mcp-server-to-clients/clients/codex.ts","../src/steps/add-mcp-server-to-clients/plugin-client.ts","../src/steps/add-mcp-server-to-clients/index.ts"],"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 | undefined,\n selectedFeatures?: string[],\n local?: boolean,\n ): MCPServerConfig {\n return getDefaultServerConfig(apiKey, 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 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 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","import {\n DefaultMCPClient,\n MCPServerConfig,\n} from '@steps/add-mcp-server-to-clients/MCPClient';\nimport * as path from 'path';\nimport * as os from 'os';\nimport {\n DefaultMCPClientConfig,\n getNativeHTTPServerConfig,\n} from '@steps/add-mcp-server-to-clients/defaults';\nimport { z } from 'zod';\n\nexport const CursorMCPConfig = DefaultMCPClientConfig;\n\nexport type CursorMCPConfig = z.infer<typeof DefaultMCPClientConfig>;\n\nexport class CursorMCPClient extends DefaultMCPClient {\n name = 'Cursor';\n\n constructor() {\n super();\n }\n\n async isClientSupported(): Promise<boolean> {\n return Promise.resolve(\n process.platform === 'darwin' || process.platform === 'win32',\n );\n }\n\n async getConfigPath(): Promise<string> {\n return Promise.resolve(path.join(os.homedir(), '.cursor', 'mcp.json'));\n }\n\n getServerConfig(\n apiKey: string | undefined,\n selectedFeatures?: string[],\n local?: boolean,\n ): MCPServerConfig {\n return getNativeHTTPServerConfig(apiKey, selectedFeatures, local);\n }\n}\n","import { DefaultMCPClient } from '@steps/add-mcp-server-to-clients/MCPClient';\nimport {\n DefaultMCPClientConfig,\n buildMCPUrl,\n} from '@steps/add-mcp-server-to-clients/defaults';\nimport {\n PluginCapable,\n PluginInstallResult,\n} from '@steps/add-mcp-server-to-clients/plugin-client';\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\n extends DefaultMCPClient\n implements PluginCapable\n{\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 const binary = this.findClaudeBinary();\n if (!binary) return Promise.resolve(false);\n const serverName = local ? 'posthog-local' : 'posthog';\n try {\n const output = execSync(`${binary} mcp list`, { stdio: 'pipe' })\n .toString()\n .toLowerCase();\n return Promise.resolve(output.includes(serverName));\n } catch {\n return Promise.resolve(false);\n }\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 binary = this.findClaudeBinary();\n if (!binary) return Promise.resolve({ success: false });\n\n const serverName = local ? 'posthog-local' : 'posthog';\n const url = buildMCPUrl(selectedFeatures, local);\n const args = [\n 'mcp',\n 'add',\n '--transport',\n 'http',\n '--scope',\n 'user',\n serverName,\n url,\n ];\n if (apiKey) {\n args.push('--header', `Authorization: Bearer ${apiKey}`);\n }\n\n try {\n execSync(`${binary} ${args.map((a) => JSON.stringify(a)).join(' ')}`, {\n stdio: 'pipe',\n });\n return Promise.resolve({ success: true });\n } catch (error) {\n const msg = error instanceof Error ? error.message : String(error);\n if (msg.includes('already exists')) {\n return Promise.resolve({ success: true });\n }\n analytics.captureException(\n new Error(`Claude Code MCP add failed: ${msg}`),\n );\n return Promise.resolve({ success: false });\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 supportsPlugin(): boolean {\n return this.findClaudeBinary() !== null;\n }\n\n isPluginInstalled(): Promise<boolean> {\n const binary = this.findClaudeBinary();\n if (!binary) return Promise.resolve(false);\n try {\n const output = execSync(`${binary} plugin list`, {\n stdio: 'pipe',\n }).toString();\n return Promise.resolve(output.toLowerCase().includes('posthog'));\n } catch {\n return Promise.resolve(false);\n }\n }\n\n installPlugin(): Promise<PluginInstallResult> {\n const binary = this.findClaudeBinary();\n if (!binary) return Promise.resolve({ success: false });\n try {\n execSync(`${binary} plugin install posthog`, { stdio: 'pipe' });\n return Promise.resolve({ success: true });\n } catch (error) {\n const msg = error instanceof Error ? error.message : String(error);\n if (msg.includes('already installed') || msg.includes('already exists')) {\n return Promise.resolve({ success: true, alreadyInstalled: true });\n }\n analytics.captureException(\n new Error(`Claude Code plugin install failed: ${msg}`),\n );\n return Promise.resolve({ success: false });\n }\n }\n}\n","import opn from 'opn';\nimport { MCPClient } from '@steps/add-mcp-server-to-clients/MCPClient';\nimport { BrowserFinishable } from '@steps/add-mcp-server-to-clients/browser-client';\n\n/**\n * Claude Desktop / Claude.ai (web). PostHog ships here as a hosted connector,\n * not a local config — so instead of writing files we open the connector\n * directory page and let the user sign in and click \"Connect\".\n */\nexport class ClaudeWebMCPClient extends MCPClient implements BrowserFinishable {\n name = 'Claude Desktop/Web';\n connectorUrl = 'https://claude.ai/directory/connectors/posthog';\n finishInstruction = 'Sign in and click \"Connect\" to finish.';\n\n isClientSupported(): Promise<boolean> {\n // Browser-based — available on every platform.\n return Promise.resolve(true);\n }\n\n isServerInstalled(): Promise<boolean> {\n // The connector lives in the user's Claude account; nothing local to\n // inspect. Returning false also keeps it out of `mcp remove`.\n return Promise.resolve(false);\n }\n\n addServer(): Promise<{ success: boolean }> {\n void opn(this.connectorUrl, { wait: false }).catch(() => {\n // opn throws in environments without a browser (e.g. CI) — swallow it;\n // the URL is still surfaced to the user on the Done screen.\n });\n return Promise.resolve({ success: true });\n }\n\n removeServer(): Promise<{ success: boolean }> {\n return Promise.resolve({ success: false });\n }\n\n getConfigPath(): Promise<string> {\n throw new Error('Not implemented');\n }\n\n getServerPropertyName(): string {\n throw new Error('Not implemented');\n }\n}\n\nexport default ClaudeWebMCPClient;\n","import z from 'zod';\nimport * as path from 'path';\nimport * as os from 'os';\nimport {\n DefaultMCPClient,\n MCPServerConfig,\n} from '@steps/add-mcp-server-to-clients/MCPClient';\nimport { getNativeHTTPServerConfig } from '@steps/add-mcp-server-to-clients/defaults';\nimport { runtimeEnv } from '@env';\n\nexport const VisualStudioCodeMCPConfig = z\n .object({\n servers: z.record(\n z.string(),\n z.union([\n z.object({\n command: z.string().optional(),\n args: z.array(z.string()).optional(),\n env: z.record(z.string(), z.string()).optional(),\n }),\n z.object({\n type: z.enum(['http', 'sse']),\n url: z.string(),\n headers: z.record(z.string(), z.string()).optional(),\n }),\n ]),\n ),\n })\n .passthrough();\n\nexport type VisualStudioCodeMCPConfig = z.infer<\n typeof VisualStudioCodeMCPConfig\n>;\n\nexport class VisualStudioCodeClient extends DefaultMCPClient {\n name = 'Visual Studio Code';\n\n getServerPropertyName(): string {\n return 'servers';\n }\n\n async isClientSupported(): Promise<boolean> {\n return Promise.resolve(\n process.platform === 'darwin' ||\n process.platform === 'win32' ||\n process.platform === 'linux',\n );\n }\n\n async getConfigPath(): Promise<string> {\n const homeDir = os.homedir();\n const isWindows = process.platform === 'win32';\n const isMac = process.platform === 'darwin';\n const isLinux = process.platform === 'linux';\n\n if (isMac) {\n return Promise.resolve(\n path.join(\n homeDir,\n 'Library',\n 'Application Support',\n 'Code',\n 'User',\n 'mcp.json',\n ),\n );\n }\n\n if (isWindows) {\n return Promise.resolve(\n path.join(runtimeEnv('APPDATA') || '', 'Code', 'User', 'mcp.json'),\n );\n }\n\n if (isLinux) {\n return Promise.resolve(\n path.join(homeDir, '.config', 'Code', 'User', 'mcp.json'),\n );\n }\n\n throw new Error(`Unsupported platform: ${process.platform}`);\n }\n\n getServerConfig(\n apiKey: string | undefined,\n selectedFeatures?: string[],\n local?: boolean,\n ): MCPServerConfig {\n return {\n type: 'http',\n ...getNativeHTTPServerConfig(apiKey, selectedFeatures, local),\n };\n }\n}\n","import z from 'zod';\nimport * as path from 'path';\nimport * as os from 'os';\nimport {\n DefaultMCPClient,\n MCPServerConfig,\n} from '@steps/add-mcp-server-to-clients/MCPClient';\nimport { getNativeHTTPServerConfig } from '@steps/add-mcp-server-to-clients/defaults';\nimport { runtimeEnv } from '@env';\n\nexport const ZedMCPConfig = z\n .object({\n context_servers: z.record(\n z.string(),\n z.union([\n z.object({\n enabled: z.boolean().optional(),\n source: z.string().optional(),\n command: z.string().optional(),\n args: z.array(z.string()).optional(),\n env: z.record(z.string(), z.string()).optional(),\n }),\n z.object({\n enabled: z.boolean().optional(),\n url: z.string(),\n headers: z.record(z.string(), z.string()).optional(),\n }),\n ]),\n ),\n })\n .passthrough();\n\nexport type ZedMCPConfig = z.infer<typeof ZedMCPConfig>;\n\nexport class ZedClient extends DefaultMCPClient {\n name = 'Zed';\n\n getServerPropertyName(): string {\n return 'context_servers';\n }\n\n async isClientSupported(): Promise<boolean> {\n return Promise.resolve(\n process.platform === 'darwin' || process.platform === 'linux',\n );\n }\n\n async getConfigPath(): Promise<string> {\n const homeDir = os.homedir();\n const isMac = process.platform === 'darwin';\n const isLinux = process.platform === 'linux';\n\n if (isMac) {\n return Promise.resolve(\n path.join(homeDir, '.config', 'zed', 'settings.json'),\n );\n }\n\n if (isLinux) {\n // https://zed.dev/docs/configuring-zed#settings-files\n const xdgConfigHome = runtimeEnv('XDG_CONFIG_HOME');\n if (xdgConfigHome) {\n return Promise.resolve(\n path.join(xdgConfigHome, 'zed', 'settings.json'),\n );\n }\n return Promise.resolve(\n path.join(homeDir, '.config', 'zed', 'settings.json'),\n );\n }\n\n throw new Error(`Unsupported platform: ${process.platform}`);\n }\n\n getServerConfig(\n apiKey: string | undefined,\n selectedFeatures?: string[],\n local?: boolean,\n ): MCPServerConfig {\n return {\n enabled: true,\n ...getNativeHTTPServerConfig(apiKey, selectedFeatures, local),\n };\n }\n}\n","import { z } from 'zod';\nimport { execSync, spawnSync } from 'node:child_process';\nimport * as fs from 'node:fs';\nimport * as os from 'node:os';\nimport * as path from 'node:path';\n\nimport { DefaultMCPClient } from '@steps/add-mcp-server-to-clients/MCPClient';\nimport {\n DefaultMCPClientConfig,\n buildMCPUrl,\n} from '@steps/add-mcp-server-to-clients/defaults';\nimport {\n PluginCapable,\n PluginInstallResult,\n} from '@steps/add-mcp-server-to-clients/plugin-client';\n\nimport { analytics } from '@utils/analytics';\n\nexport const CodexMCPConfig = DefaultMCPClientConfig;\n\nexport type CodexMCPConfig = z.infer<typeof DefaultMCPClientConfig>;\n\nexport class CodexMCPClient extends DefaultMCPClient implements PluginCapable {\n name = 'Codex';\n private codexBinaryPath: string | null = null;\n\n constructor() {\n super();\n }\n\n private findCodexBinary(): string | null {\n if (this.codexBinaryPath) return this.codexBinaryPath;\n try {\n const resolved = execSync('command -v codex', { stdio: 'pipe' })\n .toString()\n .trim();\n if (resolved) {\n this.codexBinaryPath = resolved;\n return resolved;\n }\n } catch {\n // not in PATH\n }\n return null;\n }\n\n isClientSupported(): Promise<boolean> {\n return Promise.resolve(this.findCodexBinary() !== null);\n }\n\n getConfigPath(): Promise<string> {\n throw new Error('Not implemented');\n }\n\n isServerInstalled(local?: boolean): Promise<boolean> {\n const binary = this.findCodexBinary();\n if (!binary) return Promise.resolve(false);\n const serverName = local ? 'posthog-local' : 'posthog';\n const result = spawnSync(binary, ['mcp', 'list'], { encoding: 'utf-8' });\n if (result.status !== 0) return Promise.resolve(false);\n return Promise.resolve(\n (result.stdout ?? '').toLowerCase().includes(serverName),\n );\n }\n\n addServer(\n apiKey?: string,\n selectedFeatures?: string[],\n local?: boolean,\n ): Promise<{ success: boolean }> {\n const binary = this.findCodexBinary();\n if (!binary) return Promise.resolve({ success: false });\n\n const serverName = local ? 'posthog-local' : 'posthog';\n const url = buildMCPUrl(selectedFeatures, local);\n const args = ['mcp', 'add', serverName, '--url', url];\n const env = { ...process.env };\n if (apiKey) {\n const tokenVar = 'POSTHOG_AUTH_HEADER';\n env[tokenVar] = `Bearer ${apiKey}`;\n args.push('--bearer-token-env-var', tokenVar);\n }\n\n const result = spawnSync(binary, args, { encoding: 'utf-8', env });\n if (result.status !== 0) {\n const stderr = result.stderr ?? '';\n if (stderr.toLowerCase().includes('already')) {\n return Promise.resolve({ success: true });\n }\n analytics.captureException(new Error(`Codex MCP add failed: ${stderr}`));\n return Promise.resolve({ success: false });\n }\n return Promise.resolve({ success: true });\n }\n\n removeServer(): Promise<{ success: boolean }> {\n const binary = this.findCodexBinary();\n if (!binary) return Promise.resolve({ success: false });\n\n const result = spawnSync(binary, ['mcp', 'remove', 'posthog'], {\n stdio: 'ignore',\n });\n\n if (result.error || result.status !== 0) {\n analytics.captureException(\n new Error('Failed to remove server from Codex CLI.'),\n );\n return Promise.resolve({ success: false });\n }\n\n return Promise.resolve({ success: true });\n }\n\n supportsPlugin(): boolean {\n return this.findCodexBinary() !== null;\n }\n\n isPluginInstalled(): Promise<boolean> {\n const configPath = path.join(os.homedir(), '.codex', 'config.toml');\n try {\n const contents = fs.readFileSync(configPath, 'utf-8');\n // Marketplace installs appear as [marketplaces.posthog] in config.toml\n return Promise.resolve(\n contents.toLowerCase().includes('[marketplaces.posthog]'),\n );\n } catch {\n return Promise.resolve(false);\n }\n }\n\n installPlugin(): Promise<PluginInstallResult> {\n const binary = this.findCodexBinary();\n if (!binary) return Promise.resolve({ success: false });\n\n const run = () =>\n spawnSync(binary, ['plugin', 'marketplace', 'add', 'PostHog/ai-plugin'], {\n encoding: 'utf-8',\n });\n\n let result = run();\n\n // Stale cache directory with no config.toml entry — clear it and retry\n if (\n result.status !== 0 &&\n (result.stderr ?? '').includes('already added from a different source')\n ) {\n const staleDir = path.join(\n os.homedir(),\n '.codex',\n '.tmp',\n 'marketplaces',\n 'posthog',\n );\n try {\n fs.rmSync(staleDir, { recursive: true, force: true });\n } catch {\n // ignore — retry anyway\n }\n result = run();\n }\n\n if (result.status !== 0) {\n analytics.captureException(\n new Error(`Codex plugin install failed: ${result.stderr ?? ''}`),\n );\n return Promise.resolve({ success: false });\n }\n\n return Promise.resolve({ success: true });\n }\n}\n\nexport default CodexMCPClient;\n","export interface PluginInstallResult {\n success: boolean;\n alreadyInstalled?: boolean;\n}\n\nexport interface PluginCapable {\n supportsPlugin(): boolean;\n isPluginInstalled(): Promise<boolean>;\n installPlugin(): Promise<PluginInstallResult>;\n}\n\nexport function isPluginCapable<T>(client: T): client is T & PluginCapable {\n return (\n typeof client === 'object' &&\n client !== null &&\n 'supportsPlugin' in client &&\n 'installPlugin' in client\n );\n}\n","import type { Integration } from '@lib/constants';\nimport type { CloudRegion } from '@utils/types';\nimport { withProgress } from '../../telemetry';\nimport { analytics } from '@utils/analytics';\nimport { getUI } from '@ui';\nimport { MCPClient } from './MCPClient';\nimport { CursorMCPClient } from './clients/cursor';\nimport { ClaudeCodeMCPClient } from './clients/claude-code';\nimport { ClaudeWebMCPClient } from './clients/claude-web';\nimport { VisualStudioCodeClient } from './clients/visual-studio-code';\nimport { ZedClient } from './clients/zed';\nimport { CodexMCPClient } from './clients/codex';\nimport { ALL_FEATURE_VALUES } from './defaults';\nimport { debug } from '@utils/debug';\nimport { isPluginCapable, PluginCapable } from './plugin-client';\n\nexport const getSupportedClients = async (): Promise<MCPClient[]> => {\n const allClients = [\n new ClaudeCodeMCPClient(),\n new ClaudeWebMCPClient(),\n new CodexMCPClient(),\n new CursorMCPClient(),\n new VisualStudioCodeClient(),\n new ZedClient(),\n ];\n const supportedClients: MCPClient[] = [];\n\n debug('Checking for supported MCP clients...');\n for (const client of allClients) {\n const isSupported = await client.isClientSupported();\n debug(`${client.name}: ${isSupported ? '✓ supported' : '✗ not supported'}`);\n if (isSupported) {\n supportedClients.push(client);\n }\n }\n debug(\n `Found ${supportedClients.length} supported client(s): ${supportedClients\n .map((c) => c.name)\n .join(', ')}`,\n );\n\n return supportedClients;\n};\n\n/**\n * Add MCP server to clients. No prompts — pure orchestration.\n * Prompts are handled by McpScreen (TUI) or auto-accepted (CI).\n */\nexport const addMCPServerToClientsStep = async ({\n integration,\n local = false,\n ci = false,\n cloudRegion: _cloudRegion,\n features,\n apiKey,\n}: {\n integration?: Integration;\n local?: boolean;\n ci?: boolean;\n cloudRegion?: CloudRegion;\n features?: string[];\n apiKey?: string;\n}): Promise<string[]> => {\n const ui = getUI();\n\n // CI mode: skip MCP installation entirely\n if (ci) {\n ui.log.info('Skipping MCP installation (CI mode)');\n return [];\n }\n\n const supportedClients = await getSupportedClients();\n\n if (supportedClients.length === 0) {\n ui.log.info(\n 'No supported MCP clients detected. Skipping MCP installation.',\n );\n return [];\n }\n\n // Auto-install to all supported clients\n await withProgress('adding mcp servers', async () => {\n await addMCPServer(\n supportedClients,\n apiKey,\n features ?? [...ALL_FEATURE_VALUES],\n local,\n );\n });\n\n ui.log.success(\n `Added the MCP server to:\n ${supportedClients.map((c) => `- ${c.name}`).join('\\n ')} `,\n );\n\n analytics.wizardCapture('mcp servers added', {\n clients: supportedClients.map((c) => c.name),\n integration,\n });\n\n return supportedClients.map((c) => c.name);\n};\n\nexport const removeMCPServerFromClientsStep = async ({\n integration,\n local = false,\n}: {\n integration?: Integration;\n local?: boolean;\n}): Promise<string[]> => {\n const installedClients = await getInstalledClients(local);\n if (installedClients.length === 0) {\n analytics.wizardCapture('mcp no servers to remove', {\n integration,\n });\n return [];\n }\n\n // Auto-remove from all installed clients\n const results = await withProgress('removing mcp servers', async () => {\n await removeMCPServer(installedClients, local);\n return installedClients.map((c) => c.name);\n });\n\n analytics.wizardCapture('mcp servers removed', {\n clients: results,\n integration,\n });\n\n return results;\n};\n\nexport const getInstalledClients = async (\n local?: boolean,\n): Promise<MCPClient[]> => {\n const clients = await getSupportedClients();\n const installedClients: MCPClient[] = [];\n\n for (const client of clients) {\n if (await client.isServerInstalled(local)) {\n installedClients.push(client);\n }\n }\n\n return installedClients;\n};\n\nexport const addMCPServer = async (\n clients: MCPClient[],\n personalApiKey?: string,\n selectedFeatures?: string[],\n local?: boolean,\n): Promise<void> => {\n for (const client of clients) {\n await client.addServer(personalApiKey, selectedFeatures, local);\n }\n};\n\nexport const getSupportedPluginClients = (\n clients: MCPClient[],\n): Array<MCPClient & PluginCapable> => {\n return clients.filter(isPluginCapable).filter((c) => c.supportsPlugin());\n};\n\nexport const installPlugins = async (\n clients: Array<MCPClient & PluginCapable>,\n): Promise<string[]> => {\n const installed: string[] = [];\n for (const client of clients) {\n try {\n const result = await client.installPlugin();\n if (result.success) installed.push(client.name);\n } catch (err) {\n debug(`[installPlugins] installPlugin threw for ${client.name}: ${err}`);\n }\n }\n return installed;\n};\n\nexport const removeMCPServer = async (\n clients: MCPClient[],\n local?: boolean,\n): Promise<void> => {\n for (const client of clients) {\n await client.removeServer(local);\n }\n};\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"add-mcp-server-to-clients-iV7BuQpD.js","names":["fs","path","path","os","path","os","fs","execSync","z","os","path","z","os","path","path","fs"],"sources":["../src/steps/add-mcp-server-to-clients/MCPClient.ts","../src/steps/add-mcp-server-to-clients/clients/cursor.ts","../src/steps/add-mcp-server-to-clients/clients/claude-code.ts","../src/steps/add-mcp-server-to-clients/clients/claude-web.ts","../src/steps/add-mcp-server-to-clients/clients/visual-studio-code.ts","../src/steps/add-mcp-server-to-clients/clients/zed.ts","../src/steps/add-mcp-server-to-clients/clients/codex.ts","../src/steps/add-mcp-server-to-clients/plugin-client.ts","../src/steps/add-mcp-server-to-clients/index.ts"],"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 | undefined,\n selectedFeatures?: string[],\n local?: boolean,\n ): MCPServerConfig {\n return getDefaultServerConfig(apiKey, 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 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 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","import {\n DefaultMCPClient,\n MCPServerConfig,\n} from '@steps/add-mcp-server-to-clients/MCPClient';\nimport * as path from 'path';\nimport * as os from 'os';\nimport {\n DefaultMCPClientConfig,\n getNativeHTTPServerConfig,\n} from '@steps/add-mcp-server-to-clients/defaults';\nimport { z } from 'zod';\n\nexport const CursorMCPConfig = DefaultMCPClientConfig;\n\nexport type CursorMCPConfig = z.infer<typeof DefaultMCPClientConfig>;\n\nexport class CursorMCPClient extends DefaultMCPClient {\n name = 'Cursor';\n\n constructor() {\n super();\n }\n\n async isClientSupported(): Promise<boolean> {\n return Promise.resolve(\n process.platform === 'darwin' || process.platform === 'win32',\n );\n }\n\n async getConfigPath(): Promise<string> {\n return Promise.resolve(path.join(os.homedir(), '.cursor', 'mcp.json'));\n }\n\n getServerConfig(\n apiKey: string | undefined,\n selectedFeatures?: string[],\n local?: boolean,\n ): MCPServerConfig {\n return getNativeHTTPServerConfig(apiKey, selectedFeatures, local);\n }\n}\n","import { DefaultMCPClient } from '@steps/add-mcp-server-to-clients/MCPClient';\nimport {\n DefaultMCPClientConfig,\n buildMCPUrl,\n} from '@steps/add-mcp-server-to-clients/defaults';\nimport {\n PluginCapable,\n PluginInstallResult,\n} from '@steps/add-mcp-server-to-clients/plugin-client';\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\n extends DefaultMCPClient\n implements PluginCapable\n{\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 const binary = this.findClaudeBinary();\n if (!binary) return Promise.resolve(false);\n const serverName = local ? 'posthog-local' : 'posthog';\n try {\n const output = execSync(`${binary} mcp list`, { stdio: 'pipe' })\n .toString()\n .toLowerCase();\n return Promise.resolve(output.includes(serverName));\n } catch {\n return Promise.resolve(false);\n }\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 binary = this.findClaudeBinary();\n if (!binary) return Promise.resolve({ success: false });\n\n const serverName = local ? 'posthog-local' : 'posthog';\n const url = buildMCPUrl(selectedFeatures, local);\n const args = [\n 'mcp',\n 'add',\n '--transport',\n 'http',\n '--scope',\n 'user',\n serverName,\n url,\n ];\n if (apiKey) {\n args.push('--header', `Authorization: Bearer ${apiKey}`);\n }\n\n try {\n execSync(`${binary} ${args.map((a) => JSON.stringify(a)).join(' ')}`, {\n stdio: 'pipe',\n });\n return Promise.resolve({ success: true });\n } catch (error) {\n const msg = error instanceof Error ? error.message : String(error);\n if (msg.includes('already exists')) {\n return Promise.resolve({ success: true });\n }\n analytics.captureException(\n new Error(`Claude Code MCP add failed: ${msg}`),\n );\n return Promise.resolve({ success: false });\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 supportsPlugin(): boolean {\n return this.findClaudeBinary() !== null;\n }\n\n isPluginInstalled(): Promise<boolean> {\n const binary = this.findClaudeBinary();\n if (!binary) return Promise.resolve(false);\n try {\n const output = execSync(`${binary} plugin list`, {\n stdio: 'pipe',\n }).toString();\n return Promise.resolve(output.toLowerCase().includes('posthog'));\n } catch {\n return Promise.resolve(false);\n }\n }\n\n installPlugin(): Promise<PluginInstallResult> {\n const binary = this.findClaudeBinary();\n if (!binary) return Promise.resolve({ success: false });\n try {\n execSync(`${binary} plugin install posthog`, { stdio: 'pipe' });\n return Promise.resolve({ success: true });\n } catch (error) {\n const msg = error instanceof Error ? error.message : String(error);\n if (msg.includes('already installed') || msg.includes('already exists')) {\n return Promise.resolve({ success: true, alreadyInstalled: true });\n }\n analytics.captureException(\n new Error(`Claude Code plugin install failed: ${msg}`),\n );\n return Promise.resolve({ success: false });\n }\n }\n}\n","import opn from 'opn';\nimport { MCPClient } from '@steps/add-mcp-server-to-clients/MCPClient';\nimport { BrowserFinishable } from '@steps/add-mcp-server-to-clients/browser-client';\n\n/**\n * Claude Desktop / Claude.ai (web). PostHog ships here as a hosted connector,\n * not a local config — so instead of writing files we open the connector\n * directory page and let the user sign in and click \"Connect\".\n */\nexport class ClaudeWebMCPClient extends MCPClient implements BrowserFinishable {\n name = 'Claude Desktop/Web';\n connectorUrl = 'https://claude.ai/directory/connectors/posthog';\n finishInstruction = 'Sign in and click \"Connect\" to finish.';\n\n isClientSupported(): Promise<boolean> {\n // Browser-based — available on every platform.\n return Promise.resolve(true);\n }\n\n isServerInstalled(): Promise<boolean> {\n // The connector lives in the user's Claude account; nothing local to\n // inspect. Returning false also keeps it out of `mcp remove`.\n return Promise.resolve(false);\n }\n\n addServer(): Promise<{ success: boolean }> {\n void opn(this.connectorUrl, { wait: false }).catch(() => {\n // opn throws in environments without a browser (e.g. CI) — swallow it;\n // the URL is still surfaced to the user on the Done screen.\n });\n return Promise.resolve({ success: true });\n }\n\n removeServer(): Promise<{ success: boolean }> {\n return Promise.resolve({ success: false });\n }\n\n getConfigPath(): Promise<string> {\n throw new Error('Not implemented');\n }\n\n getServerPropertyName(): string {\n throw new Error('Not implemented');\n }\n}\n\nexport default ClaudeWebMCPClient;\n","import z from 'zod';\nimport * as path from 'path';\nimport * as os from 'os';\nimport {\n DefaultMCPClient,\n MCPServerConfig,\n} from '@steps/add-mcp-server-to-clients/MCPClient';\nimport { getNativeHTTPServerConfig } from '@steps/add-mcp-server-to-clients/defaults';\nimport { runtimeEnv } from '@env';\n\nexport const VisualStudioCodeMCPConfig = z\n .object({\n servers: z.record(\n z.string(),\n z.union([\n z.object({\n command: z.string().optional(),\n args: z.array(z.string()).optional(),\n env: z.record(z.string(), z.string()).optional(),\n }),\n z.object({\n type: z.enum(['http', 'sse']),\n url: z.string(),\n headers: z.record(z.string(), z.string()).optional(),\n }),\n ]),\n ),\n })\n .passthrough();\n\nexport type VisualStudioCodeMCPConfig = z.infer<\n typeof VisualStudioCodeMCPConfig\n>;\n\nexport class VisualStudioCodeClient extends DefaultMCPClient {\n name = 'Visual Studio Code';\n\n getServerPropertyName(): string {\n return 'servers';\n }\n\n async isClientSupported(): Promise<boolean> {\n return Promise.resolve(\n process.platform === 'darwin' ||\n process.platform === 'win32' ||\n process.platform === 'linux',\n );\n }\n\n async getConfigPath(): Promise<string> {\n const homeDir = os.homedir();\n const isWindows = process.platform === 'win32';\n const isMac = process.platform === 'darwin';\n const isLinux = process.platform === 'linux';\n\n if (isMac) {\n return Promise.resolve(\n path.join(\n homeDir,\n 'Library',\n 'Application Support',\n 'Code',\n 'User',\n 'mcp.json',\n ),\n );\n }\n\n if (isWindows) {\n return Promise.resolve(\n path.join(runtimeEnv('APPDATA') || '', 'Code', 'User', 'mcp.json'),\n );\n }\n\n if (isLinux) {\n return Promise.resolve(\n path.join(homeDir, '.config', 'Code', 'User', 'mcp.json'),\n );\n }\n\n throw new Error(`Unsupported platform: ${process.platform}`);\n }\n\n getServerConfig(\n apiKey: string | undefined,\n selectedFeatures?: string[],\n local?: boolean,\n ): MCPServerConfig {\n return {\n type: 'http',\n ...getNativeHTTPServerConfig(apiKey, selectedFeatures, local),\n };\n }\n}\n","import z from 'zod';\nimport * as path from 'path';\nimport * as os from 'os';\nimport {\n DefaultMCPClient,\n MCPServerConfig,\n} from '@steps/add-mcp-server-to-clients/MCPClient';\nimport { getNativeHTTPServerConfig } from '@steps/add-mcp-server-to-clients/defaults';\nimport { runtimeEnv } from '@env';\n\nexport const ZedMCPConfig = z\n .object({\n context_servers: z.record(\n z.string(),\n z.union([\n z.object({\n enabled: z.boolean().optional(),\n source: z.string().optional(),\n command: z.string().optional(),\n args: z.array(z.string()).optional(),\n env: z.record(z.string(), z.string()).optional(),\n }),\n z.object({\n enabled: z.boolean().optional(),\n url: z.string(),\n headers: z.record(z.string(), z.string()).optional(),\n }),\n ]),\n ),\n })\n .passthrough();\n\nexport type ZedMCPConfig = z.infer<typeof ZedMCPConfig>;\n\nexport class ZedClient extends DefaultMCPClient {\n name = 'Zed';\n\n getServerPropertyName(): string {\n return 'context_servers';\n }\n\n async isClientSupported(): Promise<boolean> {\n return Promise.resolve(\n process.platform === 'darwin' || process.platform === 'linux',\n );\n }\n\n async getConfigPath(): Promise<string> {\n const homeDir = os.homedir();\n const isMac = process.platform === 'darwin';\n const isLinux = process.platform === 'linux';\n\n if (isMac) {\n return Promise.resolve(\n path.join(homeDir, '.config', 'zed', 'settings.json'),\n );\n }\n\n if (isLinux) {\n // https://zed.dev/docs/configuring-zed#settings-files\n const xdgConfigHome = runtimeEnv('XDG_CONFIG_HOME');\n if (xdgConfigHome) {\n return Promise.resolve(\n path.join(xdgConfigHome, 'zed', 'settings.json'),\n );\n }\n return Promise.resolve(\n path.join(homeDir, '.config', 'zed', 'settings.json'),\n );\n }\n\n throw new Error(`Unsupported platform: ${process.platform}`);\n }\n\n getServerConfig(\n apiKey: string | undefined,\n selectedFeatures?: string[],\n local?: boolean,\n ): MCPServerConfig {\n return {\n enabled: true,\n ...getNativeHTTPServerConfig(apiKey, selectedFeatures, local),\n };\n }\n}\n","import { z } from 'zod';\nimport { execSync, spawnSync } from 'node:child_process';\nimport * as fs from 'node:fs';\nimport * as os from 'node:os';\nimport * as path from 'node:path';\n\nimport { DefaultMCPClient } from '@steps/add-mcp-server-to-clients/MCPClient';\nimport {\n DefaultMCPClientConfig,\n buildMCPUrl,\n} from '@steps/add-mcp-server-to-clients/defaults';\nimport {\n PluginCapable,\n PluginInstallResult,\n} from '@steps/add-mcp-server-to-clients/plugin-client';\n\nimport { analytics } from '@utils/analytics';\n\nexport const CodexMCPConfig = DefaultMCPClientConfig;\n\nexport type CodexMCPConfig = z.infer<typeof DefaultMCPClientConfig>;\n\nexport class CodexMCPClient extends DefaultMCPClient implements PluginCapable {\n name = 'Codex';\n private codexBinaryPath: string | null = null;\n\n constructor() {\n super();\n }\n\n private findCodexBinary(): string | null {\n if (this.codexBinaryPath) return this.codexBinaryPath;\n try {\n const resolved = execSync('command -v codex', { stdio: 'pipe' })\n .toString()\n .trim();\n if (resolved) {\n this.codexBinaryPath = resolved;\n return resolved;\n }\n } catch {\n // not in PATH\n }\n return null;\n }\n\n isClientSupported(): Promise<boolean> {\n return Promise.resolve(this.findCodexBinary() !== null);\n }\n\n getConfigPath(): Promise<string> {\n throw new Error('Not implemented');\n }\n\n isServerInstalled(local?: boolean): Promise<boolean> {\n const binary = this.findCodexBinary();\n if (!binary) return Promise.resolve(false);\n const serverName = local ? 'posthog-local' : 'posthog';\n const result = spawnSync(binary, ['mcp', 'list'], { encoding: 'utf-8' });\n if (result.status !== 0) return Promise.resolve(false);\n return Promise.resolve(\n (result.stdout ?? '').toLowerCase().includes(serverName),\n );\n }\n\n addServer(\n apiKey?: string,\n selectedFeatures?: string[],\n local?: boolean,\n ): Promise<{ success: boolean }> {\n const binary = this.findCodexBinary();\n if (!binary) return Promise.resolve({ success: false });\n\n const serverName = local ? 'posthog-local' : 'posthog';\n const url = buildMCPUrl(selectedFeatures, local);\n const args = ['mcp', 'add', serverName, '--url', url];\n const env = { ...process.env };\n if (apiKey) {\n const tokenVar = 'POSTHOG_AUTH_HEADER';\n env[tokenVar] = `Bearer ${apiKey}`;\n args.push('--bearer-token-env-var', tokenVar);\n }\n\n const result = spawnSync(binary, args, { encoding: 'utf-8', env });\n if (result.status !== 0) {\n const stderr = result.stderr ?? '';\n if (stderr.toLowerCase().includes('already')) {\n return Promise.resolve({ success: true });\n }\n analytics.captureException(new Error(`Codex MCP add failed: ${stderr}`));\n return Promise.resolve({ success: false });\n }\n return Promise.resolve({ success: true });\n }\n\n removeServer(): Promise<{ success: boolean }> {\n const binary = this.findCodexBinary();\n if (!binary) return Promise.resolve({ success: false });\n\n const result = spawnSync(binary, ['mcp', 'remove', 'posthog'], {\n stdio: 'ignore',\n });\n\n if (result.error || result.status !== 0) {\n analytics.captureException(\n new Error('Failed to remove server from Codex CLI.'),\n );\n return Promise.resolve({ success: false });\n }\n\n return Promise.resolve({ success: true });\n }\n\n supportsPlugin(): boolean {\n return this.findCodexBinary() !== null;\n }\n\n isPluginInstalled(): Promise<boolean> {\n const configPath = path.join(os.homedir(), '.codex', 'config.toml');\n try {\n const contents = fs.readFileSync(configPath, 'utf-8');\n // Marketplace installs appear as [marketplaces.posthog] in config.toml\n return Promise.resolve(\n contents.toLowerCase().includes('[marketplaces.posthog]'),\n );\n } catch {\n return Promise.resolve(false);\n }\n }\n\n installPlugin(): Promise<PluginInstallResult> {\n const binary = this.findCodexBinary();\n if (!binary) return Promise.resolve({ success: false });\n\n const run = () =>\n spawnSync(binary, ['plugin', 'marketplace', 'add', 'PostHog/ai-plugin'], {\n encoding: 'utf-8',\n });\n\n let result = run();\n\n // Stale cache directory with no config.toml entry — clear it and retry\n if (\n result.status !== 0 &&\n (result.stderr ?? '').includes('already added from a different source')\n ) {\n const staleDir = path.join(\n os.homedir(),\n '.codex',\n '.tmp',\n 'marketplaces',\n 'posthog',\n );\n try {\n fs.rmSync(staleDir, { recursive: true, force: true });\n } catch {\n // ignore — retry anyway\n }\n result = run();\n }\n\n if (result.status !== 0) {\n analytics.captureException(\n new Error(`Codex plugin install failed: ${result.stderr ?? ''}`),\n );\n return Promise.resolve({ success: false });\n }\n\n return Promise.resolve({ success: true });\n }\n}\n\nexport default CodexMCPClient;\n","export interface PluginInstallResult {\n success: boolean;\n alreadyInstalled?: boolean;\n}\n\nexport interface PluginCapable {\n supportsPlugin(): boolean;\n isPluginInstalled(): Promise<boolean>;\n installPlugin(): Promise<PluginInstallResult>;\n}\n\nexport function isPluginCapable<T>(client: T): client is T & PluginCapable {\n return (\n typeof client === 'object' &&\n client !== null &&\n 'supportsPlugin' in client &&\n 'installPlugin' in client\n );\n}\n","import type { Integration } from '@lib/constants';\nimport type { CloudRegion } from '@utils/types';\nimport { withProgress } from '../../telemetry';\nimport { analytics } from '@utils/analytics';\nimport { getUI } from '@ui';\nimport { MCPClient } from './MCPClient';\nimport { CursorMCPClient } from './clients/cursor';\nimport { ClaudeCodeMCPClient } from './clients/claude-code';\nimport { ClaudeWebMCPClient } from './clients/claude-web';\nimport { VisualStudioCodeClient } from './clients/visual-studio-code';\nimport { ZedClient } from './clients/zed';\nimport { CodexMCPClient } from './clients/codex';\nimport { ALL_FEATURE_VALUES } from './defaults';\nimport { debug } from '@utils/debug';\nimport { isPluginCapable, PluginCapable } from './plugin-client';\n\nexport const getSupportedClients = async (): Promise<MCPClient[]> => {\n const allClients = [\n new ClaudeCodeMCPClient(),\n new ClaudeWebMCPClient(),\n new CodexMCPClient(),\n new CursorMCPClient(),\n new VisualStudioCodeClient(),\n new ZedClient(),\n ];\n const supportedClients: MCPClient[] = [];\n\n debug('Checking for supported MCP clients...');\n for (const client of allClients) {\n const isSupported = await client.isClientSupported();\n debug(`${client.name}: ${isSupported ? '✓ supported' : '✗ not supported'}`);\n if (isSupported) {\n supportedClients.push(client);\n }\n }\n debug(\n `Found ${supportedClients.length} supported client(s): ${supportedClients\n .map((c) => c.name)\n .join(', ')}`,\n );\n\n return supportedClients;\n};\n\n/**\n * Add MCP server to clients. No prompts — pure orchestration.\n * Prompts are handled by McpScreen (TUI) or auto-accepted (CI).\n */\nexport const addMCPServerToClientsStep = async ({\n integration,\n local = false,\n ci = false,\n cloudRegion: _cloudRegion,\n features,\n apiKey,\n}: {\n integration?: Integration;\n local?: boolean;\n ci?: boolean;\n cloudRegion?: CloudRegion;\n features?: string[];\n apiKey?: string;\n}): Promise<string[]> => {\n const ui = getUI();\n\n // CI mode: skip MCP installation entirely\n if (ci) {\n ui.log.info('Skipping MCP installation (CI mode)');\n return [];\n }\n\n const supportedClients = await getSupportedClients();\n\n if (supportedClients.length === 0) {\n ui.log.info(\n 'No supported MCP clients detected. Skipping MCP installation.',\n );\n return [];\n }\n\n // Auto-install to all supported clients\n await withProgress('adding mcp servers', async () => {\n await addMCPServer(\n supportedClients,\n apiKey,\n features ?? [...ALL_FEATURE_VALUES],\n local,\n );\n });\n\n ui.log.success(\n `Added the MCP server to:\n ${supportedClients.map((c) => `- ${c.name}`).join('\\n ')} `,\n );\n\n analytics.wizardCapture('mcp servers added', {\n clients: supportedClients.map((c) => c.name),\n integration,\n });\n\n return supportedClients.map((c) => c.name);\n};\n\nexport const removeMCPServerFromClientsStep = async ({\n integration,\n local = false,\n}: {\n integration?: Integration;\n local?: boolean;\n}): Promise<string[]> => {\n const installedClients = await getInstalledClients(local);\n if (installedClients.length === 0) {\n analytics.wizardCapture('mcp no servers to remove', {\n integration,\n });\n return [];\n }\n\n // Auto-remove from all installed clients\n const results = await withProgress('removing mcp servers', async () => {\n await removeMCPServer(installedClients, local);\n return installedClients.map((c) => c.name);\n });\n\n analytics.wizardCapture('mcp servers removed', {\n clients: results,\n integration,\n });\n\n return results;\n};\n\nexport const getInstalledClients = async (\n local?: boolean,\n): Promise<MCPClient[]> => {\n const clients = await getSupportedClients();\n const installedClients: MCPClient[] = [];\n\n for (const client of clients) {\n if (await client.isServerInstalled(local)) {\n installedClients.push(client);\n }\n }\n\n return installedClients;\n};\n\nexport const addMCPServer = async (\n clients: MCPClient[],\n personalApiKey?: string,\n selectedFeatures?: string[],\n local?: boolean,\n): Promise<void> => {\n for (const client of clients) {\n await client.addServer(personalApiKey, selectedFeatures, local);\n }\n};\n\nexport const getSupportedPluginClients = (\n clients: MCPClient[],\n): Array<MCPClient & PluginCapable> => {\n return clients.filter(isPluginCapable).filter((c) => c.supportsPlugin());\n};\n\nexport const installPlugins = async (\n clients: Array<MCPClient & PluginCapable>,\n): Promise<string[]> => {\n const installed: string[] = [];\n for (const client of clients) {\n try {\n const result = await client.installPlugin();\n if (result.success) installed.push(client.name);\n } catch (err) {\n debug(`[installPlugins] installPlugin threw for ${client.name}: ${err}`);\n }\n }\n return installed;\n};\n\nexport const removeMCPServer = async (\n clients: MCPClient[],\n local?: boolean,\n): Promise<void> => {\n for (const client of clients) {\n await client.removeServer(local);\n }\n};\n"],"mappings":"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"}
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import { n as __require } from "./rolldown-runtime-B_-DWIq7.js";
|
|
2
|
-
import { F as POSTHOG_PROPERTY_HEADER_PREFIX, G as WIZARD_VARIANTS, H as WIZARD_REMARK_EVENT_NAME, K as WIZARD_VARIANT_FLAG_KEY, N as POSTHOG_FLAG_HEADER_PREFIX, W as WIZARD_USER_AGENT, a as getLogFilePath, f as skillTmpPath, o as initLogFile, p as getUI, r as debug, s as logToFile, u as WIZARD_YARA_REPORT_FILE } from "./debug-
|
|
3
|
-
import { t as analytics } from "./analytics-
|
|
4
|
-
import { i as getLlmGatewayUrlFromHost } from "./urls-
|
|
5
|
-
import { n as ADDITIONAL_FEATURE_PROMPTS } from "./wizard-session-
|
|
6
|
-
import {
|
|
2
|
+
import { F as POSTHOG_PROPERTY_HEADER_PREFIX, G as WIZARD_VARIANTS, H as WIZARD_REMARK_EVENT_NAME, K as WIZARD_VARIANT_FLAG_KEY, N as POSTHOG_FLAG_HEADER_PREFIX, W as WIZARD_USER_AGENT, a as getLogFilePath, f as skillTmpPath, o as initLogFile, p as getUI, r as debug, s as logToFile, u as WIZARD_YARA_REPORT_FILE } from "./debug-BJu_sS4l.js";
|
|
3
|
+
import { t as analytics } from "./analytics-C8lJzXjY.js";
|
|
4
|
+
import { i as getLlmGatewayUrlFromHost } from "./urls-B6wBIwr1.js";
|
|
5
|
+
import { n as ADDITIONAL_FEATURE_PROMPTS } from "./wizard-session-G3VWD6hv.js";
|
|
6
|
+
import { i as wizardAbort, n as registerCleanup, t as WizardError } from "./wizard-abort-DhGgTlUA.js";
|
|
7
7
|
import { createRequire } from "node:module";
|
|
8
8
|
import * as fs$1 from "fs";
|
|
9
9
|
import fs from "fs";
|
|
@@ -12,6 +12,7 @@ import { z } from "zod";
|
|
|
12
12
|
import fg from "fast-glob";
|
|
13
13
|
import { execFileSync } from "child_process";
|
|
14
14
|
import { randomUUID } from "crypto";
|
|
15
|
+
import * as os from "os";
|
|
15
16
|
//#region src/lib/programs/audit/types.ts
|
|
16
17
|
/** Single source of truth for status glyph + color across audit views. */
|
|
17
18
|
const AUDIT_SEVERITY_STYLE = {
|
|
@@ -1530,24 +1531,15 @@ var AgentOutputSignals = class {
|
|
|
1530
1531
|
}
|
|
1531
1532
|
};
|
|
1532
1533
|
//#endregion
|
|
1533
|
-
//#region src/lib/agent/
|
|
1534
|
-
/**
|
|
1535
|
-
* Shared agent interface for PostHog wizards
|
|
1536
|
-
* Uses Claude Agent SDK directly with PostHog LLM gateway
|
|
1537
|
-
*/
|
|
1538
|
-
let _sdkModule = null;
|
|
1539
|
-
async function getSDKModule() {
|
|
1540
|
-
if (!_sdkModule) _sdkModule = await import("@anthropic-ai/claude-agent-sdk");
|
|
1541
|
-
return _sdkModule;
|
|
1542
|
-
}
|
|
1534
|
+
//#region src/lib/agent/claude-settings.ts
|
|
1543
1535
|
/**
|
|
1544
|
-
*
|
|
1545
|
-
*
|
|
1536
|
+
* Claude Code settings handling: conflict detection, backup/restore, and
|
|
1537
|
+
* orphan recovery.
|
|
1538
|
+
*
|
|
1539
|
+
* Lives apart from agent-interface so bin.ts can run orphan recovery at
|
|
1540
|
+
* process start without dragging in the agent stack (wizard-tools, yara
|
|
1541
|
+
* hooks, the SDK loader).
|
|
1546
1542
|
*/
|
|
1547
|
-
function getClaudeCodeExecutablePath() {
|
|
1548
|
-
const sdkPackagePath = (typeof __require !== "undefined" ? __require : createRequire(process.argv[1] ?? `${process.cwd()}/`)).resolve("@anthropic-ai/claude-agent-sdk");
|
|
1549
|
-
return path.join(path.dirname(sdkPackagePath), "cli.js");
|
|
1550
|
-
}
|
|
1551
1543
|
const BLOCKING_ENV_KEYS = [
|
|
1552
1544
|
"ANTHROPIC_API_KEY",
|
|
1553
1545
|
"ANTHROPIC_BASE_URL",
|
|
@@ -1577,25 +1569,43 @@ function checkSettingsFile(filePath) {
|
|
|
1577
1569
|
*/
|
|
1578
1570
|
const MANAGED_SETTINGS_PATH = "/Library/Application Support/ClaudeCode/managed-settings.json";
|
|
1579
1571
|
/**
|
|
1580
|
-
* Check
|
|
1581
|
-
* with the wizard's
|
|
1572
|
+
* Check every settings file Claude Code reads for blocking keys that conflict
|
|
1573
|
+
* with the wizard's gateway auth: org-managed, the user's global config, the
|
|
1574
|
+
* project config, and the gitignored project-local override. Each is a place
|
|
1575
|
+
* an `apiKeyHelper` or `ANTHROPIC_*` override commonly lives, and any of them
|
|
1576
|
+
* can outrank the env the wizard sets and make every agent call 401.
|
|
1582
1577
|
*/
|
|
1583
|
-
function checkAllSettingsConflicts(workingDirectory) {
|
|
1578
|
+
function checkAllSettingsConflicts(workingDirectory, homeDir = os.homedir()) {
|
|
1584
1579
|
const conflicts = [];
|
|
1585
|
-
const
|
|
1586
|
-
|
|
1587
|
-
|
|
1588
|
-
|
|
1589
|
-
|
|
1590
|
-
|
|
1591
|
-
|
|
1592
|
-
|
|
1593
|
-
|
|
1580
|
+
const home = homeDir;
|
|
1581
|
+
const sources = [
|
|
1582
|
+
{
|
|
1583
|
+
source: "managed",
|
|
1584
|
+
paths: [MANAGED_SETTINGS_PATH],
|
|
1585
|
+
writable: false
|
|
1586
|
+
},
|
|
1587
|
+
{
|
|
1588
|
+
source: "user",
|
|
1589
|
+
paths: [path.join(home, ".claude", "settings.json"), path.join(home, ".claude", "settings.local.json")],
|
|
1590
|
+
writable: false
|
|
1591
|
+
},
|
|
1592
|
+
{
|
|
1593
|
+
source: "project",
|
|
1594
|
+
paths: [path.join(workingDirectory, ".claude", "settings.json"), path.join(workingDirectory, ".claude", "settings")],
|
|
1595
|
+
writable: true
|
|
1596
|
+
},
|
|
1597
|
+
{
|
|
1598
|
+
source: "project-local",
|
|
1599
|
+
paths: [path.join(workingDirectory, ".claude", "settings.local.json")],
|
|
1600
|
+
writable: false
|
|
1601
|
+
}
|
|
1602
|
+
];
|
|
1594
1603
|
for (const { source, paths, writable } of sources) for (const filePath of paths) {
|
|
1595
1604
|
const keys = checkSettingsFile(filePath);
|
|
1596
1605
|
if (keys.length > 0) {
|
|
1597
1606
|
conflicts.push({
|
|
1598
1607
|
source,
|
|
1608
|
+
path: filePath,
|
|
1599
1609
|
keys,
|
|
1600
1610
|
writable
|
|
1601
1611
|
});
|
|
@@ -1605,17 +1615,42 @@ function checkAllSettingsConflicts(workingDirectory) {
|
|
|
1605
1615
|
return conflicts;
|
|
1606
1616
|
}
|
|
1607
1617
|
/**
|
|
1608
|
-
*
|
|
1609
|
-
*
|
|
1618
|
+
* Ensure `.claude/.gitignore` excludes `*.wizard-backup` so a backup left
|
|
1619
|
+
* orphaned by an interrupted run can't get committed to git — settings files
|
|
1620
|
+
* commonly hold `apiKeyHelper` or `ANTHROPIC_API_KEY`, which we don't want
|
|
1621
|
+
* leaking into a repo.
|
|
1622
|
+
*/
|
|
1623
|
+
function ensureBackupGitignored(claudeDir) {
|
|
1624
|
+
const gitignorePath = path.join(claudeDir, ".gitignore");
|
|
1625
|
+
const entry = "*.wizard-backup";
|
|
1626
|
+
try {
|
|
1627
|
+
const existing = fs$1.existsSync(gitignorePath) ? fs$1.readFileSync(gitignorePath, "utf-8") : "";
|
|
1628
|
+
if (existing.split("\n").map((l) => l.trim()).includes(entry)) return;
|
|
1629
|
+
const sep = existing && !existing.endsWith("\n") ? "\n" : "";
|
|
1630
|
+
fs$1.writeFileSync(gitignorePath, `${existing}${sep}${entry}\n`);
|
|
1631
|
+
} catch (error) {
|
|
1632
|
+
analytics.captureException(error);
|
|
1633
|
+
}
|
|
1634
|
+
}
|
|
1635
|
+
/**
|
|
1636
|
+
* Copy .claude/settings.json to .wizard-backup, then remove the original so
|
|
1637
|
+
* the SDK doesn't load the blocking overrides. Restored at outro and on
|
|
1638
|
+
* cleanup.
|
|
1610
1639
|
*/
|
|
1611
1640
|
function backupAndFixClaudeSettings(workingDirectory) {
|
|
1612
1641
|
for (const name of ["settings.json", "settings"]) {
|
|
1613
1642
|
const filePath = path.join(workingDirectory, ".claude", name);
|
|
1643
|
+
if (!fs$1.existsSync(filePath)) continue;
|
|
1614
1644
|
const backupPath = `${filePath}.wizard-backup`;
|
|
1615
|
-
analytics.wizardCapture("backedup-claude-settings");
|
|
1616
1645
|
try {
|
|
1617
|
-
fs$1.
|
|
1646
|
+
if (!fs$1.existsSync(backupPath)) {
|
|
1647
|
+
fs$1.copyFileSync(filePath, backupPath);
|
|
1648
|
+
const mode = fs$1.statSync(filePath).mode & 511;
|
|
1649
|
+
fs$1.chmodSync(backupPath, mode);
|
|
1650
|
+
}
|
|
1651
|
+
ensureBackupGitignored(path.join(workingDirectory, ".claude"));
|
|
1618
1652
|
fs$1.unlinkSync(filePath);
|
|
1653
|
+
analytics.wizardCapture("backedup-claude-settings");
|
|
1619
1654
|
registerCleanup(() => {
|
|
1620
1655
|
try {
|
|
1621
1656
|
restoreClaudeSettings(workingDirectory);
|
|
@@ -1624,19 +1659,29 @@ function backupAndFixClaudeSettings(workingDirectory) {
|
|
|
1624
1659
|
}
|
|
1625
1660
|
});
|
|
1626
1661
|
return true;
|
|
1627
|
-
} catch {
|
|
1662
|
+
} catch (error) {
|
|
1663
|
+
analytics.captureException(error);
|
|
1664
|
+
}
|
|
1628
1665
|
}
|
|
1629
1666
|
return false;
|
|
1630
1667
|
}
|
|
1631
1668
|
/**
|
|
1632
|
-
* Restore .claude/settings.json from .wizard-backup.
|
|
1633
|
-
*
|
|
1669
|
+
* Restore .claude/settings.json from .wizard-backup and remove the backup.
|
|
1670
|
+
*
|
|
1671
|
+
* Runs on every outro and cleanup, including runs that never had a settings
|
|
1672
|
+
* conflict (and so never wrote a backup). A missing backup is the normal,
|
|
1673
|
+
* expected state for those runs, so skip it silently — only report a genuine
|
|
1674
|
+
* copy failure. Removing the backup after a successful restore keeps repeat
|
|
1675
|
+
* calls (outro then cleanup) idempotent and avoids leaving an orphan behind.
|
|
1634
1676
|
*/
|
|
1635
1677
|
function restoreClaudeSettings(workingDirectory) {
|
|
1636
1678
|
for (const name of ["settings.json", "settings"]) {
|
|
1637
|
-
const
|
|
1679
|
+
const original = path.join(workingDirectory, ".claude", name);
|
|
1680
|
+
const backup = `${original}.wizard-backup`;
|
|
1681
|
+
if (!fs$1.existsSync(backup)) continue;
|
|
1638
1682
|
try {
|
|
1639
|
-
fs$1.copyFileSync(backup,
|
|
1683
|
+
fs$1.copyFileSync(backup, original);
|
|
1684
|
+
fs$1.rmSync(backup, { force: true });
|
|
1640
1685
|
analytics.wizardCapture("restored-claude-settings");
|
|
1641
1686
|
return;
|
|
1642
1687
|
} catch (error) {
|
|
@@ -1645,6 +1690,69 @@ function restoreClaudeSettings(workingDirectory) {
|
|
|
1645
1690
|
}
|
|
1646
1691
|
}
|
|
1647
1692
|
/**
|
|
1693
|
+
* Restore an orphaned settings backup left by a previous interrupted run.
|
|
1694
|
+
*
|
|
1695
|
+
* If a run is killed after backupAndFixClaudeSettings moved the original
|
|
1696
|
+
* aside but before restore ran, the user is left with no settings.json and a
|
|
1697
|
+
* stray .wizard-backup. The next run's conflict check then sees no file and
|
|
1698
|
+
* skips restore, so the user's settings stay silently gone. Detect that exact
|
|
1699
|
+
* state (backup present, original absent) and put the original back.
|
|
1700
|
+
*
|
|
1701
|
+
* Runs once per process, from bin.ts, before anything reads Claude settings —
|
|
1702
|
+
* conflict detection must see the user's real settings file, and a recovery
|
|
1703
|
+
* any later would resurface the conflicting overrides after the backup step
|
|
1704
|
+
* already moved them aside.
|
|
1705
|
+
*/
|
|
1706
|
+
function recoverOrphanedSettingsBackups(workingDirectory) {
|
|
1707
|
+
for (const name of ["settings.json", "settings"]) {
|
|
1708
|
+
const original = path.join(workingDirectory, ".claude", name);
|
|
1709
|
+
const backup = `${original}.wizard-backup`;
|
|
1710
|
+
if (!fs$1.existsSync(backup) || fs$1.existsSync(original)) continue;
|
|
1711
|
+
try {
|
|
1712
|
+
fs$1.copyFileSync(backup, original);
|
|
1713
|
+
fs$1.rmSync(backup, { force: true });
|
|
1714
|
+
analytics.wizardCapture("recovered-orphaned-settings");
|
|
1715
|
+
} catch (error) {
|
|
1716
|
+
analytics.captureException(error);
|
|
1717
|
+
}
|
|
1718
|
+
}
|
|
1719
|
+
}
|
|
1720
|
+
//#endregion
|
|
1721
|
+
//#region src/lib/agent/agent-interface.ts
|
|
1722
|
+
/**
|
|
1723
|
+
* Shared agent interface for PostHog wizards
|
|
1724
|
+
* Uses Claude Agent SDK directly with PostHog LLM gateway
|
|
1725
|
+
*/
|
|
1726
|
+
let _sdkModule = null;
|
|
1727
|
+
async function getSDKModule() {
|
|
1728
|
+
if (!_sdkModule) _sdkModule = await import("@anthropic-ai/claude-agent-sdk");
|
|
1729
|
+
return _sdkModule;
|
|
1730
|
+
}
|
|
1731
|
+
/**
|
|
1732
|
+
* Get the path to the bundled Claude Code CLI from the SDK package.
|
|
1733
|
+
* This ensures we use the SDK's bundled version rather than the user's installed Claude Code.
|
|
1734
|
+
*/
|
|
1735
|
+
function getClaudeCodeExecutablePath() {
|
|
1736
|
+
const sdkPackagePath = (typeof __require !== "undefined" ? __require : createRequire(process.argv[1] ?? `${process.cwd()}/`)).resolve("@anthropic-ai/claude-agent-sdk");
|
|
1737
|
+
return path.join(path.dirname(sdkPackagePath), "cli.js");
|
|
1738
|
+
}
|
|
1739
|
+
/** Region implied by the resolved gateway URL, for telemetry and display. */
|
|
1740
|
+
function regionFromGatewayUrl(gatewayUrl) {
|
|
1741
|
+
if (gatewayUrl.includes("localhost")) return "local";
|
|
1742
|
+
return gatewayUrl.includes("gateway.eu.") ? "eu" : "us";
|
|
1743
|
+
}
|
|
1744
|
+
function buildAuthErrorContext(workingDirectory, gatewayUrl, homeDir = os.homedir()) {
|
|
1745
|
+
const conflicts = checkAllSettingsConflicts(workingDirectory, homeDir);
|
|
1746
|
+
return {
|
|
1747
|
+
hasSettingsConflict: conflicts.length > 0,
|
|
1748
|
+
conflicts,
|
|
1749
|
+
conflictSources: conflicts.map((c) => c.source),
|
|
1750
|
+
conflictKeys: [...new Set(conflicts.flatMap((c) => c.keys))],
|
|
1751
|
+
gatewayUrl,
|
|
1752
|
+
region: regionFromGatewayUrl(gatewayUrl)
|
|
1753
|
+
};
|
|
1754
|
+
}
|
|
1755
|
+
/**
|
|
1648
1756
|
* Create a stop hook callback that drains the additional feature queue,
|
|
1649
1757
|
* then collects a remark, then allows stop.
|
|
1650
1758
|
*
|
|
@@ -2175,19 +2283,22 @@ async function runAgent(agentConfig, prompt, options, spinner, config, middlewar
|
|
|
2175
2283
|
if (message.type === "assistant" && signals.hasApiErrorStatus(401)) {
|
|
2176
2284
|
signalDone();
|
|
2177
2285
|
spinner.stop("Authentication failed");
|
|
2178
|
-
const
|
|
2179
|
-
|
|
2180
|
-
logToFile("Agent error: 401, showing auth error screen", {
|
|
2181
|
-
hasSettingsConflict,
|
|
2182
|
-
conflicts
|
|
2183
|
-
});
|
|
2286
|
+
const authError = buildAuthErrorContext(options.installDir, process.env.ANTHROPIC_BASE_URL ?? "");
|
|
2287
|
+
logToFile("Agent error: 401, showing auth error screen", authError);
|
|
2184
2288
|
getUI().showAuthError({
|
|
2185
|
-
hasSettingsConflict,
|
|
2289
|
+
hasSettingsConflict: authError.hasSettingsConflict,
|
|
2290
|
+
conflicts: authError.conflicts,
|
|
2186
2291
|
logFilePath: getLogFilePath()
|
|
2187
2292
|
});
|
|
2188
2293
|
await wizardAbort({
|
|
2189
2294
|
message: "Authentication failed (401)",
|
|
2190
|
-
error: new WizardError("Authentication failed"
|
|
2295
|
+
error: new WizardError("Authentication failed", {
|
|
2296
|
+
hasSettingsConflict: authError.hasSettingsConflict,
|
|
2297
|
+
conflictSources: authError.conflictSources,
|
|
2298
|
+
conflictKeys: authError.conflictKeys,
|
|
2299
|
+
gatewayUrl: authError.gatewayUrl,
|
|
2300
|
+
region: authError.region
|
|
2301
|
+
})
|
|
2191
2302
|
});
|
|
2192
2303
|
}
|
|
2193
2304
|
try {
|
|
@@ -2475,6 +2586,6 @@ function handleSDKMessage(message, options, spinner, signals, receivedSuccessRes
|
|
|
2475
2586
|
}
|
|
2476
2587
|
}
|
|
2477
2588
|
//#endregion
|
|
2478
|
-
export {
|
|
2589
|
+
export { AUDIT_CHECKS_KEY as _, backupAndFixClaudeSettings as a, coerceAuditChecks as b, restoreClaudeSettings as c, writeScanReport as d, WIZARD_TOOL_NAMES as f, AUDIT_CHECKS_FILE as g, installSkillById as h, runAgent as i, AgentSignals as l, fetchSkillMenu as m, buildWizardMetadata as n, checkAllSettingsConflicts as o, downloadSkill as p, initializeAgent as r, recoverOrphanedSettingsBackups as s, buildAgentEnv as t, formatScanReport as u, AUDIT_REPORT_FILE as v, getAuditChecks as x, AUDIT_SEVERITY_STYLE as y };
|
|
2479
2590
|
|
|
2480
|
-
//# sourceMappingURL=agent-interface-
|
|
2591
|
+
//# sourceMappingURL=agent-interface-B-LAvrNL.js.map
|