@posthog/wizard 2.19.0 → 2.20.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +11 -0
- package/dist/{add-mcp-server-to-clients-CjnvTVj0.js → add-mcp-server-to-clients-iV7BuQpD.js} +4 -4
- package/dist/{add-mcp-server-to-clients-CjnvTVj0.js.map → add-mcp-server-to-clients-iV7BuQpD.js.map} +1 -1
- package/dist/{agent-interface-CQU6x4Hj.js → agent-interface-B-LAvrNL.js} +163 -52
- package/dist/agent-interface-B-LAvrNL.js.map +1 -0
- package/dist/{agent-runner-Cj7saDkL.js → agent-runner-w2Qu9M13.js} +10 -9
- package/dist/{agent-runner-Cj7saDkL.js.map → agent-runner-w2Qu9M13.js.map} +1 -1
- package/dist/{analytics-Df-Xb81i.js → analytics-C8lJzXjY.js} +2 -2
- package/dist/{analytics-Df-Xb81i.js.map → analytics-C8lJzXjY.js.map} +1 -1
- package/dist/{api-Dw6_orDE.js → api-eUlUinVy.js} +25 -4
- package/dist/{api-Dw6_orDE.js.map → api-eUlUinVy.js.map} +1 -1
- package/dist/bin.js +74 -47
- package/dist/bin.js.map +1 -1
- package/dist/check-screens.tsx +124 -0
- package/dist/{ci-install-BKAvFfK6.js → ci-install-CSo7Q1pK.js} +4 -4
- package/dist/{ci-install-BKAvFfK6.js.map → ci-install-CSo7Q1pK.js.map} +1 -1
- package/dist/{debug-DnMO6O8O.js → debug-BJu_sS4l.js} +2 -2
- package/dist/{debug-DnMO6O8O.js.map → debug-BJu_sS4l.js.map} +1 -1
- package/dist/{debug-Cp_wNn8i.js → debug-CTViFiF-.js} +1 -1
- package/dist/{environment-Ls0H9ljT.js → environment-Dk_dWk3t.js} +3 -3
- package/dist/{environment-Ls0H9ljT.js.map → environment-Dk_dWk3t.js.map} +1 -1
- package/dist/{interactive-D15byhpc.js → interactive-BS2rIf1v.js} +2 -2
- package/dist/{interactive-D15byhpc.js.map → interactive-BS2rIf1v.js.map} +1 -1
- package/dist/{mcp-prompt-streaming-DQOTQfW1.js → mcp-prompt-streaming-BiMrlLl0.js} +4 -4
- package/dist/{mcp-prompt-streaming-DQOTQfW1.js.map → mcp-prompt-streaming-BiMrlLl0.js.map} +1 -1
- package/dist/{non-interactive-DcFLJtl_.js → non-interactive-C39d_KIp.js} +2 -2
- package/dist/{non-interactive-DcFLJtl_.js.map → non-interactive-C39d_KIp.js.map} +1 -1
- package/dist/{package-manager-DUPgLGpQ.js → package-manager-BfOTvFt-.js} +2 -2
- package/dist/{package-manager-DUPgLGpQ.js.map → package-manager-BfOTvFt-.js.map} +1 -1
- package/dist/{playground-BZ0hGjbL.js → playground-3OeRB7JU.js} +15 -9
- package/dist/playground-3OeRB7JU.js.map +1 -0
- package/dist/{posthog-integration-C8qhJnI3.js → posthog-integration-8iTgqy2J.js} +17 -11
- package/dist/posthog-integration-8iTgqy2J.js.map +1 -0
- package/dist/{provisioning-C-2ExcqY.js → provisioning-DxaT7bWw.js} +3 -3
- package/dist/{provisioning-C-2ExcqY.js.map → provisioning-DxaT7bWw.js.map} +1 -1
- package/dist/{registry-hBUgaWFx.js → registry-apQfB3rf.js} +4 -4
- package/dist/{registry-hBUgaWFx.js.map → registry-apQfB3rf.js.map} +1 -1
- package/dist/{setup-utils-DetnhXo0.js → setup-utils-B9xqAXXl.js} +10 -9
- package/dist/setup-utils-B9xqAXXl.js.map +1 -0
- package/dist/{slides-mT2s9wM_.js → slides-BEshbXqG.js} +290 -122
- package/dist/slides-BEshbXqG.js.map +1 -0
- package/dist/{start-tui-BfXoErKg.js → start-tui-CCpKnZOY.js} +243 -56
- package/dist/start-tui-CCpKnZOY.js.map +1 -0
- package/dist/{steps-SoDXSUxe.js → steps-DKbDDnVH.js} +6 -6
- package/dist/{steps-SoDXSUxe.js.map → steps-DKbDDnVH.js.map} +1 -1
- package/dist/{task-stream-CZRj6auI.js → task-stream-CZawuzlz.js} +2 -2
- package/dist/{task-stream-CZRj6auI.js.map → task-stream-CZawuzlz.js.map} +1 -1
- package/dist/{telemetry-CPcMFxcO.js → telemetry-DUeOcmpo.js} +2 -2
- package/dist/{telemetry-CPcMFxcO.js.map → telemetry-DUeOcmpo.js.map} +1 -1
- package/dist/{urls-BO7doNJG.js → urls-B6wBIwr1.js} +2 -2
- package/dist/{urls-BO7doNJG.js.map → urls-B6wBIwr1.js.map} +1 -1
- package/dist/wizard-abort-D8XZdVAR.js +2 -0
- package/dist/{wizard-abort-CDXufkqJ.js → wizard-abort-DhGgTlUA.js} +12 -7
- package/dist/wizard-abort-DhGgTlUA.js.map +1 -0
- package/dist/{wizard-session-d27JGRGi.js → wizard-session-G3VWD6hv.js} +3 -1
- package/dist/{wizard-session-d27JGRGi.js.map → wizard-session-G3VWD6hv.js.map} +1 -1
- package/dist/{wizard-session-y304gEEI.js → wizard-session-wPJtNl4c.js} +1 -1
- package/dist/wizard-ui-YdGFRyu_.js.map +1 -1
- package/package.json +4 -2
- package/dist/agent-interface-CQU6x4Hj.js.map +0 -1
- package/dist/playground-BZ0hGjbL.js.map +0 -1
- package/dist/posthog-integration-C8qhJnI3.js.map +0 -1
- package/dist/setup-utils-DetnhXo0.js.map +0 -1
- package/dist/slides-mT2s9wM_.js.map +0 -1
- package/dist/start-tui-BfXoErKg.js.map +0 -1
- package/dist/wizard-abort-CDXufkqJ.js.map +0 -1
- package/dist/wizard-abort-CtMY57ZE.js +0 -2
|
@@ -1,12 +1,13 @@
|
|
|
1
|
-
import { g as SERVICE_LABELS, s as logToFile } from "./debug-
|
|
1
|
+
import { g as SERVICE_LABELS, s as logToFile } from "./debug-BJu_sS4l.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 buildSession } from "./wizard-session-
|
|
5
|
-
import {
|
|
6
|
-
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-
|
|
3
|
+
import { r as sessionProperties, t as analytics } from "./analytics-C8lJzXjY.js";
|
|
4
|
+
import { i as buildSession } from "./wizard-session-G3VWD6hv.js";
|
|
5
|
+
import { y as AUDIT_SEVERITY_STYLE } from "./agent-interface-B-LAvrNL.js";
|
|
6
|
+
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-8iTgqy2J.js";
|
|
7
7
|
import { a as getProgramConfig, i as Program, l as getKindMeta, r as PROGRAM_REGISTRY } from "./bin.js";
|
|
8
8
|
import { n as AVAILABLE_FEATURES, o as isAllFeaturesSelected, t as ALL_FEATURE_VALUES } from "./defaults-BNWIWzjc.js";
|
|
9
9
|
import * as fs$1 from "fs";
|
|
10
|
+
import opn from "opn";
|
|
10
11
|
import { Box, Text, measureElement, useInput, useStdout } from "ink";
|
|
11
12
|
import { Component, Fragment, createContext, useCallback, useContext, useEffect, useMemo, useRef, useState, useSyncExternalStore } from "react";
|
|
12
13
|
import { Fragment as Fragment$1, jsx, jsxs } from "react/jsx-runtime";
|
|
@@ -159,8 +160,7 @@ var WizardStore = class {
|
|
|
159
160
|
this._initFromProgram(program);
|
|
160
161
|
}
|
|
161
162
|
/**
|
|
162
|
-
* Scan program steps for gate predicates and
|
|
163
|
-
* Creates gate promises and fires init work.
|
|
163
|
+
* Scan program steps for gate predicates and create gate promises.
|
|
164
164
|
*/
|
|
165
165
|
_initFromProgram(program) {
|
|
166
166
|
const steps = getProgramConfig(program).steps;
|
|
@@ -176,6 +176,15 @@ var WizardStore = class {
|
|
|
176
176
|
resolved: false
|
|
177
177
|
});
|
|
178
178
|
}
|
|
179
|
+
}
|
|
180
|
+
/**
|
|
181
|
+
* Run the program steps' onInit callbacks. startTUI calls this once
|
|
182
|
+
* the screens are actually rendering — constructing a store alone
|
|
183
|
+
* (tests, playground) must not fire init work like the health-check
|
|
184
|
+
* pre-flight, whose probes belong only to flows that show its screen.
|
|
185
|
+
*/
|
|
186
|
+
runInitHooks() {
|
|
187
|
+
const steps = getProgramConfig(this.router.activeProgram).steps;
|
|
179
188
|
const getSession = () => this.session;
|
|
180
189
|
const ctx = {
|
|
181
190
|
get session() {
|
|
@@ -487,6 +496,14 @@ var WizardStore = class {
|
|
|
487
496
|
this.$session.setKey("mcpSuggestedPromptsDismissed", true);
|
|
488
497
|
this.emitChange();
|
|
489
498
|
}
|
|
499
|
+
setSlackStepDismissed() {
|
|
500
|
+
this.$session.setKey("slackStepDismissed", true);
|
|
501
|
+
this.emitChange();
|
|
502
|
+
}
|
|
503
|
+
setSlackConnected(connected) {
|
|
504
|
+
this.$session.setKey("slackConnected", connected);
|
|
505
|
+
this.emitChange();
|
|
506
|
+
}
|
|
490
507
|
setOutroDismissed() {
|
|
491
508
|
this.$session.setKey("outroDismissed", true);
|
|
492
509
|
this.emitChange();
|
|
@@ -891,6 +908,27 @@ function useKeyBindings(id, bindings) {
|
|
|
891
908
|
* Key bindings are declared via useKeyBindings, which auto-registers
|
|
892
909
|
* hints in the KeyboardHintsBar.
|
|
893
910
|
*/
|
|
911
|
+
/**
|
|
912
|
+
* Step through a column's options in `dir`, wrapping, until an enabled
|
|
913
|
+
* option is found. Returns `from` unchanged if the column is entirely
|
|
914
|
+
* disabled.
|
|
915
|
+
*/
|
|
916
|
+
function stepEnabled(options, rows, from, dir) {
|
|
917
|
+
const colStart = Math.floor(from / rows) * rows;
|
|
918
|
+
const colLen = Math.min(rows, options.length - colStart);
|
|
919
|
+
let row = from % rows;
|
|
920
|
+
for (let i = 0; i < colLen; i++) {
|
|
921
|
+
row = (row + dir + colLen) % colLen;
|
|
922
|
+
const idx = colStart + row;
|
|
923
|
+
if (!options[idx]?.disabled) return idx;
|
|
924
|
+
}
|
|
925
|
+
return from;
|
|
926
|
+
}
|
|
927
|
+
/** Index of the first enabled option, for the initial focus. */
|
|
928
|
+
function firstEnabled(options) {
|
|
929
|
+
const idx = options.findIndex((o) => !o.disabled);
|
|
930
|
+
return idx === -1 ? 0 : idx;
|
|
931
|
+
}
|
|
894
932
|
const PickerMenu = ({ message, options, mode = "single", centered = false, columns = 1, optionMarginBottom = 0, onSelect }) => {
|
|
895
933
|
if (mode === "multi") return /* @__PURE__ */ jsx(MultiPickerMenu, {
|
|
896
934
|
message,
|
|
@@ -911,22 +949,18 @@ const PickerMenu = ({ message, options, mode = "single", centered = false, colum
|
|
|
911
949
|
};
|
|
912
950
|
/** Custom single-select with triangle indicator and accent highlight. */
|
|
913
951
|
const SinglePickerMenu = ({ message, options, centered = false, columns = 1, optionMarginBottom = 0, onSelect }) => {
|
|
914
|
-
const [focused, setFocused] = useState(
|
|
952
|
+
const [focused, setFocused] = useState(() => firstEnabled(options));
|
|
915
953
|
const rows = Math.ceil(options.length / columns);
|
|
954
|
+
useEffect(() => {
|
|
955
|
+
if (focused >= options.length || options[focused]?.disabled) setFocused(firstEnabled(options));
|
|
956
|
+
}, [options, focused]);
|
|
916
957
|
const bindings = [{
|
|
917
958
|
match: ["upArrow", "downArrow"],
|
|
918
959
|
label: "↑↓",
|
|
919
960
|
action: "navigate",
|
|
920
961
|
handler: (_input, key) => {
|
|
921
|
-
|
|
922
|
-
|
|
923
|
-
if (key.upArrow) if (row > 0) setFocused(col * rows + row - 1);
|
|
924
|
-
else setFocused(Math.min(col * rows + rows - 1, options.length - 1));
|
|
925
|
-
if (key.downArrow) {
|
|
926
|
-
const next = col * rows + row + 1;
|
|
927
|
-
if (next < options.length && row + 1 < rows) setFocused(next);
|
|
928
|
-
else setFocused(col * rows);
|
|
929
|
-
}
|
|
962
|
+
if (key.upArrow) setFocused(stepEnabled(options, rows, focused, -1));
|
|
963
|
+
if (key.downArrow) setFocused(stepEnabled(options, rows, focused, 1));
|
|
930
964
|
}
|
|
931
965
|
}, {
|
|
932
966
|
match: "return",
|
|
@@ -934,7 +968,7 @@ const SinglePickerMenu = ({ message, options, centered = false, columns = 1, opt
|
|
|
934
968
|
action: "select",
|
|
935
969
|
handler: () => {
|
|
936
970
|
const selected = options[focused];
|
|
937
|
-
if (selected) onSelect(selected.value);
|
|
971
|
+
if (selected && !selected.disabled) onSelect(selected.value);
|
|
938
972
|
}
|
|
939
973
|
}];
|
|
940
974
|
if (columns > 1) bindings.splice(1, 0, {
|
|
@@ -944,14 +978,17 @@ const SinglePickerMenu = ({ message, options, centered = false, columns = 1, opt
|
|
|
944
978
|
handler: (_input, key) => {
|
|
945
979
|
const col = Math.floor(focused / rows);
|
|
946
980
|
const row = focused % rows;
|
|
981
|
+
let next = focused;
|
|
947
982
|
if (key.leftArrow) {
|
|
948
983
|
const prevCol = col > 0 ? col - 1 : columns - 1;
|
|
949
|
-
|
|
984
|
+
next = Math.min(prevCol * rows + row, options.length - 1);
|
|
950
985
|
}
|
|
951
986
|
if (key.rightArrow) {
|
|
952
987
|
const nextCol = col < columns - 1 ? col + 1 : 0;
|
|
953
|
-
|
|
988
|
+
next = Math.min(nextCol * rows + row, options.length - 1);
|
|
954
989
|
}
|
|
990
|
+
if (options[next]?.disabled) next = stepEnabled(options, rows, next, 1);
|
|
991
|
+
setFocused(next);
|
|
955
992
|
}
|
|
956
993
|
});
|
|
957
994
|
useKeyBindings("single-picker", bindings);
|
|
@@ -972,16 +1009,23 @@ const SinglePickerMenu = ({ message, options, centered = false, columns = 1, opt
|
|
|
972
1009
|
return /* @__PURE__ */ jsxs(Box, {
|
|
973
1010
|
gap: 1,
|
|
974
1011
|
marginBottom: optionMarginBottom,
|
|
975
|
-
children: [
|
|
976
|
-
|
|
977
|
-
|
|
978
|
-
|
|
979
|
-
|
|
980
|
-
|
|
981
|
-
|
|
982
|
-
|
|
983
|
-
|
|
984
|
-
|
|
1012
|
+
children: [
|
|
1013
|
+
/* @__PURE__ */ jsx(Text, {
|
|
1014
|
+
color: isFocused ? Colors.accent : void 0,
|
|
1015
|
+
dimColor: !isFocused,
|
|
1016
|
+
children: isFocused ? Icons.triangleSmallRight : " "
|
|
1017
|
+
}),
|
|
1018
|
+
opt.icon && /* @__PURE__ */ jsx(Text, {
|
|
1019
|
+
color: opt.icon.color,
|
|
1020
|
+
children: opt.icon.glyph
|
|
1021
|
+
}),
|
|
1022
|
+
/* @__PURE__ */ jsx(Text, {
|
|
1023
|
+
color: opt.disabled ? Colors.muted : isFocused ? Colors.accent : void 0,
|
|
1024
|
+
bold: isFocused && !opt.disabled,
|
|
1025
|
+
dimColor: !isFocused || opt.disabled,
|
|
1026
|
+
children: label
|
|
1027
|
+
})
|
|
1028
|
+
]
|
|
985
1029
|
}, flatIdx);
|
|
986
1030
|
})
|
|
987
1031
|
}, colIdx))
|
|
@@ -990,24 +1034,20 @@ const SinglePickerMenu = ({ message, options, centered = false, columns = 1, opt
|
|
|
990
1034
|
};
|
|
991
1035
|
/** Custom multi-select with checkbox glyphs and accent highlight. */
|
|
992
1036
|
const MultiPickerMenu = ({ message, options, centered = false, columns = 1, optionMarginBottom = 0, onSelect }) => {
|
|
993
|
-
const [focused, setFocused] = useState(
|
|
1037
|
+
const [focused, setFocused] = useState(() => firstEnabled(options));
|
|
994
1038
|
const [selected, setSelected] = useState(/* @__PURE__ */ new Set());
|
|
995
1039
|
const rows = Math.ceil(options.length / columns);
|
|
1040
|
+
useEffect(() => {
|
|
1041
|
+
if (focused >= options.length || options[focused]?.disabled) setFocused(firstEnabled(options));
|
|
1042
|
+
}, [options, focused]);
|
|
996
1043
|
const bindings = [
|
|
997
1044
|
{
|
|
998
1045
|
match: ["upArrow", "downArrow"],
|
|
999
1046
|
label: "↑↓",
|
|
1000
1047
|
action: "navigate",
|
|
1001
1048
|
handler: (_input, key) => {
|
|
1002
|
-
|
|
1003
|
-
|
|
1004
|
-
if (key.upArrow) if (row > 0) setFocused(col * rows + row - 1);
|
|
1005
|
-
else setFocused(Math.min(col * rows + rows - 1, options.length - 1));
|
|
1006
|
-
if (key.downArrow) {
|
|
1007
|
-
const next = col * rows + row + 1;
|
|
1008
|
-
if (next < options.length && row + 1 < rows) setFocused(next);
|
|
1009
|
-
else setFocused(col * rows);
|
|
1010
|
-
}
|
|
1049
|
+
if (key.upArrow) setFocused(stepEnabled(options, rows, focused, -1));
|
|
1050
|
+
if (key.downArrow) setFocused(stepEnabled(options, rows, focused, 1));
|
|
1011
1051
|
}
|
|
1012
1052
|
},
|
|
1013
1053
|
{
|
|
@@ -1015,6 +1055,7 @@ const MultiPickerMenu = ({ message, options, centered = false, columns = 1, opti
|
|
|
1015
1055
|
label: "space",
|
|
1016
1056
|
action: "toggle",
|
|
1017
1057
|
handler: () => {
|
|
1058
|
+
if (options[focused]?.disabled) return;
|
|
1018
1059
|
setSelected((prev) => {
|
|
1019
1060
|
const next = new Set(prev);
|
|
1020
1061
|
if (next.has(focused)) {
|
|
@@ -1035,7 +1076,7 @@ const MultiPickerMenu = ({ message, options, centered = false, columns = 1, opti
|
|
|
1035
1076
|
handler: () => {
|
|
1036
1077
|
if (selected.size === 0) {
|
|
1037
1078
|
const hovered = options[focused];
|
|
1038
|
-
if (hovered) onSelect(hovered.value);
|
|
1079
|
+
if (hovered && !hovered.disabled) onSelect(hovered.value);
|
|
1039
1080
|
} else onSelect([...selected].sort().map((i) => options[i].value));
|
|
1040
1081
|
}
|
|
1041
1082
|
}
|
|
@@ -1047,14 +1088,17 @@ const MultiPickerMenu = ({ message, options, centered = false, columns = 1, opti
|
|
|
1047
1088
|
handler: (_input, key) => {
|
|
1048
1089
|
const col = Math.floor(focused / rows);
|
|
1049
1090
|
const row = focused % rows;
|
|
1091
|
+
let next = focused;
|
|
1050
1092
|
if (key.leftArrow) {
|
|
1051
1093
|
const prevCol = col > 0 ? col - 1 : columns - 1;
|
|
1052
|
-
|
|
1094
|
+
next = Math.min(prevCol * rows + row, options.length - 1);
|
|
1053
1095
|
}
|
|
1054
1096
|
if (key.rightArrow) {
|
|
1055
1097
|
const nextCol = col < columns - 1 ? col + 1 : 0;
|
|
1056
|
-
|
|
1098
|
+
next = Math.min(nextCol * rows + row, options.length - 1);
|
|
1057
1099
|
}
|
|
1100
|
+
if (options[next]?.disabled) next = stepEnabled(options, rows, next, 1);
|
|
1101
|
+
setFocused(next);
|
|
1058
1102
|
}
|
|
1059
1103
|
});
|
|
1060
1104
|
useKeyBindings("multi-picker", bindings);
|
|
@@ -1079,16 +1123,23 @@ const MultiPickerMenu = ({ message, options, centered = false, columns = 1, opti
|
|
|
1079
1123
|
return /* @__PURE__ */ jsxs(Box, {
|
|
1080
1124
|
gap: 1,
|
|
1081
1125
|
marginBottom: optionMarginBottom,
|
|
1082
|
-
children: [
|
|
1083
|
-
|
|
1084
|
-
|
|
1085
|
-
|
|
1086
|
-
|
|
1087
|
-
|
|
1088
|
-
|
|
1089
|
-
|
|
1090
|
-
|
|
1091
|
-
|
|
1126
|
+
children: [
|
|
1127
|
+
/* @__PURE__ */ jsx(Text, {
|
|
1128
|
+
color: isSelected ? "white" : Colors.muted,
|
|
1129
|
+
dimColor: !isFocused && !isSelected,
|
|
1130
|
+
children: checkbox
|
|
1131
|
+
}),
|
|
1132
|
+
opt.icon && /* @__PURE__ */ jsx(Text, {
|
|
1133
|
+
color: opt.icon.color,
|
|
1134
|
+
children: opt.icon.glyph
|
|
1135
|
+
}),
|
|
1136
|
+
/* @__PURE__ */ jsx(Text, {
|
|
1137
|
+
color: opt.disabled ? Colors.muted : isFocused ? Colors.accent : void 0,
|
|
1138
|
+
bold: isFocused && !opt.disabled,
|
|
1139
|
+
dimColor: !isFocused || opt.disabled,
|
|
1140
|
+
children: label
|
|
1141
|
+
})
|
|
1142
|
+
]
|
|
1092
1143
|
}, flatIdx);
|
|
1093
1144
|
})
|
|
1094
1145
|
}, colIdx))
|
|
@@ -2330,6 +2381,12 @@ const TIPS = [
|
|
|
2330
2381
|
title: "Get way more detail using properties",
|
|
2331
2382
|
description: "Events and person records can have any properties you want. Track things like how they found your website, what subscription tier they choose, and much more."
|
|
2332
2383
|
},
|
|
2384
|
+
{
|
|
2385
|
+
id: "slack",
|
|
2386
|
+
title: "Use PostHog in Slack",
|
|
2387
|
+
description: "Connect the PostHog Slack app to analyze data and ship product changes — deploy flags, open PRs, run queries — just by tagging @PostHog:",
|
|
2388
|
+
url: "https://posthog.com/slack-app"
|
|
2389
|
+
},
|
|
2333
2390
|
{
|
|
2334
2391
|
id: "stripe",
|
|
2335
2392
|
title: "You can track Stripe revenue with PostHog",
|
|
@@ -3749,6 +3806,13 @@ var neutralCrossSell = [{
|
|
|
3749
3806
|
"prompt": "List the top errors my users hit this week.",
|
|
3750
3807
|
"description": "Built-in error tracking — no separate tool."
|
|
3751
3808
|
}];
|
|
3809
|
+
var slackApp = {
|
|
3810
|
+
"learnMoreUrl": "https://posthog.com/slack-app",
|
|
3811
|
+
"setupUrl": "https://app.posthog.com/settings/project-integrations#integration-slack",
|
|
3812
|
+
"headline": "Take PostHog to Slack",
|
|
3813
|
+
"pitch": "You can also analyze product data and ship changes.",
|
|
3814
|
+
"capabilities": ["Tag @PostHog with a bug, edit, or a feature idea. It will spin up a sandboxed environment, plan, edit files, run tests, and open a draft PR.", "Tag @PostHog with any data question. It's the same SQL-writing, statistically-minded assistant as PostHog AI, but it responds where you send work memes."]
|
|
3815
|
+
};
|
|
3752
3816
|
//#endregion
|
|
3753
3817
|
//#region src/lib/mcp-role-prompts.ts
|
|
3754
3818
|
/**
|
|
@@ -3783,6 +3847,7 @@ const GENERIC_FOLLOW_UPS = genericFollowUps;
|
|
|
3783
3847
|
const DEEP_DIVE_FOLLOW_UPS = deepDiveFollowUps;
|
|
3784
3848
|
const CROSS_SELL_BY_ROLE = crossSellByRole;
|
|
3785
3849
|
const NEUTRAL_CROSS_SELL = neutralCrossSell;
|
|
3850
|
+
const SLACK_APP = slackApp;
|
|
3786
3851
|
const INTEGRATION_FAMILY = {
|
|
3787
3852
|
nextjs: "fullstack",
|
|
3788
3853
|
nuxt: "fullstack",
|
|
@@ -3896,6 +3961,20 @@ function getCrossSellPrompts(role) {
|
|
|
3896
3961
|
if (!isTailoredRole(role)) return NEUTRAL_CROSS_SELL;
|
|
3897
3962
|
return CROSS_SELL_BY_ROLE[role];
|
|
3898
3963
|
}
|
|
3964
|
+
/**
|
|
3965
|
+
* Resolve the "Take PostHog to Slack" card. Role-independent — the Slack
|
|
3966
|
+
* agent's two capabilities (code/PR + data) describe the product itself,
|
|
3967
|
+
* not role-specific examples.
|
|
3968
|
+
*/
|
|
3969
|
+
function getSlackAppCard() {
|
|
3970
|
+
return {
|
|
3971
|
+
headline: SLACK_APP.headline,
|
|
3972
|
+
pitch: SLACK_APP.pitch,
|
|
3973
|
+
learnMoreUrl: SLACK_APP.learnMoreUrl,
|
|
3974
|
+
setupUrl: SLACK_APP.setupUrl,
|
|
3975
|
+
capabilities: SLACK_APP.capabilities
|
|
3976
|
+
};
|
|
3977
|
+
}
|
|
3899
3978
|
//#endregion
|
|
3900
3979
|
//#region src/ui/tui/screens/McpSuggestedPromptsScreen.tsx
|
|
3901
3980
|
/**
|
|
@@ -3936,6 +4015,25 @@ function getCrossSellPrompts(role) {
|
|
|
3936
4015
|
* forces a successful login first). A defensive throw protects the
|
|
3937
4016
|
* Running useEffect against a state-machine bug.
|
|
3938
4017
|
*/
|
|
4018
|
+
var Phase = /* @__PURE__ */ function(Phase) {
|
|
4019
|
+
Phase["Choose"] = "choose";
|
|
4020
|
+
Phase["Authenticating"] = "authenticating";
|
|
4021
|
+
Phase["Greeting"] = "greeting";
|
|
4022
|
+
Phase["PromptPicker"] = "prompt-picker";
|
|
4023
|
+
Phase["Running"] = "running";
|
|
4024
|
+
Phase["FollowUp"] = "follow-up";
|
|
4025
|
+
/** Final beat on every dismissal — reminds the user how to keep
|
|
4026
|
+
* talking to PostHog after the tutorial ends. */
|
|
4027
|
+
Phase["Goodbye"] = "goodbye";
|
|
4028
|
+
Phase["Done"] = "done";
|
|
4029
|
+
return Phase;
|
|
4030
|
+
}(Phase || {});
|
|
4031
|
+
var ChoiceValue = /* @__PURE__ */ function(ChoiceValue) {
|
|
4032
|
+
ChoiceValue["Login"] = "login";
|
|
4033
|
+
ChoiceValue["ConnectSlack"] = "connect-slack";
|
|
4034
|
+
ChoiceValue["Exit"] = "exit";
|
|
4035
|
+
return ChoiceValue;
|
|
4036
|
+
}(ChoiceValue || {});
|
|
3939
4037
|
const MAX_PROMPT_RUNS = 5;
|
|
3940
4038
|
const FOLLOW_UP_DELAY_MS = 3e3;
|
|
3941
4039
|
const McpSuggestedPromptsScreen = ({ store, services }) => {
|
|
@@ -3944,8 +4042,9 @@ const McpSuggestedPromptsScreen = ({ store, services }) => {
|
|
|
3944
4042
|
const kit = getRolePrompts(session.roleAtOrganization, session.integration);
|
|
3945
4043
|
const crossSell = useMemo(() => getCrossSellPrompts(session.roleAtOrganization), [session.roleAtOrganization]);
|
|
3946
4044
|
const greeting = useMemo(() => getRoleGreeting(session.roleAtOrganization), [session.roleAtOrganization]);
|
|
3947
|
-
const [phase, setPhase] = useState("choose");
|
|
4045
|
+
const [phase, setPhase] = useState(() => store.session.credentials ? "choose" : "authenticating");
|
|
3948
4046
|
const [loginError, setLoginError] = useState(null);
|
|
4047
|
+
const startedTutorialRef = useRef(false);
|
|
3949
4048
|
const [runningPrompt, setRunningPrompt] = useState(null);
|
|
3950
4049
|
const [runChunks, setRunChunks] = useState([]);
|
|
3951
4050
|
const [runStartedAt, setRunStartedAt] = useState(null);
|
|
@@ -3967,7 +4066,7 @@ const McpSuggestedPromptsScreen = ({ store, services }) => {
|
|
|
3967
4066
|
store.setRoleAtOrganization(roleAtOrganization);
|
|
3968
4067
|
store.setApiUser(user);
|
|
3969
4068
|
store.setLoginUrl(null);
|
|
3970
|
-
setPhase("greeting");
|
|
4069
|
+
setPhase(startedTutorialRef.current ? "greeting" : "choose");
|
|
3971
4070
|
} catch (err) {
|
|
3972
4071
|
if (cancelled) return;
|
|
3973
4072
|
const message = err instanceof Error ? err.message : String(err);
|
|
@@ -3985,6 +4084,28 @@ const McpSuggestedPromptsScreen = ({ store, services }) => {
|
|
|
3985
4084
|
services,
|
|
3986
4085
|
store
|
|
3987
4086
|
]);
|
|
4087
|
+
const credentials = session.credentials;
|
|
4088
|
+
const slackConnected = session.slackConnected;
|
|
4089
|
+
useEffect(() => {
|
|
4090
|
+
if (!credentials || slackConnected !== null) return;
|
|
4091
|
+
let cancelled = false;
|
|
4092
|
+
const controller = new AbortController();
|
|
4093
|
+
services.checkSlackConnected(credentials, controller.signal).then((connected) => {
|
|
4094
|
+
if (!cancelled) store.setSlackConnected(connected);
|
|
4095
|
+
}).catch((err) => {
|
|
4096
|
+
if (cancelled) return;
|
|
4097
|
+
analytics.captureException(err instanceof Error ? err : new Error(String(err)), { step: "slack_connected_check" });
|
|
4098
|
+
});
|
|
4099
|
+
return () => {
|
|
4100
|
+
cancelled = true;
|
|
4101
|
+
controller.abort();
|
|
4102
|
+
};
|
|
4103
|
+
}, [
|
|
4104
|
+
credentials,
|
|
4105
|
+
slackConnected,
|
|
4106
|
+
services,
|
|
4107
|
+
store
|
|
4108
|
+
]);
|
|
3988
4109
|
useEffect(() => {
|
|
3989
4110
|
if (phase !== "running") return;
|
|
3990
4111
|
if (!runningPrompt) return;
|
|
@@ -4070,7 +4191,11 @@ const McpSuggestedPromptsScreen = ({ store, services }) => {
|
|
|
4070
4191
|
setLoginError(null);
|
|
4071
4192
|
if (choice === "login") {
|
|
4072
4193
|
analytics.wizardCapture("mcp suggested prompts choose", { choice: "login" });
|
|
4073
|
-
|
|
4194
|
+
startedTutorialRef.current = true;
|
|
4195
|
+
setPhase(session.credentials ? "greeting" : "authenticating");
|
|
4196
|
+
} else if (choice === "connect-slack") {
|
|
4197
|
+
analytics.wizardCapture("mcp suggested prompts choose", { choice: "connect-slack" });
|
|
4198
|
+
opn(getSlackAppCard().setupUrl, { wait: false }).catch(() => {});
|
|
4074
4199
|
} else {
|
|
4075
4200
|
analytics.wizardCapture("mcp suggested prompts choose", { choice: "exit" });
|
|
4076
4201
|
enterGoodbye();
|
|
@@ -4106,9 +4231,10 @@ const McpSuggestedPromptsScreen = ({ store, services }) => {
|
|
|
4106
4231
|
{
|
|
4107
4232
|
match: "escape",
|
|
4108
4233
|
label: "esc",
|
|
4109
|
-
action: phase === "goodbye" ? "close" : "exit",
|
|
4234
|
+
action: phase === "goodbye" ? "close" : phase === "authenticating" ? "cancel" : "exit",
|
|
4110
4235
|
handler: () => {
|
|
4111
4236
|
if (phase === "goodbye") closeWizard();
|
|
4237
|
+
else if (phase === "authenticating") setPhase("choose");
|
|
4112
4238
|
else if (phase === "running" || phase === "prompt-picker" || phase === "follow-up" || phase === "greeting") enterGoodbye();
|
|
4113
4239
|
}
|
|
4114
4240
|
},
|
|
@@ -4142,6 +4268,7 @@ const McpSuggestedPromptsScreen = ({ store, services }) => {
|
|
|
4142
4268
|
children: [
|
|
4143
4269
|
phase === "choose" && /* @__PURE__ */ jsx(ChoosePhase, {
|
|
4144
4270
|
error: loginError,
|
|
4271
|
+
slackConnected,
|
|
4145
4272
|
onSelect: handleChoice
|
|
4146
4273
|
}),
|
|
4147
4274
|
phase === "authenticating" && /* @__PURE__ */ jsx(AuthenticatingPhase, { loginUrl: session.loginUrl }),
|
|
@@ -4204,71 +4331,112 @@ const McpSuggestedPromptsScreen = ({ store, services }) => {
|
|
|
4204
4331
|
})
|
|
4205
4332
|
});
|
|
4206
4333
|
};
|
|
4207
|
-
const ChoosePhase = ({ error, onSelect }) =>
|
|
4208
|
-
|
|
4209
|
-
|
|
4210
|
-
|
|
4211
|
-
|
|
4212
|
-
|
|
4213
|
-
|
|
4214
|
-
|
|
4215
|
-
|
|
4216
|
-
|
|
4217
|
-
|
|
4218
|
-
|
|
4219
|
-
|
|
4220
|
-
|
|
4221
|
-
|
|
4222
|
-
|
|
4223
|
-
/* @__PURE__ */ jsxs(Text, { children: [/* @__PURE__ */ jsx(Text, {
|
|
4224
|
-
color: "cyan",
|
|
4225
|
-
children: Icons.diamond
|
|
4226
|
-
}), " Build dashboards"] }),
|
|
4227
|
-
/* @__PURE__ */ jsxs(Text, { children: [/* @__PURE__ */ jsx(Text, {
|
|
4228
|
-
color: "cyan",
|
|
4229
|
-
children: Icons.diamond
|
|
4230
|
-
}), " Run SQL queries"] }),
|
|
4231
|
-
/* @__PURE__ */ jsxs(Text, { children: [/* @__PURE__ */ jsx(Text, {
|
|
4232
|
-
color: "cyan",
|
|
4233
|
-
children: Icons.diamond
|
|
4234
|
-
}), " Deploy feature flags"] }),
|
|
4235
|
-
/* @__PURE__ */ jsxs(Text, { children: [/* @__PURE__ */ jsx(Text, {
|
|
4236
|
-
color: "cyan",
|
|
4237
|
-
children: Icons.diamond
|
|
4238
|
-
}), " Debug exceptions and errors"] }),
|
|
4239
|
-
/* @__PURE__ */ jsxs(Text, { children: [/* @__PURE__ */ jsx(Text, {
|
|
4240
|
-
color: "cyan",
|
|
4241
|
-
children: Icons.diamond
|
|
4242
|
-
}), " And lots more..."] })
|
|
4243
|
-
]
|
|
4244
|
-
}),
|
|
4245
|
-
/* @__PURE__ */ jsx(Box, {
|
|
4246
|
-
marginTop: 1,
|
|
4247
|
-
children: /* @__PURE__ */ jsx(Text, { children: "Want a live demo using real data from your project?" })
|
|
4248
|
-
}),
|
|
4249
|
-
/* @__PURE__ */ jsx(Box, { children: /* @__PURE__ */ jsx(PickerMenu, {
|
|
4250
|
-
options: [{
|
|
4251
|
-
label: "Start MCP tutorial",
|
|
4252
|
-
value: "login"
|
|
4253
|
-
}, {
|
|
4254
|
-
label: "Exit",
|
|
4255
|
-
value: "exit"
|
|
4256
|
-
}],
|
|
4257
|
-
onSelect
|
|
4258
|
-
}) }),
|
|
4259
|
-
error && /* @__PURE__ */ jsx(Box, {
|
|
4260
|
-
marginTop: 1,
|
|
4261
|
-
children: /* @__PURE__ */ jsxs(Text, {
|
|
4262
|
-
color: "red",
|
|
4334
|
+
const ChoosePhase = ({ error, slackConnected, onSelect }) => {
|
|
4335
|
+
return /* @__PURE__ */ jsxs(Box, {
|
|
4336
|
+
flexDirection: "column",
|
|
4337
|
+
children: [
|
|
4338
|
+
/* @__PURE__ */ jsx(Text, {
|
|
4339
|
+
bold: true,
|
|
4340
|
+
color: Colors.accent,
|
|
4341
|
+
children: "PostHog MCP"
|
|
4342
|
+
}),
|
|
4343
|
+
/* @__PURE__ */ jsx(Box, {
|
|
4344
|
+
marginTop: 1,
|
|
4345
|
+
children: /* @__PURE__ */ jsx(Text, { children: "With MCP your agent works directly with the PostHog platform. You can prompt it to:" })
|
|
4346
|
+
}),
|
|
4347
|
+
/* @__PURE__ */ jsxs(Box, {
|
|
4348
|
+
marginTop: 1,
|
|
4349
|
+
flexDirection: "column",
|
|
4263
4350
|
children: [
|
|
4264
|
-
|
|
4265
|
-
|
|
4266
|
-
|
|
4351
|
+
/* @__PURE__ */ jsxs(Text, { children: [/* @__PURE__ */ jsx(Text, {
|
|
4352
|
+
color: "cyan",
|
|
4353
|
+
children: Icons.diamond
|
|
4354
|
+
}), " Build dashboards"] }),
|
|
4355
|
+
/* @__PURE__ */ jsxs(Text, { children: [/* @__PURE__ */ jsx(Text, {
|
|
4356
|
+
color: "cyan",
|
|
4357
|
+
children: Icons.diamond
|
|
4358
|
+
}), " Run SQL queries"] }),
|
|
4359
|
+
/* @__PURE__ */ jsxs(Text, { children: [/* @__PURE__ */ jsx(Text, {
|
|
4360
|
+
color: "cyan",
|
|
4361
|
+
children: Icons.diamond
|
|
4362
|
+
}), " Deploy feature flags"] }),
|
|
4363
|
+
/* @__PURE__ */ jsxs(Text, { children: [/* @__PURE__ */ jsx(Text, {
|
|
4364
|
+
color: "cyan",
|
|
4365
|
+
children: Icons.diamond
|
|
4366
|
+
}), " Debug exceptions and errors"] }),
|
|
4367
|
+
/* @__PURE__ */ jsxs(Text, { children: [/* @__PURE__ */ jsx(Text, {
|
|
4368
|
+
color: "cyan",
|
|
4369
|
+
children: Icons.diamond
|
|
4370
|
+
}), " And lots more..."] })
|
|
4267
4371
|
]
|
|
4372
|
+
}),
|
|
4373
|
+
/* @__PURE__ */ jsx(Box, {
|
|
4374
|
+
marginTop: 1,
|
|
4375
|
+
flexDirection: "column",
|
|
4376
|
+
children: slackConnected ? /* @__PURE__ */ jsxs(Text, { children: [
|
|
4377
|
+
/* @__PURE__ */ jsx(Text, {
|
|
4378
|
+
color: Colors.success,
|
|
4379
|
+
children: Icons.check
|
|
4380
|
+
}),
|
|
4381
|
+
" Slack is connected — analyze data and ship product changes there by tagging",
|
|
4382
|
+
" ",
|
|
4383
|
+
/* @__PURE__ */ jsx(Text, {
|
|
4384
|
+
bold: true,
|
|
4385
|
+
children: "@PostHog"
|
|
4386
|
+
}),
|
|
4387
|
+
"."
|
|
4388
|
+
] }) : /* @__PURE__ */ jsxs(Text, { children: [
|
|
4389
|
+
"You can also connect PostHog to Slack, so you can analyze data and ship product changes there by tagging ",
|
|
4390
|
+
/* @__PURE__ */ jsx(Text, {
|
|
4391
|
+
bold: true,
|
|
4392
|
+
children: "@PostHog"
|
|
4393
|
+
}),
|
|
4394
|
+
"."
|
|
4395
|
+
] })
|
|
4396
|
+
}),
|
|
4397
|
+
/* @__PURE__ */ jsx(Box, {
|
|
4398
|
+
marginTop: 1,
|
|
4399
|
+
children: /* @__PURE__ */ jsx(Text, { children: "Want a live demo using real data from your project?" })
|
|
4400
|
+
}),
|
|
4401
|
+
/* @__PURE__ */ jsx(Box, { children: /* @__PURE__ */ jsx(PickerMenu, {
|
|
4402
|
+
options: [
|
|
4403
|
+
{
|
|
4404
|
+
label: "Start MCP tutorial",
|
|
4405
|
+
value: "login"
|
|
4406
|
+
},
|
|
4407
|
+
slackConnected ? {
|
|
4408
|
+
label: "Already connected to Slack",
|
|
4409
|
+
value: "connect-slack",
|
|
4410
|
+
icon: {
|
|
4411
|
+
glyph: Icons.check,
|
|
4412
|
+
color: Colors.success
|
|
4413
|
+
},
|
|
4414
|
+
disabled: true
|
|
4415
|
+
} : {
|
|
4416
|
+
label: "Connect Slack now",
|
|
4417
|
+
value: "connect-slack"
|
|
4418
|
+
},
|
|
4419
|
+
{
|
|
4420
|
+
label: "Exit",
|
|
4421
|
+
value: "exit"
|
|
4422
|
+
}
|
|
4423
|
+
],
|
|
4424
|
+
onSelect
|
|
4425
|
+
}) }),
|
|
4426
|
+
error && /* @__PURE__ */ jsx(Box, {
|
|
4427
|
+
marginTop: 1,
|
|
4428
|
+
children: /* @__PURE__ */ jsxs(Text, {
|
|
4429
|
+
color: "red",
|
|
4430
|
+
children: [
|
|
4431
|
+
"Login failed: ",
|
|
4432
|
+
error,
|
|
4433
|
+
". Try again or exit."
|
|
4434
|
+
]
|
|
4435
|
+
})
|
|
4268
4436
|
})
|
|
4269
|
-
|
|
4270
|
-
|
|
4271
|
-
}
|
|
4437
|
+
]
|
|
4438
|
+
});
|
|
4439
|
+
};
|
|
4272
4440
|
const AuthenticatingPhase = ({ loginUrl }) => /* @__PURE__ */ jsxs(Box, {
|
|
4273
4441
|
flexDirection: "column",
|
|
4274
4442
|
children: [/* @__PURE__ */ jsx(LoadingBox, { message: "Waiting for authentication..." }), loginUrl && /* @__PURE__ */ jsx(Box, {
|
|
@@ -4606,7 +4774,7 @@ const GoodbyePhase = ({ installedClients, role, integration, engaged, onClose })
|
|
|
4606
4774
|
label: "Close",
|
|
4607
4775
|
value: "close"
|
|
4608
4776
|
}],
|
|
4609
|
-
onSelect: onClose
|
|
4777
|
+
onSelect: () => onClose()
|
|
4610
4778
|
})
|
|
4611
4779
|
]
|
|
4612
4780
|
});
|
|
@@ -5472,6 +5640,6 @@ const AUDIT_3000_AREA_SLIDES = [
|
|
|
5472
5640
|
}
|
|
5473
5641
|
];
|
|
5474
5642
|
//#endregion
|
|
5475
|
-
export {
|
|
5643
|
+
export { CardLayout as A, GroupedPickerMenu as C, ProgressList as D, useKeyBindings as E, LoadingBox as O, ConfirmationInput as S, PickerMenu as T, TabContainer as _, McpSuggestedPromptsScreen as a, LogViewer as b, McpScreen as c, SEVERITY_ORDER as d, ServiceHealthList as f, HNViewer as g, ContentSequencer as h, AuditChecksViewer as i, WizardStore as j, SplitView as k, IssueTable as l, LearnCard as m, AUDIT_AREA_SLIDES as n, TAILORED_ROLES as o, TipsCard as p, VisualBox as r, getSlackAppCard as s, AUDIT_3000_AREA_SLIDES as t, SEVERITY_LABEL as u, ScreenContainer as v, useStdoutDimensions as w, ModalOverlay as x, EventPlanViewer as y };
|
|
5476
5644
|
|
|
5477
|
-
//# sourceMappingURL=slides-
|
|
5645
|
+
//# sourceMappingURL=slides-BEshbXqG.js.map
|