@posthog/wizard 2.14.3 → 2.16.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 +43 -1
- package/dist/{TextBlock-DEHERFec.js → TextBlock-DJVhBkr3.js} +4 -4
- package/dist/TextBlock-DJVhBkr3.js.map +1 -0
- package/dist/{add-mcp-server-to-clients-B48J7VVO.js → add-mcp-server-to-clients-9jQjc-CO.js} +5 -5
- package/dist/{add-mcp-server-to-clients-B48J7VVO.js.map → add-mcp-server-to-clients-9jQjc-CO.js.map} +1 -1
- package/dist/{agent-interface-cEdS_bNo.js → agent-interface-pBnqJL8P.js} +106 -21
- package/dist/agent-interface-pBnqJL8P.js.map +1 -0
- package/dist/{agent-runner-CK5r-zQF.js → agent-runner-H1FP6XTc.js} +12 -9
- package/dist/agent-runner-H1FP6XTc.js.map +1 -0
- package/dist/{analytics-DaDpDus8.js → analytics-DZaUgJte.js} +2 -2
- package/dist/{analytics-DaDpDus8.js.map → analytics-DZaUgJte.js.map} +1 -1
- package/dist/analytics-DqeW7XYt.js +2 -0
- package/dist/bin.js +965 -83
- package/dist/bin.js.map +1 -1
- package/dist/{debug-B_PK52GI.js → debug-B6rX6xye.js} +1 -1
- package/dist/{debug-BOogNcWX.js → debug-C4jRuzny.js} +57 -46
- package/dist/debug-C4jRuzny.js.map +1 -0
- package/dist/{defaults-DgKAzsD1.js → defaults-GbLPuHxj.js} +1 -1
- package/dist/{defaults-DgKAzsD1.js.map → defaults-GbLPuHxj.js.map} +1 -1
- package/dist/{detection-OCF8fpfp.js → detection-4eukp9HD.js} +3 -3
- package/dist/{detection-OCF8fpfp.js.map → detection-4eukp9HD.js.map} +1 -1
- package/dist/{env-api-key-D5G2PrXW.js → env-api-key-DU8uIEvo.js} +1 -1
- package/dist/{env-api-key-D5G2PrXW.js.map → env-api-key-DU8uIEvo.js.map} +1 -1
- package/dist/{file-utils-DPmgn9Vm.js → file-utils-DnTSiTJw.js} +1 -1
- package/dist/file-utils-DnTSiTJw.js.map +1 -0
- package/dist/mcp-prompt-streaming-DKiaymMt.js +200 -0
- package/dist/mcp-prompt-streaming-DKiaymMt.js.map +1 -0
- package/dist/package-json-Cttzi3C8.js +2 -0
- package/dist/package-json-v_g2YlN1.js +35 -0
- package/dist/package-json-v_g2YlN1.js.map +1 -0
- package/dist/{package-manager-CmMJAD-V.js → package-manager-DLt75bit.js} +2 -2
- package/dist/package-manager-DLt75bit.js.map +1 -0
- package/dist/posthog-7B92c2Ed.js +120 -0
- package/dist/posthog-7B92c2Ed.js.map +1 -0
- package/dist/{posthog-integration-By5930Gz.js → posthog-integration-CukaeYil.js} +13 -12
- package/dist/{posthog-integration-By5930Gz.js.map → posthog-integration-CukaeYil.js.map} +1 -1
- package/dist/{provisioning-BHa8VWaa.js → provisioning-C_ETLiZE.js} +3 -3
- package/dist/{provisioning-BHa8VWaa.js.map → provisioning-C_ETLiZE.js.map} +1 -1
- package/dist/provisioning-Ch6i8dRV.js +2 -0
- package/dist/{registry-DpROZPnl.js → registry-DqbwO5EL.js} +31 -31
- package/dist/registry-DqbwO5EL.js.map +1 -0
- package/dist/setup-utils-C5uZ9g60.js +2 -0
- package/dist/{setup-utils-Mzpk1vqG.js → setup-utils-DdAdxUTV.js} +170 -60
- package/dist/setup-utils-DdAdxUTV.js.map +1 -0
- package/dist/{slides-BtDXEXdn.js → slides-Dpj4j0w_.js} +580 -27
- package/dist/slides-Dpj4j0w_.js.map +1 -0
- package/dist/smoke-test-ci.sh +5 -2
- package/dist/smoke-test.sh +43 -0
- package/dist/{start-playground-zZL5y9id.js → start-playground-B40O4tye.js} +288 -6
- package/dist/start-playground-B40O4tye.js.map +1 -0
- package/dist/{start-tui-Cz7RZSn_.js → start-tui-CH_ZzQXx.js} +628 -26
- package/dist/start-tui-CH_ZzQXx.js.map +1 -0
- package/dist/{steps-C2XEzN79.js → steps-0d9XqvI6.js} +6 -6
- package/dist/{steps-C2XEzN79.js.map → steps-0d9XqvI6.js.map} +1 -1
- package/dist/task-stream-CoEsidgG.js +195 -0
- package/dist/task-stream-CoEsidgG.js.map +1 -0
- package/dist/{telemetry-BG2bOwCp.js → telemetry-jn2Daxl2.js} +2 -2
- package/dist/{telemetry-BG2bOwCp.js.map → telemetry-jn2Daxl2.js.map} +1 -1
- package/dist/{wizard-abort-BmT-F0Vr.js → wizard-abort-BjLIgu2s.js} +3 -3
- package/dist/{wizard-abort-BmT-F0Vr.js.map → wizard-abort-BjLIgu2s.js.map} +1 -1
- package/dist/{wizard-abort-CYW83OG5.js → wizard-abort-BlYGA1Jk.js} +1 -1
- package/dist/{wizard-session-CsI33S4_.js → wizard-session-Bi95IYca.js} +19 -2
- package/dist/wizard-session-Bi95IYca.js.map +1 -0
- package/dist/wizard-session-DPGTaJ4W.js +2 -0
- package/dist/wizard-ui-YdGFRyu_.js.map +1 -1
- package/package.json +3 -2
- package/dist/TextBlock-DEHERFec.js.map +0 -1
- package/dist/agent-interface-cEdS_bNo.js.map +0 -1
- package/dist/agent-runner-CK5r-zQF.js.map +0 -1
- package/dist/analytics-Bw8E-yhX.js +0 -2
- package/dist/craft-pre-release.sh +0 -10
- package/dist/debug-BOogNcWX.js.map +0 -1
- package/dist/file-BKbKreWF.js +0 -16
- package/dist/file-BKbKreWF.js.map +0 -1
- package/dist/file-utils-DPmgn9Vm.js.map +0 -1
- package/dist/package-json-DZpnf6vU.js +0 -23
- package/dist/package-json-DZpnf6vU.js.map +0 -1
- package/dist/package-json-_4PEss19.js +0 -2
- package/dist/package-manager-CmMJAD-V.js.map +0 -1
- package/dist/paths-DJS47p5x.js +0 -26
- package/dist/paths-DJS47p5x.js.map +0 -1
- package/dist/posthog-BbQf_Hzq.js +0 -11
- package/dist/posthog-BbQf_Hzq.js.map +0 -1
- package/dist/provisioning-gHqu_MXL.js +0 -2
- package/dist/registry-DpROZPnl.js.map +0 -1
- package/dist/setup-utils-Mzpk1vqG.js.map +0 -1
- package/dist/setup-utils-ptemIB6g.js +0 -2
- package/dist/slides-BtDXEXdn.js.map +0 -1
- package/dist/start-playground-zZL5y9id.js.map +0 -1
- package/dist/start-tui-Cz7RZSn_.js.map +0 -1
- package/dist/task-stream-DUpUZmFQ.js +0 -61
- package/dist/task-stream-DUpUZmFQ.js.map +0 -1
- package/dist/wizard-session-CPhhll4P.js +0 -2
- package/dist/wizard-session-CsI33S4_.js.map +0 -1
|
@@ -1,11 +1,11 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { g as SERVICE_LABELS, s as logToFile } from "./debug-C4jRuzny.js";
|
|
2
2
|
import { n as isTaskStatus } from "./wizard-ui-YdGFRyu_.js";
|
|
3
|
-
import { n as analytics, r as sessionProperties } from "./analytics-
|
|
4
|
-
import {
|
|
5
|
-
import { _ as AUDIT_SEVERITY_STYLE } from "./agent-interface-
|
|
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-
|
|
7
|
-
import {
|
|
8
|
-
import { n as AVAILABLE_FEATURES, t as ALL_FEATURE_VALUES } from "./defaults-
|
|
3
|
+
import { n as analytics, r as sessionProperties } from "./analytics-DZaUgJte.js";
|
|
4
|
+
import { i as buildSession } from "./wizard-session-Bi95IYca.js";
|
|
5
|
+
import { _ as AUDIT_SEVERITY_STYLE } from "./agent-interface-pBnqJL8P.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-DJVhBkr3.js";
|
|
7
|
+
import { n as Program, r as getProgramConfig, s as getKindMeta, t as PROGRAM_REGISTRY } from "./bin.js";
|
|
8
|
+
import { n as AVAILABLE_FEATURES, t as ALL_FEATURE_VALUES } from "./defaults-GbLPuHxj.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";
|
|
@@ -144,6 +144,8 @@ var WizardStore = class {
|
|
|
144
144
|
_backupAndFixSettings = null;
|
|
145
145
|
/** Blocks OAuth flow until the port-conflict overlay is dismissed. */
|
|
146
146
|
_resolvePortConflict = null;
|
|
147
|
+
/** Resolves the OAuth flow with a manually-entered authorization code. */
|
|
148
|
+
_resolveManualAuthCode = null;
|
|
147
149
|
/** Resolves the in-flight wizard_ask request. */
|
|
148
150
|
_resolvePendingQuestion = null;
|
|
149
151
|
constructor(program = Program.PostHogIntegration) {
|
|
@@ -272,6 +274,14 @@ var WizardStore = class {
|
|
|
272
274
|
analytics.wizardCapture("auth complete", { project_id: credentials?.projectId });
|
|
273
275
|
this.emitChange();
|
|
274
276
|
}
|
|
277
|
+
setRoleAtOrganization(role) {
|
|
278
|
+
this.$session.setKey("roleAtOrganization", role);
|
|
279
|
+
this.emitChange();
|
|
280
|
+
}
|
|
281
|
+
setApiUser(user) {
|
|
282
|
+
this.$session.setKey("apiUser", user);
|
|
283
|
+
this.emitChange();
|
|
284
|
+
}
|
|
275
285
|
setFrameworkConfig(integration, config) {
|
|
276
286
|
this.$session.setKey("integration", integration);
|
|
277
287
|
this.$session.setKey("frameworkConfig", config);
|
|
@@ -294,6 +304,10 @@ var WizardStore = class {
|
|
|
294
304
|
this.$session.setKey("loginUrl", url);
|
|
295
305
|
this.emitChange();
|
|
296
306
|
}
|
|
307
|
+
setAuthorizeUrl(url) {
|
|
308
|
+
this.$session.setKey("authorizeUrl", url);
|
|
309
|
+
this.emitChange();
|
|
310
|
+
}
|
|
297
311
|
setReadinessResult(result) {
|
|
298
312
|
this.$session.setKey("readinessResult", result);
|
|
299
313
|
this.emitChange();
|
|
@@ -337,6 +351,33 @@ var WizardStore = class {
|
|
|
337
351
|
this._resolvePortConflict = null;
|
|
338
352
|
}
|
|
339
353
|
/**
|
|
354
|
+
* Return a promise that resolves when the user submits a manually-entered
|
|
355
|
+
* OAuth code via the paste modal. The OAuth flow races this against the
|
|
356
|
+
* local callback server — see `performOAuthFlow`.
|
|
357
|
+
*/
|
|
358
|
+
waitForManualAuthCode() {
|
|
359
|
+
return new Promise((resolve) => {
|
|
360
|
+
this._resolveManualAuthCode = resolve;
|
|
361
|
+
});
|
|
362
|
+
}
|
|
363
|
+
/** Open the manual OAuth code-entry overlay over the auth screen. */
|
|
364
|
+
showManualAuthCode() {
|
|
365
|
+
this.pushOverlay("manual-auth-code");
|
|
366
|
+
}
|
|
367
|
+
/** Dismiss the manual OAuth code overlay without submitting. */
|
|
368
|
+
dismissManualAuthCode() {
|
|
369
|
+
this.popOverlay();
|
|
370
|
+
}
|
|
371
|
+
/**
|
|
372
|
+
* Submit a manually-entered authorization code: dismiss the overlay and
|
|
373
|
+
* resolve the in-flight OAuth flow so it can exchange the code for a token.
|
|
374
|
+
*/
|
|
375
|
+
submitManualAuthCode(code) {
|
|
376
|
+
this.popOverlay();
|
|
377
|
+
this._resolveManualAuthCode?.(code);
|
|
378
|
+
this._resolveManualAuthCode = null;
|
|
379
|
+
}
|
|
380
|
+
/**
|
|
340
381
|
* Open the WizardAsk overlay with a set of questions and return a promise
|
|
341
382
|
* that resolves once the user submits answers (or the request is cancelled).
|
|
342
383
|
*
|
|
@@ -433,6 +474,10 @@ var WizardStore = class {
|
|
|
433
474
|
});
|
|
434
475
|
this.emitChange();
|
|
435
476
|
}
|
|
477
|
+
setMcpSuggestedPromptsDismissed() {
|
|
478
|
+
this.$session.setKey("mcpSuggestedPromptsDismissed", true);
|
|
479
|
+
this.emitChange();
|
|
480
|
+
}
|
|
436
481
|
setOutroDismissed() {
|
|
437
482
|
this.$session.setKey("outroDismissed", true);
|
|
438
483
|
this.emitChange();
|
|
@@ -855,12 +900,13 @@ function useKeyBindings(id, bindings) {
|
|
|
855
900
|
* Key bindings are declared via useKeyBindings, which auto-registers
|
|
856
901
|
* hints in the KeyboardHintsBar.
|
|
857
902
|
*/
|
|
858
|
-
const PickerMenu = ({ message, options, mode = "single", centered = false, columns = 1, onSelect }) => {
|
|
903
|
+
const PickerMenu = ({ message, options, mode = "single", centered = false, columns = 1, optionMarginBottom = 0, onSelect }) => {
|
|
859
904
|
if (mode === "multi") return /* @__PURE__ */ jsx(MultiPickerMenu, {
|
|
860
905
|
message,
|
|
861
906
|
options,
|
|
862
907
|
centered,
|
|
863
908
|
columns,
|
|
909
|
+
optionMarginBottom,
|
|
864
910
|
onSelect
|
|
865
911
|
});
|
|
866
912
|
return /* @__PURE__ */ jsx(SinglePickerMenu, {
|
|
@@ -868,11 +914,12 @@ const PickerMenu = ({ message, options, mode = "single", centered = false, colum
|
|
|
868
914
|
options,
|
|
869
915
|
centered,
|
|
870
916
|
columns,
|
|
917
|
+
optionMarginBottom,
|
|
871
918
|
onSelect
|
|
872
919
|
});
|
|
873
920
|
};
|
|
874
921
|
/** Custom single-select with triangle indicator and accent highlight. */
|
|
875
|
-
const SinglePickerMenu = ({ message, options, centered = false, columns = 1, onSelect }) => {
|
|
922
|
+
const SinglePickerMenu = ({ message, options, centered = false, columns = 1, optionMarginBottom = 0, onSelect }) => {
|
|
876
923
|
const [focused, setFocused] = useState(0);
|
|
877
924
|
const rows = Math.ceil(options.length / columns);
|
|
878
925
|
const bindings = [{
|
|
@@ -933,6 +980,7 @@ const SinglePickerMenu = ({ message, options, centered = false, columns = 1, onS
|
|
|
933
980
|
const label = opt.hint ? `${opt.label} (${opt.hint})` : opt.label;
|
|
934
981
|
return /* @__PURE__ */ jsxs(Box, {
|
|
935
982
|
gap: 1,
|
|
983
|
+
marginBottom: optionMarginBottom,
|
|
936
984
|
children: [/* @__PURE__ */ jsx(Text, {
|
|
937
985
|
color: isFocused ? Colors.accent : void 0,
|
|
938
986
|
dimColor: !isFocused,
|
|
@@ -950,7 +998,7 @@ const SinglePickerMenu = ({ message, options, centered = false, columns = 1, onS
|
|
|
950
998
|
});
|
|
951
999
|
};
|
|
952
1000
|
/** Custom multi-select with checkbox glyphs and accent highlight. */
|
|
953
|
-
const MultiPickerMenu = ({ message, options, centered = false, columns = 1, onSelect }) => {
|
|
1001
|
+
const MultiPickerMenu = ({ message, options, centered = false, columns = 1, optionMarginBottom = 0, onSelect }) => {
|
|
954
1002
|
const [focused, setFocused] = useState(0);
|
|
955
1003
|
const [selected, setSelected] = useState(/* @__PURE__ */ new Set());
|
|
956
1004
|
const rows = Math.ceil(options.length / columns);
|
|
@@ -1034,6 +1082,7 @@ const MultiPickerMenu = ({ message, options, centered = false, columns = 1, onSe
|
|
|
1034
1082
|
const checkbox = isSelected ? Icons.squareFilled : Icons.squareOpen;
|
|
1035
1083
|
return /* @__PURE__ */ jsxs(Box, {
|
|
1036
1084
|
gap: 1,
|
|
1085
|
+
marginBottom: optionMarginBottom,
|
|
1037
1086
|
children: [/* @__PURE__ */ jsx(Text, {
|
|
1038
1087
|
color: isSelected ? "white" : Colors.muted,
|
|
1039
1088
|
dimColor: !isFocused && !isSelected,
|
|
@@ -2151,7 +2200,8 @@ const BlockRenderer = ({ block, active, completed, onComplete, mode, bullet, ani
|
|
|
2151
2200
|
animationInterval: block.animationInterval ?? animationInterval,
|
|
2152
2201
|
sentenceInterval: block.sentenceInterval ?? sentenceInterval,
|
|
2153
2202
|
maxHeight,
|
|
2154
|
-
availableWidth
|
|
2203
|
+
availableWidth,
|
|
2204
|
+
dimWhenComplete: block.dimWhenComplete ?? true
|
|
2155
2205
|
});
|
|
2156
2206
|
return /* @__PURE__ */ jsx(NodeBlock, {
|
|
2157
2207
|
content: block.content,
|
|
@@ -2589,10 +2639,10 @@ const McpScreen = ({ store, installer, mode = "install" }) => {
|
|
|
2589
2639
|
return /* @__PURE__ */ jsxs(Box, {
|
|
2590
2640
|
flexDirection: "column",
|
|
2591
2641
|
flexGrow: 1,
|
|
2592
|
-
children: [/* @__PURE__ */
|
|
2642
|
+
children: [/* @__PURE__ */ jsx(Text, {
|
|
2593
2643
|
bold: true,
|
|
2594
2644
|
color: Colors.accent,
|
|
2595
|
-
children:
|
|
2645
|
+
children: isRemove ? "Remove the PostHog MCP" : "Install the MCP so you can chat to your data"
|
|
2596
2646
|
}), /* @__PURE__ */ jsxs(Box, {
|
|
2597
2647
|
marginTop: 1,
|
|
2598
2648
|
flexDirection: "column",
|
|
@@ -2609,19 +2659,38 @@ const McpScreen = ({ store, installer, mode = "install" }) => {
|
|
|
2609
2659
|
" MCP clients detected. Skipping..."
|
|
2610
2660
|
]
|
|
2611
2661
|
}),
|
|
2612
|
-
phase === "ask" && /* @__PURE__ */ jsxs(Fragment$1, { children: [
|
|
2613
|
-
|
|
2614
|
-
|
|
2615
|
-
|
|
2616
|
-
|
|
2617
|
-
|
|
2618
|
-
|
|
2619
|
-
|
|
2620
|
-
|
|
2621
|
-
|
|
2622
|
-
|
|
2662
|
+
phase === "ask" && /* @__PURE__ */ jsxs(Fragment$1, { children: [
|
|
2663
|
+
!isRemove && /* @__PURE__ */ jsx(Box, {
|
|
2664
|
+
flexDirection: "column",
|
|
2665
|
+
marginBottom: 1,
|
|
2666
|
+
children: [
|
|
2667
|
+
"Ask your agent: \"List my feature flags\" — and it does.",
|
|
2668
|
+
"Run SQL, build dashboards, ship flags, all from your IDE.",
|
|
2669
|
+
"No copy-pasting tokens or context. Your agent has the keys."
|
|
2670
|
+
].map((bullet) => /* @__PURE__ */ jsxs(Text, {
|
|
2671
|
+
dimColor: true,
|
|
2672
|
+
children: [
|
|
2673
|
+
"•",
|
|
2674
|
+
" ",
|
|
2675
|
+
bullet
|
|
2676
|
+
]
|
|
2677
|
+
}, bullet))
|
|
2678
|
+
}),
|
|
2679
|
+
/* @__PURE__ */ jsxs(Text, {
|
|
2680
|
+
dimColor: true,
|
|
2681
|
+
children: ["Detected: ", clients.map((c) => c.name).join(", ")]
|
|
2682
|
+
}),
|
|
2683
|
+
/* @__PURE__ */ jsx(Box, {
|
|
2684
|
+
marginTop: 1,
|
|
2685
|
+
children: /* @__PURE__ */ jsx(ConfirmationInput, {
|
|
2686
|
+
message: `${isRemove ? "Remove" : "Install"} the PostHog MCP server${clients.some((c) => c.supportsPlugin) ? " and plugin" : ""}?`,
|
|
2687
|
+
confirmLabel: isRemove ? "Remove" : "Install",
|
|
2688
|
+
cancelLabel: "No thanks",
|
|
2689
|
+
onConfirm: handleConfirm,
|
|
2690
|
+
onCancel: handleSkip
|
|
2691
|
+
})
|
|
2623
2692
|
})
|
|
2624
|
-
|
|
2693
|
+
] }),
|
|
2625
2694
|
phase === "pick" && /* @__PURE__ */ jsx(PickerMenu, {
|
|
2626
2695
|
message: "Select editor to install MCP server",
|
|
2627
2696
|
options: clients.map((c) => ({
|
|
@@ -2673,6 +2742,490 @@ const McpScreen = ({ store, installer, mode = "install" }) => {
|
|
|
2673
2742
|
});
|
|
2674
2743
|
};
|
|
2675
2744
|
//#endregion
|
|
2745
|
+
//#region src/lib/mcp-role-prompts.ts
|
|
2746
|
+
/**
|
|
2747
|
+
* Roles that ship from `role_at_organization` on the PostHog user object.
|
|
2748
|
+
* `security` isn't in the enum upstream — the engineering kit covers that audience.
|
|
2749
|
+
*/
|
|
2750
|
+
const TAILORED_ROLES = [
|
|
2751
|
+
"founder",
|
|
2752
|
+
"product",
|
|
2753
|
+
"leadership",
|
|
2754
|
+
"marketing",
|
|
2755
|
+
"engineering",
|
|
2756
|
+
"data"
|
|
2757
|
+
];
|
|
2758
|
+
const STOCK_MCP_SUGGESTED_PROMPTS = [
|
|
2759
|
+
{
|
|
2760
|
+
prompt: "What are my busiest 10 events and when did each last fire?",
|
|
2761
|
+
description: "Inventories your project’s event stream so you can see what’s being captured at a glance."
|
|
2762
|
+
},
|
|
2763
|
+
{
|
|
2764
|
+
prompt: "Show me daily event volume for the last 30 days.",
|
|
2765
|
+
description: "Charts your event count day by day — a quick read on volume and trend."
|
|
2766
|
+
},
|
|
2767
|
+
{
|
|
2768
|
+
prompt: "Create a dashboard with my top 10 events broken down by day for the last 7 days.",
|
|
2769
|
+
description: "Builds a saved dashboard you can pin and share — written back to your project."
|
|
2770
|
+
}
|
|
2771
|
+
];
|
|
2772
|
+
//#endregion
|
|
2773
|
+
//#region src/ui/tui/screens/McpSuggestedPromptsScreen.tsx
|
|
2774
|
+
/**
|
|
2775
|
+
* McpSuggestedPromptsScreen — shown after MCP install succeeds in the
|
|
2776
|
+
* standalone `wizard mcp add` program.
|
|
2777
|
+
*
|
|
2778
|
+
* Phases:
|
|
2779
|
+
* 1. Choose — opens with a Log in / Exit picker, framed by a
|
|
2780
|
+
* hardcoded teaser of three example prompts.
|
|
2781
|
+
* 2. Authenticating — runs `services.performLogin()` (OAuth in
|
|
2782
|
+
* production, canned values in the playground).
|
|
2783
|
+
* Renders a spinner + login URL inline while the
|
|
2784
|
+
* promise is pending. Errors return to Choose
|
|
2785
|
+
* with an inline error line.
|
|
2786
|
+
* 3. PromptPicker — lists the role-tailored kit; user picks one to
|
|
2787
|
+
* run. The picker has its own "Exit" entry so
|
|
2788
|
+
* dismissal is discoverable without a hidden
|
|
2789
|
+
* hotkey.
|
|
2790
|
+
* 4. Running — streams the agent's response inline via
|
|
2791
|
+
* `services.runPromptStreaming`. `[esc]` aborts
|
|
2792
|
+
* and returns to the picker; `[enter]` after
|
|
2793
|
+
* completion goes back to the picker so the user
|
|
2794
|
+
* can run another or exit.
|
|
2795
|
+
*
|
|
2796
|
+
* Credentials are guaranteed non-null once PromptPicker / Running are
|
|
2797
|
+
* reached (the Choose → Authenticating gate forces a successful login
|
|
2798
|
+
* before getting there). A defensive throw protects the Running
|
|
2799
|
+
* useEffect against a state-machine bug.
|
|
2800
|
+
*/
|
|
2801
|
+
const MAX_PROMPT_RUNS = 3;
|
|
2802
|
+
const McpSuggestedPromptsScreen = ({ store, services }) => {
|
|
2803
|
+
useSyncExternalStore((cb) => store.subscribe(cb), () => store.getSnapshot());
|
|
2804
|
+
const session = store.session;
|
|
2805
|
+
const kit = STOCK_MCP_SUGGESTED_PROMPTS;
|
|
2806
|
+
const [phase, setPhase] = useState("choose");
|
|
2807
|
+
const [loginError, setLoginError] = useState(null);
|
|
2808
|
+
const [runningPrompt, setRunningPrompt] = useState(null);
|
|
2809
|
+
const [runChunks, setRunChunks] = useState([]);
|
|
2810
|
+
const [runStartedAt, setRunStartedAt] = useState(null);
|
|
2811
|
+
const [runCount, setRunCount] = useState(0);
|
|
2812
|
+
const canPickAnother = runCount < MAX_PROMPT_RUNS;
|
|
2813
|
+
const runAbortRef = useRef(null);
|
|
2814
|
+
useEffect(() => {
|
|
2815
|
+
if (phase !== "authenticating") return;
|
|
2816
|
+
let cancelled = false;
|
|
2817
|
+
(async () => {
|
|
2818
|
+
try {
|
|
2819
|
+
const { credentials, roleAtOrganization, user } = await services.performLogin();
|
|
2820
|
+
if (cancelled) return;
|
|
2821
|
+
store.setCredentials(credentials);
|
|
2822
|
+
store.setRoleAtOrganization(roleAtOrganization);
|
|
2823
|
+
store.setApiUser(user);
|
|
2824
|
+
store.setLoginUrl(null);
|
|
2825
|
+
setPhase("prompt-picker");
|
|
2826
|
+
} catch (err) {
|
|
2827
|
+
if (cancelled) return;
|
|
2828
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
2829
|
+
logToFile(`[McpSuggestedPromptsScreen] login failed: ${message}`);
|
|
2830
|
+
store.setLoginUrl(null);
|
|
2831
|
+
setLoginError(message);
|
|
2832
|
+
setPhase("choose");
|
|
2833
|
+
}
|
|
2834
|
+
})();
|
|
2835
|
+
return () => {
|
|
2836
|
+
cancelled = true;
|
|
2837
|
+
};
|
|
2838
|
+
}, [
|
|
2839
|
+
phase,
|
|
2840
|
+
services,
|
|
2841
|
+
store
|
|
2842
|
+
]);
|
|
2843
|
+
useEffect(() => {
|
|
2844
|
+
if (phase !== "running") return;
|
|
2845
|
+
if (!runningPrompt) return;
|
|
2846
|
+
if (!session.credentials) throw new Error("[McpSuggestedPromptsScreen] Running phase reached without credentials. The Choose gate should have prevented this.");
|
|
2847
|
+
const controller = new AbortController();
|
|
2848
|
+
runAbortRef.current = controller;
|
|
2849
|
+
const startedAt = Date.now();
|
|
2850
|
+
setRunStartedAt(startedAt);
|
|
2851
|
+
setRunChunks([]);
|
|
2852
|
+
(async () => {
|
|
2853
|
+
const credentials = session.credentials;
|
|
2854
|
+
if (!credentials) return;
|
|
2855
|
+
try {
|
|
2856
|
+
for await (const chunk of services.runPromptStreaming({
|
|
2857
|
+
prompt: runningPrompt,
|
|
2858
|
+
credentials,
|
|
2859
|
+
signal: controller.signal
|
|
2860
|
+
})) {
|
|
2861
|
+
if (controller.signal.aborted) return;
|
|
2862
|
+
setRunChunks((prev) => [...prev, chunk]);
|
|
2863
|
+
if (chunk.kind === "done") {
|
|
2864
|
+
analytics.wizardCapture("mcp suggested prompts run", {
|
|
2865
|
+
prompt: runningPrompt,
|
|
2866
|
+
durationMs: Date.now() - startedAt
|
|
2867
|
+
});
|
|
2868
|
+
return;
|
|
2869
|
+
}
|
|
2870
|
+
if (chunk.kind === "error") {
|
|
2871
|
+
analytics.wizardCapture("mcp suggested prompts run failed", {
|
|
2872
|
+
prompt: runningPrompt,
|
|
2873
|
+
error: chunk.text
|
|
2874
|
+
});
|
|
2875
|
+
return;
|
|
2876
|
+
}
|
|
2877
|
+
}
|
|
2878
|
+
} catch (err) {
|
|
2879
|
+
if (controller.signal.aborted) return;
|
|
2880
|
+
const text = err instanceof Error ? err.message : String(err);
|
|
2881
|
+
setRunChunks((prev) => [...prev, {
|
|
2882
|
+
kind: "error",
|
|
2883
|
+
text
|
|
2884
|
+
}]);
|
|
2885
|
+
analytics.wizardCapture("mcp suggested prompts run failed", {
|
|
2886
|
+
prompt: runningPrompt,
|
|
2887
|
+
error: text
|
|
2888
|
+
});
|
|
2889
|
+
}
|
|
2890
|
+
})();
|
|
2891
|
+
return () => {
|
|
2892
|
+
controller.abort();
|
|
2893
|
+
if (runAbortRef.current === controller) runAbortRef.current = null;
|
|
2894
|
+
};
|
|
2895
|
+
}, [
|
|
2896
|
+
phase,
|
|
2897
|
+
runningPrompt,
|
|
2898
|
+
services,
|
|
2899
|
+
session.credentials
|
|
2900
|
+
]);
|
|
2901
|
+
const dismiss = () => {
|
|
2902
|
+
setPhase("done");
|
|
2903
|
+
setTimeout(() => {
|
|
2904
|
+
store.setMcpSuggestedPromptsDismissed();
|
|
2905
|
+
}, 0);
|
|
2906
|
+
};
|
|
2907
|
+
const handleChoice = (value) => {
|
|
2908
|
+
const choice = Array.isArray(value) ? value[0] : value;
|
|
2909
|
+
setLoginError(null);
|
|
2910
|
+
if (choice === "login") {
|
|
2911
|
+
analytics.wizardCapture("mcp suggested prompts choose", { choice: "login" });
|
|
2912
|
+
setPhase("authenticating");
|
|
2913
|
+
} else {
|
|
2914
|
+
analytics.wizardCapture("mcp suggested prompts choose", { choice: "exit" });
|
|
2915
|
+
dismiss();
|
|
2916
|
+
}
|
|
2917
|
+
};
|
|
2918
|
+
const handlePromptPick = (value) => {
|
|
2919
|
+
setRunningPrompt(Array.isArray(value) ? value[0] : value);
|
|
2920
|
+
setRunCount((c) => c + 1);
|
|
2921
|
+
setPhase("running");
|
|
2922
|
+
};
|
|
2923
|
+
useKeyBindings("mcp-suggested-prompts", [{
|
|
2924
|
+
match: "escape",
|
|
2925
|
+
label: "esc",
|
|
2926
|
+
action: phase === "prompt-picker" ? "exit" : "exit",
|
|
2927
|
+
handler: () => {
|
|
2928
|
+
if (phase === "running") {
|
|
2929
|
+
runAbortRef.current?.abort();
|
|
2930
|
+
dismiss();
|
|
2931
|
+
} else if (phase === "prompt-picker") dismiss();
|
|
2932
|
+
}
|
|
2933
|
+
}, {
|
|
2934
|
+
match: "p",
|
|
2935
|
+
label: "p",
|
|
2936
|
+
action: canPickAnother ? "pick new prompt" : "cap reached",
|
|
2937
|
+
handler: () => {
|
|
2938
|
+
if (phase !== "running") return;
|
|
2939
|
+
if (!canPickAnother) return;
|
|
2940
|
+
runAbortRef.current?.abort();
|
|
2941
|
+
setPhase("prompt-picker");
|
|
2942
|
+
}
|
|
2943
|
+
}]);
|
|
2944
|
+
return /* @__PURE__ */ jsx(Box, {
|
|
2945
|
+
flexDirection: "column",
|
|
2946
|
+
flexGrow: 1,
|
|
2947
|
+
children: /* @__PURE__ */ jsxs(Box, {
|
|
2948
|
+
marginTop: 1,
|
|
2949
|
+
flexDirection: "column",
|
|
2950
|
+
children: [
|
|
2951
|
+
phase === "choose" && /* @__PURE__ */ jsx(ChoosePhase, {
|
|
2952
|
+
error: loginError,
|
|
2953
|
+
onSelect: handleChoice
|
|
2954
|
+
}),
|
|
2955
|
+
phase === "authenticating" && /* @__PURE__ */ jsx(AuthenticatingPhase, { loginUrl: session.loginUrl }),
|
|
2956
|
+
phase === "prompt-picker" && /* @__PURE__ */ jsxs(Fragment$1, { children: [/* @__PURE__ */ jsx(Box, {
|
|
2957
|
+
marginBottom: 1,
|
|
2958
|
+
children: /* @__PURE__ */ jsx(Text, {
|
|
2959
|
+
bold: true,
|
|
2960
|
+
color: Colors.accent,
|
|
2961
|
+
children: "MCP tutorial"
|
|
2962
|
+
})
|
|
2963
|
+
}), /* @__PURE__ */ jsx(PromptPickerPhase, {
|
|
2964
|
+
promptKit: kit,
|
|
2965
|
+
userDisplayName: session.apiUser?.first_name || null,
|
|
2966
|
+
onSelect: handlePromptPick
|
|
2967
|
+
})] }),
|
|
2968
|
+
phase === "running" && runningPrompt && /* @__PURE__ */ jsx(RunningPhase, {
|
|
2969
|
+
prompt: runningPrompt,
|
|
2970
|
+
chunks: runChunks,
|
|
2971
|
+
startedAt: runStartedAt,
|
|
2972
|
+
canPickAnother,
|
|
2973
|
+
runCount,
|
|
2974
|
+
maxRuns: MAX_PROMPT_RUNS
|
|
2975
|
+
})
|
|
2976
|
+
]
|
|
2977
|
+
})
|
|
2978
|
+
});
|
|
2979
|
+
};
|
|
2980
|
+
const ChoosePhase = ({ error, onSelect }) => /* @__PURE__ */ jsxs(Box, {
|
|
2981
|
+
flexDirection: "column",
|
|
2982
|
+
children: [
|
|
2983
|
+
/* @__PURE__ */ jsx(Text, {
|
|
2984
|
+
bold: true,
|
|
2985
|
+
color: Colors.accent,
|
|
2986
|
+
children: "PostHog MCP"
|
|
2987
|
+
}),
|
|
2988
|
+
/* @__PURE__ */ jsx(Box, {
|
|
2989
|
+
marginTop: 1,
|
|
2990
|
+
children: /* @__PURE__ */ jsx(Text, { children: "With MCP your agent works directly with the PostHog platform. You can prompt it to:" })
|
|
2991
|
+
}),
|
|
2992
|
+
/* @__PURE__ */ jsxs(Box, {
|
|
2993
|
+
marginTop: 1,
|
|
2994
|
+
flexDirection: "column",
|
|
2995
|
+
children: [
|
|
2996
|
+
/* @__PURE__ */ jsxs(Text, { children: [/* @__PURE__ */ jsx(Text, {
|
|
2997
|
+
color: "cyan",
|
|
2998
|
+
children: Icons.diamond
|
|
2999
|
+
}), " Build dashboards"] }),
|
|
3000
|
+
/* @__PURE__ */ jsxs(Text, { children: [/* @__PURE__ */ jsx(Text, {
|
|
3001
|
+
color: "cyan",
|
|
3002
|
+
children: Icons.diamond
|
|
3003
|
+
}), " Run SQL queries"] }),
|
|
3004
|
+
/* @__PURE__ */ jsxs(Text, { children: [/* @__PURE__ */ jsx(Text, {
|
|
3005
|
+
color: "cyan",
|
|
3006
|
+
children: Icons.diamond
|
|
3007
|
+
}), " Deploy feature flags"] }),
|
|
3008
|
+
/* @__PURE__ */ jsxs(Text, { children: [/* @__PURE__ */ jsx(Text, {
|
|
3009
|
+
color: "cyan",
|
|
3010
|
+
children: Icons.diamond
|
|
3011
|
+
}), " Debug exceptions and errors"] }),
|
|
3012
|
+
/* @__PURE__ */ jsxs(Text, { children: [/* @__PURE__ */ jsx(Text, {
|
|
3013
|
+
color: "cyan",
|
|
3014
|
+
children: Icons.diamond
|
|
3015
|
+
}), " And lots more..."] })
|
|
3016
|
+
]
|
|
3017
|
+
}),
|
|
3018
|
+
/* @__PURE__ */ jsx(Box, {
|
|
3019
|
+
marginTop: 1,
|
|
3020
|
+
children: /* @__PURE__ */ jsx(Text, { children: "Want a live demo using real data from your project?" })
|
|
3021
|
+
}),
|
|
3022
|
+
/* @__PURE__ */ jsx(Box, { children: /* @__PURE__ */ jsx(PickerMenu, {
|
|
3023
|
+
options: [{
|
|
3024
|
+
label: "Start MCP tutorial",
|
|
3025
|
+
value: "login"
|
|
3026
|
+
}, {
|
|
3027
|
+
label: "Exit",
|
|
3028
|
+
value: "exit"
|
|
3029
|
+
}],
|
|
3030
|
+
onSelect
|
|
3031
|
+
}) }),
|
|
3032
|
+
error && /* @__PURE__ */ jsx(Box, {
|
|
3033
|
+
marginTop: 1,
|
|
3034
|
+
children: /* @__PURE__ */ jsxs(Text, {
|
|
3035
|
+
color: "red",
|
|
3036
|
+
children: [
|
|
3037
|
+
"Login failed: ",
|
|
3038
|
+
error,
|
|
3039
|
+
". Try again or exit."
|
|
3040
|
+
]
|
|
3041
|
+
})
|
|
3042
|
+
})
|
|
3043
|
+
]
|
|
3044
|
+
});
|
|
3045
|
+
const AuthenticatingPhase = ({ loginUrl }) => /* @__PURE__ */ jsxs(Box, {
|
|
3046
|
+
flexDirection: "column",
|
|
3047
|
+
children: [/* @__PURE__ */ jsx(LoadingBox, { message: "Waiting for authentication..." }), loginUrl && /* @__PURE__ */ jsx(Box, {
|
|
3048
|
+
marginTop: 1,
|
|
3049
|
+
marginBottom: 1,
|
|
3050
|
+
flexDirection: "column",
|
|
3051
|
+
children: /* @__PURE__ */ jsxs(Text, { children: [
|
|
3052
|
+
/* @__PURE__ */ jsx(Text, {
|
|
3053
|
+
dimColor: true,
|
|
3054
|
+
children: "If the browser didn't open, copy and paste:"
|
|
3055
|
+
}),
|
|
3056
|
+
"\n\n",
|
|
3057
|
+
/* @__PURE__ */ jsx(Text, {
|
|
3058
|
+
color: "cyan",
|
|
3059
|
+
children: loginUrl
|
|
3060
|
+
})
|
|
3061
|
+
] })
|
|
3062
|
+
})]
|
|
3063
|
+
});
|
|
3064
|
+
const PromptPickerPhase = ({ promptKit, userDisplayName, onSelect }) => {
|
|
3065
|
+
const options = promptKit.map((p) => ({
|
|
3066
|
+
label: p.prompt,
|
|
3067
|
+
value: p.prompt
|
|
3068
|
+
}));
|
|
3069
|
+
return /* @__PURE__ */ jsx(Box, {
|
|
3070
|
+
flexDirection: "column",
|
|
3071
|
+
children: /* @__PURE__ */ jsx(ContentSequencer, {
|
|
3072
|
+
blocks: [
|
|
3073
|
+
{
|
|
3074
|
+
content: `Hello there, ${userDisplayName || "there"}!`,
|
|
3075
|
+
mode: 0,
|
|
3076
|
+
animationInterval: 100,
|
|
3077
|
+
pause: 1200,
|
|
3078
|
+
dimWhenComplete: false
|
|
3079
|
+
},
|
|
3080
|
+
{
|
|
3081
|
+
content: "Pick a prompt to see the PostHog MCP in action.",
|
|
3082
|
+
mode: 0,
|
|
3083
|
+
animationInterval: 50,
|
|
3084
|
+
pause: 1e3,
|
|
3085
|
+
dimWhenComplete: false
|
|
3086
|
+
},
|
|
3087
|
+
{
|
|
3088
|
+
content: /* @__PURE__ */ jsxs(Fragment$1, { children: [/* @__PURE__ */ jsx(PickerMenu, {
|
|
3089
|
+
options,
|
|
3090
|
+
optionMarginBottom: 1,
|
|
3091
|
+
onSelect
|
|
3092
|
+
}), /* @__PURE__ */ jsx(Box, {
|
|
3093
|
+
marginTop: 2,
|
|
3094
|
+
children: /* @__PURE__ */ jsxs(Text, { children: [/* @__PURE__ */ jsx(Text, {
|
|
3095
|
+
bold: true,
|
|
3096
|
+
children: "[esc]"
|
|
3097
|
+
}), /* @__PURE__ */ jsx(Text, { children: " to exit" })] })
|
|
3098
|
+
})] }),
|
|
3099
|
+
persist: true
|
|
3100
|
+
}
|
|
3101
|
+
],
|
|
3102
|
+
mode: 0,
|
|
3103
|
+
blockInterval: 350
|
|
3104
|
+
})
|
|
3105
|
+
});
|
|
3106
|
+
};
|
|
3107
|
+
const RunningPhase = ({ prompt, chunks, startedAt, canPickAnother, runCount, maxRuns }) => {
|
|
3108
|
+
const isDone = chunks.some((c) => c.kind === "done");
|
|
3109
|
+
const errorChunk = chunks.find((c) => c.kind === "error");
|
|
3110
|
+
const finished = isDone || !!errorChunk;
|
|
3111
|
+
const elapsed = startedAt ? Math.round((Date.now() - startedAt) / 1e3) : 0;
|
|
3112
|
+
const visibleChunks = finished ? chunks.filter((c) => c.kind === "text" || c.kind === "error") : chunks;
|
|
3113
|
+
const cappedChunks = finished ? capTextChunks(visibleChunks) : visibleChunks;
|
|
3114
|
+
return /* @__PURE__ */ jsxs(Box, {
|
|
3115
|
+
flexDirection: "column",
|
|
3116
|
+
children: [
|
|
3117
|
+
/* @__PURE__ */ jsxs(Text, { children: [
|
|
3118
|
+
/* @__PURE__ */ jsx(Text, {
|
|
3119
|
+
bold: true,
|
|
3120
|
+
children: "Prompt:"
|
|
3121
|
+
}),
|
|
3122
|
+
" ",
|
|
3123
|
+
/* @__PURE__ */ jsx(Text, {
|
|
3124
|
+
color: Colors.accent,
|
|
3125
|
+
children: prompt
|
|
3126
|
+
})
|
|
3127
|
+
] }),
|
|
3128
|
+
/* @__PURE__ */ jsxs(Box, {
|
|
3129
|
+
marginTop: 1,
|
|
3130
|
+
gap: 1,
|
|
3131
|
+
children: [
|
|
3132
|
+
!finished && /* @__PURE__ */ jsx(Spinner, {}),
|
|
3133
|
+
/* @__PURE__ */ jsx(Text, {
|
|
3134
|
+
bold: finished,
|
|
3135
|
+
children: finished ? errorChunk ? `Failed after ${elapsed}s.` : `Done in ${elapsed}s.` : "Streaming from PostHog MCP"
|
|
3136
|
+
}),
|
|
3137
|
+
/* @__PURE__ */ jsxs(Text, {
|
|
3138
|
+
dimColor: true,
|
|
3139
|
+
children: [
|
|
3140
|
+
"(",
|
|
3141
|
+
runCount,
|
|
3142
|
+
"/",
|
|
3143
|
+
maxRuns,
|
|
3144
|
+
" prompts)"
|
|
3145
|
+
]
|
|
3146
|
+
})
|
|
3147
|
+
]
|
|
3148
|
+
}),
|
|
3149
|
+
/* @__PURE__ */ jsx(Box, {
|
|
3150
|
+
marginTop: 1,
|
|
3151
|
+
flexDirection: "column",
|
|
3152
|
+
children: cappedChunks.map((chunk, idx) => /* @__PURE__ */ jsx(ChunkLine, { chunk }, idx))
|
|
3153
|
+
}),
|
|
3154
|
+
finished && !canPickAnother && /* @__PURE__ */ jsx(Box, {
|
|
3155
|
+
marginTop: 1,
|
|
3156
|
+
children: /* @__PURE__ */ jsxs(Text, { children: [
|
|
3157
|
+
/* @__PURE__ */ jsxs(Text, {
|
|
3158
|
+
dimColor: true,
|
|
3159
|
+
children: [
|
|
3160
|
+
"You've hit the ",
|
|
3161
|
+
maxRuns,
|
|
3162
|
+
"-prompt tutorial cap. Press",
|
|
3163
|
+
" "
|
|
3164
|
+
]
|
|
3165
|
+
}),
|
|
3166
|
+
/* @__PURE__ */ jsx(Text, {
|
|
3167
|
+
bold: true,
|
|
3168
|
+
dimColor: true,
|
|
3169
|
+
children: "[esc]"
|
|
3170
|
+
}),
|
|
3171
|
+
/* @__PURE__ */ jsx(Text, {
|
|
3172
|
+
dimColor: true,
|
|
3173
|
+
children: " to exit."
|
|
3174
|
+
})
|
|
3175
|
+
] })
|
|
3176
|
+
})
|
|
3177
|
+
]
|
|
3178
|
+
});
|
|
3179
|
+
};
|
|
3180
|
+
/**
|
|
3181
|
+
* Belt-and-suspenders fallback for runs where Claude ignored the
|
|
3182
|
+
* terminal-fit system prompt and produced an overlong response. Joins
|
|
3183
|
+
* all text chunks, slices to the last N lines that fit in the current
|
|
3184
|
+
* terminal, and prepends an indicator showing how many lines got cut.
|
|
3185
|
+
* Errors are preserved separately so failures don't disappear into the
|
|
3186
|
+
* truncation.
|
|
3187
|
+
*/
|
|
3188
|
+
function capTextChunks(chunks) {
|
|
3189
|
+
const rows = process.stdout.rows ?? 24;
|
|
3190
|
+
const maxMessageRows = Math.max(6, rows - 8);
|
|
3191
|
+
const textChunks = chunks.filter((c) => c.kind === "text");
|
|
3192
|
+
const errors = chunks.filter((c) => c.kind === "error");
|
|
3193
|
+
if (textChunks.length === 0) return chunks;
|
|
3194
|
+
const lines = textChunks.map((c) => c.text).join("").split("\n");
|
|
3195
|
+
if (lines.length <= maxMessageRows) return chunks;
|
|
3196
|
+
const hidden = lines.length - maxMessageRows;
|
|
3197
|
+
const tail = lines.slice(-maxMessageRows).join("\n");
|
|
3198
|
+
return [{
|
|
3199
|
+
kind: "text",
|
|
3200
|
+
text: `[${hidden} line${hidden === 1 ? "" : "s"} above — expand terminal to see more]\n\n${tail}`
|
|
3201
|
+
}, ...errors];
|
|
3202
|
+
}
|
|
3203
|
+
const ChunkLine = ({ chunk }) => {
|
|
3204
|
+
if (chunk.kind === "text") return /* @__PURE__ */ jsx(Text, { children: chunk.text });
|
|
3205
|
+
if (chunk.kind === "tool-call") return /* @__PURE__ */ jsxs(Text, { children: [
|
|
3206
|
+
" ",
|
|
3207
|
+
/* @__PURE__ */ jsxs(Text, {
|
|
3208
|
+
color: "cyan",
|
|
3209
|
+
children: ["↳ ", chunk.toolName]
|
|
3210
|
+
}),
|
|
3211
|
+
chunk.detail ? ` ${chunk.detail}` : ""
|
|
3212
|
+
] });
|
|
3213
|
+
if (chunk.kind === "tool-result") return /* @__PURE__ */ jsxs(Text, { children: [
|
|
3214
|
+
" ",
|
|
3215
|
+
/* @__PURE__ */ jsx(Text, {
|
|
3216
|
+
color: "green",
|
|
3217
|
+
children: "✓"
|
|
3218
|
+
}),
|
|
3219
|
+
" ",
|
|
3220
|
+
chunk.detail
|
|
3221
|
+
] });
|
|
3222
|
+
if (chunk.kind === "error") return /* @__PURE__ */ jsxs(Text, {
|
|
3223
|
+
color: "red",
|
|
3224
|
+
children: ["Error: ", chunk.text]
|
|
3225
|
+
});
|
|
3226
|
+
return null;
|
|
3227
|
+
};
|
|
3228
|
+
//#endregion
|
|
2676
3229
|
//#region src/ui/tui/screens/audit/AuditChecksViewer/AreaHeaderRow.tsx
|
|
2677
3230
|
/** Sub-header row inside the scrollable body — one per area group. */
|
|
2678
3231
|
const AreaHeaderRow = ({ area, resolved, total }) => /* @__PURE__ */ jsxs(Box, {
|
|
@@ -3461,6 +4014,6 @@ const AUDIT_3000_AREA_SLIDES = [
|
|
|
3461
4014
|
}
|
|
3462
4015
|
];
|
|
3463
4016
|
//#endregion
|
|
3464
|
-
export {
|
|
4017
|
+
export { PickerMenu as C, SplitView as D, LoadingBox as E, CardLayout as O, useStdoutDimensions as S, ProgressList as T, EventPlanViewer as _, TAILORED_ROLES as a, ConfirmationInput as b, SEVERITY_LABEL as c, TipsCard as d, LearnCard as f, ScreenContainer as g, TabContainer as h, McpSuggestedPromptsScreen as i, WizardStore as k, SEVERITY_ORDER as l, HNViewer as m, AUDIT_AREA_SLIDES as n, McpScreen as o, ContentSequencer as p, AuditChecksViewer as r, IssueTable as s, AUDIT_3000_AREA_SLIDES as t, ServiceHealthList as u, LogViewer as v, useKeyBindings as w, GroupedPickerMenu as x, ModalOverlay as y };
|
|
3465
4018
|
|
|
3466
|
-
//# sourceMappingURL=slides-
|
|
4019
|
+
//# sourceMappingURL=slides-Dpj4j0w_.js.map
|