@posthog/wizard 2.79.0 → 2.79.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 (142) hide show
  1. package/dist/PickerMenu-dG5DQCZA.js +758 -0
  2. package/dist/PickerMenu-dG5DQCZA.js.map +1 -0
  3. package/dist/{add-mcp-server-to-clients-amlJWW7W.js → add-mcp-server-to-clients-DIaTRWMY.js} +7 -18
  4. package/dist/{add-mcp-server-to-clients-amlJWW7W.js.map → add-mcp-server-to-clients-DIaTRWMY.js.map} +1 -1
  5. package/dist/add-mcp-server-to-clients-artmN7mz.js +2 -0
  6. package/dist/agent-BEjARD2a.js +6 -0
  7. package/dist/{agent-CNrEC-9v.js → agent-BWFhuLgo.js} +18 -24
  8. package/dist/{agent-CNrEC-9v.js.map → agent-BWFhuLgo.js.map} +1 -1
  9. package/dist/{agent-interface-BXvmAm4c.js → agent-interface-FkbaBJwz.js} +29 -17
  10. package/dist/agent-interface-FkbaBJwz.js.map +1 -0
  11. package/dist/{agent-prompt-loader-DiKUbhi_.js → agent-prompt-loader-D0weQ-7k.js} +5 -5
  12. package/dist/{agent-prompt-loader-DiKUbhi_.js.map → agent-prompt-loader-D0weQ-7k.js.map} +1 -1
  13. package/dist/analytics-DFtbRjYh.js +2 -0
  14. package/dist/{analytics-VRYdebXW.js → analytics-DXK1gc12.js} +4 -4
  15. package/dist/{analytics-VRYdebXW.js.map → analytics-DXK1gc12.js.map} +1 -1
  16. package/dist/api-Cm9UtKZh.js +2 -0
  17. package/dist/{api-DGuJTzjr.js → api-CrbCIQOz.js} +4 -16
  18. package/dist/{api-DGuJTzjr.js.map → api-CrbCIQOz.js.map} +1 -1
  19. package/dist/bin.js +5 -2960
  20. package/dist/bin.js.map +1 -1
  21. package/dist/{bounded-fs-Cpn129A4.js → bounded-fs-vAq-T-K7.js} +3 -3
  22. package/dist/{bounded-fs-Cpn129A4.js.map → bounded-fs-vAq-T-K7.js.map} +1 -1
  23. package/dist/{ci-install-BPA6gzEq.js → ci-install-COcV8SY2.js} +8 -7
  24. package/dist/{ci-install-BPA6gzEq.js.map → ci-install-COcV8SY2.js.map} +1 -1
  25. package/dist/{constants-CuJfQEcC.js → constants-DHCBSfnx.js} +3 -3
  26. package/dist/{constants-CuJfQEcC.js.map → constants-DHCBSfnx.js.map} +1 -1
  27. package/dist/{debug-B9k4ideV.js → debug-BuYHGr6_.js} +1 -1
  28. package/dist/{debug-Cj-8vfXY.js → debug-kAHwWGg7.js} +2 -2
  29. package/dist/{debug-Cj-8vfXY.js.map → debug-kAHwWGg7.js.map} +1 -1
  30. package/dist/{defaults-C6J7yL4O.js → defaults-a9TelDhJ.js} +1 -1
  31. package/dist/{defaults-C6J7yL4O.js.map → defaults-a9TelDhJ.js.map} +1 -1
  32. package/dist/emit-BSetXzDV.js +69 -0
  33. package/dist/emit-BSetXzDV.js.map +1 -0
  34. package/dist/{endpoints-DnIX0pZH.js → endpoints-BVMYm9F4.js} +3 -3
  35. package/dist/{endpoints-DnIX0pZH.js.map → endpoints-BVMYm9F4.js.map} +1 -1
  36. package/dist/{env-api-key-BWdKpGEr.js → env-api-key-BP-NFFXt.js} +3 -5
  37. package/dist/{env-api-key-BWdKpGEr.js.map → env-api-key-BP-NFFXt.js.map} +1 -1
  38. package/dist/env-api-key-CaWEDj_9.js +2 -0
  39. package/dist/{environment-DZYUSCpV.js → environment-BATlQxcQ.js} +5 -10
  40. package/dist/{environment-DZYUSCpV.js.map → environment-BATlQxcQ.js.map} +1 -1
  41. package/dist/environment-CwD8OPYj.js +2 -0
  42. package/dist/{errors-ddDE6MbA.js → errors-C2domSkK.js} +3 -67
  43. package/dist/errors-C2domSkK.js.map +1 -0
  44. package/dist/file-C5JMsyR1.js +2 -0
  45. package/dist/{file-dEhr-l3n.js → file-DcRKycV8.js} +3 -3
  46. package/dist/{file-dEhr-l3n.js.map → file-DcRKycV8.js.map} +1 -1
  47. package/dist/{file-watcher-CPM-Nn9L.js → file-watcher-Brq2nnHV.js} +2 -2
  48. package/dist/{file-watcher-CPM-Nn9L.js.map → file-watcher-Brq2nnHV.js.map} +1 -1
  49. package/dist/{gateway-CVU1G0H3.js → gateway-C9-GlLO9.js} +8 -7
  50. package/dist/{gateway-CVU1G0H3.js.map → gateway-C9-GlLO9.js.map} +1 -1
  51. package/dist/{headless-ui-pY2xB5ug.js → headless-ui-CqI2gXlD.js} +2 -2
  52. package/dist/{headless-ui-pY2xB5ug.js.map → headless-ui-CqI2gXlD.js.map} +1 -1
  53. package/dist/{interactive-BOGlinZe.js → interactive-B_Ti_CsS.js} +3 -3
  54. package/dist/{interactive-BOGlinZe.js.map → interactive-B_Ti_CsS.js.map} +1 -1
  55. package/dist/{logging-ui-CUxNYF2t.js → logging-ui-Dza4D0MK.js} +5 -5
  56. package/dist/{logging-ui-CUxNYF2t.js.map → logging-ui-Dza4D0MK.js.map} +1 -1
  57. package/dist/main-CgKxbwMP.js +1396 -0
  58. package/dist/main-CgKxbwMP.js.map +1 -0
  59. package/dist/{mcp-JcsBBnWv.js → mcp-DnAyW0-w.js} +4 -4
  60. package/dist/{mcp-JcsBBnWv.js.map → mcp-DnAyW0-w.js.map} +1 -1
  61. package/dist/{mcp-prompt-streaming-B-p_Pvb2.js → mcp-prompt-streaming-DDWQ-FCA.js} +6 -6
  62. package/dist/{mcp-prompt-streaming-B-p_Pvb2.js.map → mcp-prompt-streaming-DDWQ-FCA.js.map} +1 -1
  63. package/dist/{mint-failure-CZFZpHpW.js → mint-failure-u8xQKNOn.js} +23 -22
  64. package/dist/{mint-failure-CZFZpHpW.js.map → mint-failure-u8xQKNOn.js.map} +1 -1
  65. package/dist/{models-DnAY67Lg.js → models-WcwUnSKb.js} +2 -2
  66. package/dist/{models-DnAY67Lg.js.map → models-WcwUnSKb.js.map} +1 -1
  67. package/dist/{non-interactive-DR1CWXY1.js → non-interactive-DyVC1AGc.js} +4 -3
  68. package/dist/{non-interactive-DR1CWXY1.js.map → non-interactive-DyVC1AGc.js.map} +1 -1
  69. package/dist/{oauth-session-CQTFOk-I.js → oauth-session-DYM2Hrl2.js} +2 -2
  70. package/dist/{oauth-session-CQTFOk-I.js.map → oauth-session-DYM2Hrl2.js.map} +1 -1
  71. package/dist/{orchestrator-tools-CBdt-SXO.js → orchestrator-tools-DbgNBFGA.js} +3 -3
  72. package/dist/{orchestrator-tools-CBdt-SXO.js.map → orchestrator-tools-DbgNBFGA.js.map} +1 -1
  73. package/dist/{package-json-DY70kkNp.js → package-json-Atg34fa4.js} +2 -8
  74. package/dist/{package-json-DY70kkNp.js.map → package-json-Atg34fa4.js.map} +1 -1
  75. package/dist/package-json-D8Ga03tK.js +2 -0
  76. package/dist/{pi-BtqcLX3y.js → pi-8KsYsPmM.js} +17 -16
  77. package/dist/{pi-BtqcLX3y.js.map → pi-8KsYsPmM.js.map} +1 -1
  78. package/dist/{playground-Dz-ZVjBk.js → playground-BlYRBMj7.js} +11 -11
  79. package/dist/{playground-Dz-ZVjBk.js.map → playground-BlYRBMj7.js.map} +1 -1
  80. package/dist/{posthog-6Uqw_Eux.js → posthog-Bt0Aplb8.js} +3 -8
  81. package/dist/{posthog-6Uqw_Eux.js.map → posthog-Bt0Aplb8.js.map} +1 -1
  82. package/dist/posthog-CUgCEhH0.js +2 -0
  83. package/dist/{provisioning-Zf7yPcEs.js → provisioning-Bo2NRxFz.js} +5 -11
  84. package/dist/{provisioning-Zf7yPcEs.js.map → provisioning-Bo2NRxFz.js.map} +1 -1
  85. package/dist/provisioning-OGFGlzf7.js +2 -0
  86. package/dist/{queue-tools-B7_aCyd-.js → queue-tools-C8mXOh7e.js} +3 -3
  87. package/dist/{queue-tools-B7_aCyd-.js.map → queue-tools-C8mXOh7e.js.map} +1 -1
  88. package/dist/registry-C06e_x-p.js +2 -0
  89. package/dist/{registry-B6iLGorH.js → registry-CD5RQt38.js} +7 -9
  90. package/dist/{registry-B6iLGorH.js.map → registry-CD5RQt38.js.map} +1 -1
  91. package/dist/run-agent-legacy-ChacZImU.js +2 -0
  92. package/dist/{run-agent-legacy-6WcYMaR9.js → run-agent-legacy-DOlM6DQu.js} +20 -21
  93. package/dist/{run-agent-legacy-6WcYMaR9.js.map → run-agent-legacy-DOlM6DQu.js.map} +1 -1
  94. package/dist/runners-ov3EXF1n.js +834 -0
  95. package/dist/runners-ov3EXF1n.js.map +1 -0
  96. package/dist/{security-lkBwWbrK.js → security-C71pkwqH.js} +5 -5
  97. package/dist/{security-lkBwWbrK.js.map → security-C71pkwqH.js.map} +1 -1
  98. package/dist/{setup-utils-dCViCC6s.js → setup-utils-B26Lf2yF.js} +11 -21
  99. package/dist/{setup-utils-dCViCC6s.js.map → setup-utils-B26Lf2yF.js.map} +1 -1
  100. package/dist/setup-utils-CVS86NYR.js +2 -0
  101. package/dist/{start-tui-oCWMgsDP.js → start-tui-Bo2L0bar.js} +28 -26
  102. package/dist/{start-tui-oCWMgsDP.js.map → start-tui-Bo2L0bar.js.map} +1 -1
  103. package/dist/{steps-gx0Pq4I4.js → steps-BPcg3_3Q.js} +7 -7
  104. package/dist/{steps-gx0Pq4I4.js.map → steps-BPcg3_3Q.js.map} +1 -1
  105. package/dist/{store-xYy_6Ruv.js → store-BTzcvRGT.js} +11 -17
  106. package/dist/{store-xYy_6Ruv.js.map → store-BTzcvRGT.js.map} +1 -1
  107. package/dist/store-BpqySPXm.js +5 -0
  108. package/dist/{subagent-Bfy0sfhU.js → subagent-D1TrTchE.js} +3 -3
  109. package/dist/{subagent-Bfy0sfhU.js.map → subagent-D1TrTchE.js.map} +1 -1
  110. package/dist/{task-BOfw7GPc.js → task-DqRlQBfs.js} +18 -16
  111. package/dist/task-DqRlQBfs.js.map +1 -0
  112. package/dist/{task-stream-kYlm9qd0.js → task-stream-Bw6JaLCX.js} +8 -8
  113. package/dist/{task-stream-kYlm9qd0.js.map → task-stream-Bw6JaLCX.js.map} +1 -1
  114. package/dist/{tasks-Bbv_lOBG.js → tasks-ChWufsdO.js} +1 -1
  115. package/dist/{tasks-Bbv_lOBG.js.map → tasks-ChWufsdO.js.map} +1 -1
  116. package/dist/{telemetry-Bpv-Mh5B.js → telemetry-B7zJdRmA.js} +3 -3
  117. package/dist/{telemetry-Bpv-Mh5B.js.map → telemetry-B7zJdRmA.js.map} +1 -1
  118. package/dist/{terminal-D07EQ2y0.js → terminal-zgkEfoCL.js} +15 -15
  119. package/dist/{terminal-D07EQ2y0.js.map → terminal-zgkEfoCL.js.map} +1 -1
  120. package/dist/{tools-Cc41af5W.js → tools-CkJ2y9Wt.js} +9 -9
  121. package/dist/tools-CkJ2y9Wt.js.map +1 -0
  122. package/dist/{ui-CGXtC7Vn.js → ui-Q6-RvERF.js} +3 -3
  123. package/dist/{ui-CGXtC7Vn.js.map → ui-Q6-RvERF.js.map} +1 -1
  124. package/dist/{version-Cadof0Z_.js → version-CHhJjz_H.js} +2 -2
  125. package/dist/{version-Cadof0Z_.js.map → version-CHhJjz_H.js.map} +1 -1
  126. package/dist/{wizard-abort-HDbP3YcS.js → wizard-abort-BPdv07np.js} +7 -6
  127. package/dist/{wizard-abort-HDbP3YcS.js.map → wizard-abort-BPdv07np.js.map} +1 -1
  128. package/dist/wizard-abort-Br1qMDNa.js +3 -0
  129. package/dist/{wizard-ui-DoyOZxK8.js → wizard-ui-DVqrYaOM.js} +1 -1
  130. package/dist/{wizard-ui-DoyOZxK8.js.map → wizard-ui-DVqrYaOM.js.map} +1 -1
  131. package/dist/{yara-hooks-DCfROpZt.js → yara-hooks-BnxejtXK.js} +5 -5
  132. package/dist/{yara-hooks-DCfROpZt.js.map → yara-hooks-BnxejtXK.js.map} +1 -1
  133. package/dist/yara-hooks-DSuExwb4.js +2 -0
  134. package/package.json +1 -1
  135. package/dist/agent-interface-BXvmAm4c.js.map +0 -1
  136. package/dist/analytics-DxwRi2Hf.js +0 -2
  137. package/dist/errors-ddDE6MbA.js.map +0 -1
  138. package/dist/rolldown-runtime-B_-DWIq7.js +0 -15
  139. package/dist/task-BOfw7GPc.js.map +0 -1
  140. package/dist/tools-Cc41af5W.js.map +0 -1
  141. package/dist/wizard-abort-Y-Ip2K4z.js +0 -3
  142. package/dist/yara-hooks-B49RIk5d.js +0 -2
