@posthog/wizard 2.22.1 → 2.24.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 (56) hide show
  1. package/README.md +61 -2
  2. package/dist/{AiOptInRequiredScreen-B8mgZbe5.js → AiOptInRequiredScreen-DPn1CCeD.js} +12 -577
  3. package/dist/AiOptInRequiredScreen-DPn1CCeD.js.map +1 -0
  4. package/dist/{add-mcp-server-to-clients-lCxOS1A1.js → add-mcp-server-to-clients-BU8Owthq.js} +4 -4
  5. package/dist/{add-mcp-server-to-clients-lCxOS1A1.js.map → add-mcp-server-to-clients-BU8Owthq.js.map} +1 -1
  6. package/dist/{agent-interface-BPCzPvK-.js → agent-interface-CysYcZl5.js} +6 -7
  7. package/dist/agent-interface-CysYcZl5.js.map +1 -0
  8. package/dist/{agent-runner-DgzF2mga.js → agent-runner-Br0OxBxd.js} +8 -8
  9. package/dist/{agent-runner-DgzF2mga.js.map → agent-runner-Br0OxBxd.js.map} +1 -1
  10. package/dist/{analytics-BZv-cKyn.js → analytics-BOWrR4qd.js} +22 -2
  11. package/dist/analytics-BOWrR4qd.js.map +1 -0
  12. package/dist/{api-BkLZ8BWm.js → api-RXTR8yZo.js} +3 -3
  13. package/dist/{api-BkLZ8BWm.js.map → api-RXTR8yZo.js.map} +1 -1
  14. package/dist/bin.js +875 -423
  15. package/dist/bin.js.map +1 -1
  16. package/dist/{ci-install-DBARq5LX.js → ci-install-BscZ60Ec.js} +5 -5
  17. package/dist/{ci-install-DBARq5LX.js.map → ci-install-BscZ60Ec.js.map} +1 -1
  18. package/dist/{debug-Ckumcrye.js → debug-BUdVZP84.js} +2 -2
  19. package/dist/{debug-Ckumcrye.js.map → debug-BUdVZP84.js.map} +1 -1
  20. package/dist/{debug-DLsuyfln.js → debug-BgH07S-e.js} +1 -1
  21. package/dist/{environment-DUh_8hqW.js → environment-G0Hv6_JI.js} +3 -3
  22. package/dist/{environment-DUh_8hqW.js.map → environment-G0Hv6_JI.js.map} +1 -1
  23. package/dist/{interactive-DeiHgviS.js → interactive-fh2iyewb.js} +3 -3
  24. package/dist/{interactive-DeiHgviS.js.map → interactive-fh2iyewb.js.map} +1 -1
  25. package/dist/{mcp-prompt-streaming-kEJgmB30.js → mcp-prompt-streaming-DUtbxnNy.js} +4 -4
  26. package/dist/{mcp-prompt-streaming-kEJgmB30.js.map → mcp-prompt-streaming-DUtbxnNy.js.map} +1 -1
  27. package/dist/{non-interactive-I4ifOSau.js → non-interactive-BfqXlY8R.js} +2 -2
  28. package/dist/{non-interactive-I4ifOSau.js.map → non-interactive-BfqXlY8R.js.map} +1 -1
  29. package/dist/{package-manager-fUeLORHg.js → package-manager-Ca1maxU-.js} +2 -2
  30. package/dist/{package-manager-fUeLORHg.js.map → package-manager-Ca1maxU-.js.map} +1 -1
  31. package/dist/{playground-DLLIz4Ql.js → playground-4sqLVVJL.js} +5 -10
  32. package/dist/{playground-DLLIz4Ql.js.map → playground-4sqLVVJL.js.map} +1 -1
  33. package/dist/{posthog-integration-COcPewVt.js → posthog-integration-Bz3HWkHn.js} +11 -11
  34. package/dist/{posthog-integration-COcPewVt.js.map → posthog-integration-Bz3HWkHn.js.map} +1 -1
  35. package/dist/{provisioning-7xU12_S9.js → provisioning-CgwvlsIl.js} +3 -3
  36. package/dist/{provisioning-7xU12_S9.js.map → provisioning-CgwvlsIl.js.map} +1 -1
  37. package/dist/{registry-YwaF-aD8.js → registry-CEnQVctL.js} +4 -4
  38. package/dist/{registry-YwaF-aD8.js.map → registry-CEnQVctL.js.map} +1 -1
  39. package/dist/{setup-utils-Cr4FxJDl.js → setup-utils-Doh69vo4.js} +8 -8
  40. package/dist/{setup-utils-Cr4FxJDl.js.map → setup-utils-Doh69vo4.js.map} +1 -1
  41. package/dist/{start-tui--E4PXdwG.js → start-tui-CywbSvZE.js} +54 -1030
  42. package/dist/start-tui-CywbSvZE.js.map +1 -0
  43. package/dist/{steps-CxUxdK4V.js → steps-DJojDYQ-.js} +6 -6
  44. package/dist/{steps-CxUxdK4V.js.map → steps-DJojDYQ-.js.map} +1 -1
  45. package/dist/{telemetry-BS7yw3TP.js → telemetry-8zMpaIuK.js} +3 -3
  46. package/dist/{telemetry-BS7yw3TP.js.map → telemetry-8zMpaIuK.js.map} +1 -1
  47. package/dist/{urls-BW23_XbC.js → urls-BUfvQmU4.js} +2 -2
  48. package/dist/{urls-BW23_XbC.js.map → urls-BUfvQmU4.js.map} +1 -1
  49. package/dist/{wizard-abort-E66_R4S7.js → wizard-abort-BdGW4Tvi.js} +3 -3
  50. package/dist/{wizard-abort-E66_R4S7.js.map → wizard-abort-BdGW4Tvi.js.map} +1 -1
  51. package/dist/{wizard-abort-BPsnXKY5.js → wizard-abort-Ni-mKJ58.js} +1 -1
  52. package/package.json +2 -2
  53. package/dist/AiOptInRequiredScreen-B8mgZbe5.js.map +0 -1
  54. package/dist/agent-interface-BPCzPvK-.js.map +0 -1
  55. package/dist/analytics-BZv-cKyn.js.map +0 -1
  56. package/dist/start-tui--E4PXdwG.js.map +0 -1
@@ -1,16 +1,16 @@
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-Ckumcrye.js";
2
- import { t as analytics } from "./analytics-BZv-cKyn.js";
3
- import { o as extractOAuthCode, t as getOrAskForProjectData } from "./setup-utils-Cr4FxJDl.js";
4
- import { a as getUiHostFromHost } from "./urls-BW23_XbC.js";
5
- import { t as ApiError } from "./api-BkLZ8BWm.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-BUdVZP84.js";
2
+ import { t as analytics } from "./analytics-BOWrR4qd.js";
3
+ import { o as extractOAuthCode, t as getOrAskForProjectData } from "./setup-utils-Doh69vo4.js";
4
+ import { a as getUiHostFromHost } from "./urls-BUfvQmU4.js";
5
+ import { t as ApiError } from "./api-RXTR8yZo.js";
6
6
  import { t as ADDITIONAL_FEATURE_LABELS } from "./wizard-session-G3VWD6hv.js";
7
- import { i as wizardAbort } from "./wizard-abort-E66_R4S7.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-BPCzPvK-.js";
9
- import { f as Colors, p as Icons, t as EVENT_PLAN_FILE } from "./posthog-integration-COcPewVt.js";
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 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-B8mgZbe5.js";
7
+ import { i as wizardAbort } from "./wizard-abort-BdGW4Tvi.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-CysYcZl5.js";
9
+ import { f as Colors, p as Icons, t as EVENT_PLAN_FILE } from "./posthog-integration-Bz3HWkHn.js";
10
+ import { _ as POSTHOG_SDKS, d as DISPLAY_NAME, f as SOURCE_MAPS_CONTEXT_KEYS, g as getContentBlocks, h as fetchHealthIssues, l as Program, n as useKeyBindings, t as PickerMenu, u as getProgramConfig, v as STRIPE_SDKS } from "./bin.js";
11
+ import { A as SplitView, C as LogViewer, D as useStdoutDimensions, M as WizardStore, O as ProgressList, S as EventPlanViewer, T as ConfirmationInput, _ as LearnCard, a as SlackConnectScreen, b as TabContainer, c as AuditChecksViewer, d as McpScreen, f as IssueTable, g as TipsCard, h as ServiceHealthList, i as OutroScreen, k as LoadingBox, l as McpSuggestedPromptsScreen, m as SEVERITY_ORDER, n as SkillSourceInfo, o as AUDIT_AREA_SLIDES, p as SEVERITY_LABEL, r as useSkillEntry, s as VisualBox, t as AiOptInRequiredScreen, w as ModalOverlay, x as ScreenContainer, y as HNViewer } from "./AiOptInRequiredScreen-DPn1CCeD.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-lCxOS1A1.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-BU8Owthq.js";
14
14
  import * as fs$1 from "fs";
