@posthog/wizard 2.23.0 → 2.24.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (56) hide show
  1. package/README.md +61 -2
  2. package/dist/{AiOptInRequiredScreen-BOMyYFep.js → AiOptInRequiredScreen-_33FOcVo.js} +148 -685
  3. package/dist/AiOptInRequiredScreen-_33FOcVo.js.map +1 -0
  4. package/dist/{add-mcp-server-to-clients-BEziI3z9.js → add-mcp-server-to-clients-CfwEQT_z.js} +4 -4
  5. package/dist/{add-mcp-server-to-clients-BEziI3z9.js.map → add-mcp-server-to-clients-CfwEQT_z.js.map} +1 -1
  6. package/dist/{agent-interface-DjMPlXl0.js → agent-interface-D1vtN6Wn.js} +6 -7
  7. package/dist/agent-interface-D1vtN6Wn.js.map +1 -0
  8. package/dist/{agent-runner-Bv-7z-pQ.js → agent-runner-CBbkS0Ro.js} +8 -8
  9. package/dist/{agent-runner-Bv-7z-pQ.js.map → agent-runner-CBbkS0Ro.js.map} +1 -1
  10. package/dist/{analytics-9D4eGgmT.js → analytics-CUr82BDl.js} +11 -2
  11. package/dist/{analytics-9D4eGgmT.js.map → analytics-CUr82BDl.js.map} +1 -1
  12. package/dist/{api-Dwd0B-E9.js → api-CI3Z74NG.js} +3 -3
  13. package/dist/{api-Dwd0B-E9.js.map → api-CI3Z74NG.js.map} +1 -1
  14. package/dist/bin.js +887 -465
  15. package/dist/bin.js.map +1 -1
  16. package/dist/{ci-install-DGXCpvKh.js → ci-install-D_kxNmbJ.js} +5 -5
  17. package/dist/{ci-install-DGXCpvKh.js.map → ci-install-D_kxNmbJ.js.map} +1 -1
  18. package/dist/{debug-CgT5MmVB.js → debug-DxA_f5QT.js} +2 -2
  19. package/dist/{debug-CgT5MmVB.js.map → debug-DxA_f5QT.js.map} +1 -1
  20. package/dist/{debug-DayHBBST.js → debug-zMvpNYb2.js} +1 -1
  21. package/dist/{environment-CI2pTYTG.js → environment-CyS37cmM.js} +3 -3
  22. package/dist/{environment-CI2pTYTG.js.map → environment-CyS37cmM.js.map} +1 -1
  23. package/dist/{interactive-D52p_opJ.js → interactive-CG6FFqSw.js} +3 -3
  24. package/dist/{interactive-D52p_opJ.js.map → interactive-CG6FFqSw.js.map} +1 -1
  25. package/dist/{mcp-prompt-streaming-tdoy9UJ2.js → mcp-prompt-streaming-DQz4FSb1.js} +4 -4
  26. package/dist/{mcp-prompt-streaming-tdoy9UJ2.js.map → mcp-prompt-streaming-DQz4FSb1.js.map} +1 -1
  27. package/dist/{non-interactive-6hadW20x.js → non-interactive-DWtHX3ZR.js} +2 -2
  28. package/dist/{non-interactive-6hadW20x.js.map → non-interactive-DWtHX3ZR.js.map} +1 -1
  29. package/dist/{package-manager-BI0J5E7t.js → package-manager-BWUS4CP0.js} +2 -2
  30. package/dist/{package-manager-BI0J5E7t.js.map → package-manager-BWUS4CP0.js.map} +1 -1
  31. package/dist/{playground-z4A5dHPv.js → playground-D7AhMMF5.js} +9 -20
  32. package/dist/playground-D7AhMMF5.js.map +1 -0
  33. package/dist/{posthog-integration-BWbZU9Xq.js → posthog-integration-DexZ2uHU.js} +18 -18
  34. package/dist/{posthog-integration-BWbZU9Xq.js.map → posthog-integration-DexZ2uHU.js.map} +1 -1
  35. package/dist/{provisioning-B30Be2NA.js → provisioning-9c-AQbsa.js} +3 -3
  36. package/dist/{provisioning-B30Be2NA.js.map → provisioning-9c-AQbsa.js.map} +1 -1
  37. package/dist/{registry-CD_DplSQ.js → registry-CO7JVZyE.js} +4 -4
  38. package/dist/{registry-CD_DplSQ.js.map → registry-CO7JVZyE.js.map} +1 -1
  39. package/dist/{setup-utils-Dwgkk8AQ.js → setup-utils-0U-_Md2G.js} +8 -8
  40. package/dist/{setup-utils-Dwgkk8AQ.js.map → setup-utils-0U-_Md2G.js.map} +1 -1
  41. package/dist/{start-tui-SLeEzlJs.js → start-tui-WNb3ET14.js} +206 -1205
  42. package/dist/start-tui-WNb3ET14.js.map +1 -0
  43. package/dist/{steps-B1gzyRkC.js → steps-BAUXDCC4.js} +6 -6
  44. package/dist/{steps-B1gzyRkC.js.map → steps-BAUXDCC4.js.map} +1 -1
  45. package/dist/{telemetry-5rkeTd2_.js → telemetry-ycqCpNPr.js} +3 -3
  46. package/dist/{telemetry-5rkeTd2_.js.map → telemetry-ycqCpNPr.js.map} +1 -1
  47. package/dist/{urls-Cb4SI9kf.js → urls-C8aJWvgh.js} +2 -2
  48. package/dist/{urls-Cb4SI9kf.js.map → urls-C8aJWvgh.js.map} +1 -1
  49. package/dist/{wizard-abort-DovHQa-j.js → wizard-abort-C6gRLxUE.js} +3 -3
  50. package/dist/{wizard-abort-DovHQa-j.js.map → wizard-abort-C6gRLxUE.js.map} +1 -1
  51. package/dist/{wizard-abort-DW2-ZjiS.js → wizard-abort-DWXyJdws.js} +1 -1
  52. package/package.json +1 -1
  53. package/dist/AiOptInRequiredScreen-BOMyYFep.js.map +0 -1
  54. package/dist/agent-interface-DjMPlXl0.js.map +0 -1
  55. package/dist/playground-z4A5dHPv.js.map +0 -1
  56. package/dist/start-tui-SLeEzlJs.js.map +0 -1
@@ -1,18 +1,19 @@
1
- import { M as POSTHOG_APP_URL, Q as getSkillsBaseUrl, g as SERVICE_LABELS, s as logToFile, y as getBlockingServiceKeys } from "./debug-CgT5MmVB.js";
1
+ import { M as POSTHOG_APP_URL, Q as getSkillsBaseUrl, g as SERVICE_LABELS, s as logToFile, y as getBlockingServiceKeys } from "./debug-DxA_f5QT.js";
2
2
  import { n as isTaskStatus } from "./wizard-ui-YdGFRyu_.js";
