@posthog/wizard 2.65.0 → 2.67.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (119) hide show
  1. package/dist/{add-mcp-server-to-clients-ArtlMX9-.js → add-mcp-server-to-clients-DHTRbyJX.js} +228 -64
  2. package/dist/add-mcp-server-to-clients-DHTRbyJX.js.map +1 -0
  3. package/dist/{agent-interface-ORzGEFNM.js → agent-interface-tM_b0l__.js} +458 -76
  4. package/dist/agent-interface-tM_b0l__.js.map +1 -0
  5. package/dist/{agent-prompt-loader-D3w6sc34.js → agent-prompt-loader-BSMh5bfD.js} +5 -5
  6. package/dist/{agent-prompt-loader-D3w6sc34.js.map → agent-prompt-loader-BSMh5bfD.js.map} +1 -1
  7. package/dist/{agent-runner-Ca-e2TOQ.js → agent-runner-DD65OMkB.js} +153 -71
  8. package/dist/agent-runner-DD65OMkB.js.map +1 -0
  9. package/dist/analytics-B4Igh5nv.js +2 -0
  10. package/dist/{analytics-zBrIVjMV.js → analytics-CtIYzkK4.js} +2 -2
  11. package/dist/{analytics-zBrIVjMV.js.map → analytics-CtIYzkK4.js.map} +1 -1
  12. package/dist/{api-Wgb7AhrP.js → api-BJft9v6K.js} +3 -3
  13. package/dist/{api-Wgb7AhrP.js.map → api-BJft9v6K.js.map} +1 -1
  14. package/dist/bin.js +245 -102
  15. package/dist/bin.js.map +1 -1
  16. package/dist/{bounded-fs-DqsVmh4r.js → bounded-fs-BWqoFQvQ.js} +3 -3
  17. package/dist/{bounded-fs-DqsVmh4r.js.map → bounded-fs-BWqoFQvQ.js.map} +1 -1
  18. package/dist/{ci-install-D1QqmJIc.js → ci-install-BXGnVI7T.js} +18 -9
  19. package/dist/ci-install-BXGnVI7T.js.map +1 -0
  20. package/dist/{debug-Cm1hvkVy.js → debug-BsHD83Vy.js} +4 -4
  21. package/dist/debug-BsHD83Vy.js.map +1 -0
  22. package/dist/{debug-CtQ13sCW.js → debug-mO3yg4Z7.js} +1 -1
  23. package/dist/{defaults-BHhXrX9F.js → defaults-DI642M3n.js} +1 -1
  24. package/dist/{defaults-BHhXrX9F.js.map → defaults-DI642M3n.js.map} +1 -1
  25. package/dist/{env-api-key-CdI2XZIz.js → env-api-key-DS0ghlcO.js} +2 -2
  26. package/dist/{env-api-key-CdI2XZIz.js.map → env-api-key-DS0ghlcO.js.map} +1 -1
  27. package/dist/{environment-BhFvfkQg.js → environment-C7CKGIOE.js} +4 -4
  28. package/dist/{environment-BhFvfkQg.js.map → environment-C7CKGIOE.js.map} +1 -1
  29. package/dist/errors-BHervYGs.js +156 -0
  30. package/dist/errors-BHervYGs.js.map +1 -0
  31. package/dist/{file-watcher-Dciz09Rr.js → file-watcher-D1bdo9mq.js} +2 -2
  32. package/dist/{file-watcher-Dciz09Rr.js.map → file-watcher-D1bdo9mq.js.map} +1 -1
  33. package/dist/{headless-ui-B4FnKm11.js → headless-ui-6QuByWZ_.js} +2 -2
  34. package/dist/{headless-ui-B4FnKm11.js.map → headless-ui-6QuByWZ_.js.map} +1 -1
  35. package/dist/{interactive-DxHFVYr2.js → interactive-DUpW84WU.js} +2 -2
  36. package/dist/{interactive-DxHFVYr2.js.map → interactive-DUpW84WU.js.map} +1 -1
  37. package/dist/{local-dev-BN6NKQ0B.js → local-dev-DPZiIPCK.js} +1 -1
  38. package/dist/{local-dev-BN6NKQ0B.js.map → local-dev-DPZiIPCK.js.map} +1 -1
  39. package/dist/{mcp-t0UxAPur.js → mcp-CHo9h-WV.js} +2 -2
  40. package/dist/{mcp-t0UxAPur.js.map → mcp-CHo9h-WV.js.map} +1 -1
  41. package/dist/mcp-install-smoke-test.ts +477 -0
  42. package/dist/{mcp-prompt-streaming-ro98iUDc.js → mcp-prompt-streaming-CHRPxxd0.js} +4 -4
  43. package/dist/{mcp-prompt-streaming-ro98iUDc.js.map → mcp-prompt-streaming-CHRPxxd0.js.map} +1 -1
  44. package/dist/{non-interactive-BA2L_jDT.js → non-interactive-Cr-chffe.js} +7 -2
  45. package/dist/non-interactive-Cr-chffe.js.map +1 -0
  46. package/dist/{orchestrator-tools-vZmNsHy9.js → orchestrator-tools-Tx18_TMb.js} +3 -3
  47. package/dist/{orchestrator-tools-vZmNsHy9.js.map → orchestrator-tools-Tx18_TMb.js.map} +1 -1
  48. package/dist/{package-json-D0DCWpe5.js → package-json-GEU2VZlS.js} +1 -1
  49. package/dist/{package-json-D0DCWpe5.js.map → package-json-GEU2VZlS.js.map} +1 -1
  50. package/dist/{package-manager-DgqJdAQk.js → package-manager-CLfc31yf.js} +4 -4
  51. package/dist/package-manager-CLfc31yf.js.map +1 -0
  52. package/dist/{pi-nwrCARRp.js → pi-RlnYUHdb.js} +12 -11
  53. package/dist/{pi-nwrCARRp.js.map → pi-RlnYUHdb.js.map} +1 -1
  54. package/dist/{playground-xkEke_h0.js → playground-DQ633rje.js} +7 -7
  55. package/dist/{playground-xkEke_h0.js.map → playground-DQ633rje.js.map} +1 -1
  56. package/dist/{posthog-9To56cSd.js → posthog-DSn9bIZc.js} +2 -2
  57. package/dist/{posthog-9To56cSd.js.map → posthog-DSn9bIZc.js.map} +1 -1
  58. package/dist/{posthog-integration-CoPvN6YZ.js → posthog-integration-DFfBRGOC.js} +667 -37
  59. package/dist/posthog-integration-DFfBRGOC.js.map +1 -0
  60. package/dist/{provisioning-BYFSHSHY.js → provisioning-Cvy_vQHV.js} +3 -3
  61. package/dist/{provisioning-BYFSHSHY.js.map → provisioning-Cvy_vQHV.js.map} +1 -1
  62. package/dist/{queue-tools-BREbgGSC.js → queue-tools-BC9HxOV6.js} +33 -7
  63. package/dist/queue-tools-BC9HxOV6.js.map +1 -0
  64. package/dist/{registry-DGJQ_8QI.js → registry-DCAElOyj.js} +81 -81
  65. package/dist/{registry-DGJQ_8QI.js.map → registry-DCAElOyj.js.map} +1 -1
  66. package/dist/{security-wc-naGq5.js → security-CuSX3XVo.js} +21 -9
  67. package/dist/security-CuSX3XVo.js.map +1 -0
  68. package/dist/{setup-utils-Cz0wPLsQ.js → setup-utils-D1tv0v_R.js} +13 -13
  69. package/dist/{setup-utils-Cz0wPLsQ.js.map → setup-utils-D1tv0v_R.js.map} +1 -1
  70. package/dist/{start-tui-DDW9uVnD.js → start-tui-B5YfmqNr.js} +57 -25
  71. package/dist/start-tui-B5YfmqNr.js.map +1 -0
  72. package/dist/{steps-CZI0B24_.js → steps-CLaSMwfR.js} +7 -7
  73. package/dist/{steps-CZI0B24_.js.map → steps-CLaSMwfR.js.map} +1 -1
  74. package/dist/{store-xMkU8xAa.js → store-DzEgsAPN.js} +7 -6
  75. package/dist/{store-xMkU8xAa.js.map → store-DzEgsAPN.js.map} +1 -1
  76. package/dist/{subagent-BztacyoV.js → subagent-BUV6aD7p.js} +2 -2
  77. package/dist/{subagent-BztacyoV.js.map → subagent-BUV6aD7p.js.map} +1 -1
  78. package/dist/{task-CJ7x3McC.js → task-GnWId75q.js} +13 -12
  79. package/dist/{task-CJ7x3McC.js.map → task-GnWId75q.js.map} +1 -1
  80. package/dist/{task-stream-BK7JQ27G.js → task-stream-DSzvwJrD.js} +16 -9
  81. package/dist/task-stream-DSzvwJrD.js.map +1 -0
  82. package/dist/{tasks-FGzp_zBd.js → tasks-BO0W8ocx.js} +2 -2
  83. package/dist/{tasks-FGzp_zBd.js.map → tasks-BO0W8ocx.js.map} +1 -1
  84. package/dist/{telemetry-By56gAtF.js → telemetry-Vi9dWddJ.js} +3 -3
  85. package/dist/{telemetry-By56gAtF.js.map → telemetry-Vi9dWddJ.js.map} +1 -1
  86. package/dist/{terminal-C_rmkaku.js → terminal-B5wZK7aS.js} +73 -80
  87. package/dist/terminal-B5wZK7aS.js.map +1 -0
  88. package/dist/{tools-BpCJgMez.js → tools-C9cNluqc.js} +54 -47
  89. package/dist/tools-C9cNluqc.js.map +1 -0
  90. package/dist/{wizard-abort-BlDla_Jd.js → wizard-abort-BsNbguJt.js} +1 -1
  91. package/dist/wizard-abort-CGv3lVxw.js +71 -0
  92. package/dist/wizard-abort-CGv3lVxw.js.map +1 -0
  93. package/dist/{wizard-session-Bn6dO1gE.js → wizard-session-Cex1BiXs.js} +3 -2
  94. package/dist/wizard-session-Cex1BiXs.js.map +1 -0
  95. package/dist/{wizard-session-UxA_A0cA.js → wizard-session-DHbUcjI7.js} +1 -1
  96. package/dist/yara-hooks-C3Vm2Gow.js +2 -0
  97. package/dist/{yara-hooks-BrisBebM.js → yara-hooks-DZIVzhA6.js} +57 -8
  98. package/dist/yara-hooks-DZIVzhA6.js.map +1 -0
  99. package/package.json +2 -1
  100. package/dist/add-mcp-server-to-clients-ArtlMX9-.js.map +0 -1
  101. package/dist/agent-interface-ORzGEFNM.js.map +0 -1
  102. package/dist/agent-runner-Ca-e2TOQ.js.map +0 -1
  103. package/dist/analytics-C4j6grao.js +0 -2
  104. package/dist/ci-install-D1QqmJIc.js.map +0 -1
  105. package/dist/debug-Cm1hvkVy.js.map +0 -1
  106. package/dist/non-interactive-BA2L_jDT.js.map +0 -1
  107. package/dist/package-manager-DgqJdAQk.js.map +0 -1
  108. package/dist/posthog-integration-CoPvN6YZ.js.map +0 -1
  109. package/dist/queue-tools-BREbgGSC.js.map +0 -1
  110. package/dist/security-wc-naGq5.js.map +0 -1
  111. package/dist/start-tui-DDW9uVnD.js.map +0 -1
  112. package/dist/task-stream-BK7JQ27G.js.map +0 -1
  113. package/dist/terminal-C_rmkaku.js.map +0 -1
  114. package/dist/tools-BpCJgMez.js.map +0 -1
  115. package/dist/wizard-abort-CzwID162.js +0 -49
  116. package/dist/wizard-abort-CzwID162.js.map +0 -1
  117. package/dist/wizard-session-Bn6dO1gE.js.map +0 -1
  118. package/dist/yara-hooks-BrisBebM.js.map +0 -1
  119. package/dist/yara-hooks-D2B7Fd9G.js +0 -2
