@posthog/wizard 2.21.0 → 2.22.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 (65) hide show
  1. package/README.md +14 -1
  2. package/dist/{OutroScreen-CqF6SdBo.js → AiOptInRequiredScreen-N6L80szR.js} +443 -59
  3. package/dist/AiOptInRequiredScreen-N6L80szR.js.map +1 -0
  4. package/dist/{add-mcp-server-to-clients-DQHGhzt6.js → add-mcp-server-to-clients-DqHCkHqM.js} +12 -10
  5. package/dist/add-mcp-server-to-clients-DqHCkHqM.js.map +1 -0
  6. package/dist/{agent-interface-DE7txTqh.js → agent-interface-DZmVoik2.js} +5 -5
  7. package/dist/{agent-interface-DE7txTqh.js.map → agent-interface-DZmVoik2.js.map} +1 -1
  8. package/dist/{agent-runner-DUZ5OD6e.js → agent-runner-CGFUXR97.js} +13 -9
  9. package/dist/{agent-runner-DUZ5OD6e.js.map → agent-runner-CGFUXR97.js.map} +1 -1
  10. package/dist/{analytics-Bl5DPj_0.js → analytics-C_lVPZQT.js} +28 -4
  11. package/dist/analytics-C_lVPZQT.js.map +1 -0
  12. package/dist/{api-DuA0_88V.js → api-QI1lO_Bz.js} +3 -3
  13. package/dist/{api-DuA0_88V.js.map → api-QI1lO_Bz.js.map} +1 -1
  14. package/dist/bin.js +160 -49
  15. package/dist/bin.js.map +1 -1
  16. package/dist/{ci-install-BnOYI4mZ.js → ci-install-CXkKR4A-.js} +4 -4
  17. package/dist/{ci-install-BnOYI4mZ.js.map → ci-install-CXkKR4A-.js.map} +1 -1
  18. package/dist/{debug-h7Z9zEbD.js → debug-D8QAez2V.js} +58 -13
  19. package/dist/debug-D8QAez2V.js.map +1 -0
  20. package/dist/{debug-BVC48wlb.js → debug-lPpecs0J.js} +1 -1
  21. package/dist/{environment-uaLmtlH_.js → environment-CMmzgZkN.js} +3 -3
  22. package/dist/{environment-uaLmtlH_.js.map → environment-CMmzgZkN.js.map} +1 -1
  23. package/dist/{interactive-CW5gjyDd.js → interactive-Bu8YchJG.js} +2 -2
  24. package/dist/{interactive-CW5gjyDd.js.map → interactive-Bu8YchJG.js.map} +1 -1
  25. package/dist/{mcp-prompt-streaming-DMDwaark.js → mcp-prompt-streaming-mYw2LPZZ.js} +4 -4
  26. package/dist/{mcp-prompt-streaming-DMDwaark.js.map → mcp-prompt-streaming-mYw2LPZZ.js.map} +1 -1
  27. package/dist/{non-interactive-DJrVQ4nS.js → non-interactive-De3tJM1y.js} +2 -2
  28. package/dist/{non-interactive-DJrVQ4nS.js.map → non-interactive-De3tJM1y.js.map} +1 -1
  29. package/dist/{package-manager-DCUBRbr-.js → package-manager-BVJnbp1u.js} +2 -2
  30. package/dist/{package-manager-DCUBRbr-.js.map → package-manager-BVJnbp1u.js.map} +1 -1
  31. package/dist/{playground-DCVaVeVD.js → playground-wyoq1yIH.js} +82 -4
  32. package/dist/playground-wyoq1yIH.js.map +1 -0
  33. package/dist/{posthog-integration-ChdwFPMj.js → posthog-integration-mrMF-2IP.js} +48 -16
  34. package/dist/posthog-integration-mrMF-2IP.js.map +1 -0
  35. package/dist/{provisioning-GeMkBMSR.js → provisioning-4zipVpbq.js} +3 -3
  36. package/dist/{provisioning-GeMkBMSR.js.map → provisioning-4zipVpbq.js.map} +1 -1
  37. package/dist/{registry-VSSRH3sU.js → registry-BGUo4PlM.js} +7 -20
  38. package/dist/registry-BGUo4PlM.js.map +1 -0
  39. package/dist/{setup-utils-BfV4pydt.js → setup-utils-DmhPyWkp.js} +114 -58
  40. package/dist/setup-utils-DmhPyWkp.js.map +1 -0
  41. package/dist/{start-tui-BRvm5VP9.js → start-tui-DaQiY_EB.js} +310 -130
  42. package/dist/start-tui-DaQiY_EB.js.map +1 -0
  43. package/dist/{steps-DA4uvSbg.js → steps-CrUceWR5.js} +6 -6
  44. package/dist/{steps-DA4uvSbg.js.map → steps-CrUceWR5.js.map} +1 -1
  45. package/dist/telemetry-CCVjGq7l.js +68 -0
  46. package/dist/telemetry-CCVjGq7l.js.map +1 -0
  47. package/dist/{urls-B66Ib2jT.js → urls-BNFpfcN8.js} +2 -2
  48. package/dist/{urls-B66Ib2jT.js.map → urls-BNFpfcN8.js.map} +1 -1
  49. package/dist/{wizard-abort-D1_DnFjm.js → wizard-abort-BmYb0bG2.js} +3 -3
  50. package/dist/{wizard-abort-D1_DnFjm.js.map → wizard-abort-BmYb0bG2.js.map} +1 -1
  51. package/dist/{wizard-abort-gMB1eV6T.js → wizard-abort-Bp2yxYAy.js} +1 -1
  52. package/dist/wizard-session-G3VWD6hv.js.map +1 -1
  53. package/dist/wizard-ui-YdGFRyu_.js.map +1 -1
  54. package/package.json +1 -1
  55. package/dist/OutroScreen-CqF6SdBo.js.map +0 -1
  56. package/dist/add-mcp-server-to-clients-DQHGhzt6.js.map +0 -1
  57. package/dist/analytics-Bl5DPj_0.js.map +0 -1
  58. package/dist/debug-h7Z9zEbD.js.map +0 -1
  59. package/dist/playground-DCVaVeVD.js.map +0 -1
  60. package/dist/posthog-integration-ChdwFPMj.js.map +0 -1
  61. package/dist/registry-VSSRH3sU.js.map +0 -1
  62. package/dist/setup-utils-BfV4pydt.js.map +0 -1
  63. package/dist/start-tui-BRvm5VP9.js.map +0 -1
  64. package/dist/telemetry-BRAonUea.js +0 -13
  65. package/dist/telemetry-BRAonUea.js.map +0 -1