3
- import { r as sessionProperties, t as analytics } from "./analytics-9D4eGgmT.js";
4
- import { i as withUtm, n as openTrackedLink } from "./telemetry-5rkeTd2_.js";
5
- import { n as getCloudUrlFromRegion } from "./urls-Cb4SI9kf.js";
6
- import { a as fetchUserData, i as fetchSlackConnected } from "./api-Dwd0B-E9.js";
3
+ import { r as sessionProperties, t as analytics } from "./analytics-CUr82BDl.js";
4
+ import { i as withUtm, n as openTrackedLink } from "./telemetry-ycqCpNPr.js";
5
+ import { t as getOrAskForProjectData } from "./setup-utils-0U-_Md2G.js";
6
+ import { n as getCloudUrlFromRegion } from "./urls-C8aJWvgh.js";
7
+ import { a as fetchUserData, i as fetchSlackConnected } from "./api-CI3Z74NG.js";
7
8
  import { i as buildSession } from "./wizard-session-G3VWD6hv.js";
8
- import { m as fetchSkillMenu, y as AUDIT_SEVERITY_STYLE } from "./agent-interface-DjMPlXl0.js";
9
- import { c as computeVisibleRange, d as isObjectBlock, f as Colors, l as isClearBlock, p as Icons, s as TextBlock, u as isLinesBlock } from "./posthog-integration-BWbZU9Xq.js";
10
- import { a as getProgramConfig, i as Program, l as getKindMeta, r as PROGRAM_REGISTRY } from "./bin.js";
9
+ import { m as fetchSkillMenu, y as AUDIT_SEVERITY_STYLE } from "./agent-interface-D1vtN6Wn.js";
10
+ import { c as computeVisibleRange, d as isObjectBlock, f as Colors, l as isClearBlock, p as Icons, s as TextBlock, u as isLinesBlock } from "./posthog-integration-DexZ2uHU.js";
11
+ import { a as PromptLabel, c as PROGRAM_REGISTRY, i as useKeyboardHintsContext, l as Program, m as getKindMeta, n as useKeyBindings, r as KeyboardHintsProvider, t as PickerMenu, u as getProgramConfig } from "./bin.js";
11
12
  import { n as AVAILABLE_FEATURES, o as isAllFeaturesSelected, t as ALL_FEATURE_VALUES } from "./defaults-BNWIWzjc.js";
12
13
  import opn from "opn";
13
14
  import * as fs$1 from "fs";
14
15
  import { Box, Text, measureElement, useInput, useStdout } from "ink";
15
- import { Component, Fragment, createContext, useCallback, useContext, useEffect, useMemo, useRef, useState, useSyncExternalStore } from "react";
16
+ import { Component, Fragment, useCallback, useEffect, useMemo, useRef, useState, useSyncExternalStore } from "react";
16
17
  import { Fragment as Fragment$1, jsx, jsxs } from "react/jsx-runtime";
17
18
  import { atom, map } from "nanostores";
18
19
  import { Spinner } from "@inkjs/ui";
@@ -837,401 +838,6 @@ const ProgressList = ({ items, title }) => {
837
838
  });
838
839
  };
839
840
  //#endregion