package/dist/bin.js CHANGED
@@ -1,28 +1,29 @@
1
1
  #!/usr/bin/env node
2
- import { Ct as isHeadless, L as Integration, St as headlessOption, U as POSTHOG_DOCS_URL, a as getLogFilePath, f as getUI, gt as VERSION, m as LoggingUI, mt as getSkillsBaseUrl, p as setUI, pt as WIZARD_USER_AGENT, r as debug, s as logToFile, wt as regionOption } from "./debug-Cm1hvkVy.js";
3
- import { a as getLocalDev, i as checkLocalServices, o as initLocalDev, r as POSTHOG_LOCAL_URL, s as localMcpSkillsNotice } from "./local-dev-BN6NKQ0B.js";
4
- import { n as analytics } from "./analytics-zBrIVjMV.js";
5
- import { r as setEntryCommand } from "./telemetry-By56gAtF.js";
6
- import { a as safeReadFile, o as walkProjectFiles } from "./bounded-fs-DqsVmh4r.js";
7
- import { n as isUsingTypeScript } from "./setup-utils-Cz0wPLsQ.js";
8
- import { o as handleApiError } from "./api-Wgb7AhrP.js";
9
- import "./wizard-session-Bn6dO1gE.js";
10
- import { i as wizardAbort, r as runCleanups } from "./wizard-abort-CzwID162.js";
11
- import { n as isNonInteractiveEnvironment } from "./environment-BhFvfkQg.js";
12
- import { n as runAgent, s as authenticate } from "./agent-runner-Ca-e2TOQ.js";
13
- import { p as writeJsonAtomic } from "./queue-tools-BREbgGSC.js";
14
- import { C as WIZARD_TOOL_NAMES, E as fetchSkillMenu, l as recoverOrphanedSettingsBackups, p as AgentSignals } from "./agent-interface-ORzGEFNM.js";
15
- import { S as SETUP_REPORT_FILE, _ as AUDIT_CHECKS_KEY, g as AUDIT_CHECKS_FILE, v as AUDIT_REPORT_FILE } from "./yara-hooks-BrisBebM.js";
16
- import { i as SPINNER_MESSAGE, t as FRAMEWORK_REGISTRY } from "./registry-DGJQ_8QI.js";
17
- import { C as scopeInstallDirToProject, D as detectFramework, E as gatherFrameworkContext, S as detectIntegrationProjects, T as resolveProjectDir, _ as HEALTH_CHECK_STEP, a as LINE_CHART_BLOCK, b as getDetectedWarehouseSources, d as isClearBlock, g as detectPostHogIntegration, h as Icons, i as FUNNEL_BLOCK, m as Colors, n as integrationRunStep, o as PRODUCT_SUITE_BLOCK, r as posthogIntegrationConfig, s as StatusPeekTrigger, u as wordWrap, v as WAREHOUSE_ABORT_CASES, x as detectWarehouseSources, y as detectWarehousePrerequisites } from "./posthog-integration-CoPvN6YZ.js";
18
- import { n as readApiKeyFromEnv } from "./env-api-key-CdI2XZIz.js";
2
+ import { a as AgentSignals, c as emitWizardError, l as ErrorCodes, r as detectErrorCode } from "./errors-BHervYGs.js";
3
+ import { Ct as isHeadless, L as Integration, St as headlessOption, U as POSTHOG_DOCS_URL, a as getLogFilePath, f as getUI, gt as VERSION, m as LoggingUI, mt as getSkillsBaseUrl, p as setUI, pt as WIZARD_USER_AGENT, r as debug, s as logToFile, wt as regionOption } from "./debug-BsHD83Vy.js";
4
+ import { a as getLocalDev, i as checkLocalServices, o as initLocalDev, r as POSTHOG_LOCAL_URL, s as localMcpSkillsNotice } from "./local-dev-DPZiIPCK.js";
5
+ import { n as analytics } from "./analytics-CtIYzkK4.js";
6
+ import { r as setEntryCommand } from "./telemetry-Vi9dWddJ.js";
7
+ import { a as safeReadFile, o as walkProjectFiles } from "./bounded-fs-BWqoFQvQ.js";
8
+ import { n as isUsingTypeScript } from "./setup-utils-D1tv0v_R.js";
9
+ import { o as handleApiError } from "./api-BJft9v6K.js";
10
+ import "./wizard-session-Cex1BiXs.js";
11
+ import { i as wizardAbort, r as runCleanups } from "./wizard-abort-CGv3lVxw.js";
12
+ import { n as isNonInteractiveEnvironment } from "./environment-C7CKGIOE.js";
13
+ import { n as runAgent, s as authenticate } from "./agent-runner-DD65OMkB.js";
14
+ import { m as writeJsonAtomic } from "./queue-tools-BC9HxOV6.js";
15
+ import { T as WIZARD_TOOL_NAMES, k as fetchSkillMenu, l as recoverOrphanedSettingsBackups } from "./agent-interface-tM_b0l__.js";
16
+ import { S as SETUP_REPORT_FILE, _ as AUDIT_CHECKS_KEY, g as AUDIT_CHECKS_FILE, v as AUDIT_REPORT_FILE } from "./yara-hooks-DZIVzhA6.js";
17
+ import { i as SPINNER_MESSAGE, t as FRAMEWORK_REGISTRY } from "./registry-DCAElOyj.js";
18
+ import { C as scopeInstallDirToProject, D as detectFramework, E as gatherFrameworkContext, S as detectIntegrationProjects, T as resolveProjectDir, _ as HEALTH_CHECK_STEP, a as LINE_CHART_BLOCK, b as getDetectedWarehouseSources, d as isClearBlock, g as detectPostHogIntegration, h as Icons, i as FUNNEL_BLOCK, m as Colors, n as integrationRunStep, o as PRODUCT_SUITE_BLOCK, r as posthogIntegrationConfig, s as StatusPeekTrigger, u as wordWrap, v as WAREHOUSE_ABORT_CASES, x as detectWarehouseSources, y as detectWarehousePrerequisites } from "./posthog-integration-DFfBRGOC.js";
19
+ import { n as readApiKeyFromEnv } from "./env-api-key-DS0ghlcO.js";
19
20
  import { satisfies } from "semver";