@@ -0,0 +1,1396 @@
1
+ import { I as WIZARD_TOOL_NAMES, et as fetchSkillMenu, u as recoverOrphanedSettingsBackups } from "./agent-interface-FkbaBJwz.js";
2
+ import { n as ErrorCodes, t as emitWizardError } from "./emit-BSetXzDV.js";
3
+ import { b as isHeadless, x as regionOption, y as headlessOption } from "./debug-kAHwWGg7.js";
4
+ import { t as VERSION } from "./version-CHhJjz_H.js";
5
+ import { o as initLocalDev, s as localMcpSkillsNotice } from "./local-dev-McsurOC-.js";
6
+ import { $ as getSkillsBaseUrl, k as POSTHOG_DOCS_URL } from "./constants-DHCBSfnx.js";
7
+ import { n as analytics } from "./analytics-DXK1gc12.js";
8
+ import { r as setEntryCommand } from "./telemetry-B7zJdRmA.js";
9
+ import "./errors-C2domSkK.js";
10
+ import { t as LoggingUI } from "./logging-ui-Dza4D0MK.js";
11
+ import { n as setUI, t as getUI } from "./ui-Q6-RvERF.js";
12
+ import { t as isNonInteractiveEnvironment } from "./environment-BATlQxcQ.js";
13
+ import "./agent-BWFhuLgo.js";
14
+ import { h as AUDIT_CHECKS_FILE } from "./yara-hooks-BnxejtXK.js";
15
+ import { A as installOrUpdatePostHogCli, B as webAnalyticsDoctorConfig, D as CLI_STEERING_TARGETS, E as errorTrackingUploadSourceMapsConfig, G as createSkillProgram, H as getKindMeta, K as warehouseSourceConfig, O as detectTargets, S as errorTrackingConfig, T as replayVisionConfig, U as fetchHealthIssues, V as posthogDoctorConfig, W as auditConfig, d as metricsConfig, f as aiObservabilityConfig, j as installSteeringSnippet, k as findTarget, m as selfDrivingConfig, o as Program, p as mcpAnalyticsConfig, q as revenueAnalyticsConfig, rt as Colors, s as agentSkillConfig, z as migrationConfig } from "./mint-failure-u8xQKNOn.js";
16
+ import { i as runWizard, n as runWizardCI, t as runWizardHeadless } from "./runners-ov3EXF1n.js";
17
+ import { t as PickerMenu } from "./PickerMenu-dG5DQCZA.js";
18
+ import { t as readApiKeyFromEnv } from "./env-api-key-BP-NFFXt.js";
19
+ import { Agent, setGlobalDispatcher } from "undici";
20
+ import yargs from "yargs";
21
+ import { hideBin } from "yargs/helpers";
22
+ import * as path$1 from "node:path";
23
+ import { Box, Text, render } from "ink";
24
+ import { createElement } from "react";
25
+ import * as readline from "node:readline/promises";
26
+ //#region src/commands/command.ts
27
+ /** Extract the bare command word(s) from a yargs name spec, dropping positionals and aliases' arg syntax. */
28
+ function commandKeys(name) {
29
+ return (typeof name === "string" ? [name] : name).map((n) => n.trim().split(/\s+/)[0]);
30
+ }
31
+ function toCommandModule(cmd, parentPath) {
32
+ const entryCommand = [...parentPath, commandKeys(cmd.name)[0]].filter((key) => key !== "$0").join("-");
33
+ return {
34
+ command: cmd.name,
35
+ describe: cmd.description,
36
+ builder: (y) => {
37
+ let next = cmd.options ? y.options(cmd.options) : y;
38
+ for (const [key, opts] of Object.entries(cmd.positionals ?? {})) next = next.positional(key, opts);
39
+ if (cmd.check) next = next.check(cmd.check);
40
+ for (const [usage, description] of cmd.examples ?? []) next = next.example(usage, description);
41
+ const ownPath = [...parentPath, commandKeys(cmd.name)[0]];
42
+ for (const child of cmd.children ?? []) next = next.command(toCommandModule(child, ownPath));
43
+ if (cmd.children?.length && !cmd.handler && !cmd.interactiveDefault) next = next.demandCommand(1);
44
+ return next;
45
+ },
46
+ handler: (argv) => {
47
+ if (entryCommand) setEntryCommand(entryCommand);
48
+ (cmd.handler ?? cmd.interactiveDefault ?? (() => void 0))(argv);
49
+ }
50
+ };
51
+ }
52
+ //#endregion
53
+ //#region src/wizard.ts
54
+ /**
55
+ * Global yargs options applied to every command. These are read from the
56
+ * `POSTHOG_WIZARD` env prefix as well as flags.
57
+ *
58
+ * Options with `hidden: true` are "internal modes" — they don't show up in
59
+ * `--help` but are still accepted on every command. The `--local-*` flags live
60
+ * in the constructor's `!IS_PRODUCTION_BUILD` block instead, so published
61
+ * builds reject them; see `docs/local-dev.md`.
62
+ */
63
+ const GLOBAL_OPTIONS = {
64
+ debug: {
65
+ default: false,
66
+ describe: "Enable verbose logging\nenv: POSTHOG_WIZARD_DEBUG",
67
+ type: "boolean"
68
+ },
69
+ signup: {
70
+ default: false,
71
+ describe: "Create a new PostHog account during setup\nenv: POSTHOG_WIZARD_SIGNUP",
72
+ type: "boolean"
73
+ },
74
+ telemetry: {
75
+ default: true,
76
+ describe: "Send wizard run state to PostHog (pass --no-telemetry to disable)\nenv: POSTHOG_WIZARD_TELEMETRY",
77
+ type: "boolean"
78
+ },
79
+ "api-key": {
80
+ describe: "PostHog personal API key (phx_xxx) for authentication\nenv: POSTHOG_WIZARD_API_KEY",
81
+ type: "string"
82
+ },
83
+ "project-id": {
84
+ describe: "PostHog project ID to use (optional; when not set, uses default from API key or OAuth)\nenv: POSTHOG_WIZARD_PROJECT_ID",
85
+ type: "string"
86
+ },
87
+ email: {
88
+ describe: "Email address for signup (used with --signup)\nenv: POSTHOG_WIZARD_EMAIL",
89
+ type: "string"
90
+ },
91
+ "base-url": {
92
+ describe: "Override the PostHog base URL (e.g. http://localhost:8010), bypassing region resolution. Pins the API host, cloud URL, and OAuth server.\nenv: POSTHOG_WIZARD_BASE_URL",
93
+ type: "string",
94
+ hidden: true
95
+ },
96
+ "run-id": {
97
+ describe: "Assigned cloud WizardRun UUID",
98
+ type: "string",
99
+ hidden: true
100
+ },
101
+ benchmark: {
102
+ default: false,
103
+ describe: "Run in benchmark mode with per-phase token tracking\nenv: POSTHOG_WIZARD_BENCHMARK",
104
+ type: "boolean",
105
+ hidden: true
106
+ },
107
+ "yara-report": {
108
+ default: false,
109
+ describe: "Print YARA scanner summary after the agent run\nenv: POSTHOG_WIZARD_YARA_REPORT",
110
+ type: "boolean",
111
+ hidden: true
112
+ }
113
+ };
114
+ var Wizard = class Wizard {
115
+ cli;
116
+ constructor() {
117
+ let cli = yargs(hideBin(process.argv)).env("POSTHOG_WIZARD").options(GLOBAL_OPTIONS);
118
+ this.cli = cli.middleware((argv) => {
119
+ initLocalDev(argv);
120
+ const notice = localMcpSkillsNotice({
121
+ localDev: argv.localDev,
122
+ localMcp: argv.localMcp,
123
+ localContextMill: argv.localContextMill
124
+ });
125
+ if (notice) process.stderr.write(`\n\x1b[33m! ${notice}\x1b[0m\n\n`);
126
+ }).strictOptions().strictCommands().fail((msg, err) => {
127
+ const text = msg || err && err.message || "Invalid arguments";
128
+ process.stderr.write(`\n\x1b[1;91m✖ ${text}\x1b[0m\n Run \`wizard --help\` to see available commands and options.\n\n`);
129
+ emitWizardError({
130
+ code: ErrorCodes.CliBadArgs,
131
+ message: text
132
+ });
133
+ process.exit(1);
134
+ }).help().alias("help", "h").version().alias("version", "v");
135
+ }
136
+ /** Start a chain; equivalent to `new Wizard().use(...cmds)`. */
137
+ static use(...cmds) {
138
+ return new Wizard().use(...cmds);
139
+ }
140
+ /** Register one or more commands with yargs. */
141
+ use(...cmds) {
142
+ for (const cmd of cmds) this.cli = this.cli.command(toCommandModule(cmd, []));
143
+ return this;
144
+ }
145
+ /** Parse argv and dispatch to the matching registered command. */
146
+ init() {
147
+ {
148
+ const args = process.argv.slice(2);
149
+ const argvHasCI = args.some((a) => a === "--ci" || a === "--no-ci" || a.startsWith("--ci="));
150
+ const envHasCI = process.env.POSTHOG_WIZARD_CI != null && process.env.POSTHOG_WIZARD_CI !== "";
151
+ if (argvHasCI || envHasCI) {
152
+ process.stderr.write(`\n\x1b[1;91m✖ CI mode is not currently supported in published builds.\x1b[0m\n\n`);
153
+ emitWizardError({
154
+ code: ErrorCodes.CliFlagUnavailable,
155
+ message: "CI mode is not supported in published builds."
156
+ });
157
+ process.exit(1);
158
+ }
159
+ 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="));
160
+ 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 !== "";
161
+ if (argvHasOverride || envHasOverride) {
162
+ 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`);
163
+ emitWizardError({
164
+ code: ErrorCodes.CliFlagUnavailable,
165
+ message: "The --harness, --sequence, --model, and --capture-aio overrides are not available in published builds."
166
+ });
167
+ process.exit(1);
168
+ }
169
+ const argvHasLocalTarget = args.some((a) => LOCAL_TARGET_FLAGS.some((f) => a === `--${f}` || a === `--no-${f}` || a.startsWith(`--${f}=`)));
170
+ const envHasLocalTarget = LOCAL_TARGET_ENV_VARS.some((k) => process.env[k] != null && process.env[k] !== "");
171
+ if (argvHasLocalTarget || envHasLocalTarget) {
172
+ 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");
173
+ emitWizardError({
174
+ code: ErrorCodes.CliFlagUnavailable,
175
+ message: "The --local-dev, --local-context-mill, --local-mcp, and --local-posthog targets are not available in published builds."
176
+ });
177
+ process.exit(1);
178
+ }
179
+ }
180
+ this.cli.wrap(process.stdout.isTTY ? this.cli.terminalWidth() : 80).argv;
181
+ }
182
+ };
183
+ /** Excludes bare `local`: `wizard mcp add --local` stays available in prod. */
184
+ const LOCAL_TARGET_FLAGS = [
185
+ "local-dev",
186
+ "local-context-mill",
187
+ "local-mcp",
188
+ "local-posthog"
189
+ ];
190
+ const LOCAL_TARGET_ENV_VARS = [
191
+ "POSTHOG_WIZARD_LOCAL_DEV",
192
+ "POSTHOG_WIZARD_LOCAL_CONTEXT_MILL",
193
+ "POSTHOG_WIZARD_LOCAL_MCP",
194
+ "POSTHOG_WIZARD_LOCAL_POSTHOG"
195
+ ];
196
+ //#endregion
197
+ //#region src/commands/provision.ts
198
+ const provisionCommand = {
199
+ name: "provision",
200
+ description: "Create a new PostHog account (headless, no TUI)",
201
+ options: {
202
+ email: {
203
+ describe: "Email address for the new account",
204
+ type: "string",
205
+ demandOption: true
206
+ },
207
+ region: {
208
+ describe: "Cloud region (us or eu)",
209
+ choices: ["us", "eu"],
210
+ default: "us"
211
+ },
212
+ name: {
213
+ describe: "Name for the new account",
214
+ type: "string",
215
+ default: ""
216
+ },
217
+ json: {
218
+ describe: "Emit JSON result to stdout (defaults to true when stdout is not a TTY)",
219
+ type: "boolean"
220
+ }
221
+ },
222
+ examples: [["wizard provision --email matt+test@posthog.com --region us", ""], ["wizard provision --email user@example.com --region eu --json", ""]],
223
+ handler: runProvision
224
+ };
225
+ function runProvision(argv) {
226
+ const jsonMode = argv.json === void 0 ? !process.stdout.isTTY : Boolean(argv.json);
227
+ if (!jsonMode) setUI(new LoggingUI());
228
+ provision({
229
+ email: argv.email,
230
+ region: argv.region.toUpperCase(),
231
+ name: argv.name ?? "",
232
+ baseUrl: argv.baseUrl,
233
+ jsonMode
234
+ });
235
+ }
236
+ async function provision({ email, region, name, baseUrl, jsonMode }) {
237
+ try {
238
+ const { provisionNewAccount } = await import("./provisioning-OGFGlzf7.js");
239
+ if (!jsonMode) getUI().log.info(`Provisioning account for ${email} in ${region}...`);
240
+ emitResult(await provisionNewAccount(email, name, region, { baseUrl }), jsonMode);
241
+ process.exit(0);
242
+ } catch (error) {
243
+ emitError(error, jsonMode);
244
+ process.exit(1);
245
+ }
246
+ }
247
+ function emitResult(result, jsonMode) {
248
+ if (jsonMode) {
249
+ process.stdout.write(`${JSON.stringify(result)}\n`);
250
+ return;
251
+ }
252
+ getUI().log.success("Account provisioned successfully:");
253
+ getUI().log.info(` API Key: ${result.projectApiKey}`);
254
+ getUI().log.info(` Host: ${result.host}`);
255
+ getUI().log.info(` Project ID: ${result.projectId}`);
256
+ getUI().log.info(` Account ID: ${result.accountId}`);
257
+ getUI().log.info(` Access Token: ${result.accessToken}`);
258
+ getUI().log.info(` Refresh Token: ${result.refreshToken}`);
259
+ if (result.personalApiKey) getUI().log.info(` Personal API Key: ${result.personalApiKey}`);
260
+ }
261
+ function emitError(error, jsonMode) {
262
+ const msg = error instanceof Error ? error.message : String(error);
263
+ const code = msg.includes("already associated") ? "email_exists" : "provisioning_failed";
264
+ if (jsonMode) {
265
+ process.stderr.write(`${JSON.stringify({
266
+ error: msg,
267
+ code
268
+ })}\n`);
269
+ return;
270
+ }
271
+ getUI().log.error(`Provisioning failed: ${msg}`);
272
+ }
273
+ //#endregion
274
+ //#region src/commands/basic-integration/index.ts
275
+ const basicIntegrationCommand = {
276
+ name: ["$0"],
277
+ description: "Run the PostHog setup wizard",
278
+ children: [provisionCommand],
279
+ options: {
280
+ "install-dir": {
281
+ describe: "Directory to install PostHog in\nenv: POSTHOG_WIZARD_INSTALL_DIR",
282
+ type: "string"
283
+ },
284
+ name: {
285
+ describe: "Name for account creation with --ci --signup\nenv: POSTHOG_WIZARD_NAME",
286
+ type: "string"
287
+ },
288
+ playground: {
289
+ default: false,
290
+ describe: "Launch the TUI primitives playground",
291
+ type: "boolean",
292
+ hidden: true
293
+ },
294
+ ...headlessOption,
295
+ ...regionOption
296
+ },
297
+ check: (argv) => {
298
+ if (argv.playground && (argv.ci || isHeadless(argv))) throw new Error("--playground cannot be combined with a headless run.");
299
+ return true;
300
+ },
301
+ handler: (argv) => {
302
+ setEntryCommand("integrate");
303
+ (async () => {
304
+ if (isHeadless(argv)) {
305
+ const { runHeadlessInstall } = await import("./ci-install-COcV8SY2.js");
306
+ return runHeadlessInstall(argv);
307
+ }
308
+ if (argv.ci) {
309
+ const { runCIInstall } = await import("./ci-install-COcV8SY2.js");
310
+ return runCIInstall(argv);
311
+ }
312
+ if (isNonInteractiveEnvironment()) {
313
+ const { failNonInteractive } = await import("./non-interactive-DyVC1AGc.js");
314
+ return failNonInteractive();
315
+ }
316
+ if (argv.playground) {
317
+ const { runPlayground } = await import("./playground-BlYRBMj7.js");
318
+ return runPlayground();
319
+ }
320
+ const { runInteractive } = await import("./interactive-B_Ti_CsS.js");
321
+ runInteractive(argv);
322
+ })();
323
+ }
324
+ };
325
+ //#endregion
326
+ //#region src/commands/mcp/tui-availability.ts
327
+ /**
328
+ * startTUI throws CliInteractiveRequired, and Ink throws "Raw mode is not
329
+ * supported", when stdin has no TTY (piped input, CI, some IDE terminals).
330
+ * That is the only TUI failure the mcp commands
331
+ * degrade to LoggingUI for — any other error from the TUI path is a real bug
332
+ * and must surface rather than be silently swallowed.
333
+ */
334
+ function isTUIUnavailable(error) {
335
+ if (!(error instanceof Error)) return false;
336
+ return error.code === ErrorCodes.CliInteractiveRequired || /raw mode is not supported/i.test(error.message);
337
+ }
338
+ //#endregion
339
+ //#region src/commands/mcp/add.ts
340
+ const mcpAddCommand = {
341
+ name: "add",
342
+ description: "Install PostHog MCP server to supported clients",
343
+ options: {
344
+ local: {
345
+ default: false,
346
+ describe: "Add local development MCP server (http://localhost:8787)",
347
+ type: "boolean"
348
+ },
349
+ features: {
350
+ describe: "Comma-separated list of features to enable (default: all)",
351
+ type: "string"
352
+ },
353
+ "api-key": {
354
+ describe: "PostHog personal API key (phx_xxx) for MCP authentication",
355
+ type: "string"
356
+ },
357
+ ...headlessOption
358
+ },
359
+ handler: runMcpAdd
360
+ };
361
+ function runMcpAdd(argv) {
362
+ const features = parseFeatures(argv.features);
363
+ (async () => {
364
+ const { readApiKeyFromEnv } = await import("./env-api-key-CaWEDj_9.js");
365
+ const apiKey = argv.apiKey || readApiKeyFromEnv();
366
+ const debug = argv.debug;
367
+ const localMcp = argv.local;
368
+ const args = {
369
+ local: localMcp,
370
+ features,
371
+ apiKey
372
+ };
373
+ if (isHeadless(argv)) {
374
+ await runHeadlessAdd(args);
375
+ return;
376
+ }
377
+ try {
378
+ const { startTUI } = await import("./start-tui-Bo2L0bar.js");
379
+ const { buildSession } = await import("./wizard-session-DGaUHOF3.js");
380
+ const tui = startTUI(VERSION, Program.McpAdd);
381
+ tui.store.session = buildSession({
382
+ debug,
383
+ localMcp,
384
+ mcpFeatures: features,
385
+ apiKey,
386
+ baseUrl: argv.baseUrl
387
+ });
388
+ } catch (error) {
389
+ if (!isTUIUnavailable(error)) throw error;
390
+ await runHeadlessAdd(args);
391
+ }
392
+ })();
393
+ }
394
+ async function runHeadlessAdd(args) {
395
+ setUI(new LoggingUI());
396
+ const { addMCPServerToClientsStep } = await import("./add-mcp-server-to-clients-artmN7mz.js");
397
+ const { installed, failed } = await addMCPServerToClientsStep(args);
398
+ if (failed.length > 0 || installed.length === 0) process.exitCode = 1;
399
+ }
400
+ function parseFeatures(raw) {
401
+ if (typeof raw !== "string") return void 0;
402
+ return raw.split(",").map((s) => s.trim()).filter(Boolean);
403
+ }
404
+ //#endregion
405
+ //#region src/commands/mcp/remove.ts
406
+ const mcpRemoveCommand = {
407
+ name: "remove",
408
+ description: "Remove PostHog MCP server from supported clients",
409
+ options: {
410
+ local: {
411
+ default: false,
412
+ describe: "Remove local development MCP server (http://localhost:8787)",
413
+ type: "boolean"
414
+ },
415
+ ...headlessOption
416
+ },
417
+ handler: runMcpRemove
418
+ };
419
+ function runMcpRemove(argv) {
420
+ (async () => {
421
+ const debug = argv.debug;
422
+ const localMcp = argv.local;
423
+ if (isHeadless(argv)) {
424
+ await runHeadlessRemove(localMcp);
425
+ return;
426
+ }
427
+ try {
428
+ const { startTUI } = await import("./start-tui-Bo2L0bar.js");
429
+ const { buildSession } = await import("./wizard-session-DGaUHOF3.js");
430
+ const tui = startTUI(VERSION, Program.McpRemove);
431
+ tui.store.session = buildSession({
432
+ debug,
433
+ localMcp,
434
+ baseUrl: argv.baseUrl
435
+ });
436
+ } catch (error) {
437
+ if (!isTUIUnavailable(error)) throw error;
438
+ await runHeadlessRemove(localMcp);
439
+ }
440
+ })();
441
+ }
442
+ /** No exit code on an empty result: nothing to remove is the requested end state. */
443
+ async function runHeadlessRemove(local) {
444
+ setUI(new LoggingUI());
445
+ const { removeMCPServerFromClientsStep } = await import("./add-mcp-server-to-clients-artmN7mz.js");
446
+ await removeMCPServerFromClientsStep({ local });
447
+ }
448
+ //#endregion
449
+ //#region src/commands/mcp/tutorial.ts
450
+ const mcpTutorialCommand = {
451
+ name: "tutorial",
452
+ description: "Try the PostHog MCP with your agent (no install needed)",
453
+ options: { local: {
454
+ default: false,
455
+ describe: "Point the tutorial at the local MCP server (http://localhost:8787)",
456
+ type: "boolean"
457
+ } },
458
+ handler: runMcpTutorial
459
+ };
460
+ function runMcpTutorial(argv) {
461
+ (async () => {
462
+ const debug = argv.debug;
463
+ const localMcp = argv.local;
464
+ try {
465
+ const { startTUI } = await import("./start-tui-Bo2L0bar.js");
466
+ const { buildSession } = await import("./wizard-session-DGaUHOF3.js");
467
+ const tui = startTUI(VERSION, Program.McpTutorial);
468
+ tui.store.session = buildSession({
469
+ debug,
470
+ localMcp,
471
+ baseUrl: argv.baseUrl
472
+ });
473
+ } catch (err) {
474
+ setUI(new LoggingUI());
475
+ getUI().log.error(`The MCP tutorial requires an interactive terminal. ${err instanceof Error ? err.message : String(err)}`);
476
+ emitWizardError({
477
+ code: ErrorCodes.CliInteractiveRequired,
478
+ message: "The MCP tutorial requires an interactive terminal."
479
+ });
480
+ process.exit(1);
481
+ }
482
+ })();
483
+ }
484
+ //#endregion
485
+ //#region src/commands/mcp/index.ts
486
+ const mcpCommand = {
487
+ name: "mcp",
488
+ description: "MCP server management commands",
489
+ children: [
490
+ mcpAddCommand,
491
+ mcpRemoveCommand,
492
+ mcpTutorialCommand
493
+ ]
494
+ };
495
+ //#endregion
496
+ //#region src/commands/skill-program-options.ts
497
+ /**
498
+ * Per-command options shared by every skill-based program command
499
+ * (`audit events`, `migrate statsig`, `revenue`, `source-maps`, …).
500
+ *
501
+ * Only flags unique to skill commands live here. Global flags are declared
502
+ * once in `wizard.ts` — both in `GLOBAL_OPTIONS` and, for the dev-only ones,
503
+ * the `Wizard` constructor — and apply to every command automatically.
504
+ */
505
+ const skillProgramOptions = { "install-dir": {
506
+ describe: "Directory to install in",
507
+ type: "string"
508
+ } };
509
+ //#endregion
510
+ //#region src/commands/factories/shared.ts
511
+ /**
512
+ * Dispatch a parsed yargs invocation to the wizard runner. Applies the
513
+ * program's `mapCliOptions` transform, then routes to `runWizardHeadless`,
514
+ * `runWizardCI`, or `runWizard` based on the headless / `--ci` flags.
515
+ *
516
+ * Every command file used to inline this; the factories call it instead.
517
+ */
518
+ /**
519
+ * Run a command's async body as fire-and-forget while still surfacing failures.
520
+ * yargs handlers are synchronous, so async work kicks off a detached promise —
521
+ * without this, a rejection becomes an unhandled promise rejection (no message,
522
+ * wrong exit code). This awaits the work and turns any error into a clean
523
+ * message + non-zero exit.
524
+ */
525
+ function runCommandHandler(work) {
526
+ (async () => {
527
+ try {
528
+ await work();
529
+ } catch (err) {
530
+ const msg = err instanceof Error ? err.message : String(err);
531
+ process.stderr.write(`\n\x1b[1;91m✖ ${msg}\x1b[0m\n\n`);
532
+ emitWizardError({
533
+ code: ErrorCodes.InternalUnhandled,
534
+ message: msg
535
+ });
536
+ process.exit(1);
537
+ }
538
+ })();
539
+ }
540
+ function dispatchProgram(config, argv) {
541
+ const argvRecord = { ...argv };
542
+ const extras = config.mapCliOptions?.(argvRecord) ?? {};
543
+ const options = {
544
+ ...argvRecord,
545
+ ...extras
546
+ };
547
+ if (isHeadless(options)) runWizardHeadless(config, options);
548
+ else if (options.ci) runWizardCI(config, options);
549
+ else runWizard(config, options);
550
+ }
551
+ /**
552
+ * Merge the standard skill-program flags (`--debug`, `--install-dir`, etc.)
553
+ * with any program-specific options declared on `cliOptions`.
554
+ *
555
+ * Program-specific options shadow the standard ones — that's intentional, so
556
+ * a program can override a default flag if it ever needs to.
557
+ */
558
+ function mergeCommandOptions(config) {
559
+ return {
560
+ ...skillProgramOptions,
561
+ ...config.cliOptions ?? {}
562
+ };
563
+ }
564
+ //#endregion
565
+ //#region src/commands/factories/native-command-factory.ts
566
+ /**
567
+ * Build a yargs `Command` from a wizard-native `ProgramConfig`.
568
+ *
569
+ * Collapses the previously duplicated boilerplate (read `config.command`,
570
+ * merge skill-program flags with program-specific options, dispatch via
571
+ * `runWizard` / `runWizardCI`) into a single call.
572
+ */
573
+ function nativeCommandFactory(config, opts = {}) {
574
+ if (!config.command) throw new Error(`nativeCommandFactory: program "${config.id}" has no \`command\` — wizard-native programs must declare a CLI name`);
575
+ return {
576
+ name: config.command,
577
+ description: config.description,
578
+ options: mergeCommandOptions(config),
579
+ children: opts.children,
580
+ handler: (argv) => dispatchProgram(config, argv)
581
+ };
582
+ }
583
+ //#endregion
584
+ //#region src/commands/mcp-analytics.ts
585
+ /**
586
+ * `wizard mcp-analytics` — flat skill command, instrument-an-MCP-server today.
587
+ *
588
+ * Distinct from `wizard mcp add`: this instruments the user's own MCP server
589
+ * with the `@posthog/mcp` SDK, rather than installing the PostHog MCP server
590
+ * into a coding agent. Stays flat while instrumenting is the only action.
591
+ */
592
+ const mcpAnalyticsCommand = nativeCommandFactory(mcpAnalyticsConfig);
593
+ //#endregion
594
+ //#region src/commands/replay-vision.ts
595
+ /**
596
+ * `wizard replay-vision` — flat skill command, set up Replay vision today.
597
+ *
598
+ * Enables session replay recording and creates vision scanners tailored to
599
+ * the product's key flows. Runs the `replay-vision` orchestrator flow, which
600
+ * reuses the integration-v2 install/init mini-agents when the repo has no
601
+ * PostHog integration yet.
602
+ */
603
+ const replayVisionCommand = nativeCommandFactory(replayVisionConfig);
604
+ //#endregion
605
+ //#region src/commands/ai-observability.ts
606
+ /**
607
+ * `wizard ai-observability` — flat skill command, wire AI Observability into a
608
+ * project today.
609
+ *
610
+ * Installs the OpenTelemetry SDK, the PostHog span processor, and the
611
+ * provider-specific instrumentation so LLM calls emit `$ai_generation` events.
612
+ * The `ai-observability` context-mill skill has one variant per (LLM provider ×
613
+ * language); the agent picks the right one at run time by scanning the
614
+ * project's manifest and (when ambiguous) asking the user via `wizard_ask`.
615
+ * Stays flat while a single "add AIO to a project" flow is the only action.
616
+ */
617
+ const aiObservabilityCommand = nativeCommandFactory(aiObservabilityConfig);
618
+ //#endregion
619
+ //#region src/commands/metrics.ts
620
+ /**
621
+ * `wizard metrics` — flat skill command, wire PostHog application metrics
622
+ * (counters, gauges, histograms via \`posthog.metrics\`) into a project.
623
+ *
624
+ * The `metrics` context-mill skill has one variant per platform (python,
625
+ * nodejs, javascript, kubernetes, other/OTLP); the agent picks the right one
626
+ * at run time by scanning the project's manifest and (when ambiguous) asking
627
+ * the user via `wizard_ask`. Stays flat while a single "add metrics to a
628
+ * project" flow is the only action.
629
+ */
630
+ const metricsCommand = nativeCommandFactory(metricsConfig);
631
+ //#endregion
632
+ //#region src/programs/dispatch-family.ts
633
+ /**
634
+ * Capture a CLI dispatch error, flush analytics, and exit. The wizard never
635
+ * starts a run from these paths — use flush() (not shutdown()) so we don't
636
+ * fire a "setup wizard finished" event for a parse error that didn't run.
637
+ */
638
+ async function exitDispatchError(reason, properties, message, code = 1) {
639
+ analytics.wizardCapture("cli dispatch error", {
640
+ reason,
641
+ ...properties
642
+ });
643
+ try {
644
+ await analytics.flush();
645
+ } catch {}
646
+ process.stderr.write(message);
647
+ emitWizardError({
648
+ code: ErrorCodes.CliBadArgs,
649
+ message: reason
650
+ });
651
+ return process.exit(code);
652
+ }
653
+ /**
654
+ * Family commands (`wizard audit`, `wizard migrate`, ...) resolve their
655
+ * subcommands at runtime against the published `cliEntries` inside
656
+ * `skill-menu.json`. Adding a subcommand is a context-mill release — no
657
+ * wizard release needed.
658
+ *
659
+ * Wizard-native subcommands (programs that aren't backed by a single skill,
660
+ * e.g. `wizard audit web-analytics`) live here in code, dispatched directly
661
+ * without touching the registry. Adding a native is a wizard PR.
662
+ */
663
+ /** Wizard-native subcommands keyed by family. */
664
+ const NATIVE_HANDLERS = { audit: { "web-analytics": webAnalyticsDoctorConfig } };
665
+ /**
666
+ * Resolve a fetched CliEntry to the ProgramConfig that actually runs it.
667
+ * Most entries run via the generic agent-skill program with the entry's
668
+ * `skillId` injected. The comprehensive `audit all` is the one exception —
669
+ * skillId 'audit' triggers the specialized auditConfig (custom hooks,
670
+ * content blocks, screens).
671
+ *
672
+ * This is the one place that knows a subcommand belongs to `audit`, so the
673
+ * generic skill program picks up the ledger here rather than for every skill.
674
+ */
675
+ function configForCliEntry(entry, family) {
676
+ if (entry.skillId === "audit") return auditConfig;
677
+ return {
678
+ ...agentSkillConfig,
679
+ skillId: entry.skillId,
680
+ ...family === "audit" ? {
681
+ auditLedgerFile: AUDIT_CHECKS_FILE,
682
+ streamWorkflowId: family,
683
+ allowedTools: [
684
+ ...agentSkillConfig.allowedTools ?? [],
685
+ WIZARD_TOOL_NAMES.auditSeedChecks,
686
+ WIZARD_TOOL_NAMES.auditAddChecks,
687
+ WIZARD_TOOL_NAMES.auditResolveChecks
688
+ ]
689
+ } : {}
690
+ };
691
+ }
692
+ function familyEntries(family, entries) {
693
+ return entries.filter((e) => e.role === "command" && e.parentCommand === family && Boolean(e.command));
694
+ }
695
+ /**
696
+ * Dispatch `wizard <family> <sub>` to the right program.
697
+ *
698
+ * Order:
699
+ * 1. Native handler for (family, sub) — runs immediately, no network.
700
+ * 2. Fetched CliEntry — runs the resolved skill.
701
+ * 3. Unknown — prints the available list and exits non-zero.
702
+ */
703
+ async function dispatchFamily(family, argv) {
704
+ const sub = argv.skill?.trim();
705
+ if (!sub) return exitDispatchError("missing subcommand", { family }, `\n\x1b[1;91m✖ \`wizard ${family}\` requires a subcommand.\x1b[0m\n Pass one (e.g. \`wizard ${family} <subcommand>\`), or run it in an interactive terminal to pick from a menu.\n\n`);
706
+ const native = NATIVE_HANDLERS[family]?.[sub];
707
+ if (native) {
708
+ dispatchProgram(native, argv);
709
+ return;
710
+ }
711
+ const skillsBaseUrl = getSkillsBaseUrl();
712
+ const menu = await fetchSkillMenu(skillsBaseUrl);
713
+ if (!menu) return exitDispatchError("registry unreachable", {
714
+ family,
715
+ sub,
716
+ skillsBaseUrl
717
+ }, `\n\x1b[1;91m✖ Couldn't reach the skill registry at ${skillsBaseUrl}.\x1b[0m\n Check your network connection and try again.\n\n`);
718
+ const entries = menu.cliEntries ?? [];
719
+ const entry = familyEntries(family, entries).find((e) => e.command === sub);
720
+ if (entry) {
721
+ dispatchProgram(configForCliEntry(entry, family), argv);
722
+ return;
723
+ }
724
+ const available = [...Object.keys(NATIVE_HANDLERS[family] ?? {}), ...familyEntries(family, entries).map((e) => e.command)].sort();
725
+ return exitDispatchError("unknown subcommand", {
726
+ family,
727
+ sub,
728
+ available
729
+ }, `\n\x1b[1;91m✖ Unknown subcommand "${sub}" under \`${family}\`.\x1b[0m\n` + (available.length ? ` Available: ${available.join(", ")}\n\n` : ` No subcommands published for "${family}" yet.\n\n`));
730
+ }
731
+ /**
732
+ * Build the children list shown in the family's interactive picker.
733
+ * Combines native handlers with skill-backed entries from the live registry.
734
+ * Used by `familyCommandFactory`'s `interactiveDefault`.
735
+ */
736
+ function buildFamilyPickerChildren(family, entries) {
737
+ const natives = Object.entries(NATIVE_HANDLERS[family] ?? {}).map(([cmd, program]) => ({
738
+ name: cmd,
739
+ description: program.description,
740
+ handler: (argv) => dispatchProgram(program, argv)
741
+ }));
742
+ const live = familyEntries(family, entries).map((entry) => ({
743
+ name: entry.command,
744
+ description: entry.description,
745
+ handler: (argv) => {
746
+ dispatchFamily(family, {
747
+ ...argv,
748
+ skill: entry.command
749
+ });
750
+ },
751
+ default: entry.default
752
+ }));
753
+ return [...natives, ...live];
754
+ }
755
+ /**
756
+ * The children the family picker shows **today**: only the leaf marked
757
+ * `default` (e.g. `audit events`). Every other subcommand stays runnable
758
+ * directly (`wizard audit <name>`) — they just aren't listed in the picker yet.
759
+ * Falls back to all children when nothing is marked `default`.
760
+ *
761
+ * Temporary: when we're ready to surface the full menu, return `children`
762
+ * unchanged (and delete this note).
763
+ */
764
+ function pickerChildrenToShow(children) {
765
+ const defaults = children.filter((c) => c.default);
766
+ return defaults.length > 0 ? [...defaults] : [...children];
767
+ }
768
+ //#endregion
769
+ //#region src/commands/factories/family-picker.tsx
770
+ function FamilyPickerApp(props) {
771
+ return createElement(Box, {
772
+ flexDirection: "column",
773
+ paddingX: 1,
774
+ paddingY: 1
775
+ }, createElement(Text, {
776
+ bold: true,
777
+ color: Colors.accent
778
+ }, props.parentLabel), createElement(Box, { height: 1 }), createElement(PickerMenu, {
779
+ message: "Pick a subcommand",
780
+ options: props.options,
781
+ optionMarginBottom: 1,
782
+ onSelect: (value) => {
783
+ const cmd = Array.isArray(value) ? value[0] : value;
784
+ if (cmd) props.onSelect(cmd);
785
+ }
786
+ }));
787
+ }
788
+ function describe(child) {
789
+ return commandKeys(child.name)[0] ?? "";
790
+ }
791
+ /**
792
+ * Reorder children so the `default`-marked entry is first, while
793
+ * preserving the relative order of the rest. The picker's initial
794
+ * focus is index 0, so this is what makes "press Enter on
795
+ * `wizard audit`" run the default leaf (today `audit events`).
796
+ *
797
+ * Exported for testability — the ordering logic stays pure and
798
+ * inspectable without mounting Ink.
799
+ */
800
+ function orderFamilyChildren(children) {
801
+ const selectable = children.filter((c) => c.handler || c.children?.length);
802
+ const defaults = selectable.filter((c) => c.default);
803
+ const rest = selectable.filter((c) => !c.default);
804
+ return [...defaults, ...rest];
805
+ }
806
+ /**
807
+ * Render the picker. Resolves once the user has selected a child;
808
+ * dispatching the child's handler is the caller's responsibility (so this
809
+ * function stays pure-UI and easy to test by stubbing `render`).
810
+ */
811
+ function chooseFamilyChild(parentLabel, children) {
812
+ const ordered = orderFamilyChildren(children);
813
+ if (ordered.length === 0) return Promise.resolve(null);
814
+ const options = ordered.map((child) => ({
815
+ label: describe(child),
816
+ value: child,
817
+ hint: child.description
818
+ }));
819
+ return new Promise((resolve) => {
820
+ let app = null;
821
+ const handleSelect = (cmd) => {
822
+ app?.unmount();
823
+ resolve(cmd);
824
+ };
825
+ app = render(createElement(FamilyPickerApp, {
826
+ parentLabel,
827
+ options,
828
+ onSelect: handleSelect
829
+ }));
830
+ });
831
+ }
832
+ /**
833
+ * Returns an `interactiveDefault` handler for a family parent's no-leaf
834
+ * invocation. Always opens the picker; the `default`-marked child is
835
+ * shown first (pre-highlighted), so a single Enter keystroke runs it.
836
+ *
837
+ * Discovery + consent in one extra keystroke vs. auto-running silently.
838
+ *
839
+ * Wire onto a family parent:
840
+ * export const auditCommand: Command = {
841
+ * name: 'audit',
842
+ * description: '...',
843
+ * children: [...],
844
+ * interactiveDefault: createFamilyPickerDefault('audit', auditChildren),
845
+ * };
846
+ */
847
+ function createFamilyPickerDefault(parentLabel, children, chooser = chooseFamilyChild) {
848
+ return async (argv) => {
849
+ const chosen = await chooser(parentLabel, children);
850
+ if (!chosen) return;
851
+ await Promise.resolve(chosen.handler?.(argv));
852
+ };
853
+ }
854
+ //#endregion
855
+ //#region src/commands/factories/family-command-factory.ts
856
+ /**
857
+ * Build a yargs `Command` for a family parent (`wizard audit`, etc.).
858
+ *
859
+ * - `wizard <family> <sub>` — `dispatchFamily` resolves `<sub>` against
860
+ * native handlers first, then the live `cliEntries` from
861
+ * `skill-menu.json`. Unknown subs error with the available list.
862
+ * - `wizard <family>` (no positional) — in an interactive terminal, runs the
863
+ * family's single shown entry directly (today `audit events`, so the user
864
+ * lands on its intro screen); opens the picker once a family shows more than
865
+ * one. In non-TTY/CI, falls through to `dispatchFamily`, which prints
866
+ * "requires a subcommand" rather than running something unprompted.
867
+ *
868
+ * No static yargs children. New skill-backed subcommands appear after a
869
+ * context-mill release without a wizard release. New *native* subcommands
870
+ * (rare) are added by updating `NATIVE_HANDLERS` in `dispatch-family.ts`.
871
+ */
872
+ function familyCommandFactory({ family, description, optionsFrom }) {
873
+ const openFamilyEntry = async (argv) => {
874
+ const toShow = pickerChildrenToShow(buildFamilyPickerChildren(family, (await fetchSkillMenu(getSkillsBaseUrl()))?.cliEntries ?? []));
875
+ if (toShow.length === 1 && toShow[0]?.handler) {
876
+ await Promise.resolve(toShow[0].handler(argv));
877
+ return;
878
+ }
879
+ await createFamilyPickerDefault(`wizard ${family}`, toShow)(argv);
880
+ };
881
+ return {
882
+ name: `${family} [skill]`,
883
+ description,
884
+ options: mergeCommandOptions(optionsFrom),
885
+ positionals: { skill: {
886
+ type: "string",
887
+ describe: "Subcommand to run (omit to run the default)"
888
+ } },
889
+ handler: (argv) => {
890
+ const sub = argv.skill?.trim();
891
+ runCommandHandler(() => sub || !process.stdout.isTTY ? dispatchFamily(family, argv) : openFamilyEntry(argv));
892
+ },
893
+ interactiveDefault: openFamilyEntry
894
+ };
895
+ }
896
+ //#endregion
897
+ //#region src/commands/audit.ts
898
+ /**
899
+ * The `wizard audit` family.
900
+ *
901
+ * Subcommands are resolved at runtime: the wizard fetches `cliEntries` from
902
+ * `skill-menu.json` and dispatches based on `parentCommand: 'audit'`. The
903
+ * wizard-native handler for `web-analytics` lives in `NATIVE_HANDLERS` over
904
+ * in `dispatch-family.ts`. `wizard audit` with no positional opens the
905
+ * family picker, which combines native + live entries.
906
+ *
907
+ * Adding a new skill-backed audit subcommand is a context-mill release —
908
+ * no wizard release needed.
909
+ */
910
+ const auditCommand = familyCommandFactory({
911
+ family: "audit",
912
+ description: auditConfig.description,
913
+ optionsFrom: auditConfig
914
+ });
915
+ //#endregion
916
+ //#region src/commands/doctor.ts
917
+ const doctorCommand = {
918
+ name: "doctor",
919
+ description: posthogDoctorConfig.description,
920
+ options: {
921
+ ...skillProgramOptions,
922
+ ...posthogDoctorConfig.cliOptions ?? {}
923
+ },
924
+ handler: (argv) => {
925
+ const extras = posthogDoctorConfig.mapCliOptions?.(argv) ?? {};
926
+ const options = {
927
+ ...argv,
928
+ ...extras
929
+ };
930
+ if (options.ci) runDoctorCI(options);
931
+ else runWizard(posthogDoctorConfig, options);
932
+ }
933
+ };
934
+ const SEVERITY_ORDER = {
935
+ critical: 0,
936
+ warning: 1,
937
+ info: 2
938
+ };
939
+ async function runDoctorCI(options) {
940
+ setUI(new LoggingUI());
941
+ const apiKey = options.apiKey ?? readApiKeyFromEnv() ?? void 0;
942
+ if (!apiKey) {
943
+ getUI().intro("PostHog Wizard");
944
+ getUI().log.error("CI mode requires --api-key (personal API key phx_xxx)");
945
+ emitWizardError({
946
+ code: ErrorCodes.ArgsMissingApiKey,
947
+ message: "CI mode requires --api-key (personal API key phx_xxx)"
948
+ });
949
+ process.exit(1);
950
+ }
951
+ getUI().intro("Welcome to the PostHog setup wizard");
952
+ getUI().log.info("Running posthog-doctor in CI mode");
953
+ try {
954
+ const { getOrAskForProjectData } = await import("./setup-utils-CVS86NYR.js");
955
+ const { host, accessToken, projectId } = await getOrAskForProjectData({
956
+ signup: false,
957
+ ci: true,
958
+ apiKey,
959
+ projectId: options.projectId ? Number(options.projectId) : void 0,
960
+ baseUrl: options.baseUrl
961
+ });
962
+ const issues = await fetchHealthIssues(accessToken, host.apiHost, projectId);
963
+ if (issues.length === 0) {
964
+ getUI().log.success("No active issues — your project looks healthy.");
965
+ process.exit(0);
966
+ }
967
+ const sorted = [...issues].sort((a, b) => SEVERITY_ORDER[a.severity] - SEVERITY_ORDER[b.severity]);
968
+ getUI().log.warn(`${issues.length} active issue${issues.length === 1 ? "" : "s"} found:`);
969
+ for (const issue of sorted) getUI().log.info(` • [${issue.severity}] ${getKindMeta(issue.kind).title}`);
970
+ process.exit(1);
971
+ } catch (error) {
972
+ const { ApiError } = await import("./api-Cm9UtKZh.js");
973
+ const message = error instanceof ApiError && error.statusCode === 401 ? "Your PostHog API key is invalid or expired." : error instanceof Error ? error.message : String(error);
974
+ getUI().log.error(`Doctor failed: ${message}`);
975
+ emitWizardError({
976
+ code: error instanceof ApiError && error.statusCode === 401 ? ErrorCodes.AuthInvalidOrExpired : ErrorCodes.InternalUnhandled,
977
+ message
978
+ });
979
+ process.exit(1);
980
+ }
981
+ }
982
+ //#endregion
983
+ //#region src/commands/migrate.ts
984
+ /**
985
+ * `wizard migrate` — flat skill command, Statsig today.
986
+ *
987
+ * Stays flat while there's only one vendor. When a second vendor lands,
988
+ * restructure into a family with `familyCommandFactory` and publish each
989
+ * vendor as a `cliEntries` entry with `parentCommand: 'migrate'` from
990
+ * context-mill. That move is a deliberate breaking change for users
991
+ * (`wizard migrate` stops running Statsig directly), so do it explicitly
992
+ * when the second vendor arrives, not pre-emptively.
993
+ */
994
+ const migrateCommand = nativeCommandFactory(migrationConfig);
995
+ //#endregion
996
+ //#region src/commands/revenue.ts
997
+ /**
998
+ * `wizard revenue-analytics` — flat skill command, Stripe today.
999
+ *
1000
+ * Stays flat while there's only one provider. Restructure into a family
1001
+ * if/when a second provider lands.
1002
+ */
1003
+ const revenueCommand = nativeCommandFactory(revenueAnalyticsConfig);
1004
+ //#endregion
1005
+ //#region src/commands/warehouse.ts
1006
+ /**
1007
+ * `wizard warehouse` — detect and connect a data warehouse source.
1008
+ *
1009
+ * Mirrors `revenue-analytics`: flat skill command driven by the
1010
+ * warehouse-source program.
1011
+ */
1012
+ const warehouseCommand = nativeCommandFactory(warehouseSourceConfig);
1013
+ //#endregion
1014
+ //#region src/commands/self-driving.ts
1015
+ const selfDrivingCommand = {
1016
+ name: "self-driving",
1017
+ description: selfDrivingConfig.description,
1018
+ options: {
1019
+ ...skillProgramOptions,
1020
+ integrate: {
1021
+ describe: "Integrate the PostHog SDK first, then set up Self-driving — skips the integration prompt and logs you in via OAuth (no \"create an account?\" question). Use when the project isn't set up yet but you already have a PostHog account.",
1022
+ type: "boolean",
1023
+ default: false
1024
+ },
1025
+ ...selfDrivingConfig.cliOptions ?? {}
1026
+ },
1027
+ check: (argv) => {
1028
+ if (argv.signup) throw new Error("`self-driving` cannot run with --signup. Just run `wizard self-driving`: when your project has no PostHog, it asks whether you already have an account and offers to create one for you (no flag needed).");
1029
+ if (argv.ci) throw new Error("`self-driving` cannot run in CI mode — it requires interactive steps (GitHub connect, issue-tracker selection, custom-scout approval).");
1030
+ return true;
1031
+ },
1032
+ handler: (argv) => {
1033
+ const extras = selfDrivingConfig.mapCliOptions?.(argv) ?? {};
1034
+ const options = {
1035
+ ...argv,
1036
+ ...extras
1037
+ };
1038
+ if (options.ci) runWizardCI(selfDrivingConfig, options);
1039
+ else runWizard(selfDrivingConfig, options);
1040
+ }
1041
+ };
1042
+ //#endregion
1043
+ //#region src/commands/slack.ts
1044
+ const slackCommand = {
1045
+ name: "slack",
1046
+ description: "Connect PostHog to your Slack",
1047
+ handler: runSlackConnect,
1048
+ children: [{
1049
+ name: "add",
1050
+ description: "Connect PostHog to your Slack",
1051
+ handler: runSlackConnect
1052
+ }]
1053
+ };
1054
+ function runSlackConnect(argv) {
1055
+ (async () => {
1056
+ const debug = argv.debug;
1057
+ try {
1058
+ const { startTUI } = await import("./start-tui-Bo2L0bar.js");
1059
+ const { buildSession } = await import("./wizard-session-DGaUHOF3.js");
1060
+ const tui = startTUI(VERSION, Program.SlackConnect);
1061
+ tui.store.session = buildSession({
1062
+ debug,
1063
+ baseUrl: argv.baseUrl
1064
+ });
1065
+ } catch (err) {
1066
+ setUI(new LoggingUI());
1067
+ getUI().log.error(`Connecting Slack requires an interactive terminal. ${err instanceof Error ? err.message : String(err)}`);
1068
+ emitWizardError({
1069
+ code: ErrorCodes.CliInteractiveRequired,
1070
+ message: "Connecting Slack requires an interactive terminal."
1071
+ });
1072
+ process.exit(1);
1073
+ }
1074
+ })();
1075
+ }
1076
+ //#endregion
1077
+ //#region src/commands/upload-sourcemaps.ts
1078
+ const uploadSourcemapsCommand = {
1079
+ name: [errorTrackingUploadSourceMapsConfig.command, "upload-sourcemaps"],
1080
+ description: errorTrackingUploadSourceMapsConfig.description,
1081
+ options: {
1082
+ ...skillProgramOptions,
1083
+ ...errorTrackingUploadSourceMapsConfig.cliOptions ?? {}
1084
+ },
1085
+ handler: (argv) => {
1086
+ const extras = errorTrackingUploadSourceMapsConfig.mapCliOptions?.(argv) ?? {};
1087
+ const options = {
1088
+ ...argv,
1089
+ ...extras
1090
+ };
1091
+ if (options.ci) runWizardCI(errorTrackingUploadSourceMapsConfig, options);
1092
+ else runWizard(errorTrackingUploadSourceMapsConfig, options);
1093
+ }
1094
+ };
1095
+ //#endregion
1096
+ //#region src/commands/error-tracking.ts
1097
+ /**
1098
+ * `wizard error-tracking` — flat skill command, set up error tracking today.
1099
+ *
1100
+ * Wires up exception capture and — where the platform needs it — source-map /
1101
+ * debug-symbol upload. Runs the `error-tracking` orchestrator flow, which
1102
+ * reuses the integration-v2 install/init mini-agents when the repo has no
1103
+ * PostHog integration yet, so it works on uninstrumented projects too.
1104
+ */
1105
+ const errorTrackingCommand = nativeCommandFactory(errorTrackingConfig);
1106
+ //#endregion
1107
+ //#region src/commands/basic-integration/skill.ts
1108
+ /** Run an arbitrary context-mill skill by id (`wizard skill <id>`, headless with `--ci`). */
1109
+ function runSkillMode(argv) {
1110
+ const skillId = argv.skill;
1111
+ const config = createSkillProgram({
1112
+ skillId,
1113
+ command: "skill",
1114
+ id: "agent-skill",
1115
+ description: `Run skill: ${skillId}`,
1116
+ integrationLabel: skillId,
1117
+ successMessage: `${skillId} completed!`,
1118
+ reportFile: `posthog-${skillId}-report.md`,
1119
+ docsUrl: POSTHOG_DOCS_URL,
1120
+ spinnerMessage: `Running ${skillId}...`,
1121
+ estimatedDurationMinutes: 5
1122
+ });
1123
+ const options = {
1124
+ ...argv,
1125
+ skillId
1126
+ };
1127
+ if (argv.ci) runWizardCI(config, options);
1128
+ else runWizard(config, options);
1129
+ }
1130
+ //#endregion
1131
+ //#region src/commands/skill.ts
1132
+ /** Read the `<skill-name>` positional (yargs camelCases the hyphenated key). */
1133
+ function readSkillName(argv) {
1134
+ return String(argv.skillName ?? argv["skill-name"] ?? "").trim();
1135
+ }
1136
+ const BROWSABLE_ROLES = new Set(["command", "skill"]);
1137
+ /**
1138
+ * Reject an unknown skill id before the wizard authenticates.
1139
+ *
1140
+ * Without this, `readSkillName` accepts any non-empty string and the name is
1141
+ * only validated far downstream, when the agent tries to download it — after
1142
+ * the user has already logged in. A typo then costs a full auth round-trip
1143
+ * (the concern raised in review). We resolve against the same set
1144
+ * `downloadSkill` uses (`categories` flattened by `id`), so this never
1145
+ * false-rejects a skill the download would have accepted.
1146
+ *
1147
+ * If the registry is unreachable we stay silent and defer to the download
1148
+ * step's own `menu-fetch-failed` handling, rather than adding a second network
1149
+ * dependency that could block an otherwise-valid run.
1150
+ */
1151
+ async function assertSkillExists(skillName) {
1152
+ const skillsBaseUrl = getSkillsBaseUrl();
1153
+ const menu = await fetchSkillMenu(skillsBaseUrl);
1154
+ if (!menu) return;
1155
+ if (Object.values(menu.categories).flat().some((s) => s.id === skillName)) return;
1156
+ analytics.wizardCapture("cli dispatch error", {
1157
+ reason: "unknown skill",
1158
+ family: "skill",
1159
+ sub: skillName,
1160
+ skillsBaseUrl
1161
+ });
1162
+ try {
1163
+ await analytics.flush();
1164
+ } catch {}
1165
+ throw new Error(`Unknown skill "${skillName}". Run \`wizard skill list\` to see available skills.`);
1166
+ }
1167
+ function formatEntry(entry) {
1168
+ const path = entry.parentCommand ? `wizard ${entry.parentCommand} ${entry.command}` : entry.command ? `wizard ${entry.command}` : `wizard skill ${entry.skillId}`;
1169
+ return ` ${entry.skillId.padEnd(38)} ${path.padEnd(36)} ${entry.description}`;
1170
+ }
1171
+ /**
1172
+ * `wizard skill <skill-name>` — run a single context-mill skill by id.
1173
+ * `wizard skill list` — list every browsable skill in the catalog.
1174
+ *
1175
+ * Replaces the old `--skill=<id>` flag on the default command. The skill id
1176
+ * is fetched from context-mill's release at runtime (same mechanism the flag
1177
+ * used), so any published skill id works. Pass `--ci` to run headlessly.
1178
+ */
1179
+ const skillCommand = {
1180
+ name: "skill <skill-name>",
1181
+ description: "Run a specific context-mill skill by name (or `list` them)",
1182
+ children: [{
1183
+ name: "list",
1184
+ description: "List every browsable skill in the catalog",
1185
+ handler: () => {
1186
+ runCommandHandler(async () => {
1187
+ const skillsBaseUrl = getSkillsBaseUrl();
1188
+ const menu = await fetchSkillMenu(skillsBaseUrl);
1189
+ if (!menu) {
1190
+ analytics.wizardCapture("cli dispatch error", {
1191
+ reason: "registry unreachable",
1192
+ family: "skill",
1193
+ sub: "list",
1194
+ skillsBaseUrl
1195
+ });
1196
+ try {
1197
+ await analytics.flush();
1198
+ } catch {}
1199
+ 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");
1200
+ emitWizardError({
1201
+ code: ErrorCodes.SkillMenuFetchFailed,
1202
+ message: "Couldn't reach the skill registry."
1203
+ });
1204
+ process.exit(1);
1205
+ }
1206
+ const entries = (menu.cliEntries ?? []).filter((e) => BROWSABLE_ROLES.has(e.role));
1207
+ if (entries.length === 0) {
1208
+ process.stdout.write("No skills found.\n");
1209
+ return;
1210
+ }
1211
+ process.stdout.write(`${entries.length} skill${entries.length === 1 ? "" : "s"}:\n`);
1212
+ process.stdout.write(` ${"SKILL ID".padEnd(38)} ${"COMMAND".padEnd(36)} DESCRIPTION\n`);
1213
+ for (const entry of entries) process.stdout.write(`${formatEntry(entry)}\n`);
1214
+ });
1215
+ }
1216
+ }],
1217
+ options: { ...skillProgramOptions },
1218
+ positionals: { "skill-name": {
1219
+ type: "string",
1220
+ describe: "Skill id to run (e.g. audit-events), or `list`"
1221
+ } },
1222
+ check: (argv) => {
1223
+ if (argv.skillName == null && argv["skill-name"] == null) return true;
1224
+ if (!readSkillName(argv)) throw new Error("skill needs a skill name, e.g. `wizard skill audit-events`");
1225
+ return true;
1226
+ },
1227
+ handler: (argv) => {
1228
+ runCommandHandler(async () => {
1229
+ const skillName = readSkillName(argv);
1230
+ await assertSkillExists(skillName);
1231
+ runSkillMode({
1232
+ ...argv,
1233
+ skill: skillName
1234
+ });
1235
+ });
1236
+ }
1237
+ };
1238
+ //#endregion
1239
+ //#region src/commands/cli/add.ts
1240
+ const cliAddCommand = {
1241
+ name: "add",
1242
+ description: "Install or update PostHog CLI and add steering instructions to your coding agent's global instructions file",
1243
+ options: {
1244
+ agent: {
1245
+ describe: "Agent to install the instructions for",
1246
+ choices: CLI_STEERING_TARGETS.map((target) => target.id),
1247
+ type: "string"
1248
+ },
1249
+ path: {
1250
+ describe: "Write to an explicit instructions file instead of a detected agent",
1251
+ type: "string"
1252
+ },
1253
+ all: {
1254
+ default: false,
1255
+ describe: "Install for every detected agent without prompting",
1256
+ type: "boolean"
1257
+ }
1258
+ },
1259
+ examples: [
1260
+ ["wizard cli add", "Detect your coding agents and pick one"],
1261
+ ["wizard cli add --agent claude-code", "Install for Claude Code (~/.claude/CLAUDE.md)"],
1262
+ ["wizard cli add --all", "Install for every detected agent"],
1263
+ ["wizard cli add --path ./AGENTS.md", "Install into a specific instructions file"]
1264
+ ],
1265
+ check: (argv) => {
1266
+ if (argv.all && (argv.agent || argv.path)) throw new Error("--all cannot be combined with --agent or --path");
1267
+ return true;
1268
+ },
1269
+ handler: (argv) => {
1270
+ runCliAdd(argv);
1271
+ }
1272
+ };
1273
+ async function runCliAdd(argv) {
1274
+ setUI(new LoggingUI());
1275
+ const ui = getUI();
1276
+ ui.intro("PostHog CLI setup");
1277
+ const files = await resolveTargetFiles(argv);
1278
+ if (files.length === 0) {
1279
+ process.exit(1);
1280
+ return;
1281
+ }
1282
+ ui.log.info("Installing or updating PostHog CLI...");
1283
+ const cliInstallResult = installOrUpdatePostHogCli();
1284
+ if (!cliInstallResult.success) {
1285
+ ui.log.error(`Failed to install or update PostHog CLI: ${cliInstallResult.error ?? ""}`);
1286
+ analytics.wizardCapture("cli steering installed", {
1287
+ files: files.length,
1288
+ failures: files.length,
1289
+ cli_install_failed: true,
1290
+ agent: typeof argv.agent === "string" ? argv.agent : void 0
1291
+ });
1292
+ process.exit(1);
1293
+ return;
1294
+ }
1295
+ ui.log.success("Installed or updated PostHog CLI.");
1296
+ let failures = 0;
1297
+ for (const file of files) {
1298
+ const result = installSteeringSnippet(file);
1299
+ if (result.success) ui.log.success(`Installed PostHog steering instructions in ${file}`);
1300
+ else {
1301
+ failures += 1;
1302
+ ui.log.error(`Failed to update ${file}: ${result.error ?? ""}`);
1303
+ }
1304
+ }
1305
+ analytics.wizardCapture("cli steering installed", {
1306
+ files: files.length,
1307
+ failures,
1308
+ agent: typeof argv.agent === "string" ? argv.agent : void 0
1309
+ });
1310
+ if (failures > 0) {
1311
+ process.exit(1);
1312
+ return;
1313
+ }
1314
+ ui.outro("Done. PostHog CLI is installed and your agent will now use `posthog-cli api` for PostHog tasks.");
1315
+ process.exit(0);
1316
+ }
1317
+ /** Resolve which instruction files to write, from flags, detection, or a prompt. */
1318
+ async function resolveTargetFiles(argv) {
1319
+ const ui = getUI();
1320
+ if (typeof argv.path === "string" && argv.path.trim()) return [path$1.resolve(argv.path.trim())];
1321
+ if (typeof argv.agent === "string") {
1322
+ const target = findTarget(argv.agent);
1323
+ if (!target) {
1324
+ ui.log.error(`Unsupported agent: ${argv.agent}`);
1325
+ return [];
1326
+ }
1327
+ return [target.instructionsPath()];
1328
+ }
1329
+ const detected = detectTargets();
1330
+ if (detected.length === 0) {
1331
+ ui.log.error("No supported coding agents detected. Pass --agent <id> or --path <file> to choose a target.");
1332
+ ui.log.info(`Supported agents: ${CLI_STEERING_TARGETS.map((t) => t.id).join(", ")}`);
1333
+ return [];
1334
+ }
1335
+ if (argv.all === true) {
1336
+ ui.log.info(`Installing for all detected agents: ${detected.map((t) => t.name).join(", ")}`);
1337
+ return detected.map((target) => target.instructionsPath());
1338
+ }
1339
+ if (detected.length === 1) {
1340
+ ui.log.info(`Detected ${detected[0].name} (${detected[0].instructionsPath()})`);
1341
+ return [detected[0].instructionsPath()];
1342
+ }
1343
+ if (!process.stdin.isTTY || !process.stdout.isTTY) {
1344
+ ui.log.info(`Installing for all detected agents: ${detected.map((t) => t.name).join(", ")}`);
1345
+ return detected.map((target) => target.instructionsPath());
1346
+ }
1347
+ return (await promptForTargets(detected)).map((target) => target.instructionsPath());
1348
+ }
1349
+ /** Minimal numbered selection — this command is intentionally not a TUI flow. */
1350
+ async function promptForTargets(detected) {
1351
+ const ui = getUI();
1352
+ ui.log.info("Which coding agent are you using?");
1353
+ detected.forEach((target, index) => {
1354
+ ui.log.info(` ${index + 1}) ${target.name} (${target.instructionsPath()})`);
1355
+ });
1356
+ ui.log.info(` ${detected.length + 1}) All of the above`);
1357
+ const rl = readline.createInterface({
1358
+ input: process.stdin,
1359
+ output: process.stdout
1360
+ });
1361
+ try {
1362
+ for (;;) {
1363
+ const answer = (await rl.question(`Select 1-${detected.length + 1}: `)).trim();
1364
+ const choice = Number(answer);
1365
+ if (Number.isInteger(choice) && choice >= 1 && choice <= detected.length) return [detected[choice - 1]];
1366
+ if (choice === detected.length + 1) return detected;
1367
+ ui.log.warn(`Enter a number between 1 and ${detected.length + 1}.`);
1368
+ }
1369
+ } finally {
1370
+ rl.close();
1371
+ }
1372
+ }
1373
+ //#endregion
1374
+ //#region src/commands/cli/index.ts
1375
+ const cliCommand = {
1376
+ name: "cli",
1377
+ description: "PostHog CLI agent integration commands",
1378
+ children: [cliAddCommand]
1379
+ };
1380
+ //#endregion
1381
+ //#region main.ts
1382
+ setGlobalDispatcher(new Agent({ allowH2: false }));
1383
+ recoverOrphanedSettingsBackups(resolveInstallDir());
1384
+ function resolveInstallDir() {
1385
+ const args = process.argv.slice(2);
1386
+ const flagIndex = args.indexOf("--install-dir");
1387
+ if (flagIndex !== -1 && args[flagIndex + 1]) return args[flagIndex + 1];
1388
+ const inline = args.find((a) => a.startsWith("--install-dir="));
1389
+ if (inline) return inline.slice(14);
1390
+ return process.env.POSTHOG_WIZARD_INSTALL_DIR ?? process.cwd();
1391
+ }
1392
+ Wizard.use(basicIntegrationCommand).use(mcpCommand).use(mcpAnalyticsCommand).use(replayVisionCommand).use(aiObservabilityCommand).use(metricsCommand).use(cliCommand).use(auditCommand).use(doctorCommand).use(migrateCommand).use(revenueCommand).use(warehouseCommand).use(selfDrivingCommand).use(slackCommand).use(uploadSourcemapsCommand).use(errorTrackingCommand).use(skillCommand).init();
1393
+ //#endregion
1394
+ export {};
1395
+
1396
+ //# sourceMappingURL=main-CgKxbwMP.js.map