840
- //#region src/ui/tui/primitives/PromptLabel.tsx
841
- /**
842
- * PromptLabel — Compact inline label for input prompts.
843
- *
844
- * Renders: [!] message
845
- * where [!] is black text on accent background.
846
- */
847
- const PromptLabel = ({ message }) => {
848
- return /* @__PURE__ */ jsx(Box, { children: /* @__PURE__ */ jsxs(Text, {
849
- bold: true,
850
- color: Colors.accent,
851
- children: [" ", message]
852
- }) });
853
- };
854
- //#endregion
855
- //#region src/ui/tui/hooks/keyboard-hints-utils.ts
856
- /** Default priorities by key type. */
857
- const DEFAULT_PRIORITY = {
858
- ["upArrow"]: 0,
859
- ["downArrow"]: 0,
860
- ["leftArrow"]: 1,
861
- ["rightArrow"]: 1,
862
- ["space"]: 10,
863
- ["escape"]: 20,
864
- ["return"]: 21
865
- };
866
- /** Get the default display priority for a key match. */
867
- function getDefaultPriority(match) {
868
- return DEFAULT_PRIORITY[Array.isArray(match) ? match[0] : match] ?? 15;
869
- }
870
- /** Check if a KeyMatchOrChar matches the given input string and key flags. */
871
- function matchesKey(m, input, key) {
872
- switch (m) {
873
- case "upArrow": return !!key.upArrow;
874
- case "downArrow": return !!key.downArrow;
875
- case "leftArrow": return !!key.leftArrow;
876
- case "rightArrow": return !!key.rightArrow;
877
- case "return": return !!key.return;
878
- case "escape": return !!key.escape;
879
- case "space": return input === " ";
880
- default: return input === m;
881
- }
882
- }
883
- /** Serialize hints for comparison. */
884
- function hintsKey(hints) {
885
- return hints.map((h) => `${h.label}:${h.action}`).join("|");
886
- }
887
- /** Deduplicate hints by label+action and sort by priority. */
888
- function deduplicateAndSort(hints) {
889
- const seen = /* @__PURE__ */ new Set();
890
- const deduped = [];
891
- for (const hint of hints) {
892
- const k = `${hint.label}:${hint.action}`;
893
- if (!seen.has(k)) {
894
- seen.add(k);
895
- deduped.push(hint);
896
- }
897
- }
898
- deduped.sort((a, b) => a.priority - b.priority);
899
- return deduped;
900
- }
901
- //#endregion
902
- //#region src/ui/tui/hooks/useKeyboardHints.tsx
903
- /**
904
- * KeyboardHintsProvider — Context for collecting and displaying keyboard hints.
905
- *
906
- * Input components register their hints via useKeyBindings. The provider
907
- * flattens, deduplicates, and sorts them. The hints bar stays visible for as
908
- * long as a screen has registered hints — it never auto-dismisses.
909
- */
910
- const KeyboardHintsContext = createContext({
911
- register: () => void 0,
912
- unregister: () => void 0,
913
- hints: []
914
- });
915
- const useKeyboardHintsContext = () => useContext(KeyboardHintsContext);
916
- const KeyboardHintsProvider = ({ children }) => {
917
- const registrationsRef = useRef(/* @__PURE__ */ new Map());
918
- const [hints, setHints] = useState([]);
919
- const prevHintsKeyRef = useRef("");
920
- const recompute = useCallback(() => {
921
- const all = [];
922
- for (const h of registrationsRef.current.values()) all.push(...h);
923
- const deduped = deduplicateAndSort(all);
924
- const newKey = hintsKey(deduped);
925
- if (newKey !== prevHintsKeyRef.current) {
926
- prevHintsKeyRef.current = newKey;
927
- setHints(deduped);
928
- }
929
- }, []);
930
- const register = useCallback((id, h) => {
931
- registrationsRef.current.set(id, h);
932
- recompute();
933
- }, [recompute]);
934
- const unregister = useCallback((id) => {
935
- registrationsRef.current.delete(id);
936
- recompute();
937
- }, [recompute]);
938
- return /* @__PURE__ */ jsx(KeyboardHintsContext.Provider, {
939
- value: {
940
- register,
941
- unregister,
942
- hints
943
- },
944
- children
945
- });
946
- };
947
- //#endregion
948
- //#region src/ui/tui/hooks/useKeyBindings.ts
949
- /**
950
- * useKeyBindings — Declarative keyboard input + automatic hint registration.
951
- *
952
- * Replaces raw `useInput` in input components. Define bindings as data;
953
- * the hook wires up the Ink input handler AND registers hints in the
954
- * KeyboardHintsProvider. One source of truth for keys and their labels.
955
- */
956
- /**
957
- * Declarative key bindings hook. Replaces `useInput` in input components.
958
- * Registers hints automatically with the KeyboardHintsProvider.
959
- *
960
- * @param id Unique identifier for this component's hints registration
961
- * @param bindings Array of key binding definitions
962
- */
963
- function useKeyBindings(id, bindings) {
964
- const ctx = useKeyboardHintsContext();
965
- const hintsRef = useRef("");
966
- const hints = bindings.map((b) => ({
967
- label: b.label,
968
- action: b.action,
969
- priority: b.priority ?? getDefaultPriority(b.match)
970
- }));
971
- const serialized = hints.map((h) => `${h.label}:${h.action}:${h.priority}`).join("|");
972
- useEffect(() => {
973
- if (serialized !== hintsRef.current) {
974
- hintsRef.current = serialized;
975
- ctx.register(id, hints);
976
- }
977
- return () => ctx.unregister(id);
978
- }, [id, serialized]);
979
- useInput((input, key) => {
980
- for (const binding of bindings) if ((Array.isArray(binding.match) ? binding.match : [binding.match]).some((m) => matchesKey(m, input, key))) {
981
- binding.handler(input, key);
982
- return;
983
- }
984
- });
985
- }
986
- //#endregion
987
- //#region src/ui/tui/primitives/PickerMenu.tsx
988
- /**
989
- * PickerMenu — Single and multi select.
990
- * Single mode: custom renderer with small triangle indicator.
991
- * Multi mode: checkbox glyphs with space to toggle.
992
- *
993
- * Key bindings are declared via useKeyBindings, which auto-registers
994
- * hints in the KeyboardHintsBar.
995
- */
996
- /**
997
- * Step through a column's options in `dir`, wrapping, until an enabled
998
- * option is found. Returns `from` unchanged if the column is entirely
999
- * disabled.
1000
- */
1001
- function stepEnabled(options, rows, from, dir) {
1002
- const colStart = Math.floor(from / rows) * rows;
1003
- const colLen = Math.min(rows, options.length - colStart);
1004
- let row = from % rows;
1005
- for (let i = 0; i < colLen; i++) {
1006
- row = (row + dir + colLen) % colLen;
1007
- const idx = colStart + row;
1008
- if (!options[idx]?.disabled) return idx;
1009
- }
1010
- return from;
1011
- }
1012
- /** Index of the first enabled option, for the initial focus. */
1013
- function firstEnabled(options) {
1014
- const idx = options.findIndex((o) => !o.disabled);
1015
- return idx === -1 ? 0 : idx;
1016
- }
1017
- const PickerMenu = ({ message, options, mode = "single", centered = false, columns = 1, optionMarginBottom = 0, onSelect }) => {
1018
- if (mode === "multi") return /* @__PURE__ */ jsx(MultiPickerMenu, {
1019
- message,
1020
- options,
1021
- centered,
1022
- columns,
1023
- optionMarginBottom,
1024
- onSelect
1025
- });
1026
- return /* @__PURE__ */ jsx(SinglePickerMenu, {
1027
- message,
1028
- options,
1029
- centered,
1030
- columns,
1031
- optionMarginBottom,
1032
- onSelect
1033
- });
1034
- };
1035
- /** Custom single-select with triangle indicator and accent highlight. */
1036
- const SinglePickerMenu = ({ message, options, centered = false, columns = 1, optionMarginBottom = 0, onSelect }) => {
1037
- const [focused, setFocused] = useState(() => firstEnabled(options));
1038
- const rows = Math.ceil(options.length / columns);
1039
- useEffect(() => {
1040
- if (focused >= options.length || options[focused]?.disabled) setFocused(firstEnabled(options));
1041
- }, [options, focused]);
1042
- const bindings = [{
1043
- match: ["upArrow", "downArrow"],
1044
- label: "↑↓",
1045
- action: "navigate",
1046
- handler: (_input, key) => {
1047
- if (key.upArrow) setFocused(stepEnabled(options, rows, focused, -1));
1048
- if (key.downArrow) setFocused(stepEnabled(options, rows, focused, 1));
1049
- }
1050
- }, {
1051
- match: "return",
1052
- label: "enter",
1053
- action: "select",
1054
- handler: () => {
1055
- const selected = options[focused];
1056
- if (selected && !selected.disabled) onSelect(selected.value);
1057
- }
1058
- }];
1059
- if (columns > 1) bindings.splice(1, 0, {
1060
- match: ["leftArrow", "rightArrow"],
1061
- label: "←→",
1062
- action: "navigate",
1063
- handler: (_input, key) => {
1064
- const col = Math.floor(focused / rows);
1065
- const row = focused % rows;
1066
- let next = focused;
1067
- if (key.leftArrow) {
1068
- const prevCol = col > 0 ? col - 1 : columns - 1;
1069
- next = Math.min(prevCol * rows + row, options.length - 1);
1070
- }
1071
- if (key.rightArrow) {
1072
- const nextCol = col < columns - 1 ? col + 1 : 0;
1073
- next = Math.min(nextCol * rows + row, options.length - 1);
1074
- }
1075
- if (options[next]?.disabled) next = stepEnabled(options, rows, next, 1);
1076
- setFocused(next);
1077
- }
1078
- });
1079
- useKeyBindings("single-picker", bindings);
1080
- const columnArrays = [];
1081
- for (let c = 0; c < columns; c++) columnArrays.push(options.slice(c * rows, c * rows + rows));
1082
- return /* @__PURE__ */ jsxs(Box, {
1083
- flexDirection: "column",
1084
- alignItems: centered ? "center" : void 0,
1085
- children: [/* @__PURE__ */ jsx(PromptLabel, { message }), /* @__PURE__ */ jsx(Box, {
1086
- flexDirection: "row",
1087
- gap: 4,
1088
- children: columnArrays.map((colOpts, colIdx) => /* @__PURE__ */ jsx(Box, {
1089
- flexDirection: "column",
1090
- children: colOpts.map((opt, rowIdx) => {
1091
- const flatIdx = colIdx * rows + rowIdx;
1092
- const isFocused = flatIdx === focused;
1093
- const label = opt.hint ? `${opt.label} (${opt.hint})` : opt.label;
1094
- return /* @__PURE__ */ jsxs(Box, {
1095
- gap: 1,
1096
- marginBottom: optionMarginBottom,
1097
- children: [
1098
- /* @__PURE__ */ jsx(Text, {
1099
- color: isFocused ? Colors.accent : void 0,
1100
- dimColor: !isFocused,
1101
- children: isFocused ? Icons.triangleSmallRight : " "
1102
- }),
1103
- opt.icon && /* @__PURE__ */ jsx(Text, {
1104
- color: opt.icon.color,
1105
- children: opt.icon.glyph
1106
- }),
1107
- /* @__PURE__ */ jsx(Text, {
1108
- color: opt.disabled ? Colors.muted : isFocused ? Colors.accent : void 0,
1109
- bold: isFocused && !opt.disabled,
1110
- dimColor: !isFocused || opt.disabled,
1111
- children: label
1112
- })
1113
- ]
1114
- }, flatIdx);
1115
- })
1116
- }, colIdx))
1117
- })]
1118
- });
1119
- };
1120
- /** Custom multi-select with checkbox glyphs and accent highlight. */
1121
- const MultiPickerMenu = ({ message, options, centered = false, columns = 1, optionMarginBottom = 0, onSelect }) => {
1122
- const [focused, setFocused] = useState(() => firstEnabled(options));
1123
- const [selected, setSelected] = useState(/* @__PURE__ */ new Set());
1124
- const rows = Math.ceil(options.length / columns);
1125
- useEffect(() => {
1126
- if (focused >= options.length || options[focused]?.disabled) setFocused(firstEnabled(options));
1127
- }, [options, focused]);
1128
- const bindings = [
1129
- {
1130
- match: ["upArrow", "downArrow"],
1131
- label: "↑↓",
1132
- action: "navigate",
1133
- handler: (_input, key) => {
1134
- if (key.upArrow) setFocused(stepEnabled(options, rows, focused, -1));
1135
- if (key.downArrow) setFocused(stepEnabled(options, rows, focused, 1));
1136
- }
1137
- },
1138
- {
1139
- match: "space",
1140
- label: "space",
1141
- action: "toggle",
1142
- handler: () => {
1143
- if (options[focused]?.disabled) return;
1144
- setSelected((prev) => {
1145
- const next = new Set(prev);
1146
- if (next.has(focused)) {
1147
- next.delete(focused);
1148
- return next;
1149
- }
1150
- if (options[focused]?.exclusive) return new Set([focused]);
1151
- for (const i of next) if (options[i]?.exclusive) next.delete(i);
1152
- next.add(focused);
1153
- return next;
1154
- });
1155
- }
1156
- },
1157
- {
1158
- match: "return",
1159
- label: "enter",
1160
- action: "confirm",
1161
- handler: () => {
1162
- if (selected.size === 0) {
1163
- const hovered = options[focused];
1164
- if (hovered && !hovered.disabled) onSelect(hovered.value);
1165
- } else onSelect([...selected].sort().map((i) => options[i].value));
1166
- }
1167
- }
1168
- ];
1169
- if (columns > 1) bindings.splice(1, 0, {
1170
- match: ["leftArrow", "rightArrow"],
1171
- label: "←→",
1172
- action: "navigate",
1173
- handler: (_input, key) => {
1174
- const col = Math.floor(focused / rows);
1175
- const row = focused % rows;
1176
- let next = focused;
1177
- if (key.leftArrow) {
1178
- const prevCol = col > 0 ? col - 1 : columns - 1;
1179
- next = Math.min(prevCol * rows + row, options.length - 1);
1180
- }
1181
- if (key.rightArrow) {
1182
- const nextCol = col < columns - 1 ? col + 1 : 0;
1183
- next = Math.min(nextCol * rows + row, options.length - 1);
1184
- }
1185
- if (options[next]?.disabled) next = stepEnabled(options, rows, next, 1);
1186
- setFocused(next);
1187
- }
1188
- });
1189
- useKeyBindings("multi-picker", bindings);
1190
- const columnArrays = [];
1191
- for (let c = 0; c < columns; c++) columnArrays.push(options.slice(c * rows, c * rows + rows));
1192
- return /* @__PURE__ */ jsxs(Box, {
1193
- flexDirection: "column",
1194
- alignItems: centered ? "center" : void 0,
1195
- children: [/* @__PURE__ */ jsx(PromptLabel, { message }), /* @__PURE__ */ jsx(Box, {
1196
- flexDirection: "row",
1197
- gap: 4,
1198
- marginLeft: centered ? 0 : 2,
1199
- marginTop: 1,
1200
- children: columnArrays.map((colOpts, colIdx) => /* @__PURE__ */ jsx(Box, {
1201
- flexDirection: "column",
1202
- children: colOpts.map((opt, rowIdx) => {
1203
- const flatIdx = colIdx * rows + rowIdx;
1204
- const isFocused = flatIdx === focused;
1205
- const isSelected = selected.has(flatIdx);
1206
- const label = opt.hint ? `${opt.label} (${opt.hint})` : opt.label;
1207
- const checkbox = isSelected ? Icons.squareFilled : Icons.squareOpen;
1208
- return /* @__PURE__ */ jsxs(Box, {
1209
- gap: 1,
1210
- marginBottom: optionMarginBottom,
1211
- children: [
1212
- /* @__PURE__ */ jsx(Text, {
1213
- color: isSelected ? "white" : Colors.muted,
1214
- dimColor: !isFocused && !isSelected,
1215
- children: checkbox
1216
- }),
1217
- opt.icon && /* @__PURE__ */ jsx(Text, {
1218
- color: opt.icon.color,
1219
- children: opt.icon.glyph
1220
- }),
1221
- /* @__PURE__ */ jsx(Text, {
1222
- color: opt.disabled ? Colors.muted : isFocused ? Colors.accent : void 0,
1223
- bold: isFocused && !opt.disabled,
1224
- dimColor: !isFocused || opt.disabled,
1225
- children: label
1226
- })
1227
- ]
1228
- }, flatIdx);
1229
- })
1230
- }, colIdx))
1231
- })]
1232
- });
1233
- };
1234
- //#endregion
1235
841
  //#region src/ui/tui/hooks/useStdoutDimensions.ts