15
15
  import path from "path";
16
16
  import { join as join$1 } from "node:path";
@@ -554,6 +554,10 @@ const SettingsOverrideScreen = ({ store }) => {
554
554
  useSyncExternalStore((cb) => store.subscribe(cb), () => store.getSnapshot());
555
555
  const [feedback, setFeedback] = useState(null);
556
556
  const conflicts = store.session.settingsConflicts?.filter((c) => c.writable);
557
+ const hasConflicts = Boolean(conflicts && conflicts.length > 0);
558
+ useEffect(() => {
559
+ if (hasConflicts) analytics.wizardCapture("settings conflict shown", { kind: "override" });
560
+ }, [hasConflicts]);
557
561
  if (!conflicts || conflicts.length === 0) return null;
558
562
  return /* @__PURE__ */ jsxs(ModalOverlay, {
559
563
  borderColor: "red",
@@ -565,6 +569,7 @@ const SettingsOverrideScreen = ({ store }) => {
565
569
  confirmLabel: "Backup & continue [Enter]",
566
570
  cancelLabel: "Exit [Esc]",
567
571
  onConfirm: () => {
572
+ analytics.wizardCapture("settings conflict accepted", { kind: "override" });
568
573
  if (!store.backupAndFixSettingsOverride()) setFeedback("Could not back up the settings file.");
569
574
  },
570
575
  onCancel: () => process.exit(1)
@@ -621,8 +626,15 @@ function sourceLabel(source) {
621
626
  const ManagedSettingsScreen = ({ store }) => {
622
627
  useSyncExternalStore((cb) => store.subscribe(cb), () => store.getSnapshot());
623
628
  const readOnlyConflicts = store.session.settingsConflicts?.filter((c) => !c.writable);
629
+ const hasManaged = Boolean(readOnlyConflicts?.some((c) => c.source === "managed"));
630
+ const hasReadOnly = Boolean(readOnlyConflicts && readOnlyConflicts.length > 0);
631
+ useEffect(() => {
632
+ if (hasReadOnly) analytics.wizardCapture("settings conflict shown", {
633
+ kind: "managed",
634
+ has_managed: hasManaged
635
+ });
636
+ }, [hasReadOnly, hasManaged]);
624
637
  if (!readOnlyConflicts || readOnlyConflicts.length === 0) return null;
625
- const hasManaged = readOnlyConflicts.some((c) => c.source === "managed");
626
638
  return /* @__PURE__ */ jsxs(ModalOverlay, {
627
639
  borderColor: "red",
628
640
  title: `${Icons.warning} Settings conflict`,
@@ -978,6 +990,9 @@ const IntroScreenLayout = ({ installDir, title = "PostHog Wizard 🦔", showSubt
978
990
  * their browser.
979
991
  */
980
992
  const PrivacyPanel = () => {
993
+ useEffect(() => {
994
+ analytics.wizardCapture("privacy panel shown");
995
+ }, []);
981
996
  return /* @__PURE__ */ jsxs(Box, {
982
997
  flexDirection: "column",
983
998
  width: 64,
@@ -1045,7 +1060,7 @@ const FrameworkPicker = ({ store, onComplete }) => {
1045
1060
  })),
1046
1061
  onSelect: (value) => {
1047
1062
  const integration = Array.isArray(value) ? value[0] : value;
1048
- import("./registry-YwaF-aD8.js").then((n) => n.n).then(({ FRAMEWORK_REGISTRY }) => {
1063
+ import("./registry-CEnQVctL.js").then((n) => n.n).then(({ FRAMEWORK_REGISTRY }) => {
1049
1064
  const config = FRAMEWORK_REGISTRY[integration];
1050
1065
  store.setFrameworkConfig(integration, config);
1051
1066
  store.setDetectedFramework(config.metadata.name);
@@ -1249,6 +1264,10 @@ const PostHogIntegrationIntroScreen = ({ store }) => {
1249
1264
  }
1250
1265
  ];
1251
1266
  const handleSelect = (value) => {
1267
+ analytics.wizardCapture("intro menu selected", {
1268
+ value,
1269
+ view
1270
+ });
1252
1271
  if (view === "tools") {
1253
1272
  if (value === "back") setView("default");
1254
1273
  else launchTool(value, session.installDir);
@@ -2309,18 +2328,18 @@ function useFileWatcher(path, onUpdate, options = {}) {
2309
2328
  *
2310
2329
  * Pressing `O` opens the active slide's docs URL.
2311
2330
  */
2312
- const FINDING_STATUSES$1 = [
2331
+ const FINDING_STATUSES = [
2313
2332
  "error",
2314
2333
  "warning",
2315
2334
  "suggestion"
2316
2335
  ];
2317
- const isFinding$1 = (c) => FINDING_STATUSES$1.includes(c.status);
2318
- const fallbackSlide$1 = (area) => ({
2336
+ const isFinding = (c) => FINDING_STATUSES.includes(c.status);
2337
+ const fallbackSlide = (area) => ({
2319
2338
  area,
2320
2339
  intro: [`Verifying ${area.toLowerCase()}…`],
2321
2340
  docsUrl: ""
2322
2341
  });
2323
- const openLink$1 = (url) => {
2342
+ const openLink = (url) => {
2324
2343
  spawn(process.platform === "darwin" ? "open" : process.platform === "win32" ? "cmd" : "xdg-open", process.platform === "win32" ? [
2325
2344
  "/c",
2326
2345
  "start",
@@ -2333,9 +2352,9 @@ const openLink$1 = (url) => {
2333
2352
  };
2334
2353
  const AuditAreaPane = ({ checks, reportPath, slides = AUDIT_AREA_SLIDES, dashboardUrl, notebookUrl }) => {
2335
2354
  const activeArea = checks.filter((c) => c.status === "pending")[0]?.area;
2336
- const slide = activeArea ? slides.find((s) => s.area === activeArea) ?? fallbackSlide$1(activeArea) : null;
2355
+ const slide = activeArea ? slides.find((s) => s.area === activeArea) ?? fallbackSlide(activeArea) : null;
2337
2356
  useInput((input) => {
2338
- if (input.toLowerCase() === "o" && slide?.docsUrl) openLink$1(slide.docsUrl);
2357
+ if (input.toLowerCase() === "o" && slide?.docsUrl) openLink(slide.docsUrl);
2339
2358
  });
2340
2359
  const urlsFooter = dashboardUrl || notebookUrl ? /* @__PURE__ */ jsx(UrlsFooter, {
2341
2360
  dashboardUrl,
@@ -2343,18 +2362,18 @@ const AuditAreaPane = ({ checks, reportPath, slides = AUDIT_AREA_SLIDES, dashboa
2343
2362
  }) : null;
2344
2363
  if (slide) return /* @__PURE__ */ jsxs(Box, {
2345
2364
  flexDirection: "column",
2346
- children: [/* @__PURE__ */ jsx(ActiveSlide$1, {
2365
+ children: [/* @__PURE__ */ jsx(ActiveSlide, {
2347
2366
  slide,
2348
- hasFindings: checks.some(isFinding$1)
2367
+ hasFindings: checks.some(isFinding)
2349
2368
  }), urlsFooter]
2350
2369
  });
2351
2370
  if (checks.length === 0) return null;
2352
2371
  return /* @__PURE__ */ jsxs(Box, {
2353
2372
  flexDirection: "column",
2354
- children: [/* @__PURE__ */ jsx(WritingReport$1, { reportPath }), urlsFooter]
2373
+ children: [/* @__PURE__ */ jsx(WritingReport, { reportPath }), urlsFooter]
2355
2374
  });
2356
2375
  };
2357
- const ActiveSlide$1 = ({ slide, hasFindings }) => /* @__PURE__ */ jsxs(Box, {
2376
+ const ActiveSlide = ({ slide, hasFindings }) => /* @__PURE__ */ jsxs(Box, {
2358
2377
  flexDirection: "column",
2359
2378
  paddingX: 1,
2360
2379
  children: [
@@ -2409,7 +2428,7 @@ const UrlsFooter = ({ dashboardUrl, notebookUrl }) => /* @__PURE__ */ jsxs(Box,
2409
2428
  })] })
2410
2429
  ]
2411
2430
  });
2412
- const WritingReport$1 = ({ reportPath }) => /* @__PURE__ */ jsxs(Box, {
2431
+ const WritingReport = ({ reportPath }) => /* @__PURE__ */ jsxs(Box, {
2413
2432
  flexDirection: "column",
2414
2433
  paddingX: 1,
2415
2434
  children: [
@@ -2759,7 +2778,7 @@ const EVENTS_AUDIT_AREA_SLIDES = [
2759
2778
  ];
2760
2779
  //#endregion
2761
2780
  //#region src/ui/tui/screens/audit/PendingChecksList.tsx
2762
- function groupByArea$1(checks) {
2781
+ function groupByArea(checks) {
2763
2782
  const order = [];
2764
2783
  const map = /* @__PURE__ */ new Map();
2765
2784
  for (const c of checks) {
@@ -2774,7 +2793,7 @@ function groupByArea$1(checks) {
2774
2793
  checks: map.get(area)
2775
2794
  }));
2776
2795
  }
2777
- function groupIcon$1(group) {
2796
+ function groupIcon(group) {
2778
2797
  const total = group.checks.length;
2779
2798
  const complete = group.checks.filter((c) => c.status !== "pending").length;
2780
2799
  if (complete === 0) return {
@@ -2790,10 +2809,10 @@ function groupIcon$1(group) {
2790
2809
  color: Colors.primary
2791
2810
  };
2792
2811
  }
2793
- const GroupHeader$1 = ({ group, showIcon, isActive }) => {
2812
+ const GroupHeader = ({ group, showIcon, isActive }) => {
2794
2813
  const complete = group.checks.filter((c) => c.status !== "pending").length;
2795
2814
  const total = group.checks.length;
2796
- const { icon, color } = groupIcon$1(group);
2815
+ const { icon, color } = groupIcon(group);
2797
2816
  return /* @__PURE__ */ jsxs(Box, { children: [isActive ? /* @__PURE__ */ jsx(Box, {
2798
2817
  marginRight: 1,
2799
2818
  children: /* @__PURE__ */ jsx(Spinner, {})
@@ -2842,7 +2861,7 @@ const PendingChecksList = ({ checks }) => {
2842
2861
  /* @__PURE__ */ jsx(LoadingBox, { message: "Seeding audit checklist..." })
2843
2862
  ]
2844
2863
  });
2845
- const groups = groupByArea$1(checks);
2864
+ const groups = groupByArea(checks);
2846
2865
  const activeIndex = groups.findIndex((g) => g.checks.some((c) => c.status === "pending"));
2847
2866
  return /* @__PURE__ */ jsxs(Box, {
2848
2867
  flexDirection: "column",
@@ -2852,14 +2871,14 @@ const PendingChecksList = ({ checks }) => {
2852
2871
  children: "Checks"
2853
2872
  }),
2854
2873
  /* @__PURE__ */ jsx(Text, { children: " " }),
2855
- termRows < COLLAPSE_BELOW_ROWS ? groups.map((group, i) => /* @__PURE__ */ jsx(GroupHeader$1, {
2874
+ termRows < COLLAPSE_BELOW_ROWS ? groups.map((group, i) => /* @__PURE__ */ jsx(GroupHeader, {
2856
2875
  group,
2857
2876
  showIcon: true,
2858
2877
  isActive: i === activeIndex
2859
2878
  }, group.area)) : groups.map((group, i) => /* @__PURE__ */ jsxs(Box, {
2860
2879
  flexDirection: "column",
2861
2880
  marginTop: i === 0 ? 0 : 1,
2862
- children: [/* @__PURE__ */ jsx(GroupHeader$1, {
2881
+ children: [/* @__PURE__ */ jsx(GroupHeader, {
2863
2882
  group,
2864
2883
  showIcon: false,
2865
2884
  isActive: i === activeIndex
@@ -2881,7 +2900,7 @@ const AuditRunScreen = ({ store }) => {
2881
2900
  const areaPane = /* @__PURE__ */ jsx(AuditAreaPane, {
2882
2901
  checks,
2883
2902
  reportPath,
2884
- slides: store.session.skillId === "events-audit" ? EVENTS_AUDIT_AREA_SLIDES : AUDIT_AREA_SLIDES,
2903
+ slides: store.session.skillId === "audit-events" ? EVENTS_AUDIT_AREA_SLIDES : AUDIT_AREA_SLIDES,
2885
2904
  dashboardUrl: store.session.dashboardUrl,
2886
2905
  notebookUrl: store.session.notebookUrl
2887
2906
  });
@@ -3107,998 +3126,6 @@ const AuditOutroScreen = ({ store }) => {
3107
3126
  });
3108
3127
  };
3109
3128
  //#endregion
3110
- //#region src/ui/tui/screens/audit-3000/arcade-colors.ts
3111
- const NEON_PINK$2 = "#F54E00";
3112
- const NEON_BLUE$2 = "#1D4AFF";
3113
- const NEON_GOLD$2 = "#F9BD2B";
3114
- //#endregion
3115
- //#region src/ui/tui/screens/audit-3000/Audit3000IntroScreen.tsx
3116
- const AUDIT3000_SKILL_ID = "audit-3000";
3117
- const ArcadeBanner = () => {
3118
- const [blinkOn, setBlinkOn] = useState(true);
3119
- useEffect(() => {
3120
- const id = setInterval(() => setBlinkOn((v) => !v), 600);
3121
- return () => clearInterval(id);
3122
- }, []);
3123
- const top = "┏" + "━".repeat(32) + "┓";
3124
- const bottom = "┗" + "━".repeat(32) + "┛";
3125
- return /* @__PURE__ */ jsxs(Box, {
3126
- flexDirection: "column",
3127
- alignItems: "center",
3128
- children: [
3129
- /* @__PURE__ */ jsx(Text, {
3130
- bold: true,
3131
- color: NEON_PINK$2,
3132
- children: top
3133
- }),
3134
- /* @__PURE__ */ jsxs(Text, { children: [
3135
- /* @__PURE__ */ jsx(Text, {
3136
- bold: true,
3137
- color: NEON_PINK$2,
3138
- children: "┃"
3139
- }),
3140
- /* @__PURE__ */ jsx(Text, {
3141
- bold: true,
3142
- color: NEON_GOLD$2,
3143
- children: " A U D I T "
3144
- }),
3145
- /* @__PURE__ */ jsx(Text, {
3146
- bold: true,
3147
- color: NEON_BLUE$2,
3148
- children: "-"
3149
- }),
3150
- /* @__PURE__ */ jsx(Text, {
3151
- bold: true,
3152
- color: NEON_GOLD$2,
3153
- children: " 3 0 0 0 "
3154
- }),
3155
- /* @__PURE__ */ jsx(Text, {
3156
- bold: true,
3157
- color: NEON_PINK$2,
3158
- children: "┃"
3159
- })
3160
- ] }),
3161
- /* @__PURE__ */ jsxs(Text, { children: [
3162
- /* @__PURE__ */ jsx(Text, {
3163
- bold: true,
3164
- color: NEON_PINK$2,
3165
- children: "┃"
3166
- }),
3167
- /* @__PURE__ */ jsx(Text, {
3168
- dimColor: !blinkOn,
3169
- color: NEON_BLUE$2,
3170
- children: " ▶ INSERT COIN TO PLAY ◀ "
3171
- }),
3172
- /* @__PURE__ */ jsx(Text, {
3173
- bold: true,
3174
- color: NEON_PINK$2,
3175
- children: "┃"
3176
- })
3177
- ] }),
3178
- /* @__PURE__ */ jsx(Text, {
3179
- bold: true,
3180
- color: NEON_PINK$2,
3181
- children: bottom
3182
- })
3183
- ]
3184
- });
3185
- };
3186
- const Audit3000IntroScreen = ({ store }) => {
3187
- useSyncExternalStore((cb) => store.subscribe(cb), () => store.getSnapshot());
3188
- const [showingMoreInfo, setShowingMoreInfo] = useState(false);
3189
- const { session } = store;
3190
- const { skillEntry, fetchFailed } = useSkillEntry(AUDIT3000_SKILL_ID, session.localMcp);
3191
- const body = showingMoreInfo ? /* @__PURE__ */ jsxs(Box, {
3192
- flexDirection: "column",
3193
- width: 56,
3194
- children: [
3195
- /* @__PURE__ */ jsx(Box, {
3196
- marginBottom: 1,
3197
- children: /* @__PURE__ */ jsxs(Text, { children: ["The wizard is an agent that executes PostHog tasks. Its code is open source: ", /* @__PURE__ */ jsx(Text, {
3198
- color: "cyan",
3199
- children: "https://github.com/PostHog/wizard"
3200
- })] })
3201
- }),
3202
- /* @__PURE__ */ jsxs(Text, { children: [
3203
- "The",
3204
- " ",
3205
- /* @__PURE__ */ jsx(Text, {
3206
- color: "cyan",
3207
- italic: true,
3208
- children: AUDIT3000_SKILL_ID
3209
- }),
3210
- " ",
3211
- "program reviews your PostHog integration across 34 checks — SDK install, identification, event capture, event quality, stale feature flag hygiene, session replay (fix + optimize), and use-case expansion across 8 PostHog products. When enrichment is available it also produces a company profile and use-case match. Nothing in your project is modified."
3212
- ] }),
3213
- /* @__PURE__ */ jsx(Box, {
3214
- marginTop: 1,
3215
- children: /* @__PURE__ */ jsxs(Text, { children: [
3216
- "Results stream live to the",
3217
- " ",
3218
- /* @__PURE__ */ jsx(Text, {
3219
- color: "cyan",
3220
- bold: true,
3221
- children: "Hi-score Table"
3222
- }),
3223
- " ",
3224
- "tab during the run — that's your live report. When the audit finishes, the same report is also exported to",
3225
- " ",
3226
- /* @__PURE__ */ jsx(Text, {
3227
- color: "cyan",
3228
- children: "./posthog-audit-3000-report.md"
3229
- }),
3230
- " in your project folder."
3231
- ] })
3232
- }),
3233
- /* @__PURE__ */ jsx(Box, {
3234
- marginTop: 1,
3235
- children: /* @__PURE__ */ jsx(SkillSourceInfo, {
3236
- skillId: AUDIT3000_SKILL_ID,
3237
- skillEntry,
3238
- fetchFailed
3239
- })
3240
- })
3241
- ]
3242
- }) : /* @__PURE__ */ jsxs(Box, {
3243
- flexDirection: "column",
3244
- alignItems: "center",
3245
- children: [/* @__PURE__ */ jsx(ArcadeBanner, {}), /* @__PURE__ */ jsxs(Box, {
3246
- marginTop: 1,
3247
- flexDirection: "column",
3248
- alignItems: "center",
3249
- children: [
3250
- /* @__PURE__ */ jsx(Text, {
3251
- bold: true,
3252
- children: "34 checks. 9 levels. 1 final report."
3253
- }),
3254
- /* @__PURE__ */ jsx(Text, {
3255
- dimColor: true,
3256
- children: "High-score your PostHog integration before the boss fight."
3257
- }),
3258
- /* @__PURE__ */ jsx(Box, {
3259
- marginTop: 1,
3260
- children: /* @__PURE__ */ jsxs(Text, {
3261
- dimColor: true,
3262
- children: [
3263
- "Live report: ",
3264
- /* @__PURE__ */ jsx(Text, {
3265
- color: NEON_GOLD$2,
3266
- children: "Hi-score Table"
3267
- }),
3268
- " tab · Export: ./posthog-audit-3000-report.md"
3269
- ]
3270
- })
3271
- })
3272
- ]
3273
- })]
3274
- });
3275
- const menuOptions = showingMoreInfo ? [{
3276
- label: "Back",
3277
- value: "back"
3278
- }] : [
3279
- {
3280
- label: "PRESS START",
3281
- value: "continue"
3282
- },
3283
- {
3284
- label: "More info",
3285
- value: "more-info"
3286
- },
3287
- {
3288
- label: "Cancel",
3289
- value: "cancel"
3290
- }
3291
- ];
3292
- const handleSelect = (value) => {
3293
- if (value === "cancel") process.exit(0);
3294
- else if (value === "more-info") setShowingMoreInfo(true);
3295
- else if (value === "back") setShowingMoreInfo(false);
3296
- else store.completeSetup();
3297
- };
3298
- return /* @__PURE__ */ jsx(IntroScreenLayout, {
3299
- installDir: session.installDir,
3300
- body,
3301
- showDetection: !showingMoreInfo,
3302
- programLabel: session.programLabel,
3303
- skillId: session.skillId,
3304
- menuOptions,
3305
- onSelect: handleSelect
3306
- });
3307
- };
3308
- //#endregion
3309
- //#region src/ui/tui/screens/audit-3000/Audit3000AreaPane.tsx
3310
- /**
3311
- * Audit-3000 right pane — arcade-flavoured fork of `AuditAreaPane`.
3312
- *
3313
- * Mirrors the audit pane's three-state logic (active slide → empty →
3314
- * wrap-up) but routes through the audit-3000 slide registry and uses
3315
- * "LEVEL N: <area>" framing instead of "Verifying ...".
3316
- */
3317
- const FINDING_STATUSES = [
3318
- "error",
3319
- "warning",
3320
- "suggestion"
3321
- ];
3322
- const isFinding = (c) => FINDING_STATUSES.includes(c.status);
3323
- const fallbackSlide = (area) => ({
3324
- area,
3325
- intro: [`Now playing: ${area.toLowerCase()}\u2026`],
3326
- docsUrl: ""
3327
- });
3328
- const openLink = (url) => {
3329
- spawn(process.platform === "darwin" ? "open" : process.platform === "win32" ? "cmd" : "xdg-open", process.platform === "win32" ? [
3330
- "/c",
3331
- "start",
3332
- "",
3333
- url
3334
- ] : [url], {
3335
- detached: true,
3336
- stdio: "ignore"
3337
- }).unref();
3338
- };
3339
- const Audit3000AreaPane = ({ checks, reportPath }) => {
3340
- const activeArea = checks.filter((c) => c.status === "pending")[0]?.area;
3341
- const slide = activeArea ? AUDIT_3000_AREA_SLIDES.find((s) => s.area === activeArea) ?? fallbackSlide(activeArea) : null;
3342
- const levelIndex = activeArea ? AUDIT_3000_AREA_SLIDES.findIndex((s) => s.area === activeArea) : -1;
3343
- const level = levelIndex >= 0 ? levelIndex + 1 : null;
3344
- useInput((input) => {
3345
- if (input.toLowerCase() === "o" && slide?.docsUrl) openLink(slide.docsUrl);
3346
- });
3347
- if (slide) return /* @__PURE__ */ jsx(ActiveSlide, {
3348
- slide,
3349
- level,
3350
- hasFindings: checks.some(isFinding)
3351
- });
3352
- if (checks.length === 0) return null;
3353
- return /* @__PURE__ */ jsx(WritingReport, { reportPath });
3354
- };
3355
- const ActiveSlide = ({ slide, level, hasFindings }) => /* @__PURE__ */ jsxs(Box, {
3356
- flexDirection: "column",
3357
- paddingX: 1,
3358
- children: [
3359
- /* @__PURE__ */ jsxs(Text, {
3360
- bold: true,
3361
- color: Colors.accent,
3362
- children: [level ? `LEVEL ${level}: ` : "", slide.area.toUpperCase()]
3363
- }),
3364
- /* @__PURE__ */ jsx(Box, { height: 1 }),
3365
- slide.visual,
3366
- slide.intro.map((paragraph, i) => /* @__PURE__ */ jsxs(Fragment, { children: [i > 0 && /* @__PURE__ */ jsx(Box, { height: 1 }), /* @__PURE__ */ jsx(Text, { children: paragraph })] }, i)),
3367
- /* @__PURE__ */ jsx(Box, {
3368
- marginTop: 1,
3369
- children: /* @__PURE__ */ jsxs(Text, {
3370
- dimColor: true,
3371
- children: [slide.docsUrl && /* @__PURE__ */ jsxs(Fragment$1, { children: [
3372
- "[",
3373
- /* @__PURE__ */ jsx(Text, {
3374
- color: Colors.accent,
3375
- children: "O"
3376
- }),
3377
- "] Learn more"
3378
- ] }), hasFindings && /* @__PURE__ */ jsxs(Fragment$1, { children: [
3379
- slide.docsUrl && " ",
3380
- "[",
3381
- /* @__PURE__ */ jsx(Text, {
3382
- color: Colors.accent,
3383
- children: "→"
3384
- }),
3385
- "] View issues"
3386
- ] })]
3387
- })
3388
- })
3389
- ]
3390
- });
3391
- const WritingReport = ({ reportPath }) => /* @__PURE__ */ jsxs(Box, {
3392
- flexDirection: "column",
3393
- paddingX: 1,
3394
- children: [
3395
- /* @__PURE__ */ jsx(Text, {
3396
- bold: true,
3397
- color: Colors.accent,
3398
- children: "STAGE CLEAR."
3399
- }),
3400
- /* @__PURE__ */ jsx(Box, { height: 1 }),
3401
- /* @__PURE__ */ jsxs(Text, { children: [
3402
- "All checks resolved. Compiling your high-score reel at",
3403
- " ",
3404
- /* @__PURE__ */ jsx(Text, {
3405
- color: "cyan",
3406
- children: reportPath
3407
- }),
3408
- "."
3409
- ] }),
3410
- /* @__PURE__ */ jsx(Box, { height: 1 }),
3411
- /* @__PURE__ */ jsx(Text, { children: "The report covers everything we checked, what we found, and what to do next." }),
3412
- /* @__PURE__ */ jsx(Box, { height: 1 }),
3413
- /* @__PURE__ */ jsx(Text, {
3414
- dimColor: true,
3415
- children: "Stand by…"
3416
- })
3417
- ]
3418
- });
3419
- //#endregion
3420
- //#region src/ui/tui/screens/audit-3000/Audit3000ChecksPanel.tsx
3421
- /**
3422
- * Audit-3000 left pane on the Run screen. Arcade-flavoured fork of the
3423
- * audit program's `PendingChecksList`: a running score banner sits on
3424
- * top, then the area-level "level" headers underneath.
3425
- *
3426
- * Per-check rows are deliberately omitted here — the Hi-score Table tab
3427
- * has the full check-by-check breakdown. This pane is the at-a-glance
3428
- * stage overview.
3429
- */
3430
- const NEON_PINK$1 = "#F54E00";
3431
- const NEON_GOLD$1 = "#F9BD2B";
3432
- const NEON_BLUE$1 = "#1D4AFF";
3433
- function groupByArea(checks) {
3434
- const order = [];
3435
- const map = /* @__PURE__ */ new Map();
3436
- for (const c of checks) {
3437
- if (!map.has(c.area)) {
3438
- map.set(c.area, []);
3439
- order.push(c.area);
3440
- }
3441
- map.get(c.area).push(c);
3442
- }
3443
- return order.map((area) => ({
3444
- area,
3445
- checks: map.get(area)
3446
- }));
3447
- }
3448
- function countByStatus$1(checks) {
3449
- const counts = {
3450
- pending: 0,
3451
- pass: 0,
3452
- error: 0,
3453
- warning: 0,
3454
- suggestion: 0
3455
- };
3456
- for (const c of checks) counts[c.status] += 1;
3457
- return counts;
3458
- }
3459
- const ScoreBanner = ({ checks }) => {
3460
- const counts = countByStatus$1(checks);
3461
- const resolved = checks.length - counts.pending;
3462
- const issues = counts.error + counts.warning + counts.suggestion;
3463
- return /* @__PURE__ */ jsxs(Box, {
3464
- flexDirection: "column",
3465
- marginBottom: 1,
3466
- children: [/* @__PURE__ */ jsxs(Text, { children: [
3467
- /* @__PURE__ */ jsx(Text, {
3468
- bold: true,
3469
- color: NEON_PINK$1,
3470
- children: "SCORE "
3471
- }),
3472
- /* @__PURE__ */ jsx(Text, {
3473
- bold: true,
3474
- color: NEON_GOLD$1,
3475
- children: resolved.toString().padStart(2, "0")
3476
- }),
3477
- /* @__PURE__ */ jsx(Text, {
3478
- dimColor: true,
3479
- children: " / "
3480
- }),
3481
- /* @__PURE__ */ jsx(Text, {
3482
- bold: true,
3483
- children: checks.length.toString().padStart(2, "0")
3484
- })
3485
- ] }), /* @__PURE__ */ jsxs(Text, { children: [
3486
- /* @__PURE__ */ jsx(Text, {
3487
- color: "green",
3488
- children: `PASS \u25B2 ${counts.pass}`
3489
- }),
3490
- /* @__PURE__ */ jsx(Text, { children: " " }),
3491
- /* @__PURE__ */ jsx(Text, {
3492
- color: NEON_PINK$1,
3493
- children: `MISS \u25BC ${issues}`
3494
- }),
3495
- /* @__PURE__ */ jsx(Text, { children: " " }),
3496
- /* @__PURE__ */ jsx(Text, {
3497
- dimColor: true,
3498
- children: `QUEUE \u25CB ${counts.pending}`
3499
- })
3500
- ] })]
3501
- });
3502
- };
3503
- function groupIcon(group) {
3504
- const total = group.checks.length;
3505
- const complete = group.checks.filter((c) => c.status !== "pending").length;
3506
- if (complete === 0) return {
3507
- icon: Icons.squareOpen,
3508
- color: Colors.muted
3509
- };
3510
- if (complete === total) return {
3511
- icon: Icons.squareFilled,
3512
- color: Colors.success
3513
- };
3514
- return {
3515
- icon: Icons.triangleRight,
3516
- color: Colors.primary
3517
- };
3518
- }
3519
- const GroupHeader = ({ group, level, showIcon, isActive }) => {
3520
- const complete = group.checks.filter((c) => c.status !== "pending").length;
3521
- const total = group.checks.length;
3522
- const { icon, color } = groupIcon(group);
3523
- return /* @__PURE__ */ jsxs(Box, { children: [isActive ? /* @__PURE__ */ jsx(Box, {
3524
- marginRight: 1,
3525
- children: /* @__PURE__ */ jsx(Spinner, {})
3526
- }) : showIcon ? /* @__PURE__ */ jsxs(Text, { children: [/* @__PURE__ */ jsx(Text, {
3527
- color,
3528
- children: icon
3529
- }), " "] }) : null, /* @__PURE__ */ jsxs(Text, { children: [
3530
- /* @__PURE__ */ jsx(Text, {
3531
- color: NEON_BLUE$1,
3532
- bold: true,
3533
- children: `L${level} `
3534
- }),
3535
- /* @__PURE__ */ jsx(Text, {
3536
- bold: true,
3537
- children: group.area
3538
- }),
3539
- " ",
3540
- /* @__PURE__ */ jsxs(Text, {
3541
- dimColor: true,
3542
- children: [
3543
- "(",
3544
- complete,
3545
- "/",
3546
- total,
3547
- ")"
3548
- ]
3549
- })
3550
- ] })] });
3551
- };
3552
- const Audit3000ChecksPanel = ({ checks }) => {
3553
- if (checks.length === 0) return /* @__PURE__ */ jsxs(Box, {
3554
- flexDirection: "column",
3555
- children: [
3556
- /* @__PURE__ */ jsx(Text, {
3557
- bold: true,
3558
- children: "AUDIT-3000"
3559
- }),
3560
- /* @__PURE__ */ jsx(Text, { children: " " }),
3561
- /* @__PURE__ */ jsx(LoadingBox, { message: "Booting up arcade cabinet..." })
3562
- ]
3563
- });
3564
- const groups = groupByArea(checks);
3565
- const activeIndex = groups.findIndex((g) => g.checks.some((c) => c.status === "pending"));
3566
- return /* @__PURE__ */ jsxs(Box, {
3567
- flexDirection: "column",
3568
- children: [
3569
- /* @__PURE__ */ jsx(Text, {
3570
- bold: true,
3571
- color: NEON_PINK$1,
3572
- children: "AUDIT-3000"
3573
- }),
3574
- /* @__PURE__ */ jsx(Text, { children: " " }),
3575
- /* @__PURE__ */ jsx(ScoreBanner, { checks }),
3576
- groups.map((group, i) => /* @__PURE__ */ jsx(GroupHeader, {
3577
- group,
3578
- level: i + 1,
3579
- showIcon: true,
3580
- isActive: i === activeIndex
3581
- }, group.area)),
3582
- /* @__PURE__ */ jsx(Box, {
3583
- marginTop: 1,
3584
- children: /* @__PURE__ */ jsxs(Text, {
3585
- dimColor: true,
3586
- children: [
3587
- "Full breakdown: ",
3588
- /* @__PURE__ */ jsx(Text, {
3589
- color: NEON_GOLD$1,
3590
- children: "Hi-score table (report)"
3591
- }),
3592
- " ",
3593
- "tab"
3594
- ]
3595
- })
3596
- })
3597
- ]
3598
- });
3599
- };
3600
- function nextRandom(seed) {
3601
- let t = seed + 1831565813 >>> 0;
3602
- t = Math.imul(t ^ t >>> 15, t | 1);
3603
- t ^= t + Math.imul(t ^ t >>> 7, t | 61);
3604
- return {
3605
- value: ((t ^ t >>> 14) >>> 0) / 4294967296,
3606
- nextSeed: t >>> 0
3607
- };
3608
- }
3609
- function randomInt(seed, min, max) {
3610
- const { value, nextSeed } = nextRandom(seed);
3611
- return {
3612
- value: min + Math.floor(value * (max - min + 1)),
3613
- nextSeed
3614
- };
3615
- }
3616
- function initialState(hiScore = 0, rngSeed = 1) {
3617
- return {
3618
- hedgehogState: "grounded",
3619
- hedgehogRow: 2,
3620
- jumpFramesRemaining: 0,
3621
- obstacles: [],
3622
- score: 0,
3623
- hiScore,
3624
- isGameOver: false,
3625
- tick: 0,
3626
- ticksUntilNextSpawn: 6,
3627
- rngSeed
3628
- };
3629
- }
3630
- function jump(state) {
3631
- if (state.isGameOver) return state;
3632
- if (state.hedgehogState !== "grounded") return state;
3633
- return {
3634
- ...state,
3635
- hedgehogState: "jumping",
3636
- hedgehogRow: 1,
3637
- jumpFramesRemaining: 8
3638
- };
3639
- }
3640
- function restart(state) {
3641
- return initialState(state.hiScore, state.rngSeed);
3642
- }
3643
- function tick(state) {
3644
- if (state.isGameOver) return state;
3645
- let { hedgehogState, hedgehogRow, jumpFramesRemaining } = state;
3646
- if (hedgehogState === "jumping") {
3647
- jumpFramesRemaining -= 1;
3648
- if (jumpFramesRemaining <= 0) {
3649
- hedgehogState = "grounded";
3650
- hedgehogRow = 2;
3651
- jumpFramesRemaining = 0;
3652
- }
3653
- }
3654
- const movedObstacles = [];
3655
- let scoreDelta = 1;
3656
- let hit = false;
3657
- for (const obs of state.obstacles) {
3658
- const next = {
3659
- ...obs,
3660
- x: obs.x - 1
3661
- };
3662
- if (next.x < 0) continue;
3663
- if (next.x === 4 && next.row === hedgehogRow) {
3664
- if (next.kind === "spike") {
3665
- hit = true;
3666
- movedObstacles.push(next);
3667
- continue;
3668
- }
3669
- scoreDelta += 5;
3670
- continue;
3671
- }
3672
- movedObstacles.push(next);
3673
- }
3674
- let rngSeed = state.rngSeed;
3675
- let ticksUntilNextSpawn = state.ticksUntilNextSpawn - 1;
3676
- if (ticksUntilNextSpawn <= 0) {
3677
- const kindRoll = nextRandom(rngSeed);
3678
- rngSeed = kindRoll.nextSeed;
3679
- const kind = kindRoll.value < .65 ? "spike" : "ring";
3680
- const row = kind === "spike" ? 2 : 1;
3681
- movedObstacles.push({
3682
- kind,
3683
- x: 39,
3684
- row
3685
- });
3686
- const cooldown = randomInt(rngSeed, 6, 14);
3687
- rngSeed = cooldown.nextSeed;
3688
- ticksUntilNextSpawn = cooldown.value;
3689
- }
3690
- const score = state.score + scoreDelta;
3691
- const isGameOver = hit;
3692
- const hiScore = isGameOver ? Math.max(state.hiScore, score) : state.hiScore;
3693
- return {
3694
- hedgehogState,
3695
- hedgehogRow,
3696
- jumpFramesRemaining,
3697
- obstacles: movedObstacles,
3698
- score,
3699
- hiScore,
3700
- isGameOver,
3701
- tick: state.tick + 1,
3702
- ticksUntilNextSpawn,
3703
- rngSeed
3704
- };
3705
- }
3706
- //#endregion
3707
- //#region src/ui/tui/screens/audit-3000/HedgehogRunner.tsx
3708
- /**
3709
- * HedgehogRunner — playable arcade game shown while the audit runs.
3710
- *
3711
- * Game state lives in the parent (Audit3000RunScreen) so it survives tab
3712
- * switches. This component owns the render loop (setInterval) and key
3713
- * bindings; when the user switches tabs the component unmounts, the
3714
- * interval clears, and state freezes in the parent — free pause behaviour.
3715
- */
3716
- const TICK_MS = 150;
3717
- const PLAYFIELD_ROWS = 3;
3718
- const MIN_TERMINAL_COLUMNS = 50;
3719
- const HEDGEHOG_GLYPH = "O";
3720
- const SPIKE_GLYPH = "^";
3721
- const RING_GLYPH = "o";
3722
- const GROUND_GLYPH = "=";
3723
- const pad4 = (n) => String(n).padStart(4, "0");
3724
- const HedgehogRunner = ({ state, onChange }) => {
3725
- const [columns] = useStdoutDimensions();
3726
- useEffect(() => {
3727
- const id = setInterval(() => {
3728
- onChange((prev) => tick(prev));
3729
- }, TICK_MS);
3730
- return () => clearInterval(id);
3731
- }, [onChange]);
3732
- useKeyBindings("hedgehog-runner", [{
3733
- match: "space",
3734
- label: "space",
3735
- action: "jump",
3736
- handler: () => onChange((prev) => jump(prev))
3737
- }, {
3738
- match: "r",
3739
- label: "r",
3740
- action: "restart",
3741
- handler: () => onChange((prev) => prev.isGameOver ? restart(prev) : prev)
3742
- }]);
3743
- if (columns < MIN_TERMINAL_COLUMNS) return /* @__PURE__ */ jsx(Box, {
3744
- flexDirection: "column",
3745
- paddingX: 1,
3746
- children: /* @__PURE__ */ jsxs(Text, {
3747
- dimColor: true,
3748
- children: [
3749
- "Widen the terminal to at least ",
3750
- MIN_TERMINAL_COLUMNS,
3751
- " columns to play Hedgehog Runner."
3752
- ]
3753
- })
3754
- });
3755
- return /* @__PURE__ */ jsxs(Box, {
3756
- flexDirection: "column",
3757
- paddingX: 1,
3758
- children: [
3759
- /* @__PURE__ */ jsxs(Box, { children: [
3760
- /* @__PURE__ */ jsxs(Text, {
3761
- bold: true,
3762
- color: NEON_BLUE$2,
3763
- children: ["SCORE ", pad4(state.score)]
3764
- }),
3765
- /* @__PURE__ */ jsx(Text, { children: " " }),
3766
- /* @__PURE__ */ jsxs(Text, {
3767
- bold: true,
3768
- color: NEON_GOLD$2,
3769
- children: ["HI ", pad4(state.hiScore)]
3770
- }),
3771
- state.isGameOver && /* @__PURE__ */ jsxs(Fragment$1, { children: [/* @__PURE__ */ jsx(Text, { children: " " }), /* @__PURE__ */ jsx(Text, {
3772
- bold: true,
3773
- color: "red",
3774
- children: "✱ GAME OVER ✱"
3775
- })] })
3776
- ] }),
3777
- Array.from({ length: PLAYFIELD_ROWS }, (_, row) => /* @__PURE__ */ jsx(PlayfieldRow, {
3778
- row,
3779
- state
3780
- }, row)),
3781
- /* @__PURE__ */ jsx(Text, {
3782
- color: Colors.muted,
3783
- children: GROUND_GLYPH.repeat(40)
3784
- })
3785
- ]
3786
- });
3787
- };
3788
- const PlayfieldRow = ({ row, state }) => {
3789
- const cells = [];
3790
- for (let x = 0; x < 40; x++) {
3791
- if (x === 4 && row === state.hedgehogRow) {
3792
- cells.push({
3793
- ch: HEDGEHOG_GLYPH,
3794
- color: NEON_PINK$2,
3795
- bold: true
3796
- });
3797
- continue;
3798
- }
3799
- const obstacle = state.obstacles.find((o) => o.x === x && o.row === row);
3800
- if (obstacle) {
3801
- cells.push(obstacle.kind === "spike" ? {
3802
- ch: SPIKE_GLYPH,
3803
- color: "red",
3804
- bold: true
3805
- } : {
3806
- ch: RING_GLYPH,
3807
- color: NEON_GOLD$2,
3808
- bold: true
3809
- });
3810
- continue;
3811
- }
3812
- cells.push({ ch: " " });
3813
- }
3814
- return /* @__PURE__ */ jsx(Text, { children: cells.map((c, i) => /* @__PURE__ */ jsx(Fragment, { children: c.color ? /* @__PURE__ */ jsx(Text, {
3815
- color: c.color,
3816
- bold: c.bold,
3817
- children: c.ch
3818
- }) : c.ch }, i)) });
3819
- };
3820
- //#endregion
3821
- //#region src/ui/tui/screens/audit-3000/Audit3000RunScreen.tsx
3822
- const AUDIT_3000_REPORT_FILE_FALLBACK = "posthog-audit-3000-report.md";
3823
- const Audit3000RunScreen = ({ store }) => {
3824
- useSyncExternalStore((cb) => store.subscribe(cb), () => store.getSnapshot());
3825
- useFileWatcher(join$1(store.session.installDir, AUDIT_CHECKS_FILE), (parsed) => store.setFrameworkContext(AUDIT_CHECKS_KEY, coerceAuditChecks(parsed)));
3826
- const statuses = store.statusMessages.length > 0 ? store.statusMessages : void 0;
3827
- const [columns] = useStdoutDimensions();
3828
- const [gameState, setGameState] = useState(() => initialState());
3829
- const checks = getAuditChecks(store.session);
3830
- const reportPath = `./${getProgramConfig(store.router.activeProgram).reportFile ?? AUDIT_3000_REPORT_FILE_FALLBACK}`;
3831
- const checksPanel = /* @__PURE__ */ jsx(Audit3000ChecksPanel, { checks });
3832
- return /* @__PURE__ */ jsx(TabContainer, {
3833
- tabs: [
3834
- {
3835
- id: "status",
3836
- label: "Arcade",
3837
- component: columns < 80 ? /* @__PURE__ */ jsx(Box, {
3838
- flexDirection: "column",
3839
- flexGrow: 1,
3840
- children: checksPanel
3841
- }) : /* @__PURE__ */ jsx(SplitView, {
3842
- left: /* @__PURE__ */ jsx(Audit3000AreaPane, {
3843
- checks,
3844
- reportPath
3845
- }),
3846
- right: checksPanel
3847
- })
3848
- },
3849
- {
3850
- id: "audit-checks",
3851
- label: "Hi-score table (report)",
3852
- component: /* @__PURE__ */ jsx(AuditChecksViewer, { checks })
3853
- },
3854
- {
3855
- id: "play",
3856
- label: "Play",
3857
- component: /* @__PURE__ */ jsx(HedgehogRunner, {
3858
- state: gameState,
3859
- onChange: setGameState
3860
- })
3861
- },
3862
- {
3863
- id: "logs",
3864
- label: "Tail logs",
3865
- component: /* @__PURE__ */ jsx(LogViewer, { filePath: WIZARD_LOG_FILE })
3866
- },
3867
- {
3868
- id: "hn",
3869
- label: "HN",
3870
- component: /* @__PURE__ */ jsx(HNViewer, {})
3871
- }
3872
- ],
3873
- statusMessage: statuses,
3874
- expandableStatus: true,
3875
- store
3876
- });
3877
- };
3878
- //#endregion
3879
- //#region src/ui/tui/screens/audit-3000/Audit3000OutroScreen.tsx
3880
- /**
3881
- * Audit3000OutroScreen — high-score-style summary after a v3000 audit run.
3882
- *
3883
- * On success: arcade FINAL SCORE banner with pass / miss tallies, the
3884
- * absolute report path, and the standard problematic-items list.
3885
- *
3886
- * Error and cancel branches mirror `AuditOutroScreen` so failure modes
3887
- * stay legible without arcade dressing.
3888
- */
3889
- const NEON_PINK = "#F54E00";
3890
- const NEON_GOLD = "#F9BD2B";
3891
- const NEON_BLUE = "#1D4AFF";
3892
- const PANEL_WIDTH = 48;
3893
- const padCenter = (s, width) => {
3894
- if (s.length >= width) return s;
3895
- const total = width - s.length;
3896
- const left = Math.floor(total / 2);
3897
- const right = total - left;
3898
- return " ".repeat(left) + s + " ".repeat(right);
3899
- };
3900
- function countByStatus(checks) {
3901
- const counts = {
3902
- pending: 0,
3903
- pass: 0,
3904
- error: 0,
3905
- warning: 0,
3906
- suggestion: 0
3907
- };
3908
- for (const c of checks) counts[c.status] += 1;
3909
- return counts;
3910
- }
3911
- const FinalScorePanel = ({ checks }) => {
3912
- const counts = countByStatus(checks);
3913
- const resolved = checks.length - counts.pending;
3914
- const issues = counts.error + counts.warning + counts.suggestion;
3915
- const top = "┏" + "━".repeat(PANEL_WIDTH) + "┓";
3916
- const bottom = "┗" + "━".repeat(PANEL_WIDTH) + "┛";
3917
- const sep = "┠" + "─".repeat(PANEL_WIDTH) + "┨";
3918
- const row = (content) => /* @__PURE__ */ jsxs(Text, { children: [
3919
- /* @__PURE__ */ jsx(Text, {
3920
- bold: true,
3921
- color: NEON_PINK,
3922
- children: "┃"
3923
- }),
3924
- /* @__PURE__ */ jsx(Text, { children: content }),
3925
- /* @__PURE__ */ jsx(Text, {
3926
- bold: true,
3927
- color: NEON_PINK,
3928
- children: "┃"
3929
- })
3930
- ] });
3931
- return /* @__PURE__ */ jsxs(Box, {
3932
- flexDirection: "column",
3933
- marginTop: 1,
3934
- children: [
3935
- /* @__PURE__ */ jsx(Text, {
3936
- bold: true,
3937
- color: NEON_PINK,
3938
- children: top
3939
- }),
3940
- row(padCenter("GAME OVER", PANEL_WIDTH)),
3941
- /* @__PURE__ */ jsxs(Text, { children: [
3942
- /* @__PURE__ */ jsx(Text, {
3943
- bold: true,
3944
- color: NEON_PINK,
3945
- children: "┃"
3946
- }),
3947
- /* @__PURE__ */ jsx(Text, {
3948
- color: NEON_GOLD,
3949
- children: padCenter(`FINAL SCORE ${resolved} / ${checks.length}`, PANEL_WIDTH)
3950
- }),
3951
- /* @__PURE__ */ jsx(Text, {
3952
- bold: true,
3953
- color: NEON_PINK,
3954
- children: "┃"
3955
- })
3956
- ] }),
3957
- /* @__PURE__ */ jsx(Text, {
3958
- color: NEON_PINK,
3959
- children: sep
3960
- }),
3961
- /* @__PURE__ */ jsxs(Text, { children: [
3962
- /* @__PURE__ */ jsx(Text, {
3963
- bold: true,
3964
- color: NEON_PINK,
3965
- children: "┃"
3966
- }),
3967
- /* @__PURE__ */ jsx(Text, {
3968
- color: "green",
3969
- children: padCenter(`PASS \u25B2 ${counts.pass}`, PANEL_WIDTH)
3970
- }),
3971
- /* @__PURE__ */ jsx(Text, {
3972
- bold: true,
3973
- color: NEON_PINK,
3974
- children: "┃"
3975
- })
3976
- ] }),
3977
- /* @__PURE__ */ jsxs(Text, { children: [
3978
- /* @__PURE__ */ jsx(Text, {
3979
- bold: true,
3980
- color: NEON_PINK,
3981
- children: "┃"
3982
- }),
3983
- /* @__PURE__ */ jsx(Text, {
3984
- color: NEON_BLUE,
3985
- children: padCenter(`MISS \u25BC ${issues}`, PANEL_WIDTH)
3986
- }),
3987
- /* @__PURE__ */ jsx(Text, {
3988
- bold: true,
3989
- color: NEON_PINK,
3990
- children: "┃"
3991
- })
3992
- ] }),
3993
- /* @__PURE__ */ jsx(Text, {
3994
- bold: true,
3995
- color: NEON_PINK,
3996
- children: bottom
3997
- })
3998
- ]
3999
- });
4000
- };
4001
- const Audit3000OutroScreen = ({ store }) => {
4002
- useSyncExternalStore((cb) => store.subscribe(cb), () => store.getSnapshot());
4003
- useInput(() => {
4004
- store.setOutroDismissed();
4005
- });
4006
- const outroData = store.session.outroData;
4007
- if (!outroData) return /* @__PURE__ */ jsx(Box, {
4008
- flexDirection: "column",
4009
- flexGrow: 1,
4010
- children: /* @__PURE__ */ jsx(Text, {
4011
- dimColor: true,
4012
- children: "Counting your tokens…"
4013
- })
4014
- });
4015
- const checks = getAuditChecks(store.session);
4016
- return /* @__PURE__ */ jsxs(Box, {
4017
- flexDirection: "column",
4018
- flexGrow: 1,
4019
- children: [
4020
- outroData.kind === "success" && /* @__PURE__ */ jsxs(Box, {
4021
- flexDirection: "column",
4022
- children: [
4023
- /* @__PURE__ */ jsx(FinalScorePanel, { checks }),
4024
- /* @__PURE__ */ jsx(Box, {
4025
- marginTop: 1,
4026
- children: /* @__PURE__ */ jsxs(Text, {
4027
- bold: true,
4028
- color: "green",
4029
- children: [
4030
- "✔",
4031
- " ",
4032
- outroData.message || "AUDIT-3000 complete!"
4033
- ]
4034
- })
4035
- }),
4036
- outroData.reportFile && /* @__PURE__ */ jsxs(Box, {
4037
- flexDirection: "column",
4038
- marginTop: 1,
4039
- children: [
4040
- /* @__PURE__ */ jsx(Text, {
4041
- bold: true,
4042
- color: "cyan",
4043
- children: "High-score reel saved to:"
4044
- }),
4045
- /* @__PURE__ */ jsx(Text, { children: join$1(store.session.installDir, outroData.reportFile) }),
4046
- /* @__PURE__ */ jsx(Text, {
4047
- dimColor: true,
4048
- children: "A markdown file in your project folder — open it in any editor to read the full audit."
4049
- })
4050
- ]
4051
- }),
4052
- /* @__PURE__ */ jsx(AuditChecksOutroSection, {
4053
- checks,
4054
- installDir: store.session.installDir
4055
- }),
4056
- outroData.docsUrl && /* @__PURE__ */ jsx(Box, {
4057
- marginTop: 1,
4058
- children: /* @__PURE__ */ jsxs(Text, { children: ["Learn more: ", /* @__PURE__ */ jsx(Text, {
4059
- color: "cyan",
4060
- children: outroData.docsUrl
4061
- })] })
4062
- })
4063
- ]
4064
- }),
4065
- outroData.kind === "error" && /* @__PURE__ */ jsxs(Box, {
4066
- flexDirection: "column",
4067
- children: [/* @__PURE__ */ jsxs(Text, {
4068
- color: "red",
4069
- bold: true,
4070
- children: [
4071
- "✘",
4072
- " ",
4073
- outroData.message || "An error occurred"
4074
- ]
4075
- }), outroData.body && /* @__PURE__ */ jsx(Box, {
4076
- marginTop: 1,
4077
- children: /* @__PURE__ */ jsx(Text, {
4078
- dimColor: true,
4079
- children: outroData.body
4080
- })
4081
- })]
4082
- }),
4083
- outroData.kind === "cancel" && /* @__PURE__ */ jsxs(Text, {
4084
- color: "yellow",
4085
- children: [
4086
- "■",
4087
- " ",
4088
- outroData.message || "Cancelled"
4089
- ]
4090
- }),
4091
- /* @__PURE__ */ jsx(Box, {
4092
- marginTop: 1,
4093
- children: /* @__PURE__ */ jsx(Text, {
4094
- color: Colors.muted,
4095
- children: "Press any key to continue"
4096
- })
4097
- })
4098
- ]
4099
- });
4100
- };
4101
- //#endregion
4102
3129
  //#region src/ui/tui/screens/SetupScreen.tsx
4103
3130
  /**
4104
3131
  * SetupScreen — Generic framework disambiguation.
@@ -4944,14 +3971,14 @@ function createMcpSuggestedPromptsServices(_store) {
4944
3971
  };
4945
3972
  },
4946
3973
  checkSlackConnected: async (credentials, signal) => {
4947
- const { fetchSlackConnected } = await import("./api-BkLZ8BWm.js").then((n) => n.n);
3974
+ const { fetchSlackConnected } = await import("./api-RXTR8yZo.js").then((n) => n.n);
4948
3975
  return fetchSlackConnected(credentials.accessToken, credentials.projectId, credentials.host, signal);
4949
3976
  },
4950
3977
  runPromptStreaming: (args) => runProductionPromptStreaming(args)
4951
3978
  };
4952
3979
  }
4953
3980
  async function* runProductionPromptStreaming(args) {
4954
- const { runMcpPromptViaSdk } = await import("./mcp-prompt-streaming-kEJgmB30.js");
3981
+ const { runMcpPromptViaSdk } = await import("./mcp-prompt-streaming-DUtbxnNy.js");
4955
3982
  yield* runMcpPromptViaSdk(args);
4956
3983
  }
4957
3984
  //#endregion
@@ -4980,9 +4007,6 @@ function createScreens(store, services) {
4980
4007
  ["audit-intro"]: /* @__PURE__ */ jsx(AuditIntroScreen, { store }),
4981
4008
  ["audit-run"]: /* @__PURE__ */ jsx(AuditRunScreen, { store }),
4982
4009
  ["audit-outro"]: /* @__PURE__ */ jsx(AuditOutroScreen, { store }),
4983
- ["audit-3000-intro"]: /* @__PURE__ */ jsx(Audit3000IntroScreen, { store }),
4984
- ["audit-3000-run"]: /* @__PURE__ */ jsx(Audit3000RunScreen, { store }),
4985
- ["audit-3000-outro"]: /* @__PURE__ */ jsx(Audit3000OutroScreen, { store }),
4986
4010
  ["health-check"]: /* @__PURE__ */ jsx(HealthCheckScreen, { store }),
4987
4011
  ["doctor-intro"]: /* @__PURE__ */ jsx(DoctorIntroScreen, { store }),
4988
4012
  ["doctor-report"]: /* @__PURE__ */ jsx(DoctorReportScreen, { store }),
@@ -5091,4 +4115,4 @@ function startTUI(version, program = Program.PostHogIntegration) {
5091
4115
  //#endregion
5092
4116
  export { startTUI };
5093
4117
 
5094
- //# sourceMappingURL=start-tui--E4PXdwG.js.map
4118
+ //# sourceMappingURL=start-tui-CywbSvZE.js.map