20
21
  import yargs from "yargs";
21
22
  import { hideBin } from "yargs/helpers";
22
23
  import { existsSync, readFileSync, readdirSync, statSync } from "fs";
23
24
  import path, { join, relative } from "path";
24
25
  import * as os from "node:os";
25
- import * as path$1 from "node:path";
26
+ import * as path$2 from "node:path";
26
27
  import { join as join$1 } from "node:path";
27
28
  import { spawnSync } from "node:child_process";
28
29
  import * as fs$1 from "node:fs";
@@ -132,6 +133,10 @@ var Wizard = class Wizard {
132
133
  }).strictOptions().strictCommands().fail((msg, err) => {
133
134
  const text = msg || err && err.message || "Invalid arguments";
134
135
  process.stderr.write(`\n\x1b[1;91m✖ ${text}\x1b[0m\n Run \`wizard --help\` to see available commands and options.\n\n`);
136
+ emitWizardError({
137
+ code: ErrorCodes.CliBadArgs,
138
+ message: text
139
+ });
135
140
  process.exit(1);
136
141
  }).help().alias("help", "h").version().alias("version", "v");
137
142
  }
@@ -152,18 +157,30 @@ var Wizard = class Wizard {
152
157
  const envHasCI = process.env.POSTHOG_WIZARD_CI != null && process.env.POSTHOG_WIZARD_CI !== "";
153
158
  if (argvHasCI || envHasCI) {
154
159
  process.stderr.write(`\n\x1b[1;91m✖ CI mode is not currently supported in published builds.\x1b[0m\n\n`);
160
+ emitWizardError({
161
+ code: ErrorCodes.CliFlagUnavailable,
162
+ message: "CI mode is not supported in published builds."
163
+ });
155
164
  process.exit(1);
156
165
  }
157
166
  const argvHasOverride = args.some((a) => a === "--harness" || a.startsWith("--harness=") || a === "--sequence" || a.startsWith("--sequence=") || a === "--model" || a.startsWith("--model=") || a === "--capture-aio" || a === "--no-capture-aio" || a.startsWith("--capture-aio="));
158
167
  const envHasOverride = process.env.POSTHOG_WIZARD_HARNESS != null && process.env.POSTHOG_WIZARD_HARNESS !== "" || process.env.POSTHOG_WIZARD_SEQUENCE != null && process.env.POSTHOG_WIZARD_SEQUENCE !== "" || process.env.POSTHOG_WIZARD_MODEL != null && process.env.POSTHOG_WIZARD_MODEL !== "" || process.env.POSTHOG_WIZARD_CAPTURE_AIO != null && process.env.POSTHOG_WIZARD_CAPTURE_AIO !== "";
159
168
  if (argvHasOverride || envHasOverride) {
160
169
  process.stderr.write(`\n\x1b[1;91m✖ The --harness, --sequence, --model, and --capture-aio overrides are not available in published builds.\x1b[0m\n\n`);
170
+ emitWizardError({
171
+ code: ErrorCodes.CliFlagUnavailable,
172
+ message: "The --harness, --sequence, --model, and --capture-aio overrides are not available in published builds."
173
+ });
161
174
  process.exit(1);
162
175
  }
163
176
  const argvHasLocalTarget = args.some((a) => LOCAL_TARGET_FLAGS.some((f) => a === `--${f}` || a === `--no-${f}` || a.startsWith(`--${f}=`)));
164
177
  const envHasLocalTarget = LOCAL_TARGET_ENV_VARS.some((k) => process.env[k] != null && process.env[k] !== "");
165
178
  if (argvHasLocalTarget || envHasLocalTarget) {
166
179
  process.stderr.write("\n\x1B[1;91m✖ The --local-dev, --local-context-mill, --local-mcp, and --local-posthog targets are not available in published builds.\x1B[0m\n They point the wizard at development servers on localhost.\n\n");
180
+ emitWizardError({
181
+ code: ErrorCodes.CliFlagUnavailable,
182
+ message: "The --local-dev, --local-context-mill, --local-mcp, and --local-posthog targets are not available in published builds."
183
+ });
167
184
  process.exit(1);
168
185
  }
169
186
  }
@@ -225,7 +242,7 @@ function runProvision(argv) {
225
242
  }
