@posthog/wizard 2.18.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-DnPwZl1P.js → add-mcp-server-to-clients-iV7BuQpD.js} +72 -13
- package/dist/add-mcp-server-to-clients-iV7BuQpD.js.map +1 -0
- package/dist/{agent-interface-C2VEF-BD.js → agent-interface-B-LAvrNL.js} +165 -52
- package/dist/agent-interface-B-LAvrNL.js.map +1 -0
- package/dist/{agent-runner-Dw8cjZoN.js → agent-runner-w2Qu9M13.js} +16 -11
- package/dist/{agent-runner-Dw8cjZoN.js.map → agent-runner-w2Qu9M13.js.map} +1 -1
- package/dist/{analytics-C-zcTO6g.js → analytics-C8lJzXjY.js} +2 -2
- package/dist/{analytics-C-zcTO6g.js.map → analytics-C8lJzXjY.js.map} +1 -1
- package/dist/{api-B3MWP3vm.js → api-eUlUinVy.js} +25 -4
- package/dist/{api-B3MWP3vm.js.map → api-eUlUinVy.js.map} +1 -1
- package/dist/bin.js +79 -50
- package/dist/bin.js.map +1 -1
- package/dist/check-screens.tsx +124 -0
- package/dist/{ci-install-DLuSmSq6.js → ci-install-CSo7Q1pK.js} +4 -4
- package/dist/{ci-install-DLuSmSq6.js.map → ci-install-CSo7Q1pK.js.map} +1 -1
- package/dist/{debug-BorYMfpE.js → debug-BJu_sS4l.js} +36 -21
- package/dist/debug-BJu_sS4l.js.map +1 -0
- package/dist/{debug--gQGudnY.js → debug-CTViFiF-.js} +1 -1
- package/dist/{defaults-DA3-9dHT.js → defaults-BNWIWzjc.js} +34 -8
- package/dist/defaults-BNWIWzjc.js.map +1 -0
- package/dist/{environment-DIOtLqTQ.js → environment-Dk_dWk3t.js} +3 -3
- package/dist/{environment-DIOtLqTQ.js.map → environment-Dk_dWk3t.js.map} +1 -1
- package/dist/{interactive-DjGjlvY3.js → interactive-BS2rIf1v.js} +2 -2
- package/dist/{interactive-DjGjlvY3.js.map → interactive-BS2rIf1v.js.map} +1 -1
- package/dist/{mcp-prompt-streaming-Dm47tmiy.js → mcp-prompt-streaming-BiMrlLl0.js} +4 -4
- package/dist/{mcp-prompt-streaming-Dm47tmiy.js.map → mcp-prompt-streaming-BiMrlLl0.js.map} +1 -1
- package/dist/{non-interactive-C2f3Gwva.js → non-interactive-C39d_KIp.js} +2 -2
- package/dist/{non-interactive-C2f3Gwva.js.map → non-interactive-C39d_KIp.js.map} +1 -1
- package/dist/{package-manager-Bl2KOUFK.js → package-manager-BfOTvFt-.js} +2 -2
- package/dist/{package-manager-Bl2KOUFK.js.map → package-manager-BfOTvFt-.js.map} +1 -1
- package/dist/{playground-ZLG68cvx.js → playground-3OeRB7JU.js} +23 -9
- package/dist/playground-3OeRB7JU.js.map +1 -0
- package/dist/{posthog-integration-B_DLodqr.js → posthog-integration-8iTgqy2J.js} +20 -12
- package/dist/posthog-integration-8iTgqy2J.js.map +1 -0
- package/dist/{provisioning-Bk4E6VYn.js → provisioning-DxaT7bWw.js} +3 -3
- package/dist/{provisioning-Bk4E6VYn.js.map → provisioning-DxaT7bWw.js.map} +1 -1
- package/dist/{registry-DMM3UmZD.js → registry-apQfB3rf.js} +4 -4
- package/dist/{registry-DMM3UmZD.js.map → registry-apQfB3rf.js.map} +1 -1
- package/dist/{setup-utils-Df9ezAjZ.js → setup-utils-B9xqAXXl.js} +35 -20
- package/dist/{setup-utils-Df9ezAjZ.js.map → setup-utils-B9xqAXXl.js.map} +1 -1
- package/dist/{slides-DwvXZ8iS.js → slides-BEshbXqG.js} +448 -187
- package/dist/slides-BEshbXqG.js.map +1 -0
- package/dist/{start-tui-P9aMwBzt.js → start-tui-CCpKnZOY.js} +245 -57
- package/dist/start-tui-CCpKnZOY.js.map +1 -0
- package/dist/{steps-RCRZbLjZ.js → steps-DKbDDnVH.js} +6 -6
- package/dist/{steps-RCRZbLjZ.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-CMbVbpaY.js → telemetry-DUeOcmpo.js} +2 -2
- package/dist/{telemetry-CMbVbpaY.js.map → telemetry-DUeOcmpo.js.map} +1 -1
- package/dist/{urls-BzG_Jtw9.js → urls-B6wBIwr1.js} +2 -2
- package/dist/{urls-BzG_Jtw9.js.map → urls-B6wBIwr1.js.map} +1 -1
- package/dist/wizard-abort-D8XZdVAR.js +2 -0
- package/dist/{wizard-abort-QuKm_B5z.js → wizard-abort-DhGgTlUA.js} +14 -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/add-mcp-server-to-clients-DnPwZl1P.js.map +0 -1
- package/dist/agent-interface-C2VEF-BD.js.map +0 -1
- package/dist/debug-BorYMfpE.js.map +0 -1
- package/dist/defaults-DA3-9dHT.js.map +0 -1
- package/dist/playground-ZLG68cvx.js.map +0 -1
- package/dist/posthog-integration-B_DLodqr.js.map +0 -1
- package/dist/slides-DwvXZ8iS.js.map +0 -1
- package/dist/start-tui-P9aMwBzt.js.map +0 -1
- package/dist/wizard-abort-Dl8WJQgJ.js +0 -2
- package/dist/wizard-abort-QuKm_B5z.js.map +0 -1
|
@@ -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
|
-
import { n as AVAILABLE_FEATURES, t as ALL_FEATURE_VALUES } from "./defaults-
|
|
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() {
|
|
@@ -320,6 +329,7 @@ var WizardStore = class {
|
|
|
320
329
|
}
|
|
321
330
|
/** User dismissed the blocking outage screen. Gate resolves via _checkGates(). */
|
|
322
331
|
dismissOutage() {
|
|
332
|
+
logToFile("[health-checks] user dismissed outage screen, continuing");
|
|
323
333
|
this.$session.setKey("outageDismissed", true);
|
|
324
334
|
this.emitChange();
|
|
325
335
|
}
|
|
@@ -461,13 +471,15 @@ var WizardStore = class {
|
|
|
461
471
|
analytics.wizardCapture("feature enabled", { feature });
|
|
462
472
|
this.emitChange();
|
|
463
473
|
}
|
|
464
|
-
setMcpComplete(outcome = "skipped", installedClients = []) {
|
|
474
|
+
setMcpComplete(outcome = "skipped", installedClients = [], featuresSelected) {
|
|
465
475
|
this.$session.setKey("mcpComplete", true);
|
|
466
476
|
this.$session.setKey("mcpOutcome", outcome);
|
|
467
477
|
this.$session.setKey("mcpInstalledClients", installedClients);
|
|
478
|
+
const featuresPayload = outcome === "installed" && featuresSelected !== void 0 ? { mcp_features_selected: featuresSelected } : {};
|
|
468
479
|
analytics.wizardCapture("mcp complete", {
|
|
469
480
|
mcp_outcome: outcome,
|
|
470
481
|
mcp_installed_clients: installedClients,
|
|
482
|
+
...featuresPayload,
|
|
471
483
|
...sessionProperties(this.session)
|
|
472
484
|
});
|
|
473
485
|
this.emitChange();
|
|
@@ -484,6 +496,14 @@ var WizardStore = class {
|
|
|
484
496
|
this.$session.setKey("mcpSuggestedPromptsDismissed", true);
|
|
485
497
|
this.emitChange();
|
|
486
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
|
+
}
|
|
487
507
|
setOutroDismissed() {
|
|
488
508
|
this.$session.setKey("outroDismissed", true);
|
|
489
509
|
this.emitChange();
|
|
@@ -888,6 +908,27 @@ function useKeyBindings(id, bindings) {
|
|
|
888
908
|
* Key bindings are declared via useKeyBindings, which auto-registers
|
|
889
909
|
* hints in the KeyboardHintsBar.
|
|
890
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
|
+
}
|
|
891
932
|
const PickerMenu = ({ message, options, mode = "single", centered = false, columns = 1, optionMarginBottom = 0, onSelect }) => {
|
|
892
933
|
if (mode === "multi") return /* @__PURE__ */ jsx(MultiPickerMenu, {
|
|
893
934
|
message,
|
|
@@ -908,22 +949,18 @@ const PickerMenu = ({ message, options, mode = "single", centered = false, colum
|
|
|
908
949
|
};
|
|
909
950
|
/** Custom single-select with triangle indicator and accent highlight. */
|
|
910
951
|
const SinglePickerMenu = ({ message, options, centered = false, columns = 1, optionMarginBottom = 0, onSelect }) => {
|
|
911
|
-
const [focused, setFocused] = useState(
|
|
952
|
+
const [focused, setFocused] = useState(() => firstEnabled(options));
|
|
912
953
|
const rows = Math.ceil(options.length / columns);
|
|
954
|
+
useEffect(() => {
|
|
955
|
+
if (focused >= options.length || options[focused]?.disabled) setFocused(firstEnabled(options));
|
|
956
|
+
}, [options, focused]);
|
|
913
957
|
const bindings = [{
|
|
914
958
|
match: ["upArrow", "downArrow"],
|
|
915
959
|
label: "↑↓",
|
|
916
960
|
action: "navigate",
|
|
917
961
|
handler: (_input, key) => {
|
|
918
|
-
|
|
919
|
-
|
|
920
|
-
if (key.upArrow) if (row > 0) setFocused(col * rows + row - 1);
|
|
921
|
-
else setFocused(Math.min(col * rows + rows - 1, options.length - 1));
|
|
922
|
-
if (key.downArrow) {
|
|
923
|
-
const next = col * rows + row + 1;
|
|
924
|
-
if (next < options.length && row + 1 < rows) setFocused(next);
|
|
925
|
-
else setFocused(col * rows);
|
|
926
|
-
}
|
|
962
|
+
if (key.upArrow) setFocused(stepEnabled(options, rows, focused, -1));
|
|
963
|
+
if (key.downArrow) setFocused(stepEnabled(options, rows, focused, 1));
|
|
927
964
|
}
|
|
928
965
|
}, {
|
|
929
966
|
match: "return",
|
|
@@ -931,7 +968,7 @@ const SinglePickerMenu = ({ message, options, centered = false, columns = 1, opt
|
|
|
931
968
|
action: "select",
|
|
932
969
|
handler: () => {
|
|
933
970
|
const selected = options[focused];
|
|
934
|
-
if (selected) onSelect(selected.value);
|
|
971
|
+
if (selected && !selected.disabled) onSelect(selected.value);
|
|
935
972
|
}
|
|
936
973
|
}];
|
|
937
974
|
if (columns > 1) bindings.splice(1, 0, {
|
|
@@ -941,14 +978,17 @@ const SinglePickerMenu = ({ message, options, centered = false, columns = 1, opt
|
|
|
941
978
|
handler: (_input, key) => {
|
|
942
979
|
const col = Math.floor(focused / rows);
|
|
943
980
|
const row = focused % rows;
|
|
981
|
+
let next = focused;
|
|
944
982
|
if (key.leftArrow) {
|
|
945
983
|
const prevCol = col > 0 ? col - 1 : columns - 1;
|
|
946
|
-
|
|
984
|
+
next = Math.min(prevCol * rows + row, options.length - 1);
|
|
947
985
|
}
|
|
948
986
|
if (key.rightArrow) {
|
|
949
987
|
const nextCol = col < columns - 1 ? col + 1 : 0;
|
|
950
|
-
|
|
988
|
+
next = Math.min(nextCol * rows + row, options.length - 1);
|
|
951
989
|
}
|
|
990
|
+
if (options[next]?.disabled) next = stepEnabled(options, rows, next, 1);
|
|
991
|
+
setFocused(next);
|
|
952
992
|
}
|
|
953
993
|
});
|
|
954
994
|
useKeyBindings("single-picker", bindings);
|
|
@@ -969,16 +1009,23 @@ const SinglePickerMenu = ({ message, options, centered = false, columns = 1, opt
|
|
|
969
1009
|
return /* @__PURE__ */ jsxs(Box, {
|
|
970
1010
|
gap: 1,
|
|
971
1011
|
marginBottom: optionMarginBottom,
|
|
972
|
-
children: [
|
|
973
|
-
|
|
974
|
-
|
|
975
|
-
|
|
976
|
-
|
|
977
|
-
|
|
978
|
-
|
|
979
|
-
|
|
980
|
-
|
|
981
|
-
|
|
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
|
+
]
|
|
982
1029
|
}, flatIdx);
|
|
983
1030
|
})
|
|
984
1031
|
}, colIdx))
|
|
@@ -987,24 +1034,20 @@ const SinglePickerMenu = ({ message, options, centered = false, columns = 1, opt
|
|
|
987
1034
|
};
|
|
988
1035
|
/** Custom multi-select with checkbox glyphs and accent highlight. */
|
|
989
1036
|
const MultiPickerMenu = ({ message, options, centered = false, columns = 1, optionMarginBottom = 0, onSelect }) => {
|
|
990
|
-
const [focused, setFocused] = useState(
|
|
1037
|
+
const [focused, setFocused] = useState(() => firstEnabled(options));
|
|
991
1038
|
const [selected, setSelected] = useState(/* @__PURE__ */ new Set());
|
|
992
1039
|
const rows = Math.ceil(options.length / columns);
|
|
1040
|
+
useEffect(() => {
|
|
1041
|
+
if (focused >= options.length || options[focused]?.disabled) setFocused(firstEnabled(options));
|
|
1042
|
+
}, [options, focused]);
|
|
993
1043
|
const bindings = [
|
|
994
1044
|
{
|
|
995
1045
|
match: ["upArrow", "downArrow"],
|
|
996
1046
|
label: "↑↓",
|
|
997
1047
|
action: "navigate",
|
|
998
1048
|
handler: (_input, key) => {
|
|
999
|
-
|
|
1000
|
-
|
|
1001
|
-
if (key.upArrow) if (row > 0) setFocused(col * rows + row - 1);
|
|
1002
|
-
else setFocused(Math.min(col * rows + rows - 1, options.length - 1));
|
|
1003
|
-
if (key.downArrow) {
|
|
1004
|
-
const next = col * rows + row + 1;
|
|
1005
|
-
if (next < options.length && row + 1 < rows) setFocused(next);
|
|
1006
|
-
else setFocused(col * rows);
|
|
1007
|
-
}
|
|
1049
|
+
if (key.upArrow) setFocused(stepEnabled(options, rows, focused, -1));
|
|
1050
|
+
if (key.downArrow) setFocused(stepEnabled(options, rows, focused, 1));
|
|
1008
1051
|
}
|
|
1009
1052
|
},
|
|
1010
1053
|
{
|
|
@@ -1012,10 +1055,16 @@ const MultiPickerMenu = ({ message, options, centered = false, columns = 1, opti
|
|
|
1012
1055
|
label: "space",
|
|
1013
1056
|
action: "toggle",
|
|
1014
1057
|
handler: () => {
|
|
1058
|
+
if (options[focused]?.disabled) return;
|
|
1015
1059
|
setSelected((prev) => {
|
|
1016
1060
|
const next = new Set(prev);
|
|
1017
|
-
if (next.has(focused))
|
|
1018
|
-
|
|
1061
|
+
if (next.has(focused)) {
|
|
1062
|
+
next.delete(focused);
|
|
1063
|
+
return next;
|
|
1064
|
+
}
|
|
1065
|
+
if (options[focused]?.exclusive) return new Set([focused]);
|
|
1066
|
+
for (const i of next) if (options[i]?.exclusive) next.delete(i);
|
|
1067
|
+
next.add(focused);
|
|
1019
1068
|
return next;
|
|
1020
1069
|
});
|
|
1021
1070
|
}
|
|
@@ -1027,7 +1076,7 @@ const MultiPickerMenu = ({ message, options, centered = false, columns = 1, opti
|
|
|
1027
1076
|
handler: () => {
|
|
1028
1077
|
if (selected.size === 0) {
|
|
1029
1078
|
const hovered = options[focused];
|
|
1030
|
-
if (hovered) onSelect(hovered.value);
|
|
1079
|
+
if (hovered && !hovered.disabled) onSelect(hovered.value);
|
|
1031
1080
|
} else onSelect([...selected].sort().map((i) => options[i].value));
|
|
1032
1081
|
}
|
|
1033
1082
|
}
|
|
@@ -1039,14 +1088,17 @@ const MultiPickerMenu = ({ message, options, centered = false, columns = 1, opti
|
|
|
1039
1088
|
handler: (_input, key) => {
|
|
1040
1089
|
const col = Math.floor(focused / rows);
|
|
1041
1090
|
const row = focused % rows;
|
|
1091
|
+
let next = focused;
|
|
1042
1092
|
if (key.leftArrow) {
|
|
1043
1093
|
const prevCol = col > 0 ? col - 1 : columns - 1;
|
|
1044
|
-
|
|
1094
|
+
next = Math.min(prevCol * rows + row, options.length - 1);
|
|
1045
1095
|
}
|
|
1046
1096
|
if (key.rightArrow) {
|
|
1047
1097
|
const nextCol = col < columns - 1 ? col + 1 : 0;
|
|
1048
|
-
|
|
1098
|
+
next = Math.min(nextCol * rows + row, options.length - 1);
|
|
1049
1099
|
}
|
|
1100
|
+
if (options[next]?.disabled) next = stepEnabled(options, rows, next, 1);
|
|
1101
|
+
setFocused(next);
|
|
1050
1102
|
}
|
|
1051
1103
|
});
|
|
1052
1104
|
useKeyBindings("multi-picker", bindings);
|
|
@@ -1071,16 +1123,23 @@ const MultiPickerMenu = ({ message, options, centered = false, columns = 1, opti
|
|
|
1071
1123
|
return /* @__PURE__ */ jsxs(Box, {
|
|
1072
1124
|
gap: 1,
|
|
1073
1125
|
marginBottom: optionMarginBottom,
|
|
1074
|
-
children: [
|
|
1075
|
-
|
|
1076
|
-
|
|
1077
|
-
|
|
1078
|
-
|
|
1079
|
-
|
|
1080
|
-
|
|
1081
|
-
|
|
1082
|
-
|
|
1083
|
-
|
|
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
|
+
]
|
|
1084
1143
|
}, flatIdx);
|
|
1085
1144
|
})
|
|
1086
1145
|
}, colIdx))
|
|
@@ -1748,6 +1807,7 @@ var ScreenErrorBoundary = class extends Component {
|
|
|
1748
1807
|
}
|
|
1749
1808
|
componentDidCatch(error) {
|
|
1750
1809
|
const { store } = this.props;
|
|
1810
|
+
logToFile("[screen-error-boundary]", error);
|
|
1751
1811
|
console.error("[ScreenErrorBoundary]", error.message, error.stack);
|
|
1752
1812
|
store.setOutroData({
|
|
1753
1813
|
kind: "error",
|
|
@@ -2321,6 +2381,12 @@ const TIPS = [
|
|
|
2321
2381
|
title: "Get way more detail using properties",
|
|
2322
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."
|
|
2323
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
|
+
},
|
|
2324
2390
|
{
|
|
2325
2391
|
id: "stripe",
|
|
2326
2392
|
title: "You can track Stripe revenue with PostHog",
|
|
@@ -2613,8 +2679,22 @@ const IssueRow = ({ issue, docsWidth }) => {
|
|
|
2613
2679
|
*
|
|
2614
2680
|
* When done, calls store.setMcpComplete(). The router resolves to outro.
|
|
2615
2681
|
*/
|
|
2616
|
-
const markDone = (store, outcome, clients = []) => {
|
|
2617
|
-
store.setMcpComplete(outcome, clients);
|
|
2682
|
+
const markDone = (store, outcome, clients = [], featuresSelected) => {
|
|
2683
|
+
store.setMcpComplete(outcome, clients, featuresSelected);
|
|
2684
|
+
};
|
|
2685
|
+
const reportFeatures = (features) => isAllFeaturesSelected(features) ? "all" : features;
|
|
2686
|
+
/**
|
|
2687
|
+
* Connector step prompt — Enter continues (opens the connector page). There's
|
|
2688
|
+
* no skip: picking the connector commits to opening it.
|
|
2689
|
+
*/
|
|
2690
|
+
const ConnectorContinue = ({ onContinue }) => {
|
|
2691
|
+
useInput((_input, key) => {
|
|
2692
|
+
if (key.return) onContinue();
|
|
2693
|
+
});
|
|
2694
|
+
return /* @__PURE__ */ jsxs(Text, {
|
|
2695
|
+
color: Colors.primary,
|
|
2696
|
+
children: ["Press enter to continue ", Icons.triangleRight]
|
|
2697
|
+
});
|
|
2618
2698
|
};
|
|
2619
2699
|
const McpScreen = ({ store, installer, mode = "install" }) => {
|
|
2620
2700
|
useSyncExternalStore((cb) => store.subscribe(cb), () => store.getSnapshot());
|
|
@@ -2625,6 +2705,7 @@ const McpScreen = ({ store, installer, mode = "install" }) => {
|
|
|
2625
2705
|
const [selectedClientNames, setSelectedClientNames] = useState([]);
|
|
2626
2706
|
const [resultClients, setResultClients] = useState([]);
|
|
2627
2707
|
const [pluginClients, setPluginClients] = useState([]);
|
|
2708
|
+
const [installMode, setInstallMode] = useState("custom");
|
|
2628
2709
|
useEffect(() => {
|
|
2629
2710
|
(async () => {
|
|
2630
2711
|
try {
|
|
@@ -2642,23 +2723,34 @@ const McpScreen = ({ store, installer, mode = "install" }) => {
|
|
|
2642
2723
|
}
|
|
2643
2724
|
})();
|
|
2644
2725
|
}, [installer]);
|
|
2645
|
-
const
|
|
2726
|
+
const proceedAfterClientPick = (clientNames, chosenMode) => {
|
|
2646
2727
|
setSelectedClientNames(clientNames);
|
|
2728
|
+
if (chosenMode === "all") {
|
|
2729
|
+
doInstall(clientNames, [...ALL_FEATURE_VALUES]);
|
|
2730
|
+
return;
|
|
2731
|
+
}
|
|
2647
2732
|
if (store.session.mcpFeatures) {
|
|
2648
2733
|
doInstall(clientNames, store.session.mcpFeatures);
|
|
2649
2734
|
return;
|
|
2650
2735
|
}
|
|
2651
|
-
if (
|
|
2652
|
-
|
|
2653
|
-
})) {
|
|
2654
|
-
doInstall(clientNames, []);
|
|
2736
|
+
if (clientNames.some((name) => clients.find((c) => c.name === name)?.finish)) {
|
|
2737
|
+
setPhase("connector");
|
|
2655
2738
|
return;
|
|
2656
2739
|
}
|
|
2657
2740
|
setPhase("feature-select");
|
|
2658
2741
|
};
|
|
2659
2742
|
const handleConfirm = () => {
|
|
2660
2743
|
if (isRemove) doRemove();
|
|
2661
|
-
else if (clients.length === 1)
|
|
2744
|
+
else if (clients.length === 1) proceedAfterClientPick([clients[0].name], "custom");
|
|
2745
|
+
else setPhase("pick");
|
|
2746
|
+
};
|
|
2747
|
+
const handleTriStateChoice = (choice) => {
|
|
2748
|
+
if (choice === "skip") {
|
|
2749
|
+
handleSkip();
|
|
2750
|
+
return;
|
|
2751
|
+
}
|
|
2752
|
+
setInstallMode(choice);
|
|
2753
|
+
if (clients.length === 1) proceedAfterClientPick([clients[0].name], choice);
|
|
2662
2754
|
else setPhase("pick");
|
|
2663
2755
|
};
|
|
2664
2756
|
const handleSkip = () => {
|
|
@@ -2668,17 +2760,25 @@ const McpScreen = ({ store, installer, mode = "install" }) => {
|
|
|
2668
2760
|
setPhase("working");
|
|
2669
2761
|
let mcpResult = [];
|
|
2670
2762
|
let pluginResult = [];
|
|
2671
|
-
|
|
2763
|
+
const pluginCapableSet = new Set(clients.filter((c) => c.supportsPlugin).map((c) => c.name));
|
|
2764
|
+
const pluginCapableNames = names.filter((n) => pluginCapableSet.has(n));
|
|
2765
|
+
const directNames = names.filter((n) => !pluginCapableSet.has(n));
|
|
2766
|
+
if (installMode === "all") {
|
|
2767
|
+
try {
|
|
2768
|
+
mcpResult = await installer.install(directNames, features, store.session.apiKey);
|
|
2769
|
+
} catch {}
|
|
2770
|
+
try {
|
|
2771
|
+
pluginResult = await installer.installPlugins(pluginCapableNames);
|
|
2772
|
+
} catch {}
|
|
2773
|
+
} else try {
|
|
2672
2774
|
mcpResult = await installer.install(names, features, store.session.apiKey);
|
|
2673
2775
|
} catch {}
|
|
2674
|
-
try {
|
|
2675
|
-
pluginResult = await installer.installPlugins(names);
|
|
2676
|
-
} catch {}
|
|
2677
2776
|
setResultClients(mcpResult);
|
|
2678
2777
|
setPluginClients(pluginResult);
|
|
2679
2778
|
setPhase("done");
|
|
2680
|
-
const outcome = mcpResult.length > 0 ? "installed" : "failed";
|
|
2681
|
-
|
|
2779
|
+
const outcome = mcpResult.length + pluginResult.length > 0 ? "installed" : "failed";
|
|
2780
|
+
const featuresReport = reportFeatures(features ?? [...ALL_FEATURE_VALUES]);
|
|
2781
|
+
setTimeout(() => markDone(store, outcome, [...mcpResult, ...pluginResult], featuresReport), 2e3);
|
|
2682
2782
|
};
|
|
2683
2783
|
const doRemove = async () => {
|
|
2684
2784
|
setPhase("working");
|
|
@@ -2746,7 +2846,26 @@ const McpScreen = ({ store, installer, mode = "install" }) => {
|
|
|
2746
2846
|
}),
|
|
2747
2847
|
/* @__PURE__ */ jsx(Box, {
|
|
2748
2848
|
marginTop: 1,
|
|
2749
|
-
children: /* @__PURE__ */ jsx(
|
|
2849
|
+
children: !isRemove && !store.session.mcpFeatures ? /* @__PURE__ */ jsx(PickerMenu, {
|
|
2850
|
+
message: `Install the PostHog MCP server${clients.some((c) => c.supportsPlugin) ? " and plugin" : ""}?`,
|
|
2851
|
+
options: [
|
|
2852
|
+
{
|
|
2853
|
+
label: "Install with all features",
|
|
2854
|
+
value: "all",
|
|
2855
|
+
hint: "recommended"
|
|
2856
|
+
},
|
|
2857
|
+
{
|
|
2858
|
+
label: "Customize features",
|
|
2859
|
+
value: "custom"
|
|
2860
|
+
},
|
|
2861
|
+
{
|
|
2862
|
+
label: "No thanks",
|
|
2863
|
+
value: "skip"
|
|
2864
|
+
}
|
|
2865
|
+
],
|
|
2866
|
+
mode: "single",
|
|
2867
|
+
onSelect: (choice) => handleTriStateChoice(choice)
|
|
2868
|
+
}) : /* @__PURE__ */ jsx(ConfirmationInput, {
|
|
2750
2869
|
message: `${isRemove ? "Remove" : "Install"} the PostHog MCP server${clients.some((c) => c.supportsPlugin) ? " and plugin" : ""}?`,
|
|
2751
2870
|
confirmLabel: isRemove ? "Remove" : "Install",
|
|
2752
2871
|
cancelLabel: "No thanks",
|
|
@@ -2756,76 +2875,107 @@ const McpScreen = ({ store, installer, mode = "install" }) => {
|
|
|
2756
2875
|
})
|
|
2757
2876
|
] }),
|
|
2758
2877
|
phase === "pick" && /* @__PURE__ */ jsx(PickerMenu, {
|
|
2759
|
-
message: "Select editor to install MCP server",
|
|
2878
|
+
message: installMode === "all" ? "Select editor to install" : "Select editor to install MCP server",
|
|
2760
2879
|
options: clients.map((c) => ({
|
|
2761
2880
|
label: c.name,
|
|
2762
|
-
value: c.name
|
|
2881
|
+
value: c.name,
|
|
2882
|
+
exclusive: Boolean(c.finish),
|
|
2883
|
+
hint: installMode === "all" ? c.finish ? "connector" : c.supportsPlugin ? "plugin" : "MCP" : void 0
|
|
2763
2884
|
})),
|
|
2764
2885
|
mode: "multi",
|
|
2765
2886
|
onSelect: (selected) => {
|
|
2766
|
-
|
|
2887
|
+
proceedAfterClientPick(Array.isArray(selected) ? selected : [selected], installMode);
|
|
2767
2888
|
}
|
|
2768
2889
|
}),
|
|
2769
2890
|
phase === "feature-select" && /* @__PURE__ */ jsx(GroupedPickerMenu, {
|
|
2770
2891
|
message: "Select features to enable",
|
|
2771
2892
|
groups: AVAILABLE_FEATURES,
|
|
2772
|
-
initialSelected: [
|
|
2893
|
+
initialSelected: [],
|
|
2773
2894
|
onSelect: (features) => {
|
|
2774
2895
|
doInstall(selectedClientNames, features);
|
|
2775
2896
|
}
|
|
2776
2897
|
}),
|
|
2898
|
+
phase === "connector" && /* @__PURE__ */ jsxs(Box, {
|
|
2899
|
+
flexDirection: "column",
|
|
2900
|
+
children: [/* @__PURE__ */ jsx(Box, {
|
|
2901
|
+
marginBottom: 1,
|
|
2902
|
+
children: /* @__PURE__ */ jsx(Text, {
|
|
2903
|
+
dimColor: true,
|
|
2904
|
+
children: "You'll choose which features and tools to enable in Claude's UI after connecting."
|
|
2905
|
+
})
|
|
2906
|
+
}), /* @__PURE__ */ jsx(ConnectorContinue, { onContinue: () => void doInstall(selectedClientNames, []) })]
|
|
2907
|
+
}),
|
|
2777
2908
|
phase === "working" && /* @__PURE__ */ jsxs(Text, {
|
|
2778
2909
|
dimColor: true,
|
|
2779
2910
|
children: [isRemove ? "Removing" : "Installing", " MCP server..."]
|
|
2780
2911
|
}),
|
|
2781
2912
|
phase === "done" && /* @__PURE__ */ jsx(Box, {
|
|
2782
2913
|
flexDirection: "column",
|
|
2783
|
-
children: installedNow.length
|
|
2914
|
+
children: installedNow.length + pluginClients.length + finishNotes.length === 0 ? /* @__PURE__ */ jsxs(Text, {
|
|
2784
2915
|
dimColor: true,
|
|
2785
2916
|
children: [isRemove ? "Removal" : "Installation", " skipped."]
|
|
2786
|
-
}) : /* @__PURE__ */ jsxs(Fragment$1, { children: [
|
|
2787
|
-
|
|
2788
|
-
|
|
2789
|
-
|
|
2790
|
-
"✔",
|
|
2791
|
-
|
|
2792
|
-
!isRemove && pluginClients.length > 0 ? " and plugin" : "",
|
|
2917
|
+
}) : /* @__PURE__ */ jsxs(Fragment$1, { children: [
|
|
2918
|
+
pluginClients.length > 0 && /* @__PURE__ */ jsxs(Fragment$1, { children: [/* @__PURE__ */ jsxs(Text, {
|
|
2919
|
+
color: "green",
|
|
2920
|
+
bold: true,
|
|
2921
|
+
children: ["✔", " Plugin installed for:"]
|
|
2922
|
+
}), pluginClients.map((name, i) => /* @__PURE__ */ jsxs(Text, { children: [
|
|
2793
2923
|
" ",
|
|
2794
|
-
|
|
2795
|
-
"
|
|
2796
|
-
|
|
2797
|
-
|
|
2798
|
-
|
|
2799
|
-
|
|
2800
|
-
|
|
2801
|
-
|
|
2802
|
-
|
|
2803
|
-
|
|
2804
|
-
|
|
2805
|
-
|
|
2806
|
-
|
|
2807
|
-
|
|
2808
|
-
|
|
2809
|
-
|
|
2810
|
-
|
|
2811
|
-
|
|
2812
|
-
|
|
2813
|
-
|
|
2814
|
-
|
|
2815
|
-
|
|
2816
|
-
|
|
2924
|
+
"•",
|
|
2925
|
+
" ",
|
|
2926
|
+
name
|
|
2927
|
+
] }, `p-${i}`))] }),
|
|
2928
|
+
installedNow.length > 0 && /* @__PURE__ */ jsxs(Fragment$1, { children: [/* @__PURE__ */ jsxs(Text, {
|
|
2929
|
+
color: "green",
|
|
2930
|
+
bold: true,
|
|
2931
|
+
children: [
|
|
2932
|
+
"✔",
|
|
2933
|
+
" MCP server",
|
|
2934
|
+
" ",
|
|
2935
|
+
isRemove ? "removed from" : "installed for",
|
|
2936
|
+
":"
|
|
2937
|
+
]
|
|
2938
|
+
}), installedNow.map((name, i) => /* @__PURE__ */ jsxs(Text, { children: [
|
|
2939
|
+
" ",
|
|
2940
|
+
"•",
|
|
2941
|
+
" ",
|
|
2942
|
+
name
|
|
2943
|
+
] }, `m-${i}`))] }),
|
|
2944
|
+
finishNotes.map((note) => /* @__PURE__ */ jsxs(Box, {
|
|
2945
|
+
flexDirection: "column",
|
|
2946
|
+
marginTop: 1,
|
|
2947
|
+
children: [
|
|
2948
|
+
/* @__PURE__ */ jsxs(Text, {
|
|
2949
|
+
color: "green",
|
|
2950
|
+
bold: true,
|
|
2951
|
+
children: [
|
|
2952
|
+
"✔",
|
|
2953
|
+
" ",
|
|
2954
|
+
note.name,
|
|
2955
|
+
" ",
|
|
2956
|
+
"—",
|
|
2957
|
+
" installs a PostHog connector:"
|
|
2958
|
+
]
|
|
2959
|
+
}),
|
|
2960
|
+
/* @__PURE__ */ jsxs(Text, { children: [
|
|
2961
|
+
" ",
|
|
2962
|
+
"Opened ",
|
|
2963
|
+
/* @__PURE__ */ jsx(Text, {
|
|
2964
|
+
color: "cyan",
|
|
2965
|
+
children: note.url
|
|
2966
|
+
})
|
|
2967
|
+
] }),
|
|
2968
|
+
/* @__PURE__ */ jsxs(Text, {
|
|
2969
|
+
dimColor: true,
|
|
2970
|
+
children: [" ", note.instruction]
|
|
2971
|
+
}),
|
|
2972
|
+
/* @__PURE__ */ jsxs(Text, {
|
|
2973
|
+
dimColor: true,
|
|
2974
|
+
children: [" ", "(If it didn't open, paste the URL above.)"]
|
|
2817
2975
|
})
|
|
2818
|
-
]
|
|
2819
|
-
|
|
2820
|
-
|
|
2821
|
-
children: [" ", note.instruction]
|
|
2822
|
-
}),
|
|
2823
|
-
/* @__PURE__ */ jsxs(Text, {
|
|
2824
|
-
dimColor: true,
|
|
2825
|
-
children: [" ", "(If it didn't open, paste the URL above.)"]
|
|
2826
|
-
})
|
|
2827
|
-
]
|
|
2828
|
-
}, note.name))] })
|
|
2976
|
+
]
|
|
2977
|
+
}, note.name))
|
|
2978
|
+
] })
|
|
2829
2979
|
})
|
|
2830
2980
|
]
|
|
2831
2981
|
})]
|
|
@@ -3656,6 +3806,13 @@ var neutralCrossSell = [{
|
|
|
3656
3806
|
"prompt": "List the top errors my users hit this week.",
|
|
3657
3807
|
"description": "Built-in error tracking — no separate tool."
|
|
3658
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
|
+
};
|
|
3659
3816
|
//#endregion
|
|
3660
3817
|
//#region src/lib/mcp-role-prompts.ts
|
|
3661
3818
|
/**
|
|
@@ -3690,6 +3847,7 @@ const GENERIC_FOLLOW_UPS = genericFollowUps;
|
|
|
3690
3847
|
const DEEP_DIVE_FOLLOW_UPS = deepDiveFollowUps;
|
|
3691
3848
|
const CROSS_SELL_BY_ROLE = crossSellByRole;
|
|
3692
3849
|
const NEUTRAL_CROSS_SELL = neutralCrossSell;
|
|
3850
|
+
const SLACK_APP = slackApp;
|
|
3693
3851
|
const INTEGRATION_FAMILY = {
|
|
3694
3852
|
nextjs: "fullstack",
|
|
3695
3853
|
nuxt: "fullstack",
|
|
@@ -3803,6 +3961,20 @@ function getCrossSellPrompts(role) {
|
|
|
3803
3961
|
if (!isTailoredRole(role)) return NEUTRAL_CROSS_SELL;
|
|
3804
3962
|
return CROSS_SELL_BY_ROLE[role];
|
|
3805
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
|
+
}
|
|
3806
3978
|
//#endregion
|
|
3807
3979
|
//#region src/ui/tui/screens/McpSuggestedPromptsScreen.tsx
|
|
3808
3980
|
/**
|
|
@@ -3843,6 +4015,25 @@ function getCrossSellPrompts(role) {
|
|
|
3843
4015
|
* forces a successful login first). A defensive throw protects the
|
|
3844
4016
|
* Running useEffect against a state-machine bug.
|
|
3845
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 || {});
|
|
3846
4037
|
const MAX_PROMPT_RUNS = 5;
|
|
3847
4038
|
const FOLLOW_UP_DELAY_MS = 3e3;
|
|
3848
4039
|
const McpSuggestedPromptsScreen = ({ store, services }) => {
|
|
@@ -3851,8 +4042,9 @@ const McpSuggestedPromptsScreen = ({ store, services }) => {
|
|
|
3851
4042
|
const kit = getRolePrompts(session.roleAtOrganization, session.integration);
|
|
3852
4043
|
const crossSell = useMemo(() => getCrossSellPrompts(session.roleAtOrganization), [session.roleAtOrganization]);
|
|
3853
4044
|
const greeting = useMemo(() => getRoleGreeting(session.roleAtOrganization), [session.roleAtOrganization]);
|
|
3854
|
-
const [phase, setPhase] = useState("choose");
|
|
4045
|
+
const [phase, setPhase] = useState(() => store.session.credentials ? "choose" : "authenticating");
|
|
3855
4046
|
const [loginError, setLoginError] = useState(null);
|
|
4047
|
+
const startedTutorialRef = useRef(false);
|
|
3856
4048
|
const [runningPrompt, setRunningPrompt] = useState(null);
|
|
3857
4049
|
const [runChunks, setRunChunks] = useState([]);
|
|
3858
4050
|
const [runStartedAt, setRunStartedAt] = useState(null);
|
|
@@ -3874,7 +4066,7 @@ const McpSuggestedPromptsScreen = ({ store, services }) => {
|
|
|
3874
4066
|
store.setRoleAtOrganization(roleAtOrganization);
|
|
3875
4067
|
store.setApiUser(user);
|
|
3876
4068
|
store.setLoginUrl(null);
|
|
3877
|
-
setPhase("greeting");
|
|
4069
|
+
setPhase(startedTutorialRef.current ? "greeting" : "choose");
|
|
3878
4070
|
} catch (err) {
|
|
3879
4071
|
if (cancelled) return;
|
|
3880
4072
|
const message = err instanceof Error ? err.message : String(err);
|
|
@@ -3892,6 +4084,28 @@ const McpSuggestedPromptsScreen = ({ store, services }) => {
|
|
|
3892
4084
|
services,
|
|
3893
4085
|
store
|
|
3894
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
|
+
]);
|
|
3895
4109
|
useEffect(() => {
|
|
3896
4110
|
if (phase !== "running") return;
|
|
3897
4111
|
if (!runningPrompt) return;
|
|
@@ -3977,7 +4191,11 @@ const McpSuggestedPromptsScreen = ({ store, services }) => {
|
|
|
3977
4191
|
setLoginError(null);
|
|
3978
4192
|
if (choice === "login") {
|
|
3979
4193
|
analytics.wizardCapture("mcp suggested prompts choose", { choice: "login" });
|
|
3980
|
-
|
|
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(() => {});
|
|
3981
4199
|
} else {
|
|
3982
4200
|
analytics.wizardCapture("mcp suggested prompts choose", { choice: "exit" });
|
|
3983
4201
|
enterGoodbye();
|
|
@@ -4013,9 +4231,10 @@ const McpSuggestedPromptsScreen = ({ store, services }) => {
|
|
|
4013
4231
|
{
|
|
4014
4232
|
match: "escape",
|
|
4015
4233
|
label: "esc",
|
|
4016
|
-
action: phase === "goodbye" ? "close" : "exit",
|
|
4234
|
+
action: phase === "goodbye" ? "close" : phase === "authenticating" ? "cancel" : "exit",
|
|
4017
4235
|
handler: () => {
|
|
4018
4236
|
if (phase === "goodbye") closeWizard();
|
|
4237
|
+
else if (phase === "authenticating") setPhase("choose");
|
|
4019
4238
|
else if (phase === "running" || phase === "prompt-picker" || phase === "follow-up" || phase === "greeting") enterGoodbye();
|
|
4020
4239
|
}
|
|
4021
4240
|
},
|
|
@@ -4049,6 +4268,7 @@ const McpSuggestedPromptsScreen = ({ store, services }) => {
|
|
|
4049
4268
|
children: [
|
|
4050
4269
|
phase === "choose" && /* @__PURE__ */ jsx(ChoosePhase, {
|
|
4051
4270
|
error: loginError,
|
|
4271
|
+
slackConnected,
|
|
4052
4272
|
onSelect: handleChoice
|
|
4053
4273
|
}),
|
|
4054
4274
|
phase === "authenticating" && /* @__PURE__ */ jsx(AuthenticatingPhase, { loginUrl: session.loginUrl }),
|
|
@@ -4111,71 +4331,112 @@ const McpSuggestedPromptsScreen = ({ store, services }) => {
|
|
|
4111
4331
|
})
|
|
4112
4332
|
});
|
|
4113
4333
|
};
|
|
4114
|
-
const ChoosePhase = ({ error, onSelect }) =>
|
|
4115
|
-
|
|
4116
|
-
|
|
4117
|
-
|
|
4118
|
-
|
|
4119
|
-
|
|
4120
|
-
|
|
4121
|
-
|
|
4122
|
-
|
|
4123
|
-
|
|
4124
|
-
|
|
4125
|
-
|
|
4126
|
-
|
|
4127
|
-
|
|
4128
|
-
|
|
4129
|
-
|
|
4130
|
-
/* @__PURE__ */ jsxs(Text, { children: [/* @__PURE__ */ jsx(Text, {
|
|
4131
|
-
color: "cyan",
|
|
4132
|
-
children: Icons.diamond
|
|
4133
|
-
}), " Build dashboards"] }),
|
|
4134
|
-
/* @__PURE__ */ jsxs(Text, { children: [/* @__PURE__ */ jsx(Text, {
|
|
4135
|
-
color: "cyan",
|
|
4136
|
-
children: Icons.diamond
|
|
4137
|
-
}), " Run SQL queries"] }),
|
|
4138
|
-
/* @__PURE__ */ jsxs(Text, { children: [/* @__PURE__ */ jsx(Text, {
|
|
4139
|
-
color: "cyan",
|
|
4140
|
-
children: Icons.diamond
|
|
4141
|
-
}), " Deploy feature flags"] }),
|
|
4142
|
-
/* @__PURE__ */ jsxs(Text, { children: [/* @__PURE__ */ jsx(Text, {
|
|
4143
|
-
color: "cyan",
|
|
4144
|
-
children: Icons.diamond
|
|
4145
|
-
}), " Debug exceptions and errors"] }),
|
|
4146
|
-
/* @__PURE__ */ jsxs(Text, { children: [/* @__PURE__ */ jsx(Text, {
|
|
4147
|
-
color: "cyan",
|
|
4148
|
-
children: Icons.diamond
|
|
4149
|
-
}), " And lots more..."] })
|
|
4150
|
-
]
|
|
4151
|
-
}),
|
|
4152
|
-
/* @__PURE__ */ jsx(Box, {
|
|
4153
|
-
marginTop: 1,
|
|
4154
|
-
children: /* @__PURE__ */ jsx(Text, { children: "Want a live demo using real data from your project?" })
|
|
4155
|
-
}),
|
|
4156
|
-
/* @__PURE__ */ jsx(Box, { children: /* @__PURE__ */ jsx(PickerMenu, {
|
|
4157
|
-
options: [{
|
|
4158
|
-
label: "Start MCP tutorial",
|
|
4159
|
-
value: "login"
|
|
4160
|
-
}, {
|
|
4161
|
-
label: "Exit",
|
|
4162
|
-
value: "exit"
|
|
4163
|
-
}],
|
|
4164
|
-
onSelect
|
|
4165
|
-
}) }),
|
|
4166
|
-
error && /* @__PURE__ */ jsx(Box, {
|
|
4167
|
-
marginTop: 1,
|
|
4168
|
-
children: /* @__PURE__ */ jsxs(Text, {
|
|
4169
|
-
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",
|
|
4170
4350
|
children: [
|
|
4171
|
-
|
|
4172
|
-
|
|
4173
|
-
|
|
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..."] })
|
|
4174
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
|
+
})
|
|
4175
4436
|
})
|
|
4176
|
-
|
|
4177
|
-
|
|
4178
|
-
}
|
|
4437
|
+
]
|
|
4438
|
+
});
|
|
4439
|
+
};
|
|
4179
4440
|
const AuthenticatingPhase = ({ loginUrl }) => /* @__PURE__ */ jsxs(Box, {
|
|
4180
4441
|
flexDirection: "column",
|
|
4181
4442
|
children: [/* @__PURE__ */ jsx(LoadingBox, { message: "Waiting for authentication..." }), loginUrl && /* @__PURE__ */ jsx(Box, {
|
|
@@ -4513,7 +4774,7 @@ const GoodbyePhase = ({ installedClients, role, integration, engaged, onClose })
|
|
|
4513
4774
|
label: "Close",
|
|
4514
4775
|
value: "close"
|
|
4515
4776
|
}],
|
|
4516
|
-
onSelect: onClose
|
|
4777
|
+
onSelect: () => onClose()
|
|
4517
4778
|
})
|
|
4518
4779
|
]
|
|
4519
4780
|
});
|
|
@@ -5379,6 +5640,6 @@ const AUDIT_3000_AREA_SLIDES = [
|
|
|
5379
5640
|
}
|
|
5380
5641
|
];
|
|
5381
5642
|
//#endregion
|
|
5382
|
-
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 };
|
|
5383
5644
|
|
|
5384
|
-
//# sourceMappingURL=slides-
|
|
5645
|
+
//# sourceMappingURL=slides-BEshbXqG.js.map
|