1236
842
  /**
1237
843
  * useStdoutDimensions — Returns [columns, rows] and re-renders on terminal resize.
@@ -4114,7 +3720,7 @@ const McpSuggestedPromptsScreen = ({ store, services }) => {
4114
3720
  const kit = getRolePrompts(session.roleAtOrganization, session.integration);
4115
3721
  const crossSell = useMemo(() => getCrossSellPrompts(session.roleAtOrganization), [session.roleAtOrganization]);
4116
3722
  const greeting = useMemo(() => getRoleGreeting(session.roleAtOrganization), [session.roleAtOrganization]);
4117
- const [phase, setPhase] = useState(() => store.session.credentials ? "choose" : "authenticating");
3723
+ const [phase, setPhase] = useState("choose");
4118
3724
  const [loginError, setLoginError] = useState(null);
4119
3725
  const startedTutorialRef = useRef(false);
4120
3726
  const [runningPrompt, setRunningPrompt] = useState(null);
@@ -4156,28 +3762,6 @@ const McpSuggestedPromptsScreen = ({ store, services }) => {
4156
3762
  services,
4157
3763
  store
4158
3764
  ]);
4159
- const credentials = session.credentials;
4160
- const slackConnected = session.slackConnected;
4161
- useEffect(() => {
4162
- if (!credentials || slackConnected !== null) return;
4163
- let cancelled = false;
4164
- const controller = new AbortController();
4165
- services.checkSlackConnected(credentials, controller.signal).then((connected) => {
4166
- if (!cancelled) store.setSlackConnected(connected);
4167
- }).catch((err) => {
4168
- if (cancelled) return;
4169
- analytics.captureException(err instanceof Error ? err : new Error(String(err)), { step: "slack_connected_check" });
4170
- });
4171
- return () => {
4172
- cancelled = true;
4173
- controller.abort();
4174
- };
4175
- }, [
4176
- credentials,
4177
- slackConnected,
4178
- services,
4179
- store
4180
- ]);
4181
3765
  useEffect(() => {
4182
3766
  if (phase !== "running") return;
4183
3767
  if (!runningPrompt) return;
@@ -4265,9 +3849,6 @@ const McpSuggestedPromptsScreen = ({ store, services }) => {
4265
3849
  analytics.wizardCapture("mcp suggested prompts choose", { choice: "login" });
4266
3850
  startedTutorialRef.current = true;
4267
3851
  setPhase(session.credentials ? "greeting" : "authenticating");
4268
- } else if (choice === "connect-slack") {
4269
- analytics.wizardCapture("mcp suggested prompts choose", { choice: "connect-slack" });
4270
- openTrackedLink(getSlackAppCard().setupUrl, "mcp-prompts-slack-setup");
4271
3852
  } else {
4272
3853
  analytics.wizardCapture("mcp suggested prompts choose", { choice: "exit" });
4273
3854
  enterGoodbye();
@@ -4340,7 +3921,6 @@ const McpSuggestedPromptsScreen = ({ store, services }) => {
4340
3921
  children: [
4341
3922
  phase === "choose" && /* @__PURE__ */ jsx(ChoosePhase, {
4342
3923
  error: loginError,
4343
- slackConnected,
4344
3924
  onSelect: handleChoice
4345
3925
  }),
