@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.
- package/README.md +61 -2
- package/dist/{AiOptInRequiredScreen-BOMyYFep.js → AiOptInRequiredScreen-_33FOcVo.js} +148 -685
- package/dist/AiOptInRequiredScreen-_33FOcVo.js.map +1 -0
- package/dist/{add-mcp-server-to-clients-BEziI3z9.js → add-mcp-server-to-clients-CfwEQT_z.js} +4 -4
- package/dist/{add-mcp-server-to-clients-BEziI3z9.js.map → add-mcp-server-to-clients-CfwEQT_z.js.map} +1 -1
- package/dist/{agent-interface-DjMPlXl0.js → agent-interface-D1vtN6Wn.js} +6 -7
- package/dist/agent-interface-D1vtN6Wn.js.map +1 -0
- package/dist/{agent-runner-Bv-7z-pQ.js → agent-runner-CBbkS0Ro.js} +8 -8
- package/dist/{agent-runner-Bv-7z-pQ.js.map → agent-runner-CBbkS0Ro.js.map} +1 -1
- package/dist/{analytics-9D4eGgmT.js → analytics-CUr82BDl.js} +11 -2
- package/dist/{analytics-9D4eGgmT.js.map → analytics-CUr82BDl.js.map} +1 -1
- package/dist/{api-Dwd0B-E9.js → api-CI3Z74NG.js} +3 -3
- package/dist/{api-Dwd0B-E9.js.map → api-CI3Z74NG.js.map} +1 -1
- package/dist/bin.js +887 -465
- package/dist/bin.js.map +1 -1
- package/dist/{ci-install-DGXCpvKh.js → ci-install-D_kxNmbJ.js} +5 -5
- package/dist/{ci-install-DGXCpvKh.js.map → ci-install-D_kxNmbJ.js.map} +1 -1
- package/dist/{debug-CgT5MmVB.js → debug-DxA_f5QT.js} +2 -2
- package/dist/{debug-CgT5MmVB.js.map → debug-DxA_f5QT.js.map} +1 -1
- package/dist/{debug-DayHBBST.js → debug-zMvpNYb2.js} +1 -1
- package/dist/{environment-CI2pTYTG.js → environment-CyS37cmM.js} +3 -3
- package/dist/{environment-CI2pTYTG.js.map → environment-CyS37cmM.js.map} +1 -1
- package/dist/{interactive-D52p_opJ.js → interactive-CG6FFqSw.js} +3 -3
- package/dist/{interactive-D52p_opJ.js.map → interactive-CG6FFqSw.js.map} +1 -1
- package/dist/{mcp-prompt-streaming-tdoy9UJ2.js → mcp-prompt-streaming-DQz4FSb1.js} +4 -4
- package/dist/{mcp-prompt-streaming-tdoy9UJ2.js.map → mcp-prompt-streaming-DQz4FSb1.js.map} +1 -1
- package/dist/{non-interactive-6hadW20x.js → non-interactive-DWtHX3ZR.js} +2 -2
- package/dist/{non-interactive-6hadW20x.js.map → non-interactive-DWtHX3ZR.js.map} +1 -1
- package/dist/{package-manager-BI0J5E7t.js → package-manager-BWUS4CP0.js} +2 -2
- package/dist/{package-manager-BI0J5E7t.js.map → package-manager-BWUS4CP0.js.map} +1 -1
- package/dist/{playground-z4A5dHPv.js → playground-D7AhMMF5.js} +9 -20
- package/dist/playground-D7AhMMF5.js.map +1 -0
- package/dist/{posthog-integration-BWbZU9Xq.js → posthog-integration-DexZ2uHU.js} +18 -18
- package/dist/{posthog-integration-BWbZU9Xq.js.map → posthog-integration-DexZ2uHU.js.map} +1 -1
- package/dist/{provisioning-B30Be2NA.js → provisioning-9c-AQbsa.js} +3 -3
- package/dist/{provisioning-B30Be2NA.js.map → provisioning-9c-AQbsa.js.map} +1 -1
- package/dist/{registry-CD_DplSQ.js → registry-CO7JVZyE.js} +4 -4
- package/dist/{registry-CD_DplSQ.js.map → registry-CO7JVZyE.js.map} +1 -1
- package/dist/{setup-utils-Dwgkk8AQ.js → setup-utils-0U-_Md2G.js} +8 -8
- package/dist/{setup-utils-Dwgkk8AQ.js.map → setup-utils-0U-_Md2G.js.map} +1 -1
- package/dist/{start-tui-SLeEzlJs.js → start-tui-WNb3ET14.js} +206 -1205
- package/dist/start-tui-WNb3ET14.js.map +1 -0
- package/dist/{steps-B1gzyRkC.js → steps-BAUXDCC4.js} +6 -6
- package/dist/{steps-B1gzyRkC.js.map → steps-BAUXDCC4.js.map} +1 -1
- package/dist/{telemetry-5rkeTd2_.js → telemetry-ycqCpNPr.js} +3 -3
- package/dist/{telemetry-5rkeTd2_.js.map → telemetry-ycqCpNPr.js.map} +1 -1
- package/dist/{urls-Cb4SI9kf.js → urls-C8aJWvgh.js} +2 -2
- package/dist/{urls-Cb4SI9kf.js.map → urls-C8aJWvgh.js.map} +1 -1
- package/dist/{wizard-abort-DovHQa-j.js → wizard-abort-C6gRLxUE.js} +3 -3
- package/dist/{wizard-abort-DovHQa-j.js.map → wizard-abort-C6gRLxUE.js.map} +1 -1
- package/dist/{wizard-abort-DW2-ZjiS.js → wizard-abort-DWXyJdws.js} +1 -1
- package/package.json +1 -1
- package/dist/AiOptInRequiredScreen-BOMyYFep.js.map +0 -1
- package/dist/agent-interface-DjMPlXl0.js.map +0 -1
- package/dist/playground-z4A5dHPv.js.map +0 -1
- 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-
|
|
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-
|
|
4
|
-
import { i as withUtm, n as openTrackedLink } from "./telemetry-
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
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-
|
|
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-
|
|
10
|
-
import { a as
|
|
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,
|
|
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(
|
|
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,
|
|
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
|
-
|
|
4477
|
-
|
|
4478
|
-
|
|
4479
|
-
|
|
4480
|
-
|
|
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.
|
|
5735
|
-
* standalone `wizard slack` flow
|
|
5736
|
-
*
|
|
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
|
|
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(
|
|
5181
|
+
if (connected) analytics.wizardCapture("slack connect done", { role });
|
|
5182
|
+
else analytics.wizardCapture("slack connect skipped", {
|
|
5797
5183
|
role,
|
|
5798
|
-
|
|
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
|
-
|
|
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: () =>
|
|
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 (
|
|
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 {
|
|
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-
|
|
5855
|
+
//# sourceMappingURL=AiOptInRequiredScreen-_33FOcVo.js.map
|