@posthog/wizard 2.72.0 → 2.73.1
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 +10 -2
- package/dist/{add-mcp-server-to-clients-QZyr6NuZ.js → add-mcp-server-to-clients-D47ONFCD.js} +4 -4
- package/dist/{add-mcp-server-to-clients-QZyr6NuZ.js.map → add-mcp-server-to-clients-D47ONFCD.js.map} +1 -1
- package/dist/{agent-interface-Yjknz6Al.js → agent-interface-CQ_iz7g7.js} +104 -19
- package/dist/agent-interface-CQ_iz7g7.js.map +1 -0
- package/dist/{agent-prompt-loader-CDXm4C35.js → agent-prompt-loader-Dh2CZEw4.js} +5 -5
- package/dist/{agent-prompt-loader-CDXm4C35.js.map → agent-prompt-loader-Dh2CZEw4.js.map} +1 -1
- package/dist/{agent-runner-CL7rCY0G.js → agent-runner-kj8juD_r.js} +14 -14
- package/dist/{agent-runner-CL7rCY0G.js.map → agent-runner-kj8juD_r.js.map} +1 -1
- package/dist/analytics-BYknS_x4.js +2 -0
- package/dist/{analytics-DjCPD6u-.js → analytics-DHkqXgxG.js} +2 -2
- package/dist/{analytics-DjCPD6u-.js.map → analytics-DHkqXgxG.js.map} +1 -1
- package/dist/{api-xwQeBMcX.js → api-BM5Gaf2x.js} +3 -3
- package/dist/{api-xwQeBMcX.js.map → api-BM5Gaf2x.js.map} +1 -1
- package/dist/bin.js +45 -45
- package/dist/bin.js.map +1 -1
- package/dist/{bounded-fs-BtxN0nYO.js → bounded-fs-Byv2xRSy.js} +3 -3
- package/dist/{bounded-fs-BtxN0nYO.js.map → bounded-fs-Byv2xRSy.js.map} +1 -1
- package/dist/{ci-install-BVzTnIBw.js → ci-install-BUUD2hSG.js} +4 -4
- package/dist/{ci-install-BVzTnIBw.js.map → ci-install-BUUD2hSG.js.map} +1 -1
- package/dist/{debug-BoadIH6Q.js → debug-C14qe0b-.js} +1 -1
- package/dist/{debug-D0T44879.js → debug-D0k3Quos.js} +50 -16
- package/dist/debug-D0k3Quos.js.map +1 -0
- package/dist/{env-api-key-Bj9butHX.js → env-api-key-CBjWUJTZ.js} +2 -2
- package/dist/{env-api-key-Bj9butHX.js.map → env-api-key-CBjWUJTZ.js.map} +1 -1
- package/dist/{environment-vpmKreMf.js → environment-DqdmG3WX.js} +4 -4
- package/dist/{environment-vpmKreMf.js.map → environment-DqdmG3WX.js.map} +1 -1
- package/dist/{file-watcher-BPH4wR8R.js → file-watcher-CxStDuTR.js} +2 -2
- package/dist/{file-watcher-BPH4wR8R.js.map → file-watcher-CxStDuTR.js.map} +1 -1
- package/dist/{headless-ui-vA7lv8m2.js → headless-ui-DC1Qus7M.js} +2 -2
- package/dist/{headless-ui-vA7lv8m2.js.map → headless-ui-DC1Qus7M.js.map} +1 -1
- package/dist/{interactive-jk3IGgns.js → interactive-DeNrHRZE.js} +2 -2
- package/dist/{interactive-jk3IGgns.js.map → interactive-DeNrHRZE.js.map} +1 -1
- package/dist/{mcp-DE2AonGF.js → mcp-Bnjc-Qsz.js} +2 -2
- package/dist/{mcp-DE2AonGF.js.map → mcp-Bnjc-Qsz.js.map} +1 -1
- package/dist/{mcp-prompt-streaming-pPEIwc78.js → mcp-prompt-streaming-Va6vRL7E.js} +4 -4
- package/dist/{mcp-prompt-streaming-pPEIwc78.js.map → mcp-prompt-streaming-Va6vRL7E.js.map} +1 -1
- package/dist/{non-interactive-CEGz0nDY.js → non-interactive-ZACUU6DC.js} +2 -2
- package/dist/{non-interactive-CEGz0nDY.js.map → non-interactive-ZACUU6DC.js.map} +1 -1
- package/dist/{orchestrator-tools-BZ4Nzw6a.js → orchestrator-tools-BI3suN6p.js} +3 -3
- package/dist/{orchestrator-tools-BZ4Nzw6a.js.map → orchestrator-tools-BI3suN6p.js.map} +1 -1
- package/dist/{package-manager-BZjKEDO2.js → package-manager-DgRcS6CY.js} +2 -2
- package/dist/{package-manager-BZjKEDO2.js.map → package-manager-DgRcS6CY.js.map} +1 -1
- package/dist/{pi-D48qAwlf.js → pi-DbEYScTs.js} +11 -11
- package/dist/{pi-D48qAwlf.js.map → pi-DbEYScTs.js.map} +1 -1
- package/dist/{playground-DYGJwugo.js → playground-xa1G6pym.js} +8 -8
- package/dist/playground-xa1G6pym.js.map +1 -0
- package/dist/{posthog-BTvVhvBY.js → posthog-Dk8S5c6h.js} +2 -2
- package/dist/{posthog-BTvVhvBY.js.map → posthog-Dk8S5c6h.js.map} +1 -1
- package/dist/{posthog-integration-BQh-YQAP.js → posthog-integration-BG5Y9Fb4.js} +12 -12
- package/dist/{posthog-integration-BQh-YQAP.js.map → posthog-integration-BG5Y9Fb4.js.map} +1 -1
- package/dist/{provisioning-Dw3B2T_b.js → provisioning-e7J3SvpF.js} +3 -3
- package/dist/{provisioning-Dw3B2T_b.js.map → provisioning-e7J3SvpF.js.map} +1 -1
- package/dist/{queue-tools-DEbzMDrF.js → queue-tools-C3D_nwy_.js} +3 -3
- package/dist/{queue-tools-DEbzMDrF.js.map → queue-tools-C3D_nwy_.js.map} +1 -1
- package/dist/{registry-Dv6JVm5r.js → registry-Bw-e1Fes.js} +5 -5
- package/dist/{registry-Dv6JVm5r.js.map → registry-Bw-e1Fes.js.map} +1 -1
- package/dist/{security-BaggjIE4.js → security-BUg5_2uC.js} +5 -5
- package/dist/{security-BaggjIE4.js.map → security-BUg5_2uC.js.map} +1 -1
- package/dist/{setup-utils-CnW0Zsu8.js → setup-utils-CzMg2Vpy.js} +8 -8
- package/dist/{setup-utils-CnW0Zsu8.js.map → setup-utils-CzMg2Vpy.js.map} +1 -1
- package/dist/{start-tui-SpyGz7wM.js → start-tui-Kt61g7LE.js} +30 -30
- package/dist/start-tui-Kt61g7LE.js.map +1 -0
- package/dist/{steps-ClfUajTv.js → steps-De2a1a0X.js} +7 -7
- package/dist/{steps-ClfUajTv.js.map → steps-De2a1a0X.js.map} +1 -1
- package/dist/{store-Cmy0pN1R.js → store-DDrR7nF6.js} +6 -6
- package/dist/store-DDrR7nF6.js.map +1 -0
- package/dist/{subagent-tYlbbkJt.js → subagent-cD2JOzo1.js} +2 -2
- package/dist/{subagent-tYlbbkJt.js.map → subagent-cD2JOzo1.js.map} +1 -1
- package/dist/{task-B8QfEVcu.js → task-FBY3mllc.js} +12 -12
- package/dist/{task-B8QfEVcu.js.map → task-FBY3mllc.js.map} +1 -1
- package/dist/{task-stream-BRSWhbXQ.js → task-stream-BjTFIY4l.js} +4 -4
- package/dist/{task-stream-BRSWhbXQ.js.map → task-stream-BjTFIY4l.js.map} +1 -1
- package/dist/{tasks-DjEvyWQJ.js → tasks-BjevyqMO.js} +2 -2
- package/dist/{tasks-DjEvyWQJ.js.map → tasks-BjevyqMO.js.map} +1 -1
- package/dist/{telemetry-EPB2n_f6.js → telemetry-Asp60nwm.js} +3 -3
- package/dist/{telemetry-EPB2n_f6.js.map → telemetry-Asp60nwm.js.map} +1 -1
- package/dist/{terminal-DJ4Gaupr.js → terminal-CVgx_zHz.js} +11 -11
- package/dist/{terminal-DJ4Gaupr.js.map → terminal-CVgx_zHz.js.map} +1 -1
- package/dist/{tools-CB0Vfc6r.js → tools-CPwnElLN.js} +6 -6
- package/dist/{tools-CB0Vfc6r.js.map → tools-CPwnElLN.js.map} +1 -1
- package/dist/{wizard-abort-Db_YNkB2.js → wizard-abort-DKpVH-t6.js} +3 -3
- package/dist/{wizard-abort-Db_YNkB2.js.map → wizard-abort-DKpVH-t6.js.map} +1 -1
- package/dist/{wizard-abort-DD-kkQaq.js → wizard-abort-owSE9WC8.js} +1 -1
- package/dist/{yara-hooks-BvyFD2Nb.js → yara-hooks-D-QD1ZCB.js} +7 -6
- package/dist/yara-hooks-D-QD1ZCB.js.map +1 -0
- package/dist/yara-hooks-DPo3t8nU.js +2 -0
- package/package.json +2 -2
- package/dist/agent-interface-Yjknz6Al.js.map +0 -1
- package/dist/analytics-CkNv3N4o.js +0 -2
- package/dist/debug-D0T44879.js.map +0 -1
- package/dist/playground-DYGJwugo.js.map +0 -1
- package/dist/start-tui-SpyGz7wM.js.map +0 -1
- package/dist/store-Cmy0pN1R.js.map +0 -1
- package/dist/yara-hooks-BvyFD2Nb.js.map +0 -1
- package/dist/yara-hooks-CuW_b30M.js +0 -2
package/README.md
CHANGED
|
@@ -614,7 +614,7 @@ point is `evaluateWizardReadiness()`, which returns one of three values:
|
|
|
614
614
|
| --- | --- |
|
|
615
615
|
| `types.ts` | Enums, interfaces (`ServiceHealthStatus`, `AllServicesHealth`, etc.) |
|
|
616
616
|
| `statuspage.ts` | Statuspage.io v2 API helpers + checks for Anthropic, PostHog, GitHub, npm, Cloudflare |
|
|
617
|
-
| `endpoints.ts` | Direct endpoint checks for LLM Gateway (`/_liveness`)
|
|
617
|
+
| `endpoints.ts` | Direct endpoint checks for LLM Gateway (`/_liveness`), MCP (`/`), and the skills origins (`skill-menu.json` on GitHub Releases + the AWS mirror) |
|
|
618
618
|
| `readiness.ts` | `checkAllExternalServices`, `evaluateWizardReadiness`, readiness config |
|
|
619
619
|
| `index.ts` | Barrel re-export |
|
|
620
620
|
| `testme.md` | Test running instructions and endpoint reference |
|
|
@@ -632,10 +632,18 @@ two arrays:
|
|
|
632
632
|
### Current defaults
|
|
633
633
|
|
|
634
634
|
```ts
|
|
635
|
-
downBlocksRun: ['anthropic', '
|
|
635
|
+
downBlocksRun: ['anthropic', 'npmOverall', 'llmGateway', 'mcp', 'skillsOrigin'],
|
|
636
636
|
degradedBlocksRun: ['anthropic'],
|
|
637
637
|
```
|
|
638
638
|
|
|
639
|
+
`skillsOrigin` is one entry covering two origins: skills are published to
|
|
640
|
+
GitHub Releases and an AWS mirror under the same filenames, and downloads fail
|
|
641
|
+
over between them (`src/lib/fetch-retry.ts`). Both are probed in parallel, so
|
|
642
|
+
the key only reports **Down** when neither origin answers — a GitHub Releases
|
|
643
|
+
outage on its own doesn't block a run, including a 403 or 404, which is as
|
|
644
|
+
often about the origin (expired asset redirect, blocked region, a publish that
|
|
645
|
+
reached one origin and not the other) as about the asset.
|
|
646
|
+
|
|
639
647
|
## Smoke test helper (`scripts/smoke-test-ci.sh`)
|
|
640
648
|
|
|
641
649
|
This repo includes a helper script to run a full end‑to‑end smoke test of the wizard packaged in a tarball against a real app from [`posthog/wizard-workbench`](https://github.com/PostHog/wizard-workbench). This will catch certain packaging issues that might not be caught by other tests.
|
package/dist/{add-mcp-server-to-clients-QZyr6NuZ.js → add-mcp-server-to-clients-D47ONFCD.js}
RENAMED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { t as __exportAll } from "./rolldown-runtime-B_-DWIq7.js";
|
|
2
|
-
import {
|
|
3
|
-
import { n as analytics } from "./analytics-
|
|
4
|
-
import { n as openTrackedLink, t as withProgress } from "./telemetry-
|
|
2
|
+
import { St as runtimeEnv, f as getUI, r as debug } from "./debug-D0k3Quos.js";
|
|
3
|
+
import { n as analytics } from "./analytics-DHkqXgxG.js";
|
|
4
|
+
import { n as openTrackedLink, t as withProgress } from "./telemetry-Asp60nwm.js";
|
|
5
5
|
import { a as getNativeHTTPServerConfig, c as namesWithStatus, d as toClientResult, i as getDefaultServerConfig, l as redactSecrets, r as buildMCPUrl, t as ALL_FEATURE_VALUES } from "./defaults-DI642M3n.js";
|
|
6
6
|
import * as fs$2 from "fs";
|
|
7
7
|
import * as path$3 from "path";
|
|
@@ -900,4 +900,4 @@ const removeMCPServer = async (clients, local) => {
|
|
|
900
900
|
//#endregion
|
|
901
901
|
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 };
|
|
902
902
|
|
|
903
|
-
//# sourceMappingURL=add-mcp-server-to-clients-
|
|
903
|
+
//# sourceMappingURL=add-mcp-server-to-clients-D47ONFCD.js.map
|
package/dist/{add-mcp-server-to-clients-QZyr6NuZ.js.map → add-mcp-server-to-clients-D47ONFCD.js.map}
RENAMED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"add-mcp-server-to-clients-QZyr6NuZ.js","names":["fs","path","path","os","path","os","fs","execSync","z","os","path","z","os","path","path","fs","z","path","fs","os"],"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/clients/opencode.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';\nimport type { InstallResult } from './results';\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<InstallResult>;\n abstract removeServer(local?: boolean): Promise<InstallResult>;\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<InstallResult> {\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\n // An identical entry means this config is already set up — leave the file\n // untouched and report it, so a re-run says \"already installed\" instead of\n // claiming a write that changed nothing. A differing entry (new features,\n // new key) still gets overwritten and reported as installed.\n const existingServerConfig = typedConfig[serverPropertyName][serverName];\n if (\n existingServerConfig !== undefined &&\n JSON.stringify(existingServerConfig) === JSON.stringify(newServerConfig)\n ) {\n return { success: true, alreadyInstalled: true };\n }\n\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 (error) {\n return {\n success: false,\n reason: error instanceof Error ? error.message : String(error),\n };\n }\n }\n\n async removeServer(local?: boolean): Promise<InstallResult> {\n let configPath = '';\n try {\n configPath = await this.getConfigPath();\n\n if (!fs.existsSync(configPath)) {\n return { success: true, alreadyInstalled: true };\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 // No PostHog entry to delete — the config changed under us between the\n // detection pass and now. Nothing failed, so don't report a failure.\n return { success: true, alreadyInstalled: true };\n } catch (error) {\n return {\n success: false,\n reason: `${configPath}: ${\n error instanceof Error ? error.message : String(error)\n }`,\n };\n }\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 {\n redactSecrets,\n type InstallResult,\n} from '@steps/add-mcp-server-to-clients/results';\nimport { LoginCapable } from '@steps/add-mcp-server-to-clients/login-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, LoginCapable\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 // `mcp get <name>` exits non-zero when the entry doesn't exist. A substring\n // scan of `mcp list` also matches the claude.ai \"PostHog\" connector and the\n // plugin's `plugin:posthog:posthog`, reporting installed forever.\n try {\n execSync(`${binary} mcp get ${serverName}`, { stdio: 'pipe' });\n return Promise.resolve(true);\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<InstallResult> {\n const binary = this.findClaudeBinary();\n if (!binary)\n return Promise.resolve({\n success: false,\n reason: 'The claude CLI is no longer on your PATH.',\n });\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 // The failing command echoes back the Authorization header we passed, so\n // redact before this reaches a log, the screen, or an exception report.\n const msg = redactSecrets(\n error instanceof Error ? error.message : String(error),\n );\n if (msg.includes('already exists')) {\n return Promise.resolve({ success: true, alreadyInstalled: true });\n }\n analytics.captureException(\n new Error(`Claude Code MCP add failed: ${msg}`),\n );\n return Promise.resolve({ success: false, reason: msg });\n }\n }\n\n /** Claude Code's own login runs its OAuth and owns the token; the wizard only surfaces the command. */\n loginCommand(local?: boolean): string {\n return `claude mcp login ${local ? 'posthog-local' : 'posthog'}`;\n }\n\n /** The plugin bundles its own `posthog` server, addressed as `plugin:<plugin>:<server>`. */\n pluginLoginCommand(): string {\n return 'claude mcp login plugin:posthog:posthog';\n }\n\n async removePlugin(): Promise<PluginInstallResult> {\n const binary = this.findClaudeBinary();\n if (!binary)\n return {\n success: false,\n reason: 'The claude CLI is no longer on your PATH.',\n };\n\n if (!(await this.isPluginInstalled())) {\n return { success: true, alreadyInstalled: true };\n }\n\n try {\n execSync(`${binary} plugin uninstall posthog`, { stdio: 'pipe' });\n return { success: true };\n } catch (error) {\n const msg = error instanceof Error ? error.message : String(error);\n analytics.captureException(\n new Error(`Claude Code plugin uninstall failed: ${msg}`),\n );\n return { success: false, reason: msg };\n }\n }\n\n removeServer(local?: boolean): Promise<InstallResult> {\n const claudeBinary = this.findClaudeBinary();\n if (!claudeBinary) {\n return Promise.resolve({\n success: false,\n reason: 'The claude CLI is no longer on your PATH.',\n });\n }\n\n const serverName = local ? 'posthog-local' : 'posthog';\n const command = `${claudeBinary} mcp remove --scope user ${serverName}`;\n\n try {\n execSync(command, { stdio: 'pipe' });\n } catch (error) {\n const reason = redactSecrets(\n error instanceof Error ? error.message : String(error),\n );\n // Removing something that isn't there is the requested end state, not a\n // failure to report.\n if (/no( such)? mcp server|not found/i.test(reason)) {\n return Promise.resolve({ success: true, alreadyInstalled: true });\n }\n analytics.captureException(\n new Error(`Failed to remove server from Claude Code: ${reason}`),\n );\n return Promise.resolve({ success: false, reason });\n }\n\n return Promise.resolve({ success: true });\n }\n\n /** The plugin ships mcp.json with the posthog server — no direct entry needed. */\n pluginBundlesMcpServer(): boolean {\n return 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 async installPlugin(): Promise<PluginInstallResult> {\n const binary = this.findClaudeBinary();\n if (!binary)\n return {\n success: false,\n reason: 'The claude CLI is no longer on your PATH.',\n };\n\n // Ask before installing so a re-run reports \"already installed\" rather than\n // relying on the CLI's error text to spot the no-op.\n if (await this.isPluginInstalled()) {\n return { success: true, alreadyInstalled: true };\n }\n\n try {\n execSync(`${binary} plugin install posthog`, { stdio: 'pipe' });\n return { 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 { success: true, alreadyInstalled: true };\n }\n analytics.captureException(\n new Error(`Claude Code plugin install failed: ${msg}`),\n );\n return { success: false, reason: msg };\n }\n }\n}\n","import { MCPClient } from '@steps/add-mcp-server-to-clients/MCPClient';\nimport type { InstallResult } from '@steps/add-mcp-server-to-clients/results';\nimport { BrowserFinishable } from '@steps/add-mcp-server-to-clients/browser-client';\nimport { openTrackedLink } from '@utils/links';\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<InstallResult> {\n // Not a PostHog property, so no UTMs — just the tracked open.\n openTrackedLink(this.connectorUrl, 'claude-web-connector', {\n auto: true,\n skipUtm: true,\n });\n return Promise.resolve({ success: true });\n }\n\n removeServer(): Promise<InstallResult> {\n // The connector lives in the user's Claude account, so `mcp remove` can't\n // touch it. It never reaches here today (isServerInstalled is always\n // false), but say where to go if it ever does.\n return Promise.resolve({\n success: false,\n reason:\n 'This connector is managed in your Claude account — remove it at claude.ai/settings/connectors.',\n });\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 { LoginCapable } from '@steps/add-mcp-server-to-clients/login-client';\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';\nimport {\n redactSecrets,\n type InstallResult,\n} from '@steps/add-mcp-server-to-clients/results';\n\nimport { analytics } from '@utils/analytics';\n\n/** Wording codex uses when the thing we're adding is already registered. */\nconst ALREADY_INSTALLED_PATTERN =\n /already (installed|exists|added|registered)/i;\n/** Wording that means the opposite: a cache entry exists but the plugin doesn't. */\nconst STALE_MARKETPLACE_CACHE = /already added from a different source/i;\n\n/**\n * Codex allows servers 10s to finish the MCP initialize handshake, and a remote\n * OAuth handshake can exceed that on a cold start — the \"servers were not\n * initialized\" warning.\n */\nconst STARTUP_TIMEOUT_SEC = 30;\n\n/**\n * The server's table header. TOML accepts a bare or quoted key for the same\n * table, and matching only the bare form means we append a second definition of\n * a table that already exists — a duplicate-key error that takes the user's\n * whole config down, not just PostHog's entry.\n */\nconst sectionHeader = (serverName: string): RegExp =>\n new RegExp(\n `^\\\\[mcp_servers\\\\.(?:${serverName}|\"${serverName}\")\\\\][ \\\\t]*$`,\n 'm',\n );\n\n/**\n * Set `key = value` inside a section body, inserting it when absent. Scans the\n * whole body rather than the line after the header: TOML does not care about\n * key order, and assuming it does means silently matching nothing.\n */\nconst setKey = (body: string, key: string, value: string): string => {\n const existing = new RegExp(`^[ \\\\t]*${key}[ \\\\t]*=.*$`, 'm');\n return existing.test(body)\n ? body.replace(existing, `${key} = ${value}`)\n : `\\n${key} = ${value}${body}`;\n};\n\nexport const CodexMCPConfig = DefaultMCPClientConfig;\n\nexport type CodexMCPConfig = z.infer<typeof DefaultMCPClientConfig>;\n\nexport class CodexMCPClient\n extends DefaultMCPClient\n implements PluginCapable, LoginCapable\n{\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 private configPath(): string {\n return path.join(os.homedir(), '.codex', 'config.toml');\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 serverName = local ? 'posthog-local' : 'posthog';\n // The `[mcp_servers.<name>]` section in config.toml — both the CLI and the\n // desktop app read (and `codex mcp add` writes) this file, and a substring\n // scan of `mcp list` matches unrelated posthog-ish servers.\n try {\n const contents = fs.readFileSync(this.configPath(), 'utf-8');\n return Promise.resolve(sectionHeader(serverName).test(contents));\n } catch {\n return Promise.resolve(false);\n }\n }\n\n addServer(\n apiKey?: string,\n selectedFeatures?: string[],\n local?: boolean,\n ): Promise<InstallResult> {\n const serverName = local ? 'posthog-local' : 'posthog';\n const url = buildMCPUrl(selectedFeatures, local);\n\n // Api-key installs go through the CLI for its bearer-token env wiring.\n if (apiKey) {\n const binary = this.findCodexBinary();\n if (!binary)\n return Promise.resolve({\n success: false,\n reason: 'An API-key install into Codex needs the codex CLI.',\n });\n const args = [\n 'mcp',\n 'add',\n serverName,\n '--url',\n url,\n '--bearer-token-env-var',\n 'POSTHOG_AUTH_HEADER',\n ];\n const env = { ...process.env, POSTHOG_AUTH_HEADER: `Bearer ${apiKey}` };\n const result = spawnSync(binary, args, { encoding: 'utf-8', env });\n if (result.status !== 0) {\n const stderr = result.stderr ?? '';\n if (ALREADY_INSTALLED_PATTERN.test(stderr)) {\n return Promise.resolve({ success: true, alreadyInstalled: true });\n }\n const reason = redactSecrets(stderr);\n analytics.captureException(\n new Error(`Codex MCP add failed: ${reason}`),\n );\n return Promise.resolve({ success: false, reason });\n }\n return Promise.resolve({ success: true });\n }\n\n // OAuth installs write config.toml directly: running `codex mcp add` here\n // would hang the wizard on its built-in OAuth browser wait. Codex nags\n // about the unauthenticated server until the surfaced `codex mcp login`\n // runs — the same interim state as Claude Code's \"needs authentication\".\n return Promise.resolve(this.writeServerSection(serverName, url));\n }\n\n /**\n * Create or update the `[mcp_servers.<name>]` section in config.toml, editing\n * in place so the user's other servers, key order, and comments survive.\n */\n private writeServerSection(serverName: string, url: string): InstallResult {\n const configPath = this.configPath();\n try {\n // A machine that has codex installed but has never run it has no\n // ~/.codex at all — `codex mcp add` used to create it for us.\n fs.mkdirSync(path.dirname(configPath), { recursive: true });\n const contents = fs.existsSync(configPath)\n ? fs.readFileSync(configPath, 'utf-8')\n : '';\n\n const header = sectionHeader(serverName).exec(contents);\n if (!header) {\n const gap = contents === '' || contents.endsWith('\\n\\n') ? '' : '\\n';\n const pad = contents === '' || contents.endsWith('\\n') ? '' : '\\n';\n this.write(\n configPath,\n `${contents}${pad}${gap}[mcp_servers.${serverName}]\\n` +\n `url = \"${url}\"\\nstartup_timeout_sec = ${STARTUP_TIMEOUT_SEC}\\n`,\n );\n return { success: true };\n }\n\n // Everything up to the next table header belongs to this server.\n const start = header.index + header[0].length;\n const rest = contents.slice(start);\n const next = /^\\[/m.exec(rest);\n const end = next ? start + next.index : contents.length;\n\n const body = contents.slice(start, end);\n const updated = setKey(\n setKey(body, 'url', `\"${url}\"`),\n 'startup_timeout_sec',\n String(STARTUP_TIMEOUT_SEC),\n );\n if (updated === body) return { success: true, alreadyInstalled: true };\n\n this.write(\n configPath,\n contents.slice(0, start) + updated + contents.slice(end),\n );\n return { success: true };\n } catch (error) {\n const reason = error instanceof Error ? error.message : String(error);\n analytics.captureException(\n new Error(`Codex config.toml write failed: ${reason}`),\n );\n return { success: false, reason };\n }\n }\n\n /** Write via a sibling temp file: a crash mid-write must not truncate the config. */\n private write(configPath: string, contents: string): void {\n const tmp = `${configPath}.wizard-tmp`;\n fs.writeFileSync(tmp, contents);\n fs.renameSync(tmp, configPath);\n }\n\n /** Codex's own login runs its OAuth and owns the token; the wizard only surfaces the command. */\n loginCommand(local?: boolean): string | null {\n if (!this.findCodexBinary()) return null;\n return `codex mcp login ${local ? 'posthog-local' : 'posthog'}`;\n }\n\n removeServer(local?: boolean): Promise<InstallResult> {\n const binary = this.findCodexBinary();\n if (!binary)\n return Promise.resolve({\n success: false,\n reason: 'The codex CLI is no longer on your PATH.',\n });\n\n // `local` was ignored here, so `mcp remove --local` reported success while\n // leaving the posthog-local server in place.\n const serverName = local ? 'posthog-local' : 'posthog';\n const result = spawnSync(binary, ['mcp', 'remove', serverName], {\n encoding: 'utf-8',\n });\n\n if (result.error || result.status !== 0) {\n const reason = redactSecrets(\n result.error?.message ?? result.stderr ?? 'codex mcp remove failed',\n );\n analytics.captureException(\n new Error(`Failed to remove server from Codex CLI: ${reason}`),\n );\n return Promise.resolve({ success: false, reason });\n }\n\n return Promise.resolve({ success: true });\n }\n\n /** The codex marketplace plugin ships skills only — the MCP server needs its own entry. */\n pluginBundlesMcpServer(): boolean {\n return false;\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 async removePlugin(): Promise<PluginInstallResult> {\n const binary = this.findCodexBinary();\n if (!binary)\n return {\n success: false,\n reason: 'The codex CLI is no longer on your PATH.',\n };\n\n if (!(await this.isPluginInstalled())) {\n return { success: true, alreadyInstalled: true };\n }\n\n const result = spawnSync(\n binary,\n ['plugin', 'marketplace', 'remove', 'posthog'],\n { encoding: 'utf-8' },\n );\n if (result.status !== 0) {\n const reason = redactSecrets(\n result.stderr ?? 'codex plugin marketplace remove failed',\n );\n analytics.captureException(\n new Error(`Codex plugin uninstall failed: ${reason}`),\n );\n return { success: false, reason };\n }\n return { success: true };\n }\n\n async installPlugin(): Promise<PluginInstallResult> {\n const binary = this.findCodexBinary();\n if (!binary)\n return {\n success: false,\n reason: 'The codex CLI is no longer on your PATH.',\n };\n\n // `codex plugin marketplace add` exits non-zero once the marketplace is\n // registered, so ask config.toml first. Without this the second run of\n // `mcp add` looked like a failure and reported nothing at all.\n if (await this.isPluginInstalled()) {\n return { success: true, alreadyInstalled: true };\n }\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 STALE_MARKETPLACE_CACHE.test(result.stderr ?? '')\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 const stderr = result.stderr ?? '';\n // The marketplace was registered by something other than us (a manual\n // `codex plugin marketplace add`, or a version that writes config.toml\n // differently) — that's still \"already installed\", not a failure. The\n // stale-cache wording above is deliberately excluded: that one means the\n // plugin is NOT registered, and it only reaches here if the retry failed.\n if (\n ALREADY_INSTALLED_PATTERN.test(stderr) &&\n !STALE_MARKETPLACE_CACHE.test(stderr)\n ) {\n return { success: true, alreadyInstalled: true };\n }\n const reason = redactSecrets(stderr);\n analytics.captureException(\n new Error(`Codex plugin install failed: ${reason}`),\n );\n return { success: false, reason };\n }\n\n return { success: true };\n }\n}\n\nexport default CodexMCPClient;\n","import z from 'zod';\nimport * as path from 'path';\nimport * as os from 'os';\nimport * as fs from 'fs';\nimport { execSync } from 'node:child_process';\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 OpenCodeMCPConfig = z\n .object({\n mcp: z.record(\n z.string(),\n z.object({\n type: z.literal('remote'),\n url: z.string(),\n headers: z.record(z.string(), z.string()).optional(),\n }),\n ),\n })\n .passthrough();\n\nexport type OpenCodeMCPConfig = z.infer<typeof OpenCodeMCPConfig>;\n\nexport class OpenCodeMCPClient extends DefaultMCPClient {\n name = 'OpenCode';\n private opencodeBinaryPath: string | null = null;\n\n override getServerPropertyName(): string {\n return 'mcp';\n }\n\n private findOpenCodeBinary(): string | null {\n if (this.opencodeBinaryPath) return this.opencodeBinaryPath;\n try {\n const resolved = execSync('command -v opencode', { stdio: 'pipe' })\n .toString()\n .trim();\n if (resolved) {\n this.opencodeBinaryPath = 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.findOpenCodeBinary() !== null);\n }\n\n getConfigPath(): Promise<string> {\n const configDir = this.resolveConfigDir();\n const jsoncPath = path.join(configDir, 'opencode.jsonc');\n const jsonPath = path.join(configDir, 'opencode.json');\n if (fs.existsSync(jsoncPath)) return Promise.resolve(jsoncPath);\n return Promise.resolve(jsonPath);\n }\n\n private resolveConfigDir(): string {\n const envDir = runtimeEnv('OPENCODE_CONFIG_DIR');\n if (envDir) return envDir;\n\n const xdgHome = runtimeEnv('XDG_CONFIG_HOME');\n if (xdgHome) return path.join(xdgHome, 'opencode');\n\n return path.join(os.homedir(), '.config', 'opencode');\n }\n\n override getServerConfig(\n apiKey: string | undefined,\n selectedFeatures?: string[],\n local?: boolean,\n ): MCPServerConfig {\n return {\n type: 'remote',\n ...getNativeHTTPServerConfig(apiKey, selectedFeatures, local),\n };\n }\n}\n","import type { InstallResult } from './results';\n\nexport type PluginInstallResult = InstallResult;\n\nexport interface PluginCapable {\n supportsPlugin(): boolean;\n isPluginInstalled(): Promise<boolean>;\n installPlugin(): Promise<PluginInstallResult>;\n /** Uninstall the plugin. Absent when the client CLI has no uninstall surface. */\n removePlugin?(): Promise<PluginInstallResult>;\n /** True when the plugin ships its own posthog MCP server, making a direct entry redundant. */\n pluginBundlesMcpServer(): boolean;\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 { OpenCodeMCPClient } from './clients/opencode';\nimport { ALL_FEATURE_VALUES } from './defaults';\nimport { debug } from '@utils/debug';\nimport { isPluginCapable, PluginCapable } from './plugin-client';\nimport {\n McpClientStatus,\n namesWithStatus,\n toClientResult,\n type McpClientResult,\n} from './results';\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 new OpenCodeMCPClient(),\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/** Per-client outcome, so a scripted caller can turn a failure into an exit code. */\nexport interface McpStepOutcome {\n /** Clients that ended up with the server, whether we wrote it or it was already there. */\n installed: string[];\n failed: string[];\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<McpStepOutcome> => {\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 { installed: [], failed: [] };\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 { installed: [], failed: [] };\n }\n\n // Auto-install to all supported clients\n const results = await withProgress('adding mcp servers', () =>\n addMCPServer(\n supportedClients,\n apiKey,\n features ?? [...ALL_FEATURE_VALUES],\n local,\n ),\n );\n\n const installed = namesWithStatus(results, McpClientStatus.Changed);\n const already = namesWithStatus(results, McpClientStatus.Unchanged);\n const failed = results.filter((r) => r.status === McpClientStatus.Failed);\n\n // Report each outcome on its own — a blanket \"Added the MCP server to: ...\"\n // hid both the no-op re-runs and the outright failures.\n if (installed.length > 0) {\n ui.log.success(`Added the MCP server to:\\n${bulletList(installed)}`);\n }\n if (already.length > 0) {\n ui.log.info(\n `The PostHog MCP server was already installed, so nothing changed for:\\n${bulletList(\n already,\n )}`,\n );\n }\n if (failed.length > 0) {\n ui.log.warn(\n `Couldn't add the MCP server to:\\n${bulletList(\n failed.map((r) => (r.detail ? `${r.name} — ${r.detail}` : r.name)),\n )}`,\n );\n }\n\n const withServer = [...installed, ...already];\n\n analytics.wizardCapture('mcp servers added', {\n // `clients` stays \"every client that ended up with the MCP server\", which is\n // what it meant before — the new properties break that down.\n clients: withServer,\n already_installed_clients: already,\n failed_clients: failed.map((r) => r.name),\n attempted_clients: supportedClients.map((c) => c.name),\n integration,\n });\n\n return { installed: withServer, failed: failed.map((r) => r.name) };\n};\n\nconst bulletList = (items: string[]): string =>\n items.map((item) => ` - ${item}`).join('\\n');\n\nexport const removeMCPServerFromClientsStep = async ({\n integration,\n local = false,\n}: {\n integration?: Integration;\n local?: boolean;\n}): Promise<string[]> => {\n const ui = getUI();\n const installedClients = await getInstalledClients(local);\n if (installedClients.length === 0) {\n ui.log.info(\n 'The PostHog MCP server is not installed for any supported client. Nothing to remove.',\n );\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', () =>\n removeMCPServer(installedClients, local),\n );\n\n const removed = namesWithStatus(results, McpClientStatus.Changed);\n const nothingToDo = namesWithStatus(results, McpClientStatus.Unchanged);\n const failed = results.filter((r) => r.status === McpClientStatus.Failed);\n\n // This step used to print nothing at all, so a non-TTY `mcp remove` gave no\n // hint whether anything happened — let alone whether a client failed.\n if (removed.length > 0) {\n ui.log.success(`Removed the MCP server from:\\n${bulletList(removed)}`);\n }\n if (nothingToDo.length > 0) {\n ui.log.info(\n `No PostHog MCP entry left to remove for:\\n${bulletList(nothingToDo)}`,\n );\n }\n if (failed.length > 0) {\n ui.log.warn(\n `Couldn't remove the MCP server from:\\n${bulletList(\n failed.map((r) => (r.detail ? `${r.name} — ${r.detail}` : r.name)),\n )}`,\n );\n }\n\n analytics.wizardCapture('mcp servers removed', {\n clients: removed,\n nothing_to_remove_clients: nothingToDo,\n failed_clients: failed.map((r) => r.name),\n attempted_clients: installedClients.map((c) => c.name),\n integration,\n });\n\n return removed;\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 // The plugin bundles its own posthog MCP server, so for removal purposes a\n // plugin install counts as installed even with no config entry (`--local`\n // targets only the local-dev entry and leaves the plugin alone).\n const pluginInstalled =\n !local && isPluginCapable(client) && (await client.isPluginInstalled());\n if ((await client.isServerInstalled(local)) || pluginInstalled) {\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<McpClientResult[]> => {\n const results: McpClientResult[] = [];\n for (const client of clients) {\n try {\n const result = await client.addServer(\n personalApiKey,\n selectedFeatures,\n local,\n );\n results.push(toClientResult(client.name, result));\n } catch (err) {\n debug(`[addMCPServer] addServer threw for ${client.name}: ${err}`);\n results.push(\n toClientResult(client.name, {\n success: false,\n reason: err instanceof Error ? err.message : String(err),\n }),\n );\n }\n }\n return results;\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<McpClientResult[]> => {\n const results: McpClientResult[] = [];\n for (const client of clients) {\n try {\n results.push(toClientResult(client.name, await client.installPlugin()));\n } catch (err) {\n debug(`[installPlugins] installPlugin threw for ${client.name}: ${err}`);\n results.push(\n toClientResult(client.name, {\n success: false,\n reason: err instanceof Error ? err.message : String(err),\n }),\n );\n }\n }\n return results;\n};\n\nexport const removeMCPServer = async (\n clients: MCPClient[],\n local?: boolean,\n): Promise<McpClientResult[]> => {\n const results: McpClientResult[] = [];\n for (const client of clients) {\n try {\n let result = await client.removeServer(local);\n // The plugin bundles its own posthog server — leaving it installed makes\n // the removal a lie (`--local` never touches the plugin).\n if (!local && isPluginCapable(client) && client.removePlugin) {\n const plugin = await client.removePlugin();\n result =\n !result.success || !plugin.success\n ? {\n success: false,\n reason: [result.reason, plugin.reason]\n .filter(Boolean)\n .join('; '),\n }\n : {\n success: true,\n ...(result.alreadyInstalled && plugin.alreadyInstalled\n ? { alreadyInstalled: true }\n : {}),\n };\n }\n results.push(toClientResult(client.name, result));\n } catch (err) {\n debug(`[removeMCPServer] removeServer threw for ${client.name}: ${err}`);\n results.push(\n toClientResult(client.name, {\n success: false,\n reason: err instanceof Error ? err.message : String(err),\n }),\n );\n }\n }\n return results;\n};\n"],"mappings":";;;;;;;;;;;;;;;;AAQA,IAAsB,YAAtB,MAAgC;CAC9B;;AAaF,IAAsB,mBAAtB,cAA+C,UAAU;CACvD,OAAO;CAEP,cAAc;AACZ,SAAO;;CAGT,wBAAgC;AAC9B,SAAO;;CAGT,gBACE,QACA,kBACA,OACiB;AACjB,SAAO,uBAAuB,QAAQ,kBAAkB,MAAM;;CAGhE,MAAM,kBAAkB,OAAmC;AACzD,MAAI;GACF,MAAM,aAAa,MAAM,KAAK,eAAe;AAE7C,OAAI,CAACA,KAAG,WAAW,WAAW,CAC5B,QAAO;GAGT,MAAM,gBAAgB,MAAMA,KAAG,SAAS,SAAS,YAAY,OAAO;GACpE,MAAM,SAAS,MAAM,MAAM,cAAc;GACzC,MAAM,qBAAqB,KAAK,uBAAuB;GACvD,MAAM,aAAa,QAAQ,kBAAkB;AAE7C,UACE,sBAAsB,UAAU,cAAc,OAAO;UAEjD;AACN,UAAO;;;CAIX,MAAM,UACJ,QACA,kBACA,OACwB;AACxB,MAAI;GACF,MAAM,aAAa,MAAM,KAAK,eAAe;GAC7C,MAAM,YAAYC,OAAK,QAAQ,WAAW;AAE1C,SAAMD,KAAG,SAAS,MAAM,WAAW,EAAE,WAAW,MAAM,CAAC;GAEvD,MAAM,qBAAqB,KAAK,uBAAuB;GACvD,IAAI,gBAAgB;GACpB,IAAI,iBAAiB,EAAE;AAEvB,OAAIA,KAAG,WAAW,WAAW,EAAE;AAC7B,oBAAgB,MAAMA,KAAG,SAAS,SAAS,YAAY,OAAO;AAC9D,qBAAiB,MAAM,MAAM,cAAc,IAAI,EAAE;;GAGnD,MAAM,kBAAkB,KAAK,gBAC3B,QACA,kBACA,MACD;GACD,MAAM,cAAc;AACpB,OAAI,CAAC,YAAY,oBACf,aAAY,sBAAsB,EAAE;GAEtC,MAAM,aAAa,QAAQ,kBAAkB;GAM7C,MAAM,uBAAuB,YAAY,oBAAoB;AAC7D,OACE,yBAAyB,KAAA,KACzB,KAAK,UAAU,qBAAqB,KAAK,KAAK,UAAU,gBAAgB,CAExE,QAAO;IAAE,SAAS;IAAM,kBAAkB;IAAM;AAGlD,eAAY,oBAAoB,cAAc;GAE9C,MAAM,QAAQ,MAAM,OAClB,eACA,CAAC,oBAAoB,WAAW,EAChC,iBACA,EACE,mBAAmB;IACjB,SAAS;IACT,cAAc;IACf,EACF,CACF;GAED,MAAM,kBAAkB,MAAM,WAAW,eAAe,MAAM;AAE9D,SAAMA,KAAG,SAAS,UAAU,YAAY,iBAAiB,OAAO;AAEhE,UAAO,EAAE,SAAS,MAAM;WACjB,OAAO;AACd,UAAO;IACL,SAAS;IACT,QAAQ,iBAAiB,QAAQ,MAAM,UAAU,OAAO,MAAM;IAC/D;;;CAIL,MAAM,aAAa,OAAyC;EAC1D,IAAI,aAAa;AACjB,MAAI;AACF,gBAAa,MAAM,KAAK,eAAe;AAEvC,OAAI,CAACA,KAAG,WAAW,WAAW,CAC5B,QAAO;IAAE,SAAS;IAAM,kBAAkB;IAAM;GAGlD,MAAM,gBAAgB,MAAMA,KAAG,SAAS,SAAS,YAAY,OAAO;GACpE,MAAM,SAAS,MAAM,MAAM,cAAc;GACzC,MAAM,qBAAqB,KAAK,uBAAuB;GAEvD,MAAM,aAAa,QAAQ,kBAAkB;AAE7C,OACE,sBAAsB,UACtB,cAAc,OAAO,qBACrB;IACA,MAAM,QAAQ,MAAM,OAClB,eACA,CAAC,oBAAoB,WAAW,EAChC,KAAA,GACA,EACE,mBAAmB;KACjB,SAAS;KACT,cAAc;KACf,EACF,CACF;IAED,MAAM,kBAAkB,MAAM,WAAW,eAAe,MAAM;AAE9D,UAAMA,KAAG,SAAS,UAAU,YAAY,iBAAiB,OAAO;AAEhE,WAAO,EAAE,SAAS,MAAM;;AAI1B,UAAO;IAAE,SAAS;IAAM,kBAAkB;IAAM;WACzC,OAAO;AACd,UAAO;IACL,SAAS;IACT,QAAQ,GAAG,WAAW,IACpB,iBAAiB,QAAQ,MAAM,UAAU,OAAO,MAAM;IAEzD;;;;;;AClKP,IAAa,kBAAb,cAAqC,iBAAiB;CACpD,OAAO;CAEP,cAAc;AACZ,SAAO;;CAGT,MAAM,oBAAsC;AAC1C,SAAO,QAAQ,QACb,QAAQ,aAAa,YAAY,QAAQ,aAAa,QACvD;;CAGH,MAAM,gBAAiC;AACrC,SAAO,QAAQ,QAAQE,OAAK,KAAKC,KAAG,SAAS,EAAE,WAAW,WAAW,CAAC;;CAGxE,gBACE,QACA,kBACA,OACiB;AACjB,SAAO,0BAA0B,QAAQ,kBAAkB,MAAM;;;;;ACZrE,IAAa,sBAAb,cACU,iBAEV;CACE,OAAO;CACP,mBAA0C;CAE1C,cAAc;AACZ,SAAO;;CAGT,mBAA0C;AACxC,MAAI,KAAK,iBACP,QAAO,KAAK;EAId,MAAM,gBAAgB;GACpBC,OAAK,KAAKC,KAAG,SAAS,EAAE,WAAW,SAAS,SAAS;GACrD;GACA;GACD;AAED,OAAK,MAAM,cAAc,cACvB,KAAIC,KAAG,WAAW,WAAW,EAAE;AAC7B,SAAM,6BAA6B,aAAa;AAChD,QAAK,mBAAmB;AACxB,UAAO;;AAKX,MAAI;AACF,cAAS,qBAAqB,EAAE,OAAO,QAAQ,CAAC;AAChD,SAAM,yBAAyB;AAC/B,QAAK,mBAAmB;AACxB,UAAO;UACD;AAIR,SAAO;;CAGT,oBAAsC;AACpC,MAAI;AACF,SAAM,gCAAgC;GACtC,MAAM,eAAe,KAAK,kBAAkB;AAE5C,OAAI,CAAC,cAAc;AACjB,UAAM,uDAAuD;AAC7D,UAAM,SAASF,OAAK,KAAKC,KAAG,SAAS,EAAE,WAAW,SAAS,SAAS,GAAG;AACvE,UAAM,8BAA8B;AACpC,UAAM,iCAAiC;AACvC,UAAM,aAAa;AACnB,WAAO,QAAQ,QAAQ,MAAM;;AAK/B,SAAM,2BAFSE,WAAS,GAAG,aAAa,aAAa,EAAE,OAAO,QAAQ,CAAC,CAChD,UAAU,CAAC,MAAM,GACG;AAC3C,UAAO,QAAQ,QAAQ,KAAK;WACrB,OAAO;AACd,SACE,+BACE,iBAAiB,QAAQ,MAAM,UAAU,OAAO,MAAM,GAEzD;AACD,UAAO,QAAQ,QAAQ,MAAM;;;CAIjC,kBAAkB,OAAmC;EACnD,MAAM,SAAS,KAAK,kBAAkB;AACtC,MAAI,CAAC,OAAQ,QAAO,QAAQ,QAAQ,MAAM;EAC1C,MAAM,aAAa,QAAQ,kBAAkB;AAI7C,MAAI;AACF,cAAS,GAAG,OAAO,WAAW,cAAc,EAAE,OAAO,QAAQ,CAAC;AAC9D,UAAO,QAAQ,QAAQ,KAAK;UACtB;AACN,UAAO,QAAQ,QAAQ,MAAM;;;CAIjC,gBAAiC;AAC/B,QAAM,IAAI,MAAM,kBAAkB;;CAGpC,UACE,QACA,kBACA,OACwB;EACxB,MAAM,SAAS,KAAK,kBAAkB;AACtC,MAAI,CAAC,OACH,QAAO,QAAQ,QAAQ;GACrB,SAAS;GACT,QAAQ;GACT,CAAC;EAIJ,MAAM,OAAO;GACX;GACA;GACA;GACA;GACA;GACA;GARiB,QAAQ,kBAAkB;GACjC,YAAY,kBAAkB,MAAM;GAU/C;AACD,MAAI,OACF,MAAK,KAAK,YAAY,yBAAyB,SAAS;AAG1D,MAAI;AACF,cAAS,GAAG,OAAO,GAAG,KAAK,KAAK,MAAM,KAAK,UAAU,EAAE,CAAC,CAAC,KAAK,IAAI,IAAI,EACpE,OAAO,QACR,CAAC;AACF,UAAO,QAAQ,QAAQ,EAAE,SAAS,MAAM,CAAC;WAClC,OAAO;GAGd,MAAM,MAAM,cACV,iBAAiB,QAAQ,MAAM,UAAU,OAAO,MAAM,CACvD;AACD,OAAI,IAAI,SAAS,iBAAiB,CAChC,QAAO,QAAQ,QAAQ;IAAE,SAAS;IAAM,kBAAkB;IAAM,CAAC;AAEnE,aAAU,iCACR,IAAI,MAAM,+BAA+B,MAAM,CAChD;AACD,UAAO,QAAQ,QAAQ;IAAE,SAAS;IAAO,QAAQ;IAAK,CAAC;;;;CAK3D,aAAa,OAAyB;AACpC,SAAO,oBAAoB,QAAQ,kBAAkB;;;CAIvD,qBAA6B;AAC3B,SAAO;;CAGT,MAAM,eAA6C;EACjD,MAAM,SAAS,KAAK,kBAAkB;AACtC,MAAI,CAAC,OACH,QAAO;GACL,SAAS;GACT,QAAQ;GACT;AAEH,MAAI,CAAE,MAAM,KAAK,mBAAmB,CAClC,QAAO;GAAE,SAAS;GAAM,kBAAkB;GAAM;AAGlD,MAAI;AACF,cAAS,GAAG,OAAO,4BAA4B,EAAE,OAAO,QAAQ,CAAC;AACjE,UAAO,EAAE,SAAS,MAAM;WACjB,OAAO;GACd,MAAM,MAAM,iBAAiB,QAAQ,MAAM,UAAU,OAAO,MAAM;AAClE,aAAU,iCACR,IAAI,MAAM,wCAAwC,MAAM,CACzD;AACD,UAAO;IAAE,SAAS;IAAO,QAAQ;IAAK;;;CAI1C,aAAa,OAAyC;EACpD,MAAM,eAAe,KAAK,kBAAkB;AAC5C,MAAI,CAAC,aACH,QAAO,QAAQ,QAAQ;GACrB,SAAS;GACT,QAAQ;GACT,CAAC;EAIJ,MAAM,UAAU,GAAG,aAAa,2BADb,QAAQ,kBAAkB;AAG7C,MAAI;AACF,cAAS,SAAS,EAAE,OAAO,QAAQ,CAAC;WAC7B,OAAO;GACd,MAAM,SAAS,cACb,iBAAiB,QAAQ,MAAM,UAAU,OAAO,MAAM,CACvD;AAGD,OAAI,mCAAmC,KAAK,OAAO,CACjD,QAAO,QAAQ,QAAQ;IAAE,SAAS;IAAM,kBAAkB;IAAM,CAAC;AAEnE,aAAU,iCACR,IAAI,MAAM,6CAA6C,SAAS,CACjE;AACD,UAAO,QAAQ,QAAQ;IAAE,SAAS;IAAO;IAAQ,CAAC;;AAGpD,SAAO,QAAQ,QAAQ,EAAE,SAAS,MAAM,CAAC;;;CAI3C,yBAAkC;AAChC,SAAO;;CAGT,iBAA0B;AACxB,SAAO,KAAK,kBAAkB,KAAK;;CAGrC,oBAAsC;EACpC,MAAM,SAAS,KAAK,kBAAkB;AACtC,MAAI,CAAC,OAAQ,QAAO,QAAQ,QAAQ,MAAM;AAC1C,MAAI;GACF,MAAM,SAASA,WAAS,GAAG,OAAO,eAAe,EAC/C,OAAO,QACR,CAAC,CAAC,UAAU;AACb,UAAO,QAAQ,QAAQ,OAAO,aAAa,CAAC,SAAS,UAAU,CAAC;UAC1D;AACN,UAAO,QAAQ,QAAQ,MAAM;;;CAIjC,MAAM,gBAA8C;EAClD,MAAM,SAAS,KAAK,kBAAkB;AACtC,MAAI,CAAC,OACH,QAAO;GACL,SAAS;GACT,QAAQ;GACT;AAIH,MAAI,MAAM,KAAK,mBAAmB,CAChC,QAAO;GAAE,SAAS;GAAM,kBAAkB;GAAM;AAGlD,MAAI;AACF,cAAS,GAAG,OAAO,0BAA0B,EAAE,OAAO,QAAQ,CAAC;AAC/D,UAAO,EAAE,SAAS,MAAM;WACjB,OAAO;GACd,MAAM,MAAM,iBAAiB,QAAQ,MAAM,UAAU,OAAO,MAAM;AAClE,OAAI,IAAI,SAAS,oBAAoB,IAAI,IAAI,SAAS,iBAAiB,CACrE,QAAO;IAAE,SAAS;IAAM,kBAAkB;IAAM;AAElD,aAAU,iCACR,IAAI,MAAM,sCAAsC,MAAM,CACvD;AACD,UAAO;IAAE,SAAS;IAAO,QAAQ;IAAK;;;;;;;;;;;AC7Q5C,IAAa,qBAAb,cAAwC,UAAuC;CAC7E,OAAO;CACP,eAAe;CACf,oBAAoB;CAEpB,oBAAsC;AAEpC,SAAO,QAAQ,QAAQ,KAAK;;CAG9B,oBAAsC;AAGpC,SAAO,QAAQ,QAAQ,MAAM;;CAG/B,YAAoC;AAElC,kBAAgB,KAAK,cAAc,wBAAwB;GACzD,MAAM;GACN,SAAS;GACV,CAAC;AACF,SAAO,QAAQ,QAAQ,EAAE,SAAS,MAAM,CAAC;;CAG3C,eAAuC;AAIrC,SAAO,QAAQ,QAAQ;GACrB,SAAS;GACT,QACE;GACH,CAAC;;CAGJ,gBAAiC;AAC/B,QAAM,IAAI,MAAM,kBAAkB;;CAGpC,wBAAgC;AAC9B,QAAM,IAAI,MAAM,kBAAkB;;;ACzCGC,IACtC,OAAO,EACN,SAASA,IAAE,OACTA,IAAE,QAAQ,EACVA,IAAE,MAAM,CACNA,IAAE,OAAO;CACP,SAASA,IAAE,QAAQ,CAAC,UAAU;CAC9B,MAAMA,IAAE,MAAMA,IAAE,QAAQ,CAAC,CAAC,UAAU;CACpC,KAAKA,IAAE,OAAOA,IAAE,QAAQ,EAAEA,IAAE,QAAQ,CAAC,CAAC,UAAU;CACjD,CAAC,EACFA,IAAE,OAAO;CACP,MAAMA,IAAE,KAAK,CAAC,QAAQ,MAAM,CAAC;CAC7B,KAAKA,IAAE,QAAQ;CACf,SAASA,IAAE,OAAOA,IAAE,QAAQ,EAAEA,IAAE,QAAQ,CAAC,CAAC,UAAU;CACrD,CAAC,CACH,CAAC,CACH,EACF,CAAC,CACD,aAAa;AAMhB,IAAa,yBAAb,cAA4C,iBAAiB;CAC3D,OAAO;CAEP,wBAAgC;AAC9B,SAAO;;CAGT,MAAM,oBAAsC;AAC1C,SAAO,QAAQ,QACb,QAAQ,aAAa,YACnB,QAAQ,aAAa,WACrB,QAAQ,aAAa,QACxB;;CAGH,MAAM,gBAAiC;EACrC,MAAM,UAAUC,KAAG,SAAS;EAC5B,MAAM,YAAY,QAAQ,aAAa;EACvC,MAAM,QAAQ,QAAQ,aAAa;EACnC,MAAM,UAAU,QAAQ,aAAa;AAErC,MAAI,MACF,QAAO,QAAQ,QACbC,OAAK,KACH,SACA,WACA,uBACA,QACA,QACA,WACD,CACF;AAGH,MAAI,UACF,QAAO,QAAQ,QACbA,OAAK,KAAK,WAAW,UAAU,IAAI,IAAI,QAAQ,QAAQ,WAAW,CACnE;AAGH,MAAI,QACF,QAAO,QAAQ,QACbA,OAAK,KAAK,SAAS,WAAW,QAAQ,QAAQ,WAAW,CAC1D;AAGH,QAAM,IAAI,MAAM,yBAAyB,QAAQ,WAAW;;CAG9D,gBACE,QACA,kBACA,OACiB;AACjB,SAAO;GACL,MAAM;GACN,GAAG,0BAA0B,QAAQ,kBAAkB,MAAM;GAC9D;;;ACjFuBC,IACzB,OAAO,EACN,iBAAiBA,IAAE,OACjBA,IAAE,QAAQ,EACVA,IAAE,MAAM,CACNA,IAAE,OAAO;CACP,SAASA,IAAE,SAAS,CAAC,UAAU;CAC/B,QAAQA,IAAE,QAAQ,CAAC,UAAU;CAC7B,SAASA,IAAE,QAAQ,CAAC,UAAU;CAC9B,MAAMA,IAAE,MAAMA,IAAE,QAAQ,CAAC,CAAC,UAAU;CACpC,KAAKA,IAAE,OAAOA,IAAE,QAAQ,EAAEA,IAAE,QAAQ,CAAC,CAAC,UAAU;CACjD,CAAC,EACFA,IAAE,OAAO;CACP,SAASA,IAAE,SAAS,CAAC,UAAU;CAC/B,KAAKA,IAAE,QAAQ;CACf,SAASA,IAAE,OAAOA,IAAE,QAAQ,EAAEA,IAAE,QAAQ,CAAC,CAAC,UAAU;CACrD,CAAC,CACH,CAAC,CACH,EACF,CAAC,CACD,aAAa;AAIhB,IAAa,YAAb,cAA+B,iBAAiB;CAC9C,OAAO;CAEP,wBAAgC;AAC9B,SAAO;;CAGT,MAAM,oBAAsC;AAC1C,SAAO,QAAQ,QACb,QAAQ,aAAa,YAAY,QAAQ,aAAa,QACvD;;CAGH,MAAM,gBAAiC;EACrC,MAAM,UAAUC,KAAG,SAAS;EAC5B,MAAM,QAAQ,QAAQ,aAAa;EACnC,MAAM,UAAU,QAAQ,aAAa;AAErC,MAAI,MACF,QAAO,QAAQ,QACbC,OAAK,KAAK,SAAS,WAAW,OAAO,gBAAgB,CACtD;AAGH,MAAI,SAAS;GAEX,MAAM,gBAAgB,WAAW,kBAAkB;AACnD,OAAI,cACF,QAAO,QAAQ,QACbA,OAAK,KAAK,eAAe,OAAO,gBAAgB,CACjD;AAEH,UAAO,QAAQ,QACbA,OAAK,KAAK,SAAS,WAAW,OAAO,gBAAgB,CACtD;;AAGH,QAAM,IAAI,MAAM,yBAAyB,QAAQ,WAAW;;CAG9D,gBACE,QACA,kBACA,OACiB;AACjB,SAAO;GACL,SAAS;GACT,GAAG,0BAA0B,QAAQ,kBAAkB,MAAM;GAC9D;;;;;;AC1DL,MAAM,4BACJ;;AAEF,MAAM,0BAA0B;;;;;;AAOhC,MAAM,sBAAsB;;;;;;;AAQ5B,MAAM,iBAAiB,eACrB,IAAI,OACF,wBAAwB,WAAW,IAAI,WAAW,gBAClD,IACD;;;;;;AAOH,MAAM,UAAU,MAAc,KAAa,UAA0B;CACnE,MAAM,WAAW,IAAI,OAAO,WAAW,IAAI,cAAc,IAAI;AAC7D,QAAO,SAAS,KAAK,KAAK,GACtB,KAAK,QAAQ,UAAU,GAAG,IAAI,KAAK,QAAQ,GAC3C,KAAK,IAAI,KAAK,QAAQ;;AAO5B,IAAa,iBAAb,cACU,iBAEV;CACE,OAAO;CACP,kBAAyC;CAEzC,cAAc;AACZ,SAAO;;CAGT,kBAAyC;AACvC,MAAI,KAAK,gBAAiB,QAAO,KAAK;AACtC,MAAI;GACF,MAAM,WAAW,SAAS,oBAAoB,EAAE,OAAO,QAAQ,CAAC,CAC7D,UAAU,CACV,MAAM;AACT,OAAI,UAAU;AACZ,SAAK,kBAAkB;AACvB,WAAO;;UAEH;AAGR,SAAO;;CAGT,aAA6B;AAC3B,SAAOC,OAAK,KAAK,GAAG,SAAS,EAAE,UAAU,cAAc;;CAGzD,oBAAsC;AACpC,SAAO,QAAQ,QAAQ,KAAK,iBAAiB,KAAK,KAAK;;CAGzD,gBAAiC;AAC/B,QAAM,IAAI,MAAM,kBAAkB;;CAGpC,kBAAkB,OAAmC;EACnD,MAAM,aAAa,QAAQ,kBAAkB;AAI7C,MAAI;GACF,MAAM,WAAWC,KAAG,aAAa,KAAK,YAAY,EAAE,QAAQ;AAC5D,UAAO,QAAQ,QAAQ,cAAc,WAAW,CAAC,KAAK,SAAS,CAAC;UAC1D;AACN,UAAO,QAAQ,QAAQ,MAAM;;;CAIjC,UACE,QACA,kBACA,OACwB;EACxB,MAAM,aAAa,QAAQ,kBAAkB;EAC7C,MAAM,MAAM,YAAY,kBAAkB,MAAM;AAGhD,MAAI,QAAQ;GACV,MAAM,SAAS,KAAK,iBAAiB;AACrC,OAAI,CAAC,OACH,QAAO,QAAQ,QAAQ;IACrB,SAAS;IACT,QAAQ;IACT,CAAC;GAWJ,MAAM,SAAS,UAAU,QAVZ;IACX;IACA;IACA;IACA;IACA;IACA;IACA;IACD,EAEsC;IAAE,UAAU;IAAS,KADhD;KAAE,GAAG,QAAQ;KAAK,qBAAqB,UAAU;KAAU;IACN,CAAC;AAClE,OAAI,OAAO,WAAW,GAAG;IACvB,MAAM,SAAS,OAAO,UAAU;AAChC,QAAI,0BAA0B,KAAK,OAAO,CACxC,QAAO,QAAQ,QAAQ;KAAE,SAAS;KAAM,kBAAkB;KAAM,CAAC;IAEnE,MAAM,SAAS,cAAc,OAAO;AACpC,cAAU,iCACR,IAAI,MAAM,yBAAyB,SAAS,CAC7C;AACD,WAAO,QAAQ,QAAQ;KAAE,SAAS;KAAO;KAAQ,CAAC;;AAEpD,UAAO,QAAQ,QAAQ,EAAE,SAAS,MAAM,CAAC;;AAO3C,SAAO,QAAQ,QAAQ,KAAK,mBAAmB,YAAY,IAAI,CAAC;;;;;;CAOlE,mBAA2B,YAAoB,KAA4B;EACzE,MAAM,aAAa,KAAK,YAAY;AACpC,MAAI;AAGF,QAAG,UAAUD,OAAK,QAAQ,WAAW,EAAE,EAAE,WAAW,MAAM,CAAC;GAC3D,MAAM,WAAWC,KAAG,WAAW,WAAW,GACtCA,KAAG,aAAa,YAAY,QAAQ,GACpC;GAEJ,MAAM,SAAS,cAAc,WAAW,CAAC,KAAK,SAAS;AACvD,OAAI,CAAC,QAAQ;IACX,MAAM,MAAM,aAAa,MAAM,SAAS,SAAS,OAAO,GAAG,KAAK;IAChE,MAAM,MAAM,aAAa,MAAM,SAAS,SAAS,KAAK,GAAG,KAAK;AAC9D,SAAK,MACH,YACA,GAAG,WAAW,MAAM,IAAI,eAAe,WAAW,YACtC,IAAI,2BAA2B,oBAAoB,IAChE;AACD,WAAO,EAAE,SAAS,MAAM;;GAI1B,MAAM,QAAQ,OAAO,QAAQ,OAAO,GAAG;GACvC,MAAM,OAAO,SAAS,MAAM,MAAM;GAClC,MAAM,OAAO,OAAO,KAAK,KAAK;GAC9B,MAAM,MAAM,OAAO,QAAQ,KAAK,QAAQ,SAAS;GAEjD,MAAM,OAAO,SAAS,MAAM,OAAO,IAAI;GACvC,MAAM,UAAU,OACd,OAAO,MAAM,OAAO,IAAI,IAAI,GAAG,EAC/B,uBACA,OAAO,oBAAoB,CAC5B;AACD,OAAI,YAAY,KAAM,QAAO;IAAE,SAAS;IAAM,kBAAkB;IAAM;AAEtE,QAAK,MACH,YACA,SAAS,MAAM,GAAG,MAAM,GAAG,UAAU,SAAS,MAAM,IAAI,CACzD;AACD,UAAO,EAAE,SAAS,MAAM;WACjB,OAAO;GACd,MAAM,SAAS,iBAAiB,QAAQ,MAAM,UAAU,OAAO,MAAM;AACrE,aAAU,iCACR,IAAI,MAAM,mCAAmC,SAAS,CACvD;AACD,UAAO;IAAE,SAAS;IAAO;IAAQ;;;;CAKrC,MAAc,YAAoB,UAAwB;EACxD,MAAM,MAAM,GAAG,WAAW;AAC1B,OAAG,cAAc,KAAK,SAAS;AAC/B,OAAG,WAAW,KAAK,WAAW;;;CAIhC,aAAa,OAAgC;AAC3C,MAAI,CAAC,KAAK,iBAAiB,CAAE,QAAO;AACpC,SAAO,mBAAmB,QAAQ,kBAAkB;;CAGtD,aAAa,OAAyC;EACpD,MAAM,SAAS,KAAK,iBAAiB;AACrC,MAAI,CAAC,OACH,QAAO,QAAQ,QAAQ;GACrB,SAAS;GACT,QAAQ;GACT,CAAC;EAKJ,MAAM,SAAS,UAAU,QAAQ;GAAC;GAAO;GADtB,QAAQ,kBAAkB;GACiB,EAAE,EAC9D,UAAU,SACX,CAAC;AAEF,MAAI,OAAO,SAAS,OAAO,WAAW,GAAG;GACvC,MAAM,SAAS,cACb,OAAO,OAAO,WAAW,OAAO,UAAU,0BAC3C;AACD,aAAU,iCACR,IAAI,MAAM,2CAA2C,SAAS,CAC/D;AACD,UAAO,QAAQ,QAAQ;IAAE,SAAS;IAAO;IAAQ,CAAC;;AAGpD,SAAO,QAAQ,QAAQ,EAAE,SAAS,MAAM,CAAC;;;CAI3C,yBAAkC;AAChC,SAAO;;CAGT,iBAA0B;AACxB,SAAO,KAAK,iBAAiB,KAAK;;CAGpC,oBAAsC;EACpC,MAAM,aAAaD,OAAK,KAAK,GAAG,SAAS,EAAE,UAAU,cAAc;AACnE,MAAI;GACF,MAAM,WAAWC,KAAG,aAAa,YAAY,QAAQ;AAErD,UAAO,QAAQ,QACb,SAAS,aAAa,CAAC,SAAS,yBAAyB,CAC1D;UACK;AACN,UAAO,QAAQ,QAAQ,MAAM;;;CAIjC,MAAM,eAA6C;EACjD,MAAM,SAAS,KAAK,iBAAiB;AACrC,MAAI,CAAC,OACH,QAAO;GACL,SAAS;GACT,QAAQ;GACT;AAEH,MAAI,CAAE,MAAM,KAAK,mBAAmB,CAClC,QAAO;GAAE,SAAS;GAAM,kBAAkB;GAAM;EAGlD,MAAM,SAAS,UACb,QACA;GAAC;GAAU;GAAe;GAAU;GAAU,EAC9C,EAAE,UAAU,SAAS,CACtB;AACD,MAAI,OAAO,WAAW,GAAG;GACvB,MAAM,SAAS,cACb,OAAO,UAAU,yCAClB;AACD,aAAU,iCACR,IAAI,MAAM,kCAAkC,SAAS,CACtD;AACD,UAAO;IAAE,SAAS;IAAO;IAAQ;;AAEnC,SAAO,EAAE,SAAS,MAAM;;CAG1B,MAAM,gBAA8C;EAClD,MAAM,SAAS,KAAK,iBAAiB;AACrC,MAAI,CAAC,OACH,QAAO;GACL,SAAS;GACT,QAAQ;GACT;AAKH,MAAI,MAAM,KAAK,mBAAmB,CAChC,QAAO;GAAE,SAAS;GAAM,kBAAkB;GAAM;EAGlD,MAAM,YACJ,UAAU,QAAQ;GAAC;GAAU;GAAe;GAAO;GAAoB,EAAE,EACvE,UAAU,SACX,CAAC;EAEJ,IAAI,SAAS,KAAK;AAGlB,MACE,OAAO,WAAW,KAClB,wBAAwB,KAAK,OAAO,UAAU,GAAG,EACjD;GACA,MAAM,WAAWD,OAAK,KACpB,GAAG,SAAS,EACZ,UACA,QACA,gBACA,UACD;AACD,OAAI;AACF,SAAG,OAAO,UAAU;KAAE,WAAW;KAAM,OAAO;KAAM,CAAC;WAC/C;AAGR,YAAS,KAAK;;AAGhB,MAAI,OAAO,WAAW,GAAG;GACvB,MAAM,SAAS,OAAO,UAAU;AAMhC,OACE,0BAA0B,KAAK,OAAO,IACtC,CAAC,wBAAwB,KAAK,OAAO,CAErC,QAAO;IAAE,SAAS;IAAM,kBAAkB;IAAM;GAElD,MAAM,SAAS,cAAc,OAAO;AACpC,aAAU,iCACR,IAAI,MAAM,gCAAgC,SAAS,CACpD;AACD,UAAO;IAAE,SAAS;IAAO;IAAQ;;AAGnC,SAAO,EAAE,SAAS,MAAM;;;ACxWKE,IAC9B,OAAO,EACN,KAAKA,IAAE,OACLA,IAAE,QAAQ,EACVA,IAAE,OAAO;CACP,MAAMA,IAAE,QAAQ,SAAS;CACzB,KAAKA,IAAE,QAAQ;CACf,SAASA,IAAE,OAAOA,IAAE,QAAQ,EAAEA,IAAE,QAAQ,CAAC,CAAC,UAAU;CACrD,CAAC,CACH,EACF,CAAC,CACD,aAAa;AAIhB,IAAa,oBAAb,cAAuC,iBAAiB;CACtD,OAAO;CACP,qBAA4C;CAE5C,wBAAyC;AACvC,SAAO;;CAGT,qBAA4C;AAC1C,MAAI,KAAK,mBAAoB,QAAO,KAAK;AACzC,MAAI;GACF,MAAM,WAAW,SAAS,uBAAuB,EAAE,OAAO,QAAQ,CAAC,CAChE,UAAU,CACV,MAAM;AACT,OAAI,UAAU;AACZ,SAAK,qBAAqB;AAC1B,WAAO;;UAEH;AAGR,SAAO;;CAGT,oBAAsC;AACpC,SAAO,QAAQ,QAAQ,KAAK,oBAAoB,KAAK,KAAK;;CAG5D,gBAAiC;EAC/B,MAAM,YAAY,KAAK,kBAAkB;EACzC,MAAM,YAAYC,OAAK,KAAK,WAAW,iBAAiB;EACxD,MAAM,WAAWA,OAAK,KAAK,WAAW,gBAAgB;AACtD,MAAIC,KAAG,WAAW,UAAU,CAAE,QAAO,QAAQ,QAAQ,UAAU;AAC/D,SAAO,QAAQ,QAAQ,SAAS;;CAGlC,mBAAmC;EACjC,MAAM,SAAS,WAAW,sBAAsB;AAChD,MAAI,OAAQ,QAAO;EAEnB,MAAM,UAAU,WAAW,kBAAkB;AAC7C,MAAI,QAAS,QAAOD,OAAK,KAAK,SAAS,WAAW;AAElD,SAAOA,OAAK,KAAKE,KAAG,SAAS,EAAE,WAAW,WAAW;;CAGvD,gBACE,QACA,kBACA,OACiB;AACjB,SAAO;GACL,MAAM;GACN,GAAG,0BAA0B,QAAQ,kBAAkB,MAAM;GAC9D;;;;;ACnEL,SAAgB,gBAAmB,QAAwC;AACzE,QACE,OAAO,WAAW,YAClB,WAAW,QACX,oBAAoB,UACpB,mBAAmB;;;;;;;;;;;;;;ACIvB,MAAa,sBAAsB,YAAkC;CACnE,MAAM,aAAa;EACjB,IAAI,qBAAqB;EACzB,IAAI,oBAAoB;EACxB,IAAI,gBAAgB;EACpB,IAAI,iBAAiB;EACrB,IAAI,wBAAwB;EAC5B,IAAI,WAAW;EACf,IAAI,mBAAmB;EACxB;CACD,MAAM,mBAAgC,EAAE;AAExC,OAAM,wCAAwC;AAC9C,MAAK,MAAM,UAAU,YAAY;EAC/B,MAAM,cAAc,MAAM,OAAO,mBAAmB;AACpD,QAAM,GAAG,OAAO,KAAK,IAAI,cAAc,gBAAgB,oBAAoB;AAC3E,MAAI,YACF,kBAAiB,KAAK,OAAO;;AAGjC,OACE,SAAS,iBAAiB,OAAO,wBAAwB,iBACtD,KAAK,MAAM,EAAE,KAAK,CAClB,KAAK,KAAK,GACd;AAED,QAAO;;;;;;AAcT,MAAa,4BAA4B,OAAO,EAC9C,aACA,QAAQ,OACR,KAAK,OACL,aAAa,cACb,UACA,aAQ6B;CAC7B,MAAM,KAAK,OAAO;AAGlB,KAAI,IAAI;AACN,KAAG,IAAI,KAAK,sCAAsC;AAClD,SAAO;GAAE,WAAW,EAAE;GAAE,QAAQ,EAAE;GAAE;;CAGtC,MAAM,mBAAmB,MAAM,qBAAqB;AAEpD,KAAI,iBAAiB,WAAW,GAAG;AACjC,KAAG,IAAI,KACL,gEACD;AACD,SAAO;GAAE,WAAW,EAAE;GAAE,QAAQ,EAAE;GAAE;;CAItC,MAAM,UAAU,MAAM,aAAa,4BACjC,aACE,kBACA,QACA,YAAY,CAAC,GAAG,mBAAmB,EACnC,MACD,CACF;CAED,MAAM,YAAY,gBAAgB,SAAA,UAAiC;CACnE,MAAM,UAAU,gBAAgB,SAAA,YAAmC;CACnE,MAAM,SAAS,QAAQ,QAAQ,MAAM,EAAE,WAAA,SAAkC;AAIzE,KAAI,UAAU,SAAS,EACrB,IAAG,IAAI,QAAQ,6BAA6B,WAAW,UAAU,GAAG;AAEtE,KAAI,QAAQ,SAAS,EACnB,IAAG,IAAI,KACL,0EAA0E,WACxE,QACD,GACF;AAEH,KAAI,OAAO,SAAS,EAClB,IAAG,IAAI,KACL,oCAAoC,WAClC,OAAO,KAAK,MAAO,EAAE,SAAS,GAAG,EAAE,KAAK,KAAK,EAAE,WAAW,EAAE,KAAM,CACnE,GACF;CAGH,MAAM,aAAa,CAAC,GAAG,WAAW,GAAG,QAAQ;AAE7C,WAAU,cAAc,qBAAqB;EAG3C,SAAS;EACT,2BAA2B;EAC3B,gBAAgB,OAAO,KAAK,MAAM,EAAE,KAAK;EACzC,mBAAmB,iBAAiB,KAAK,MAAM,EAAE,KAAK;EACtD;EACD,CAAC;AAEF,QAAO;EAAE,WAAW;EAAY,QAAQ,OAAO,KAAK,MAAM,EAAE,KAAK;EAAE;;AAGrE,MAAM,cAAc,UAClB,MAAM,KAAK,SAAS,OAAO,OAAO,CAAC,KAAK,KAAK;AAE/C,MAAa,iCAAiC,OAAO,EACnD,aACA,QAAQ,YAIe;CACvB,MAAM,KAAK,OAAO;CAClB,MAAM,mBAAmB,MAAM,oBAAoB,MAAM;AACzD,KAAI,iBAAiB,WAAW,GAAG;AACjC,KAAG,IAAI,KACL,uFACD;AACD,YAAU,cAAc,4BAA4B,EAClD,aACD,CAAC;AACF,SAAO,EAAE;;CAIX,MAAM,UAAU,MAAM,aAAa,8BACjC,gBAAgB,kBAAkB,MAAM,CACzC;CAED,MAAM,UAAU,gBAAgB,SAAA,UAAiC;CACjE,MAAM,cAAc,gBAAgB,SAAA,YAAmC;CACvE,MAAM,SAAS,QAAQ,QAAQ,MAAM,EAAE,WAAA,SAAkC;AAIzE,KAAI,QAAQ,SAAS,EACnB,IAAG,IAAI,QAAQ,iCAAiC,WAAW,QAAQ,GAAG;AAExE,KAAI,YAAY,SAAS,EACvB,IAAG,IAAI,KACL,6CAA6C,WAAW,YAAY,GACrE;AAEH,KAAI,OAAO,SAAS,EAClB,IAAG,IAAI,KACL,yCAAyC,WACvC,OAAO,KAAK,MAAO,EAAE,SAAS,GAAG,EAAE,KAAK,KAAK,EAAE,WAAW,EAAE,KAAM,CACnE,GACF;AAGH,WAAU,cAAc,uBAAuB;EAC7C,SAAS;EACT,2BAA2B;EAC3B,gBAAgB,OAAO,KAAK,MAAM,EAAE,KAAK;EACzC,mBAAmB,iBAAiB,KAAK,MAAM,EAAE,KAAK;EACtD;EACD,CAAC;AAEF,QAAO;;AAGT,MAAa,sBAAsB,OACjC,UACyB;CACzB,MAAM,UAAU,MAAM,qBAAqB;CAC3C,MAAM,mBAAgC,EAAE;AAExC,MAAK,MAAM,UAAU,SAAS;EAI5B,MAAM,kBACJ,CAAC,SAAS,gBAAgB,OAAO,IAAK,MAAM,OAAO,mBAAmB;AACxE,MAAK,MAAM,OAAO,kBAAkB,MAAM,IAAK,gBAC7C,kBAAiB,KAAK,OAAO;;AAIjC,QAAO;;AAGT,MAAa,eAAe,OAC1B,SACA,gBACA,kBACA,UAC+B;CAC/B,MAAM,UAA6B,EAAE;AACrC,MAAK,MAAM,UAAU,QACnB,KAAI;EACF,MAAM,SAAS,MAAM,OAAO,UAC1B,gBACA,kBACA,MACD;AACD,UAAQ,KAAK,eAAe,OAAO,MAAM,OAAO,CAAC;UAC1C,KAAK;AACZ,QAAM,sCAAsC,OAAO,KAAK,IAAI,MAAM;AAClE,UAAQ,KACN,eAAe,OAAO,MAAM;GAC1B,SAAS;GACT,QAAQ,eAAe,QAAQ,IAAI,UAAU,OAAO,IAAI;GACzD,CAAC,CACH;;AAGL,QAAO;;AAGT,MAAa,6BACX,YACqC;AACrC,QAAO,QAAQ,OAAO,gBAAgB,CAAC,QAAQ,MAAM,EAAE,gBAAgB,CAAC;;AAG1E,MAAa,iBAAiB,OAC5B,YAC+B;CAC/B,MAAM,UAA6B,EAAE;AACrC,MAAK,MAAM,UAAU,QACnB,KAAI;AACF,UAAQ,KAAK,eAAe,OAAO,MAAM,MAAM,OAAO,eAAe,CAAC,CAAC;UAChE,KAAK;AACZ,QAAM,4CAA4C,OAAO,KAAK,IAAI,MAAM;AACxE,UAAQ,KACN,eAAe,OAAO,MAAM;GAC1B,SAAS;GACT,QAAQ,eAAe,QAAQ,IAAI,UAAU,OAAO,IAAI;GACzD,CAAC,CACH;;AAGL,QAAO;;AAGT,MAAa,kBAAkB,OAC7B,SACA,UAC+B;CAC/B,MAAM,UAA6B,EAAE;AACrC,MAAK,MAAM,UAAU,QACnB,KAAI;EACF,IAAI,SAAS,MAAM,OAAO,aAAa,MAAM;AAG7C,MAAI,CAAC,SAAS,gBAAgB,OAAO,IAAI,OAAO,cAAc;GAC5D,MAAM,SAAS,MAAM,OAAO,cAAc;AAC1C,YACE,CAAC,OAAO,WAAW,CAAC,OAAO,UACvB;IACE,SAAS;IACT,QAAQ,CAAC,OAAO,QAAQ,OAAO,OAAO,CACnC,OAAO,QAAQ,CACf,KAAK,KAAK;IACd,GACD;IACE,SAAS;IACT,GAAI,OAAO,oBAAoB,OAAO,mBAClC,EAAE,kBAAkB,MAAM,GAC1B,EAAE;IACP;;AAET,UAAQ,KAAK,eAAe,OAAO,MAAM,OAAO,CAAC;UAC1C,KAAK;AACZ,QAAM,4CAA4C,OAAO,KAAK,IAAI,MAAM;AACxE,UAAQ,KACN,eAAe,OAAO,MAAM;GAC1B,SAAS;GACT,QAAQ,eAAe,QAAQ,IAAI,UAAU,OAAO,IAAI;GACzD,CAAC,CACH;;AAGL,QAAO"}
|
|
1
|
+
{"version":3,"file":"add-mcp-server-to-clients-D47ONFCD.js","names":["fs","path","path","os","path","os","fs","execSync","z","os","path","z","os","path","path","fs","z","path","fs","os"],"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/clients/opencode.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';\nimport type { InstallResult } from './results';\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<InstallResult>;\n abstract removeServer(local?: boolean): Promise<InstallResult>;\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<InstallResult> {\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\n // An identical entry means this config is already set up — leave the file\n // untouched and report it, so a re-run says \"already installed\" instead of\n // claiming a write that changed nothing. A differing entry (new features,\n // new key) still gets overwritten and reported as installed.\n const existingServerConfig = typedConfig[serverPropertyName][serverName];\n if (\n existingServerConfig !== undefined &&\n JSON.stringify(existingServerConfig) === JSON.stringify(newServerConfig)\n ) {\n return { success: true, alreadyInstalled: true };\n }\n\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 (error) {\n return {\n success: false,\n reason: error instanceof Error ? error.message : String(error),\n };\n }\n }\n\n async removeServer(local?: boolean): Promise<InstallResult> {\n let configPath = '';\n try {\n configPath = await this.getConfigPath();\n\n if (!fs.existsSync(configPath)) {\n return { success: true, alreadyInstalled: true };\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 // No PostHog entry to delete — the config changed under us between the\n // detection pass and now. Nothing failed, so don't report a failure.\n return { success: true, alreadyInstalled: true };\n } catch (error) {\n return {\n success: false,\n reason: `${configPath}: ${\n error instanceof Error ? error.message : String(error)\n }`,\n };\n }\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 {\n redactSecrets,\n type InstallResult,\n} from '@steps/add-mcp-server-to-clients/results';\nimport { LoginCapable } from '@steps/add-mcp-server-to-clients/login-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, LoginCapable\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 // `mcp get <name>` exits non-zero when the entry doesn't exist. A substring\n // scan of `mcp list` also matches the claude.ai \"PostHog\" connector and the\n // plugin's `plugin:posthog:posthog`, reporting installed forever.\n try {\n execSync(`${binary} mcp get ${serverName}`, { stdio: 'pipe' });\n return Promise.resolve(true);\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<InstallResult> {\n const binary = this.findClaudeBinary();\n if (!binary)\n return Promise.resolve({\n success: false,\n reason: 'The claude CLI is no longer on your PATH.',\n });\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 // The failing command echoes back the Authorization header we passed, so\n // redact before this reaches a log, the screen, or an exception report.\n const msg = redactSecrets(\n error instanceof Error ? error.message : String(error),\n );\n if (msg.includes('already exists')) {\n return Promise.resolve({ success: true, alreadyInstalled: true });\n }\n analytics.captureException(\n new Error(`Claude Code MCP add failed: ${msg}`),\n );\n return Promise.resolve({ success: false, reason: msg });\n }\n }\n\n /** Claude Code's own login runs its OAuth and owns the token; the wizard only surfaces the command. */\n loginCommand(local?: boolean): string {\n return `claude mcp login ${local ? 'posthog-local' : 'posthog'}`;\n }\n\n /** The plugin bundles its own `posthog` server, addressed as `plugin:<plugin>:<server>`. */\n pluginLoginCommand(): string {\n return 'claude mcp login plugin:posthog:posthog';\n }\n\n async removePlugin(): Promise<PluginInstallResult> {\n const binary = this.findClaudeBinary();\n if (!binary)\n return {\n success: false,\n reason: 'The claude CLI is no longer on your PATH.',\n };\n\n if (!(await this.isPluginInstalled())) {\n return { success: true, alreadyInstalled: true };\n }\n\n try {\n execSync(`${binary} plugin uninstall posthog`, { stdio: 'pipe' });\n return { success: true };\n } catch (error) {\n const msg = error instanceof Error ? error.message : String(error);\n analytics.captureException(\n new Error(`Claude Code plugin uninstall failed: ${msg}`),\n );\n return { success: false, reason: msg };\n }\n }\n\n removeServer(local?: boolean): Promise<InstallResult> {\n const claudeBinary = this.findClaudeBinary();\n if (!claudeBinary) {\n return Promise.resolve({\n success: false,\n reason: 'The claude CLI is no longer on your PATH.',\n });\n }\n\n const serverName = local ? 'posthog-local' : 'posthog';\n const command = `${claudeBinary} mcp remove --scope user ${serverName}`;\n\n try {\n execSync(command, { stdio: 'pipe' });\n } catch (error) {\n const reason = redactSecrets(\n error instanceof Error ? error.message : String(error),\n );\n // Removing something that isn't there is the requested end state, not a\n // failure to report.\n if (/no( such)? mcp server|not found/i.test(reason)) {\n return Promise.resolve({ success: true, alreadyInstalled: true });\n }\n analytics.captureException(\n new Error(`Failed to remove server from Claude Code: ${reason}`),\n );\n return Promise.resolve({ success: false, reason });\n }\n\n return Promise.resolve({ success: true });\n }\n\n /** The plugin ships mcp.json with the posthog server — no direct entry needed. */\n pluginBundlesMcpServer(): boolean {\n return 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 async installPlugin(): Promise<PluginInstallResult> {\n const binary = this.findClaudeBinary();\n if (!binary)\n return {\n success: false,\n reason: 'The claude CLI is no longer on your PATH.',\n };\n\n // Ask before installing so a re-run reports \"already installed\" rather than\n // relying on the CLI's error text to spot the no-op.\n if (await this.isPluginInstalled()) {\n return { success: true, alreadyInstalled: true };\n }\n\n try {\n execSync(`${binary} plugin install posthog`, { stdio: 'pipe' });\n return { 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 { success: true, alreadyInstalled: true };\n }\n analytics.captureException(\n new Error(`Claude Code plugin install failed: ${msg}`),\n );\n return { success: false, reason: msg };\n }\n }\n}\n","import { MCPClient } from '@steps/add-mcp-server-to-clients/MCPClient';\nimport type { InstallResult } from '@steps/add-mcp-server-to-clients/results';\nimport { BrowserFinishable } from '@steps/add-mcp-server-to-clients/browser-client';\nimport { openTrackedLink } from '@utils/links';\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<InstallResult> {\n // Not a PostHog property, so no UTMs — just the tracked open.\n openTrackedLink(this.connectorUrl, 'claude-web-connector', {\n auto: true,\n skipUtm: true,\n });\n return Promise.resolve({ success: true });\n }\n\n removeServer(): Promise<InstallResult> {\n // The connector lives in the user's Claude account, so `mcp remove` can't\n // touch it. It never reaches here today (isServerInstalled is always\n // false), but say where to go if it ever does.\n return Promise.resolve({\n success: false,\n reason:\n 'This connector is managed in your Claude account — remove it at claude.ai/settings/connectors.',\n });\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 { LoginCapable } from '@steps/add-mcp-server-to-clients/login-client';\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';\nimport {\n redactSecrets,\n type InstallResult,\n} from '@steps/add-mcp-server-to-clients/results';\n\nimport { analytics } from '@utils/analytics';\n\n/** Wording codex uses when the thing we're adding is already registered. */\nconst ALREADY_INSTALLED_PATTERN =\n /already (installed|exists|added|registered)/i;\n/** Wording that means the opposite: a cache entry exists but the plugin doesn't. */\nconst STALE_MARKETPLACE_CACHE = /already added from a different source/i;\n\n/**\n * Codex allows servers 10s to finish the MCP initialize handshake, and a remote\n * OAuth handshake can exceed that on a cold start — the \"servers were not\n * initialized\" warning.\n */\nconst STARTUP_TIMEOUT_SEC = 30;\n\n/**\n * The server's table header. TOML accepts a bare or quoted key for the same\n * table, and matching only the bare form means we append a second definition of\n * a table that already exists — a duplicate-key error that takes the user's\n * whole config down, not just PostHog's entry.\n */\nconst sectionHeader = (serverName: string): RegExp =>\n new RegExp(\n `^\\\\[mcp_servers\\\\.(?:${serverName}|\"${serverName}\")\\\\][ \\\\t]*$`,\n 'm',\n );\n\n/**\n * Set `key = value` inside a section body, inserting it when absent. Scans the\n * whole body rather than the line after the header: TOML does not care about\n * key order, and assuming it does means silently matching nothing.\n */\nconst setKey = (body: string, key: string, value: string): string => {\n const existing = new RegExp(`^[ \\\\t]*${key}[ \\\\t]*=.*$`, 'm');\n return existing.test(body)\n ? body.replace(existing, `${key} = ${value}`)\n : `\\n${key} = ${value}${body}`;\n};\n\nexport const CodexMCPConfig = DefaultMCPClientConfig;\n\nexport type CodexMCPConfig = z.infer<typeof DefaultMCPClientConfig>;\n\nexport class CodexMCPClient\n extends DefaultMCPClient\n implements PluginCapable, LoginCapable\n{\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 private configPath(): string {\n return path.join(os.homedir(), '.codex', 'config.toml');\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 serverName = local ? 'posthog-local' : 'posthog';\n // The `[mcp_servers.<name>]` section in config.toml — both the CLI and the\n // desktop app read (and `codex mcp add` writes) this file, and a substring\n // scan of `mcp list` matches unrelated posthog-ish servers.\n try {\n const contents = fs.readFileSync(this.configPath(), 'utf-8');\n return Promise.resolve(sectionHeader(serverName).test(contents));\n } catch {\n return Promise.resolve(false);\n }\n }\n\n addServer(\n apiKey?: string,\n selectedFeatures?: string[],\n local?: boolean,\n ): Promise<InstallResult> {\n const serverName = local ? 'posthog-local' : 'posthog';\n const url = buildMCPUrl(selectedFeatures, local);\n\n // Api-key installs go through the CLI for its bearer-token env wiring.\n if (apiKey) {\n const binary = this.findCodexBinary();\n if (!binary)\n return Promise.resolve({\n success: false,\n reason: 'An API-key install into Codex needs the codex CLI.',\n });\n const args = [\n 'mcp',\n 'add',\n serverName,\n '--url',\n url,\n '--bearer-token-env-var',\n 'POSTHOG_AUTH_HEADER',\n ];\n const env = { ...process.env, POSTHOG_AUTH_HEADER: `Bearer ${apiKey}` };\n const result = spawnSync(binary, args, { encoding: 'utf-8', env });\n if (result.status !== 0) {\n const stderr = result.stderr ?? '';\n if (ALREADY_INSTALLED_PATTERN.test(stderr)) {\n return Promise.resolve({ success: true, alreadyInstalled: true });\n }\n const reason = redactSecrets(stderr);\n analytics.captureException(\n new Error(`Codex MCP add failed: ${reason}`),\n );\n return Promise.resolve({ success: false, reason });\n }\n return Promise.resolve({ success: true });\n }\n\n // OAuth installs write config.toml directly: running `codex mcp add` here\n // would hang the wizard on its built-in OAuth browser wait. Codex nags\n // about the unauthenticated server until the surfaced `codex mcp login`\n // runs — the same interim state as Claude Code's \"needs authentication\".\n return Promise.resolve(this.writeServerSection(serverName, url));\n }\n\n /**\n * Create or update the `[mcp_servers.<name>]` section in config.toml, editing\n * in place so the user's other servers, key order, and comments survive.\n */\n private writeServerSection(serverName: string, url: string): InstallResult {\n const configPath = this.configPath();\n try {\n // A machine that has codex installed but has never run it has no\n // ~/.codex at all — `codex mcp add` used to create it for us.\n fs.mkdirSync(path.dirname(configPath), { recursive: true });\n const contents = fs.existsSync(configPath)\n ? fs.readFileSync(configPath, 'utf-8')\n : '';\n\n const header = sectionHeader(serverName).exec(contents);\n if (!header) {\n const gap = contents === '' || contents.endsWith('\\n\\n') ? '' : '\\n';\n const pad = contents === '' || contents.endsWith('\\n') ? '' : '\\n';\n this.write(\n configPath,\n `${contents}${pad}${gap}[mcp_servers.${serverName}]\\n` +\n `url = \"${url}\"\\nstartup_timeout_sec = ${STARTUP_TIMEOUT_SEC}\\n`,\n );\n return { success: true };\n }\n\n // Everything up to the next table header belongs to this server.\n const start = header.index + header[0].length;\n const rest = contents.slice(start);\n const next = /^\\[/m.exec(rest);\n const end = next ? start + next.index : contents.length;\n\n const body = contents.slice(start, end);\n const updated = setKey(\n setKey(body, 'url', `\"${url}\"`),\n 'startup_timeout_sec',\n String(STARTUP_TIMEOUT_SEC),\n );\n if (updated === body) return { success: true, alreadyInstalled: true };\n\n this.write(\n configPath,\n contents.slice(0, start) + updated + contents.slice(end),\n );\n return { success: true };\n } catch (error) {\n const reason = error instanceof Error ? error.message : String(error);\n analytics.captureException(\n new Error(`Codex config.toml write failed: ${reason}`),\n );\n return { success: false, reason };\n }\n }\n\n /** Write via a sibling temp file: a crash mid-write must not truncate the config. */\n private write(configPath: string, contents: string): void {\n const tmp = `${configPath}.wizard-tmp`;\n fs.writeFileSync(tmp, contents);\n fs.renameSync(tmp, configPath);\n }\n\n /** Codex's own login runs its OAuth and owns the token; the wizard only surfaces the command. */\n loginCommand(local?: boolean): string | null {\n if (!this.findCodexBinary()) return null;\n return `codex mcp login ${local ? 'posthog-local' : 'posthog'}`;\n }\n\n removeServer(local?: boolean): Promise<InstallResult> {\n const binary = this.findCodexBinary();\n if (!binary)\n return Promise.resolve({\n success: false,\n reason: 'The codex CLI is no longer on your PATH.',\n });\n\n // `local` was ignored here, so `mcp remove --local` reported success while\n // leaving the posthog-local server in place.\n const serverName = local ? 'posthog-local' : 'posthog';\n const result = spawnSync(binary, ['mcp', 'remove', serverName], {\n encoding: 'utf-8',\n });\n\n if (result.error || result.status !== 0) {\n const reason = redactSecrets(\n result.error?.message ?? result.stderr ?? 'codex mcp remove failed',\n );\n analytics.captureException(\n new Error(`Failed to remove server from Codex CLI: ${reason}`),\n );\n return Promise.resolve({ success: false, reason });\n }\n\n return Promise.resolve({ success: true });\n }\n\n /** The codex marketplace plugin ships skills only — the MCP server needs its own entry. */\n pluginBundlesMcpServer(): boolean {\n return false;\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 async removePlugin(): Promise<PluginInstallResult> {\n const binary = this.findCodexBinary();\n if (!binary)\n return {\n success: false,\n reason: 'The codex CLI is no longer on your PATH.',\n };\n\n if (!(await this.isPluginInstalled())) {\n return { success: true, alreadyInstalled: true };\n }\n\n const result = spawnSync(\n binary,\n ['plugin', 'marketplace', 'remove', 'posthog'],\n { encoding: 'utf-8' },\n );\n if (result.status !== 0) {\n const reason = redactSecrets(\n result.stderr ?? 'codex plugin marketplace remove failed',\n );\n analytics.captureException(\n new Error(`Codex plugin uninstall failed: ${reason}`),\n );\n return { success: false, reason };\n }\n return { success: true };\n }\n\n async installPlugin(): Promise<PluginInstallResult> {\n const binary = this.findCodexBinary();\n if (!binary)\n return {\n success: false,\n reason: 'The codex CLI is no longer on your PATH.',\n };\n\n // `codex plugin marketplace add` exits non-zero once the marketplace is\n // registered, so ask config.toml first. Without this the second run of\n // `mcp add` looked like a failure and reported nothing at all.\n if (await this.isPluginInstalled()) {\n return { success: true, alreadyInstalled: true };\n }\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 STALE_MARKETPLACE_CACHE.test(result.stderr ?? '')\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 const stderr = result.stderr ?? '';\n // The marketplace was registered by something other than us (a manual\n // `codex plugin marketplace add`, or a version that writes config.toml\n // differently) — that's still \"already installed\", not a failure. The\n // stale-cache wording above is deliberately excluded: that one means the\n // plugin is NOT registered, and it only reaches here if the retry failed.\n if (\n ALREADY_INSTALLED_PATTERN.test(stderr) &&\n !STALE_MARKETPLACE_CACHE.test(stderr)\n ) {\n return { success: true, alreadyInstalled: true };\n }\n const reason = redactSecrets(stderr);\n analytics.captureException(\n new Error(`Codex plugin install failed: ${reason}`),\n );\n return { success: false, reason };\n }\n\n return { success: true };\n }\n}\n\nexport default CodexMCPClient;\n","import z from 'zod';\nimport * as path from 'path';\nimport * as os from 'os';\nimport * as fs from 'fs';\nimport { execSync } from 'node:child_process';\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 OpenCodeMCPConfig = z\n .object({\n mcp: z.record(\n z.string(),\n z.object({\n type: z.literal('remote'),\n url: z.string(),\n headers: z.record(z.string(), z.string()).optional(),\n }),\n ),\n })\n .passthrough();\n\nexport type OpenCodeMCPConfig = z.infer<typeof OpenCodeMCPConfig>;\n\nexport class OpenCodeMCPClient extends DefaultMCPClient {\n name = 'OpenCode';\n private opencodeBinaryPath: string | null = null;\n\n override getServerPropertyName(): string {\n return 'mcp';\n }\n\n private findOpenCodeBinary(): string | null {\n if (this.opencodeBinaryPath) return this.opencodeBinaryPath;\n try {\n const resolved = execSync('command -v opencode', { stdio: 'pipe' })\n .toString()\n .trim();\n if (resolved) {\n this.opencodeBinaryPath = 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.findOpenCodeBinary() !== null);\n }\n\n getConfigPath(): Promise<string> {\n const configDir = this.resolveConfigDir();\n const jsoncPath = path.join(configDir, 'opencode.jsonc');\n const jsonPath = path.join(configDir, 'opencode.json');\n if (fs.existsSync(jsoncPath)) return Promise.resolve(jsoncPath);\n return Promise.resolve(jsonPath);\n }\n\n private resolveConfigDir(): string {\n const envDir = runtimeEnv('OPENCODE_CONFIG_DIR');\n if (envDir) return envDir;\n\n const xdgHome = runtimeEnv('XDG_CONFIG_HOME');\n if (xdgHome) return path.join(xdgHome, 'opencode');\n\n return path.join(os.homedir(), '.config', 'opencode');\n }\n\n override getServerConfig(\n apiKey: string | undefined,\n selectedFeatures?: string[],\n local?: boolean,\n ): MCPServerConfig {\n return {\n type: 'remote',\n ...getNativeHTTPServerConfig(apiKey, selectedFeatures, local),\n };\n }\n}\n","import type { InstallResult } from './results';\n\nexport type PluginInstallResult = InstallResult;\n\nexport interface PluginCapable {\n supportsPlugin(): boolean;\n isPluginInstalled(): Promise<boolean>;\n installPlugin(): Promise<PluginInstallResult>;\n /** Uninstall the plugin. Absent when the client CLI has no uninstall surface. */\n removePlugin?(): Promise<PluginInstallResult>;\n /** True when the plugin ships its own posthog MCP server, making a direct entry redundant. */\n pluginBundlesMcpServer(): boolean;\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 { OpenCodeMCPClient } from './clients/opencode';\nimport { ALL_FEATURE_VALUES } from './defaults';\nimport { debug } from '@utils/debug';\nimport { isPluginCapable, PluginCapable } from './plugin-client';\nimport {\n McpClientStatus,\n namesWithStatus,\n toClientResult,\n type McpClientResult,\n} from './results';\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 new OpenCodeMCPClient(),\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/** Per-client outcome, so a scripted caller can turn a failure into an exit code. */\nexport interface McpStepOutcome {\n /** Clients that ended up with the server, whether we wrote it or it was already there. */\n installed: string[];\n failed: string[];\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<McpStepOutcome> => {\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 { installed: [], failed: [] };\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 { installed: [], failed: [] };\n }\n\n // Auto-install to all supported clients\n const results = await withProgress('adding mcp servers', () =>\n addMCPServer(\n supportedClients,\n apiKey,\n features ?? [...ALL_FEATURE_VALUES],\n local,\n ),\n );\n\n const installed = namesWithStatus(results, McpClientStatus.Changed);\n const already = namesWithStatus(results, McpClientStatus.Unchanged);\n const failed = results.filter((r) => r.status === McpClientStatus.Failed);\n\n // Report each outcome on its own — a blanket \"Added the MCP server to: ...\"\n // hid both the no-op re-runs and the outright failures.\n if (installed.length > 0) {\n ui.log.success(`Added the MCP server to:\\n${bulletList(installed)}`);\n }\n if (already.length > 0) {\n ui.log.info(\n `The PostHog MCP server was already installed, so nothing changed for:\\n${bulletList(\n already,\n )}`,\n );\n }\n if (failed.length > 0) {\n ui.log.warn(\n `Couldn't add the MCP server to:\\n${bulletList(\n failed.map((r) => (r.detail ? `${r.name} — ${r.detail}` : r.name)),\n )}`,\n );\n }\n\n const withServer = [...installed, ...already];\n\n analytics.wizardCapture('mcp servers added', {\n // `clients` stays \"every client that ended up with the MCP server\", which is\n // what it meant before — the new properties break that down.\n clients: withServer,\n already_installed_clients: already,\n failed_clients: failed.map((r) => r.name),\n attempted_clients: supportedClients.map((c) => c.name),\n integration,\n });\n\n return { installed: withServer, failed: failed.map((r) => r.name) };\n};\n\nconst bulletList = (items: string[]): string =>\n items.map((item) => ` - ${item}`).join('\\n');\n\nexport const removeMCPServerFromClientsStep = async ({\n integration,\n local = false,\n}: {\n integration?: Integration;\n local?: boolean;\n}): Promise<string[]> => {\n const ui = getUI();\n const installedClients = await getInstalledClients(local);\n if (installedClients.length === 0) {\n ui.log.info(\n 'The PostHog MCP server is not installed for any supported client. Nothing to remove.',\n );\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', () =>\n removeMCPServer(installedClients, local),\n );\n\n const removed = namesWithStatus(results, McpClientStatus.Changed);\n const nothingToDo = namesWithStatus(results, McpClientStatus.Unchanged);\n const failed = results.filter((r) => r.status === McpClientStatus.Failed);\n\n // This step used to print nothing at all, so a non-TTY `mcp remove` gave no\n // hint whether anything happened — let alone whether a client failed.\n if (removed.length > 0) {\n ui.log.success(`Removed the MCP server from:\\n${bulletList(removed)}`);\n }\n if (nothingToDo.length > 0) {\n ui.log.info(\n `No PostHog MCP entry left to remove for:\\n${bulletList(nothingToDo)}`,\n );\n }\n if (failed.length > 0) {\n ui.log.warn(\n `Couldn't remove the MCP server from:\\n${bulletList(\n failed.map((r) => (r.detail ? `${r.name} — ${r.detail}` : r.name)),\n )}`,\n );\n }\n\n analytics.wizardCapture('mcp servers removed', {\n clients: removed,\n nothing_to_remove_clients: nothingToDo,\n failed_clients: failed.map((r) => r.name),\n attempted_clients: installedClients.map((c) => c.name),\n integration,\n });\n\n return removed;\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 // The plugin bundles its own posthog MCP server, so for removal purposes a\n // plugin install counts as installed even with no config entry (`--local`\n // targets only the local-dev entry and leaves the plugin alone).\n const pluginInstalled =\n !local && isPluginCapable(client) && (await client.isPluginInstalled());\n if ((await client.isServerInstalled(local)) || pluginInstalled) {\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<McpClientResult[]> => {\n const results: McpClientResult[] = [];\n for (const client of clients) {\n try {\n const result = await client.addServer(\n personalApiKey,\n selectedFeatures,\n local,\n );\n results.push(toClientResult(client.name, result));\n } catch (err) {\n debug(`[addMCPServer] addServer threw for ${client.name}: ${err}`);\n results.push(\n toClientResult(client.name, {\n success: false,\n reason: err instanceof Error ? err.message : String(err),\n }),\n );\n }\n }\n return results;\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<McpClientResult[]> => {\n const results: McpClientResult[] = [];\n for (const client of clients) {\n try {\n results.push(toClientResult(client.name, await client.installPlugin()));\n } catch (err) {\n debug(`[installPlugins] installPlugin threw for ${client.name}: ${err}`);\n results.push(\n toClientResult(client.name, {\n success: false,\n reason: err instanceof Error ? err.message : String(err),\n }),\n );\n }\n }\n return results;\n};\n\nexport const removeMCPServer = async (\n clients: MCPClient[],\n local?: boolean,\n): Promise<McpClientResult[]> => {\n const results: McpClientResult[] = [];\n for (const client of clients) {\n try {\n let result = await client.removeServer(local);\n // The plugin bundles its own posthog server — leaving it installed makes\n // the removal a lie (`--local` never touches the plugin).\n if (!local && isPluginCapable(client) && client.removePlugin) {\n const plugin = await client.removePlugin();\n result =\n !result.success || !plugin.success\n ? {\n success: false,\n reason: [result.reason, plugin.reason]\n .filter(Boolean)\n .join('; '),\n }\n : {\n success: true,\n ...(result.alreadyInstalled && plugin.alreadyInstalled\n ? { alreadyInstalled: true }\n : {}),\n };\n }\n results.push(toClientResult(client.name, result));\n } catch (err) {\n debug(`[removeMCPServer] removeServer threw for ${client.name}: ${err}`);\n results.push(\n toClientResult(client.name, {\n success: false,\n reason: err instanceof Error ? err.message : String(err),\n }),\n );\n }\n }\n return results;\n};\n"],"mappings":"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"}
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
import { n as __require } from "./rolldown-runtime-B_-DWIq7.js";
|
|
2
2
|
import { a as AgentSignals, o as REMARK_INSTRUCTION, s as classifyAuthFailure } from "./errors-u8z27V-x.js";
|
|
3
|
-
import {
|
|
3
|
+
import { D as CONTEXT_MILL_URL, St as runtimeEnv, T as AWS_SKILLS_BASE_URL, X as POSTHOG_PROPERTY_HEADER_PREFIX, a as getLogFilePath, f as getUI, ft as WIZARD_REMARK_EVENT_NAME, gt as wizardUserAgentForProgram, o as initLogFile, q as POSTHOG_FLAG_HEADER_PREFIX, r as debug, s as logToFile } from "./debug-D0k3Quos.js";
|
|
4
4
|
import { n as ADDITIONAL_FEATURE_PROMPTS } from "./wizard-session-GdDN_aMS.js";
|
|
5
|
-
import { n as analytics } from "./analytics-
|
|
6
|
-
import { a as safeReadFile, i as readProjectFile, o as walkProjectFiles } from "./bounded-fs-
|
|
7
|
-
import { i as wizardAbort, n as registerCleanup, t as WizardError } from "./wizard-abort-
|
|
8
|
-
import { b as coerceAuditChecks, g as AUDIT_CHECKS_FILE, l as prewarmYaraScanner, n as createPostToolUseYaraHooks, p as scanInstalledSkill, r as createPreToolUseYaraHooks } from "./yara-hooks-
|
|
9
|
-
import { S as writeJsonAtomic, b as triageModelFor, c as buildOrchestratorTools, v as modelCapabilities, x as makeMutex } from "./queue-tools-
|
|
5
|
+
import { n as analytics } from "./analytics-DHkqXgxG.js";
|
|
6
|
+
import { a as safeReadFile, i as readProjectFile, o as walkProjectFiles } from "./bounded-fs-Byv2xRSy.js";
|
|
7
|
+
import { i as wizardAbort, n as registerCleanup, t as WizardError } from "./wizard-abort-DKpVH-t6.js";
|
|
8
|
+
import { b as coerceAuditChecks, g as AUDIT_CHECKS_FILE, l as prewarmYaraScanner, n as createPostToolUseYaraHooks, p as scanInstalledSkill, r as createPreToolUseYaraHooks } from "./yara-hooks-D-QD1ZCB.js";
|
|
9
|
+
import { S as writeJsonAtomic, b as triageModelFor, c as buildOrchestratorTools, v as modelCapabilities, x as makeMutex } from "./queue-tools-C3D_nwy_.js";
|
|
10
10
|
import { createRequire } from "node:module";
|
|
11
11
|
import * as fs$1 from "fs";
|
|
12
12
|
import fs from "fs";
|
|
@@ -985,30 +985,115 @@ function createWizardAskBridge(opts) {
|
|
|
985
985
|
//#endregion
|
|
986
986
|
//#region src/lib/fetch-retry.ts
|
|
987
987
|
/**
|
|
988
|
-
*
|
|
989
|
-
*
|
|
990
|
-
*
|
|
991
|
-
*
|
|
988
|
+
* One retry + failover policy for every critical-path fetch. GitHub is primary,
|
|
989
|
+
* AWS is the fallback. A status a retry can't heal (404, 403) spends no retry
|
|
990
|
+
* budget at the origin that returned it — but it still costs the other origin
|
|
991
|
+
* one try, because the two are published separately and GitHub 403s expired
|
|
992
|
+
* asset redirects and blocked regions where the asset is present.
|
|
992
993
|
*/
|
|
993
994
|
const DEFAULT_TIMEOUT_MS = 6e4;
|
|
994
995
|
const DEFAULT_MAX_ATTEMPTS = 3;
|
|
995
996
|
const DEFAULT_BACKOFF_MS = 500;
|
|
997
|
+
const GITHUB_LATEST_PREFIX = `${CONTEXT_MILL_URL}/releases/latest/download/`;
|
|
998
|
+
const GITHUB_PINNED_PREFIX = `${CONTEXT_MILL_URL}/releases/download/`;
|
|
999
|
+
/** Version-pinned URLs name their own prefix, so they need the host alone. */
|
|
1000
|
+
const AWS_ORIGIN = new URL(AWS_SKILLS_BASE_URL).origin;
|
|
996
1001
|
function sleep(ms) {
|
|
997
1002
|
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
998
1003
|
}
|
|
999
|
-
/**
|
|
1004
|
+
/**
|
|
1005
|
+
* Maps a context-mill release URL onto AWS; null when there is no second origin.
|
|
1006
|
+
*
|
|
1007
|
+
* .../releases/latest/download/x.zip -> <aws>/latest/x.zip
|
|
1008
|
+
* .../releases/download/v1.50.0/x.zip -> <aws>/v1.50.0/x.zip
|
|
1009
|
+
*/
|
|
1010
|
+
function awsUrlFor(url) {
|
|
1011
|
+
if (url.startsWith(GITHUB_LATEST_PREFIX)) return `${AWS_SKILLS_BASE_URL}/${url.slice(GITHUB_LATEST_PREFIX.length)}`;
|
|
1012
|
+
if (url.startsWith(GITHUB_PINNED_PREFIX)) return `${AWS_ORIGIN}/${url.slice(GITHUB_PINNED_PREFIX.length)}`;
|
|
1013
|
+
return null;
|
|
1014
|
+
}
|
|
1015
|
+
/** Sticky: without it every asset re-pays GitHub's retry budget during an outage. */
|
|
1016
|
+
let preferredOrigin = "github";
|
|
1017
|
+
/** A response status that retrying can't fix; propagates past the retry loop. */
|
|
1018
|
+
var NonRetryableFetchError = class extends Error {};
|
|
1019
|
+
/**
|
|
1020
|
+
* 5xx are transient; 408 (request timeout) and 429 (rate limit) explicitly ask
|
|
1021
|
+
* to retry. Every other 4xx is a client error a retry won't heal (404 missing
|
|
1022
|
+
* skill, 403 bad token) — retrying only burns the backoff before failing.
|
|
1023
|
+
*/
|
|
1024
|
+
function isRetryableStatus(status) {
|
|
1025
|
+
return status >= 500 || status === 408 || status === 429;
|
|
1026
|
+
}
|
|
1027
|
+
function messageOf(err) {
|
|
1028
|
+
return err instanceof Error ? err.message : String(err);
|
|
1029
|
+
}
|
|
1030
|
+
/** Try one origin to exhaustion. */
|
|
1031
|
+
async function fetchOrigin(url, opts) {
|
|
1032
|
+
const failures = [];
|
|
1033
|
+
for (let attempt = 1; attempt <= opts.maxAttempts; attempt++) try {
|
|
1034
|
+
const resp = await opts.fetchImpl(url, { signal: AbortSignal.timeout(opts.timeoutMs) });
|
|
1035
|
+
if (resp.ok) return resp;
|
|
1036
|
+
const msg = `HTTP ${resp.status} ${resp.statusText}`.trim();
|
|
1037
|
+
if (!isRetryableStatus(resp.status)) throw new NonRetryableFetchError(msg);
|
|
1038
|
+
throw new Error(msg);
|
|
1039
|
+
} catch (err) {
|
|
1040
|
+
if (err instanceof NonRetryableFetchError) throw err;
|
|
1041
|
+
failures.push(`attempt ${attempt}: ${messageOf(err)}`);
|
|
1042
|
+
if (attempt < opts.maxAttempts) await opts.sleepImpl(opts.backoffMs * 2 ** (attempt - 1));
|
|
1043
|
+
}
|
|
1044
|
+
throw new Error(failures.join("; "));
|
|
1045
|
+
}
|
|
1046
|
+
/**
|
|
1047
|
+
* Retry with backoff, then fail over. Throws once every origin is exhausted.
|
|
1048
|
+
*/
|
|
1000
1049
|
async function fetchWithRetry(url, opts = {}) {
|
|
1001
|
-
const { fetchImpl = fetch, sleepImpl = sleep, timeoutMs = DEFAULT_TIMEOUT_MS, maxAttempts = DEFAULT_MAX_ATTEMPTS, backoffMs = DEFAULT_BACKOFF_MS } = opts;
|
|
1050
|
+
const { fetchImpl = fetch, sleepImpl = sleep, timeoutMs = DEFAULT_TIMEOUT_MS, maxAttempts = DEFAULT_MAX_ATTEMPTS, backoffMs = DEFAULT_BACKOFF_MS, failover = true, onEvent = (event, props) => analytics.wizardCapture(event, props) } = opts;
|
|
1051
|
+
const originOpts = {
|
|
1052
|
+
fetchImpl,
|
|
1053
|
+
sleepImpl,
|
|
1054
|
+
timeoutMs,
|
|
1055
|
+
maxAttempts,
|
|
1056
|
+
backoffMs
|
|
1057
|
+
};
|
|
1058
|
+
const awsUrl = failover ? awsUrlFor(url) : null;
|
|
1059
|
+
if (!awsUrl) try {
|
|
1060
|
+
return await fetchOrigin(url, originOpts);
|
|
1061
|
+
} catch (err) {
|
|
1062
|
+
throw new Error(`fetch ${url} failed — ${messageOf(err)}`);
|
|
1063
|
+
}
|
|
1064
|
+
const order = preferredOrigin === "aws" ? [{
|
|
1065
|
+
origin: "aws",
|
|
1066
|
+
target: awsUrl
|
|
1067
|
+
}, {
|
|
1068
|
+
origin: "github",
|
|
1069
|
+
target: url
|
|
1070
|
+
}] : [{
|
|
1071
|
+
origin: "github",
|
|
1072
|
+
target: url
|
|
1073
|
+
}, {
|
|
1074
|
+
origin: "aws",
|
|
1075
|
+
target: awsUrl
|
|
1076
|
+
}];
|
|
1002
1077
|
const failures = [];
|
|
1003
|
-
for (
|
|
1004
|
-
const resp = await
|
|
1005
|
-
if (
|
|
1078
|
+
for (const [index, candidate] of order.entries()) try {
|
|
1079
|
+
const resp = await fetchOrigin(candidate.target, originOpts);
|
|
1080
|
+
if (candidate.origin !== preferredOrigin) {
|
|
1081
|
+
preferredOrigin = candidate.origin;
|
|
1082
|
+
logToFile(`fetchWithRetry: failed over to ${candidate.origin}`);
|
|
1083
|
+
onEvent("skills fetch failed over", {
|
|
1084
|
+
origin: candidate.origin,
|
|
1085
|
+
url: candidate.target
|
|
1086
|
+
});
|
|
1087
|
+
}
|
|
1006
1088
|
return resp;
|
|
1007
1089
|
} catch (err) {
|
|
1008
|
-
failures.push(
|
|
1009
|
-
if (
|
|
1090
|
+
failures.push(`${candidate.origin}: ${messageOf(err)}`);
|
|
1091
|
+
if (index === order.length - 1) onEvent("skills fetch failed", {
|
|
1092
|
+
url,
|
|
1093
|
+
failures: failures.length
|
|
1094
|
+
});
|
|
1010
1095
|
}
|
|
1011
|
-
throw new Error(`fetch ${url} failed — ${failures.join("
|
|
1096
|
+
throw new Error(`fetch ${url} failed — ${failures.join(" | ")}`);
|
|
1012
1097
|
}
|
|
1013
1098
|
//#endregion
|
|
1014
1099
|
//#region src/lib/wizard-tools/tools.ts
|
|
@@ -3917,4 +4002,4 @@ function handleSDKMessage(message, options, spinner, signals, receivedSuccessRes
|
|
|
3917
4002
|
//#endregion
|
|
3918
4003
|
export { checkEnvKeys as A, vaultSensitiveAnswers as B, CHECK_ENV_KEYS_DESCRIPTION as C, WIZARD_ASK_SUBJECT_DESCRIPTION as D, WIZARD_ASK_SENSITIVE_DESCRIPTION as E, mergeEnvValues as F, MAX_ENV_KEY_SET as G, createWizardAskBridge as H, normaliseAskSubject as I, toPromptSafeRelativePath as J, isEnvFileName as K, resolveEnvPath as L, downloadSkill as M, fetchSkillMenu as N, WIZARD_ASK_TOOL_DESCRIPTION as O, installSkillById as P, resolveEnvSecretRefs as R, publishHandoff as S, ENV_FILE_PATH_DESCRIPTION as T, isFullyCancelled as U, fetchWithRetry as V, gatewayAuth as W, markGrantRevoked as Y, buildGatewayProvider as _, wizardCanUseTool as a, PUBLISH_HANDOFF_DESCRIPTION as b, checkAllSettingsConflicts as c, restoreClaudeSettings as d, sanitizeAgentSubprocessEnv as f, GATEWAY_PROVIDER as g, createTriageLLMProvider as h, runAgent as i, createAskAccounting as j, WIZARD_TOOL_NAMES as k, classifySettingsConflicts as l, assembleCommandments as m, buildRunTags as n, createIsolatedAgentConfigDir as o, AgentOutputSignals as p, parseEnvKeyNames as q, initializeAgent as r, backupAndFixClaudeSettings as s, buildAgentEnv as t, recoverOrphanedSettingsBackups as u, createSecretVault as v, CHECK_ENV_KEYS_FILE_PATH_DESCRIPTION as w, PUBLISH_HANDOFF_TOOL_NAME as x, PUBLISH_HANDOFF_CONTENT_DESCRIPTION as y, templateEnvWriteRefusal as z };
|
|
3919
4004
|
|
|
3920
|
-
//# sourceMappingURL=agent-interface-
|
|
4005
|
+
//# sourceMappingURL=agent-interface-CQ_iz7g7.js.map
|