@@ -1,20 +1,20 @@
1
- import { M as POSTHOG_DOCS_URL, O as Integration, R as REMOTE_SKILLS_BASE_URL, U as WIZARD_TOOLS_MENU_FLAG_KEY, _ as SIGNUP_WIZARD_READINESS_CONFIG, d as relativeToInstallDir, k as OAUTH_PORTS, l as WIZARD_LOG_FILE, m as setUI, q as getSkillsBaseUrl, s as logToFile, y as getBlockingServiceKeys } from "./debug-h7Z9zEbD.js";
2
- import { t as analytics } from "./analytics-Bl5DPj_0.js";
3
- import { o as extractOAuthCode, t as getOrAskForProjectData } from "./setup-utils-BfV4pydt.js";
4
- import { a as getUiHostFromHost } from "./urls-B66Ib2jT.js";
5
- import { t as ApiError } from "./api-DuA0_88V.js";
1
+ import { A as OAUTH_PORTS, J as WIZARD_TOOLS_MENU_FLAG_KEY, L as POSTHOG_ORG_AI_SETTINGS_URL, P as POSTHOG_DOCS_URL, R as POSTHOG_PRIVACY_URL, U as REMOTE_SKILLS_BASE_URL, V as POSTHOG_TERMS_URL, _ as SIGNUP_WIZARD_READINESS_CONFIG, d as relativeToInstallDir, j as OAUTH_TIMEOUT_MS, k as Integration, l as WIZARD_LOG_FILE, m as setUI, s as logToFile, y as getBlockingServiceKeys } from "./debug-D8QAez2V.js";
2
+ import { t as analytics } from "./analytics-C_lVPZQT.js";
3
+ import { o as extractOAuthCode, t as getOrAskForProjectData } from "./setup-utils-DmhPyWkp.js";
4
+ import { a as getUiHostFromHost } from "./urls-BNFpfcN8.js";
5
+ import { t as ApiError } from "./api-QI1lO_Bz.js";
6
6
  import { t as ADDITIONAL_FEATURE_LABELS } from "./wizard-session-G3VWD6hv.js";
7
- import { i as wizardAbort } from "./wizard-abort-D1_DnFjm.js";
8
- import { _ as AUDIT_CHECKS_KEY, b as coerceAuditChecks, g as AUDIT_CHECKS_FILE, m as fetchSkillMenu, p as downloadSkill, x as getAuditChecks, y as AUDIT_SEVERITY_STYLE } from "./agent-interface-DE7txTqh.js";
9
- import { f as Colors, p as Icons, t as EVENT_PLAN_FILE } from "./posthog-integration-ChdwFPMj.js";
7
+ import { i as wizardAbort } from "./wizard-abort-BmYb0bG2.js";
8
+ import { _ as AUDIT_CHECKS_KEY, b as coerceAuditChecks, g as AUDIT_CHECKS_FILE, m as fetchSkillMenu, p as downloadSkill, x as getAuditChecks, y as AUDIT_SEVERITY_STYLE } from "./agent-interface-DZmVoik2.js";
9
+ import { f as Colors, p as Icons, t as EVENT_PLAN_FILE } from "./posthog-integration-mrMF-2IP.js";
10
10
  import { a as getProgramConfig, d as getContentBlocks, f as POSTHOG_SDKS, i as Program, o as DISPLAY_NAME, p as STRIPE_SDKS, s as SOURCE_MAPS_CONTEXT_KEYS, u as fetchHealthIssues } from "./bin.js";
11
- import { A as SplitView, C as ConfirmationInput, D as useKeyBindings, E as PickerMenu, M as WizardStore, O as ProgressList, S as ModalOverlay, T as useStdoutDimensions, _ as HNViewer, a as VisualBox, b as EventPlanViewer, d as SEVERITY_LABEL, f as SEVERITY_ORDER, h as LearnCard, i as AUDIT_AREA_SLIDES, k as LoadingBox, l as McpScreen, m as TipsCard, n as SlackConnectScreen, o as AuditChecksViewer, p as ServiceHealthList, r as AUDIT_3000_AREA_SLIDES, s as McpSuggestedPromptsScreen, t as OutroScreen, u as IssueTable, v as TabContainer, x as LogViewer, y as ScreenContainer } from "./OutroScreen-CqF6SdBo.js";
11
+ import { A as useKeyBindings, C as EventPlanViewer, E as ConfirmationInput, F as WizardStore, M as LoadingBox, N as SplitView, O as useStdoutDimensions, S as ScreenContainer, T as ModalOverlay, _ as TipsCard, a as SlackConnectScreen, b as HNViewer, c as VisualBox, f as McpScreen, g as ServiceHealthList, h as SEVERITY_ORDER, i as OutroScreen, j as ProgressList, k as PickerMenu, l as AuditChecksViewer, m as SEVERITY_LABEL, n as SkillSourceInfo, o as AUDIT_3000_AREA_SLIDES, p as IssueTable, r as useSkillEntry, s as AUDIT_AREA_SLIDES, t as AiOptInRequiredScreen, u as McpSuggestedPromptsScreen, v as LearnCard, w as LogViewer, x as TabContainer } from "./AiOptInRequiredScreen-N6L80szR.js";
12
12
  import { t as ALL_FEATURE_VALUES } from "./defaults-BNWIWzjc.js";
13
- import { a as getSupportedClients, c as removeMCPServer, i as getInstalledClients, o as getSupportedPluginClients, s as installPlugins, u as isPluginCapable } from "./add-mcp-server-to-clients-DQHGhzt6.js";
14
- import { spawn, spawnSync } from "node:child_process";
15
- import { join } from "node:path";
13
+ import { a as getSupportedClients, c as removeMCPServer, i as getInstalledClients, o as getSupportedPluginClients, s as installPlugins, u as isPluginCapable } from "./add-mcp-server-to-clients-DqHCkHqM.js";
16
14
  import * as fs$1 from "fs";
17
15
  import path from "path";
16
+ import { join as join$1 } from "node:path";
17
+ import { spawn, spawnSync } from "node:child_process";
18
18
  import { Box, Text, render, useInput } from "ink";
19
19
  import { Fragment, createElement, useEffect, useMemo, useState, useSyncExternalStore } from "react";
20
20
  import { Fragment as Fragment$1, jsx, jsxs } from "react/jsx-runtime";
