@posthog/wizard 2.16.1 → 2.17.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/dist/{TextBlock-CdeZog_6.js → TextBlock-D0Ep3zC9.js} +2 -2
- package/dist/{TextBlock-CdeZog_6.js.map → TextBlock-D0Ep3zC9.js.map} +1 -1
- package/dist/{add-mcp-server-to-clients-BS6Rjcwh.js → add-mcp-server-to-clients-D4PK6ulR.js} +38 -5
- package/dist/add-mcp-server-to-clients-D4PK6ulR.js.map +1 -0
- package/dist/{agent-interface-B4eUlMso.js → agent-interface-7t5DBo2A.js} +7 -7
- package/dist/{agent-interface-B4eUlMso.js.map → agent-interface-7t5DBo2A.js.map} +1 -1
- package/dist/{agent-runner-BxqiKVEf.js → agent-runner-CTkKLVhp.js} +8 -7
- package/dist/{agent-runner-BxqiKVEf.js.map → agent-runner-CTkKLVhp.js.map} +1 -1
- package/dist/{analytics-DUuUurR3.js → analytics-DN_Gy87F.js} +2 -2
- package/dist/{analytics-DUuUurR3.js.map → analytics-DN_Gy87F.js.map} +1 -1
- package/dist/{api-CGJ1iGps.js → api-serd0SMY.js} +14 -4
- package/dist/{api-CGJ1iGps.js.map → api-serd0SMY.js.map} +1 -1
- package/dist/bin.js +44 -43
- package/dist/bin.js.map +1 -1
- package/dist/{ci-install-DD7WMmIF.js → ci-install-BbJ7c3WK.js} +4 -4
- package/dist/{ci-install-DD7WMmIF.js.map → ci-install-BbJ7c3WK.js.map} +1 -1
- package/dist/{debug-Cd0hPlZy.js → debug-BI-Js0PB.js} +1 -1
- package/dist/{debug-ubpO6102.js → debug-Bx7nvCWW.js} +2 -2
- package/dist/{debug-ubpO6102.js.map → debug-Bx7nvCWW.js.map} +1 -1
- package/dist/{defaults-zrYmZ2ID.js → defaults-CPH6eWhN.js} +1 -1
- package/dist/{defaults-zrYmZ2ID.js.map → defaults-CPH6eWhN.js.map} +1 -1
- package/dist/{env-api-key-DEl3LJBv.js → env-api-key-B3gE9Un0.js} +1 -1
- package/dist/{env-api-key-DEl3LJBv.js.map → env-api-key-B3gE9Un0.js.map} +1 -1
- package/dist/{environment-BAaC5THg.js → environment-CiZVSSYt.js} +3 -3
- package/dist/{environment-BAaC5THg.js.map → environment-CiZVSSYt.js.map} +1 -1
- package/dist/{file-utils-DPmgn9Vm.js → file-utils-Dy9JncCo.js} +1 -1
- package/dist/{file-utils-DPmgn9Vm.js.map → file-utils-Dy9JncCo.js.map} +1 -1
- package/dist/{interactive-BaMAq88Q.js → interactive-BwIzklw0.js} +2 -2
- package/dist/{interactive-BaMAq88Q.js.map → interactive-BwIzklw0.js.map} +1 -1
- package/dist/{mcp-prompt-streaming-clGsVw8q.js → mcp-prompt-streaming-8U9Qs9EV.js} +62 -12
- package/dist/mcp-prompt-streaming-8U9Qs9EV.js.map +1 -0
- package/dist/{non-interactive-l2AKE3jD.js → non-interactive-DTaZnVq_.js} +2 -2
- package/dist/{non-interactive-l2AKE3jD.js.map → non-interactive-DTaZnVq_.js.map} +1 -1
- package/dist/{package-json-Cynjr9k4.js → package-json-DCuoye-H.js} +8 -2
- package/dist/{package-json-Cynjr9k4.js.map → package-json-DCuoye-H.js.map} +1 -1
- package/dist/{package-manager-BqsJK3ej.js → package-manager-CKQLR20D.js} +2 -2
- package/dist/{package-manager-BqsJK3ej.js.map → package-manager-CKQLR20D.js.map} +1 -1
- package/dist/{playground-DlE5RNfE.js → playground-CR81Mwe3.js} +21 -10
- package/dist/playground-CR81Mwe3.js.map +1 -0
- package/dist/{posthog-DWL8uOcl.js → posthog-BrLFkaji.js} +1 -1
- package/dist/{posthog-DWL8uOcl.js.map → posthog-BrLFkaji.js.map} +1 -1
- package/dist/{posthog-integration-Bf_vtWI9.js → posthog-integration-Bv7987YJ.js} +13 -12
- package/dist/{posthog-integration-Bf_vtWI9.js.map → posthog-integration-Bv7987YJ.js.map} +1 -1
- package/dist/{provisioning-D_hAuxUN.js → provisioning-C96Kw-9D.js} +9 -4
- package/dist/{provisioning-D_hAuxUN.js.map → provisioning-C96Kw-9D.js.map} +1 -1
- package/dist/{registry-DKgYqROt.js → registry-B9k73FKR.js} +5 -5
- package/dist/{registry-DKgYqROt.js.map → registry-B9k73FKR.js.map} +1 -1
- package/dist/{setup-utils-D-uTycLX.js → setup-utils-Bpfsap9L.js} +80 -39
- package/dist/setup-utils-Bpfsap9L.js.map +1 -0
- package/dist/{skill-CnOQAZXp.js → skill-CPqcV8zp.js} +2 -2
- package/dist/{skill-CnOQAZXp.js.map → skill-CPqcV8zp.js.map} +1 -1
- package/dist/{slides-CL1mv_Kq.js → slides-DRbBgsdd.js} +1426 -181
- package/dist/slides-DRbBgsdd.js.map +1 -0
- package/dist/{start-tui-DXrv6cof.js → start-tui-BZ7rEf3e.js} +28 -17
- package/dist/start-tui-BZ7rEf3e.js.map +1 -0
- package/dist/{steps-CgScwqso.js → steps-DDx35170.js} +6 -6
- package/dist/{steps-CgScwqso.js.map → steps-DDx35170.js.map} +1 -1
- package/dist/{task-stream-CF6QMVMv.js → task-stream-BI8rJg9H.js} +3 -3
- package/dist/{task-stream-CF6QMVMv.js.map → task-stream-BI8rJg9H.js.map} +1 -1
- package/dist/{telemetry-v6O12Bep.js → telemetry-ByYtIfW0.js} +2 -2
- package/dist/{telemetry-v6O12Bep.js.map → telemetry-ByYtIfW0.js.map} +1 -1
- package/dist/urls-CTCJIxbR.js +35 -0
- package/dist/urls-CTCJIxbR.js.map +1 -0
- package/dist/{wizard-abort-iTaJ8wC8.js → wizard-abort-CY0ibdq1.js} +3 -3
- package/dist/{wizard-abort-iTaJ8wC8.js.map → wizard-abort-CY0ibdq1.js.map} +1 -1
- package/dist/{wizard-abort-BGoBKgvC.js → wizard-abort-QdRxGQp_.js} +1 -1
- package/dist/{wizard-session-gsn8Z3bZ.js → wizard-session-d27JGRGi.js} +1 -1
- package/dist/{wizard-session-gsn8Z3bZ.js.map → wizard-session-d27JGRGi.js.map} +1 -1
- package/dist/{wizard-session-7tMjgOvP.js → wizard-session-y304gEEI.js} +1 -1
- package/package.json +1 -1
- package/dist/add-mcp-server-to-clients-BS6Rjcwh.js.map +0 -1
- package/dist/api-B8OR0N1V.js +0 -2
- package/dist/mcp-prompt-streaming-clGsVw8q.js.map +0 -1
- package/dist/package-json-CumwmZpv.js +0 -2
- package/dist/playground-DlE5RNfE.js.map +0 -1
- package/dist/provisioning-BlBnlcFd.js +0 -2
- package/dist/setup-utils-BHZEdkNZ.js +0 -2
- package/dist/setup-utils-D-uTycLX.js.map +0 -1
- package/dist/slides-CL1mv_Kq.js.map +0 -1
- package/dist/start-tui-DXrv6cof.js.map +0 -1
|
@@ -1,11 +1,11 @@
|
|
|
1
|
-
import { g as SERVICE_LABELS, s as logToFile } from "./debug-
|
|
1
|
+
import { g as SERVICE_LABELS, s as logToFile } from "./debug-Bx7nvCWW.js";
|
|
2
2
|
import { n as isTaskStatus } from "./wizard-ui-YdGFRyu_.js";
|
|
3
|
-
import { n as sessionProperties, t as analytics } from "./analytics-
|
|
4
|
-
import { i as buildSession } from "./wizard-session-
|
|
5
|
-
import {
|
|
6
|
-
import { a as isObjectBlock, i as isLinesBlock, n as computeVisibleRange, o as Colors, r as isClearBlock, s as Icons, t as TextBlock } from "./TextBlock-
|
|
3
|
+
import { n as sessionProperties, t as analytics } from "./analytics-DN_Gy87F.js";
|
|
4
|
+
import { i as buildSession } from "./wizard-session-d27JGRGi.js";
|
|
5
|
+
import { v as AUDIT_SEVERITY_STYLE } from "./agent-interface-7t5DBo2A.js";
|
|
6
|
+
import { a as isObjectBlock, i as isLinesBlock, n as computeVisibleRange, o as Colors, r as isClearBlock, s as Icons, t as TextBlock } from "./TextBlock-D0Ep3zC9.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, t as ALL_FEATURE_VALUES } from "./defaults-CPH6eWhN.js";
|
|
9
9
|
import * as fs$1 from "fs";
|
|
10
10
|
import { Box, Text, measureElement, useInput, useStdout } from "ink";
|
|
11
11
|
import { Component, Fragment, createContext, useCallback, useContext, useEffect, useMemo, useRef, useState, useSyncExternalStore } from "react";
|
|
@@ -2628,8 +2628,17 @@ const McpScreen = ({ store, installer, mode = "install" }) => {
|
|
|
2628
2628
|
}, [installer]);
|
|
2629
2629
|
const proceedToFeatureSelectOrInstall = (clientNames) => {
|
|
2630
2630
|
setSelectedClientNames(clientNames);
|
|
2631
|
-
if (store.session.mcpFeatures)
|
|
2632
|
-
|
|
2631
|
+
if (store.session.mcpFeatures) {
|
|
2632
|
+
doInstall(clientNames, store.session.mcpFeatures);
|
|
2633
|
+
return;
|
|
2634
|
+
}
|
|
2635
|
+
if (!clientNames.some((name) => {
|
|
2636
|
+
return !clients.find((c) => c.name === name)?.finish;
|
|
2637
|
+
})) {
|
|
2638
|
+
doInstall(clientNames, []);
|
|
2639
|
+
return;
|
|
2640
|
+
}
|
|
2641
|
+
setPhase("feature-select");
|
|
2633
2642
|
};
|
|
2634
2643
|
const handleConfirm = () => {
|
|
2635
2644
|
if (isRemove) doRemove();
|
|
@@ -2668,6 +2677,17 @@ const McpScreen = ({ store, installer, mode = "install" }) => {
|
|
|
2668
2677
|
const outcome = result.length > 0 ? "installed" : "failed";
|
|
2669
2678
|
setTimeout(() => markDone(store, outcome, result), 2e3);
|
|
2670
2679
|
};
|
|
2680
|
+
const installValueBullets = [
|
|
2681
|
+
"Ask your agent: \"List my feature flags\" — and it does.",
|
|
2682
|
+
"Run SQL, build dashboards, ship flags, all from your IDE.",
|
|
2683
|
+
"No copy-pasting tokens or context. Your agent has the keys."
|
|
2684
|
+
];
|
|
2685
|
+
const finishNotes = clients.flatMap((c) => c.finish && resultClients.includes(c.name) ? [{
|
|
2686
|
+
name: c.name,
|
|
2687
|
+
url: c.finish.url,
|
|
2688
|
+
instruction: c.finish.instruction
|
|
2689
|
+
}] : []);
|
|
2690
|
+
const installedNow = resultClients.filter((name) => !finishNotes.some((n) => n.name === name));
|
|
2671
2691
|
return /* @__PURE__ */ jsxs(Box, {
|
|
2672
2692
|
flexDirection: "column",
|
|
2673
2693
|
flexGrow: 1,
|
|
@@ -2695,11 +2715,7 @@ const McpScreen = ({ store, installer, mode = "install" }) => {
|
|
|
2695
2715
|
!isRemove && /* @__PURE__ */ jsx(Box, {
|
|
2696
2716
|
flexDirection: "column",
|
|
2697
2717
|
marginBottom: 1,
|
|
2698
|
-
children:
|
|
2699
|
-
"Ask your agent: \"List my feature flags\" — and it does.",
|
|
2700
|
-
"Run SQL, build dashboards, ship flags, all from your IDE.",
|
|
2701
|
-
"No copy-pasting tokens or context. Your agent has the keys."
|
|
2702
|
-
].map((bullet) => /* @__PURE__ */ jsxs(Text, {
|
|
2718
|
+
children: installValueBullets.map((bullet) => /* @__PURE__ */ jsxs(Text, {
|
|
2703
2719
|
dimColor: true,
|
|
2704
2720
|
children: [
|
|
2705
2721
|
"•",
|
|
@@ -2748,7 +2764,10 @@ const McpScreen = ({ store, installer, mode = "install" }) => {
|
|
|
2748
2764
|
}),
|
|
2749
2765
|
phase === "done" && /* @__PURE__ */ jsx(Box, {
|
|
2750
2766
|
flexDirection: "column",
|
|
2751
|
-
children:
|
|
2767
|
+
children: installedNow.length === 0 && finishNotes.length === 0 ? /* @__PURE__ */ jsxs(Text, {
|
|
2768
|
+
dimColor: true,
|
|
2769
|
+
children: [isRemove ? "Removal" : "Installation", " skipped."]
|
|
2770
|
+
}) : /* @__PURE__ */ jsxs(Fragment$1, { children: [installedNow.length > 0 && /* @__PURE__ */ jsxs(Fragment$1, { children: [/* @__PURE__ */ jsxs(Text, {
|
|
2752
2771
|
color: "green",
|
|
2753
2772
|
bold: true,
|
|
2754
2773
|
children: [
|
|
@@ -2759,25 +2778,874 @@ const McpScreen = ({ store, installer, mode = "install" }) => {
|
|
|
2759
2778
|
isRemove ? "removed from" : "installed for",
|
|
2760
2779
|
":"
|
|
2761
2780
|
]
|
|
2762
|
-
}),
|
|
2781
|
+
}), installedNow.map((name, i) => /* @__PURE__ */ jsxs(Text, { children: [
|
|
2763
2782
|
" ",
|
|
2764
2783
|
"•",
|
|
2765
2784
|
" ",
|
|
2766
2785
|
name
|
|
2767
|
-
] }, i))] })
|
|
2768
|
-
|
|
2769
|
-
|
|
2770
|
-
|
|
2786
|
+
] }, i))] }), finishNotes.map((note) => /* @__PURE__ */ jsxs(Box, {
|
|
2787
|
+
flexDirection: "column",
|
|
2788
|
+
marginTop: 1,
|
|
2789
|
+
children: [
|
|
2790
|
+
/* @__PURE__ */ jsxs(Text, {
|
|
2791
|
+
color: "green",
|
|
2792
|
+
bold: true,
|
|
2793
|
+
children: [note.name, " \\u2014 finish in your browser:"]
|
|
2794
|
+
}),
|
|
2795
|
+
/* @__PURE__ */ jsxs(Text, { children: [
|
|
2796
|
+
" ",
|
|
2797
|
+
"Opened ",
|
|
2798
|
+
/* @__PURE__ */ jsx(Text, {
|
|
2799
|
+
color: "cyan",
|
|
2800
|
+
children: note.url
|
|
2801
|
+
})
|
|
2802
|
+
] }),
|
|
2803
|
+
/* @__PURE__ */ jsxs(Text, {
|
|
2804
|
+
dimColor: true,
|
|
2805
|
+
children: [" ", note.instruction]
|
|
2806
|
+
}),
|
|
2807
|
+
/* @__PURE__ */ jsxs(Text, {
|
|
2808
|
+
dimColor: true,
|
|
2809
|
+
children: [" ", "(If it didn't open, paste the URL above.)"]
|
|
2810
|
+
})
|
|
2811
|
+
]
|
|
2812
|
+
}, note.name))] })
|
|
2771
2813
|
})
|
|
2772
2814
|
]
|
|
2773
2815
|
})]
|
|
2774
2816
|
});
|
|
2775
2817
|
};
|
|
2776
2818
|
//#endregion
|
|
2819
|
+
//#region src/lib/mcp-role-prompts.copy.json
|
|
2820
|
+
var pinnedFirstPrompt = {
|
|
2821
|
+
"prompt": "Show me my top 5 events from the last 7 days",
|
|
2822
|
+
"description": "A safe first pick — works on any project regardless of role or setup."
|
|
2823
|
+
};
|
|
2824
|
+
var defaultKit = [
|
|
2825
|
+
{
|
|
2826
|
+
"key": "verify",
|
|
2827
|
+
"prompt": "Annotate today with 'PostHog wizard install'",
|
|
2828
|
+
"description": "Creates a dated note on your project — visible on every chart. Delete anytime from PostHog."
|
|
2829
|
+
},
|
|
2830
|
+
{
|
|
2831
|
+
"key": "top-events",
|
|
2832
|
+
"prompt": "Show me my top 5 events from the last 7 days",
|
|
2833
|
+
"description": "Get a feel for what your project is tracking."
|
|
2834
|
+
},
|
|
2835
|
+
{
|
|
2836
|
+
"key": "main-funnel",
|
|
2837
|
+
"prompt": "Build me a funnel for my main user journey and show where the drop-off is",
|
|
2838
|
+
"description": "Insight discovery — your agent picks the events."
|
|
2839
|
+
},
|
|
2840
|
+
{
|
|
2841
|
+
"key": "flags-inventory",
|
|
2842
|
+
"prompt": "Show me my feature flags and what each is currently rolled out to",
|
|
2843
|
+
"description": "Inventory the rollout state of every flag in your project."
|
|
2844
|
+
},
|
|
2845
|
+
{
|
|
2846
|
+
"key": "error-trend",
|
|
2847
|
+
"prompt": "Show me daily error count for the last 30 days and flag anything that looks like a spike",
|
|
2848
|
+
"description": "Pulse-check on stability — no dashboard setup required."
|
|
2849
|
+
}
|
|
2850
|
+
];
|
|
2851
|
+
var roleKits = {
|
|
2852
|
+
"founder": [
|
|
2853
|
+
{
|
|
2854
|
+
"key": "verify",
|
|
2855
|
+
"prompt": "Annotate today with 'PostHog wizard install'",
|
|
2856
|
+
"description": "Creates a dated note on your project — visible on every chart. Delete anytime from PostHog."
|
|
2857
|
+
},
|
|
2858
|
+
{
|
|
2859
|
+
"key": "exec-dashboard",
|
|
2860
|
+
"prompt": "Build me an exec dashboard with MRR, MAU, churn, and top events, then save it",
|
|
2861
|
+
"description": "A one-glance view of the business you can pin and share."
|
|
2862
|
+
},
|
|
2863
|
+
{
|
|
2864
|
+
"key": "wau",
|
|
2865
|
+
"prompt": "Show me weekly active users for the last 90 days",
|
|
2866
|
+
"description": "The trendline you actually care about."
|
|
2867
|
+
},
|
|
2868
|
+
{
|
|
2869
|
+
"key": "mau-trend",
|
|
2870
|
+
"prompt": "Show me weekly MAU for the last 12 weeks and where the inflection points are",
|
|
2871
|
+
"description": "See where growth bent — up or down — without setting up alerts."
|
|
2872
|
+
},
|
|
2873
|
+
{
|
|
2874
|
+
"key": "nps-summary",
|
|
2875
|
+
"prompt": "Show me NPS responses from my paid users and summarize the themes",
|
|
2876
|
+
"description": "Pulse-check on the people paying you."
|
|
2877
|
+
}
|
|
2878
|
+
],
|
|
2879
|
+
"product": [
|
|
2880
|
+
{
|
|
2881
|
+
"key": "verify",
|
|
2882
|
+
"prompt": "Annotate today with 'PostHog wizard install'",
|
|
2883
|
+
"description": "Creates a dated note on your project — visible on every chart. Delete anytime from PostHog."
|
|
2884
|
+
},
|
|
2885
|
+
{
|
|
2886
|
+
"key": "onboarding",
|
|
2887
|
+
"prompt": "Build a funnel for my onboarding flow and show me the biggest drop-off step",
|
|
2888
|
+
"description": "See where new users drop off in their first session."
|
|
2889
|
+
},
|
|
2890
|
+
{
|
|
2891
|
+
"key": "pricing-flag-state",
|
|
2892
|
+
"prompt": "Show me feature flags scoped to the pricing page and who's currently in each",
|
|
2893
|
+
"description": "Inspect rollout state of pricing experiments without changing anything."
|
|
2894
|
+
},
|
|
2895
|
+
{
|
|
2896
|
+
"key": "cta-compare",
|
|
2897
|
+
"prompt": "Show me how my upgrade CTA variants are converting across my recent experiments",
|
|
2898
|
+
"description": "Read the verdict on CTA tests without spinning up a new one."
|
|
2899
|
+
},
|
|
2900
|
+
{
|
|
2901
|
+
"key": "retention",
|
|
2902
|
+
"prompt": "Compute week-1 retention split by acquisition channel",
|
|
2903
|
+
"description": "Find the channel that actually retains users."
|
|
2904
|
+
}
|
|
2905
|
+
],
|
|
2906
|
+
"leadership": [
|
|
2907
|
+
{
|
|
2908
|
+
"key": "verify",
|
|
2909
|
+
"prompt": "Annotate today with 'PostHog wizard install'",
|
|
2910
|
+
"description": "Creates a dated note on your project — visible on every chart. Delete anytime from PostHog."
|
|
2911
|
+
},
|
|
2912
|
+
{
|
|
2913
|
+
"key": "board-dashboard",
|
|
2914
|
+
"prompt": "Build a board dashboard with revenue, MAU, churn, and support backlog, then save it",
|
|
2915
|
+
"description": "Pre-board prep in one prompt."
|
|
2916
|
+
},
|
|
2917
|
+
{
|
|
2918
|
+
"key": "mau-growth",
|
|
2919
|
+
"prompt": "Show MAU growth over the last 4 quarters",
|
|
2920
|
+
"description": "The chart for the next leadership slide."
|
|
2921
|
+
},
|
|
2922
|
+
{
|
|
2923
|
+
"key": "churn-trend",
|
|
2924
|
+
"prompt": "Show me churn over the last 8 weeks and where it moved most",
|
|
2925
|
+
"description": "See the trend without configuring a notification."
|
|
2926
|
+
},
|
|
2927
|
+
{
|
|
2928
|
+
"key": "upgrade-drivers",
|
|
2929
|
+
"prompt": "Which features drive the most upgrades?",
|
|
2930
|
+
"description": "Ranked breakdown of what actually moves the needle."
|
|
2931
|
+
}
|
|
2932
|
+
],
|
|
2933
|
+
"marketing": [
|
|
2934
|
+
{
|
|
2935
|
+
"key": "verify",
|
|
2936
|
+
"prompt": "Annotate today with 'PostHog wizard install'",
|
|
2937
|
+
"description": "Creates a dated note on your project — visible on every chart. Delete anytime from PostHog."
|
|
2938
|
+
},
|
|
2939
|
+
{
|
|
2940
|
+
"key": "pricing-leavers",
|
|
2941
|
+
"prompt": "Show me users who saw pricing but didn't sign up — what did they do next?",
|
|
2942
|
+
"description": "Identify high-intent visitors and what they bounced to."
|
|
2943
|
+
},
|
|
2944
|
+
{
|
|
2945
|
+
"key": "hero-compare",
|
|
2946
|
+
"prompt": "Show me how my landing page hero variants performed — which group converted best?",
|
|
2947
|
+
"description": "Read the verdict on hero copy tests."
|
|
2948
|
+
},
|
|
2949
|
+
{
|
|
2950
|
+
"key": "newsletter-clicks",
|
|
2951
|
+
"prompt": "Find users who clicked our last newsletter and show me what they did next",
|
|
2952
|
+
"description": "See the downstream behavior of your last campaign."
|
|
2953
|
+
},
|
|
2954
|
+
{
|
|
2955
|
+
"key": "landing-annotation",
|
|
2956
|
+
"prompt": "Annotate today as the launch of the new landing page",
|
|
2957
|
+
"description": "Pin the deploy on every chart so future you can find it."
|
|
2958
|
+
}
|
|
2959
|
+
],
|
|
2960
|
+
"engineering": [
|
|
2961
|
+
{
|
|
2962
|
+
"key": "verify",
|
|
2963
|
+
"prompt": "Annotate today with 'PostHog wizard install'",
|
|
2964
|
+
"description": "Creates a dated note on your project — visible on every chart. Delete anytime from PostHog."
|
|
2965
|
+
},
|
|
2966
|
+
{
|
|
2967
|
+
"key": "stale-flags",
|
|
2968
|
+
"prompt": "List flags rolled out to 100% — they're probably safe to delete",
|
|
2969
|
+
"description": "Dead-code hunt for your feature flag config."
|
|
2970
|
+
},
|
|
2971
|
+
{
|
|
2972
|
+
"key": "top-errors",
|
|
2973
|
+
"prompt": "Show me the top 5 unresolved errors this week",
|
|
2974
|
+
"description": "Triage queue without opening another tab."
|
|
2975
|
+
},
|
|
2976
|
+
{
|
|
2977
|
+
"key": "reliability-trend",
|
|
2978
|
+
"prompt": "Show me 5xx error rate over the last 24 hours by endpoint",
|
|
2979
|
+
"description": "See where reliability is drifting, no alert setup."
|
|
2980
|
+
},
|
|
2981
|
+
{
|
|
2982
|
+
"key": "zero-rollout-flags",
|
|
2983
|
+
"prompt": "Show me feature flags currently rolled out at 0% — anything ready to retire?",
|
|
2984
|
+
"description": "Find dead kill-switch flags you can clean up later."
|
|
2985
|
+
}
|
|
2986
|
+
],
|
|
2987
|
+
"data": [
|
|
2988
|
+
{
|
|
2989
|
+
"key": "verify",
|
|
2990
|
+
"prompt": "Annotate today with 'PostHog wizard install'",
|
|
2991
|
+
"description": "Creates a dated note on your project — visible on every chart. Delete anytime from PostHog."
|
|
2992
|
+
},
|
|
2993
|
+
{
|
|
2994
|
+
"key": "top-events-24h",
|
|
2995
|
+
"prompt": "Top 5 events by volume in the last 24 hours",
|
|
2996
|
+
"description": "Smoke test for ingestion + a sanity check on volumes."
|
|
2997
|
+
},
|
|
2998
|
+
{
|
|
2999
|
+
"key": "paid-retention",
|
|
3000
|
+
"prompt": "Retention curve for paid users by signup month",
|
|
3001
|
+
"description": "The cohort chart you'd build first anyway."
|
|
3002
|
+
},
|
|
3003
|
+
{
|
|
3004
|
+
"key": "full-funnel",
|
|
3005
|
+
"prompt": "Funnel: signup → activated → first power feature → paid",
|
|
3006
|
+
"description": "Drop-off across the full journey, ready to slice."
|
|
3007
|
+
},
|
|
3008
|
+
{
|
|
3009
|
+
"key": "power-users-query",
|
|
3010
|
+
"prompt": "Show me users with 5+ sessions per week over the last month and what they have in common",
|
|
3011
|
+
"description": "Profile your power-user segment without materializing a cohort."
|
|
3012
|
+
}
|
|
3013
|
+
]
|
|
3014
|
+
};
|
|
3015
|
+
var roleFamilyOverrides = {
|
|
3016
|
+
"product": {
|
|
3017
|
+
"frontend-web": { "cta-compare": {
|
|
3018
|
+
"prompt": "Compare conversion across the variants of my last upgrade CTA experiment (control, red, green)",
|
|
3019
|
+
"description": "Read the verdict on a three-arm frontend experiment."
|
|
3020
|
+
} },
|
|
3021
|
+
"mobile": {
|
|
3022
|
+
"onboarding": {
|
|
3023
|
+
"prompt": "Build a funnel app_open → onboarding_complete → first_session_complete and show me the drop-off",
|
|
3024
|
+
"description": "Mobile-flavored onboarding funnel with sensible defaults."
|
|
3025
|
+
},
|
|
3026
|
+
"cta-compare": {
|
|
3027
|
+
"prompt": "Show me feature flags gated on app version — who's in each release tier?",
|
|
3028
|
+
"description": "See which clients see what, without changing anything."
|
|
3029
|
+
}
|
|
3030
|
+
},
|
|
3031
|
+
"backend": { "onboarding": {
|
|
3032
|
+
"prompt": "Funnel of signup → first API call → paid for last 30 days",
|
|
3033
|
+
"description": "Backend funnel that reflects what your service actually sees."
|
|
3034
|
+
} }
|
|
3035
|
+
},
|
|
3036
|
+
"engineering": {
|
|
3037
|
+
"frontend-web": { "top-errors": {
|
|
3038
|
+
"prompt": "Top 5 JS errors by occurrence count this week, with affected URLs",
|
|
3039
|
+
"description": "Frontend-specific error triage — sorted by blast radius."
|
|
3040
|
+
} },
|
|
3041
|
+
"mobile": {
|
|
3042
|
+
"top-errors": {
|
|
3043
|
+
"prompt": "Top crashes this week by app version, sorted by affected users",
|
|
3044
|
+
"description": "Mobile crash triage straight from the same data PostHog has."
|
|
3045
|
+
},
|
|
3046
|
+
"reliability-trend": {
|
|
3047
|
+
"prompt": "Show me crash-free sessions over the last 7 days by app version",
|
|
3048
|
+
"description": "Crash-free trend per release — the one mobile metric that matters."
|
|
3049
|
+
}
|
|
3050
|
+
},
|
|
3051
|
+
"backend": {
|
|
3052
|
+
"top-errors": {
|
|
3053
|
+
"prompt": "Top 5 server-side errors this week, grouped by endpoint",
|
|
3054
|
+
"description": "Backend error triage by route, sorted by frequency."
|
|
3055
|
+
},
|
|
3056
|
+
"reliability-trend": {
|
|
3057
|
+
"prompt": "Show me p95 response time over the last 24 hours by endpoint",
|
|
3058
|
+
"description": "Latency trend from the data you already collect."
|
|
3059
|
+
}
|
|
3060
|
+
}
|
|
3061
|
+
},
|
|
3062
|
+
"data": { "backend": { "full-funnel": {
|
|
3063
|
+
"prompt": "Funnel: api_signup → first_api_call → first_paid_event over last 30 days",
|
|
3064
|
+
"description": "Backend conversion funnel — captures the value your service delivers."
|
|
3065
|
+
} } }
|
|
3066
|
+
};
|
|
3067
|
+
var roleGreetings = {
|
|
3068
|
+
"founder": {
|
|
3069
|
+
"headline": "Founders use MCP to keep a hand on growth.",
|
|
3070
|
+
"bullets": [
|
|
3071
|
+
"Weekly active users, retention, and revenue without leaving your IDE.",
|
|
3072
|
+
"Spot stalls in your trends without setting up dashboards by hand.",
|
|
3073
|
+
"Pin annotations on every chart so you remember what shipped."
|
|
3074
|
+
],
|
|
3075
|
+
"outro": "Pick a prompt — your agent will run it on your project's real data."
|
|
3076
|
+
},
|
|
3077
|
+
"product": {
|
|
3078
|
+
"headline": "PMs use MCP to learn faster and decide quicker.",
|
|
3079
|
+
"bullets": [
|
|
3080
|
+
"Funnels for every onboarding flow you want to inspect.",
|
|
3081
|
+
"Inspect feature flags and experiment outcomes without leaving your IDE.",
|
|
3082
|
+
"Retention sliced by acquisition channel in seconds."
|
|
3083
|
+
],
|
|
3084
|
+
"outro": "Pick a prompt — your agent will do the legwork."
|
|
3085
|
+
},
|
|
3086
|
+
"leadership": {
|
|
3087
|
+
"headline": "Read the business from your terminal.",
|
|
3088
|
+
"bullets": [
|
|
3089
|
+
"Board-ready dashboards in one prompt.",
|
|
3090
|
+
"Trend lines for MAU, churn, and revenue, one query away.",
|
|
3091
|
+
"The numbers for the next leadership slide, on tap."
|
|
3092
|
+
],
|
|
3093
|
+
"outro": "Pick a prompt to see PostHog work for you."
|
|
3094
|
+
},
|
|
3095
|
+
"marketing": {
|
|
3096
|
+
"headline": "Inspect campaigns, end to end.",
|
|
3097
|
+
"bullets": [
|
|
3098
|
+
"Find high-intent visitors and what they did next.",
|
|
3099
|
+
"Compare landing-copy experiments and see which arm is winning.",
|
|
3100
|
+
"Tie every campaign to revenue with annotated launches."
|
|
3101
|
+
],
|
|
3102
|
+
"outro": "Pick a prompt to try it on your data."
|
|
3103
|
+
},
|
|
3104
|
+
"engineering": {
|
|
3105
|
+
"headline": "MCP is your shortest path from bug to root cause.",
|
|
3106
|
+
"bullets": [
|
|
3107
|
+
"Top errors this week, sorted by blast radius.",
|
|
3108
|
+
"Latency and crash-free trends checked against real data.",
|
|
3109
|
+
"Audit which flags are stale or fully rolled out."
|
|
3110
|
+
],
|
|
3111
|
+
"outro": "Pick a prompt — your agent has read access across your project."
|
|
3112
|
+
},
|
|
3113
|
+
"data": {
|
|
3114
|
+
"headline": "Data work without leaving the terminal.",
|
|
3115
|
+
"bullets": [
|
|
3116
|
+
"Profile any segment in seconds.",
|
|
3117
|
+
"Retention curves by signup month, sliced any way you want.",
|
|
3118
|
+
"Run SQL against your event stream — no copy-paste, no exports."
|
|
3119
|
+
],
|
|
3120
|
+
"outro": "Pick a prompt — every result is real data from your project."
|
|
3121
|
+
}
|
|
3122
|
+
};
|
|
3123
|
+
var neutralGreeting = {
|
|
3124
|
+
"headline": "PostHog MCP turns your agent into a product analyst.",
|
|
3125
|
+
"bullets": [
|
|
3126
|
+
"Run queries, build insights, save dashboards — straight from your IDE.",
|
|
3127
|
+
"Every result is real data from your project.",
|
|
3128
|
+
"No copy-pasting tokens, no context switching."
|
|
3129
|
+
],
|
|
3130
|
+
"outro": "Pick a prompt to see what MCP can do."
|
|
3131
|
+
};
|
|
3132
|
+
var toolFollowUps = {
|
|
3133
|
+
"query-error-tracking-issue": [
|
|
3134
|
+
{
|
|
3135
|
+
"label": "Stack trace for the top error",
|
|
3136
|
+
"prompt": "Show me the stack trace and recent occurrences for the top error."
|
|
3137
|
+
},
|
|
3138
|
+
{
|
|
3139
|
+
"label": "Who is most affected?",
|
|
3140
|
+
"prompt": "Which users have hit that error most often in the last 7 days?"
|
|
3141
|
+
},
|
|
3142
|
+
{
|
|
3143
|
+
"label": "When did it start?",
|
|
3144
|
+
"prompt": "Show me when that error first appeared and any deploy that landed nearby."
|
|
3145
|
+
},
|
|
3146
|
+
{
|
|
3147
|
+
"label": "Find related sessions",
|
|
3148
|
+
"prompt": "Find session recordings that hit that error so I can see what users were doing."
|
|
3149
|
+
},
|
|
3150
|
+
{
|
|
3151
|
+
"label": "Save the top-errors view",
|
|
3152
|
+
"prompt": "Save this top-errors view as an insight I can come back to."
|
|
3153
|
+
},
|
|
3154
|
+
{
|
|
3155
|
+
"label": "Pin to engineering dashboard",
|
|
3156
|
+
"prompt": "Pin this errors view to my engineering dashboard."
|
|
3157
|
+
}
|
|
3158
|
+
],
|
|
3159
|
+
"query-trends": [
|
|
3160
|
+
{
|
|
3161
|
+
"label": "Break down by property",
|
|
3162
|
+
"prompt": "Break that trend down by the most common user property."
|
|
3163
|
+
},
|
|
3164
|
+
{
|
|
3165
|
+
"label": "Find the outlier day",
|
|
3166
|
+
"prompt": "Which day stood out the most and what else was going on?"
|
|
3167
|
+
},
|
|
3168
|
+
{
|
|
3169
|
+
"label": "Compare to last month",
|
|
3170
|
+
"prompt": "Compare that against the same period last month."
|
|
3171
|
+
},
|
|
3172
|
+
{
|
|
3173
|
+
"label": "Build a funnel from it",
|
|
3174
|
+
"prompt": "Build a funnel using the top events from that trend."
|
|
3175
|
+
},
|
|
3176
|
+
{
|
|
3177
|
+
"label": "Save as an insight",
|
|
3178
|
+
"prompt": "Save that trend as an insight named 'Trends'."
|
|
3179
|
+
},
|
|
3180
|
+
{
|
|
3181
|
+
"label": "Pin to main dashboard",
|
|
3182
|
+
"prompt": "Pin that trend to my main dashboard."
|
|
3183
|
+
}
|
|
3184
|
+
],
|
|
3185
|
+
"query-funnel": [
|
|
3186
|
+
{
|
|
3187
|
+
"label": "Biggest drop-off",
|
|
3188
|
+
"prompt": "Which step has the biggest drop-off, and who falls out there?"
|
|
3189
|
+
},
|
|
3190
|
+
{
|
|
3191
|
+
"label": "Completion time",
|
|
3192
|
+
"prompt": "How long does it take users who complete that funnel?"
|
|
3193
|
+
},
|
|
3194
|
+
{
|
|
3195
|
+
"label": "Slice by platform",
|
|
3196
|
+
"prompt": "Show that funnel split by mobile vs desktop."
|
|
3197
|
+
},
|
|
3198
|
+
{
|
|
3199
|
+
"label": "Find drop-off sessions",
|
|
3200
|
+
"prompt": "Find session recordings of users who dropped out at the biggest step."
|
|
3201
|
+
},
|
|
3202
|
+
{
|
|
3203
|
+
"label": "Save the funnel",
|
|
3204
|
+
"prompt": "Save that funnel as an insight."
|
|
3205
|
+
},
|
|
3206
|
+
{
|
|
3207
|
+
"label": "Pin to dashboard",
|
|
3208
|
+
"prompt": "Pin that funnel to my main dashboard."
|
|
3209
|
+
}
|
|
3210
|
+
],
|
|
3211
|
+
"query-retention": [
|
|
3212
|
+
{
|
|
3213
|
+
"label": "Best-retaining cohort",
|
|
3214
|
+
"prompt": "Which cohort retains the longest in that curve?"
|
|
3215
|
+
},
|
|
3216
|
+
{
|
|
3217
|
+
"label": "Worst-retaining cohort",
|
|
3218
|
+
"prompt": "Which cohort drops off fastest in that curve?"
|
|
3219
|
+
},
|
|
3220
|
+
{
|
|
3221
|
+
"label": "Slice by acquisition channel",
|
|
3222
|
+
"prompt": "Re-run that retention split by acquisition channel."
|
|
3223
|
+
},
|
|
3224
|
+
{
|
|
3225
|
+
"label": "Find churned users",
|
|
3226
|
+
"prompt": "Find session recordings of users who churned during week 1."
|
|
3227
|
+
},
|
|
3228
|
+
{
|
|
3229
|
+
"label": "Save the retention chart",
|
|
3230
|
+
"prompt": "Save that retention chart as an insight."
|
|
3231
|
+
},
|
|
3232
|
+
{
|
|
3233
|
+
"label": "Pin to growth dashboard",
|
|
3234
|
+
"prompt": "Pin that retention chart to my growth dashboard."
|
|
3235
|
+
}
|
|
3236
|
+
],
|
|
3237
|
+
"query-feature-flag": [
|
|
3238
|
+
{
|
|
3239
|
+
"label": "Who's in this flag?",
|
|
3240
|
+
"prompt": "Show me which users are currently in the rollout for that flag."
|
|
3241
|
+
},
|
|
3242
|
+
{
|
|
3243
|
+
"label": "What changed recently?",
|
|
3244
|
+
"prompt": "Show me the rollout history for that flag — when did it last change?"
|
|
3245
|
+
},
|
|
3246
|
+
{
|
|
3247
|
+
"label": "Compare against another flag",
|
|
3248
|
+
"prompt": "Show me the audience overlap between that flag and one related flag."
|
|
3249
|
+
},
|
|
3250
|
+
{
|
|
3251
|
+
"label": "Find sessions for that flag",
|
|
3252
|
+
"prompt": "Find recent session recordings from users currently in that flag."
|
|
3253
|
+
},
|
|
3254
|
+
{
|
|
3255
|
+
"label": "Save flag inventory",
|
|
3256
|
+
"prompt": "Save this flag inventory as an insight."
|
|
3257
|
+
},
|
|
3258
|
+
{
|
|
3259
|
+
"label": "Pin to release dashboard",
|
|
3260
|
+
"prompt": "Pin this flag view to my release dashboard."
|
|
3261
|
+
}
|
|
3262
|
+
],
|
|
3263
|
+
"query-survey-responses": [
|
|
3264
|
+
{
|
|
3265
|
+
"label": "Summarize the themes",
|
|
3266
|
+
"prompt": "Summarize the themes from those survey responses."
|
|
3267
|
+
},
|
|
3268
|
+
{
|
|
3269
|
+
"label": "Score distribution",
|
|
3270
|
+
"prompt": "Show me the score distribution across those responses."
|
|
3271
|
+
},
|
|
3272
|
+
{
|
|
3273
|
+
"label": "Who are the detractors?",
|
|
3274
|
+
"prompt": "Show me users who left a low score and what they did next."
|
|
3275
|
+
},
|
|
3276
|
+
{
|
|
3277
|
+
"label": "Find their sessions",
|
|
3278
|
+
"prompt": "Find session recordings from users who left a low score."
|
|
3279
|
+
},
|
|
3280
|
+
{
|
|
3281
|
+
"label": "Save the response summary",
|
|
3282
|
+
"prompt": "Save this response summary as an insight."
|
|
3283
|
+
},
|
|
3284
|
+
{
|
|
3285
|
+
"label": "Add to research notebook",
|
|
3286
|
+
"prompt": "Add this survey summary to my user research notebook."
|
|
3287
|
+
}
|
|
3288
|
+
],
|
|
3289
|
+
"query-experiment": [
|
|
3290
|
+
{
|
|
3291
|
+
"label": "Which variant is winning?",
|
|
3292
|
+
"prompt": "Show me the conversion rate of each variant in that experiment."
|
|
3293
|
+
},
|
|
3294
|
+
{
|
|
3295
|
+
"label": "Slice by segment",
|
|
3296
|
+
"prompt": "Show me how each variant performed by user segment."
|
|
3297
|
+
},
|
|
3298
|
+
{
|
|
3299
|
+
"label": "Statistical significance",
|
|
3300
|
+
"prompt": "Has that experiment reached statistical significance yet?"
|
|
3301
|
+
},
|
|
3302
|
+
{
|
|
3303
|
+
"label": "Find variant sessions",
|
|
3304
|
+
"prompt": "Find session recordings from users in the winning variant."
|
|
3305
|
+
},
|
|
3306
|
+
{
|
|
3307
|
+
"label": "Save the readout",
|
|
3308
|
+
"prompt": "Save that experiment readout as an insight."
|
|
3309
|
+
},
|
|
3310
|
+
{
|
|
3311
|
+
"label": "Add to experiment notebook",
|
|
3312
|
+
"prompt": "Add this experiment readout to my experiments notebook."
|
|
3313
|
+
}
|
|
3314
|
+
],
|
|
3315
|
+
"query-session-recordings-list": [
|
|
3316
|
+
{
|
|
3317
|
+
"label": "Summarize what users did",
|
|
3318
|
+
"prompt": "Summarize what users did in those sessions."
|
|
3319
|
+
},
|
|
3320
|
+
{
|
|
3321
|
+
"label": "Find common drop-offs",
|
|
3322
|
+
"prompt": "What's the most common step where users got stuck in those sessions?"
|
|
3323
|
+
},
|
|
3324
|
+
{
|
|
3325
|
+
"label": "Errors in those sessions",
|
|
3326
|
+
"prompt": "Which errors fired most often across those sessions?"
|
|
3327
|
+
},
|
|
3328
|
+
{
|
|
3329
|
+
"label": "Properties of those users",
|
|
3330
|
+
"prompt": "Show me the most common user properties across those sessions."
|
|
3331
|
+
},
|
|
3332
|
+
{
|
|
3333
|
+
"label": "Save the session summary",
|
|
3334
|
+
"prompt": "Save the summary of those sessions as an insight."
|
|
3335
|
+
},
|
|
3336
|
+
{
|
|
3337
|
+
"label": "Add to UX notebook",
|
|
3338
|
+
"prompt": "Add these session findings to my UX research notebook."
|
|
3339
|
+
}
|
|
3340
|
+
],
|
|
3341
|
+
"execute-sql": [
|
|
3342
|
+
{
|
|
3343
|
+
"label": "Add p50/p90/p99",
|
|
3344
|
+
"prompt": "Re-run that query with p50/p90/p99 added."
|
|
3345
|
+
},
|
|
3346
|
+
{
|
|
3347
|
+
"label": "Slice differently",
|
|
3348
|
+
"prompt": "Re-run that query grouped by the most common user property."
|
|
3349
|
+
},
|
|
3350
|
+
{
|
|
3351
|
+
"label": "Find the outliers",
|
|
3352
|
+
"prompt": "Re-run that query and surface the top 5 outliers."
|
|
3353
|
+
},
|
|
3354
|
+
{
|
|
3355
|
+
"label": "Compare to last week",
|
|
3356
|
+
"prompt": "Compare that query result to the same window last week."
|
|
3357
|
+
},
|
|
3358
|
+
{
|
|
3359
|
+
"label": "Save as an insight",
|
|
3360
|
+
"prompt": "Turn that query result into a saved insight."
|
|
3361
|
+
},
|
|
3362
|
+
{
|
|
3363
|
+
"label": "Pin to data dashboard",
|
|
3364
|
+
"prompt": "Pin that query result to my data dashboard."
|
|
3365
|
+
}
|
|
3366
|
+
],
|
|
3367
|
+
"create-dashboard": [
|
|
3368
|
+
{
|
|
3369
|
+
"label": "Add another tile",
|
|
3370
|
+
"prompt": "Add a tile showing daily active users to that dashboard."
|
|
3371
|
+
},
|
|
3372
|
+
{
|
|
3373
|
+
"label": "Add a leaderboard tile",
|
|
3374
|
+
"prompt": "Add a top-5 users tile to that dashboard."
|
|
3375
|
+
},
|
|
3376
|
+
{
|
|
3377
|
+
"label": "Annotate today",
|
|
3378
|
+
"prompt": "Annotate today on that dashboard as the launch baseline."
|
|
3379
|
+
},
|
|
3380
|
+
{
|
|
3381
|
+
"label": "Compare to last quarter",
|
|
3382
|
+
"prompt": "Add a tile comparing this quarter to the last on the same dashboard."
|
|
3383
|
+
},
|
|
3384
|
+
{
|
|
3385
|
+
"label": "Add an errors tile",
|
|
3386
|
+
"prompt": "Add a tile showing the top 3 errors this week to that dashboard."
|
|
3387
|
+
},
|
|
3388
|
+
{
|
|
3389
|
+
"label": "Add to dashboards notebook",
|
|
3390
|
+
"prompt": "Add a link to that dashboard in my dashboards notebook."
|
|
3391
|
+
}
|
|
3392
|
+
],
|
|
3393
|
+
"create-insight": [
|
|
3394
|
+
{
|
|
3395
|
+
"label": "Pin to main dashboard",
|
|
3396
|
+
"prompt": "Pin that insight to my main dashboard."
|
|
3397
|
+
},
|
|
3398
|
+
{
|
|
3399
|
+
"label": "Split by user property",
|
|
3400
|
+
"prompt": "Re-run that insight split by the most common user property."
|
|
3401
|
+
},
|
|
3402
|
+
{
|
|
3403
|
+
"label": "Compare to a control",
|
|
3404
|
+
"prompt": "Re-run that insight comparing paid vs free users side-by-side."
|
|
3405
|
+
},
|
|
3406
|
+
{
|
|
3407
|
+
"label": "Save the underlying query",
|
|
3408
|
+
"prompt": "Save the underlying query for that insight so I can edit it later."
|
|
3409
|
+
},
|
|
3410
|
+
{
|
|
3411
|
+
"label": "Add to notebook",
|
|
3412
|
+
"prompt": "Add that insight to my analytics notebook."
|
|
3413
|
+
},
|
|
3414
|
+
{
|
|
3415
|
+
"label": "Annotate the moment",
|
|
3416
|
+
"prompt": "Annotate today on the chart for that insight."
|
|
3417
|
+
}
|
|
3418
|
+
]
|
|
3419
|
+
};
|
|
3420
|
+
var roleFollowUps = {
|
|
3421
|
+
"founder": [
|
|
3422
|
+
{
|
|
3423
|
+
"label": "Pin to exec dashboard",
|
|
3424
|
+
"prompt": "Add that result to my exec dashboard."
|
|
3425
|
+
},
|
|
3426
|
+
{
|
|
3427
|
+
"label": "Tie it to revenue",
|
|
3428
|
+
"prompt": "How does that correlate with paid conversions?"
|
|
3429
|
+
},
|
|
3430
|
+
{
|
|
3431
|
+
"label": "Compare to last quarter",
|
|
3432
|
+
"prompt": "How does that compare against the same period last quarter?"
|
|
3433
|
+
},
|
|
3434
|
+
{
|
|
3435
|
+
"label": "Save for board update",
|
|
3436
|
+
"prompt": "Save that as an insight I can attach to the next board update."
|
|
3437
|
+
}
|
|
3438
|
+
],
|
|
3439
|
+
"product": [
|
|
3440
|
+
{
|
|
3441
|
+
"label": "Build a funnel around it",
|
|
3442
|
+
"prompt": "Build a funnel that includes that step."
|
|
3443
|
+
},
|
|
3444
|
+
{
|
|
3445
|
+
"label": "Find high-intent users",
|
|
3446
|
+
"prompt": "Show me which users in that group also completed activation."
|
|
3447
|
+
},
|
|
3448
|
+
{
|
|
3449
|
+
"label": "Check related experiments",
|
|
3450
|
+
"prompt": "Show me how this metric trended across my recent experiments."
|
|
3451
|
+
},
|
|
3452
|
+
{
|
|
3453
|
+
"label": "Save to product notebook",
|
|
3454
|
+
"prompt": "Add this finding to my product analytics notebook."
|
|
3455
|
+
}
|
|
3456
|
+
],
|
|
3457
|
+
"leadership": [
|
|
3458
|
+
{
|
|
3459
|
+
"label": "Compare to last quarter",
|
|
3460
|
+
"prompt": "How does that compare against the same period last quarter?"
|
|
3461
|
+
},
|
|
3462
|
+
{
|
|
3463
|
+
"label": "Pin to leadership dashboard",
|
|
3464
|
+
"prompt": "Pin this view to my leadership dashboard."
|
|
3465
|
+
},
|
|
3466
|
+
{
|
|
3467
|
+
"label": "Save for next meeting",
|
|
3468
|
+
"prompt": "Save this as an insight I can pull up in the next leadership meeting."
|
|
3469
|
+
}
|
|
3470
|
+
],
|
|
3471
|
+
"marketing": [
|
|
3472
|
+
{
|
|
3473
|
+
"label": "Annotate the launch",
|
|
3474
|
+
"prompt": "Annotate today as the campaign launch on that chart."
|
|
3475
|
+
},
|
|
3476
|
+
{
|
|
3477
|
+
"label": "What did they do next?",
|
|
3478
|
+
"prompt": "Show me what users in that group did next."
|
|
3479
|
+
},
|
|
3480
|
+
{
|
|
3481
|
+
"label": "Tie back to channel",
|
|
3482
|
+
"prompt": "Split that result by acquisition channel."
|
|
3483
|
+
},
|
|
3484
|
+
{
|
|
3485
|
+
"label": "Compare to landing tests",
|
|
3486
|
+
"prompt": "Compare this result across my recent landing-page experiments."
|
|
3487
|
+
}
|
|
3488
|
+
],
|
|
3489
|
+
"engineering": [
|
|
3490
|
+
{
|
|
3491
|
+
"label": "Did a deploy land?",
|
|
3492
|
+
"prompt": "Did that change land alongside a deploy in the last 24 hours?"
|
|
3493
|
+
},
|
|
3494
|
+
{
|
|
3495
|
+
"label": "Flag changes that fit",
|
|
3496
|
+
"prompt": "Show me which feature flag changes correlate with that change in metric."
|
|
3497
|
+
},
|
|
3498
|
+
{
|
|
3499
|
+
"label": "Group by release",
|
|
3500
|
+
"prompt": "Re-run that broken down by app version or release."
|
|
3501
|
+
},
|
|
3502
|
+
{
|
|
3503
|
+
"label": "Save to incident notebook",
|
|
3504
|
+
"prompt": "Save this analysis to my incident notebook."
|
|
3505
|
+
}
|
|
3506
|
+
],
|
|
3507
|
+
"data": [
|
|
3508
|
+
{
|
|
3509
|
+
"label": "Add percentiles",
|
|
3510
|
+
"prompt": "Add p50/p90/p99 distributions to that result."
|
|
3511
|
+
},
|
|
3512
|
+
{
|
|
3513
|
+
"label": "Compare to last month",
|
|
3514
|
+
"prompt": "Show me how that result trended over the last month."
|
|
3515
|
+
},
|
|
3516
|
+
{
|
|
3517
|
+
"label": "Save as an insight",
|
|
3518
|
+
"prompt": "Save that query result as an insight."
|
|
3519
|
+
},
|
|
3520
|
+
{
|
|
3521
|
+
"label": "Pin to data dashboard",
|
|
3522
|
+
"prompt": "Pin this result to my data team dashboard."
|
|
3523
|
+
}
|
|
3524
|
+
]
|
|
3525
|
+
};
|
|
3526
|
+
var genericFollowUps = [
|
|
3527
|
+
{
|
|
3528
|
+
"label": "Go one level deeper",
|
|
3529
|
+
"prompt": "Run that same question one level deeper."
|
|
3530
|
+
},
|
|
3531
|
+
{
|
|
3532
|
+
"label": "Take a different angle",
|
|
3533
|
+
"prompt": "Look at the same question from a completely different angle."
|
|
3534
|
+
},
|
|
3535
|
+
{
|
|
3536
|
+
"label": "Find the surprise",
|
|
3537
|
+
"prompt": "What's the most surprising thing in that result?"
|
|
3538
|
+
},
|
|
3539
|
+
{
|
|
3540
|
+
"label": "Slice by user",
|
|
3541
|
+
"prompt": "Re-run that split by the highest-value user segment."
|
|
3542
|
+
},
|
|
3543
|
+
{
|
|
3544
|
+
"label": "Compare with last month",
|
|
3545
|
+
"prompt": "How does that look compared to the same window a month ago?"
|
|
3546
|
+
},
|
|
3547
|
+
{
|
|
3548
|
+
"label": "Save as an insight",
|
|
3549
|
+
"prompt": "Save that result as an insight I can come back to."
|
|
3550
|
+
},
|
|
3551
|
+
{
|
|
3552
|
+
"label": "Pin to a dashboard",
|
|
3553
|
+
"prompt": "Pin this view to my main dashboard."
|
|
3554
|
+
},
|
|
3555
|
+
{
|
|
3556
|
+
"label": "Add to a notebook",
|
|
3557
|
+
"prompt": "Add this finding to my notebook."
|
|
3558
|
+
}
|
|
3559
|
+
];
|
|
3560
|
+
var deepDiveFollowUps = [
|
|
3561
|
+
{
|
|
3562
|
+
"label": "Save this exploration",
|
|
3563
|
+
"prompt": "Save the most useful chart from this session as a dashboard I can come back to."
|
|
3564
|
+
},
|
|
3565
|
+
{
|
|
3566
|
+
"label": "Summarize what we found",
|
|
3567
|
+
"prompt": "Summarize the key findings from everything we just looked at in 3 bullets."
|
|
3568
|
+
},
|
|
3569
|
+
{
|
|
3570
|
+
"label": "Pin a session summary",
|
|
3571
|
+
"prompt": "Pin a summary of this session to my main dashboard."
|
|
3572
|
+
},
|
|
3573
|
+
{
|
|
3574
|
+
"label": "Write to a notebook",
|
|
3575
|
+
"prompt": "Write everything we just covered into a notebook entry I can revisit."
|
|
3576
|
+
}
|
|
3577
|
+
];
|
|
3578
|
+
var crossSellByRole = {
|
|
3579
|
+
"founder": [{
|
|
3580
|
+
"product": "Session Replay",
|
|
3581
|
+
"prompt": "Find 3 recent sessions where a user looked at pricing but did not sign up.",
|
|
3582
|
+
"description": "Watch what users see — replay turns funnel drop-offs into video."
|
|
3583
|
+
}, {
|
|
3584
|
+
"product": "Surveys",
|
|
3585
|
+
"prompt": "Show me how my NPS results have trended over the last quarter.",
|
|
3586
|
+
"description": "Quantitative pulse check on the survey side of PostHog."
|
|
3587
|
+
}],
|
|
3588
|
+
"product": [{
|
|
3589
|
+
"product": "Experiments",
|
|
3590
|
+
"prompt": "Show me results from my latest onboarding experiment — which variant is winning?",
|
|
3591
|
+
"description": "Experiments piggyback on flags — same SDK, all readable here."
|
|
3592
|
+
}, {
|
|
3593
|
+
"product": "Session Replay",
|
|
3594
|
+
"prompt": "Find sessions where users got stuck on the empty state in onboarding.",
|
|
3595
|
+
"description": "See what funnels can't show you."
|
|
3596
|
+
}],
|
|
3597
|
+
"leadership": [{
|
|
3598
|
+
"product": "Surveys",
|
|
3599
|
+
"prompt": "Show me NPS scores from the last quarter — who are the detractors?",
|
|
3600
|
+
"description": "Read the survey data PostHog already collects for you."
|
|
3601
|
+
}, {
|
|
3602
|
+
"product": "Data Warehouse",
|
|
3603
|
+
"prompt": "Compare MRR by signup source using Stripe data joined with event data.",
|
|
3604
|
+
"description": "Query revenue alongside events when warehouse is connected."
|
|
3605
|
+
}],
|
|
3606
|
+
"marketing": [{
|
|
3607
|
+
"product": "Session Replay",
|
|
3608
|
+
"prompt": "Watch 5 sessions from users who came via our last campaign and converted.",
|
|
3609
|
+
"description": "See campaign visitors behave — beyond aggregate numbers."
|
|
3610
|
+
}, {
|
|
3611
|
+
"product": "Web Analytics",
|
|
3612
|
+
"prompt": "Show me top traffic sources to the pricing page this week.",
|
|
3613
|
+
"description": "GA-style first-party web analytics, no cookie banner."
|
|
3614
|
+
}],
|
|
3615
|
+
"engineering": [{
|
|
3616
|
+
"product": "Error Tracking",
|
|
3617
|
+
"prompt": "Show me the top 5 errors this week and who is affected.",
|
|
3618
|
+
"description": "Built-in error tracking — no Sentry subscription."
|
|
3619
|
+
}, {
|
|
3620
|
+
"product": "Session Replay",
|
|
3621
|
+
"prompt": "Replay the last 3 sessions that hit a 5xx error.",
|
|
3622
|
+
"description": "Stack trace meets replay — see what the user did."
|
|
3623
|
+
}],
|
|
3624
|
+
"data": [{
|
|
3625
|
+
"product": "Data Warehouse",
|
|
3626
|
+
"prompt": "Join my event stream with Stripe subscriptions to surface churn signals.",
|
|
3627
|
+
"description": "Connect Stripe / Salesforce / S3, query everything with SQL."
|
|
3628
|
+
}, {
|
|
3629
|
+
"product": "LLM Observability",
|
|
3630
|
+
"prompt": "Show me the top 5 LLM prompts by cost over the last 7 days.",
|
|
3631
|
+
"description": "Track LLM calls, latency, and cost next to product events."
|
|
3632
|
+
}]
|
|
3633
|
+
};
|
|
3634
|
+
var neutralCrossSell = [{
|
|
3635
|
+
"product": "Session Replay",
|
|
3636
|
+
"prompt": "Show me 5 recent sessions where users dropped off before completing signup.",
|
|
3637
|
+
"description": "Replay what users actually do — included on every plan."
|
|
3638
|
+
}, {
|
|
3639
|
+
"product": "Error Tracking",
|
|
3640
|
+
"prompt": "List the top errors my users hit this week.",
|
|
3641
|
+
"description": "Built-in error tracking — no separate tool."
|
|
3642
|
+
}];
|
|
3643
|
+
//#endregion
|
|
2777
3644
|
//#region src/lib/mcp-role-prompts.ts
|
|
2778
3645
|
/**
|
|
2779
3646
|
* Roles that ship from `role_at_organization` on the PostHog user object.
|
|
2780
|
-
* `security` isn't in the enum upstream — the engineering kit covers
|
|
3647
|
+
* `security` isn't in the enum upstream — the engineering kit covers
|
|
3648
|
+
* that audience.
|
|
2781
3649
|
*/
|
|
2782
3650
|
const TAILORED_ROLES = [
|
|
2783
3651
|
"founder",
|
|
@@ -2787,62 +3655,198 @@ const TAILORED_ROLES = [
|
|
|
2787
3655
|
"engineering",
|
|
2788
3656
|
"data"
|
|
2789
3657
|
];
|
|
2790
|
-
const
|
|
2791
|
-
|
|
2792
|
-
|
|
2793
|
-
|
|
2794
|
-
|
|
2795
|
-
|
|
2796
|
-
|
|
2797
|
-
|
|
2798
|
-
|
|
2799
|
-
|
|
2800
|
-
|
|
2801
|
-
|
|
3658
|
+
const FOLLOW_UP_EXIT_SENTINEL = "__follow_up_exit__";
|
|
3659
|
+
/**
|
|
3660
|
+
* Always shown as the picker's first option regardless of role —
|
|
3661
|
+
* a safe generic read that works on any project setup. The screen
|
|
3662
|
+
* prepends it and dedupes against the role kit so it never appears
|
|
3663
|
+
* twice when DEFAULT_KIT happens to include it.
|
|
3664
|
+
*/
|
|
3665
|
+
const PINNED_FIRST_PROMPT = pinnedFirstPrompt;
|
|
3666
|
+
const DEFAULT_KIT = defaultKit;
|
|
3667
|
+
const ROLE_KITS = roleKits;
|
|
3668
|
+
const ROLE_FAMILY_OVERRIDES = roleFamilyOverrides;
|
|
3669
|
+
const ROLE_GREETINGS = roleGreetings;
|
|
3670
|
+
const NEUTRAL_GREETING = neutralGreeting;
|
|
3671
|
+
const TOOL_FOLLOW_UPS = toolFollowUps;
|
|
3672
|
+
const ROLE_FOLLOW_UPS = roleFollowUps;
|
|
3673
|
+
const GENERIC_FOLLOW_UPS = genericFollowUps;
|
|
3674
|
+
const DEEP_DIVE_FOLLOW_UPS = deepDiveFollowUps;
|
|
3675
|
+
const CROSS_SELL_BY_ROLE = crossSellByRole;
|
|
3676
|
+
const NEUTRAL_CROSS_SELL = neutralCrossSell;
|
|
3677
|
+
const INTEGRATION_FAMILY = {
|
|
3678
|
+
nextjs: "fullstack",
|
|
3679
|
+
nuxt: "fullstack",
|
|
3680
|
+
"tanstack-start": "fullstack",
|
|
3681
|
+
astro: "fullstack",
|
|
3682
|
+
sveltekit: "fullstack",
|
|
3683
|
+
vue: "frontend-web",
|
|
3684
|
+
angular: "frontend-web",
|
|
3685
|
+
"react-router": "frontend-web",
|
|
3686
|
+
"tanstack-router": "frontend-web",
|
|
3687
|
+
javascript_web: "frontend-web",
|
|
3688
|
+
"react-native": "mobile",
|
|
3689
|
+
swift: "mobile",
|
|
3690
|
+
android: "mobile",
|
|
3691
|
+
django: "backend",
|
|
3692
|
+
flask: "backend",
|
|
3693
|
+
fastapi: "backend",
|
|
3694
|
+
python: "backend",
|
|
3695
|
+
laravel: "backend",
|
|
3696
|
+
rails: "backend",
|
|
3697
|
+
ruby: "backend",
|
|
3698
|
+
javascript_node: "backend"
|
|
3699
|
+
};
|
|
3700
|
+
const EXIT_FOLLOW_UP = {
|
|
3701
|
+
label: "I'm done — exit",
|
|
3702
|
+
prompt: FOLLOW_UP_EXIT_SENTINEL
|
|
3703
|
+
};
|
|
3704
|
+
function isTailoredRole(role) {
|
|
3705
|
+
return typeof role === "string" && TAILORED_ROLES.includes(role);
|
|
3706
|
+
}
|
|
3707
|
+
/**
|
|
3708
|
+
* Strip MCP tool-name prefixes so lookup keys can stay short. Real MCP
|
|
3709
|
+
* tool names arrive as `mcp__<server>__<tool>`; the agent SDK also
|
|
3710
|
+
* sometimes drops the prefix. We take the substring after the last
|
|
3711
|
+
* double-underscore (or the input untouched if there's none).
|
|
3712
|
+
*/
|
|
3713
|
+
function normalizeToolName(toolName) {
|
|
3714
|
+
if (!toolName) return null;
|
|
3715
|
+
const idx = toolName.lastIndexOf("__");
|
|
3716
|
+
return idx >= 0 ? toolName.slice(idx + 2) : toolName;
|
|
3717
|
+
}
|
|
3718
|
+
/** Pick `n` items from a pool starting at a rotation offset. */
|
|
3719
|
+
function pickRotated(pool, n, rotation) {
|
|
3720
|
+
if (pool.length === 0) return [];
|
|
3721
|
+
if (pool.length <= n) return pool;
|
|
3722
|
+
const start = (Math.floor(rotation) % pool.length + pool.length) % pool.length;
|
|
3723
|
+
const result = [];
|
|
3724
|
+
for (let i = 0; i < n; i++) result.push(pool[(start + i) % pool.length]);
|
|
3725
|
+
return result;
|
|
3726
|
+
}
|
|
3727
|
+
/** Drop duplicates while preserving order (by prompt text). */
|
|
3728
|
+
function dedupeFollowUps(list) {
|
|
3729
|
+
const seen = /* @__PURE__ */ new Set();
|
|
3730
|
+
const out = [];
|
|
3731
|
+
for (const f of list) {
|
|
3732
|
+
if (seen.has(f.prompt)) continue;
|
|
3733
|
+
seen.add(f.prompt);
|
|
3734
|
+
out.push(f);
|
|
2802
3735
|
}
|
|
2803
|
-
|
|
3736
|
+
return out;
|
|
3737
|
+
}
|
|
3738
|
+
function getFrameworkFamily(integration) {
|
|
3739
|
+
if (!integration) return "unknown";
|
|
3740
|
+
return INTEGRATION_FAMILY[integration] ?? "unknown";
|
|
3741
|
+
}
|
|
3742
|
+
/**
|
|
3743
|
+
* Resolve the right kit given everything we know about the user + project.
|
|
3744
|
+
* Always returns at least DEFAULT_KIT; never throws.
|
|
3745
|
+
*/
|
|
3746
|
+
function getRolePrompts(role, integration) {
|
|
3747
|
+
const family = getFrameworkFamily(integration);
|
|
3748
|
+
if (!isTailoredRole(role)) return DEFAULT_KIT;
|
|
3749
|
+
const baseKit = ROLE_KITS[role];
|
|
3750
|
+
const overridesForFamily = ROLE_FAMILY_OVERRIDES[role]?.[family];
|
|
3751
|
+
if (!overridesForFamily) return baseKit;
|
|
3752
|
+
return baseKit.map((entry) => {
|
|
3753
|
+
return (entry.key ? overridesForFamily[entry.key] : void 0) ?? entry;
|
|
3754
|
+
});
|
|
3755
|
+
}
|
|
3756
|
+
function getRoleGreeting(role) {
|
|
3757
|
+
if (!isTailoredRole(role)) return NEUTRAL_GREETING;
|
|
3758
|
+
return ROLE_GREETINGS[role];
|
|
3759
|
+
}
|
|
3760
|
+
/**
|
|
3761
|
+
* Resolve `FOLLOW_UP_COUNT` context-aware follow-ups + an always-present
|
|
3762
|
+
* exit entry. Pulls from up to four pools — tool-specific, role-specific,
|
|
3763
|
+
* deep-dive (only after the user has explored a few steps), and generic —
|
|
3764
|
+
* dedupes, filters out anything already in `branchHistory`, then picks
|
|
3765
|
+
* `FOLLOW_UP_COUNT` with a rotation offset driven by `branchHistory.length`
|
|
3766
|
+
* so successive visits surface different slices.
|
|
3767
|
+
*/
|
|
3768
|
+
function getFollowUps(args) {
|
|
3769
|
+
const { lastToolName, role, branchHistory } = args;
|
|
3770
|
+
const normalized = normalizeToolName(lastToolName);
|
|
3771
|
+
const depth = branchHistory.length;
|
|
3772
|
+
const candidates = [];
|
|
3773
|
+
if (normalized && TOOL_FOLLOW_UPS[normalized]) candidates.push(...TOOL_FOLLOW_UPS[normalized]);
|
|
3774
|
+
if (isTailoredRole(role)) candidates.push(...ROLE_FOLLOW_UPS[role]);
|
|
3775
|
+
if (depth >= 3) candidates.push(...DEEP_DIVE_FOLLOW_UPS);
|
|
3776
|
+
candidates.push(...GENERIC_FOLLOW_UPS);
|
|
3777
|
+
const deduped = dedupeFollowUps(candidates);
|
|
3778
|
+
const seen = new Set(branchHistory);
|
|
3779
|
+
return [...pickRotated(deduped.filter((f) => !seen.has(f.prompt)), 3, depth), EXIT_FOLLOW_UP];
|
|
3780
|
+
}
|
|
3781
|
+
/**
|
|
3782
|
+
* Cross-sell prompts to surface above the role kit in PromptPicker.
|
|
3783
|
+
* Filtered by role so the recommendations stay coherent (founders see
|
|
3784
|
+
* the "exec-friendly" cross-sells, engineers see "debug-friendly", etc).
|
|
3785
|
+
*/
|
|
3786
|
+
function getCrossSellPrompts(role) {
|
|
3787
|
+
if (!isTailoredRole(role)) return NEUTRAL_CROSS_SELL;
|
|
3788
|
+
return CROSS_SELL_BY_ROLE[role];
|
|
3789
|
+
}
|
|
2804
3790
|
//#endregion
|
|
2805
3791
|
//#region src/ui/tui/screens/McpSuggestedPromptsScreen.tsx
|
|
2806
3792
|
/**
|
|
2807
3793
|
* McpSuggestedPromptsScreen — shown after MCP install succeeds in the
|
|
2808
|
-
* standalone `wizard mcp add` program
|
|
3794
|
+
* standalone `wizard mcp add` program, and as the entry point for
|
|
3795
|
+
* `wizard mcp tutorial`.
|
|
2809
3796
|
*
|
|
2810
3797
|
* Phases:
|
|
2811
|
-
* 1. Choose
|
|
2812
|
-
*
|
|
2813
|
-
* 2. Authenticating
|
|
2814
|
-
*
|
|
2815
|
-
*
|
|
2816
|
-
*
|
|
2817
|
-
*
|
|
2818
|
-
* 3.
|
|
2819
|
-
*
|
|
2820
|
-
*
|
|
2821
|
-
*
|
|
2822
|
-
*
|
|
2823
|
-
*
|
|
2824
|
-
*
|
|
2825
|
-
*
|
|
2826
|
-
*
|
|
3798
|
+
* 1. Choose — opens with a Log in / Exit picker, framed by a
|
|
3799
|
+
* teaser of what MCP can do.
|
|
3800
|
+
* 2. Authenticating — runs `services.performLogin()` (OAuth in
|
|
3801
|
+
* production, canned values in the playground).
|
|
3802
|
+
* Renders a spinner + login URL inline while the
|
|
3803
|
+
* promise is pending. Errors return to Choose
|
|
3804
|
+
* with an inline error line.
|
|
3805
|
+
* 3. Greeting — role-tuned welcome via `getRoleGreeting`. A
|
|
3806
|
+
* ContentSequencer animates the headline,
|
|
3807
|
+
* bullets, and outro, then hands off to
|
|
3808
|
+
* PromptPicker. Only fires once per session
|
|
3809
|
+
* (returning via `[p]` skips it).
|
|
3810
|
+
* 4. PromptPicker — lists the role-tailored kit from
|
|
3811
|
+
* `getRolePrompts`; user picks one to run.
|
|
3812
|
+
* 5. Running — streams the agent's response inline via
|
|
3813
|
+
* `services.runPromptStreaming`. Text chunks
|
|
3814
|
+
* typewrite in; tool calls and results render
|
|
3815
|
+
* as styled badges. `[esc]` aborts; `[p]`
|
|
3816
|
+
* returns to the picker. On `done`/`error`,
|
|
3817
|
+
* auto-advances to FollowUp.
|
|
3818
|
+
* 6. FollowUp — surfaces 3 context-aware next prompts inferred
|
|
3819
|
+
* from the last tool the agent used (via
|
|
3820
|
+
* `getFollowUps`), plus an explicit exit.
|
|
3821
|
+
* Picking a follow-up re-enters Running; the
|
|
3822
|
+
* conversation tree grows as deep as
|
|
3823
|
+
* MAX_PROMPT_RUNS allows.
|
|
2827
3824
|
*
|
|
2828
|
-
* Credentials are guaranteed non-null once
|
|
2829
|
-
* reached (the Choose → Authenticating gate
|
|
2830
|
-
*
|
|
2831
|
-
* useEffect against a state-machine bug.
|
|
3825
|
+
* Credentials are guaranteed non-null once Greeting / PromptPicker /
|
|
3826
|
+
* Running / FollowUp are reached (the Choose → Authenticating gate
|
|
3827
|
+
* forces a successful login first). A defensive throw protects the
|
|
3828
|
+
* Running useEffect against a state-machine bug.
|
|
2832
3829
|
*/
|
|
2833
|
-
const MAX_PROMPT_RUNS =
|
|
3830
|
+
const MAX_PROMPT_RUNS = 5;
|
|
3831
|
+
const FOLLOW_UP_DELAY_MS = 3e3;
|
|
2834
3832
|
const McpSuggestedPromptsScreen = ({ store, services }) => {
|
|
2835
3833
|
useSyncExternalStore((cb) => store.subscribe(cb), () => store.getSnapshot());
|
|
2836
3834
|
const session = store.session;
|
|
2837
|
-
const kit =
|
|
3835
|
+
const kit = getRolePrompts(session.roleAtOrganization, session.integration);
|
|
3836
|
+
const crossSell = useMemo(() => getCrossSellPrompts(session.roleAtOrganization), [session.roleAtOrganization]);
|
|
3837
|
+
const greeting = useMemo(() => getRoleGreeting(session.roleAtOrganization), [session.roleAtOrganization]);
|
|
2838
3838
|
const [phase, setPhase] = useState("choose");
|
|
2839
3839
|
const [loginError, setLoginError] = useState(null);
|
|
2840
3840
|
const [runningPrompt, setRunningPrompt] = useState(null);
|
|
2841
3841
|
const [runChunks, setRunChunks] = useState([]);
|
|
2842
3842
|
const [runStartedAt, setRunStartedAt] = useState(null);
|
|
3843
|
+
const [runDurationSecs, setRunDurationSecs] = useState(null);
|
|
2843
3844
|
const [runCount, setRunCount] = useState(0);
|
|
2844
3845
|
const canPickAnother = runCount < MAX_PROMPT_RUNS;
|
|
3846
|
+
const [lastToolName, setLastToolName] = useState(null);
|
|
3847
|
+
const [branchHistory, setBranchHistory] = useState([]);
|
|
2845
3848
|
const runAbortRef = useRef(null);
|
|
3849
|
+
const currentSessionIdRef = useRef(null);
|
|
2846
3850
|
useEffect(() => {
|
|
2847
3851
|
if (phase !== "authenticating") return;
|
|
2848
3852
|
let cancelled = false;
|
|
@@ -2854,7 +3858,7 @@ const McpSuggestedPromptsScreen = ({ store, services }) => {
|
|
|
2854
3858
|
store.setRoleAtOrganization(roleAtOrganization);
|
|
2855
3859
|
store.setApiUser(user);
|
|
2856
3860
|
store.setLoginUrl(null);
|
|
2857
|
-
setPhase("
|
|
3861
|
+
setPhase("greeting");
|
|
2858
3862
|
} catch (err) {
|
|
2859
3863
|
if (cancelled) return;
|
|
2860
3864
|
const message = err instanceof Error ? err.message : String(err);
|
|
@@ -2881,6 +3885,24 @@ const McpSuggestedPromptsScreen = ({ store, services }) => {
|
|
|
2881
3885
|
const startedAt = Date.now();
|
|
2882
3886
|
setRunStartedAt(startedAt);
|
|
2883
3887
|
setRunChunks([]);
|
|
3888
|
+
setLastToolName(null);
|
|
3889
|
+
setRunDurationSecs(null);
|
|
3890
|
+
const finishStream = (kind, durationMs, errorText) => {
|
|
3891
|
+
if (controller.signal.aborted) return;
|
|
3892
|
+
setRunDurationSecs(Math.round(durationMs / 1e3));
|
|
3893
|
+
if (kind === "done") analytics.wizardCapture("mcp suggested prompts run", {
|
|
3894
|
+
prompt: runningPrompt,
|
|
3895
|
+
durationMs
|
|
3896
|
+
});
|
|
3897
|
+
else analytics.wizardCapture("mcp suggested prompts run failed", {
|
|
3898
|
+
prompt: runningPrompt,
|
|
3899
|
+
error: errorText
|
|
3900
|
+
});
|
|
3901
|
+
setTimeout(() => {
|
|
3902
|
+
if (controller.signal.aborted) return;
|
|
3903
|
+
setPhase("follow-up");
|
|
3904
|
+
}, FOLLOW_UP_DELAY_MS);
|
|
3905
|
+
};
|
|
2884
3906
|
(async () => {
|
|
2885
3907
|
const credentials = session.credentials;
|
|
2886
3908
|
if (!credentials) return;
|
|
@@ -2888,22 +3910,19 @@ const McpSuggestedPromptsScreen = ({ store, services }) => {
|
|
|
2888
3910
|
for await (const chunk of services.runPromptStreaming({
|
|
2889
3911
|
prompt: runningPrompt,
|
|
2890
3912
|
credentials,
|
|
2891
|
-
signal: controller.signal
|
|
3913
|
+
signal: controller.signal,
|
|
3914
|
+
resumeSessionId: currentSessionIdRef.current ?? void 0
|
|
2892
3915
|
})) {
|
|
2893
3916
|
if (controller.signal.aborted) return;
|
|
2894
3917
|
setRunChunks((prev) => [...prev, chunk]);
|
|
3918
|
+
if (chunk.kind === "tool-call") setLastToolName(chunk.toolName);
|
|
2895
3919
|
if (chunk.kind === "done") {
|
|
2896
|
-
|
|
2897
|
-
|
|
2898
|
-
durationMs: Date.now() - startedAt
|
|
2899
|
-
});
|
|
3920
|
+
if (chunk.sessionId) currentSessionIdRef.current = chunk.sessionId;
|
|
3921
|
+
finishStream("done", Date.now() - startedAt);
|
|
2900
3922
|
return;
|
|
2901
3923
|
}
|
|
2902
3924
|
if (chunk.kind === "error") {
|
|
2903
|
-
|
|
2904
|
-
prompt: runningPrompt,
|
|
2905
|
-
error: chunk.text
|
|
2906
|
-
});
|
|
3925
|
+
finishStream("error", Date.now() - startedAt, chunk.text);
|
|
2907
3926
|
return;
|
|
2908
3927
|
}
|
|
2909
3928
|
}
|
|
@@ -2914,10 +3933,7 @@ const McpSuggestedPromptsScreen = ({ store, services }) => {
|
|
|
2914
3933
|
kind: "error",
|
|
2915
3934
|
text
|
|
2916
3935
|
}]);
|
|
2917
|
-
|
|
2918
|
-
prompt: runningPrompt,
|
|
2919
|
-
error: text
|
|
2920
|
-
});
|
|
3936
|
+
finishStream("error", Date.now() - startedAt, text);
|
|
2921
3937
|
}
|
|
2922
3938
|
})();
|
|
2923
3939
|
return () => {
|
|
@@ -2930,7 +3946,11 @@ const McpSuggestedPromptsScreen = ({ store, services }) => {
|
|
|
2930
3946
|
services,
|
|
2931
3947
|
session.credentials
|
|
2932
3948
|
]);
|
|
2933
|
-
const
|
|
3949
|
+
const enterGoodbye = () => {
|
|
3950
|
+
runAbortRef.current?.abort();
|
|
3951
|
+
setPhase("goodbye");
|
|
3952
|
+
};
|
|
3953
|
+
const closeWizard = () => {
|
|
2934
3954
|
setPhase("done");
|
|
2935
3955
|
setTimeout(() => {
|
|
2936
3956
|
store.setMcpSuggestedPromptsDismissed();
|
|
@@ -2944,35 +3964,66 @@ const McpSuggestedPromptsScreen = ({ store, services }) => {
|
|
|
2944
3964
|
setPhase("authenticating");
|
|
2945
3965
|
} else {
|
|
2946
3966
|
analytics.wizardCapture("mcp suggested prompts choose", { choice: "exit" });
|
|
2947
|
-
|
|
3967
|
+
enterGoodbye();
|
|
2948
3968
|
}
|
|
2949
3969
|
};
|
|
2950
|
-
const
|
|
2951
|
-
setRunningPrompt(
|
|
3970
|
+
const startRun = (prompt) => {
|
|
3971
|
+
setRunningPrompt(prompt);
|
|
2952
3972
|
setRunCount((c) => c + 1);
|
|
3973
|
+
setBranchHistory((h) => [...h, prompt]);
|
|
2953
3974
|
setPhase("running");
|
|
2954
3975
|
};
|
|
2955
|
-
|
|
2956
|
-
|
|
2957
|
-
|
|
2958
|
-
|
|
2959
|
-
|
|
2960
|
-
|
|
2961
|
-
|
|
2962
|
-
|
|
2963
|
-
|
|
2964
|
-
|
|
2965
|
-
|
|
2966
|
-
|
|
2967
|
-
label: "p",
|
|
2968
|
-
action: canPickAnother ? "pick new prompt" : "cap reached",
|
|
2969
|
-
handler: () => {
|
|
2970
|
-
if (phase !== "running") return;
|
|
2971
|
-
if (!canPickAnother) return;
|
|
2972
|
-
runAbortRef.current?.abort();
|
|
2973
|
-
setPhase("prompt-picker");
|
|
3976
|
+
const handlePromptPick = (value) => {
|
|
3977
|
+
startRun(Array.isArray(value) ? value[0] : value);
|
|
3978
|
+
};
|
|
3979
|
+
const handleFollowUpPick = (value) => {
|
|
3980
|
+
const picked = Array.isArray(value) ? value[0] : value;
|
|
3981
|
+
if (picked === "__follow_up_exit__") {
|
|
3982
|
+
analytics.wizardCapture("mcp suggested prompts follow-up", {
|
|
3983
|
+
choice: "exit",
|
|
3984
|
+
depth: branchHistory.length
|
|
3985
|
+
});
|
|
3986
|
+
enterGoodbye();
|
|
3987
|
+
return;
|
|
2974
3988
|
}
|
|
2975
|
-
|
|
3989
|
+
analytics.wizardCapture("mcp suggested prompts follow-up", {
|
|
3990
|
+
choice: "continue",
|
|
3991
|
+
depth: branchHistory.length,
|
|
3992
|
+
lastToolName
|
|
3993
|
+
});
|
|
3994
|
+
startRun(picked);
|
|
3995
|
+
};
|
|
3996
|
+
useKeyBindings("mcp-suggested-prompts", [
|
|
3997
|
+
{
|
|
3998
|
+
match: "escape",
|
|
3999
|
+
label: "esc",
|
|
4000
|
+
action: phase === "goodbye" ? "close" : "exit",
|
|
4001
|
+
handler: () => {
|
|
4002
|
+
if (phase === "goodbye") closeWizard();
|
|
4003
|
+
else if (phase === "running" || phase === "prompt-picker" || phase === "follow-up" || phase === "greeting") enterGoodbye();
|
|
4004
|
+
}
|
|
4005
|
+
},
|
|
4006
|
+
{
|
|
4007
|
+
match: "p",
|
|
4008
|
+
label: "p",
|
|
4009
|
+
action: canPickAnother ? "pick new prompt" : "cap reached",
|
|
4010
|
+
handler: () => {
|
|
4011
|
+
if (phase !== "running" && phase !== "follow-up") return;
|
|
4012
|
+
if (!canPickAnother) return;
|
|
4013
|
+
runAbortRef.current?.abort();
|
|
4014
|
+
currentSessionIdRef.current = null;
|
|
4015
|
+
setPhase("prompt-picker");
|
|
4016
|
+
}
|
|
4017
|
+
},
|
|
4018
|
+
...phase === "greeting" ? [{
|
|
4019
|
+
match: "return",
|
|
4020
|
+
label: "enter",
|
|
4021
|
+
action: "continue",
|
|
4022
|
+
handler: () => {
|
|
4023
|
+
setPhase("prompt-picker");
|
|
4024
|
+
}
|
|
4025
|
+
}] : []
|
|
4026
|
+
]);
|
|
2976
4027
|
return /* @__PURE__ */ jsx(Box, {
|
|
2977
4028
|
flexDirection: "column",
|
|
2978
4029
|
flexGrow: 1,
|
|
@@ -2985,25 +4036,60 @@ const McpSuggestedPromptsScreen = ({ store, services }) => {
|
|
|
2985
4036
|
onSelect: handleChoice
|
|
2986
4037
|
}),
|
|
2987
4038
|
phase === "authenticating" && /* @__PURE__ */ jsx(AuthenticatingPhase, { loginUrl: session.loginUrl }),
|
|
2988
|
-
phase === "
|
|
2989
|
-
|
|
2990
|
-
children: /* @__PURE__ */ jsx(Text, {
|
|
2991
|
-
bold: true,
|
|
2992
|
-
color: Colors.accent,
|
|
2993
|
-
children: "MCP tutorial"
|
|
2994
|
-
})
|
|
2995
|
-
}), /* @__PURE__ */ jsx(PromptPickerPhase, {
|
|
2996
|
-
promptKit: kit,
|
|
4039
|
+
phase === "greeting" && /* @__PURE__ */ jsx(GreetingPhase, {
|
|
4040
|
+
greeting,
|
|
2997
4041
|
userDisplayName: session.apiUser?.first_name || null,
|
|
4042
|
+
onComplete: () => setPhase("prompt-picker")
|
|
4043
|
+
}),
|
|
4044
|
+
phase === "prompt-picker" && /* @__PURE__ */ jsx(PromptPickerPhase, {
|
|
4045
|
+
promptKit: kit,
|
|
4046
|
+
crossSell,
|
|
2998
4047
|
onSelect: handlePromptPick
|
|
2999
|
-
})
|
|
4048
|
+
}),
|
|
3000
4049
|
phase === "running" && runningPrompt && /* @__PURE__ */ jsx(RunningPhase, {
|
|
3001
4050
|
prompt: runningPrompt,
|
|
3002
4051
|
chunks: runChunks,
|
|
3003
4052
|
startedAt: runStartedAt,
|
|
3004
|
-
|
|
4053
|
+
frozenDurationSecs: runDurationSecs,
|
|
3005
4054
|
runCount,
|
|
3006
4055
|
maxRuns: MAX_PROMPT_RUNS
|
|
4056
|
+
}),
|
|
4057
|
+
phase === "follow-up" && /* @__PURE__ */ jsxs(Box, {
|
|
4058
|
+
flexDirection: "column",
|
|
4059
|
+
flexGrow: 1,
|
|
4060
|
+
children: [runningPrompt && /* @__PURE__ */ jsx(Box, {
|
|
4061
|
+
flexDirection: "column",
|
|
4062
|
+
flexShrink: 1,
|
|
4063
|
+
children: /* @__PURE__ */ jsx(RunningPhase, {
|
|
4064
|
+
prompt: runningPrompt,
|
|
4065
|
+
chunks: runChunks,
|
|
4066
|
+
startedAt: runStartedAt,
|
|
4067
|
+
frozenDurationSecs: runDurationSecs,
|
|
4068
|
+
runCount,
|
|
4069
|
+
maxRuns: MAX_PROMPT_RUNS
|
|
4070
|
+
})
|
|
4071
|
+
}), /* @__PURE__ */ jsx(Box, {
|
|
4072
|
+
marginTop: 1,
|
|
4073
|
+
flexShrink: 0,
|
|
4074
|
+
flexDirection: "column",
|
|
4075
|
+
children: /* @__PURE__ */ jsx(FollowUpPhase, {
|
|
4076
|
+
lastToolName,
|
|
4077
|
+
lastPrompt: runningPrompt,
|
|
4078
|
+
chunks: runChunks,
|
|
4079
|
+
role: session.roleAtOrganization,
|
|
4080
|
+
branchHistory,
|
|
4081
|
+
canPickAnother,
|
|
4082
|
+
maxRuns: MAX_PROMPT_RUNS,
|
|
4083
|
+
onSelect: handleFollowUpPick
|
|
4084
|
+
})
|
|
4085
|
+
})]
|
|
4086
|
+
}),
|
|
4087
|
+
phase === "goodbye" && /* @__PURE__ */ jsx(GoodbyePhase, {
|
|
4088
|
+
installedClients: session.mcpInstalledClients,
|
|
4089
|
+
role: session.roleAtOrganization,
|
|
4090
|
+
integration: session.integration,
|
|
4091
|
+
engaged: branchHistory.length > 0,
|
|
4092
|
+
onClose: closeWizard
|
|
3007
4093
|
})
|
|
3008
4094
|
]
|
|
3009
4095
|
})
|
|
@@ -3093,56 +4179,109 @@ const AuthenticatingPhase = ({ loginUrl }) => /* @__PURE__ */ jsxs(Box, {
|
|
|
3093
4179
|
] })
|
|
3094
4180
|
})]
|
|
3095
4181
|
});
|
|
3096
|
-
const
|
|
3097
|
-
const
|
|
3098
|
-
|
|
3099
|
-
|
|
3100
|
-
|
|
3101
|
-
|
|
4182
|
+
const GreetingPhase = ({ greeting, userDisplayName, onComplete }) => {
|
|
4183
|
+
const blocks = [];
|
|
4184
|
+
if (userDisplayName) blocks.push({
|
|
4185
|
+
content: `Hi ${userDisplayName}!`,
|
|
4186
|
+
mode: 0,
|
|
4187
|
+
animationInterval: 70,
|
|
4188
|
+
pause: 1200
|
|
4189
|
+
});
|
|
4190
|
+
blocks.push({
|
|
4191
|
+
content: greeting.headline,
|
|
4192
|
+
mode: 0,
|
|
4193
|
+
animationInterval: 45,
|
|
4194
|
+
pause: 2e3
|
|
4195
|
+
});
|
|
4196
|
+
blocks.push({
|
|
4197
|
+
type: "lines",
|
|
4198
|
+
lines: greeting.bullets.map((bullet, i) => /* @__PURE__ */ jsxs(Text, { children: [
|
|
4199
|
+
/* @__PURE__ */ jsx(Text, {
|
|
4200
|
+
color: Colors.primary,
|
|
4201
|
+
children: Icons.diamond
|
|
4202
|
+
}),
|
|
4203
|
+
" ",
|
|
4204
|
+
/* @__PURE__ */ jsx(Text, {
|
|
4205
|
+
dimColor: true,
|
|
4206
|
+
children: bullet
|
|
4207
|
+
})
|
|
4208
|
+
] }, i)),
|
|
4209
|
+
interval: 700,
|
|
4210
|
+
pause: 2200
|
|
4211
|
+
});
|
|
4212
|
+
blocks.push({
|
|
4213
|
+
content: greeting.outro,
|
|
4214
|
+
mode: 0,
|
|
4215
|
+
animationInterval: 38,
|
|
4216
|
+
pause: 1800
|
|
4217
|
+
});
|
|
4218
|
+
return /* @__PURE__ */ jsxs(Box, {
|
|
3102
4219
|
flexDirection: "column",
|
|
3103
|
-
children: /* @__PURE__ */ jsx(
|
|
3104
|
-
|
|
3105
|
-
|
|
3106
|
-
|
|
3107
|
-
|
|
3108
|
-
|
|
3109
|
-
|
|
3110
|
-
|
|
3111
|
-
|
|
3112
|
-
{
|
|
3113
|
-
content: "Pick a prompt to see the PostHog MCP in action.",
|
|
3114
|
-
mode: 0,
|
|
3115
|
-
animationInterval: 50,
|
|
3116
|
-
pause: 1e3,
|
|
3117
|
-
dimWhenComplete: false
|
|
3118
|
-
},
|
|
3119
|
-
{
|
|
3120
|
-
content: /* @__PURE__ */ jsxs(Fragment$1, { children: [/* @__PURE__ */ jsx(PickerMenu, {
|
|
3121
|
-
options,
|
|
3122
|
-
optionMarginBottom: 1,
|
|
3123
|
-
onSelect
|
|
3124
|
-
}), /* @__PURE__ */ jsx(Box, {
|
|
3125
|
-
marginTop: 2,
|
|
3126
|
-
children: /* @__PURE__ */ jsxs(Text, { children: [/* @__PURE__ */ jsx(Text, {
|
|
3127
|
-
bold: true,
|
|
3128
|
-
children: "[esc]"
|
|
3129
|
-
}), /* @__PURE__ */ jsx(Text, { children: " to exit" })] })
|
|
3130
|
-
})] }),
|
|
3131
|
-
persist: true
|
|
3132
|
-
}
|
|
3133
|
-
],
|
|
4220
|
+
children: [/* @__PURE__ */ jsx(Box, {
|
|
4221
|
+
marginBottom: 1,
|
|
4222
|
+
children: /* @__PURE__ */ jsx(Text, {
|
|
4223
|
+
bold: true,
|
|
4224
|
+
color: Colors.accent,
|
|
4225
|
+
children: "MCP tutorial"
|
|
4226
|
+
})
|
|
4227
|
+
}), /* @__PURE__ */ jsx(ContentSequencer, {
|
|
4228
|
+
blocks,
|
|
3134
4229
|
mode: 0,
|
|
3135
|
-
blockInterval:
|
|
3136
|
-
|
|
4230
|
+
blockInterval: 500,
|
|
4231
|
+
onSequenceComplete: onComplete
|
|
4232
|
+
})]
|
|
4233
|
+
});
|
|
4234
|
+
};
|
|
4235
|
+
const PromptPickerPhase = ({ promptKit, crossSell, onSelect }) => {
|
|
4236
|
+
const seenPrompts = /* @__PURE__ */ new Set();
|
|
4237
|
+
const options = [
|
|
4238
|
+
PINNED_FIRST_PROMPT,
|
|
4239
|
+
...crossSell,
|
|
4240
|
+
...promptKit
|
|
4241
|
+
].filter((o) => {
|
|
4242
|
+
if (seenPrompts.has(o.prompt)) return false;
|
|
4243
|
+
seenPrompts.add(o.prompt);
|
|
4244
|
+
return true;
|
|
4245
|
+
}).slice(0, 4).map((o) => ({
|
|
4246
|
+
label: o.product ? `Try ${o.product} — ${o.label ?? o.prompt}` : o.label ?? o.prompt,
|
|
4247
|
+
value: o.prompt
|
|
4248
|
+
}));
|
|
4249
|
+
return /* @__PURE__ */ jsxs(Box, {
|
|
4250
|
+
flexDirection: "column",
|
|
4251
|
+
children: [
|
|
4252
|
+
/* @__PURE__ */ jsx(Box, {
|
|
4253
|
+
marginBottom: 1,
|
|
4254
|
+
children: /* @__PURE__ */ jsx(Text, {
|
|
4255
|
+
bold: true,
|
|
4256
|
+
color: Colors.accent,
|
|
4257
|
+
children: "MCP tutorial"
|
|
4258
|
+
})
|
|
4259
|
+
}),
|
|
4260
|
+
/* @__PURE__ */ jsx(Box, {
|
|
4261
|
+
marginBottom: 1,
|
|
4262
|
+
children: /* @__PURE__ */ jsx(Text, { children: "Pick a prompt to see the PostHog MCP in action." })
|
|
4263
|
+
}),
|
|
4264
|
+
/* @__PURE__ */ jsx(PickerMenu, {
|
|
4265
|
+
options,
|
|
4266
|
+
optionMarginBottom: 1,
|
|
4267
|
+
onSelect
|
|
4268
|
+
}),
|
|
4269
|
+
/* @__PURE__ */ jsx(Box, {
|
|
4270
|
+
marginTop: 2,
|
|
4271
|
+
children: /* @__PURE__ */ jsxs(Text, { children: [/* @__PURE__ */ jsx(Text, {
|
|
4272
|
+
bold: true,
|
|
4273
|
+
children: "[esc]"
|
|
4274
|
+
}), /* @__PURE__ */ jsx(Text, { children: " to exit" })] })
|
|
4275
|
+
})
|
|
4276
|
+
]
|
|
3137
4277
|
});
|
|
3138
4278
|
};
|
|
3139
|
-
const RunningPhase = ({ prompt, chunks, startedAt,
|
|
4279
|
+
const RunningPhase = ({ prompt, chunks, startedAt, frozenDurationSecs, runCount, maxRuns }) => {
|
|
3140
4280
|
const isDone = chunks.some((c) => c.kind === "done");
|
|
3141
4281
|
const errorChunk = chunks.find((c) => c.kind === "error");
|
|
3142
4282
|
const finished = isDone || !!errorChunk;
|
|
3143
|
-
const elapsed = startedAt ? Math.round((Date.now() - startedAt) / 1e3) : 0;
|
|
3144
|
-
const visibleChunks = finished ?
|
|
3145
|
-
const cappedChunks = finished ? capTextChunks(visibleChunks) : visibleChunks;
|
|
4283
|
+
const elapsed = frozenDurationSecs ?? (startedAt ? Math.round((Date.now() - startedAt) / 1e3) : 0);
|
|
4284
|
+
const visibleChunks = finished ? capTextChunks(collapseToFinalAnswer(chunks)) : chunks;
|
|
3146
4285
|
return /* @__PURE__ */ jsxs(Box, {
|
|
3147
4286
|
flexDirection: "column",
|
|
3148
4287
|
children: [
|
|
@@ -3181,52 +4320,63 @@ const RunningPhase = ({ prompt, chunks, startedAt, canPickAnother, runCount, max
|
|
|
3181
4320
|
/* @__PURE__ */ jsx(Box, {
|
|
3182
4321
|
marginTop: 1,
|
|
3183
4322
|
flexDirection: "column",
|
|
3184
|
-
children:
|
|
3185
|
-
}),
|
|
3186
|
-
finished && !canPickAnother && /* @__PURE__ */ jsx(Box, {
|
|
3187
|
-
marginTop: 1,
|
|
3188
|
-
children: /* @__PURE__ */ jsxs(Text, { children: [
|
|
3189
|
-
/* @__PURE__ */ jsxs(Text, {
|
|
3190
|
-
dimColor: true,
|
|
3191
|
-
children: [
|
|
3192
|
-
"You've hit the ",
|
|
3193
|
-
maxRuns,
|
|
3194
|
-
"-prompt tutorial cap. Press",
|
|
3195
|
-
" "
|
|
3196
|
-
]
|
|
3197
|
-
}),
|
|
3198
|
-
/* @__PURE__ */ jsx(Text, {
|
|
3199
|
-
bold: true,
|
|
3200
|
-
dimColor: true,
|
|
3201
|
-
children: "[esc]"
|
|
3202
|
-
}),
|
|
3203
|
-
/* @__PURE__ */ jsx(Text, {
|
|
3204
|
-
dimColor: true,
|
|
3205
|
-
children: " to exit."
|
|
3206
|
-
})
|
|
3207
|
-
] })
|
|
4323
|
+
children: visibleChunks.map((chunk, idx) => /* @__PURE__ */ jsx(ChunkLine, { chunk }, idx))
|
|
3208
4324
|
})
|
|
3209
4325
|
]
|
|
3210
4326
|
});
|
|
3211
4327
|
};
|
|
3212
4328
|
/**
|
|
4329
|
+
* Strip everything except the agent's final answer + any error chunks.
|
|
4330
|
+
* Drops tool-call / tool-result chatter (their work is done once the
|
|
4331
|
+
* stream completes) and any text blocks emitted BEFORE the last text
|
|
4332
|
+
* block — those are typically Sonnet's "I'll query X…" preamble that
|
|
4333
|
+
* arrives alongside the first tool_use and adds noise above the picker.
|
|
4334
|
+
*
|
|
4335
|
+
* If the run produced no text at all (pure tool calls, or only errors),
|
|
4336
|
+
* fall through to whatever chunks survived so the user isn't left with
|
|
4337
|
+
* a blank result.
|
|
4338
|
+
*/
|
|
4339
|
+
function collapseToFinalAnswer(chunks) {
|
|
4340
|
+
const textChunks = chunks.filter((c) => c.kind === "text");
|
|
4341
|
+
const errors = chunks.filter((c) => c.kind === "error");
|
|
4342
|
+
if (textChunks.length === 0) return errors;
|
|
4343
|
+
return [textChunks[textChunks.length - 1], ...errors];
|
|
4344
|
+
}
|
|
4345
|
+
/**
|
|
3213
4346
|
* Belt-and-suspenders fallback for runs where Claude ignored the
|
|
3214
4347
|
* terminal-fit system prompt and produced an overlong response. Joins
|
|
3215
|
-
* all text chunks,
|
|
3216
|
-
*
|
|
3217
|
-
*
|
|
3218
|
-
*
|
|
4348
|
+
* all text chunks, then walks them from the bottom keeping only as many
|
|
4349
|
+
* lines as fit in the visual row budget — wide lines that wrap to
|
|
4350
|
+
* multiple rows on a narrow terminal cost their wrapped row count, not
|
|
4351
|
+
* 1. Prepends an indicator showing how many source lines got cut. Tool
|
|
4352
|
+
* calls, results, and errors are preserved separately so they don't
|
|
4353
|
+
* disappear into the truncation.
|
|
4354
|
+
*
|
|
4355
|
+
* Visual-row-aware truncation is what makes the FollowUp picker feel
|
|
4356
|
+
* pinned: a 5-row table that wraps to 12 visual rows on a 60-col
|
|
4357
|
+
* terminal correctly counts as 12, so the cap leaves exactly the room
|
|
4358
|
+
* the picker needs.
|
|
3219
4359
|
*/
|
|
3220
4360
|
function capTextChunks(chunks) {
|
|
3221
4361
|
const rows = process.stdout.rows ?? 24;
|
|
3222
|
-
const
|
|
4362
|
+
const cols = process.stdout.columns ?? 120;
|
|
4363
|
+
const maxVisualRows = Math.max(3, rows - 19);
|
|
3223
4364
|
const textChunks = chunks.filter((c) => c.kind === "text");
|
|
3224
4365
|
const errors = chunks.filter((c) => c.kind === "error");
|
|
3225
4366
|
if (textChunks.length === 0) return chunks;
|
|
3226
4367
|
const lines = textChunks.map((c) => c.text).join("").split("\n");
|
|
3227
|
-
|
|
3228
|
-
|
|
3229
|
-
|
|
4368
|
+
const visualRows = (line) => Math.max(1, Math.ceil(line.length / cols));
|
|
4369
|
+
let used = 0;
|
|
4370
|
+
let keepFrom = lines.length;
|
|
4371
|
+
for (let i = lines.length - 1; i >= 0; i--) {
|
|
4372
|
+
const cost = visualRows(lines[i]);
|
|
4373
|
+
if (used + cost > maxVisualRows) break;
|
|
4374
|
+
used += cost;
|
|
4375
|
+
keepFrom = i;
|
|
4376
|
+
}
|
|
4377
|
+
if (keepFrom === 0) return chunks;
|
|
4378
|
+
const hidden = keepFrom;
|
|
4379
|
+
const tail = lines.slice(keepFrom).join("\n");
|
|
3230
4380
|
return [{
|
|
3231
4381
|
kind: "text",
|
|
3232
4382
|
text: `[${hidden} line${hidden === 1 ? "" : "s"} above — expand terminal to see more]\n\n${tail}`
|
|
@@ -3257,6 +4407,101 @@ const ChunkLine = ({ chunk }) => {
|
|
|
3257
4407
|
});
|
|
3258
4408
|
return null;
|
|
3259
4409
|
};
|
|
4410
|
+
const FollowUpPhase = ({ lastToolName, lastPrompt, chunks, role, branchHistory, canPickAnother, maxRuns, onSelect }) => {
|
|
4411
|
+
const followUps = useMemo(() => getFollowUps({
|
|
4412
|
+
lastToolName,
|
|
4413
|
+
lastPrompt: lastPrompt || "",
|
|
4414
|
+
role,
|
|
4415
|
+
branchHistory
|
|
4416
|
+
}), [
|
|
4417
|
+
lastToolName,
|
|
4418
|
+
lastPrompt,
|
|
4419
|
+
role,
|
|
4420
|
+
branchHistory
|
|
4421
|
+
]);
|
|
4422
|
+
const options = canPickAnother ? followUps.map((f) => ({
|
|
4423
|
+
label: f.label ?? f.prompt,
|
|
4424
|
+
value: f.prompt
|
|
4425
|
+
})) : [{
|
|
4426
|
+
label: "Exit",
|
|
4427
|
+
value: FOLLOW_UP_EXIT_SENTINEL
|
|
4428
|
+
}];
|
|
4429
|
+
return /* @__PURE__ */ jsxs(Box, {
|
|
4430
|
+
flexDirection: "column",
|
|
4431
|
+
children: [/* @__PURE__ */ jsx(Text, { children: chunks.find((c) => c.kind === "error") ? "That one errored out — try a different angle?" : !canPickAnother ? `You've hit the ${maxRuns}-prompt tutorial cap.` : `Want to keep exploring? Select a follow-up prompt.` }), /* @__PURE__ */ jsx(PickerMenu, {
|
|
4432
|
+
options,
|
|
4433
|
+
onSelect
|
|
4434
|
+
})]
|
|
4435
|
+
});
|
|
4436
|
+
};
|
|
4437
|
+
const GoodbyePhase = ({ installedClients, role, integration, engaged, onClose }) => {
|
|
4438
|
+
const samples = getRolePrompts(role, integration).slice(0, 3);
|
|
4439
|
+
const headline = engaged ? "Nice work. You can keep talking to PostHog anytime." : "You're all set — PostHog MCP is here when you're ready.";
|
|
4440
|
+
const introLine = installedClients.length > 0 ? /* @__PURE__ */ jsxs(Text, { children: [
|
|
4441
|
+
"MCP is set up in",
|
|
4442
|
+
" ",
|
|
4443
|
+
/* @__PURE__ */ jsx(Text, {
|
|
4444
|
+
bold: true,
|
|
4445
|
+
color: Colors.primary,
|
|
4446
|
+
children: installedClients.join(", ")
|
|
4447
|
+
}),
|
|
4448
|
+
". Open one and try a prompt like:"
|
|
4449
|
+
] }) : /* @__PURE__ */ jsx(Text, { children: "Wherever you have MCP set up (Claude Code, Cursor, VS Code, Windsurf, Zed, etc.), open the agent and try a prompt like:" });
|
|
4450
|
+
return /* @__PURE__ */ jsxs(Box, {
|
|
4451
|
+
flexDirection: "column",
|
|
4452
|
+
children: [
|
|
4453
|
+
/* @__PURE__ */ jsx(Box, {
|
|
4454
|
+
marginBottom: 1,
|
|
4455
|
+
children: /* @__PURE__ */ jsx(Text, {
|
|
4456
|
+
bold: true,
|
|
4457
|
+
color: Colors.accent,
|
|
4458
|
+
children: headline
|
|
4459
|
+
})
|
|
4460
|
+
}),
|
|
4461
|
+
/* @__PURE__ */ jsx(Box, {
|
|
4462
|
+
marginBottom: 1,
|
|
4463
|
+
children: introLine
|
|
4464
|
+
}),
|
|
4465
|
+
/* @__PURE__ */ jsx(Box, {
|
|
4466
|
+
marginBottom: 1,
|
|
4467
|
+
flexDirection: "column",
|
|
4468
|
+
children: samples.map((p, i) => /* @__PURE__ */ jsxs(Box, { children: [
|
|
4469
|
+
/* @__PURE__ */ jsx(Text, {
|
|
4470
|
+
color: Colors.primary,
|
|
4471
|
+
children: Icons.triangleSmallRight
|
|
4472
|
+
}),
|
|
4473
|
+
/* @__PURE__ */ jsx(Text, { children: " " }),
|
|
4474
|
+
/* @__PURE__ */ jsx(Text, {
|
|
4475
|
+
dimColor: true,
|
|
4476
|
+
children: p.prompt
|
|
4477
|
+
})
|
|
4478
|
+
] }, i))
|
|
4479
|
+
}),
|
|
4480
|
+
/* @__PURE__ */ jsx(Box, {
|
|
4481
|
+
marginBottom: 1,
|
|
4482
|
+
children: /* @__PURE__ */ jsxs(Text, {
|
|
4483
|
+
dimColor: true,
|
|
4484
|
+
children: [
|
|
4485
|
+
"Re-run this tutorial anytime with",
|
|
4486
|
+
" ",
|
|
4487
|
+
/* @__PURE__ */ jsx(Text, {
|
|
4488
|
+
bold: true,
|
|
4489
|
+
children: "npx @posthog/wizard mcp tutorial"
|
|
4490
|
+
}),
|
|
4491
|
+
"."
|
|
4492
|
+
]
|
|
4493
|
+
})
|
|
4494
|
+
}),
|
|
4495
|
+
/* @__PURE__ */ jsx(PickerMenu, {
|
|
4496
|
+
options: [{
|
|
4497
|
+
label: "Close",
|
|
4498
|
+
value: "close"
|
|
4499
|
+
}],
|
|
4500
|
+
onSelect: onClose
|
|
4501
|
+
})
|
|
4502
|
+
]
|
|
4503
|
+
});
|
|
4504
|
+
};
|
|
3260
4505
|
//#endregion
|
|
3261
4506
|
//#region src/ui/tui/screens/audit/AuditChecksViewer/AreaHeaderRow.tsx
|
|
3262
4507
|
/** Sub-header row inside the scrollable body — one per area group. */
|
|
@@ -4120,4 +5365,4 @@ const AUDIT_3000_AREA_SLIDES = [
|
|
|
4120
5365
|
//#endregion
|
|
4121
5366
|
export { WizardStore as A, useStdoutDimensions as C, LoadingBox as D, ProgressList as E, SplitView as O, GroupedPickerMenu as S, useKeyBindings as T, ScreenContainer as _, McpSuggestedPromptsScreen as a, ModalOverlay as b, IssueTable as c, ServiceHealthList as d, TipsCard as f, TabContainer as g, HNViewer as h, AuditChecksViewer as i, CardLayout as k, SEVERITY_LABEL as l, ContentSequencer as m, AUDIT_AREA_SLIDES as n, TAILORED_ROLES as o, LearnCard as p, VisualBox as r, McpScreen as s, AUDIT_3000_AREA_SLIDES as t, SEVERITY_ORDER as u, EventPlanViewer as v, PickerMenu as w, ConfirmationInput as x, LogViewer as y };
|
|
4122
5367
|
|
|
4123
|
-
//# sourceMappingURL=slides-
|
|
5368
|
+
//# sourceMappingURL=slides-DRbBgsdd.js.map
|