4346
3926
  phase === "authenticating" && /* @__PURE__ */ jsx(AuthenticatingPhase, { loginUrl: session.loginUrl }),
@@ -4403,7 +3983,7 @@ const McpSuggestedPromptsScreen = ({ store, services }) => {
4403
3983
  })
4404
3984
  });
4405
3985
  };
4406
- const ChoosePhase = ({ error, slackConnected, onSelect }) => {
3986
+ const ChoosePhase = ({ error, onSelect }) => {
4407
3987
  return /* @__PURE__ */ jsxs(Box, {
4408
3988
  flexDirection: "column",
4409
3989
  children: [
@@ -4442,57 +4022,18 @@ const ChoosePhase = ({ error, slackConnected, onSelect }) => {
4442
4022
  }), " And lots more..."] })
4443
4023
  ]
4444
4024
  }),
4445
- /* @__PURE__ */ jsx(Box, {
4446
- marginTop: 1,
4447
- flexDirection: "column",
4448
- children: slackConnected ? /* @__PURE__ */ jsxs(Text, { children: [
4449
- /* @__PURE__ */ jsx(Text, {
4450
- color: Colors.success,
4451
- children: Icons.check
4452
- }),
4453
- " Slack is connected — analyze data and ship product changes there by tagging",
4454
- " ",
4455
- /* @__PURE__ */ jsx(Text, {
4456
- bold: true,
4457
- children: "@PostHog"
4458
- }),
4459
- "."
4460
- ] }) : /* @__PURE__ */ jsxs(Text, { children: [
4461
- "You can also connect PostHog to Slack, so you can analyze data and ship product changes there by tagging ",
4462
- /* @__PURE__ */ jsx(Text, {
4463
- bold: true,
4464
- children: "@PostHog"
4465
- }),
4466
- "."
4467
- ] })
4468
- }),
4469
4025
  /* @__PURE__ */ jsx(Box, {
4470
4026
  marginTop: 1,
4471
4027
  children: /* @__PURE__ */ jsx(Text, { children: "Want a live demo using real data from your project?" })
4472
4028
  }),
4473
4029
  /* @__PURE__ */ jsx(Box, { children: /* @__PURE__ */ jsx(PickerMenu, {
4474
- options: [
4475
- {
4476
- label: "Start MCP tutorial",
4477
- value: "login"
4478
- },
4479
- slackConnected ? {
4480
- label: "Already connected to Slack",
4481
- value: "connect-slack",
4482
- icon: {
4483
- glyph: Icons.check,
4484
- color: Colors.success
4485
- },
4486
- disabled: true
4487
- } : {
4488
- label: "Connect Slack now",
4489
- value: "connect-slack"
4490
- },
4491
- {
4492
- label: "Exit",
4493
- value: "exit"
4494
- }
4495
- ],
4030
+ options: [{
4031
+ label: "Start MCP tutorial",
4032
+ value: "login"
4033
+ }, {
4034
+ label: "Exit",
4035
+ value: "exit"
4036
+ }],
4496
4037
  onSelect
4497
4038
  }) }),