@@ -67,6 +67,9 @@ var InkUI = class {
67
67
  setApiUser(user) {
68
68
  this.store.setApiUser(user);
69
69
  }
70
+ waitForAiOptIn() {
71
+ return this.store.getGate("ai-opt-in");
72
+ }
70
73
  setDetectedFramework(label) {
71
74
  this.store.setDetectedFramework(label);
72
75
  }
@@ -98,6 +101,9 @@ var InkUI = class {
98
101
  showAuthError(detail) {
99
102
  this.store.showAuthError(detail);
100
103
  }
104
+ showSessionTimeout() {
105
+ this.store.showSessionTimeout();
106
+ }
101
107
  requestQuestion(question) {
102
108
  return this.store.requestQuestion(question);
103
109
  }
@@ -837,7 +843,7 @@ const WizardTitle = ({ title }) => /* @__PURE__ */ jsxs(Text, {
837
843
  title
838
844
  ]
839
845
  });
840
- const IntroScreenLayout = ({ installDir, title = "PostHog Wizard 🦔", showSubtitle = true, body, showDetection = true, detectionRows, children, menuOptions, onSelect, programLabel, skillId, errorView }) => {
846
+ const IntroScreenLayout = ({ installDir, title = "PostHog Wizard 🦔", showSubtitle = true, body, showDetection = true, detectionRows, children, menuOptions, menuAlign = "center", onSelect, programLabel, skillId, errorView }) => {
841
847
  const resolvedMenuOptions = menuOptions === void 0 ? [{
842
848
  label: "Continue",
843
849
  value: "continue"
@@ -933,9 +939,10 @@ const IntroScreenLayout = ({ installDir, title = "PostHog Wizard 🦔", showSubt
933
939
  ]
934
940
  }),
935
941
  /* @__PURE__ */ jsx(Box, {
936
- width: 24,
942
+ width: menuAlign === "left" ? 64 : 24,
943
+ marginTop: 1,
937
944
  children: resolvedMenuOptions && onSelect && /* @__PURE__ */ jsx(Box, {
938
- justifyContent: "center",
945
+ justifyContent: menuAlign === "left" ? "flex-start" : "center",
939
946
  children: /* @__PURE__ */ jsx(PickerMenu, {
940
947
  options: resolvedMenuOptions,
941
948
  onSelect: (value) => {
@@ -948,68 +955,51 @@ const IntroScreenLayout = ({ installDir, title = "PostHog Wizard 🦔", showSubt
948
955
  }) });
949
956
  };
950
957
  //#endregion
951
- //#region src/ui/tui/screens/SkillSourceInfo.tsx
958
+ //#region src/ui/tui/components/PrivacyPanel.tsx
952
959
  /**
953
- * Shared "Skill: <id> / URL: <downloadUrl>" block for intro screens.
960
+ * PrivacyPanel Shared disclosure component.
954
961
  *
955
- * `useSkillEntry` fetches the entry from the skill menu and re-runs when
956
- * `skillId` or `local` change. The previous fetch is cancelled (its result
957
- * is ignored) so a session that flips `local=false true` mid-mount picks
958
- * up the right base URL.
962
+ * Single source of truth for the wizard's privacy disclosure, rendered
963
+ * identically from the intro screen ("Privacy & data usage" menu option)
964
+ * and as an overlay from the auth screen ([I] keystroke).
959
965
  *
960
- * `<SkillSourceInfo>` renders the block, taking the entry as a prop so the
961
- * caller can reuse the same hook result for additional UI (e.g. showing
962
- * `skillEntry.name`) without invoking the hook twice.
966
+ * Must fit in a default-sized macOS Terminal (~24 rows). Two condensed
967
+ * paragraphs carry the top-level disclosure; the link footer follows.
968
+ * Users who want the full legal text follow the Terms / Privacy URLs to
969
+ * their browser.
963
970
  */
964
- function useSkillEntry(skillId, local) {
965
- const [skillEntry, setSkillEntry] = useState(null);
966
- const [fetchFailed, setFetchFailed] = useState(false);
967
- useEffect(() => {
968
- if (!skillId) {
969
- setFetchFailed(true);
970
- return;
971
- }
972
- let cancelled = false;
973
- setSkillEntry(null);
974
- setFetchFailed(false);
975
- fetchSkillMenu(getSkillsBaseUrl(local)).then((menu) => {
976
- if (cancelled) return;
977
- if (!menu) {
978
- setFetchFailed(true);
979
- return;
980
- }
981
- const match = Object.values(menu.categories).flat().find((s) => s.id === skillId);
982
- if (match) setSkillEntry(match);
983
- else setFetchFailed(true);
984
- });
985
- return () => {
986
- cancelled = true;
987
- };
988
- }, [skillId, local]);
989
- return {
990
- skillEntry,
991
- fetchFailed
992
- };
993
- }
994
- const SkillSourceInfo = ({ skillId, skillEntry, fetchFailed }) => /* @__PURE__ */ jsxs(Box, {
995
- flexDirection: "column",
996
- children: [/* @__PURE__ */ jsxs(Text, { children: [
997
- "Skill:",
998
- " ",
999
- /* @__PURE__ */ jsx(Text, {
1000
- italic: true,
1001
- color: "cyan",
1002
- children: skillId ?? "unknown"
1003
- })
1004
- ] }), /* @__PURE__ */ jsxs(Text, { children: [
1005
- "URL:",
1006
- " ",
1007
- /* @__PURE__ */ jsx(Text, {
1008
- color: "cyan",
1009
- children: skillEntry?.downloadUrl ?? (fetchFailed ? "unavailable" : "Loading...")
1010
- })
1011
- ] })]
1012
- });
971
+ const PrivacyPanel = () => {
972
+ return /* @__PURE__ */ jsxs(Box, {
973
+ flexDirection: "column",
974
+ width: 64,
975
+ flexShrink: 0,
976
+ children: [
977
+ /* @__PURE__ */ jsx(Text, { children: "We use Anthropic's Claude via the PostHog LLM gateway to read your source files as AI context. .env* files, secrets, and anything matched by the security scanner stay on your machine." }),
978
+ /* @__PURE__ */ jsx(Box, {
979
+ marginTop: 1,
980
+ children: /* @__PURE__ */ jsx(Text, { children: "To use the wizard, AI features must be enabled in your organization's settings." })
981
+ }),
982
+ /* @__PURE__ */ jsxs(Box, {
983
+ marginTop: 1,
984
+ flexDirection: "column",
985
+ children: [
986
+ /* @__PURE__ */ jsxs(Text, { children: ["Terms: ", /* @__PURE__ */ jsx(Text, {
987
+ color: "cyan",
988
+ children: POSTHOG_TERMS_URL
989
+ })] }),
990
+ /* @__PURE__ */ jsxs(Text, { children: ["Privacy: ", /* @__PURE__ */ jsx(Text, {
991
+ color: "cyan",
992
+ children: POSTHOG_PRIVACY_URL
993
+ })] }),
994
+ /* @__PURE__ */ jsxs(Text, { children: ["AI settings: ", /* @__PURE__ */ jsx(Text, {
995
+ color: "cyan",
996
+ children: POSTHOG_ORG_AI_SETTINGS_URL
997
+ })] })
998
+ ]
999
+ })
1000
+ ]
1001
+ });
1002
+ };
1013
1003
  //#endregion
1014
1004
  //#region src/ui/tui/screens/PostHogIntegrationIntroScreen.tsx
1015
1005
  /**
@@ -1046,7 +1036,7 @@ const FrameworkPicker = ({ store, onComplete }) => {
1046
1036
  })),
1047
1037
  onSelect: (value) => {
1048
1038
  const integration = Array.isArray(value) ? value[0] : value;
1049
- import("./registry-VSSRH3sU.js").then((n) => n.n).then(({ FRAMEWORK_REGISTRY }) => {
1039
+ import("./registry-BGUo4PlM.js").then((n) => n.n).then(({ FRAMEWORK_REGISTRY }) => {
1050
1040
  const config = FRAMEWORK_REGISTRY[integration];
1051
1041
  store.setFrameworkConfig(integration, config);
1052
1042
  store.setDetectedFramework(config.metadata.name);
@@ -1079,7 +1069,7 @@ const PostHogIntegrationIntroScreen = ({ store }) => {
1079
1069
  const needsFrameworkPick = session.detectionComplete && !session.frameworkConfig;
1080
1070
  const unsupported = session.unsupportedVersion;
1081
1071
  const showContinue = session.frameworkConfig !== null && !detecting && !pickingFramework && view === "default" && !unsupported;
1082
- const title = detecting ? "PostHog Wizard starting up" : "PostHog Wizard 🦔";
1072
+ const title = view === "privacy" ? "Wizard privacy & usage" : detecting ? "PostHog Wizard starting up" : "PostHog Wizard 🦔";
1083
1073
  let body = null;
1084
1074
  if (detecting) body = /* @__PURE__ */ jsx(Box, {
1085
1075
  marginY: 1,
@@ -1101,7 +1091,7 @@ const PostHogIntegrationIntroScreen = ({ store }) => {
1101
1091
  });
1102
1092
  else if (view === "more-info") body = /* @__PURE__ */ jsxs(Box, {
1103
1093
  flexDirection: "column",
1104
- width: 56,
1094
+ width: 64,
1105
1095
  flexShrink: 0,
1106
1096
  children: [
1107
1097
  /* @__PURE__ */ jsxs(Text, { children: ["The wizard is an agent that executes PostHog tasks. Its code is open source: ", /* @__PURE__ */ jsx(Text, {
@@ -1128,10 +1118,10 @@ const PostHogIntegrationIntroScreen = ({ store }) => {
1128
1118
  marginTop: 1,
1129
1119
  paddingLeft: 4,
1130
1120
  children: [
1131
- /* @__PURE__ */ jsxs(Text, { children: [`\u2022`, " Product Analytics"] }),
1132
- /* @__PURE__ */ jsxs(Text, { children: [`\u2022`, " Web Analytics"] }),
1133
- /* @__PURE__ */ jsxs(Text, { children: [`\u2022`, " Session Replay"] }),
1134
- /* @__PURE__ */ jsxs(Text, { children: [`\u2022`, " Error Tracking"] })
1121
+ /* @__PURE__ */ jsxs(Text, { children: [`•`, " Product Analytics"] }),
1122
+ /* @__PURE__ */ jsxs(Text, { children: [`•`, " Web Analytics"] }),
1123
+ /* @__PURE__ */ jsxs(Text, { children: [`•`, " Session Replay"] }),
1124
+ /* @__PURE__ */ jsxs(Text, { children: [`•`, " Error Tracking"] })
1135
1125
  ]
1136
1126
  }),
1137
1127
  /* @__PURE__ */ jsxs(Box, {
@@ -1148,6 +1138,7 @@ const PostHogIntegrationIntroScreen = ({ store }) => {
1148
1138
  })
1149
1139
  ]
1150
1140
  });
1141
+ else if (view === "privacy") body = /* @__PURE__ */ jsx(PrivacyPanel, {});
1151
1142
  else if (showContinue) body = /* @__PURE__ */ jsx(Fragment$1, { children: /* @__PURE__ */ jsx(Box, { children: /* @__PURE__ */ jsx(Text, { children: "Let's do two hours of work in eight minutes." }) }) });
1152
1143
  const detectionRows = [];
1153
1144
  if (frameworkLabel) {
@@ -1218,6 +1209,13 @@ const PostHogIntegrationIntroScreen = ({ store }) => {
1218
1209
  else if (view === "more-info") menuOptions = [{
1219
1210
  label: "Back",
1220
1211
  value: "back"
1212
+ }, {
1213
+ label: "Privacy & data usage",
1214
+ value: "privacy"
1215
+ }];
1216
+ else if (view === "privacy") menuOptions = [{
1217
+ label: "Back",
1218
+ value: "back"
1221
1219
  }];
1222
1220
  else if (showContinue) menuOptions = [
1223
1221
  {
@@ -1252,8 +1250,9 @@ const PostHogIntegrationIntroScreen = ({ store }) => {
1252
1250
  setPickingFramework(true);
1253
1251
  setManuallySelected(true);
1254
1252
  } else if (value === "more-info") setView("more-info");
1253
+ else if (value === "privacy") setView("privacy");
1255
1254
  else if (value === "tools") setView("tools");
1256
- else if (value === "back") setView("default");
1255
+ else if (value === "back") setView(view === "privacy" ? "more-info" : "default");
1257
1256
  else store.completeSetup();
1258
1257
  };
1259
1258
  return /* @__PURE__ */ jsx(IntroScreenLayout, {
@@ -1264,6 +1263,7 @@ const PostHogIntegrationIntroScreen = ({ store }) => {
1264
1263
  showDetection: showContinue,
1265
1264
  detectionRows,
1266
1265
  menuOptions: unsupported ? null : menuOptions,
1266
+ menuAlign: "center",
1267
1267
  onSelect: handleSelect,
1268
1268
  programLabel: session.programLabel,
1269
1269
  skillId: session.skillId,
@@ -1582,6 +1582,7 @@ const MigrationIntroScreen = ({ store }) => {
1582
1582
  */
1583
1583
  const SourceMapsIntroScreen = ({ store }) => {
1584
1584
  useSyncExternalStore((cb) => store.subscribe(cb), () => store.getSnapshot());
1585
+ const [view, setView] = useState("default");
1585
1586
  const { session } = store;
1586
1587
  const detectError = session.frameworkContext[SOURCE_MAPS_CONTEXT_KEYS.detectError];
1587
1588
  const variant = session.frameworkContext[SOURCE_MAPS_CONTEXT_KEYS.skillVariant];
@@ -1596,7 +1597,54 @@ const SourceMapsIntroScreen = ({ store }) => {
1596
1597
  label: "Skill",
1597
1598
  value: `error-tracking-upload-source-maps-${variant}`
1598
1599
  });
1599
- const body = /* @__PURE__ */ jsxs(Fragment$1, { children: [/* @__PURE__ */ jsxs(Box, {
1600
+ const body = view === "more-info" ? /* @__PURE__ */ jsxs(Box, {
1601
+ flexDirection: "column",
1602
+ width: 56,
1603
+ flexShrink: 0,
1604
+ children: [
1605
+ /* @__PURE__ */ jsxs(Text, { children: [
1606
+ "The wizard is an agent that executes PostHog tasks. Its code is open source: ",
1607
+ /* @__PURE__ */ jsx(Text, {
1608
+ color: "cyan",
1609
+ children: "https://github.com/PostHog/wizard"
1610
+ }),
1611
+ "."
1612
+ ] }),
1613
+ /* @__PURE__ */ jsx(Box, {
1614
+ flexDirection: "column",
1615
+ marginTop: 1,
1616
+ children: /* @__PURE__ */ jsxs(Text, { children: [
1617
+ "The",
1618
+ " ",
1619
+ /* @__PURE__ */ jsx(Text, {
1620
+ italic: true,
1621
+ color: "cyan",
1622
+ children: session.programLabel
1623
+ }),
1624
+ " ",
1625
+ "program sets up your project to upload source maps to PostHog, so Error Tracking shows production stack traces in your original source instead of minified bundles. It will:"
1626
+ ] })
1627
+ }),
1628
+ /* @__PURE__ */ jsxs(Box, {
1629
+ flexDirection: "column",
1630
+ marginTop: 1,
1631
+ paddingLeft: 4,
1632
+ children: [
1633
+ /* @__PURE__ */ jsxs(Text, { children: ["•", " Ask for a personal API key to authorize uploads"] }),
1634
+ /* @__PURE__ */ jsxs(Text, { children: ["•", " Wire map generation + upload into your build"] }),
1635
+ /* @__PURE__ */ jsxs(Text, { children: ["•", " Write the upload credentials to your .env"] }),
1636
+ /* @__PURE__ */ jsxs(Text, { children: ["•", " Wire CI for deploys and offer a local test run"] })
1637
+ ]
1638
+ }),
1639
+ /* @__PURE__ */ jsx(Box, {
1640
+ marginTop: 1,
1641
+ children: /* @__PURE__ */ jsx(Text, {
1642
+ dimColor: true,
1643
+ children: "Maps upload to PostHog during the production build and never need to be served publicly."
1644
+ })
1645
+ })
1646
+ ]
1647
+ }) : view === "privacy" ? /* @__PURE__ */ jsx(PrivacyPanel, {}) : /* @__PURE__ */ jsxs(Fragment$1, { children: [/* @__PURE__ */ jsxs(Box, {
1600
1648
  flexDirection: "column",
1601
1649
  alignItems: "center",
1602
1650
  children: [/* @__PURE__ */ jsx(Text, { children: "Upload source maps for accurate error stack traces." }), /* @__PURE__ */ jsx(Box, {
@@ -1643,23 +1691,46 @@ const SourceMapsIntroScreen = ({ store }) => {
1643
1691
  }],
1644
1692
  onSelect: () => process.exit(1)
1645
1693
  })] }) : void 0;
1694
+ const menuOptions = view === "more-info" ? [{
1695
+ label: "Back",
1696
+ value: "back"
1697
+ }, {
1698
+ label: "Privacy & data usage",
1699
+ value: "privacy"
1700
+ }] : view === "privacy" ? [{
1701
+ label: "Back",
1702
+ value: "back"
1703
+ }] : [
1704
+ {
1705
+ label: "Continue",
1706
+ value: "continue"
1707
+ },
1708
+ {
1709
+ label: "More info",
1710
+ value: "more-info"
1711
+ },
1712
+ {
1713
+ label: "Cancel",
1714
+ value: "cancel"
1715
+ }
1716
+ ];
1717
+ const title = view === "privacy" ? "Wizard privacy & usage" : "PostHog Wizard 🦔";
1646
1718
  return /* @__PURE__ */ jsx(IntroScreenLayout, {
1647
1719
  installDir: session.installDir,
1720
+ title,
1721
+ showSubtitle: view === "default",
1648
1722
  body,
1649
- showDetection: true,
1723
+ showDetection: view === "default",
1650
1724
  detectionRows,
1651
1725
  errorView,
1652
1726
  programLabel: session.programLabel,
1653
1727
  skillId: session.skillId,
1654
- menuOptions: [{
1655
- label: "Continue",
1656
- value: "continue"
1657
- }, {
1658
- label: "Cancel",
1659
- value: "cancel"
1660
- }],
1728
+ menuOptions,
1661
1729
  onSelect: (value) => {
1662
1730
  if (value === "cancel") process.exit(0);
1731
+ else if (value === "more-info") setView("more-info");
1732
+ else if (value === "privacy") setView("privacy");
1733
+ else if (value === "back") setView(view === "privacy" ? "more-info" : "default");
1663
1734
  else store.completeSetup();
1664
1735
  }
1665
1736
  });
@@ -1832,7 +1903,7 @@ const DetectErrorBody = ({ error }) => {
1832
1903
  * Unlike the generic OutroScreen, this spells out the operational facts a user
1833
1904
  * needs to actually get de-minified stack traces: that packages were installed
1834
1905
  * and upload credentials written to .env, plus the three gotchas (builds
1835
- * upload, run the build, mirror the env vars in CI). All static guidance —
1906
+ * upload, run the build, give CI the same credentials). All static guidance —
1836
1907
  * driven only by the program's `buildOutroData` (kind / message / report /
1837
1908
  * docs), no per-run data.
1838
1909
  */
@@ -1899,12 +1970,7 @@ const SourceMapsOutroScreen = ({ store }) => {
1899
1970
  bold: true,
1900
1971
  children: "CI"
1901
1972
  }),
1902
- ", make sure the build job exposes the same env vars the wizard added to your ",
1903
- /* @__PURE__ */ jsx(Text, {
1904
- bold: true,
1905
- children: ".env"
1906
- }),
1907
- "."
1973
+ ", the build job needs the same upload credentials. If the wizard wired your pipeline, add the referenced secrets to your CI provider (e.g. GitHub repo secrets) before your next deploy."
1908
1974
  ] })
1909
1975
  ]
1910
1976
  }),
@@ -1915,7 +1981,7 @@ const SourceMapsOutroScreen = ({ store }) => {
1915
1981
  " ",
1916
1982
  /* @__PURE__ */ jsx(Text, {
1917
1983
  bold: true,
1918
- children: join(store.session.installDir, outroData.reportFile)
1984
+ children: join$1(store.session.installDir, outroData.reportFile)
1919
1985
  })
1920
1986
  ] })
1921
1987
  }),
@@ -2797,7 +2863,7 @@ const PendingChecksList = ({ checks }) => {
2797
2863
  //#region src/ui/tui/screens/audit/AuditRunScreen.tsx
2798
2864
  const AuditRunScreen = ({ store }) => {
2799
2865
  useSyncExternalStore((cb) => store.subscribe(cb), () => store.getSnapshot());
2800
- useFileWatcher(join(store.session.installDir, AUDIT_CHECKS_FILE), (parsed) => store.setFrameworkContext(AUDIT_CHECKS_KEY, coerceAuditChecks(parsed)));
2866
+ useFileWatcher(join$1(store.session.installDir, AUDIT_CHECKS_FILE), (parsed) => store.setFrameworkContext(AUDIT_CHECKS_KEY, coerceAuditChecks(parsed)));
2801
2867
  const statuses = store.statusMessages.length > 0 ? store.statusMessages : void 0;
2802
2868
  const [columns] = useStdoutDimensions();
2803
2869
  const checks = getAuditChecks(store.session);
@@ -2983,7 +3049,7 @@ const AuditOutroScreen = ({ store }) => {
2983
3049
  bold: true,
2984
3050
  children: "Report saved to:"
2985
3051
  }),
2986
- /* @__PURE__ */ jsx(Text, { children: join(store.session.installDir, outroData.reportFile) }),
3052
+ /* @__PURE__ */ jsx(Text, { children: join$1(store.session.installDir, outroData.reportFile) }),
2987
3053
  /* @__PURE__ */ jsx(Text, {
2988
3054
  dimColor: true,
2989
3055
  children: "A markdown file in your project folder. Open it in any editor to read the full audit."
@@ -3747,7 +3813,7 @@ const PlayfieldRow = ({ row, state }) => {
3747
3813
  const AUDIT_3000_REPORT_FILE_FALLBACK = "posthog-audit-3000-report.md";
3748
3814
  const Audit3000RunScreen = ({ store }) => {
3749
3815
  useSyncExternalStore((cb) => store.subscribe(cb), () => store.getSnapshot());
3750
- useFileWatcher(join(store.session.installDir, AUDIT_CHECKS_FILE), (parsed) => store.setFrameworkContext(AUDIT_CHECKS_KEY, coerceAuditChecks(parsed)));
3816
+ useFileWatcher(join$1(store.session.installDir, AUDIT_CHECKS_FILE), (parsed) => store.setFrameworkContext(AUDIT_CHECKS_KEY, coerceAuditChecks(parsed)));
3751
3817
  const statuses = store.statusMessages.length > 0 ? store.statusMessages : void 0;
3752
3818
  const [columns] = useStdoutDimensions();
3753
3819
  const [gameState, setGameState] = useState(() => initialState());
@@ -3967,7 +4033,7 @@ const Audit3000OutroScreen = ({ store }) => {
3967
4033
  color: "cyan",
3968
4034
  children: "High-score reel saved to:"
3969
4035
  }),
3970
- /* @__PURE__ */ jsx(Text, { children: join(store.session.installDir, outroData.reportFile) }),
4036
+ /* @__PURE__ */ jsx(Text, { children: join$1(store.session.installDir, outroData.reportFile) }),
3971
4037
  /* @__PURE__ */ jsx(Text, {
3972
4038
  dimColor: true,
3973
4039
  children: "A markdown file in your project folder — open it in any editor to read the full audit."
@@ -4100,19 +4166,47 @@ const SetupScreen = ({ store }) => {
4100
4166
  /**
4101
4167
  * AuthScreen — Shown while waiting for OAuth authentication.
4102
4168
  *
4103
- * Displays framework detection results, beta/disclosure notices,
4104
- * a waiting spinner, and the login URL when available.
4169
+ * Displays framework detection, a compressed privacy summary, a waiting
4170
+ * spinner, and the login URL when available. [I] opens the full
4171
+ * PrivacyPanel as an overlay. [P] (when loginUrl is set) lets the user
4172
+ * paste the callback URL by hand.
4173
+ *
4105
4174
  * The router resolves past this screen once session.credentials is set.
4106
4175
  */
4107
4176
  const AuthScreen = ({ store }) => {
4108
4177
  useSyncExternalStore((cb) => store.subscribe(cb), () => store.getSnapshot());
4178
+ const [showPrivacy, setShowPrivacy] = useState(false);
4109
4179
  const { session } = store;
4110
- useKeyBindings("auth", Boolean(session.loginUrl) ? [{
4111
- match: ["p", "P"],
4112
- label: "P",
4113
- action: "paste auth code",
4114
- handler: () => store.showManualAuthCode()
4115
- }] : []);
4180
+ const canPasteCode = Boolean(session.loginUrl);
4181
+ const bindings = [];
4182
+ if (!showPrivacy) {
4183
+ if (canPasteCode) bindings.push({
4184
+ match: ["p", "P"],
4185
+ label: "P",
4186
+ action: "paste auth code",
4187
+ handler: () => store.showManualAuthCode()
4188
+ });
4189
+ bindings.push({
4190
+ match: ["i", "I"],
4191
+ label: "I",
4192
+ action: "privacy info",
4193
+ handler: () => setShowPrivacy(true)
4194
+ });
4195
+ }
4196
+ useKeyBindings("auth", bindings);
4197
+ if (showPrivacy) return /* @__PURE__ */ jsx(IntroScreenLayout, {
4198
+ installDir: session.installDir,
4199
+ title: "Wizard privacy & usage",
4200
+ showSubtitle: false,
4201
+ showDetection: false,
4202
+ body: /* @__PURE__ */ jsx(PrivacyPanel, {}),
4203
+ menuOptions: [{
4204
+ label: "Back",
4205
+ value: "back"
4206
+ }],
4207
+ menuAlign: "left",
4208
+ onSelect: () => setShowPrivacy(false)
4209
+ });
4116
4210
  const config = session.frameworkConfig;
4117
4211
  const frameworkLabel = session.detectedFrameworkLabel ?? config?.metadata.name;
4118
4212
  return /* @__PURE__ */ jsxs(Box, {
@@ -4146,6 +4240,37 @@ const AuthScreen = ({ store }) => {
4146
4240
  })
4147
4241
  ]
4148
4242
  }),
4243
+ /* @__PURE__ */ jsxs(Box, {
4244
+ flexDirection: "column",
4245
+ marginBottom: 1,
4246
+ children: [
4247
+ /* @__PURE__ */ jsx(Text, {
4248
+ bold: true,
4249
+ dimColor: true,
4250
+ children: "How does the wizard use your data?"
4251
+ }),
4252
+ /* @__PURE__ */ jsxs(Text, {
4253
+ dimColor: true,
4254
+ children: ["•", " Source files are read by Claude for AI context"]
4255
+ }),
4256
+ /* @__PURE__ */ jsxs(Text, {
4257
+ dimColor: true,
4258
+ children: ["•", " .env* and secrets stay on your machine"]
4259
+ }),
4260
+ /* @__PURE__ */ jsxs(Text, {
4261
+ dimColor: true,
4262
+ children: [
4263
+ "•",
4264
+ " Press ",
4265
+ /* @__PURE__ */ jsx(Text, {
4266
+ color: Colors.accent,
4267
+ children: "[I]"
4268
+ }),
4269
+ " for full privacy & usage info"
4270
+ ]
4271
+ })
4272
+ ]
4273
+ }),
4149
4274
  /* @__PURE__ */ jsx(LoadingBox, { message: "Waiting for authentication..." }),
4150
4275
  session.loginUrl && /* @__PURE__ */ jsxs(Box, {
4151
4276
  marginTop: 1,
@@ -4191,7 +4316,7 @@ const AuthScreen = ({ store }) => {
4191
4316
  */
4192
4317
  const RunScreen = ({ store }) => {
4193
4318
  useSyncExternalStore((cb) => store.subscribe(cb), () => store.getSnapshot());
4194
- useFileWatcher(join(store.session.installDir, EVENT_PLAN_FILE), (parsed) => {
4319
+ useFileWatcher(join$1(store.session.installDir, EVENT_PLAN_FILE), (parsed) => {
4195
4320
  if (!Array.isArray(parsed)) return;
4196
4321
  store.setEventPlan(parsed.map((e) => ({
4197
4322
  name: e.name ?? e.event ?? "",
@@ -4277,7 +4402,7 @@ const KeepSkillsScreen = ({ store }) => {
4277
4402
  useSyncExternalStore((cb) => store.subscribe(cb), () => store.getSnapshot());
4278
4403
  const [phase, setPhase] = useState("loading");
4279
4404
  const [skills, setSkills] = useState([]);
4280
- const skillsDir = join(store.session.installDir, ".claude", "skills");
4405
+ const skillsDir = join$1(store.session.installDir, ".claude", "skills");
4281
4406
  useEffect(() => {
4282
4407
  (async () => {
4283
4408
  try {
@@ -4285,11 +4410,11 @@ const KeepSkillsScreen = ({ store }) => {
4285
4410
  const result = [];
4286
4411
  for (const dir of dirs) {
4287
4412
  try {
4288
- await access(join(skillsDir, dir.name, WIZARD_MARKER));
4413
+ await access(join$1(skillsDir, dir.name, WIZARD_MARKER));
4289
4414
  } catch {
4290
4415
  continue;
4291
4416
  }
4292
- const children = (await readdir(join(skillsDir, dir.name))).filter((c) => c !== WIZARD_MARKER);
4417
+ const children = (await readdir(join$1(skillsDir, dir.name))).filter((c) => c !== WIZARD_MARKER);
4293
4418
  result.push({
4294
4419
  name: dir.name,
4295
4420
  children
@@ -4314,7 +4439,7 @@ const KeepSkillsScreen = ({ store }) => {
4314
4439
  const handleRemove = async () => {
4315
4440
  setPhase("removing");
4316
4441
  for (const skill of skills) try {
4317
- await rm(join(skillsDir, skill.name), {
4442
+ await rm(join$1(skillsDir, skill.name), {
4318
4443
  recursive: true,
4319
4444
  force: true
4320
4445
  });
@@ -4559,6 +4684,53 @@ const AuthErrorScreen = ({ store }) => {
4559
4684
  });
4560
4685
  };
4561
4686
  //#endregion
4687
+ //#region src/ui/tui/screens/SessionTimeoutScreen.tsx
4688
+ /**
4689
+ * SessionTimeoutScreen — shown when the OAuth login window expires before the
4690
+ * user completes authorization.
4691
+ *
4692
+ * Pushed as an overlay so it takes priority over the gated AuthScreen (which
4693
+ * never completes without credentials). Terminal state: any key exits, since
4694
+ * the only way forward is to re-run the wizard for a fresh login window.
4695
+ */
4696
+ const TIMEOUT_MINUTES = Math.round(OAUTH_TIMEOUT_MS / 6e4);
4697
+ const SessionTimeoutScreen = ({ store }) => {
4698
+ useSyncExternalStore((cb) => store.subscribe(cb), () => store.getSnapshot());
4699
+ useInput(() => {
4700
+ process.exit(1);
4701
+ });
4702
+ return /* @__PURE__ */ jsxs(Box, {
4703
+ flexDirection: "column",
4704
+ flexGrow: 1,
4705
+ children: [
4706
+ /* @__PURE__ */ jsxs(Text, {
4707
+ color: "red",
4708
+ bold: true,
4709
+ children: ["✘", " Login timed out"]
4710
+ }),
4711
+ /* @__PURE__ */ jsx(Box, {
4712
+ marginTop: 1,
4713
+ children: /* @__PURE__ */ jsxs(Text, { children: [
4714
+ "The OAuth link timed out after ",
4715
+ TIMEOUT_MINUTES,
4716
+ " minutes."
4717
+ ] })
4718
+ }),
4719
+ /* @__PURE__ */ jsx(Box, {
4720
+ marginTop: 1,
4721
+ children: /* @__PURE__ */ jsx(Text, { children: "Re-run the wizard to get a fresh link and try again." })
4722
+ }),
4723
+ /* @__PURE__ */ jsx(Box, {
4724
+ marginTop: 1,
4725
+ children: /* @__PURE__ */ jsx(Text, {
4726
+ color: Colors.muted,
4727
+ children: "Press any key to exit"
4728
+ })
4729
+ })
4730
+ ]
4731
+ });
4732
+ };
4733
+ //#endregion
4562
4734
  //#region src/ui/tui/screens/WizardAskScreen.tsx
4563
4735
  /**
4564
4736
  * WizardAskScreen — Overlay for the `wizard_ask` MCP tool.
@@ -4763,14 +4935,14 @@ function createMcpSuggestedPromptsServices(_store) {
4763
4935
  };
4764
4936
  },
4765
4937
  checkSlackConnected: async (credentials, signal) => {
4766
- const { fetchSlackConnected } = await import("./api-DuA0_88V.js").then((n) => n.n);
4938
+ const { fetchSlackConnected } = await import("./api-QI1lO_Bz.js").then((n) => n.n);
4767
4939
  return fetchSlackConnected(credentials.accessToken, credentials.projectId, credentials.host, signal);
4768
4940
  },
4769
4941
  runPromptStreaming: (args) => runProductionPromptStreaming(args)
4770
4942
  };
4771
4943
  }
4772
4944
  async function* runProductionPromptStreaming(args) {
4773
- const { runMcpPromptViaSdk } = await import("./mcp-prompt-streaming-DMDwaark.js");
4945
+ const { runMcpPromptViaSdk } = await import("./mcp-prompt-streaming-mYw2LPZZ.js");
4774
4946
  yield* runMcpPromptViaSdk(args);
4775
4947
  }
4776
4948
  //#endregion
@@ -4788,6 +4960,7 @@ function createScreens(store, services) {
4788
4960
  ["port-conflict"]: /* @__PURE__ */ jsx(PortConflictScreen, { store }),
4789
4961
  ["manual-auth-code"]: /* @__PURE__ */ jsx(ManualAuthCodeScreen, { store }),
4790
4962
  ["auth-error"]: /* @__PURE__ */ jsx(AuthErrorScreen, { store }),
4963
+ ["session-timeout"]: /* @__PURE__ */ jsx(SessionTimeoutScreen, { store }),
4791
4964
  ["wizard-ask"]: /* @__PURE__ */ jsx(WizardAskScreen, { store }),
4792
4965
  ["intro"]: /* @__PURE__ */ jsx(PostHogIntegrationIntroScreen, { store }),
4793
4966
  ["revenue-intro"]: /* @__PURE__ */ jsx(RevenueIntroScreen, { store }),
@@ -4806,6 +4979,7 @@ function createScreens(store, services) {
4806
4979
  ["doctor-report"]: /* @__PURE__ */ jsx(DoctorReportScreen, { store }),
4807
4980
  ["setup"]: /* @__PURE__ */ jsx(SetupScreen, { store }),
4808
4981
  ["auth"]: /* @__PURE__ */ jsx(AuthScreen, { store }),
4982
+ ["ai-opt-in"]: /* @__PURE__ */ jsx(AiOptInRequiredScreen, { store }),
4809
4983
  ["run"]: /* @__PURE__ */ jsx(RunScreen, { store }),
4810
4984
  ["mcp"]: /* @__PURE__ */ jsx(McpScreen, {
4811
4985
  store,
@@ -4840,6 +5014,23 @@ const App = ({ store }) => {
4840
5014
  });
4841
5015
  };
4842
5016
  //#endregion
5017
+ //#region src/ui/tui/exit-line.ts
5018
+ const RESET_ATTRS$1 = "\x1B[0m";
5019
+ const GREEN = "\x1B[32m";
5020
+ const BOLD = "\x1B[1m";
5021
+ const DIM = "\x1B[2m";
5022
+ function getExitLine(store) {
5023
+ const outro = store.session.outroData;
5024
+ const label = store.session.programLabel ?? "Wizard";
5025
+ if (outro?.kind === "success") {
5026
+ const message = outro.message ?? `${label} completed successfully.`;
5027
+ const headline = `${GREEN}${BOLD}✔${RESET_ATTRS$1} ${message}${outro.reportFile && !message.includes(outro.reportFile) ? ` Check ./${outro.reportFile} for details.` : ""}`;
5028
+ if (outro.handoffPrompt) return `${headline}\n\n${DIM}Hand this to your coding agent to finish up (triple-click to select):${RESET_ATTRS$1}\n` + outro.handoffPrompt;
5029
+ return headline;
5030
+ }
5031
+ return `${DIM}${label} exited.${RESET_ATTRS$1}`;
5032
+ }
5033
+ //#endregion
4843
5034
  //#region src/ui/tui/start-tui.ts
4844
5035
  /**
4845
5036
  * start-tui.ts — Sets up the Ink TUI renderer and InkUI.
@@ -4854,27 +5045,16 @@ const CURSOR_HOME = "\x1B[H";
4854
5045
  const BG_BLACK = "\x1B[48;2;0;0;0m";
4855
5046
  const ENTER_ALT_SCREEN = "\x1B[?1049h";
4856
5047
  const LEAVE_ALT_SCREEN = "\x1B[?1049l";
4857
- const GREEN = "\x1B[32m";
4858
- const BOLD = "\x1B[1m";
4859
- const DIM = "\x1B[2m";
4860
5048
  function releaseTerminal() {
4861
5049
  process.stdout.write(RESET_ATTRS + LEAVE_ALT_SCREEN);
4862
5050
  }
4863
- function getExitLine(store) {
4864
- const outro = store.session.outroData;
4865
- const label = store.session.programLabel ?? "Wizard";
4866
- if (outro?.kind === "success") {
4867
- const message = outro.message ?? `${label} completed successfully.`;
4868
- return `${GREEN}${BOLD}\u2714${RESET_ATTRS} ${message}${outro.reportFile && !message.includes(outro.reportFile) ? ` Check ./${outro.reportFile} for details.` : ""}`;
4869
- }
4870
- return `${DIM}${label} exited.${RESET_ATTRS}`;
4871
- }
4872
5051
  function startTUI(version, program = Program.PostHogIntegration) {
4873
5052
  process.stdout.write(ENTER_ALT_SCREEN + BG_BLACK + CLEAR_SCREEN + CURSOR_HOME);
4874
5053
  const store = new WizardStore(program);
4875
5054
  store.version = version;
4876
5055
  setUI(new InkUI(store));
4877
5056
  const { unmount: inkUnmount, waitUntilExit } = render(createElement(App, { store }));
5057
+ analytics.wizardCapture("started", { program_id: program });
4878
5058
  store.runInitHooks();
4879
5059
  process.stdin.on("error", (err) => {
4880
5060
  if (err.code !== "EIO") throw err;
@@ -4902,4 +5082,4 @@ function startTUI(version, program = Program.PostHogIntegration) {
4902
5082
  //#endregion
4903
5083
  export { startTUI };
4904
5084
 
4905
- //# sourceMappingURL=start-tui-BRvm5VP9.js.map
5085
+ //# sourceMappingURL=start-tui-DaQiY_EB.js.map