226
243
  async function provision({ email, region, name, baseUrl, jsonMode }) {
227
244
  try {
228
- const { provisionNewAccount } = await import("./provisioning-BYFSHSHY.js").then((n) => n.r);
245
+ const { provisionNewAccount } = await import("./provisioning-Cvy_vQHV.js").then((n) => n.r);
229
246
  if (!jsonMode) getUI().log.info(`Provisioning account for ${email} in ${region}...`);
230
247
  emitResult(await provisionNewAccount(email, name, region, { baseUrl }), jsonMode);
231
248
  process.exit(0);
@@ -292,22 +309,22 @@ const basicIntegrationCommand = {
292
309
  setEntryCommand("integrate");
293
310
  (async () => {
294
311
  if (isHeadless(argv)) {
295
- const { runHeadlessInstall } = await import("./ci-install-D1QqmJIc.js");
312
+ const { runHeadlessInstall } = await import("./ci-install-BXGnVI7T.js");
296
313
  return runHeadlessInstall(argv);
297
314
  }
298
315
  if (argv.ci) {
299
- const { runCIInstall } = await import("./ci-install-D1QqmJIc.js");
316
+ const { runCIInstall } = await import("./ci-install-BXGnVI7T.js");
300
317
  return runCIInstall(argv);
301
318
  }
302
319
  if (isNonInteractiveEnvironment()) {
303
- const { failNonInteractive } = await import("./non-interactive-BA2L_jDT.js");
320
+ const { failNonInteractive } = await import("./non-interactive-Cr-chffe.js");
304
321
  return failNonInteractive();
305
322
  }
306
323
  if (argv.playground) {
307
- const { runPlayground } = await import("./playground-xkEke_h0.js");
324
+ const { runPlayground } = await import("./playground-DQ633rje.js");
308
325
  return runPlayground();
309
326
  }
310
- const { runInteractive } = await import("./interactive-DxHFVYr2.js");
327
+ const { runInteractive } = await import("./interactive-DUpW84WU.js");
311
328
  runInteractive(argv);
312
329
  })();
313
330
  }
@@ -592,7 +609,10 @@ function buildPrompt(session) {
592
609
  "The wizard detected the following data warehouse sources in this project:",
593
610
  ...sources.map((s) => `- ${s.label} (kind: ${s.kind}, mode: ${s.mode}) — ${s.matchedSignal}`),
594
611
  "",
595
- "Set these up in PostHog following the skill instructions: create `in-cli` sources directly via the PostHog MCP after collecting credentials; for `deep-link` sources, provide the user the pre-filled new-source URL."
612
+ "Each signal names the file it came from. Trust that path — the wizard read it. To confirm a key is set, call `check_env_keys` with the key names and no `filePath`; it scans every `.env` file in the project.",
613
+ "",
614
+ "Set these up in PostHog following the skill instructions: create `in-cli` sources directly via the PostHog MCP after collecting credentials; for `deep-link` sources, provide the user the pre-filled new-source URL.",
615
+ "Use the `kind` string exactly as printed above for `source_type` — PostHog rejects the display label."
596
616
  ].join("\n");
597
617
  }
598
618
  const warehouseSourceConfig = {
@@ -683,6 +703,7 @@ function createSkillProgram(opts) {
683
703
  * defined in the skill's `Abort statuses` section. */
684
704
  const AUDIT_ABORT_CASES = [{
685
705
  match: /^no posthog sdk found$/i,
706
+ errorCode: ErrorCodes.DetectNoPosthogSdk,
686
707
  message: "No PostHog SDK found",
687
708
  body: "The audit needs an existing PostHog integration to review. No PostHog SDK appears in this project’s dependency manifests. Run the basic integration program to install PostHog first, then re-run the audit.",
688
709
  docsUrl: "https://posthog.com/docs/getting-started/install"
@@ -1186,12 +1207,14 @@ const WEB_ANALYTICS_ABORT_CASES = [
1186
1207
  },
1187
1208
  {
1188
1209
  match: /^insufficient permissions$/i,
1210
+ errorCode: ErrorCodes.AuthMissingScope,
1189
1211
  message: "Insufficient permissions",
1190
1212
  body: "The doctor could not query your project — the authenticated token is missing query access. Re-run the wizard to sign in again, or use a key with read access to your events.",
1191
1213
  docsUrl: "https://posthog.com/docs/web-analytics"
1192
1214
  },
1193
1215
  {
1194
1216
  match: /^posthog sdk not installed$/i,
1217
+ errorCode: ErrorCodes.DetectNoPosthogSdk,
1195
1218
  message: "PostHog SDK not installed",
1196
1219
  body: "The doctor could not find a PostHog SDK in this project. Install and configure PostHog first (run `npx @posthog/wizard`), then run the doctor to check your web analytics setup.",
1197
1220
  docsUrl: "https://posthog.com/docs/libraries/js"
@@ -1888,6 +1911,7 @@ const GO_SDK_MODULE = "github.com/posthog/posthog-go";
1888
1911
  const SOURCE_MAPS_ABORT_CASES = [
1889
1912
  {
1890
1913
  match: /^no posthog sdk detected$/i,
1914
+ errorCode: ErrorCodes.DetectNoPosthogSdk,
1891
1915
  message: "No PostHog SDK detected",
1892
1916
  body: "The agent could not find a PostHog SDK in your project. Source map upload requires the SDK to already be installed so it can report errors. Run `npx @posthog/wizard` first to install the SDK (for Go and Rust, add posthog-go / posthog-rs by hand first — the wizard cannot install the SDK for those stacks yet).",
1893
1917
  docsUrl: "https://posthog.com/docs/error-tracking"
@@ -1900,6 +1924,7 @@ const SOURCE_MAPS_ABORT_CASES = [
1900
1924
  },
1901
1925
  {
1902
1926
  match: /^bare react native not supported$/i,
1927
+ errorCode: ErrorCodes.DetectUnsupportedPlatform,
1903
1928
  message: "Bare React Native is not supported",
1904
1929
  body: "Source-map upload for React Native requires Expo, and this project has no `expo` package. Bare React Native builds cannot inject the chunk IDs PostHog needs to resolve stack traces.",
1905
1930
  docsUrl: "https://posthog.com/docs/error-tracking/upload-source-maps/react-native"
@@ -1976,8 +2001,12 @@ STEP 5 — Write the credentials to the env file. (skill: "Write credentials to
1976
2001
  Use the wizard-tools MCP server. Reuse the env file the skill tells you to
1977
2002
  pick — the prerequisite PostHog integration usually already wrote
1978
2003
  POSTHOG_* vars to one, so seed your keys alongside them.
1979
- - First call check_env_keys on that file (returns present/absent, never
1980
- values — don't read the file directly).
2004
+ - First call check_env_keys with the key names and that file as filePath.
2005
+ It answers { status: "present" | "missing", foundIn: [paths] } per key —
2006
+ names and paths only, never values, so don't read the file directly.
2007
+ "present" means a real env file sets the key; a key found only in a
2008
+ committed template (.env.example and friends) reads as "missing",
2009
+ because a template documents a key rather than setting it.
1981
2010
  - Env tool path rule: ${inSubproject ? `Tool filePaths are relative to the wizard's working directory, not the selected project directory. Treat the skill's env path as relative to the selected project and prefix it with \`${projectPath}/\` when calling the tools: for example, pass \`${projectPath}/.env\`, not \`.env\` (which would target the wizard's working directory).${variant === "rust" ? ` Cargo workspace exception: when the skill places the env file at the workspace root instead, pass the path of the ROOT manifest's directory relative to the wizard's working directory (e.g. \`rust/.env\` for a workspace root at \`rust/\`, or plain \`.env\` when the workspace root IS the working directory) — not the member path.` : ""}` : `Tool filePaths are relative to the wizard's working directory. For an env file at this project root, pass \`.env\`; never prefix it with this directory's path inside an ancestor repository.`}
1982
2011
  - Then call set_env_values, passing the STEP 1 secretRef as a value
1983
2012
  object, not a literal string:
@@ -2478,7 +2507,7 @@ const getContentBlocks$1 = (store) => pace([
2478
2507
  //#region src/steps/install-cli-steering/index.ts
2479
2508
  const dirExists = (...segments) => {
2480
2509
  try {
2481
- return fs$1.existsSync(path$1.join(os.homedir(), ...segments));
2510
+ return fs$1.existsSync(path$2.join(os.homedir(), ...segments));
2482
2511
  } catch {
2483
2512
  return false;
2484
2513
  }
@@ -2487,19 +2516,19 @@ const CLI_STEERING_TARGETS = [
2487
2516
  {
2488
2517
  id: "claude-code",
2489
2518
  name: "Claude Code",
2490
- instructionsPath: () => path$1.join(os.homedir(), ".claude", "CLAUDE.md"),
2519
+ instructionsPath: () => path$2.join(os.homedir(), ".claude", "CLAUDE.md"),
2491
2520
  isDetected: () => dirExists(".claude")
2492
2521
  },
2493
2522
  {
2494
2523
  id: "codex",
2495
2524
  name: "Codex",
2496
- instructionsPath: () => path$1.join(os.homedir(), ".codex", "AGENTS.md"),
2525
+ instructionsPath: () => path$2.join(os.homedir(), ".codex", "AGENTS.md"),
2497
2526
  isDetected: () => dirExists(".codex")
2498
2527
  },
2499
2528
  {
2500
2529
  id: "gemini",
2501
2530
  name: "Gemini CLI",
2502
- instructionsPath: () => path$1.join(os.homedir(), ".gemini", "GEMINI.md"),
2531
+ instructionsPath: () => path$2.join(os.homedir(), ".gemini", "GEMINI.md"),
2503
2532
  isDetected: () => dirExists(".gemini")
2504
2533
  }
2505
2534
  ];
@@ -2844,6 +2873,7 @@ const SELF_DRIVING_ABORT_CASES = [
2844
2873
  },
2845
2874
  {
2846
2875
  match: /^requires-interactive-mode$/i,
2876
+ errorCode: ErrorCodes.CliInteractiveRequired,
2847
2877
  message: "Interactive terminal required",
2848
2878
  body: "Self-driving setup asks questions along the way (GitHub and issue trackers), so it needs an interactive terminal. Run the wizard outside CI / non-interactive mode."
2849
2879
  },
@@ -3857,6 +3887,29 @@ const mcpTutorialConfig = {
3857
3887
  //#region src/lib/programs/mcp-analytics/index.ts
3858
3888
  const MCP_ANALYTICS_REPORT_FILE = "posthog-mcp-analytics-report.md";
3859
3889
  /**
3890
+ * `[ABORT]` reasons the mcp-analytics skill emits when the project can't be
3891
+ * instrumented. Kept in sync with the stop conditions in the skill's
3892
+ * `description.md` (context-mill `context/skills/mcp-analytics`).
3893
+ */
3894
+ const MCP_ANALYTICS_ABORT_CASES = [
3895
+ {
3896
+ match: /^unsupported language for mcp analytics$/i,
3897
+ errorCode: ErrorCodes.DetectUnsupportedPlatform,
3898
+ message: "Unsupported language for MCP analytics",
3899
+ body: "MCP analytics supports TypeScript/JavaScript (`@posthog/mcp`) and Python (`posthog.mcp`, shipped inside the `posthog` package). This project doesn't look like either, so there's nothing to instrument. See https://posthog.com/docs/mcp-analytics for the supported setups."
3900
+ },
3901
+ {
3902
+ match: /^no mcp server found$/i,
3903
+ message: "No MCP server found",
3904
+ body: "This command instruments an existing MCP server with PostHog analytics, but no MCP server was found in this project. If you just want PostHog product analytics, run `npx @posthog/wizard` instead."
3905
+ },
3906
+ {
3907
+ match: /^could not locate the server entry point$/i,
3908
+ message: "Could not locate the MCP server entry point",
3909
+ body: "This project has MCP signals, but the agent couldn't find where the server is constructed or requests are dispatched, so there's nowhere safe to add instrumentation. See https://posthog.com/docs/mcp-analytics for the supported server styles, or point the wizard at the package that defines the server if it's in a monorepo subdirectory."
3910
+ }
3911
+ ];
3912
+ /**
3860
3913
  * `wizard mcp-analytics` — flat skill command.
3861
3914
  *
3862
3915
  * Instruments the user's own MCP server with the `@posthog/mcp` SDK so it
@@ -3882,23 +3935,7 @@ const mcpAnalyticsConfig = createSkillProgram({
3882
3935
  docsUrl: "https://posthog.com/docs/mcp-analytics",
3883
3936
  spinnerMessage: "Setting up MCP analytics...",
3884
3937
  estimatedDurationMinutes: 5,
3885
- abortCases: [
3886
- {
3887
- match: /^unsupported language for mcp analytics$/i,
3888
- message: "Unsupported language for MCP analytics",
3889
- body: "MCP analytics supports TypeScript/JavaScript (`@posthog/mcp`) and Python (`posthog.mcp`, shipped inside the `posthog` package). This project doesn't look like either, so there's nothing to instrument. See https://posthog.com/docs/mcp-analytics for the supported setups."
3890
- },
3891
- {
3892
- match: /^no mcp server found$/i,
3893
- message: "No MCP server found",
3894
- body: "This command instruments an existing MCP server with PostHog analytics, but no MCP server was found in this project. If you just want PostHog product analytics, run `npx @posthog/wizard` instead."
3895
- },
3896
- {
3897
- match: /^could not locate the server entry point$/i,
3898
- message: "Could not locate the MCP server entry point",
3899
- body: "This project has MCP signals, but the agent couldn't find where the server is constructed or requests are dispatched, so there's nowhere safe to add instrumentation. See https://posthog.com/docs/mcp-analytics for the supported server styles, or point the wizard at the package that defines the server if it's in a monorepo subdirectory."
3900
- }
3901
- ]
3938
+ abortCases: MCP_ANALYTICS_ABORT_CASES
3902
3939
  });
3903
3940
  //#endregion
3904
3941
  //#region src/lib/programs/replay-vision/index.ts
@@ -3936,8 +3973,10 @@ const REPLAY_VISION_SUPPORTED = new Set([
3936
3973
  "flutter"
3937
3974
  ]);
3938
3975
  async function abortUnsupportedPlatform(integration) {
3976
+ const name = FRAMEWORK_REGISTRY[integration]?.metadata.name ?? integration;
3939
3977
  await wizardAbort({
3940
- message: `Session replay isn't available for ${FRAMEWORK_REGISTRY[integration]?.metadata.name ?? integration} projects, and Replay vision needs session recordings to watch — so there is nothing to set up here.
3978
+ code: ErrorCodes.DetectUnsupportedPlatform,
3979
+ message: `Session replay isn't available for ${name} projects, and Replay vision needs session recordings to watch — so there is nothing to set up here.
3941
3980
 
3942
3981
  If this repo also contains a web or mobile app, run the command from that project directory instead. See what replay supports at:
3943
3982
  https://posthog.com/docs/session-replay`,
@@ -4016,7 +4055,10 @@ const replayVisionConfig = {
4016
4055
  await scopeInstallDirToProject(session);
4017
4056
  const integration = await detectFramework(session.installDir);
4018
4057
  if (!integration) {
4019
- await wizardAbort({ message: "Could not auto-detect your framework for this project." });
4058
+ await wizardAbort({
4059
+ code: ErrorCodes.DetectNoFramework,
4060
+ message: "Could not auto-detect your framework for this project."
4061
+ });
4020
4062
  return;
4021
4063
  }
4022
4064
  if (!REPLAY_VISION_SUPPORTED.has(integration)) {
@@ -4275,20 +4317,30 @@ const mcpAddCommand = {
4275
4317
  "api-key": {
4276
4318
  describe: "PostHog personal API key (phx_xxx) for MCP authentication",
4277
4319
  type: "string"
4278
- }
4320
+ },
4321
+ ...headlessOption
4279
4322
  },
4280
4323
  handler: runMcpAdd
4281
4324
  };
4282
4325
  function runMcpAdd(argv) {
4283
4326
  const features = parseFeatures(argv.features);
4284
4327
  (async () => {
4285
- const { readApiKeyFromEnv } = await import("./env-api-key-CdI2XZIz.js").then((n) => n.t);
4328
+ const { readApiKeyFromEnv } = await import("./env-api-key-DS0ghlcO.js").then((n) => n.t);
4286
4329
  const apiKey = argv.apiKey || readApiKeyFromEnv();
4287
4330
  const debug = argv.debug;
4288
4331
  const localMcp = argv.local;
4332
+ const args = {
4333
+ local: localMcp,
4334
+ features,
4335
+ apiKey
4336
+ };
4337
+ if (isHeadless(argv)) {
4338
+ await runHeadlessAdd(args);
4339
+ return;
4340
+ }
4289
4341
  try {
4290
- const { startTUI } = await import("./start-tui-DDW9uVnD.js");
4291
- const { buildSession } = await import("./wizard-session-UxA_A0cA.js");
4342
+ const { startTUI } = await import("./start-tui-B5YfmqNr.js");
4343
+ const { buildSession } = await import("./wizard-session-DHbUcjI7.js");
4292
4344
  const tui = startTUI(VERSION, Program.McpAdd);
4293
4345
  tui.store.session = buildSession({
4294
4346
  debug,
@@ -4299,16 +4351,16 @@ function runMcpAdd(argv) {
4299
4351
  });
4300
4352
  } catch (error) {
4301
4353
  if (!isTUIUnavailable(error)) throw error;
4302
- setUI(new LoggingUI());
4303
- const { addMCPServerToClientsStep } = await import("./add-mcp-server-to-clients-ArtlMX9-.js").then((n) => n.r);
4304
- await addMCPServerToClientsStep({
4305
- local: localMcp,
4306
- features,
4307
- apiKey
4308
- });
4354
+ await runHeadlessAdd(args);
4309
4355
  }
4310
4356
  })();
4311
4357
  }
4358
+ async function runHeadlessAdd(args) {
4359
+ setUI(new LoggingUI());
4360
+ const { addMCPServerToClientsStep } = await import("./add-mcp-server-to-clients-DHTRbyJX.js").then((n) => n.r);
4361
+ const { installed, failed } = await addMCPServerToClientsStep(args);
4362
+ if (failed.length > 0 || installed.length === 0) process.exitCode = 1;
4363
+ }
4312
4364
  function parseFeatures(raw) {
4313
4365
  if (typeof raw !== "string") return void 0;
4314
4366
  return raw.split(",").map((s) => s.trim()).filter(Boolean);
@@ -4318,20 +4370,27 @@ function parseFeatures(raw) {
4318
4370
  const mcpRemoveCommand = {
4319
4371
  name: "remove",
4320
4372
  description: "Remove PostHog MCP server from supported clients",
4321
- options: { local: {
4322
- default: false,
4323
- describe: "Remove local development MCP server (http://localhost:8787)",
4324
- type: "boolean"
4325
- } },
4373
+ options: {
4374
+ local: {
4375
+ default: false,
4376
+ describe: "Remove local development MCP server (http://localhost:8787)",
4377
+ type: "boolean"
4378
+ },
4379
+ ...headlessOption
4380
+ },
4326
4381
  handler: runMcpRemove
4327
4382
  };
4328
4383
  function runMcpRemove(argv) {
4329
4384
  (async () => {
4330
4385
  const debug = argv.debug;
4331
4386
  const localMcp = argv.local;
4387
+ if (isHeadless(argv)) {
4388
+ await runHeadlessRemove(localMcp);
4389
+ return;
4390
+ }
4332
4391
  try {
4333
- const { startTUI } = await import("./start-tui-DDW9uVnD.js");
4334
- const { buildSession } = await import("./wizard-session-UxA_A0cA.js");
4392
+ const { startTUI } = await import("./start-tui-B5YfmqNr.js");
4393
+ const { buildSession } = await import("./wizard-session-DHbUcjI7.js");
4335
4394
  const tui = startTUI(VERSION, Program.McpRemove);
4336
4395
  tui.store.session = buildSession({
4337
4396
  debug,
@@ -4340,12 +4399,16 @@ function runMcpRemove(argv) {
4340
4399
  });
4341
4400
  } catch (error) {
4342
4401
  if (!isTUIUnavailable(error)) throw error;
4343
- setUI(new LoggingUI());
4344
- const { removeMCPServerFromClientsStep } = await import("./add-mcp-server-to-clients-ArtlMX9-.js").then((n) => n.r);
4345
- await removeMCPServerFromClientsStep({ local: localMcp });
4402
+ await runHeadlessRemove(localMcp);
4346
4403
  }
4347
4404
  })();
4348
4405
  }
4406
+ /** No exit code on an empty result: nothing to remove is the requested end state. */
4407
+ async function runHeadlessRemove(local) {
4408
+ setUI(new LoggingUI());
4409
+ const { removeMCPServerFromClientsStep } = await import("./add-mcp-server-to-clients-DHTRbyJX.js").then((n) => n.r);
4410
+ await removeMCPServerFromClientsStep({ local });
4411
+ }
4349
4412
  //#endregion
4350
4413
  //#region src/commands/mcp/tutorial.ts
4351
4414
  const mcpTutorialCommand = {
@@ -4363,8 +4426,8 @@ function runMcpTutorial(argv) {
4363
4426
  const debug = argv.debug;
4364
4427
  const localMcp = argv.local;
4365
4428
  try {
4366
- const { startTUI } = await import("./start-tui-DDW9uVnD.js");
4367
- const { buildSession } = await import("./wizard-session-UxA_A0cA.js");
4429
+ const { startTUI } = await import("./start-tui-B5YfmqNr.js");
4430
+ const { buildSession } = await import("./wizard-session-DHbUcjI7.js");
4368
4431
  const tui = startTUI(VERSION, Program.McpTutorial);
4369
4432
  tui.store.session = buildSession({
4370
4433
  debug,
@@ -4374,6 +4437,10 @@ function runMcpTutorial(argv) {
4374
4437
  } catch (err) {
4375
4438
  setUI(new LoggingUI());
4376
4439
  getUI().log.error(`The MCP tutorial requires an interactive terminal. ${err instanceof Error ? err.message : String(err)}`);
4440
+ emitWizardError({
4441
+ code: ErrorCodes.CliInteractiveRequired,
4442
+ message: "The MCP tutorial requires an interactive terminal."
4443
+ });
4377
4444
  process.exit(1);
4378
4445
  }
4379
4446
  })();
@@ -4445,17 +4512,17 @@ function runWizard(config, options) {
4445
4512
  (async () => {
4446
4513
  try {
4447
4514
  const installDir = options.installDir || process.cwd();
4448
- const { startTUI } = await import("./start-tui-DDW9uVnD.js");
4449
- const { buildSession, RunPhase } = await import("./wizard-session-UxA_A0cA.js");
4450
- const { TaskStreamPush } = await import("./task-stream-BK7JQ27G.js");
4451
- const { PostHogDestination } = await import("./posthog-9To56cSd.js");
4515
+ const { startTUI } = await import("./start-tui-B5YfmqNr.js");
4516
+ const { buildSession, RunPhase } = await import("./wizard-session-DHbUcjI7.js");
4517
+ const { TaskStreamPush } = await import("./task-stream-DSzvwJrD.js");
4518
+ const { PostHogDestination } = await import("./posthog-DSn9bIZc.js");
4452
4519
  const local = getLocalDev();
4453
4520
  const localServicesError = await checkLocalServices({
4454
4521
  ...local,
4455
4522
  localPosthog: local.localPosthog && !options.baseUrl
4456
4523
  });
4457
4524
  if (localServicesError) {
4458
- const { wizardAbort } = await import("./wizard-abort-BlDla_Jd.js");
4525
+ const { wizardAbort } = await import("./wizard-abort-BsNbguJt.js");
4459
4526
  await wizardAbort({ message: localServicesError });
4460
4527
  return;
4461
4528
  }
@@ -4526,7 +4593,7 @@ function runWizard(config, options) {
4526
4593
  if (shown(step)) await advanceStep(step, activeTui.store, config);
4527
4594
  }
4528
4595
  else if (skipAgent) {
4529
- const { getOrAskForProjectData } = await import("./setup-utils-Cz0wPLsQ.js").then((n) => n.r);
4596
+ const { getOrAskForProjectData } = await import("./setup-utils-D1tv0v_R.js").then((n) => n.r);
4530
4597
  const { projectApiKey, host, accessToken, projectId } = await getOrAskForProjectData({
4531
4598
  signup: session.signup,
4532
4599
  ci: session.ci,
@@ -4577,6 +4644,10 @@ function runWizard(config, options) {
4577
4644
  } catch {}
4578
4645
  console.error("Wizard run failed:", err);
4579
4646
  console.error(`Full logs: ${getLogFilePath()}`);
4647
+ emitWizardError({
4648
+ code: ErrorCodes.InternalUnhandled,
4649
+ message: err instanceof Error ? err.message : String(err)
4650
+ });
4580
4651
  process.exit(1);
4581
4652
  }
4582
4653
  })();
@@ -4599,11 +4670,19 @@ function validateNonInteractiveOptions(options, mode) {
4599
4670
  if (!options.apiKey) {
4600
4671
  getUI().intro("PostHog Wizard");
4601
4672
  getUI().log.error(`${label} mode requires --api-key (${keyHint})`);
4673
+ emitWizardError({
4674
+ code: ErrorCodes.ArgsMissingApiKey,
4675
+ message: `${label} mode requires --api-key (${keyHint})`
4676
+ });
4602
4677
  process.exit(1);
4603
4678
  }
4604
4679
  if (!options.installDir) {
4605
4680
  getUI().intro("PostHog Wizard");
4606
4681
  getUI().log.error(`${label} mode requires --install-dir (directory to install in)`);
4682
+ emitWizardError({
4683
+ code: ErrorCodes.ArgsMissingInstallDir,
4684
+ message: `${label} mode requires --install-dir`
4685
+ });
4607
4686
  process.exit(1);
4608
4687
  }
4609
4688
  }
@@ -4627,11 +4706,11 @@ function runNonInteractive(config, options, mode) {
4627
4706
  analytics.setTag("build", mode);
4628
4707
  (async () => {
4629
4708
  const path = await import("path");
4630
- const { buildSession, RunPhase, OutroKind } = await import("./wizard-session-UxA_A0cA.js");
4631
- const { readEnvironment } = await import("./environment-BhFvfkQg.js").then((n) => n.t);
4632
- const { readApiKeyFromEnv } = await import("./env-api-key-CdI2XZIz.js").then((n) => n.t);
4633
- const { configureLogFileFromEnvironment, logToFile } = await import("./debug-CtQ13sCW.js");
4634
- const { wizardAbort, WizardError } = await import("./wizard-abort-BlDla_Jd.js");
4709
+ const { buildSession, RunPhase, OutroKind } = await import("./wizard-session-DHbUcjI7.js");
4710
+ const { readEnvironment } = await import("./environment-C7CKGIOE.js").then((n) => n.t);
4711
+ const { readApiKeyFromEnv } = await import("./env-api-key-DS0ghlcO.js").then((n) => n.t);
4712
+ const { configureLogFileFromEnvironment, logToFile } = await import("./debug-mO3yg4Z7.js");
4713
+ const { wizardAbort, WizardError } = await import("./wizard-abort-BsNbguJt.js");
4635
4714
  configureLogFileFromEnvironment();
4636
4715
  const env = readEnvironment();
4637
4716
  const apiKey = options.apiKey ?? readApiKeyFromEnv() ?? void 0;
@@ -4669,15 +4748,18 @@ function runNonInteractive(config, options, mode) {
4669
4748
  localPosthog: session.baseUrl === POSTHOG_LOCAL_URL
4670
4749
  });
4671
4750
  if (localServicesError) {
4672
- await wizardAbort({ message: localServicesError });
4751
+ await wizardAbort({
4752
+ code: ErrorCodes.EnvLocalServicesDown,
4753
+ message: localServicesError
4754
+ });
4673
4755
  return;
4674
4756
  }
4675
4757
  let store = null;
4676
4758
  let taskStream = null;
4677
4759
  if (mode === "headless") {
4678
- const { WizardStore } = await import("./store-xMkU8xAa.js").then((n) => n.n);
4679
- const { HeadlessUI } = await import("./headless-ui-B4FnKm11.js");
4680
- const { TaskStreamPush, PostHogDestination } = await import("./task-stream-BK7JQ27G.js");
4760
+ const { WizardStore } = await import("./store-DzEgsAPN.js").then((n) => n.n);
4761
+ const { HeadlessUI } = await import("./headless-ui-6QuByWZ_.js");
4762
+ const { TaskStreamPush, PostHogDestination } = await import("./task-stream-DSzvwJrD.js");
4681
4763
  store = new WizardStore(config.id);
4682
4764
  store.session = session;
4683
4765
  setUI(new HeadlessUI(store));
@@ -4713,27 +4795,54 @@ function runNonInteractive(config, options, mode) {
4713
4795
  setSkillId: (skillId) => {
4714
4796
  session.skillId = skillId;
4715
4797
  },
4716
- setUnsupportedVersion: () => void 0,
4798
+ setUnsupportedVersion: (info) => {
4799
+ session.unsupportedVersion = info;
4800
+ },
4717
4801
  addDiscoveredFeature: () => void 0,
4718
4802
  setDetectionComplete: () => void 0
4719
4803
  };
4720
4804
  for (const step of config.steps) if (step.onReady) await step.onReady(readyCtx);
4721
4805
  const detectError = session.frameworkContext.detectError;
4806
+ if (session.unsupportedVersion) {
4807
+ const { current, minimum, docsUrl } = session.unsupportedVersion;
4808
+ const message = `Detected framework version ${current} is not supported. Minimum supported version is ${minimum}.`;
4809
+ await settleStream(RunPhase.Error, {
4810
+ kind: OutroKind.Error,
4811
+ message,
4812
+ errorCode: ErrorCodes.DetectUnsupportedVersion
4813
+ });
4814
+ await wizardAbort({
4815
+ code: ErrorCodes.DetectUnsupportedVersion,
4816
+ message: `${message}\n\nSee ${docsUrl}`,
4817
+ error: new WizardError(`${config.id} unsupported framework version`, {
4818
+ integration: config.id,
4819
+ current,
4820
+ minimum
4821
+ }, ErrorCodes.DetectUnsupportedVersion)
4822
+ });
4823
+ }
4722
4824
  if (detectError) {
4825
+ const code = detectErrorCode(detectError.kind);
4826
+ const detectKind = detectError.kind;
4827
+ const detail = { ...detectError };
4723
4828
  await settleStream(RunPhase.Error, {
4724
4829
  kind: OutroKind.Error,
4725
- message: `Prerequisites not met: ${detectError.kind}`
4830
+ message: `Prerequisites not met: ${detectKind}`,
4831
+ errorCode: code,
4832
+ errorDetail: detail
4726
4833
  });
4727
4834
  await wizardAbort({
4728
- message: `Prerequisites not met: ${detectError.kind}\n\nSee ${runDef?.docsUrl ?? "https://posthog.com/docs"}`,
4835
+ code,
4836
+ detail,
4837
+ message: `Prerequisites not met: ${detectKind}\n\nSee ${runDef?.docsUrl ?? "https://posthog.com/docs"}`,
4729
4838
  error: new WizardError(`${config.id} prerequisites failed`, {
4730
4839
  integration: config.id,
4731
- detect_error_kind: detectError.kind
4732
- })
4840
+ detect_error_kind: detectKind
4841
+ }, code)
4733
4842
  });
4734
4843
  }
4735
4844
  }
4736
- const { runAgent } = await import("./agent-runner-Ca-e2TOQ.js").then((n) => n.t);
4845
+ const { runAgent } = await import("./agent-runner-DD65OMkB.js").then((n) => n.t);
4737
4846
  await runAgent(config, session);
4738
4847
  await settleStream(RunPhase.Completed);
4739
4848
  } catch (error) {
@@ -4745,14 +4854,20 @@ function runNonInteractive(config, options, mode) {
4745
4854
  const docsUrl = session.frameworkConfig?.metadata.docsUrl ?? runDef?.docsUrl ?? "https://posthog.com/docs";
4746
4855
  await settleStream(RunPhase.Error, {
4747
4856
  kind: OutroKind.Error,
4748
- message: errorMessage
4857
+ message: errorMessage,
4858
+ errorCode: ErrorCodes.InternalUnhandled
4749
4859
  });
4750
4860
  await wizardAbort({
4861
+ code: ErrorCodes.InternalUnhandled,
4751
4862
  message: `Something went wrong: ${errorMessage}\n\nYou can read the documentation at ${docsUrl} to set up manually.${debugInfo}`,
4752
4863
  error
4753
4864
  });
4754
4865
  }
4755
- })().catch(() => {
4866
+ })().catch((error) => {
4867
+ emitWizardError({
4868
+ code: ErrorCodes.InternalUnhandled,
4869
+ message: error instanceof Error ? error.message : String(error)
4870
+ });
4756
4871
  process.exit(1);
4757
4872
  });
4758
4873
  }
@@ -4818,12 +4933,16 @@ function runCommandHandler(work) {
4818
4933
  } catch (err) {
4819
4934
  const msg = err instanceof Error ? err.message : String(err);
4820
4935
  process.stderr.write(`\n\x1b[1;91m✖ ${msg}\x1b[0m\n\n`);
4936
+ emitWizardError({
4937
+ code: ErrorCodes.InternalUnhandled,
4938
+ message: msg
4939
+ });
4821
4940
  process.exit(1);
4822
4941
  }
4823
4942
  })();
4824
4943
  }
4825
4944
  function dispatchProgram(config, argv) {
4826
- const argvRecord = argv;
4945
+ const argvRecord = { ...argv };
4827
4946
  const extras = config.mapCliOptions?.(argvRecord) ?? {};
4828
4947
  const options = {
4829
4948
  ...argvRecord,
@@ -4929,6 +5048,10 @@ async function exitDispatchError(reason, properties, message, code = 1) {
4929
5048
  await analytics.flush();
4930
5049
  } catch {}
4931
5050
  process.stderr.write(message);
5051
+ emitWizardError({
5052
+ code: ErrorCodes.CliBadArgs,
5053
+ message: reason
5054
+ });
4932
5055
  return process.exit(code);
4933
5056
  }
4934
5057
  /**
@@ -5957,12 +6080,16 @@ async function runDoctorCI(options) {
5957
6080
  if (!apiKey) {
5958
6081
  getUI().intro("PostHog Wizard");
5959
6082
  getUI().log.error("CI mode requires --api-key (personal API key phx_xxx)");
6083
+ emitWizardError({
6084
+ code: ErrorCodes.ArgsMissingApiKey,
6085
+ message: "CI mode requires --api-key (personal API key phx_xxx)"
6086
+ });
5960
6087
  process.exit(1);
5961
6088
  }
5962
6089
  getUI().intro("Welcome to the PostHog setup wizard");
5963
6090
  getUI().log.info("Running posthog-doctor in CI mode");
5964
6091
  try {
5965
- const { getOrAskForProjectData } = await import("./setup-utils-Cz0wPLsQ.js").then((n) => n.r);
6092
+ const { getOrAskForProjectData } = await import("./setup-utils-D1tv0v_R.js").then((n) => n.r);
5966
6093
  const { host, accessToken, projectId } = await getOrAskForProjectData({
5967
6094
  signup: false,
5968
6095
  ci: true,
@@ -5980,9 +6107,13 @@ async function runDoctorCI(options) {
5980
6107
  for (const issue of sorted) getUI().log.info(` • [${issue.severity}] ${getKindMeta(issue.kind).title}`);
5981
6108
  process.exit(1);
5982
6109
  } catch (error) {
5983
- const { ApiError } = await import("./api-Wgb7AhrP.js").then((n) => n.n);
6110
+ const { ApiError } = await import("./api-BJft9v6K.js").then((n) => n.n);
5984
6111
  const message = error instanceof ApiError && error.statusCode === 401 ? "Your PostHog API key is invalid or expired." : error instanceof Error ? error.message : String(error);
5985
6112
  getUI().log.error(`Doctor failed: ${message}`);
6113
+ emitWizardError({
6114
+ code: error instanceof ApiError && error.statusCode === 401 ? ErrorCodes.AuthInvalidOrExpired : ErrorCodes.InternalUnhandled,
6115
+ message
6116
+ });
5986
6117
  process.exit(1);
5987
6118
  }
5988
6119
  }
@@ -6062,8 +6193,8 @@ function runSlackConnect(argv) {
6062
6193
  (async () => {
6063
6194
  const debug = argv.debug;
6064
6195
  try {
6065
- const { startTUI } = await import("./start-tui-DDW9uVnD.js");
6066
- const { buildSession } = await import("./wizard-session-UxA_A0cA.js");
6196
+ const { startTUI } = await import("./start-tui-B5YfmqNr.js");
6197
+ const { buildSession } = await import("./wizard-session-DHbUcjI7.js");
6067
6198
  const tui = startTUI(VERSION, Program.SlackConnect);
6068
6199
  tui.store.session = buildSession({
6069
6200
  debug,
@@ -6072,6 +6203,10 @@ function runSlackConnect(argv) {
6072
6203
  } catch (err) {
6073
6204
  setUI(new LoggingUI());
6074
6205
  getUI().log.error(`Connecting Slack requires an interactive terminal. ${err instanceof Error ? err.message : String(err)}`);
6206
+ emitWizardError({
6207
+ code: ErrorCodes.CliInteractiveRequired,
6208
+ message: "Connecting Slack requires an interactive terminal."
6209
+ });
6075
6210
  process.exit(1);
6076
6211
  }
6077
6212
  })();
@@ -6189,6 +6324,10 @@ const skillCommand = {
6189
6324
  await analytics.flush();
6190
6325
  } catch {}
6191
6326
  process.stderr.write("\n\x1B[1;91m✖ Couldn't reach the skill registry.\x1B[0m\n Check your network connection and try again.\n\n");
6327
+ emitWizardError({
6328
+ code: ErrorCodes.SkillMenuFetchFailed,
6329
+ message: "Couldn't reach the skill registry."
6330
+ });
6192
6331
  process.exit(1);
6193
6332
  }
6194
6333
  const entries = (menu.cliEntries ?? []).filter((e) => BROWSABLE_ROLES.has(e.role));
@@ -6305,7 +6444,7 @@ async function runCliAdd(argv) {
6305
6444
  /** Resolve which instruction files to write, from flags, detection, or a prompt. */
6306
6445
  async function resolveTargetFiles(argv) {
6307
6446
  const ui = getUI();
6308
- if (typeof argv.path === "string" && argv.path.trim()) return [path$1.resolve(argv.path.trim())];
6447
+ if (typeof argv.path === "string" && argv.path.trim()) return [path$2.resolve(argv.path.trim())];
6309
6448
  if (typeof argv.agent === "string") {
6310
6449
  const target = findTarget(argv.agent);
6311
6450
  if (!target) {
@@ -6382,6 +6521,10 @@ if (!satisfies(process.version, NODE_VERSION_RANGE)) {
6382
6521
  ``,
6383
6522
  `Then run the wizard again. Stuck? Email wizard@posthog.com and we'll help.`
6384
6523
  ].join("\n"));
6524
+ emitWizardError({
6525
+ code: ErrorCodes.CliNodeVersion,
6526
+ message: `Node ${process.version} is below the required range ${NODE_VERSION_RANGE}`
6527
+ });
6385
6528
  process.exit(1);
6386
6529
  }
6387
6530
  recoverOrphanedSettingsBackups(resolveInstallDir());