4498
4039
  error && /* @__PURE__ */ jsx(Box, {
@@ -5542,176 +5083,6 @@ const AUDIT_AREA_SLIDES = [
5542
5083
  }
5543
5084
  ];
5544
5085
  //#endregion
5545
- //#region src/ui/tui/screens/audit-3000/slides/eventQuality.tsx
5546
- const EventQualityVisual = () => /* @__PURE__ */ jsxs(VisualBox, { children: [
5547
- /* @__PURE__ */ jsxs(Text, { children: [/* @__PURE__ */ jsx(Text, {
5548
- color: "green",
5549
- children: "event_clicked "
5550
- }), /* @__PURE__ */ jsx(Text, {
5551
- color: "green",
5552
- children: "✓"
5553
- })] }),
5554
- /* @__PURE__ */ jsxs(Text, { children: [/* @__PURE__ */ jsx(Text, {
5555
- color: "yellow",
5556
- children: "eventClicked "
5557
- }), /* @__PURE__ */ jsx(Text, {
5558
- color: "yellow",
5559
- children: "~ duplicate?"
5560
- })] }),
5561
- /* @__PURE__ */ jsxs(Text, { children: [/* @__PURE__ */ jsx(Text, {
5562
- color: "yellow",
5563
- children: "click_event "
5564
- }), /* @__PURE__ */ jsx(Text, {
5565
- color: "yellow",
5566
- children: "~ duplicate?"
5567
- })] }),
5568
- /* @__PURE__ */ jsxs(Text, { children: [/* @__PURE__ */ jsx(Text, {
5569
- color: "red",
5570
- children: "big_kitchen_sink "
5571
- }), /* @__PURE__ */ jsx(Text, {
5572
- color: "red",
5573
- children: "✗ 22 props"
5574
- })] })
5575
- ] });
5576
- const EventQualitySlide = {
5577
- area: "Event Quality",
5578
- intro: [
5579
- "LEVEL 5: EVENT QUALITY. The capture call-sites are clean. The events themselves are the real boss fight.",
5580
- "Scanning for: naming inconsistencies, semantic duplicates, kitchen-sink event payloads, and (if your PostHog project is linked) which captured events actually drive insights and dashboards.",
5581
- "4 subagents fan out in parallel. The ticker shows them clearing checks live."
5582
- ],
5583
- visual: /* @__PURE__ */ jsx(EventQualityVisual, {}),
5584
- docsUrl: "https://posthog.com/docs/product-analytics/best-practices"
5585
- };
5586
- //#endregion
5587
- //#region src/ui/tui/screens/audit-3000/slides/featureFlags.tsx
5588
- const FeatureFlagsVisual = () => /* @__PURE__ */ jsxs(VisualBox, { children: [
5589
- /* @__PURE__ */ jsxs(Text, { children: [
5590
- /* @__PURE__ */ jsx(Text, {
5591
- color: "red",
5592
- children: "new-checkout-v2 "
5593
- }),
5594
- /* @__PURE__ */ jsx(Text, {
5595
- dimColor: true,
5596
- children: "no code refs "
5597
- }),
5598
- /* @__PURE__ */ jsx(Text, {
5599
- color: "red",
5600
- children: "DROP"
5601
- })
5602
- ] }),
5603
- /* @__PURE__ */ jsxs(Text, { children: [
5604
- /* @__PURE__ */ jsx(Text, {
5605
- color: "yellow",
5606
- children: "beta-dashboard "
5607
- }),
5608
- /* @__PURE__ */ jsx(Text, {
5609
- dimColor: true,
5610
- children: "1 ref, 100% on "
5611
- }),
5612
- /* @__PURE__ */ jsx(Text, {
5613
- color: "yellow",
5614
- children: "REVIEW"
5615
- })
5616
- ] }),
5617
- /* @__PURE__ */ jsxs(Text, { children: [
5618
- /* @__PURE__ */ jsx(Text, {
5619
- color: "green",
5620
- children: "killswitch-payments"
5621
- }),
5622
- /* @__PURE__ */ jsx(Text, {
5623
- dimColor: true,
5624
- children: "live experiment"
5625
- }),
5626
- /* @__PURE__ */ jsx(Text, {
5627
- color: "green",
5628
- children: "KEEP"
5629
- })
5630
- ] })
5631
- ] });
5632
- const FeatureFlagsSlide = {
5633
- area: "Feature Flags",
5634
- intro: [
5635
- "LEVEL 6: STALE FLAGS. Old flags add evaluation overhead and confuse the next engineer who wonders if a flag is still live.",
5636
- "Cross-referencing PostHog's stale-flag classification against your source tree. Each flag scored: safe-to-disable, needs-review, or unknown.",
5637
- "The final report ships with a copy-paste cleanup prompt. We never touch a flag."
5638
- ],
5639
- visual: /* @__PURE__ */ jsx(FeatureFlagsVisual, {}),
5640
- docsUrl: "https://posthog.com/docs/feature-flags"
5641
- };
5642
- //#endregion
5643
- //#region src/ui/tui/screens/audit-3000/slides/expansion.tsx
5644
- const ExpansionVisual = () => /* @__PURE__ */ jsxs(VisualBox, { children: [
5645
- /* @__PURE__ */ jsxs(Text, { children: [/* @__PURE__ */ jsx(Text, {
5646
- color: "cyan",
5647
- children: "product analytics "
5648
- }), /* @__PURE__ */ jsx(Text, {
5649
- color: "green",
5650
- children: "■■■■■"
5651
- })] }),
5652
- /* @__PURE__ */ jsxs(Text, { children: [
5653
- /* @__PURE__ */ jsx(Text, {
5654
- color: "cyan",
5655
- children: "error tracking "
5656
- }),
5657
- /* @__PURE__ */ jsx(Text, {
5658
- color: "red",
5659
- children: "□□□□□"
5660
- }),
5661
- /* @__PURE__ */ jsx(Text, {
5662
- dimColor: true,
5663
- children: " sentry detected"
5664
- })
5665
- ] }),
5666
- /* @__PURE__ */ jsxs(Text, { children: [
5667
- /* @__PURE__ */ jsx(Text, {
5668
- color: "cyan",
5669
- children: "session replay "
5670
- }),
5671
- /* @__PURE__ */ jsx(Text, {
5672
- color: "yellow",
5673
- children: "■■□□□"
5674
- }),
5675
- /* @__PURE__ */ jsx(Text, {
5676
- dimColor: true,
5677
- children: " partial"
5678
- })
5679
- ] }),
5680
- /* @__PURE__ */ jsxs(Text, { children: [
5681
- /* @__PURE__ */ jsx(Text, {
5682
- color: "cyan",
5683
- children: "llm observability "
5684
- }),
5685
- /* @__PURE__ */ jsx(Text, {
5686
- color: "red",
5687
- children: "□□□□□"
5688
- }),
5689
- /* @__PURE__ */ jsx(Text, {
5690
- dimColor: true,
5691
- children: " greenfield"
5692
- })
5693
- ] })
5694
- ] });
5695
- //#endregion
5696
- //#region src/ui/tui/screens/audit-3000/slides/index.ts
5697
- const AUDIT_3000_AREA_SLIDES = [
5698
- InstallationSlide,
5699
- IdentificationSlide,
5700
- EventCaptureSlide,
5701
- EventQualitySlide,
5702
- FeatureFlagsSlide,
5703
- {
5704
- area: "Use Case: Expansion",
5705
- intro: [
5706
- "BONUS ROUND: EXPANSION. You might be paying for tools PostHog covers natively.",
5707
- "Scanning for competitive SDKs (Sentry, LaunchDarkly, Mixpanel, Datadog, OpenTelemetry, GA4) and PostHog coverage gaps across 8 product surfaces.",
5708
- "8 subagents in two waves of 4. Each one returns one of: cross-sell, greenfield, gap, or pass."
5709
- ],
5710
- visual: /* @__PURE__ */ jsx(ExpansionVisual, {}),
5711
- docsUrl: "https://posthog.com/docs"
5712
- }
5713
- ];
5714
- //#endregion
5715
5086
  //#region src/ui/tui/screens/SlackConnectScreen.tsx
5716
5087
  /**
5717
5088
  * SlackConnectScreen — the dedicated "Connect Slack" step shown after the
@@ -5731,9 +5102,11 @@ const AUDIT_3000_AREA_SLIDES = [
5731
5102
  * "Skip" / "Done" / esc dismiss the step (`slackStepDismissed`) and let
5732
5103
  * the router advance to exit.
5733
5104
  *
5734
- * The mcp and integration flows arrive here already authenticated. In the
5735
- * standalone `wizard slack` flow the program's `onInit` runs the OAuth
5736
- * while this screen renders the auth-wait state.
5105
+ * The mcp and integration flows arrive here already authenticated. The
5106
+ * standalone `wizard slack` flow lands without credentials and only
5107
+ * triggers OAuth when the user explicitly picks "Open Slack setup" —
5108
+ * once authed, the connected-state poll lets the screen flip to the
5109
+ * "Slack connected" copy without nagging users who already have it.
5737
5110
  */
5738
5111
  const POLL_INTERVAL_MS = 3e3;
5739
5112
  const SlackConnectScreen = ({ store }) => {
@@ -5743,10 +5116,16 @@ const SlackConnectScreen = ({ store }) => {
5743
5116
  const setupUrl = withUtm(slack.setupUrl, "slack-connect-setup");
5744
5117
  const learnMoreUrl = withUtm(slack.learnMoreUrl, "slack-connect-learn-more");
5745
5118
  const credentials = store.session.credentials;
5746
- const awaitingLogin = store.router.activeProgram === Program.SlackConnect && !credentials;
5747
5119
  const connectedState = store.session.slackConnected;
5748
5120
  const connected = connectedState === true;
5749
- const known = connectedState !== null || !credentials && !awaitingLogin;
5121
+ const [phase, setPhase] = useState("nudge");
5122
+ const [loginError, setLoginError] = useState(null);
5123
+ const [setupOpened, setSetupOpened] = useState(false);
5124
+ const openSlackSetup = () => {
5125
+ openTrackedLink(setupUrl, "slack-connect-setup");
5126
+ setSetupOpened(true);
5127
+ };
5128
+ const known = connectedState !== null;
5750
5129
  const impressionFired = useRef(false);
5751
5130
  useEffect(() => {
5752
5131
  if (!known || impressionFired.current) return;
@@ -5760,6 +5139,12 @@ const SlackConnectScreen = ({ store }) => {
5760
5139
  connected,
5761
5140
  role
5762
5141
  ]);
5142
+ const nudgeImpressionFired = useRef(false);
5143
+ useEffect(() => {
5144
+ if (credentials || nudgeImpressionFired.current) return;
5145
+ nudgeImpressionFired.current = true;
5146
+ analytics.wizardCapture("slack connect nudge shown", { role });
5147
+ }, [credentials, role]);
5763
5148
  useEffect(() => {
5764
5149
  if (!credentials || connected) return;
5765
5150
  let cancelled = false;
@@ -5793,27 +5178,83 @@ const SlackConnectScreen = ({ store }) => {
5793
5178
  store
5794
5179
  ]);
5795
5180
  const dismiss = () => {
5796
- analytics.wizardCapture(connected ? "slack connect done" : "slack connect skipped", {
5181
+ if (connected) analytics.wizardCapture("slack connect done", { role });
5182
+ else analytics.wizardCapture("slack connect skipped", {
5797
5183
  role,
5798
- connected
5184
+ connection_state: credentials ? "not_connected" : "unknown"
5799
5185
  });
5800
5186
  store.setSlackStepDismissed();
5801
5187
  };
5802
5188
  const handleSelect = (value) => {
5803
5189
  if ((Array.isArray(value) ? value[0] : value) === "open") {
5804
5190
  analytics.wizardCapture("slack connect opened", { role });
5805
- openTrackedLink(setupUrl, "slack-connect-setup");
5191
+ setLoginError(null);
5192
+ if (credentials) {
5193
+ openSlackSetup();
5194
+ return;
5195
+ }
5196
+ setPhase("authenticating");
5806
5197
  return;
5807
5198
  }
5808
5199
  dismiss();
5809
5200
  };
5201
+ useEffect(() => {
5202
+ if (phase !== "authenticating") return;
5203
+ let cancelled = false;
5204
+ (async () => {
5205
+ try {
5206
+ const data = await getOrAskForProjectData({
5207
+ signup: false,
5208
+ ci: false,
5209
+ apiKey: void 0,
5210
+ projectId: void 0,
5211
+ programId: Program.SlackConnect
5212
+ });
5213
+ if (cancelled) return;
5214
+ store.setCredentials({
5215
+ accessToken: data.accessToken,
5216
+ projectApiKey: data.projectApiKey,
5217
+ host: data.host,
5218
+ projectId: data.projectId
5219
+ });
5220
+ store.setRoleAtOrganization(data.roleAtOrganization);
5221
+ store.setApiUser(data.user);
5222
+ store.setLoginUrl(null);
5223
+ openSlackSetup();
5224
+ setPhase("nudge");
5225
+ } catch (err) {
5226
+ if (cancelled) return;
5227
+ const message = err instanceof Error ? err.message : String(err);
5228
+ logToFile(`[SlackConnectScreen] login failed: ${message}`);
5229
+ analytics.captureException(err instanceof Error ? err : new Error(String(err)), { step: "slack_connect_login" });
5230
+ store.setLoginUrl(null);
5231
+ setLoginError(message);
5232
+ setPhase("nudge");
5233
+ }
5234
+ })();
5235
+ return () => {
5236
+ cancelled = true;
5237
+ };
5238
+ }, [
5239
+ phase,
5240
+ role,
5241
+ setupUrl,
5242
+ store
5243
+ ]);
5810
5244
  useKeyBindings("slack-connect", [{
5811
5245
  match: "escape",
5812
5246
  label: "esc",
5813
- action: connected ? "done" : "skip",
5814
- handler: () => dismiss()
5247
+ action: phase === "authenticating" ? "cancel" : connected ? "done" : "skip",
5248
+ handler: () => {
5249
+ if (phase === "authenticating") {
5250
+ store.setLoginUrl(null);
5251
+ setPhase("nudge");
5252
+ return;
5253
+ }
5254
+ dismiss();
5255
+ }
5815
5256
  }]);
5816
- if (awaitingLogin) return /* @__PURE__ */ jsxs(Box, {
5257
+ if (phase === "authenticating") return /* @__PURE__ */ jsxs(Box, {
5817
5258
  flexDirection: "column",
5818
5259
  flexGrow: 1,
5819
5260
  marginTop: 1,
@@ -5839,6 +5280,7 @@ const SlackConnectScreen = ({ store }) => {
5839
5280
  marginTop: 1,
5840
5281
  children: /* @__PURE__ */ jsx(LoadingBox, { message: "Checking for an existing Slack connection..." })
5841
5282
  });
5283
+ const awaitingBrowser = setupOpened && !connected;
5842
5284
  return /* @__PURE__ */ jsx(Box, {
5843
5285
  flexDirection: "column",
5844
5286
  flexGrow: 1,
@@ -5850,6 +5292,10 @@ const SlackConnectScreen = ({ store }) => {
5850
5292
  bold: true,
5851
5293
  color: Colors.success,
5852
5294
  children: [Icons.check, " Slack connected"]
5295
+ }) : awaitingBrowser ? /* @__PURE__ */ jsx(Text, {
5296
+ bold: true,
5297
+ color: Colors.accent,
5298
+ children: "Finish connecting Slack"
5853
5299
  }) : /* @__PURE__ */ jsx(Text, {
5854
5300
  bold: true,
5855
5301
  color: Colors.accent,
@@ -5857,7 +5303,7 @@ const SlackConnectScreen = ({ store }) => {
5857
5303
  }),
5858
5304
  /* @__PURE__ */ jsx(Box, {
5859
5305
  marginTop: 1,
5860
- children: /* @__PURE__ */ jsx(Text, { children: connected ? "Slack is connected — here's what you can do:" : slack.pitch })
5306
+ children: /* @__PURE__ */ jsx(Text, { children: connected ? "Slack is connected — here's what you can do:" : awaitingBrowser ? "We've opened PostHog's Slack setup page in your browser. Authorize the Slack app there — we'll detect the connection automatically and continue." : slack.pitch })
5861
5307
  }),
5862
5308
  /* @__PURE__ */ jsx(Box, {
5863
5309
  marginTop: 1,
@@ -5875,7 +5321,7 @@ const SlackConnectScreen = ({ store }) => {
5875
5321
  flexDirection: "column",
5876
5322
  children: [!connected && /* @__PURE__ */ jsxs(Text, {
5877
5323
  dimColor: true,
5878
- children: ["Connect it: ", /* @__PURE__ */ jsx(Text, {
5324
+ children: [awaitingBrowser ? "Setup page: " : "Connect it: ", /* @__PURE__ */ jsx(Text, {
5879
5325
  color: "cyan",
5880
5326
  children: setupUrl
5881
5327
  })]
@@ -5893,6 +5339,12 @@ const SlackConnectScreen = ({ store }) => {
5893
5339
  options: connected ? [{
5894
5340
  label: "Done",
5895
5341
  value: "skip"
5342
+ }] : awaitingBrowser ? [{
5343
+ label: "Re-open Slack setup",
5344
+ value: "open"
5345
+ }, {
5346
+ label: "Skip / Continue",
5347
+ value: "skip"
5896
5348
  }] : [{
5897
5349
  label: "Open Slack setup",
5898
5350
  value: "open"
@@ -5902,6 +5354,17 @@ const SlackConnectScreen = ({ store }) => {
5902
5354
  }],
5903
5355
  onSelect: handleSelect
5904
5356
  })
5357
+ }),
5358
+ loginError && /* @__PURE__ */ jsx(Box, {
5359
+ marginTop: 1,
5360
+ children: /* @__PURE__ */ jsxs(Text, {
5361
+ color: "red",
5362
+ children: [
5363
+ "Login failed: ",
5364
+ loginError,
5365
+ ". Try again or skip."
5366
+ ]
5367
+ })
5905
5368
  })
5906
5369
  ]
5907
5370
  })
@@ -5942,6 +5405,28 @@ const OutroScreen = ({ store }) => {
5942
5405
  bold: true,
5943
5406
  children: ["✔ ", outroData.message || "Done!"]
5944
5407
  }),
5408
+ outroData.dashboardUrl && /* @__PURE__ */ jsx(Box, {
5409
+ marginTop: 1,
5410
+ children: /* @__PURE__ */ jsxs(Text, { children: [
5411
+ "Dashboard:",
5412
+ " ",
5413
+ /* @__PURE__ */ jsx(Text, {
5414
+ color: "cyan",
5415
+ children: withUtm(outroData.dashboardUrl, "outro-dashboard")
5416
+ })
5417
+ ] })
5418
+ }),
5419
+ outroData.notebookUrl && /* @__PURE__ */ jsx(Box, {
5420
+ marginTop: 1,
5421
+ children: /* @__PURE__ */ jsxs(Text, { children: [
5422
+ "Notebook:",
5423
+ " ",
5424
+ /* @__PURE__ */ jsx(Text, {
5425
+ color: "cyan",
5426
+ children: withUtm(outroData.notebookUrl, "outro-notebook")
5427
+ })
5428
+ ] })
5429
+ }),
5945
5430
  outroData.body && /* @__PURE__ */ jsx(Box, {
5946
5431
  marginTop: 1,
5947
5432
  children: /* @__PURE__ */ jsx(Text, {
@@ -5988,28 +5473,6 @@ const OutroScreen = ({ store }) => {
5988
5473
  })
5989
5474
  ] }, event.name))]
5990
5475
  }),
5991
- outroData.dashboardUrl && /* @__PURE__ */ jsx(Box, {
5992
- marginTop: 1,
5993
- children: /* @__PURE__ */ jsxs(Text, { children: [
5994
- "We've also made you a dashboard:",
5995
- " ",
5996
- /* @__PURE__ */ jsx(Text, {
5997
- color: "cyan",
5998
- children: withUtm(outroData.dashboardUrl, "outro-dashboard")
5999
- })
6000
- ] })
6001
- }),
6002
- outroData.notebookUrl && /* @__PURE__ */ jsx(Box, {
6003
- marginTop: 1,
6004
- children: /* @__PURE__ */ jsxs(Text, { children: [
6005
- "And uploaded the report to a PostHog notebook:",
6006
- " ",
6007
- /* @__PURE__ */ jsx(Text, {
6008
- color: "cyan",
6009
- children: withUtm(outroData.notebookUrl, "outro-notebook")
6010
- })
6011
- ] })
6012
- }),
6013
5476
  outroData.docsUrl && /* @__PURE__ */ jsx(Box, {
6014
5477
  marginTop: 1,
6015
5478
  children: /* @__PURE__ */ jsxs(Text, { children: [
@@ -6387,6 +5850,6 @@ const AiOptInRequiredScreen = ({ store }) => {
6387
5850
  });
6388
5851
  };
6389
5852
  //#endregion
6390
- export { useKeyBindings as A, EventPlanViewer as C, GroupedPickerMenu as D, ConfirmationInput as E, WizardStore as F, LoadingBox as M, SplitView as N, useStdoutDimensions as O, CardLayout as P, ScreenContainer as S, ModalOverlay as T, TipsCard as _, SlackConnectScreen as a, HNViewer as b, VisualBox as c, TAILORED_ROLES as d, McpScreen as f, ServiceHealthList as g, SEVERITY_ORDER as h, OutroScreen as i, ProgressList as j, PickerMenu as k, AuditChecksViewer as l, SEVERITY_LABEL as m, SkillSourceInfo as n, AUDIT_3000_AREA_SLIDES as o, IssueTable as p, useSkillEntry as r, AUDIT_AREA_SLIDES as s, AiOptInRequiredScreen as t, McpSuggestedPromptsScreen as u, LearnCard as v, LogViewer as w, TabContainer as x, ContentSequencer as y };
5853
+ export { SplitView as A, LogViewer as C, useStdoutDimensions as D, GroupedPickerMenu as E, WizardStore as M, ProgressList as O, EventPlanViewer as S, ConfirmationInput as T, LearnCard as _, SlackConnectScreen as a, TabContainer as b, AuditChecksViewer as c, McpScreen as d, IssueTable as f, TipsCard as g, ServiceHealthList as h, OutroScreen as i, CardLayout as j, LoadingBox as k, McpSuggestedPromptsScreen as l, SEVERITY_ORDER as m, SkillSourceInfo as n, AUDIT_AREA_SLIDES as o, SEVERITY_LABEL as p, useSkillEntry as r, VisualBox as s, AiOptInRequiredScreen as t, TAILORED_ROLES as u, ContentSequencer as v, ModalOverlay as w, ScreenContainer as x, HNViewer as y };
6391
5854
 
6392
- //# sourceMappingURL=AiOptInRequiredScreen-BOMyYFep.js.map
5855
+ //# sourceMappingURL=AiOptInRequiredScreen-_33FOcVo.js.map