@posthog/wizard 2.15.0 → 2.16.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.
Files changed (89) hide show
  1. package/README.md +0 -4
  2. package/dist/{TextBlock-B_8bXLLs.js → TextBlock-CdeZog_6.js} +4 -4
  3. package/dist/TextBlock-CdeZog_6.js.map +1 -0
  4. package/dist/{add-mcp-server-to-clients-Dq0n2yzq.js → add-mcp-server-to-clients-BS6Rjcwh.js} +6 -6
  5. package/dist/{add-mcp-server-to-clients-Dq0n2yzq.js.map → add-mcp-server-to-clients-BS6Rjcwh.js.map} +1 -1
  6. package/dist/{agent-interface-yB_27jG8.js → agent-interface-B4eUlMso.js} +33 -7
  7. package/dist/agent-interface-B4eUlMso.js.map +1 -0
  8. package/dist/{agent-runner-C9sSudE0.js → agent-runner-BxqiKVEf.js} +21 -22
  9. package/dist/{agent-runner-C9sSudE0.js.map → agent-runner-BxqiKVEf.js.map} +1 -1
  10. package/dist/{analytics-Da4QHjMw.js → analytics-DUuUurR3.js} +3 -3
  11. package/dist/{analytics-Da4QHjMw.js.map → analytics-DUuUurR3.js.map} +1 -1
  12. package/dist/api-B8OR0N1V.js +2 -0
  13. package/dist/api-CGJ1iGps.js +138 -0
  14. package/dist/api-CGJ1iGps.js.map +1 -0
  15. package/dist/bin.js +808 -476
  16. package/dist/bin.js.map +1 -1
  17. package/dist/ci-install-DD7WMmIF.js +73 -0
  18. package/dist/ci-install-DD7WMmIF.js.map +1 -0
  19. package/dist/{debug-D5kt4fxB.js → debug-Cd0hPlZy.js} +1 -1
  20. package/dist/{debug-DRKLej5r.js → debug-ubpO6102.js} +14 -6
  21. package/dist/debug-ubpO6102.js.map +1 -0
  22. package/dist/{defaults-CPH6eWhN.js → defaults-zrYmZ2ID.js} +1 -1
  23. package/dist/{defaults-CPH6eWhN.js.map → defaults-zrYmZ2ID.js.map} +1 -1
  24. package/dist/{env-api-key-HFqv1l-z.js → env-api-key-DEl3LJBv.js} +4 -2
  25. package/dist/{env-api-key-HFqv1l-z.js.map → env-api-key-DEl3LJBv.js.map} +1 -1
  26. package/dist/environment-BAaC5THg.js +22 -0
  27. package/dist/environment-BAaC5THg.js.map +1 -0
  28. package/dist/{file-utils-DnTSiTJw.js → file-utils-DPmgn9Vm.js} +1 -1
  29. package/dist/{file-utils-DnTSiTJw.js.map → file-utils-DPmgn9Vm.js.map} +1 -1
  30. package/dist/interactive-BaMAq88Q.js +11 -0
  31. package/dist/interactive-BaMAq88Q.js.map +1 -0
  32. package/dist/mcp-prompt-streaming-clGsVw8q.js +200 -0
  33. package/dist/mcp-prompt-streaming-clGsVw8q.js.map +1 -0
  34. package/dist/non-interactive-l2AKE3jD.js +12 -0
  35. package/dist/non-interactive-l2AKE3jD.js.map +1 -0
  36. package/dist/package-json-CumwmZpv.js +2 -0
  37. package/dist/{package-json-v_g2YlN1.js → package-json-Cynjr9k4.js} +1 -1
  38. package/dist/{package-json-v_g2YlN1.js.map → package-json-Cynjr9k4.js.map} +1 -1
  39. package/dist/{package-manager-DlTISyej.js → package-manager-BqsJK3ej.js} +2 -2
  40. package/dist/{package-manager-DlTISyej.js.map → package-manager-BqsJK3ej.js.map} +1 -1
  41. package/dist/{start-playground-Bxd2KG2L.js → playground-DlE5RNfE.js} +297 -8
  42. package/dist/playground-DlE5RNfE.js.map +1 -0
  43. package/dist/{posthog-B1G0raJU.js → posthog-DWL8uOcl.js} +1 -1
  44. package/dist/{posthog-B1G0raJU.js.map → posthog-DWL8uOcl.js.map} +1 -1
  45. package/dist/{posthog-integration-D-DyEJvz.js → posthog-integration-Bf_vtWI9.js} +229 -21
  46. package/dist/posthog-integration-Bf_vtWI9.js.map +1 -0
  47. package/dist/provisioning-BlBnlcFd.js +2 -0
  48. package/dist/{provisioning-DmN8ZDbE.js → provisioning-D_hAuxUN.js} +3 -3
  49. package/dist/{provisioning-DmN8ZDbE.js.map → provisioning-D_hAuxUN.js.map} +1 -1
  50. package/dist/{registry-CofBzIdU.js → registry-DKgYqROt.js} +5 -5
  51. package/dist/{registry-CofBzIdU.js.map → registry-DKgYqROt.js.map} +1 -1
  52. package/dist/setup-utils-BHZEdkNZ.js +2 -0
  53. package/dist/{setup-utils-_P-or31U.js → setup-utils-D-uTycLX.js} +24 -90
  54. package/dist/setup-utils-D-uTycLX.js.map +1 -0
  55. package/dist/skill-CnOQAZXp.js +29 -0
  56. package/dist/skill-CnOQAZXp.js.map +1 -0
  57. package/dist/{slides-D3I6JzlG.js → slides-CL1mv_Kq.js} +692 -68
  58. package/dist/slides-CL1mv_Kq.js.map +1 -0
  59. package/dist/{start-tui-Bl8fCbp_.js → start-tui-DXrv6cof.js} +470 -31
  60. package/dist/start-tui-DXrv6cof.js.map +1 -0
  61. package/dist/{steps-B-vmvb2V.js → steps-CgScwqso.js} +6 -6
  62. package/dist/{steps-B-vmvb2V.js.map → steps-CgScwqso.js.map} +1 -1
  63. package/dist/{task-stream-z6QFZtpC.js → task-stream-CF6QMVMv.js} +3 -3
  64. package/dist/{task-stream-z6QFZtpC.js.map → task-stream-CF6QMVMv.js.map} +1 -1
  65. package/dist/{telemetry-XO0SlTFs.js → telemetry-v6O12Bep.js} +2 -2
  66. package/dist/{telemetry-XO0SlTFs.js.map → telemetry-v6O12Bep.js.map} +1 -1
  67. package/dist/{wizard-abort-CuaS1eXn.js → wizard-abort-BGoBKgvC.js} +1 -1
  68. package/dist/{wizard-abort-uolun8Q3.js → wizard-abort-iTaJ8wC8.js} +3 -3
  69. package/dist/{wizard-abort-uolun8Q3.js.map → wizard-abort-iTaJ8wC8.js.map} +1 -1
  70. package/dist/{wizard-session-DxU5ZMBN.js → wizard-session-7tMjgOvP.js} +1 -1
  71. package/dist/{wizard-session-BlgiX-5d.js → wizard-session-gsn8Z3bZ.js} +5 -3
  72. package/dist/wizard-session-gsn8Z3bZ.js.map +1 -0
  73. package/dist/wizard-ui-YdGFRyu_.js.map +1 -1
  74. package/package.json +1 -1
  75. package/dist/TextBlock-B_8bXLLs.js.map +0 -1
  76. package/dist/agent-interface-yB_27jG8.js.map +0 -1
  77. package/dist/analytics-BnR9904x.js +0 -2
  78. package/dist/debug-DRKLej5r.js.map +0 -1
  79. package/dist/detection-0Pz2NncX.js +0 -206
  80. package/dist/detection-0Pz2NncX.js.map +0 -1
  81. package/dist/package-json-Cttzi3C8.js +0 -2
  82. package/dist/posthog-integration-D-DyEJvz.js.map +0 -1
  83. package/dist/provisioning-COeHnCVG.js +0 -2
  84. package/dist/setup-utils-C5iSJ3eg.js +0 -2
  85. package/dist/setup-utils-_P-or31U.js.map +0 -1
  86. package/dist/slides-D3I6JzlG.js.map +0 -1
  87. package/dist/start-playground-Bxd2KG2L.js.map +0 -1
  88. package/dist/start-tui-Bl8fCbp_.js.map +0 -1
  89. package/dist/wizard-session-BlgiX-5d.js.map +0 -1
package/dist/bin.js CHANGED
@@ -1,39 +1,269 @@
1
1
  #!/usr/bin/env node
2
- import { t as __exportAll } from "./rolldown-runtime-B_-DWIq7.js";
3
- import { M as POSTHOG_DOCS_URL, W as WIZARD_USER_AGENT, X as VERSION, Y as runtimeEnv, _ as SIGNUP_WIZARD_READINESS_CONFIG, h as LoggingUI, m as setUI, p as getUI, s as logToFile, v as evaluateWizardReadiness, y as getBlockingServiceKeys } from "./debug-DRKLej5r.js";
4
- import { n as analytics } from "./analytics-Da4QHjMw.js";
5
- import { a as isUsingTypeScript, f as getCloudUrlFromRegion, m as getUiHostFromHost, u as handleApiError } from "./setup-utils-_P-or31U.js";
6
- import "./wizard-session-BlgiX-5d.js";
7
- import { g as AUDIT_REPORT_FILE, h as AUDIT_CHECKS_KEY, m as AUDIT_CHECKS_FILE, t as AgentSignals, u as WIZARD_TOOL_NAMES } from "./agent-interface-yB_27jG8.js";
8
- import { i as SPINNER_MESSAGE } from "./registry-CofBzIdU.js";
9
- import { c as HEALTH_CHECK_STEP, o as Colors, r as isClearBlock } from "./TextBlock-B_8bXLLs.js";
10
- import { a as LINE_CHART_BLOCK, i as FUNNEL_BLOCK, n as posthogIntegrationConfig, o as PRODUCT_SUITE_BLOCK, s as StatusPeekTrigger } from "./posthog-integration-D-DyEJvz.js";
11
- import { t as IGNORED_DIRS } from "./file-utils-DnTSiTJw.js";
2
+ import { J as VERSION, M as POSTHOG_DOCS_URL, W as WIZARD_USER_AGENT, X as runtimeEnv, _ as SIGNUP_WIZARD_READINESS_CONFIG, h as LoggingUI, m as setUI, p as getUI, s as logToFile, v as evaluateWizardReadiness, y as getBlockingServiceKeys } from "./debug-ubpO6102.js";
3
+ import { t as analytics } from "./analytics-DUuUurR3.js";
4
+ import { a as isUsingTypeScript, f as getUiHostFromHost, u as getCloudUrlFromRegion } from "./setup-utils-D-uTycLX.js";
5
+ import { s as handleApiError } from "./api-CGJ1iGps.js";
6
+ import "./wizard-session-gsn8Z3bZ.js";
7
+ import { n as isNonInteractiveEnvironment } from "./environment-BAaC5THg.js";
8
+ import { g as AUDIT_REPORT_FILE, h as AUDIT_CHECKS_KEY, m as AUDIT_CHECKS_FILE, t as AgentSignals, u as WIZARD_TOOL_NAMES } from "./agent-interface-B4eUlMso.js";
9
+ import { i as SPINNER_MESSAGE } from "./registry-DKgYqROt.js";
10
+ import { a as PRODUCT_SUITE_BLOCK, i as LINE_CHART_BLOCK, n as posthogIntegrationConfig, o as StatusPeekTrigger, r as FUNNEL_BLOCK } from "./posthog-integration-Bf_vtWI9.js";
11
+ import { c as HEALTH_CHECK_STEP, o as Colors, r as isClearBlock } from "./TextBlock-CdeZog_6.js";
12
+ import { t as IGNORED_DIRS } from "./file-utils-DPmgn9Vm.js";
13
+ import { n as readApiKeyFromEnv } from "./env-api-key-DEl3LJBv.js";
12
14
  import { satisfies } from "semver";
