@posthog/wizard 2.21.0 → 2.22.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 +14 -1
- package/dist/{OutroScreen-CqF6SdBo.js → AiOptInRequiredScreen-N6L80szR.js} +443 -59
- package/dist/AiOptInRequiredScreen-N6L80szR.js.map +1 -0
- package/dist/{add-mcp-server-to-clients-DQHGhzt6.js → add-mcp-server-to-clients-DqHCkHqM.js} +12 -10
- package/dist/add-mcp-server-to-clients-DqHCkHqM.js.map +1 -0
- package/dist/{agent-interface-DE7txTqh.js → agent-interface-DZmVoik2.js} +5 -5
- package/dist/{agent-interface-DE7txTqh.js.map → agent-interface-DZmVoik2.js.map} +1 -1
- package/dist/{agent-runner-DUZ5OD6e.js → agent-runner-CGFUXR97.js} +13 -9
- package/dist/{agent-runner-DUZ5OD6e.js.map → agent-runner-CGFUXR97.js.map} +1 -1
- package/dist/{analytics-Bl5DPj_0.js → analytics-C_lVPZQT.js} +28 -4
- package/dist/analytics-C_lVPZQT.js.map +1 -0
- package/dist/{api-DuA0_88V.js → api-QI1lO_Bz.js} +3 -3
- package/dist/{api-DuA0_88V.js.map → api-QI1lO_Bz.js.map} +1 -1
- package/dist/bin.js +160 -49
- package/dist/bin.js.map +1 -1
- package/dist/{ci-install-BnOYI4mZ.js → ci-install-CXkKR4A-.js} +4 -4
- package/dist/{ci-install-BnOYI4mZ.js.map → ci-install-CXkKR4A-.js.map} +1 -1
- package/dist/{debug-h7Z9zEbD.js → debug-D8QAez2V.js} +58 -13
- package/dist/debug-D8QAez2V.js.map +1 -0
- package/dist/{debug-BVC48wlb.js → debug-lPpecs0J.js} +1 -1
- package/dist/{environment-uaLmtlH_.js → environment-CMmzgZkN.js} +3 -3
- package/dist/{environment-uaLmtlH_.js.map → environment-CMmzgZkN.js.map} +1 -1
- package/dist/{interactive-CW5gjyDd.js → interactive-Bu8YchJG.js} +2 -2
- package/dist/{interactive-CW5gjyDd.js.map → interactive-Bu8YchJG.js.map} +1 -1
- package/dist/{mcp-prompt-streaming-DMDwaark.js → mcp-prompt-streaming-mYw2LPZZ.js} +4 -4
- package/dist/{mcp-prompt-streaming-DMDwaark.js.map → mcp-prompt-streaming-mYw2LPZZ.js.map} +1 -1
- package/dist/{non-interactive-DJrVQ4nS.js → non-interactive-De3tJM1y.js} +2 -2
- package/dist/{non-interactive-DJrVQ4nS.js.map → non-interactive-De3tJM1y.js.map} +1 -1
- package/dist/{package-manager-DCUBRbr-.js → package-manager-BVJnbp1u.js} +2 -2
- package/dist/{package-manager-DCUBRbr-.js.map → package-manager-BVJnbp1u.js.map} +1 -1
- package/dist/{playground-DCVaVeVD.js → playground-wyoq1yIH.js} +82 -4
- package/dist/playground-wyoq1yIH.js.map +1 -0
- package/dist/{posthog-integration-ChdwFPMj.js → posthog-integration-mrMF-2IP.js} +48 -16
- package/dist/posthog-integration-mrMF-2IP.js.map +1 -0
- package/dist/{provisioning-GeMkBMSR.js → provisioning-4zipVpbq.js} +3 -3
- package/dist/{provisioning-GeMkBMSR.js.map → provisioning-4zipVpbq.js.map} +1 -1
- package/dist/{registry-VSSRH3sU.js → registry-BGUo4PlM.js} +7 -20
- package/dist/registry-BGUo4PlM.js.map +1 -0
- package/dist/{setup-utils-BfV4pydt.js → setup-utils-DmhPyWkp.js} +114 -58
- package/dist/setup-utils-DmhPyWkp.js.map +1 -0
- package/dist/{start-tui-BRvm5VP9.js → start-tui-DaQiY_EB.js} +310 -130
- package/dist/start-tui-DaQiY_EB.js.map +1 -0
- package/dist/{steps-DA4uvSbg.js → steps-CrUceWR5.js} +6 -6
- package/dist/{steps-DA4uvSbg.js.map → steps-CrUceWR5.js.map} +1 -1
- package/dist/telemetry-CCVjGq7l.js +68 -0
- package/dist/telemetry-CCVjGq7l.js.map +1 -0
- package/dist/{urls-B66Ib2jT.js → urls-BNFpfcN8.js} +2 -2
- package/dist/{urls-B66Ib2jT.js.map → urls-BNFpfcN8.js.map} +1 -1
- package/dist/{wizard-abort-D1_DnFjm.js → wizard-abort-BmYb0bG2.js} +3 -3
- package/dist/{wizard-abort-D1_DnFjm.js.map → wizard-abort-BmYb0bG2.js.map} +1 -1
- package/dist/{wizard-abort-gMB1eV6T.js → wizard-abort-Bp2yxYAy.js} +1 -1
- package/dist/wizard-session-G3VWD6hv.js.map +1 -1
- package/dist/wizard-ui-YdGFRyu_.js.map +1 -1
- package/package.json +1 -1
- package/dist/OutroScreen-CqF6SdBo.js.map +0 -1
- package/dist/add-mcp-server-to-clients-DQHGhzt6.js.map +0 -1
- package/dist/analytics-Bl5DPj_0.js.map +0 -1
- package/dist/debug-h7Z9zEbD.js.map +0 -1
- package/dist/playground-DCVaVeVD.js.map +0 -1
- package/dist/posthog-integration-ChdwFPMj.js.map +0 -1
- package/dist/registry-VSSRH3sU.js.map +0 -1
- package/dist/setup-utils-BfV4pydt.js.map +0 -1
- package/dist/start-tui-BRvm5VP9.js.map +0 -1
- package/dist/telemetry-BRAonUea.js +0 -13
- package/dist/telemetry-BRAonUea.js.map +0 -1
|
@@ -1,14 +1,16 @@
|
|
|
1
|
-
import { g as SERVICE_LABELS, s as logToFile } from "./debug-
|
|
1
|
+
import { M as POSTHOG_APP_URL, Q as getSkillsBaseUrl, g as SERVICE_LABELS, s as logToFile } from "./debug-D8QAez2V.js";
|
|
2
2
|
import { n as isTaskStatus } from "./wizard-ui-YdGFRyu_.js";
|
|
3
|
-
import { r as sessionProperties, t as analytics } from "./analytics-
|
|
4
|
-
import { i as
|
|
3
|
+
import { r as sessionProperties, t as analytics } from "./analytics-C_lVPZQT.js";
|
|
4
|
+
import { i as withUtm, n as openTrackedLink } from "./telemetry-CCVjGq7l.js";
|
|
5
|
+
import { n as getCloudUrlFromRegion } from "./urls-BNFpfcN8.js";
|
|
6
|
+
import { a as fetchUserData, i as fetchSlackConnected } from "./api-QI1lO_Bz.js";
|
|
5
7
|
import { i as buildSession } from "./wizard-session-G3VWD6hv.js";
|
|
6
|
-
import { y as AUDIT_SEVERITY_STYLE } from "./agent-interface-
|
|
7
|
-
import { c as computeVisibleRange, d as isObjectBlock, f as Colors, l as isClearBlock, p as Icons, s as TextBlock, u as isLinesBlock } from "./posthog-integration-
|
|
8
|
+
import { m as fetchSkillMenu, y as AUDIT_SEVERITY_STYLE } from "./agent-interface-DZmVoik2.js";
|
|
9
|
+
import { c as computeVisibleRange, d as isObjectBlock, f as Colors, l as isClearBlock, p as Icons, s as TextBlock, u as isLinesBlock } from "./posthog-integration-mrMF-2IP.js";
|
|
8
10
|
import { a as getProgramConfig, i as Program, l as getKindMeta, r as PROGRAM_REGISTRY } from "./bin.js";
|
|
9
11
|
import { n as AVAILABLE_FEATURES, o as isAllFeaturesSelected, t as ALL_FEATURE_VALUES } from "./defaults-BNWIWzjc.js";
|
|
10
|
-
import * as fs$1 from "fs";
|
|
11
12
|
import opn from "opn";
|
|
13
|
+
import * as fs$1 from "fs";
|
|
12
14
|
import { Box, Text, measureElement, useInput, useStdout } from "ink";
|
|
13
15
|
import { Component, Fragment, createContext, useCallback, useContext, useEffect, useMemo, useRef, useState, useSyncExternalStore } from "react";
|
|
14
16
|
import { Fragment as Fragment$1, jsx, jsxs } from "react/jsx-runtime";
|
|
@@ -41,9 +43,40 @@ function createProgramSequence(steps) {
|
|
|
41
43
|
return entries;
|
|
42
44
|
}
|
|
43
45
|
//#endregion
|
|
46
|
+
//#region src/lib/programs/ai-opt-in-gate.ts
|
|
47
|
+
/** Step id — also the ScreenId.AiOptIn enum value in screen-sequences. */
|
|
48
|
+
const AI_OPT_IN_STEP_ID = "ai-opt-in";
|
|
49
|
+
function aiApproved(session) {
|
|
50
|
+
return !!session.apiUser?.organization?.is_ai_data_processing_approved;
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* Returns the program's steps with the AI opt-in gate injected after
|
|
54
|
+
* `auth`. Programs with `requiresAi: false` or no auth step pass
|
|
55
|
+
* through unchanged — without auth, `apiUser` would never be populated
|
|
56
|
+
* for evaluation anyway.
|
|
57
|
+
*/
|
|
58
|
+
function withAiOptInGate(config) {
|
|
59
|
+
if (config.requiresAi === false) return config.steps;
|
|
60
|
+
const authIdx = config.steps.findIndex((s) => s.id === "auth");
|
|
61
|
+
if (authIdx === -1) return config.steps;
|
|
62
|
+
const gateStep = {
|
|
63
|
+
id: AI_OPT_IN_STEP_ID,
|
|
64
|
+
label: "AI opt-in check",
|
|
65
|
+
screenId: AI_OPT_IN_STEP_ID,
|
|
66
|
+
show: (session) => !session.ci && session.apiUser != null && !aiApproved(session),
|
|
67
|
+
isComplete: (session) => session.ci || aiApproved(session),
|
|
68
|
+
gate: (session) => session.ci || aiApproved(session)
|
|
69
|
+
};
|
|
70
|
+
return [
|
|
71
|
+
...config.steps.slice(0, authIdx + 1),
|
|
72
|
+
gateStep,
|
|
73
|
+
...config.steps.slice(authIdx + 1)
|
|
74
|
+
];
|
|
75
|
+
}
|
|
76
|
+
//#endregion
|
|
44
77
|
//#region src/ui/tui/screen-sequences.ts
|
|
45
78
|
/** All program screen sequences keyed by program id. */
|
|
46
|
-
const PROGRAM_SEQUENCES = Object.fromEntries(PROGRAM_REGISTRY.map((c) => [c.id, createProgramSequence(c
|
|
79
|
+
const PROGRAM_SEQUENCES = Object.fromEntries(PROGRAM_REGISTRY.map((c) => [c.id, createProgramSequence(withAiOptInGate(c))]));
|
|
47
80
|
//#endregion
|
|
48
81
|
//#region src/ui/tui/router.ts
|
|
49
82
|
var WizardRouter = class {
|
|
@@ -162,9 +195,15 @@ var WizardStore = class {
|
|
|
162
195
|
}
|
|
163
196
|
/**
|
|
164
197
|
* Scan program steps for gate predicates and create gate promises.
|
|
198
|
+
*
|
|
199
|
+
* Steps are wrapped with withAiOptInGate so the injected ai-opt-in
|
|
200
|
+
* step's gate registers here — the agent runner awaits it (via
|
|
201
|
+
* WizardUI.waitForAiOptIn) before any source leaves the machine.
|
|
202
|
+
* Same wrapper screen-sequences.ts uses, so the gate and its screen
|
|
203
|
+
* can't drift apart.
|
|
165
204
|
*/
|
|
166
205
|
_initFromProgram(program) {
|
|
167
|
-
const steps = getProgramConfig(program)
|
|
206
|
+
const steps = withAiOptInGate(getProgramConfig(program));
|
|
168
207
|
for (const step of steps) if (step.gate) {
|
|
169
208
|
let resolve;
|
|
170
209
|
const promise = new Promise((r) => {
|
|
@@ -210,6 +249,7 @@ var WizardStore = class {
|
|
|
210
249
|
setFrameworkContext: (k, v) => this.setFrameworkContext(k, v),
|
|
211
250
|
setFrameworkConfig: (i, c) => this.setFrameworkConfig(i, c),
|
|
212
251
|
setDetectedFramework: (l) => this.setDetectedFramework(l),
|
|
252
|
+
setSkillId: (id) => this.setSkillId(id),
|
|
213
253
|
setUnsupportedVersion: (info) => this.setUnsupportedVersion(info),
|
|
214
254
|
addDiscoveredFeature: (f) => this.addDiscoveredFeature(f),
|
|
215
255
|
setDetectionComplete: () => this.setDetectionComplete()
|
|
@@ -312,6 +352,10 @@ var WizardStore = class {
|
|
|
312
352
|
this.$session.setKey("detectedFrameworkLabel", label);
|
|
313
353
|
this.emitChange();
|
|
314
354
|
}
|
|
355
|
+
setSkillId(skillId) {
|
|
356
|
+
this.$session.setKey("skillId", skillId);
|
|
357
|
+
this.emitChange();
|
|
358
|
+
}
|
|
315
359
|
setUnsupportedVersion(info) {
|
|
316
360
|
this.$session.setKey("unsupportedVersion", info);
|
|
317
361
|
this.emitChange();
|
|
@@ -456,6 +500,10 @@ var WizardStore = class {
|
|
|
456
500
|
this.$session.setKey("authErrorDetail", detail ?? null);
|
|
457
501
|
this.pushOverlay("auth-error");
|
|
458
502
|
}
|
|
503
|
+
/** Push the session-timeout overlay (no dismiss — user must exit). */
|
|
504
|
+
showSessionTimeout() {
|
|
505
|
+
this.pushOverlay("session-timeout");
|
|
506
|
+
}
|
|
459
507
|
addDiscoveredFeature(feature) {
|
|
460
508
|
if (!this.session.discoveredFeatures.includes(feature)) {
|
|
461
509
|
this.session.discoveredFeatures.push(feature);
|
|
@@ -584,6 +632,7 @@ var WizardStore = class {
|
|
|
584
632
|
_detectTransition() {
|
|
585
633
|
const next = this.router.resolve(this.session);
|
|
586
634
|
const prev = this._lastScreen;
|
|
635
|
+
if (next !== prev) analytics.setTag("$screen_name", next);
|
|
587
636
|
if (prev !== null && next !== prev) {
|
|
588
637
|
const hooks = this._enterScreenHooks.get(next);
|
|
589
638
|
if (hooks) for (const fn of hooks) fn();
|
|
@@ -2388,7 +2437,7 @@ const TIPS = [
|
|
|
2388
2437
|
id: "slack",
|
|
2389
2438
|
title: "Use PostHog in Slack",
|
|
2390
2439
|
description: "Connect the PostHog Slack app to analyze data and ship product changes — deploy flags, open PRs, run queries — just by tagging @PostHog:",
|
|
2391
|
-
url: "https://posthog.com/slack
|
|
2440
|
+
url: "https://posthog.com/slack"
|
|
2392
2441
|
},
|
|
2393
2442
|
{
|
|
2394
2443
|
id: "stripe",
|
|
@@ -3810,10 +3859,10 @@ var neutralCrossSell = [{
|
|
|
3810
3859
|
"description": "Built-in error tracking — no separate tool."
|
|
3811
3860
|
}];
|
|
3812
3861
|
var slackApp = {
|
|
3813
|
-
"learnMoreUrl": "https://posthog.com/slack
|
|
3862
|
+
"learnMoreUrl": "https://posthog.com/slack",
|
|
3814
3863
|
"setupUrl": "https://app.posthog.com/settings/project-integrations#integration-slack",
|
|
3815
|
-
"headline": "
|
|
3816
|
-
"pitch": "
|
|
3864
|
+
"headline": "@PostHog in Slack",
|
|
3865
|
+
"pitch": "Ask about your product data, debug issues, and generate PRs without leaving the thread.",
|
|
3817
3866
|
"capabilities": ["Tag @PostHog with a bug, edit, or a feature idea. It will spin up a sandboxed environment, plan, edit files, run tests, and open a draft PR.", "Tag @PostHog with any data question. It's the same SQL-writing, statistically-minded assistant as PostHog AI, but it responds where you send work memes."]
|
|
3818
3867
|
};
|
|
3819
3868
|
//#endregion
|
|
@@ -4018,25 +4067,6 @@ function getSlackAppCard() {
|
|
|
4018
4067
|
* forces a successful login first). A defensive throw protects the
|
|
4019
4068
|
* Running useEffect against a state-machine bug.
|
|
4020
4069
|
*/
|
|
4021
|
-
var Phase = /* @__PURE__ */ function(Phase) {
|
|
4022
|
-
Phase["Choose"] = "choose";
|
|
4023
|
-
Phase["Authenticating"] = "authenticating";
|
|
4024
|
-
Phase["Greeting"] = "greeting";
|
|
4025
|
-
Phase["PromptPicker"] = "prompt-picker";
|
|
4026
|
-
Phase["Running"] = "running";
|
|
4027
|
-
Phase["FollowUp"] = "follow-up";
|
|
4028
|
-
/** Final beat on every dismissal — reminds the user how to keep
|
|
4029
|
-
* talking to PostHog after the tutorial ends. */
|
|
4030
|
-
Phase["Goodbye"] = "goodbye";
|
|
4031
|
-
Phase["Done"] = "done";
|
|
4032
|
-
return Phase;
|
|
4033
|
-
}(Phase || {});
|
|
4034
|
-
var ChoiceValue$1 = /* @__PURE__ */ function(ChoiceValue) {
|
|
4035
|
-
ChoiceValue["Login"] = "login";
|
|
4036
|
-
ChoiceValue["ConnectSlack"] = "connect-slack";
|
|
4037
|
-
ChoiceValue["Exit"] = "exit";
|
|
4038
|
-
return ChoiceValue;
|
|
4039
|
-
}(ChoiceValue$1 || {});
|
|
4040
4070
|
const MAX_PROMPT_RUNS = 5;
|
|
4041
4071
|
const FOLLOW_UP_DELAY_MS = 3e3;
|
|
4042
4072
|
const McpSuggestedPromptsScreen = ({ store, services }) => {
|
|
@@ -4198,7 +4228,7 @@ const McpSuggestedPromptsScreen = ({ store, services }) => {
|
|
|
4198
4228
|
setPhase(session.credentials ? "greeting" : "authenticating");
|
|
4199
4229
|
} else if (choice === "connect-slack") {
|
|
4200
4230
|
analytics.wizardCapture("mcp suggested prompts choose", { choice: "connect-slack" });
|
|
4201
|
-
|
|
4231
|
+
openTrackedLink(getSlackAppCard().setupUrl, "mcp-prompts-slack-setup");
|
|
4202
4232
|
} else {
|
|
4203
4233
|
analytics.wizardCapture("mcp suggested prompts choose", { choice: "exit" });
|
|
4204
4234
|
enterGoodbye();
|
|
@@ -5646,8 +5676,9 @@ const AUDIT_3000_AREA_SLIDES = [
|
|
|
5646
5676
|
//#region src/ui/tui/screens/SlackConnectScreen.tsx
|
|
5647
5677
|
/**
|
|
5648
5678
|
* SlackConnectScreen — the dedicated "Connect Slack" step shown after the
|
|
5649
|
-
* MCP tutorial (`wizard mcp tutorial`)
|
|
5650
|
-
* (`wizard mcp add`)
|
|
5679
|
+
* MCP tutorial (`wizard mcp tutorial`), after a successful install
|
|
5680
|
+
* (`wizard mcp add`), at the end of the integration flow, and as the whole
|
|
5681
|
+
* program in the standalone `wizard slack` flow.
|
|
5651
5682
|
*
|
|
5652
5683
|
* Presents the PostHog Slack app plus role-tailored use-cases. The copy
|
|
5653
5684
|
* adapts to whether Slack is already connected (polled while the screen
|
|
@@ -5660,22 +5691,36 @@ const AUDIT_3000_AREA_SLIDES = [
|
|
|
5660
5691
|
* who already have it aren't nagged.
|
|
5661
5692
|
* "Skip" / "Done" / esc dismiss the step (`slackStepDismissed`) and let
|
|
5662
5693
|
* the router advance to exit.
|
|
5694
|
+
*
|
|
5695
|
+
* The mcp and integration flows arrive here already authenticated. In the
|
|
5696
|
+
* standalone `wizard slack` flow the program's `onInit` runs the OAuth
|
|
5697
|
+
* while this screen renders the auth-wait state.
|
|
5663
5698
|
*/
|
|
5664
|
-
var ChoiceValue = /* @__PURE__ */ function(ChoiceValue) {
|
|
5665
|
-
ChoiceValue["Open"] = "open";
|
|
5666
|
-
ChoiceValue["Skip"] = "skip";
|
|
5667
|
-
return ChoiceValue;
|
|
5668
|
-
}(ChoiceValue || {});
|
|
5669
5699
|
const POLL_INTERVAL_MS = 3e3;
|
|
5670
5700
|
const SlackConnectScreen = ({ store }) => {
|
|
5671
5701
|
useSyncExternalStore((cb) => store.subscribe(cb), () => store.getSnapshot());
|
|
5672
5702
|
const role = store.session.roleAtOrganization;
|
|
5673
5703
|
const slack = getSlackAppCard();
|
|
5674
|
-
|
|
5675
|
-
|
|
5676
|
-
}, []);
|
|
5677
|
-
const connected = store.session.slackConnected === true;
|
|
5704
|
+
const setupUrl = withUtm(slack.setupUrl, "slack-connect-setup");
|
|
5705
|
+
const learnMoreUrl = withUtm(slack.learnMoreUrl, "slack-connect-learn-more");
|
|
5678
5706
|
const credentials = store.session.credentials;
|
|
5707
|
+
const awaitingLogin = store.router.activeProgram === Program.SlackConnect && !credentials;
|
|
5708
|
+
const connectedState = store.session.slackConnected;
|
|
5709
|
+
const connected = connectedState === true;
|
|
5710
|
+
const known = connectedState !== null || !credentials && !awaitingLogin;
|
|
5711
|
+
const impressionFired = useRef(false);
|
|
5712
|
+
useEffect(() => {
|
|
5713
|
+
if (!known || impressionFired.current) return;
|
|
5714
|
+
impressionFired.current = true;
|
|
5715
|
+
analytics.wizardCapture("slack connect shown", {
|
|
5716
|
+
role,
|
|
5717
|
+
already_connected: connected
|
|
5718
|
+
});
|
|
5719
|
+
}, [
|
|
5720
|
+
known,
|
|
5721
|
+
connected,
|
|
5722
|
+
role
|
|
5723
|
+
]);
|
|
5679
5724
|
useEffect(() => {
|
|
5680
5725
|
if (!credentials || connected) return;
|
|
5681
5726
|
let cancelled = false;
|
|
@@ -5684,10 +5729,16 @@ const SlackConnectScreen = ({ store }) => {
|
|
|
5684
5729
|
const check = () => {
|
|
5685
5730
|
fetchSlackConnected(credentials.accessToken, credentials.projectId, credentials.host, controller.signal).then((isConnected) => {
|
|
5686
5731
|
if (cancelled) return;
|
|
5687
|
-
if (isConnected)
|
|
5688
|
-
|
|
5732
|
+
if (isConnected) {
|
|
5733
|
+
if (store.session.slackConnected === false) analytics.wizardCapture("slack connect completed", { role });
|
|
5734
|
+
store.setSlackConnected(true);
|
|
5735
|
+
} else {
|
|
5736
|
+
if (store.session.slackConnected === null) store.setSlackConnected(false);
|
|
5737
|
+
timer = setTimeout(check, POLL_INTERVAL_MS);
|
|
5738
|
+
}
|
|
5689
5739
|
}).catch((err) => {
|
|
5690
5740
|
if (cancelled) return;
|
|
5741
|
+
if (store.session.slackConnected === null) store.setSlackConnected(false);
|
|
5691
5742
|
analytics.captureException(err instanceof Error ? err : new Error(String(err)), { step: "slack_connected_check" });
|
|
5692
5743
|
});
|
|
5693
5744
|
};
|
|
@@ -5703,7 +5754,7 @@ const SlackConnectScreen = ({ store }) => {
|
|
|
5703
5754
|
store
|
|
5704
5755
|
]);
|
|
5705
5756
|
const dismiss = () => {
|
|
5706
|
-
analytics.wizardCapture("slack connect skipped", {
|
|
5757
|
+
analytics.wizardCapture(connected ? "slack connect done" : "slack connect skipped", {
|
|
5707
5758
|
role,
|
|
5708
5759
|
connected
|
|
5709
5760
|
});
|
|
@@ -5712,7 +5763,7 @@ const SlackConnectScreen = ({ store }) => {
|
|
|
5712
5763
|
const handleSelect = (value) => {
|
|
5713
5764
|
if ((Array.isArray(value) ? value[0] : value) === "open") {
|
|
5714
5765
|
analytics.wizardCapture("slack connect opened", { role });
|
|
5715
|
-
|
|
5766
|
+
openTrackedLink(setupUrl, "slack-connect-setup");
|
|
5716
5767
|
return;
|
|
5717
5768
|
}
|
|
5718
5769
|
dismiss();
|
|
@@ -5723,6 +5774,32 @@ const SlackConnectScreen = ({ store }) => {
|
|
|
5723
5774
|
action: connected ? "done" : "skip",
|
|
5724
5775
|
handler: () => dismiss()
|
|
5725
5776
|
}]);
|
|
5777
|
+
if (awaitingLogin) return /* @__PURE__ */ jsxs(Box, {
|
|
5778
|
+
flexDirection: "column",
|
|
5779
|
+
flexGrow: 1,
|
|
5780
|
+
marginTop: 1,
|
|
5781
|
+
children: [/* @__PURE__ */ jsx(LoadingBox, { message: "Waiting for authentication..." }), store.session.loginUrl && /* @__PURE__ */ jsx(Box, {
|
|
5782
|
+
marginTop: 1,
|
|
5783
|
+
flexDirection: "column",
|
|
5784
|
+
children: /* @__PURE__ */ jsxs(Text, { children: [
|
|
5785
|
+
/* @__PURE__ */ jsx(Text, {
|
|
5786
|
+
dimColor: true,
|
|
5787
|
+
children: "If the browser didn't open, copy and paste:"
|
|
5788
|
+
}),
|
|
5789
|
+
"\n\n",
|
|
5790
|
+
/* @__PURE__ */ jsx(Text, {
|
|
5791
|
+
color: "cyan",
|
|
5792
|
+
children: store.session.loginUrl
|
|
5793
|
+
})
|
|
5794
|
+
] })
|
|
5795
|
+
})]
|
|
5796
|
+
});
|
|
5797
|
+
if (credentials && connectedState === null) return /* @__PURE__ */ jsx(Box, {
|
|
5798
|
+
flexDirection: "column",
|
|
5799
|
+
flexGrow: 1,
|
|
5800
|
+
marginTop: 1,
|
|
5801
|
+
children: /* @__PURE__ */ jsx(LoadingBox, { message: "Checking for an existing Slack connection..." })
|
|
5802
|
+
});
|
|
5726
5803
|
return /* @__PURE__ */ jsx(Box, {
|
|
5727
5804
|
flexDirection: "column",
|
|
5728
5805
|
flexGrow: 1,
|
|
@@ -5761,13 +5838,13 @@ const SlackConnectScreen = ({ store }) => {
|
|
|
5761
5838
|
dimColor: true,
|
|
5762
5839
|
children: ["Connect it: ", /* @__PURE__ */ jsx(Text, {
|
|
5763
5840
|
color: "cyan",
|
|
5764
|
-
children:
|
|
5841
|
+
children: setupUrl
|
|
5765
5842
|
})]
|
|
5766
5843
|
}), /* @__PURE__ */ jsxs(Text, {
|
|
5767
5844
|
dimColor: true,
|
|
5768
5845
|
children: ["Learn more: ", /* @__PURE__ */ jsx(Text, {
|
|
5769
5846
|
color: "cyan",
|
|
5770
|
-
children:
|
|
5847
|
+
children: learnMoreUrl
|
|
5771
5848
|
})]
|
|
5772
5849
|
})]
|
|
5773
5850
|
}),
|
|
@@ -5781,7 +5858,7 @@ const SlackConnectScreen = ({ store }) => {
|
|
|
5781
5858
|
label: "Open Slack setup",
|
|
5782
5859
|
value: "open"
|
|
5783
5860
|
}, {
|
|
5784
|
-
label: "Skip",
|
|
5861
|
+
label: "Skip / Continue",
|
|
5785
5862
|
value: "skip"
|
|
5786
5863
|
}],
|
|
5787
5864
|
onSelect: handleSelect
|
|
@@ -5879,7 +5956,7 @@ const OutroScreen = ({ store }) => {
|
|
|
5879
5956
|
" ",
|
|
5880
5957
|
/* @__PURE__ */ jsx(Text, {
|
|
5881
5958
|
color: "cyan",
|
|
5882
|
-
children: outroData.dashboardUrl
|
|
5959
|
+
children: withUtm(outroData.dashboardUrl, "outro-dashboard")
|
|
5883
5960
|
})
|
|
5884
5961
|
] })
|
|
5885
5962
|
}),
|
|
@@ -5890,23 +5967,27 @@ const OutroScreen = ({ store }) => {
|
|
|
5890
5967
|
" ",
|
|
5891
5968
|
/* @__PURE__ */ jsx(Text, {
|
|
5892
5969
|
color: "cyan",
|
|
5893
|
-
children: outroData.notebookUrl
|
|
5970
|
+
children: withUtm(outroData.notebookUrl, "outro-notebook")
|
|
5894
5971
|
})
|
|
5895
5972
|
] })
|
|
5896
5973
|
}),
|
|
5897
5974
|
outroData.docsUrl && /* @__PURE__ */ jsx(Box, {
|
|
5898
5975
|
marginTop: 1,
|
|
5899
|
-
children: /* @__PURE__ */ jsxs(Text, { children: [
|
|
5900
|
-
|
|
5901
|
-
|
|
5902
|
-
|
|
5976
|
+
children: /* @__PURE__ */ jsxs(Text, { children: [
|
|
5977
|
+
"Learn more:",
|
|
5978
|
+
" ",
|
|
5979
|
+
/* @__PURE__ */ jsx(Text, {
|
|
5980
|
+
color: "cyan",
|
|
5981
|
+
children: withUtm(outroData.docsUrl, "outro-docs")
|
|
5982
|
+
})
|
|
5983
|
+
] })
|
|
5903
5984
|
}),
|
|
5904
5985
|
outroData.continueUrl && /* @__PURE__ */ jsx(Box, { children: /* @__PURE__ */ jsxs(Text, { children: [
|
|
5905
5986
|
"Continue onboarding:",
|
|
5906
5987
|
" ",
|
|
5907
5988
|
/* @__PURE__ */ jsx(Text, {
|
|
5908
5989
|
color: "cyan",
|
|
5909
|
-
children: outroData.continueUrl
|
|
5990
|
+
children: withUtm(outroData.continueUrl, "outro-continue")
|
|
5910
5991
|
})
|
|
5911
5992
|
] }) }),
|
|
5912
5993
|
/* @__PURE__ */ jsx(Box, {
|
|
@@ -5964,6 +6045,309 @@ const OutroScreen = ({ store }) => {
|
|
|
5964
6045
|
});
|
|
5965
6046
|
};
|
|
5966
6047
|
//#endregion
|
|
5967
|
-
|
|
6048
|
+
//#region src/ui/tui/screens/SkillSourceInfo.tsx
|
|
6049
|
+
/**
|
|
6050
|
+
* Shared "Skill: <id> / URL: <downloadUrl>" block for intro screens.
|
|
6051
|
+
*
|
|
6052
|
+
* `useSkillEntry` fetches the entry from the skill menu and re-runs when
|
|
6053
|
+
* `skillId` or `local` change. The previous fetch is cancelled (its result
|
|
6054
|
+
* is ignored) so a session that flips `local=false → true` mid-mount picks
|
|
6055
|
+
* up the right base URL.
|
|
6056
|
+
*
|
|
6057
|
+
* `<SkillSourceInfo>` renders the block, taking the entry as a prop so the
|
|
6058
|
+
* caller can reuse the same hook result for additional UI (e.g. showing
|
|
6059
|
+
* `skillEntry.name`) without invoking the hook twice.
|
|
6060
|
+
*/
|
|
6061
|
+
/**
|
|
6062
|
+
* Resolve a session skillId against the skill-menu entries.
|
|
6063
|
+
*
|
|
6064
|
+
* `session.skillId` is seeded with the raw integration id during
|
|
6065
|
+
* detection (e.g. 'python'), but the menu publishes integration skills
|
|
6066
|
+
* under prefixed ids ('integration-python'); frameworks with variants
|
|
6067
|
+
* publish several ('integration-nextjs-app-router', '-pages-router').
|
|
6068
|
+
* Match chain: exact id → `integration-<id>` → unique
|
|
6069
|
+
* `integration-<id>-*` prefix. Ambiguous variants (≥2 prefix matches)
|
|
6070
|
+
* return null — the caller should point at the skills repo instead of
|
|
6071
|
+
* guessing the wrong variant.
|
|
6072
|
+
*/
|
|
6073
|
+
function resolveSkillEntry(entries, skillId) {
|
|
6074
|
+
const exact = entries.find((s) => s.id === skillId);
|
|
6075
|
+
if (exact) return exact;
|
|
6076
|
+
const prefixed = entries.find((s) => s.id === `integration-${skillId}`);
|
|
6077
|
+
if (prefixed) return prefixed;
|
|
6078
|
+
const variants = entries.filter((s) => s.id.startsWith(`integration-${skillId}-`));
|
|
6079
|
+
return variants.length === 1 ? variants[0] : null;
|
|
6080
|
+
}
|
|
6081
|
+
function useSkillEntry(skillId, local) {
|
|
6082
|
+
const [skillEntry, setSkillEntry] = useState(null);
|
|
6083
|
+
const [fetchFailed, setFetchFailed] = useState(false);
|
|
6084
|
+
useEffect(() => {
|
|
6085
|
+
if (!skillId) {
|
|
6086
|
+
setFetchFailed(true);
|
|
6087
|
+
return;
|
|
6088
|
+
}
|
|
6089
|
+
let cancelled = false;
|
|
6090
|
+
setSkillEntry(null);
|
|
6091
|
+
setFetchFailed(false);
|
|
6092
|
+
fetchSkillMenu(getSkillsBaseUrl(local)).then((menu) => {
|
|
6093
|
+
if (cancelled) return;
|
|
6094
|
+
if (!menu) {
|
|
6095
|
+
setFetchFailed(true);
|
|
6096
|
+
return;
|
|
6097
|
+
}
|
|
6098
|
+
const match = resolveSkillEntry(Object.values(menu.categories).flat(), skillId);
|
|
6099
|
+
if (match) setSkillEntry(match);
|
|
6100
|
+
else setFetchFailed(true);
|
|
6101
|
+
});
|
|
6102
|
+
return () => {
|
|
6103
|
+
cancelled = true;
|
|
6104
|
+
};
|
|
6105
|
+
}, [skillId, local]);
|
|
6106
|
+
return {
|
|
6107
|
+
skillEntry,
|
|
6108
|
+
fetchFailed
|
|
6109
|
+
};
|
|
6110
|
+
}
|
|
6111
|
+
const SkillSourceInfo = ({ skillId, skillEntry, fetchFailed }) => /* @__PURE__ */ jsxs(Box, {
|
|
6112
|
+
flexDirection: "column",
|
|
6113
|
+
children: [/* @__PURE__ */ jsxs(Text, { children: [
|
|
6114
|
+
"Skill:",
|
|
6115
|
+
" ",
|
|
6116
|
+
/* @__PURE__ */ jsx(Text, {
|
|
6117
|
+
italic: true,
|
|
6118
|
+
color: "cyan",
|
|
6119
|
+
children: skillId ?? "unknown"
|
|
6120
|
+
})
|
|
6121
|
+
] }), /* @__PURE__ */ jsxs(Text, { children: [
|
|
6122
|
+
"URL:",
|
|
6123
|
+
" ",
|
|
6124
|
+
/* @__PURE__ */ jsx(Text, {
|
|
6125
|
+
color: "cyan",
|
|
6126
|
+
children: skillEntry?.downloadUrl ?? (fetchFailed ? "https://github.com/PostHog/context-mill/releases/latest" : "Loading...")
|
|
6127
|
+
})
|
|
6128
|
+
] })]
|
|
6129
|
+
});
|
|
6130
|
+
//#endregion
|
|
6131
|
+
//#region src/ui/tui/screens/AiOptInRequiredScreen.tsx
|
|
6132
|
+
/**
|
|
6133
|
+
* AiOptInRequiredScreen — Renders when the wizard authenticates against an
|
|
6134
|
+
* org whose `is_ai_data_processing_approved` is not `true`. Mirrors Max's
|
|
6135
|
+
* strict reading: `null`, `undefined`, and `false` all block.
|
|
6136
|
+
*
|
|
6137
|
+
* Two variants selected from `apiUser.organization.membership_level`:
|
|
6138
|
+
* - Admin (>= 8): can fix it themselves — [O] opens settings in browser.
|
|
6139
|
+
* - Non-admin: needs to escalate — settings URL is displayed prominently
|
|
6140
|
+
* to copy and share with the admin.
|
|
6141
|
+
*
|
|
6142
|
+
* Both variants offer [S] (show skill source for BYOAI), [R] (retry —
|
|
6143
|
+
* re-fetches user data and re-evaluates the gate without restarting), and
|
|
6144
|
+
* [E] (exit).
|
|
6145
|
+
*/
|
|
6146
|
+
const ORG_ADMIN_LEVEL = 8;
|
|
6147
|
+
const SETTINGS_PATH = "settings/organization-details";
|
|
6148
|
+
const SETTINGS_ANCHOR = "#organization-ai-consent";
|
|
6149
|
+
const AiOptInRequiredScreen = ({ store }) => {
|
|
6150
|
+
useSyncExternalStore((cb) => store.subscribe(cb), () => store.getSnapshot());
|
|
6151
|
+
const { session } = store;
|
|
6152
|
+
const isAdmin = ((session.apiUser?.organization)?.membership_level ?? 0) >= ORG_ADMIN_LEVEL;
|
|
6153
|
+
const variant = isAdmin ? "admin" : "non-admin";
|
|
6154
|
+
const region = session.region ?? "us";
|
|
6155
|
+
const projectId = session.credentials?.projectId;
|
|
6156
|
+
const settingsUrl = projectId != null ? `${POSTHOG_APP_URL}/project/${projectId}/${SETTINGS_PATH}${SETTINGS_ANCHOR}` : `${POSTHOG_APP_URL}/${SETTINGS_PATH}${SETTINGS_ANCHOR}`;
|
|
6157
|
+
const [showSkill, setShowSkill] = useState(false);
|
|
6158
|
+
const [retrying, setRetrying] = useState(false);
|
|
6159
|
+
const [retryError, setRetryError] = useState(null);
|
|
6160
|
+
const { skillEntry } = useSkillEntry(session.skillId, session.localMcp);
|
|
6161
|
+
useEffect(() => {
|
|
6162
|
+
analytics.wizardCapture("ai opt-in shown", { variant });
|
|
6163
|
+
}, [variant]);
|
|
6164
|
+
const handleOpenSettings = () => {
|
|
6165
|
+
analytics.wizardCapture("ai opt-in action", {
|
|
6166
|
+
variant,
|
|
6167
|
+
action: "open_settings"
|
|
6168
|
+
});
|
|
6169
|
+
opn(settingsUrl, { wait: false }).catch(() => {});
|
|
6170
|
+
};
|
|
6171
|
+
const handleShowSkill = () => {
|
|
6172
|
+
analytics.wizardCapture("ai opt-in action", {
|
|
6173
|
+
variant,
|
|
6174
|
+
action: "show_skill"
|
|
6175
|
+
});
|
|
6176
|
+
setShowSkill(true);
|
|
6177
|
+
};
|
|
6178
|
+
const handleRetry = () => {
|
|
6179
|
+
analytics.wizardCapture("ai opt-in action", {
|
|
6180
|
+
variant,
|
|
6181
|
+
action: "retry"
|
|
6182
|
+
});
|
|
6183
|
+
const accessToken = session.credentials?.accessToken;
|
|
6184
|
+
if (!accessToken) {
|
|
6185
|
+
setRetryError("Missing credentials — cannot retry.");
|
|
6186
|
+
return;
|
|
6187
|
+
}
|
|
6188
|
+
setRetrying(true);
|
|
6189
|
+
setRetryError(null);
|
|
6190
|
+
fetchUserData(accessToken, getCloudUrlFromRegion(region)).then((user) => {
|
|
6191
|
+
store.setApiUser(user);
|
|
6192
|
+
}).catch((err) => {
|
|
6193
|
+
setRetryError(err instanceof Error ? err.message : "Retry failed.");
|
|
6194
|
+
}).finally(() => {
|
|
6195
|
+
setRetrying(false);
|
|
6196
|
+
});
|
|
6197
|
+
};
|
|
6198
|
+
const handleExit = () => {
|
|
6199
|
+
analytics.wizardCapture("ai opt-in action", {
|
|
6200
|
+
variant,
|
|
6201
|
+
action: "exit"
|
|
6202
|
+
});
|
|
6203
|
+
process.exit(0);
|
|
6204
|
+
};
|
|
6205
|
+
useKeyBindings("ai-opt-in", [
|
|
6206
|
+
...isAdmin ? [{
|
|
6207
|
+
match: ["o", "O"],
|
|
6208
|
+
label: "O",
|
|
6209
|
+
action: "open settings",
|
|
6210
|
+
handler: handleOpenSettings
|
|
6211
|
+
}] : [],
|
|
6212
|
+
{
|
|
6213
|
+
match: ["s", "S"],
|
|
6214
|
+
label: "S",
|
|
6215
|
+
action: "show skill",
|
|
6216
|
+
handler: handleShowSkill
|
|
6217
|
+
},
|
|
6218
|
+
{
|
|
6219
|
+
match: ["r", "R"],
|
|
6220
|
+
label: "R",
|
|
6221
|
+
action: "retry",
|
|
6222
|
+
handler: handleRetry
|
|
6223
|
+
},
|
|
6224
|
+
{
|
|
6225
|
+
match: ["e", "E"],
|
|
6226
|
+
label: "E",
|
|
6227
|
+
action: "exit",
|
|
6228
|
+
handler: handleExit
|
|
6229
|
+
}
|
|
6230
|
+
]);
|
|
6231
|
+
return /* @__PURE__ */ jsxs(Box, {
|
|
6232
|
+
flexDirection: "column",
|
|
6233
|
+
flexGrow: 1,
|
|
6234
|
+
children: [
|
|
6235
|
+
/* @__PURE__ */ jsxs(Box, {
|
|
6236
|
+
flexDirection: "column",
|
|
6237
|
+
marginBottom: 1,
|
|
6238
|
+
children: [/* @__PURE__ */ jsx(Text, {
|
|
6239
|
+
bold: true,
|
|
6240
|
+
color: Colors.accent,
|
|
6241
|
+
children: "PostHog Setup Wizard"
|
|
6242
|
+
}), session.apiUser?.email && /* @__PURE__ */ jsxs(Text, { children: [/* @__PURE__ */ jsxs(Text, {
|
|
6243
|
+
color: "green",
|
|
6244
|
+
children: ["✔", " "]
|
|
6245
|
+
}), /* @__PURE__ */ jsxs(Text, { children: ["Authenticated as ", session.apiUser.email] })] })]
|
|
6246
|
+
}),
|
|
6247
|
+
/* @__PURE__ */ jsx(Box, {
|
|
6248
|
+
flexDirection: "column",
|
|
6249
|
+
marginBottom: 1,
|
|
6250
|
+
children: /* @__PURE__ */ jsx(Text, {
|
|
6251
|
+
color: "yellow",
|
|
6252
|
+
bold: true,
|
|
6253
|
+
children: "⚠ PostHog AI services are disabled for your organization"
|
|
6254
|
+
})
|
|
6255
|
+
}),
|
|
6256
|
+
/* @__PURE__ */ jsx(Box, {
|
|
6257
|
+
flexDirection: "column",
|
|
6258
|
+
marginBottom: 1,
|
|
6259
|
+
width: 68,
|
|
6260
|
+
children: isAdmin ? /* @__PURE__ */ jsxs(Text, { children: [
|
|
6261
|
+
"The wizard uses Anthropic Claude. To proceed, enable",
|
|
6262
|
+
" ",
|
|
6263
|
+
/* @__PURE__ */ jsx(Text, {
|
|
6264
|
+
italic: true,
|
|
6265
|
+
children: "\"Enable PostHog features that use third-party AI services\""
|
|
6266
|
+
}),
|
|
6267
|
+
" ",
|
|
6268
|
+
"in your organization settings."
|
|
6269
|
+
] }) : /* @__PURE__ */ jsxs(Fragment$1, { children: [/* @__PURE__ */ jsxs(Text, { children: [
|
|
6270
|
+
"The wizard uses Anthropic Claude. Your organization admin needs to enable",
|
|
6271
|
+
" ",
|
|
6272
|
+
/* @__PURE__ */ jsx(Text, {
|
|
6273
|
+
italic: true,
|
|
6274
|
+
children: "\"Enable PostHog features that use third-party AI services\""
|
|
6275
|
+
}),
|
|
6276
|
+
" ",
|
|
6277
|
+
"in organization settings."
|
|
6278
|
+
] }), /* @__PURE__ */ jsx(Box, {
|
|
6279
|
+
marginTop: 1,
|
|
6280
|
+
children: /* @__PURE__ */ jsx(Text, {
|
|
6281
|
+
dimColor: true,
|
|
6282
|
+
children: "Share this link with your admin:"
|
|
6283
|
+
})
|
|
6284
|
+
})] })
|
|
6285
|
+
}),
|
|
6286
|
+
/* @__PURE__ */ jsx(Box, {
|
|
6287
|
+
marginBottom: 1,
|
|
6288
|
+
children: /* @__PURE__ */ jsx(Text, {
|
|
6289
|
+
color: "cyan",
|
|
6290
|
+
children: settingsUrl
|
|
6291
|
+
})
|
|
6292
|
+
}),
|
|
6293
|
+
showSkill && /* @__PURE__ */ jsxs(Box, {
|
|
6294
|
+
marginBottom: 1,
|
|
6295
|
+
flexDirection: "column",
|
|
6296
|
+
children: [/* @__PURE__ */ jsxs(Text, { children: [
|
|
6297
|
+
"Prefer your own AI? Download",
|
|
6298
|
+
" ",
|
|
6299
|
+
skillEntry ? /* @__PURE__ */ jsxs(Fragment$1, { children: [
|
|
6300
|
+
"the ",
|
|
6301
|
+
/* @__PURE__ */ jsx(Text, {
|
|
6302
|
+
bold: true,
|
|
6303
|
+
children: skillEntry.id
|
|
6304
|
+
}),
|
|
6305
|
+
" skill"
|
|
6306
|
+
] }) : "the skill for your framework",
|
|
6307
|
+
" ",
|
|
6308
|
+
"and run it in your own agent:"
|
|
6309
|
+
] }), /* @__PURE__ */ jsx(Text, {
|
|
6310
|
+
color: "cyan",
|
|
6311
|
+
children: "https://github.com/PostHog/context-mill/releases/latest"
|
|
6312
|
+
})]
|
|
6313
|
+
}),
|
|
6314
|
+
retrying && /* @__PURE__ */ jsx(Box, {
|
|
6315
|
+
marginBottom: 1,
|
|
6316
|
+
children: /* @__PURE__ */ jsx(LoadingBox, { message: "Re-checking organization settings..." })
|
|
6317
|
+
}),
|
|
6318
|
+
retryError && /* @__PURE__ */ jsx(Box, {
|
|
6319
|
+
marginBottom: 1,
|
|
6320
|
+
children: /* @__PURE__ */ jsx(Text, {
|
|
6321
|
+
color: "red",
|
|
6322
|
+
children: retryError
|
|
6323
|
+
})
|
|
6324
|
+
}),
|
|
6325
|
+
/* @__PURE__ */ jsxs(Box, {
|
|
6326
|
+
flexDirection: "column",
|
|
6327
|
+
marginTop: 1,
|
|
6328
|
+
children: [
|
|
6329
|
+
isAdmin && /* @__PURE__ */ jsxs(Text, { children: [/* @__PURE__ */ jsx(Text, {
|
|
6330
|
+
color: Colors.accent,
|
|
6331
|
+
children: "[O]"
|
|
6332
|
+
}), " Open settings in browser"] }),
|
|
6333
|
+
/* @__PURE__ */ jsxs(Text, { children: [/* @__PURE__ */ jsx(Text, {
|
|
6334
|
+
color: Colors.accent,
|
|
6335
|
+
children: "[S]"
|
|
6336
|
+
}), " Show how to use your own AI"] }),
|
|
6337
|
+
/* @__PURE__ */ jsxs(Text, { children: [/* @__PURE__ */ jsx(Text, {
|
|
6338
|
+
color: Colors.accent,
|
|
6339
|
+
children: "[R]"
|
|
6340
|
+
}), " Retry (after the toggle is enabled)"] }),
|
|
6341
|
+
/* @__PURE__ */ jsxs(Text, { children: [/* @__PURE__ */ jsx(Text, {
|
|
6342
|
+
color: Colors.accent,
|
|
6343
|
+
children: "[E]"
|
|
6344
|
+
}), " Exit"] })
|
|
6345
|
+
]
|
|
6346
|
+
})
|
|
6347
|
+
]
|
|
6348
|
+
});
|
|
6349
|
+
};
|
|
6350
|
+
//#endregion
|
|
6351
|
+
export { useKeyBindings as A, EventPlanViewer as C, GroupedPickerMenu as D, ConfirmationInput as E, WizardStore as F, LoadingBox as M, SplitView as N, useStdoutDimensions as O, CardLayout as P, ScreenContainer as S, ModalOverlay as T, TipsCard as _, SlackConnectScreen as a, HNViewer as b, VisualBox as c, TAILORED_ROLES as d, McpScreen as f, ServiceHealthList as g, SEVERITY_ORDER as h, OutroScreen as i, ProgressList as j, PickerMenu as k, AuditChecksViewer as l, SEVERITY_LABEL as m, SkillSourceInfo as n, AUDIT_3000_AREA_SLIDES as o, IssueTable as p, useSkillEntry as r, AUDIT_AREA_SLIDES as s, AiOptInRequiredScreen as t, McpSuggestedPromptsScreen as u, LearnCard as v, LogViewer as w, TabContainer as x, ContentSequencer as y };
|
|
5968
6352
|
|
|
5969
|
-
//# sourceMappingURL=
|
|
6353
|
+
//# sourceMappingURL=AiOptInRequiredScreen-N6L80szR.js.map
|