13
15
  import yargs from "yargs";
14
16
  import { hideBin } from "yargs/helpers";
15
- import readEnvModule from "read-env";
16
17
  import fs, { existsSync, readFileSync, readdirSync, statSync } from "fs";
17
18
  import path, { join, relative } from "path";
18
19
  import axios from "axios";
19
20
  import { z } from "zod";
20
- import "fast-glob";
21
21
  import { Text } from "ink";
22
22
  import { jsx, jsxs } from "react/jsx-runtime";
23
- //#region src/utils/environment.ts
24
- var environment_exports = /* @__PURE__ */ __exportAll({
25
- isNonInteractiveEnvironment: () => isNonInteractiveEnvironment,
26
- readEnvironment: () => readEnvironment
27
- });
28
- const readEnv = typeof readEnvModule === "function" ? readEnvModule : readEnvModule.default;
29
- function isNonInteractiveEnvironment() {
30
- if (!process.stdout.isTTY || !process.stderr.isTTY) return true;
31
- return false;
23
+ //#region src/commands/command.ts
24
+ /** Extract the bare command word(s) from a yargs name spec, dropping positionals and aliases' arg syntax. */
25
+ function commandKeys(name) {
26
+ return (typeof name === "string" ? [name] : name).map((n) => n.trim().split(/\s+/)[0]);
32
27
  }
33
- function readEnvironment() {
34
- return readEnv("POSTHOG_WIZARD");
28
+ function toCommandModule(cmd, parentPath) {
29
+ return {
30
+ command: cmd.name,
31
+ describe: cmd.description,
32
+ builder: (y) => {
33
+ let next = cmd.options ? y.options(cmd.options) : y;
34
+ if (cmd.check) next = next.check(cmd.check);
35
+ for (const [usage, description] of cmd.examples ?? []) next = next.example(usage, description);
36
+ const ownPath = [...parentPath, commandKeys(cmd.name)[0]];
37
+ for (const child of cmd.children ?? []) next = next.command(toCommandModule(child, ownPath));
38
+ if (cmd.children?.length && !cmd.handler) next = next.demandCommand(1);
39
+ return next;
40
+ },
41
+ handler: cmd.handler ?? (() => void 0)
42
+ };
35
43
  }
36
44
  //#endregion
45
+ //#region src/wizard.ts
46
+ /**
47
+ * Global yargs options applied to every command. These are read from the
48
+ * `POSTHOG_WIZARD` env prefix as well as flags.
49
+ */
50
+ const GLOBAL_OPTIONS = {
51
+ debug: {
52
+ default: false,
53
+ describe: "Enable verbose logging\nenv: POSTHOG_WIZARD_DEBUG",
54
+ type: "boolean"
55
+ },
56
+ region: {
57
+ describe: "PostHog cloud region\nenv: POSTHOG_WIZARD_REGION",
58
+ choices: ["us", "eu"],
59
+ type: "string"
60
+ },
61
+ signup: {
62
+ default: false,
63
+ describe: "Create a new PostHog account during setup\nenv: POSTHOG_WIZARD_SIGNUP",
64
+ type: "boolean"
65
+ },
66
+ "local-mcp": {
67
+ default: false,
68
+ describe: "Use local MCP server at http://localhost:8787/mcp\nenv: POSTHOG_WIZARD_LOCAL_MCP",
69
+ type: "boolean"
70
+ },
71
+ telemetry: {
72
+ default: true,
73
+ describe: "Send wizard run state to PostHog (pass --no-telemetry to disable)\nenv: POSTHOG_WIZARD_TELEMETRY",
74
+ type: "boolean"
75
+ },
76
+ "api-key": {
77
+ describe: "PostHog personal API key (phx_xxx) for authentication\nenv: POSTHOG_WIZARD_API_KEY",
78
+ type: "string"
79
+ },
80
+ "project-id": {
81
+ describe: "PostHog project ID to use (optional; when not set, uses default from API key or OAuth)\nenv: POSTHOG_WIZARD_PROJECT_ID",
82
+ type: "string"
83
+ },
84
+ email: {
85
+ describe: "Email address for signup (used with --signup)\nenv: POSTHOG_WIZARD_EMAIL",
86
+ type: "string"
87
+ }
88
+ };
89
+ var Wizard = class Wizard {
90
+ cli;
91
+ constructor() {
92
+ let cli = yargs(hideBin(process.argv)).env("POSTHOG_WIZARD").options(GLOBAL_OPTIONS);
93
+ this.cli = cli.strictOptions().fail((msg, err, parser) => {
94
+ const text = msg || err && err.message || "Invalid arguments";
95
+ process.stderr.write(`\n\x1b[1;91m✖ ${text}\x1b[0m\n\n`);
96
+ parser.showHelp();
97
+ process.exit(1);
98
+ }).help().alias("help", "h").version().alias("version", "v");
99
+ }
100
+ /** Start a chain; equivalent to `new Wizard().use(...cmds)`. */
101
+ static use(...cmds) {
102
+ return new Wizard().use(...cmds);
103
+ }
104
+ /** Register one or more commands with yargs. */
105
+ use(...cmds) {
106
+ for (const cmd of cmds) this.cli = this.cli.command(toCommandModule(cmd, []));
107
+ return this;
108
+ }
109
+ /** Parse argv and dispatch to the matching registered command. */
110
+ init() {
111
+ {
112
+ const argvHasCI = process.argv.slice(2).some((a) => a === "--ci" || a === "--no-ci" || a.startsWith("--ci="));
113
+ const envHasCI = process.env.POSTHOG_WIZARD_CI != null && process.env.POSTHOG_WIZARD_CI !== "";
114
+ if (argvHasCI || envHasCI) {
115
+ process.stderr.write(`\n\x1b[1;91m✖ CI mode is not currently supported in published builds.\x1b[0m\n\n`);
116
+ process.exit(1);
117
+ }
118
+ }
119
+ this.cli.wrap(process.stdout.isTTY ? this.cli.terminalWidth() : 80).argv;
120
+ }
121
+ };
122
+ //#endregion
123
+ //#region src/commands/provision.ts
124
+ const provisionCommand = {
125
+ name: "provision",
126
+ description: "Create a new PostHog account (headless, no TUI)",
127
+ options: {
128
+ email: {
129
+ describe: "Email address for the new account",
130
+ type: "string",
131
+ demandOption: true
132
+ },
133
+ region: {
134
+ describe: "Cloud region (us or eu)",
135
+ choices: ["us", "eu"],
136
+ default: "us"
137
+ },
138
+ name: {
139
+ describe: "Name for the new account",
140
+ type: "string",
141
+ default: ""
142
+ },
143
+ json: {
144
+ describe: "Emit JSON result to stdout (defaults to true when stdout is not a TTY)",
145
+ type: "boolean"
146
+ }
147
+ },
148
+ examples: [["wizard provision --email matt+test@posthog.com --region us", ""], ["wizard provision --email user@example.com --region eu --json", ""]],
149
+ handler: runProvision
150
+ };
151
+ function runProvision(argv) {
152
+ const jsonMode = argv.json === void 0 ? !process.stdout.isTTY : Boolean(argv.json);
153
+ if (!jsonMode) setUI(new LoggingUI());
154
+ provision({
155
+ email: argv.email,
156
+ region: argv.region.toUpperCase(),
157
+ name: argv.name ?? "",
158
+ jsonMode
159
+ });
160
+ }
161
+ async function provision({ email, region, name, jsonMode }) {
162
+ try {
163
+ const { provisionNewAccount } = await import("./provisioning-BlBnlcFd.js");
164
+ if (!jsonMode) getUI().log.info(`Provisioning account for ${email} in ${region}...`);
165
+ emitResult(await provisionNewAccount(email, name, region), jsonMode);
166
+ process.exit(0);
167
+ } catch (error) {
168
+ emitError(error, jsonMode);
169
+ process.exit(1);
170
+ }
171
+ }
172
+ function emitResult(result, jsonMode) {
173
+ if (jsonMode) {
174
+ process.stdout.write(`${JSON.stringify(result)}\n`);
175
+ return;
176
+ }
177
+ getUI().log.success("Account provisioned successfully:");
178
+ getUI().log.info(` API Key: ${result.projectApiKey}`);
179
+ getUI().log.info(` Host: ${result.host}`);
180
+ getUI().log.info(` Project ID: ${result.projectId}`);
181
+ getUI().log.info(` Account ID: ${result.accountId}`);
182
+ getUI().log.info(` Access Token: ${result.accessToken}`);
183
+ getUI().log.info(` Refresh Token: ${result.refreshToken}`);
184
+ if (result.personalApiKey) getUI().log.info(` Personal API Key: ${result.personalApiKey}`);
185
+ }
186
+ function emitError(error, jsonMode) {
187
+ const msg = error instanceof Error ? error.message : String(error);
188
+ const code = msg.includes("already associated") ? "email_exists" : "provisioning_failed";
189
+ if (jsonMode) {
190
+ process.stderr.write(`${JSON.stringify({
191
+ error: msg,
192
+ code
193
+ })}\n`);
194
+ return;
195
+ }
196
+ getUI().log.error(`Provisioning failed: ${msg}`);
197
+ }
198
+ //#endregion
199
+ //#region src/commands/basic-integration/index.ts
200
+ const basicIntegrationCommand = {
201
+ name: ["$0"],
202
+ description: "Run the PostHog setup wizard",
203
+ children: [provisionCommand],
204
+ options: {
205
+ "install-dir": {
206
+ describe: "Directory to install PostHog in\nenv: POSTHOG_WIZARD_INSTALL_DIR",
207
+ type: "string"
208
+ },
209
+ playground: {
210
+ default: false,
211
+ describe: "Launch the TUI primitives playground",
212
+ type: "boolean"
213
+ },
214
+ benchmark: {
215
+ default: false,
216
+ describe: "Run in benchmark mode with per-phase token tracking\nenv: POSTHOG_WIZARD_BENCHMARK",
217
+ type: "boolean"
218
+ },
219
+ "yara-report": {
220
+ default: false,
221
+ describe: "Print YARA scanner summary after the agent run\nenv: POSTHOG_WIZARD_YARA_REPORT",
222
+ type: "boolean",
223
+ hidden: true
224
+ },
225
+ skill: {
226
+ describe: "Run a specific context-mill skill by ID\nenv: POSTHOG_WIZARD_SKILL",
227
+ type: "string"
228
+ },
229
+ name: {
230
+ describe: "Name for account creation with --ci --signup\nenv: POSTHOG_WIZARD_NAME",
231
+ type: "string"
232
+ }
233
+ },
234
+ check: (argv) => {
235
+ if (argv.playground && (argv.ci || argv.skill)) throw new Error("--playground cannot be combined with --ci or --skill.");
236
+ if (typeof argv.skill === "string" && argv.skill.trim() === "") throw new Error("--skill needs a skill ID, e.g. --skill=\"foo\"");
237
+ return true;
238
+ },
239
+ handler: (argv) => {
240
+ (async () => {
241
+ if (argv.ci && argv.skill) {
242
+ const { runSkillMode } = await import("./skill-CnOQAZXp.js");
243
+ return runSkillMode(argv);
244
+ }
245
+ if (argv.ci) {
246
+ const { runCIInstall } = await import("./ci-install-DD7WMmIF.js");
247
+ return runCIInstall(argv);
248
+ }
249
+ if (isNonInteractiveEnvironment()) {
250
+ const { failNonInteractive } = await import("./non-interactive-l2AKE3jD.js");
251
+ return failNonInteractive();
252
+ }
253
+ if (argv.playground) {
254
+ const { runPlayground } = await import("./playground-DlE5RNfE.js");
255
+ return runPlayground();
256
+ }
257
+ if (argv.skill) {
258
+ const { runSkillMode } = await import("./skill-CnOQAZXp.js");
259
+ return runSkillMode(argv);
260
+ }
261
+ const { runInteractive } = await import("./interactive-BaMAq88Q.js");
262
+ runInteractive(argv);
263
+ })();
264
+ }
265
+ };
266
+ //#endregion
37
267
  //#region src/lib/programs/revenue-analytics/detect.ts
38
268
  const POSTHOG_SDKS$1 = [
39
269
  "posthog-js",
@@ -297,7 +527,6 @@ const AGENT_SKILL_STEPS = [
297
527
  ];
298
528
  //#endregion
299
529
  //#region src/lib/programs/agent-skill/index.ts
300
- var agent_skill_exports = /* @__PURE__ */ __exportAll({ createSkillProgram: () => createSkillProgram });
301
530
  function createSkillProgram(opts) {
302
531
  return {
303
532
  command: opts.command,
@@ -334,7 +563,12 @@ const AUDIT_ABORT_CASES = [{
334
563
  }];
335
564
  //#endregion
336
565
  //#region src/lib/programs/audit/seed.ts
337
- /** The 10 data-integrity checks the audit runs. */
566
+ /**
567
+ * The 10 data-integrity checks the audit runs, plus one workflow row for the
568
+ * notebook upload at the end (so the skill's `audit_resolve_checks` call for
569
+ * `upload-notebook` succeeds — the skill writes the report to a PostHog
570
+ * notebook as its final step).
571
+ */
338
572
  const AUDIT_SEED_CHECKS = [
339
573
  {
340
574
  id: "sdk-installed",
@@ -395,15 +629,32 @@ const AUDIT_SEED_CHECKS = [
395
629
  area: "Event Capture",
396
630
  label: "Key activation events captured",
397
631
  status: "pending"
632
+ },
633
+ {
634
+ id: "write-report",
635
+ area: "Write report",
636
+ label: "Create posthog-audit-report.md",
637
+ status: "pending"
638
+ },
639
+ {
640
+ id: "upload-notebook",
641
+ area: "Upload notebook",
642
+ label: "Write the report into a PostHog notebook",
643
+ status: "pending"
398
644
  }
399
645
  ];
400
- /** Atomically write the seeded ledger to the project's audit checks file. */
401
- function seedAuditLedger(installDir) {
646
+ /**
647
+ * Atomically write a seeded ledger to the project's audit checks file.
648
+ *
649
+ * Each audit-flavored program (doctor, events-audit) owns its own seed
650
+ * shape — pass the seed in so this writer stays program-agnostic.
651
+ */
652
+ function seedAuditLedger(installDir, checks = AUDIT_SEED_CHECKS) {
402
653
  const target = path.join(installDir, AUDIT_CHECKS_FILE);
403
654
  const tmp = `${target}.tmp`;
404
- fs.writeFileSync(tmp, JSON.stringify(AUDIT_SEED_CHECKS, null, 2), "utf8");
655
+ fs.writeFileSync(tmp, JSON.stringify(checks, null, 2), "utf8");
405
656
  fs.renameSync(tmp, target);
406
- logToFile(`seedAuditLedger: wrote ${AUDIT_SEED_CHECKS.length} entries to ${target}`);
657
+ logToFile(`seedAuditLedger: wrote ${checks.length} entries to ${target}`);
407
658
  }
408
659
  //#endregion
409
660
  //#region src/lib/programs/audit/index.ts
@@ -443,7 +694,23 @@ const baseConfig$1 = createSkillProgram({
443
694
  const auditRun = async (session) => {
444
695
  seedBeforeAuditRun(session);
445
696
  if (!baseConfig$1.run) throw new Error("Audit program has no run configuration.");
446
- return typeof baseConfig$1.run === "function" ? baseConfig$1.run(session) : baseConfig$1.run;
697
+ const baseRun = typeof baseConfig$1.run === "function" ? await baseConfig$1.run(session) : baseConfig$1.run;
698
+ return {
699
+ ...baseRun,
700
+ buildOutroData: (sess, _credentials, cloudRegion) => {
701
+ const cloudUrl = cloudRegion ? getCloudUrlFromRegion(cloudRegion) : void 0;
702
+ const continueUrl = sess.signup && cloudUrl ? `${cloudUrl}/products?source=wizard` : void 0;
703
+ return {
704
+ kind: "success",
705
+ message: baseRun.successMessage,
706
+ reportFile: baseRun.reportFile,
707
+ docsUrl: baseRun.docsUrl,
708
+ continueUrl,
709
+ dashboardUrl: sess.dashboardUrl ?? void 0,
710
+ notebookUrl: sess.notebookUrl ?? void 0
711
+ };
712
+ }
713
+ };
447
714
  };
448
715
  const auditConfig = {
449
716
  ...baseConfig$1,
@@ -505,6 +772,62 @@ const EVENTS_AUDIT_PROGRAM = [
505
772
  }
506
773
  ];
507
774
  //#endregion
775
+ //#region src/lib/programs/events-audit/seed.ts
776
+ /**
777
+ * The 7 phases the events-audit skill marches through. One check per area
778
+ * so PendingChecksList renders a clean linear pipeline (area = bold header,
779
+ * single row = the active spinner).
780
+ *
781
+ * Phase ids match what the skill's step files resolve via
782
+ * `mcp__wizard-tools__audit_resolve_checks` as each phase completes. The
783
+ * skill's step 1 also seeds these same ids — keep both in sync so the
784
+ * wizard pre-seed and the skill's MCP seed agree.
785
+ */
786
+ const EVENTS_AUDIT_SEED_CHECKS = [
787
+ {
788
+ id: "detect-sdk",
789
+ area: "Detect SDK",
790
+ label: "Identify PostHog SDK(s) in dependencies",
791
+ status: "pending"
792
+ },
793
+ {
794
+ id: "scan-sites",
795
+ area: "Scan capture sites",
796
+ label: "Grep capture/identify/group call sites",
797
+ status: "pending"
798
+ },
799
+ {
800
+ id: "enrich-sites",
801
+ area: "Enrich",
802
+ label: "Subagent fan-out to read capture files",
803
+ status: "pending"
804
+ },
805
+ {
806
+ id: "query-volume",
807
+ area: "Query PostHog",
808
+ label: "30-day volume + last_seen via MCP",
809
+ status: "pending"
810
+ },
811
+ {
812
+ id: "write-report",
813
+ area: "Write report",
814
+ label: "Create posthog-events-audit-report.md",
815
+ status: "pending"
816
+ },
817
+ {
818
+ id: "create-dashboard",
819
+ area: "Create dashboard",
820
+ label: "Optional: dashboard for resolved events",
821
+ status: "pending"
822
+ },
823
+ {
824
+ id: "upload-notebook",
825
+ area: "Upload notebook",
826
+ label: "Write the report into a PostHog notebook",
827
+ status: "pending"
828
+ }
829
+ ];
830
+ //#endregion
508
831
  //#region src/lib/programs/events-audit/index.ts
509
832
  const SETUP_REPORT_FILE = "posthog-events-audit-report.md";
510
833
  const DOCS_URL$1 = "https://posthog.com/docs/product-analytics/best-practices";
@@ -520,8 +843,8 @@ const eventsAuditConfig = {
520
843
  run: (session) => {
521
844
  const typeScriptDetected = isUsingTypeScript({ installDir: session.installDir });
522
845
  session.typescript = typeScriptDetected;
523
- seedAuditLedger(session.installDir);
524
- session.frameworkContext[AUDIT_CHECKS_KEY] = AUDIT_SEED_CHECKS;
846
+ seedAuditLedger(session.installDir, EVENTS_AUDIT_SEED_CHECKS);
847
+ session.frameworkContext[AUDIT_CHECKS_KEY] = EVENTS_AUDIT_SEED_CHECKS;
525
848
  return Promise.resolve({
526
849
  skillId: "events-audit",
527
850
  integrationLabel: "events-audit",
@@ -549,7 +872,8 @@ Project context:
549
872
  changes: [],
550
873
  docsUrl: DOCS_URL$1,
551
874
  continueUrl: sess.signup && cloudUrl ? `${cloudUrl}/products?source=wizard` : void 0,
552
- dashboardUrl: sess.dashboardUrl ?? (cloudUrl ? `${cloudUrl}/dashboard` : void 0)
875
+ dashboardUrl: sess.dashboardUrl ?? (cloudUrl ? `${cloudUrl}/dashboard` : void 0),
876
+ notebookUrl: sess.notebookUrl ?? void 0
553
877
  };
554
878
  }
555
879
  });
@@ -1873,15 +2197,23 @@ const withPace = (block) => {
1873
2197
  };
1874
2198
  /** Apply the dwell multiplier to every block in a deck. */
1875
2199
  const pace = (blocks) => blocks.map(withPace);
1876
- /** A minified production stack trace — the problem source maps solve. */
2200
+ /**
2201
+ * A minified production stack trace — the problem source maps solve. Framed as
2202
+ * a labelled, muted example (no error-red ✘) so a glance reads it as
2203
+ * illustrative content, not as the wizard itself having errored mid-run.
2204
+ */
1877
2205
  const MINIFIED_TRACE = {
1878
2206
  type: "lines",
1879
2207
  interval: 400,
1880
2208
  pause: 7e3,
1881
2209
  lines: [
1882
2210
  /* @__PURE__ */ jsx(Text, {
1883
- color: Colors.error,
1884
- children: " TypeError: cart is undefined"
2211
+ dimColor: true,
2212
+ children: "example minified production trace"
2213
+ }),
2214
+ /* @__PURE__ */ jsx(Text, {
2215
+ color: Colors.muted,
2216
+ children: " TypeError: cart is undefined"
1885
2217
  }),
1886
2218
  /* @__PURE__ */ jsx(Text, {
1887
2219
  dimColor: true,
@@ -1903,9 +2235,13 @@ const RESOLVED_TRACE = {
1903
2235
  interval: 400,
1904
2236
  pause: 8e3,
1905
2237
  lines: [
2238
+ /* @__PURE__ */ jsx(Text, {
2239
+ dimColor: true,
2240
+ children: "example — resolved with source maps"
2241
+ }),
1906
2242
  /* @__PURE__ */ jsx(Text, {
1907
2243
  color: Colors.success,
1908
- children: "✔ TypeError: cart is undefined"
2244
+ children: " ✔ TypeError: cart is undefined"
1909
2245
  }),
1910
2246
  /* @__PURE__ */ jsxs(Text, { children: [
1911
2247
  /* @__PURE__ */ jsx(Text, {
@@ -2164,7 +2500,7 @@ const getContentBlocks = (store) => pace([
2164
2500
  const REPORT_FILE = "posthog-source-maps-report.md";
2165
2501
  const DOCS_URL = "https://posthog.com/docs/error-tracking/upload-source-maps";
2166
2502
  const errorTrackingUploadSourceMapsConfig = {
2167
- command: "upload-sourcemaps",
2503
+ command: "upload-source-maps",
2168
2504
  description: "Upload source maps to PostHog Error Tracking",
2169
2505
  id: "error-tracking-upload-source-maps",
2170
2506
  steps: ERROR_TRACKING_UPLOAD_SOURCE_MAPS_PROGRAM,
@@ -2221,8 +2557,28 @@ const mcpAddConfig = {
2221
2557
  label: "Add MCP server",
2222
2558
  screenId: "mcp-add",
2223
2559
  isComplete: (s) => s.mcpComplete
2560
+ }, {
2561
+ id: "mcp-suggested-prompts",
2562
+ label: "Suggested prompts",
2563
+ screenId: "mcp-suggested-prompts",
2564
+ show: (s) => s.mcpOutcome === "installed",
2565
+ isComplete: (s) => s.mcpSuggestedPromptsDismissed
2224
2566
  }]
2225
2567
  };
2568
+ /**
2569
+ * `wizard mcp remove` — single-step uninstall flow.
2570
+ *
2571
+ * DO NOT append `mcp-suggested-prompts` (or any other tutorial-shaped
2572
+ * step) here. A user who just removed MCP is opting OUT of the agent
2573
+ * having access to PostHog; immediately pivoting into a tutorial that
2574
+ * asks them to log in and try prompts is wrong on intent and confusing
2575
+ * on UX. The screen also reads `session.mcpInstalledClients` for its
2576
+ * Choose-phase copy ("MCP is installed for X") — that array is empty
2577
+ * post-remove, so the copy would be a lie.
2578
+ *
2579
+ * If you want a "did you mean to keep it?" confirmation, build that as
2580
+ * a screen earlier in this program — don't reuse the tutorial.
2581
+ */
2226
2582
  const mcpRemoveConfig = {
2227
2583
  id: "mcp-remove",
2228
2584
  description: "Remove PostHog MCP server from supported clients",
@@ -2233,6 +2589,26 @@ const mcpRemoveConfig = {
2233
2589
  isComplete: (s) => s.mcpComplete
2234
2590
  }]
2235
2591
  };
2592
+ /**
2593
+ * Standalone tutorial flow — boots directly into the Choose phase of
2594
+ * McpSuggestedPromptsScreen without going through MCP install first.
2595
+ * Useful for users who already installed MCP and want to revisit the
2596
+ * tutorial, or anyone who just wants to try the agent against PostHog
2597
+ * without touching their IDE config.
2598
+ *
2599
+ * The screen handles its own OAuth (via services.performLogin) so this
2600
+ * program doesn't pre-populate credentials.
2601
+ */
2602
+ const mcpTutorialConfig = {
2603
+ id: "mcp-tutorial",
2604
+ description: "Try the PostHog MCP with your agent — no install needed",
2605
+ steps: [{
2606
+ id: "mcp-suggested-prompts",
2607
+ label: "MCP tutorial",
2608
+ screenId: "mcp-suggested-prompts",
2609
+ isComplete: (s) => s.mcpSuggestedPromptsDismissed
2610
+ }]
2611
+ };
2236
2612
  //#endregion
2237
2613
  //#region src/lib/programs/program-registry.ts
2238
2614
  const agentSkillConfig = {
@@ -2253,7 +2629,8 @@ const PROGRAM_REGISTRY = [
2253
2629
  migrationConfig,
2254
2630
  agentSkillConfig,
2255
2631
  mcpAddConfig,
2256
- mcpRemoveConfig
2632
+ mcpRemoveConfig,
2633
+ mcpTutorialConfig
2257
2634
  ];
2258
2635
  /**
2259
2636
  * Typed program names. Values come from each config's `id`, so there's
@@ -2271,7 +2648,8 @@ const Program = {
2271
2648
  PosthogDoctor: posthogDoctorConfig.id,
2272
2649
  AgentSkill: agentSkillConfig.id,
2273
2650
  McpAdd: mcpAddConfig.id,
2274
- McpRemove: mcpRemoveConfig.id
2651
+ McpRemove: mcpRemoveConfig.id,
2652
+ McpTutorial: mcpTutorialConfig.id
2275
2653
  };
2276
2654
  /**
2277
2655
  * Look up a program config by its id. `ProgramId` is a union of every
@@ -2281,432 +2659,150 @@ const Program = {
2281
2659
  function getProgramConfig(id) {
2282
2660
  return PROGRAM_REGISTRY.find((c) => c.id === id);
2283
2661
  }
2284
- /** All program configs that are exposed as CLI subcommands. */
2285
- function getSubcommandPrograms() {
2286
- return PROGRAM_REGISTRY.filter((c) => c.command != null);
2287
- }
2288
2662
  //#endregion
2289
- //#region bin.ts
2290
- const MIN_NODE_VERSION = ">=18.17.0";
2291
- if (!satisfies(process.version, MIN_NODE_VERSION)) {
2292
- console.log(`PostHog wizard needs Node.js ${MIN_NODE_VERSION}. Detected ${process.version} — please upgrade Node and re-run.`);
2293
- process.exit(1);
2294
- }
2295
- const WIZARD_VERSION = VERSION;
2296
- /** Shared yargs options for skill-based program subcommands. */
2297
- const skillSubcommandOptions = {
2298
- debug: {
2299
- default: false,
2300
- describe: "Enable verbose logging",
2301
- type: "boolean"
2302
- },
2303
- "install-dir": {
2304
- describe: "Directory to install in",
2305
- type: "string"
2306
- },
2307
- "local-mcp": {
2308
- default: false,
2309
- describe: "Use local MCP server",
2310
- type: "boolean"
2311
- },
2312
- benchmark: {
2313
- default: false,
2314
- describe: "Run in benchmark mode",
2315
- type: "boolean"
2316
- },
2317
- "yara-report": {
2318
- default: false,
2319
- describe: "Print YARA scanner summary",
2320
- type: "boolean",
2321
- hidden: true
2322
- }
2323
- };
2324
- const cli = yargs(hideBin(process.argv)).env("POSTHOG_WIZARD").options({
2325
- debug: {
2326
- default: false,
2327
- describe: "Enable verbose logging\nenv: POSTHOG_WIZARD_DEBUG",
2328
- type: "boolean"
2329
- },
2330
- region: {
2331
- describe: "PostHog cloud region\nenv: POSTHOG_WIZARD_REGION",
2332
- choices: ["us", "eu"],
2333
- type: "string"
2334
- },
2335
- default: {
2336
- default: true,
2337
- describe: "Use default options for all prompts\nenv: POSTHOG_WIZARD_DEFAULT",
2338
- type: "boolean"
2339
- },
2340
- signup: {
2341
- default: false,
2342
- describe: "Create a new PostHog account during setup\nenv: POSTHOG_WIZARD_SIGNUP",
2343
- type: "boolean"
2344
- },
2345
- "local-mcp": {
2346
- default: false,
2347
- describe: "Use local MCP server at http://localhost:8787/mcp\nenv: POSTHOG_WIZARD_LOCAL_MCP",
2348
- type: "boolean"
2349
- },
2350
- "api-key": {
2351
- describe: "PostHog personal API key (phx_xxx) for authentication\nenv: POSTHOG_WIZARD_API_KEY",
2352
- type: "string"
2353
- },
2354
- "project-id": {
2355
- describe: "PostHog project ID to use (optional; when not set, uses default from API key or OAuth)\nenv: POSTHOG_WIZARD_PROJECT_ID",
2356
- type: "string"
2357
- },
2358
- email: {
2359
- describe: "Email address for signup (used with --signup)\nenv: POSTHOG_WIZARD_EMAIL",
2360
- type: "string"
2361
- },
2362
- telemetry: {
2363
- default: true,
2364
- describe: "Send wizard run state to PostHog (pass --no-telemetry to disable)\nenv: POSTHOG_WIZARD_TELEMETRY",
2365
- type: "boolean"
2366
- }
2367
- }).command(["$0"], "Run the PostHog setup wizard", (yargs) => {
2368
- return yargs.options({
2369
- "force-install": {
2663
+ //#region src/commands/mcp/add.ts
2664
+ const mcpAddCommand = {
2665
+ name: "add",
2666
+ description: "Install PostHog MCP server to supported clients",
2667
+ options: {
2668
+ local: {
2370
2669
  default: false,
2371
- describe: "Force install packages even if peer dependency checks fail\nenv: POSTHOG_WIZARD_FORCE_INSTALL",
2670
+ describe: "Add local development MCP server (http://localhost:8787)",
2372
2671
  type: "boolean"
2373
2672
  },
2374
- "install-dir": {
2375
- describe: "Directory to install PostHog in\nenv: POSTHOG_WIZARD_INSTALL_DIR",
2673
+ features: {
2674
+ describe: "Comma-separated list of features to enable (default: all)",
2376
2675
  type: "string"
2377
2676
  },
2378
- playground: {
2379
- default: false,
2380
- describe: "Launch the TUI primitives playground",
2381
- type: "boolean"
2382
- },
2383
- integration: {
2384
- describe: "Integration to set up",
2385
- choices: [
2386
- "nextjs",
2387
- "astro",
2388
- "react",
2389
- "svelte",
2390
- "react-native",
2391
- "tanstack-router",
2392
- "tanstack-start"
2393
- ],
2677
+ "api-key": {
2678
+ describe: "PostHog personal API key (phx_xxx) for MCP authentication",
2394
2679
  type: "string"
2395
- },
2396
- menu: {
2397
- default: false,
2398
- describe: "Show menu for manual integration selection instead of auto-detecting\nenv: POSTHOG_WIZARD_MENU",
2399
- type: "boolean"
2400
- },
2401
- benchmark: {
2402
- default: false,
2403
- describe: "Run in benchmark mode with per-phase token tracking\nenv: POSTHOG_WIZARD_BENCHMARK",
2404
- type: "boolean"
2405
- },
2406
- "yara-report": {
2407
- default: false,
2408
- describe: "Print YARA scanner summary after the agent run\nenv: POSTHOG_WIZARD_YARA_REPORT",
2409
- type: "boolean",
2410
- hidden: true
2411
- },
2412
- skill: {
2413
- describe: "Run a specific context-mill skill by ID\nenv: POSTHOG_WIZARD_SKILL",
2414
- type: "string"
2415
- },
2416
- name: {
2417
- describe: "Name for account creation with --ci --signup\nenv: POSTHOG_WIZARD_NAME",
2418
- type: "string"
2419
- }
2420
- });
2421
- }, (argv) => {
2422
- const options = { ...argv };
2423
- if (options.ci) {
2424
- if (!options.region) options.region = "us";
2425
- if (!options.installDir) {
2426
- setUI(new LoggingUI());
2427
- getUI().intro("PostHog Wizard");
2428
- getUI().log.error("CI mode requires --install-dir (directory to install in)");
2429
- process.exit(1);
2430
- return;
2431
2680
  }
2432
- if (!options.apiKey && !options.signup) {
2681
+ },
2682
+ handler: runMcpAdd
2683
+ };
2684
+ function runMcpAdd(argv) {
2685
+ const features = parseFeatures(argv.features);
2686
+ (async () => {
2687
+ const { readApiKeyFromEnv } = await import("./env-api-key-DEl3LJBv.js").then((n) => n.t);
2688
+ const apiKey = argv.apiKey || readApiKeyFromEnv();
2689
+ const debug = argv.debug;
2690
+ const localMcp = argv.local;
2691
+ try {
2692
+ const { startTUI } = await import("./start-tui-DXrv6cof.js");
2693
+ const { buildSession } = await import("./wizard-session-7tMjgOvP.js");
2694
+ const tui = startTUI(VERSION, Program.McpAdd);
2695
+ tui.store.session = buildSession({
2696
+ debug,
2697
+ localMcp,
2698
+ mcpFeatures: features,
2699
+ apiKey
2700
+ });
2701
+ } catch (error) {
2702
+ if (!isTUIUnavailable(error)) throw error;
2433
2703
  setUI(new LoggingUI());
2434
- getUI().intro("PostHog Wizard");
2435
- getUI().log.error("CI mode requires --api-key (personal API key phx_xxx). To create a new account instead, use --signup --email you@example.com.");
2436
- process.exit(1);
2437
- return;
2704
+ const { addMCPServerToClientsStep } = await import("./add-mcp-server-to-clients-BS6Rjcwh.js").then((n) => n.r);
2705
+ await addMCPServerToClientsStep({
2706
+ local: localMcp,
2707
+ features,
2708
+ apiKey
2709
+ });
2438
2710
  }
2439
- if (!options.apiKey && options.signup && !options.email) {
2711
+ })();
2712
+ }
2713
+ /**
2714
+ * Ink throws "Raw mode is not supported" when stdin has no TTY (piped input,
2715
+ * CI, some IDE terminals). That is the only TUI failure we degrade to
2716
+ * LoggingUI for — any other error from the TUI path is a real bug and must
2717
+ * surface rather than be silently swallowed.
2718
+ */
2719
+ function isTUIUnavailable(error) {
2720
+ return error instanceof Error && /raw mode is not supported/i.test(error.message);
2721
+ }
2722
+ function parseFeatures(raw) {
2723
+ if (typeof raw !== "string") return void 0;
2724
+ return raw.split(",").map((s) => s.trim()).filter(Boolean);
2725
+ }
2726
+ //#endregion
2727
+ //#region src/commands/mcp/remove.ts
2728
+ const mcpRemoveCommand = {
2729
+ name: "remove",
2730
+ description: "Remove PostHog MCP server from supported clients",
2731
+ options: { local: {
2732
+ default: false,
2733
+ describe: "Remove local development MCP server (http://localhost:8787)",
2734
+ type: "boolean"
2735
+ } },
2736
+ handler: runMcpRemove
2737
+ };
2738
+ function runMcpRemove(argv) {
2739
+ (async () => {
2740
+ const debug = argv.debug;
2741
+ const localMcp = argv.local;
2742
+ try {
2743
+ const { startTUI } = await import("./start-tui-DXrv6cof.js");
2744
+ const { buildSession } = await import("./wizard-session-7tMjgOvP.js");
2745
+ const tui = startTUI(VERSION, Program.McpRemove);
2746
+ tui.store.session = buildSession({
2747
+ debug,
2748
+ localMcp
2749
+ });
2750
+ } catch {
2440
2751
  setUI(new LoggingUI());
2441
- getUI().intro("PostHog Wizard");
2442
- getUI().log.error("CI --signup requires --email to create a new account.");
2443
- process.exit(1);
2444
- return;
2445
- }
2446
- if (options.apiKey) {
2447
- const apiKeyValue = String(options.apiKey);
2448
- if (!apiKeyValue.startsWith("phx_")) {
2449
- setUI(new LoggingUI());
2450
- getUI().intro("PostHog Wizard");
2451
- const prefix = apiKeyValue.slice(0, 4);
2452
- let hint = "";
2453
- if (prefix === "pha_") hint = " (pha_ is an OAuth access token — CI mode expects a personal API key)";
2454
- else if (prefix === "phc_") hint = " (phc_ is a project/client key — CI mode expects a personal API key)";
2455
- getUI().log.warn(`--api-key does not start with "phx_"${hint}. Continuing anyway, but the LLM Gateway may reject it with a 401.`);
2456
- }
2752
+ const { removeMCPServerFromClientsStep } = await import("./add-mcp-server-to-clients-BS6Rjcwh.js").then((n) => n.r);
2753
+ await removeMCPServerFromClientsStep({ local: localMcp });
2457
2754
  }
2458
- (async () => {
2459
- if (!options.apiKey && options.signup) {
2460
- setUI(new LoggingUI());
2461
- getUI().intro("PostHog Wizard");
2462
- try {
2463
- const { provisionNewAccount } = await import("./provisioning-COeHnCVG.js");
2464
- const signupRegion = options.region.toUpperCase();
2465
- getUI().log.info(`Provisioning new PostHog account for ${String(options.email)} in ${signupRegion}...`);
2466
- const result = await provisionNewAccount(options.email, options.name ?? "", signupRegion);
2467
- if (!result.personalApiKey) {
2468
- getUI().log.error("Provisioning succeeded but no personal API key was returned — cannot continue install.");
2469
- process.exit(1);
2470
- return;
2471
- }
2472
- getUI().log.success("Account ready.");
2473
- getUI().log.info(` Project API Key: ${result.projectApiKey}`);
2474
- getUI().log.info(` Personal API Key: ${result.personalApiKey}`);
2475
- getUI().log.info(` Host: ${result.host}`);
2476
- options.apiKey = result.personalApiKey;
2477
- if (options.projectId == null) options.projectId = result.projectId;
2478
- } catch (error) {
2479
- const msg = error instanceof Error ? error.message : String(error);
2480
- getUI().log.error(`Provisioning failed: ${msg}`);
2481
- process.exit(1);
2482
- return;
2483
- }
2484
- }
2485
- const { posthogIntegrationConfig } = await import("./posthog-integration-D-DyEJvz.js").then((n) => n.r);
2486
- const { FRAMEWORK_REGISTRY } = await import("./registry-CofBzIdU.js").then((n) => n.n);
2487
- const { detectFramework, gatherFrameworkContext } = await import("./detection-0Pz2NncX.js").then((n) => n.t);
2488
- const { analytics } = await import("./analytics-BnR9904x.js");
2489
- const { wizardAbort } = await import("./wizard-abort-CuaS1eXn.js");
2490
- runWizardCI(posthogIntegrationConfig, options, async (session) => {
2491
- const integration = session.integration ?? await detectFramework(session.installDir);
2492
- if (!integration) {
2493
- await wizardAbort({ message: "Could not auto-detect your framework. Please specify --integration on the command line." });
2494
- return;
2495
- }
2496
- session.integration = integration;
2497
- analytics.setTag("integration", integration);
2498
- const frameworkConfig = FRAMEWORK_REGISTRY[integration];
2499
- session.frameworkConfig = frameworkConfig;
2500
- const context = await gatherFrameworkContext(frameworkConfig, {
2501
- installDir: session.installDir,
2502
- debug: session.debug,
2503
- forceInstall: session.forceInstall,
2504
- default: false,
2505
- signup: session.signup,
2506
- localMcp: session.localMcp,
2507
- ci: true,
2508
- menu: session.menu,
2509
- benchmark: session.benchmark,
2510
- yaraReport: session.yaraReport
2511
- });
2512
- for (const [key, value] of Object.entries(context)) if (!(key in session.frameworkContext)) session.frameworkContext[key] = value;
2513
- });
2514
- })().catch(() => {
2515
- process.exit(1);
2516
- });
2517
- } else if (isNonInteractiveEnvironment()) {
2518
- getUI().intro(`PostHog Wizard`);
2519
- getUI().log.error("This installer requires an interactive terminal (TTY) to run.\nIt appears you are running in a non-interactive environment.\n\nNon-interactive (CI) mode is not supported in published builds.\n");
2520
- process.exit(1);
2521
- } else if (options.playground) (async () => {
2522
- const { startPlayground } = await import("./start-playground-Bxd2KG2L.js");
2523
- startPlayground(WIZARD_VERSION);
2524
- })();
2525
- else if (options.skill) (async () => {
2526
- const { createSkillProgram } = await Promise.resolve().then(() => agent_skill_exports);
2527
- const skillId = options.skill;
2528
- runWizard(createSkillProgram({
2529
- skillId,
2530
- command: "skill",
2531
- id: "agent-skill",
2532
- description: `Run skill: ${skillId}`,
2533
- integrationLabel: skillId,
2534
- successMessage: `${skillId} completed!`,
2535
- reportFile: `posthog-${skillId}-report.md`,
2536
- docsUrl: POSTHOG_DOCS_URL,
2537
- spinnerMessage: `Running ${skillId}...`,
2538
- estimatedDurationMinutes: 5
2539
- }), {
2540
- ...options,
2541
- skillId
2542
- });
2543
- })();
2544
- else (async () => {
2545
- const { posthogIntegrationConfig } = await import("./posthog-integration-D-DyEJvz.js").then((n) => n.r);
2546
- runWizard(posthogIntegrationConfig, options);
2547
2755
  })();
2548
- }).command("mcp <command>", "MCP server management commands", (yargs) => {
2549
- return yargs.command("add", "Install PostHog MCP server to supported clients", (yargs) => {
2550
- return yargs.options({
2551
- local: {
2552
- default: false,
2553
- describe: "Add local development MCP server (http://localhost:8787)",
2554
- type: "boolean"
2555
- },
2556
- features: {
2557
- describe: "Comma-separated list of features to enable (default: all)",
2558
- type: "string"
2559
- },
2560
- "api-key": {
2561
- describe: "PostHog personal API key (phx_xxx) for MCP authentication",
2562
- type: "string"
2563
- }
2564
- });
2565
- }, (argv) => {
2566
- const options = { ...argv };
2567
- const mcpFeatures = options.features?.split(",").map((s) => s.trim()).filter(Boolean);
2568
- (async () => {
2569
- const { readApiKeyFromEnv } = await import("./env-api-key-HFqv1l-z.js");
2570
- const apiKey = options.apiKey || readApiKeyFromEnv();
2571
- try {
2572
- const { startTUI } = await import("./start-tui-Bl8fCbp_.js");
2573
- const { buildSession } = await import("./wizard-session-DxU5ZMBN.js");
2574
- const tui = startTUI(WIZARD_VERSION, Program.McpAdd);
2575
- const session = buildSession({
2576
- debug: options.debug,
2577
- localMcp: options.local,
2578
- mcpFeatures,
2579
- apiKey
2580
- });
2581
- tui.store.session = session;
2582
- } catch {
2583
- setUI(new LoggingUI());
2584
- const { addMCPServerToClientsStep } = await import("./add-mcp-server-to-clients-Dq0n2yzq.js").then((n) => n.r);
2585
- await addMCPServerToClientsStep({
2586
- local: options.local,
2587
- features: mcpFeatures,
2588
- apiKey
2589
- });
2590
- }
2591
- })();
2592
- }).command("remove", "Remove PostHog MCP server from supported clients", (yargs) => {
2593
- return yargs.options({ local: {
2594
- default: false,
2595
- describe: "Remove local development MCP server (http://localhost:8787)",
2596
- type: "boolean"
2597
- } });
2598
- }, (argv) => {
2599
- const options = { ...argv };
2600
- (async () => {
2601
- try {
2602
- const { startTUI } = await import("./start-tui-Bl8fCbp_.js");
2603
- const { buildSession } = await import("./wizard-session-DxU5ZMBN.js");
2604
- const tui = startTUI(WIZARD_VERSION, Program.McpRemove);
2605
- const session = buildSession({
2606
- debug: options.debug,
2607
- localMcp: options.local
2608
- });
2609
- tui.store.session = session;
2610
- } catch {
2611
- setUI(new LoggingUI());
2612
- const { removeMCPServerFromClientsStep } = await import("./add-mcp-server-to-clients-Dq0n2yzq.js").then((n) => n.r);
2613
- await removeMCPServerFromClientsStep({ local: options.local });
2614
- }
2615
- })();
2616
- }).demandCommand(1, "You must specify a subcommand (add or remove)").help();
2617
- });
2618
- cli.command("provision", "Create a new PostHog account (headless, no TUI)", (yargs) => {
2619
- return yargs.options({
2620
- email: {
2621
- describe: "Email address for the new account",
2622
- type: "string",
2623
- demandOption: true
2624
- },
2625
- region: {
2626
- describe: "Cloud region (us or eu)",
2627
- choices: ["us", "eu"],
2628
- default: "us"
2629
- },
2630
- name: {
2631
- describe: "Name for the new account",
2632
- type: "string",
2633
- default: ""
2634
- },
2635
- json: {
2636
- describe: "Emit JSON result to stdout (defaults to true when stdout is not a TTY)",
2637
- type: "boolean"
2638
- }
2639
- }).example("wizard provision --email matt+test@posthog.com --region us", "").example("wizard provision --email user@example.com --region eu --json", "");
2640
- }, (argv) => {
2641
- const email = argv.email;
2642
- const region = argv.region.toUpperCase();
2643
- const name = argv.name ?? "";
2644
- const jsonMode = argv.json === void 0 ? !process.stdout.isTTY : argv.json;
2645
- if (!jsonMode) setUI(new LoggingUI());
2756
+ }
2757
+ //#endregion
2758
+ //#region src/commands/mcp/tutorial.ts
2759
+ const mcpTutorialCommand = {
2760
+ name: "tutorial",
2761
+ description: "Try the PostHog MCP with your agent (no install needed)",
2762
+ options: { local: {
2763
+ default: false,
2764
+ describe: "Point the tutorial at the local MCP server (http://localhost:8787)",
2765
+ type: "boolean"
2766
+ } },
2767
+ handler: runMcpTutorial
2768
+ };
2769
+ function runMcpTutorial(argv) {
2646
2770
  (async () => {
2771
+ const debug = argv.debug;
2772
+ const localMcp = argv.local;
2647
2773
  try {
2648
- const { provisionNewAccount } = await import("./provisioning-COeHnCVG.js");
2649
- if (!jsonMode) getUI().log.info(`Provisioning account for ${email} in ${region}...`);
2650
- const result = await provisionNewAccount(email, name, region);
2651
- if (jsonMode) process.stdout.write(`${JSON.stringify(result)}\n`);
2652
- else {
2653
- getUI().log.success("Account provisioned successfully:");
2654
- getUI().log.info(` API Key: ${result.projectApiKey}`);
2655
- getUI().log.info(` Host: ${result.host}`);
2656
- getUI().log.info(` Project ID: ${result.projectId}`);
2657
- getUI().log.info(` Account ID: ${result.accountId}`);
2658
- getUI().log.info(` Access Token: ${result.accessToken}`);
2659
- getUI().log.info(` Refresh Token: ${result.refreshToken}`);
2660
- if (result.personalApiKey) getUI().log.info(` Personal API Key: ${result.personalApiKey}`);
2661
- }
2662
- process.exit(0);
2663
- } catch (error) {
2664
- const msg = error instanceof Error ? error.message : String(error);
2665
- const code = msg.includes("already associated") ? "email_exists" : "provisioning_failed";
2666
- if (jsonMode) process.stderr.write(`${JSON.stringify({
2667
- error: msg,
2668
- code
2669
- })}\n`);
2670
- else getUI().log.error(`Provisioning failed: ${msg}`);
2774
+ const { startTUI } = await import("./start-tui-DXrv6cof.js");
2775
+ const { buildSession } = await import("./wizard-session-7tMjgOvP.js");
2776
+ const tui = startTUI(VERSION, Program.McpTutorial);
2777
+ tui.store.session = buildSession({
2778
+ debug,
2779
+ localMcp
2780
+ });
2781
+ } catch (err) {
2782
+ setUI(new LoggingUI());
2783
+ getUI().log.error(`The MCP tutorial requires an interactive terminal. ${err instanceof Error ? err.message : String(err)}`);
2671
2784
  process.exit(1);
2672
2785
  }
2673
2786
  })();
2674
- });
2675
- for (const programConfig of getSubcommandPrograms()) cli.command(programConfig.command, programConfig.description, (y) => y.options({
2676
- ...skillSubcommandOptions,
2677
- ...programConfig.cliOptions ?? {}
2678
- }), (argv) => {
2679
- const extras = programConfig.mapCliOptions?.(argv) ?? {};
2680
- const options = {
2681
- ...argv,
2682
- ...extras
2683
- };
2684
- if (options.ci) runWizardCI(programConfig, options);
2685
- else runWizard(programConfig, options);
2686
- });
2687
- cli.strictOptions().fail((msg, err) => {
2688
- throw err || new Error(msg);
2689
- }).help().alias("help", "h").version().alias("version", "v").wrap(process.stdout.isTTY ? cli.terminalWidth() : 80);
2690
- {
2691
- const argvHasCI = process.argv.slice(2).some((a) => a === "--ci" || a === "--no-ci" || a.startsWith("--ci="));
2692
- const envHasCI = process.env.POSTHOG_WIZARD_CI != null && process.env.POSTHOG_WIZARD_CI !== "";
2693
- if (argvHasCI || envHasCI) exitWithProductionCIError();
2694
- }
2695
- try {
2696
- cli.parse();
2697
- } catch (err) {
2698
- const RED = "\x1B[31m";
2699
- const BOLD = "\x1B[1m";
2700
- const RESET = "\x1B[0m";
2701
- const message = err instanceof Error ? err.message : String(err);
2702
- process.stderr.write(`${RED}${BOLD}✖ ${message}${RESET}\n`);
2703
- process.stderr.write("Run with --help to see available options.\n");
2704
- process.exit(1);
2705
- }
2706
- function exitWithProductionCIError() {
2707
- process.stderr.write(`✖ CI mode is not currently supported in published builds.\n`);
2708
- process.exit(1);
2709
2787
  }
2788
+ //#endregion
2789
+ //#region src/commands/mcp/index.ts
2790
+ const mcpCommand = {
2791
+ name: "mcp",
2792
+ description: "MCP server management commands",
2793
+ children: [
2794
+ mcpAddCommand,
2795
+ mcpRemoveCommand,
2796
+ mcpTutorialCommand
2797
+ ]
2798
+ };
2799
+ //#endregion
2800
+ //#region src/lib/runners/resolve-no-telemetry.ts
2801
+ /**
2802
+ * `--no-telemetry` flips `telemetry: false` via yargs negation;
2803
+ * `POSTHOG_WIZARD_NO_TELEMETRY` is honoured separately so the env-var
2804
+ * form documented in the README keeps working.
2805
+ */
2710
2806
  function resolveNoTelemetry(options) {
2711
2807
  if (options.telemetry === false) return true;
2712
2808
  const env = process.env.POSTHOG_WIZARD_NO_TELEMETRY;
@@ -2714,6 +2810,9 @@ function resolveNoTelemetry(options) {
2714
2810
  const norm = env.toLowerCase();
2715
2811
  return norm !== "0" && norm !== "false";
2716
2812
  }
2813
+ //#endregion
2814
+ //#region src/lib/runners/run-wizard.ts
2815
+ const WIZARD_VERSION = VERSION;
2717
2816
  /**
2718
2817
  * Run a full wizard program in the TUI. Handles the full lifecycle: start TUI,
2719
2818
  * build session, run detection, wait for intro gate, execute the
@@ -2727,16 +2826,15 @@ function runWizard(config, options) {
2727
2826
  (async () => {
2728
2827
  try {
2729
2828
  const installDir = options.installDir || process.cwd();
2730
- const { startTUI } = await import("./start-tui-Bl8fCbp_.js");
2731
- const { buildSession, RunPhase } = await import("./wizard-session-DxU5ZMBN.js");
2732
- const { TaskStreamPush } = await import("./task-stream-z6QFZtpC.js");
2733
- const { PostHogDestination } = await import("./posthog-B1G0raJU.js");
2734
- const { logToFile } = await import("./debug-D5kt4fxB.js");
2829
+ const { startTUI } = await import("./start-tui-DXrv6cof.js");
2830
+ const { buildSession, RunPhase } = await import("./wizard-session-7tMjgOvP.js");
2831
+ const { TaskStreamPush } = await import("./task-stream-CF6QMVMv.js");
2832
+ const { PostHogDestination } = await import("./posthog-DWL8uOcl.js");
2833
+ const { logToFile } = await import("./debug-Cd0hPlZy.js");
2735
2834
  tui = startTUI(WIZARD_VERSION, config.id);
2736
2835
  const activeTui = tui;
2737
2836
  const session = buildSession({
2738
2837
  debug: options.debug,
2739
- forceInstall: options.forceInstall,
2740
2838
  localMcp: options.localMcp,
2741
2839
  installDir,
2742
2840
  ci: false,
@@ -2744,8 +2842,6 @@ function runWizard(config, options) {
2744
2842
  apiKey: options.apiKey,
2745
2843
  projectId: options.projectId,
2746
2844
  email: options.email,
2747
- menu: options.menu,
2748
- integration: options.integration,
2749
2845
  benchmark: options.benchmark,
2750
2846
  yaraReport: options.yaraReport,
2751
2847
  noTelemetry: resolveNoTelemetry(options)
@@ -2785,7 +2881,7 @@ function runWizard(config, options) {
2785
2881
  await activeTui.store.getGate("health-check");
2786
2882
  const skipAgent = config.run == null;
2787
2883
  if (skipAgent) {
2788
- const { getOrAskForProjectData } = await import("./setup-utils-C5iSJ3eg.js");
2884
+ const { getOrAskForProjectData } = await import("./setup-utils-BHZEdkNZ.js");
2789
2885
  const { projectApiKey, host, accessToken, projectId } = await getOrAskForProjectData({
2790
2886
  signup: session.signup,
2791
2887
  ci: session.ci,
@@ -2799,7 +2895,7 @@ function runWizard(config, options) {
2799
2895
  projectId
2800
2896
  });
2801
2897
  } else {
2802
- const { runAgent } = await import("./agent-runner-C9sSudE0.js");
2898
+ const { runAgent } = await import("./agent-runner-BxqiKVEf.js");
2803
2899
  await runAgent(config, activeTui.store.session);
2804
2900
  }
2805
2901
  const isDone = () => skipAgent ? activeTui.store.session.outroDismissed : activeTui.store.session.skillsComplete;
@@ -2838,16 +2934,14 @@ function runWizard(config, options) {
2838
2934
  }
2839
2935
  })();
2840
2936
  }
2937
+ //#endregion
2938
+ //#region src/lib/runners/run-wizard-ci.ts
2841
2939
  /**
2842
- * CI-mode pipeline shared by every non-interactive entry point.
2843
- *
2844
- * Validates flags, builds a `ci:true` session, runs `preRun` (or the
2845
- * program's `onReady` hooks by default), executes `runAgent`, and
2846
- * routes any failure through `wizardAbort`. `wizardAbort` owns all
2847
- * exits — never add a raw `process.exit` here.
2940
+ * The single CI validation layer: defaults region and requires api-key and
2941
+ * install-dir. Every CI entry point routes through `runWizardCI`, so this is
2942
+ * the one place these checks live. UI must be initialized before calling.
2848
2943
  */
2849
- function runWizardCI(config, options, preRun) {
2850
- setUI(new LoggingUI());
2944
+ function validateCiOptions(options) {
2851
2945
  if (!options.region) options.region = "us";
2852
2946
  if (!options.apiKey) {
2853
2947
  getUI().intro("PostHog Wizard");
@@ -2859,28 +2953,37 @@ function runWizardCI(config, options, preRun) {
2859
2953
  getUI().log.error("CI mode requires --install-dir (directory to install in)");
2860
2954
  process.exit(1);
2861
2955
  }
2956
+ }
2957
+ /**
2958
+ * CI-mode pipeline shared by every non-interactive entry point.
2959
+ *
2960
+ * Validates flags, builds a `ci:true` session, runs `config.ciPreRun` (or the
2961
+ * program's `onReady` hooks by default), executes `runAgent`, and routes any
2962
+ * failure through `wizardAbort`. `wizardAbort` owns all exits — never add a
2963
+ * raw `process.exit` here.
2964
+ */
2965
+ function runWizardCI(config, options) {
2966
+ setUI(new LoggingUI());
2967
+ validateCiOptions(options);
2862
2968
  (async () => {
2863
2969
  const path = await import("path");
2864
- const { buildSession } = await import("./wizard-session-DxU5ZMBN.js");
2865
- const { readEnvironment } = await Promise.resolve().then(() => environment_exports);
2866
- const { readApiKeyFromEnv } = await import("./env-api-key-HFqv1l-z.js");
2867
- const { configureLogFileFromEnvironment, logToFile } = await import("./debug-D5kt4fxB.js");
2868
- const { wizardAbort, WizardError } = await import("./wizard-abort-CuaS1eXn.js");
2970
+ const { buildSession } = await import("./wizard-session-7tMjgOvP.js");
2971
+ const { readEnvironment } = await import("./environment-BAaC5THg.js").then((n) => n.t);
2972
+ const { readApiKeyFromEnv } = await import("./env-api-key-DEl3LJBv.js").then((n) => n.t);
2973
+ const { configureLogFileFromEnvironment, logToFile } = await import("./debug-Cd0hPlZy.js");
2974
+ const { wizardAbort, WizardError } = await import("./wizard-abort-BGoBKgvC.js");
2869
2975
  configureLogFileFromEnvironment();
2870
2976
  const env = readEnvironment();
2871
2977
  const apiKey = options.apiKey ?? readApiKeyFromEnv() ?? void 0;
2872
2978
  const installDir = path.isAbsolute(options.installDir) ? options.installDir : path.join(process.cwd(), options.installDir);
2873
2979
  const session = buildSession({
2874
2980
  debug: options.debug,
2875
- forceInstall: options.forceInstall,
2876
2981
  installDir,
2877
2982
  ci: true,
2878
2983
  signup: options.signup,
2879
2984
  localMcp: options.localMcp,
2880
2985
  apiKey,
2881
2986
  email: options.email,
2882
- menu: options.menu,
2883
- integration: options.integration,
2884
2987
  projectId: options.projectId,
2885
2988
  benchmark: options.benchmark,
2886
2989
  yaraReport: options.yaraReport,
@@ -2893,7 +2996,7 @@ function runWizardCI(config, options, preRun) {
2893
2996
  getUI().intro("Welcome to the PostHog setup wizard");
2894
2997
  getUI().log.info(`Running ${config.id} in CI mode`);
2895
2998
  try {
2896
- if (preRun) await preRun(session);
2999
+ if (config.ciPreRun) await config.ciPreRun(session);
2897
3000
  else {
2898
3001
  const readyCtx = {
2899
3002
  session,
@@ -2916,7 +3019,7 @@ function runWizardCI(config, options, preRun) {
2916
3019
  })
2917
3020
  });
2918
3021
  }
2919
- const { runAgent } = await import("./agent-runner-C9sSudE0.js");
3022
+ const { runAgent } = await import("./agent-runner-BxqiKVEf.js");
2920
3023
  await runAgent(config, session);
2921
3024
  } catch (error) {
2922
3025
  const errorMessage = error instanceof Error ? error.message : String(error);
@@ -2934,6 +3037,235 @@ function runWizardCI(config, options, preRun) {
2934
3037
  });
2935
3038
  }
2936
3039
  //#endregion
2937
- export { SOURCE_MAPS_CONTEXT_KEYS as a, fetchHealthIssues as c, STRIPE_SDKS as d, DISPLAY_NAME as i, getContentBlocks$2 as l, Program as n, getContentBlocks$1 as o, getProgramConfig as r, getKindMeta as s, PROGRAM_REGISTRY as t, POSTHOG_SDKS$1 as u };
3040
+ //#region src/commands/skill-program-options.ts
3041
+ /** Flags shared by every skill-based program command (integrate, audit, …). */
3042
+ const skillProgramOptions = {
3043
+ debug: {
3044
+ default: false,
3045
+ describe: "Enable verbose logging",
3046
+ type: "boolean"
3047
+ },
3048
+ "install-dir": {
3049
+ describe: "Directory to install in",
3050
+ type: "string"
3051
+ },
3052
+ "local-mcp": {
3053
+ default: false,
3054
+ describe: "Use local MCP server",
3055
+ type: "boolean"
3056
+ },
3057
+ benchmark: {
3058
+ default: false,
3059
+ describe: "Run in benchmark mode",
3060
+ type: "boolean"
3061
+ },
3062
+ "yara-report": {
3063
+ default: false,
3064
+ describe: "Print YARA scanner summary",
3065
+ type: "boolean",
3066
+ hidden: true
3067
+ }
3068
+ };
3069
+ //#endregion
3070
+ //#region src/commands/integrate.ts
3071
+ const integrateCommand = {
3072
+ name: "integrate",
3073
+ description: posthogIntegrationConfig.description,
3074
+ options: {
3075
+ ...skillProgramOptions,
3076
+ ...posthogIntegrationConfig.cliOptions ?? {}
3077
+ },
3078
+ handler: (argv) => {
3079
+ const extras = posthogIntegrationConfig.mapCliOptions?.(argv) ?? {};
3080
+ const options = {
3081
+ ...argv,
3082
+ ...extras
3083
+ };
3084
+ if (options.ci) runWizardCI(posthogIntegrationConfig, options);
3085
+ else runWizard(posthogIntegrationConfig, options);
3086
+ }
3087
+ };
3088
+ //#endregion
3089
+ //#region src/commands/audit.ts
3090
+ const auditCommand = {
3091
+ name: "audit",
3092
+ description: auditConfig.description,
3093
+ options: {
3094
+ ...skillProgramOptions,
3095
+ ...auditConfig.cliOptions ?? {}
3096
+ },
3097
+ handler: (argv) => {
3098
+ const extras = auditConfig.mapCliOptions?.(argv) ?? {};
3099
+ const options = {
3100
+ ...argv,
3101
+ ...extras
3102
+ };
3103
+ if (options.ci) runWizardCI(auditConfig, options);
3104
+ else runWizard(auditConfig, options);
3105
+ }
3106
+ };
3107
+ //#endregion
3108
+ //#region src/commands/audit-3000.ts
3109
+ const audit3000Command = {
3110
+ name: "audit-3000",
3111
+ description: audit3000Config.description,
3112
+ options: {
3113
+ ...skillProgramOptions,
3114
+ ...audit3000Config.cliOptions ?? {}
3115
+ },
3116
+ handler: (argv) => {
3117
+ const extras = audit3000Config.mapCliOptions?.(argv) ?? {};
3118
+ const options = {
3119
+ ...argv,
3120
+ ...extras
3121
+ };
3122
+ if (options.ci) runWizardCI(audit3000Config, options);
3123
+ else runWizard(audit3000Config, options);
3124
+ }
3125
+ };
3126
+ //#endregion
3127
+ //#region src/commands/doctor.ts
3128
+ const doctorCommand = {
3129
+ name: "doctor",
3130
+ description: posthogDoctorConfig.description,
3131
+ options: {
3132
+ ...skillProgramOptions,
3133
+ ...posthogDoctorConfig.cliOptions ?? {}
3134
+ },
3135
+ handler: (argv) => {
3136
+ const extras = posthogDoctorConfig.mapCliOptions?.(argv) ?? {};
3137
+ const options = {
3138
+ ...argv,
3139
+ ...extras
3140
+ };
3141
+ if (options.ci) runDoctorCI(options);
3142
+ else runWizard(posthogDoctorConfig, options);
3143
+ }
3144
+ };
3145
+ const SEVERITY_ORDER = {
3146
+ critical: 0,
3147
+ warning: 1,
3148
+ info: 2
3149
+ };
3150
+ async function runDoctorCI(options) {
3151
+ setUI(new LoggingUI());
3152
+ const apiKey = options.apiKey ?? readApiKeyFromEnv() ?? void 0;
3153
+ if (!apiKey) {
3154
+ getUI().intro("PostHog Wizard");
3155
+ getUI().log.error("CI mode requires --api-key (personal API key phx_xxx)");
3156
+ process.exit(1);
3157
+ }
3158
+ getUI().intro("Welcome to the PostHog setup wizard");
3159
+ getUI().log.info("Running posthog-doctor in CI mode");
3160
+ try {
3161
+ const { getOrAskForProjectData } = await import("./setup-utils-BHZEdkNZ.js");
3162
+ const { host, accessToken, projectId } = await getOrAskForProjectData({
3163
+ signup: false,
3164
+ ci: true,
3165
+ apiKey,
3166
+ projectId: options.projectId ? Number(options.projectId) : void 0
3167
+ });
3168
+ const issues = await fetchHealthIssues(accessToken, host, projectId);
3169
+ if (issues.length === 0) {
3170
+ getUI().log.success("No active issues — your project looks healthy.");
3171
+ process.exit(0);
3172
+ }
3173
+ const sorted = [...issues].sort((a, b) => SEVERITY_ORDER[a.severity] - SEVERITY_ORDER[b.severity]);
3174
+ getUI().log.warn(`${issues.length} active issue${issues.length === 1 ? "" : "s"} found:`);
3175
+ for (const issue of sorted) getUI().log.info(` • [${issue.severity}] ${getKindMeta(issue.kind).title}`);
3176
+ process.exit(1);
3177
+ } catch (error) {
3178
+ const { ApiError } = await import("./api-B8OR0N1V.js");
3179
+ const message = error instanceof ApiError && error.statusCode === 401 ? "Your PostHog API key is invalid or expired." : error instanceof Error ? error.message : String(error);
3180
+ getUI().log.error(`Doctor failed: ${message}`);
3181
+ process.exit(1);
3182
+ }
3183
+ }
3184
+ //#endregion
3185
+ //#region src/commands/migrate.ts
3186
+ const migrateCommand = {
3187
+ name: "migrate",
3188
+ description: migrationConfig.description,
3189
+ options: {
3190
+ ...skillProgramOptions,
3191
+ ...migrationConfig.cliOptions ?? {}
3192
+ },
3193
+ handler: (argv) => {
3194
+ const extras = migrationConfig.mapCliOptions?.(argv) ?? {};
3195
+ const options = {
3196
+ ...argv,
3197
+ ...extras
3198
+ };
3199
+ if (options.ci) runWizardCI(migrationConfig, options);
3200
+ else runWizard(migrationConfig, options);
3201
+ }
3202
+ };
3203
+ //#endregion
3204
+ //#region src/commands/events-audit.ts
3205
+ const eventsAuditCommand = {
3206
+ name: "events-audit",
3207
+ description: eventsAuditConfig.description,
3208
+ options: {
3209
+ ...skillProgramOptions,
3210
+ ...eventsAuditConfig.cliOptions ?? {}
3211
+ },
3212
+ handler: (argv) => {
3213
+ const extras = eventsAuditConfig.mapCliOptions?.(argv) ?? {};
3214
+ const options = {
3215
+ ...argv,
3216
+ ...extras
3217
+ };
3218
+ if (options.ci) runWizardCI(eventsAuditConfig, options);
3219
+ else runWizard(eventsAuditConfig, options);
3220
+ }
3221
+ };
3222
+ //#endregion
3223
+ //#region src/commands/revenue.ts
3224
+ const revenueCommand = {
3225
+ name: "revenue",
3226
+ description: revenueAnalyticsConfig.description,
3227
+ options: {
3228
+ ...skillProgramOptions,
3229
+ ...revenueAnalyticsConfig.cliOptions ?? {}
3230
+ },
3231
+ handler: (argv) => {
3232
+ const extras = revenueAnalyticsConfig.mapCliOptions?.(argv) ?? {};
3233
+ const options = {
3234
+ ...argv,
3235
+ ...extras
3236
+ };
3237
+ if (options.ci) runWizardCI(revenueAnalyticsConfig, options);
3238
+ else runWizard(revenueAnalyticsConfig, options);
3239
+ }
3240
+ };
3241
+ //#endregion
3242
+ //#region src/commands/upload-sourcemaps.ts
3243
+ const uploadSourcemapsCommand = {
3244
+ name: "upload-sourcemaps",
3245
+ description: errorTrackingUploadSourceMapsConfig.description,
3246
+ options: {
3247
+ ...skillProgramOptions,
3248
+ ...errorTrackingUploadSourceMapsConfig.cliOptions ?? {}
3249
+ },
3250
+ handler: (argv) => {
3251
+ const extras = errorTrackingUploadSourceMapsConfig.mapCliOptions?.(argv) ?? {};
3252
+ const options = {
3253
+ ...argv,
3254
+ ...extras
3255
+ };
3256
+ if (options.ci) runWizardCI(errorTrackingUploadSourceMapsConfig, options);
3257
+ else runWizard(errorTrackingUploadSourceMapsConfig, options);
3258
+ }
3259
+ };
3260
+ //#endregion
3261
+ //#region bin.ts
3262
+ const NODE_VERSION_RANGE = ">=18.17.0";
3263
+ if (!satisfies(process.version, NODE_VERSION_RANGE)) {
3264
+ console.log(`PostHog wizard requires Node.js ${NODE_VERSION_RANGE}. You are using Node.js ${process.version}. Please upgrade your Node.js version.`);
3265
+ process.exit(1);
3266
+ }
3267
+ Wizard.use(basicIntegrationCommand).use(mcpCommand).use(integrateCommand).use(auditCommand).use(audit3000Command).use(doctorCommand).use(migrateCommand).use(eventsAuditCommand).use(revenueCommand).use(uploadSourcemapsCommand).init();
3268
+ //#endregion
3269
+ export { getProgramConfig as a, getContentBlocks$1 as c, createSkillProgram as d, getContentBlocks$2 as f, Program as i, getKindMeta as l, STRIPE_SDKS as m, runWizard as n, DISPLAY_NAME as o, POSTHOG_SDKS$1 as p, PROGRAM_REGISTRY as r, SOURCE_MAPS_CONTEXT_KEYS as s, runWizardCI as t, fetchHealthIssues as u };
2938
3270
 
2939
3271
  //# sourceMappingURL=bin.js.map