@posthog/wizard 2.42.0 → 2.44.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.
Files changed (91) hide show
  1. package/dist/{add-mcp-server-to-clients-fGAJ6wRG.js → add-mcp-server-to-clients-D5qsqCkj.js} +5 -5
  2. package/dist/{add-mcp-server-to-clients-fGAJ6wRG.js.map → add-mcp-server-to-clients-D5qsqCkj.js.map} +1 -1
  3. package/dist/{agent-interface-dPcuJv8g.js → agent-interface-BvTxWiol.js} +8 -8
  4. package/dist/agent-interface-BvTxWiol.js.map +1 -0
  5. package/dist/{agent-runner-3bDJ_WLl.js → agent-runner-BF6_f8Qh.js} +40 -18
  6. package/dist/agent-runner-BF6_f8Qh.js.map +1 -0
  7. package/dist/analytics-C7Xx6csw.js +2 -0
  8. package/dist/{analytics-jQRtyqzG.js → analytics-DSlQuwOT.js} +2 -2
  9. package/dist/{analytics-jQRtyqzG.js.map → analytics-DSlQuwOT.js.map} +1 -1
  10. package/dist/{api-Bweisj9K.js → api-BXduJZrw.js} +3 -3
  11. package/dist/{api-Bweisj9K.js.map → api-BXduJZrw.js.map} +1 -1
  12. package/dist/bin.js +78 -63
  13. package/dist/bin.js.map +1 -1
  14. package/dist/{ci-install-BoATzVVs.js → ci-install-GirEJqu2.js} +4 -4
  15. package/dist/{ci-install-BoATzVVs.js.map → ci-install-GirEJqu2.js.map} +1 -1
  16. package/dist/{debug-DCQHRXu9.js → debug-BOFxiVVs.js} +1 -1
  17. package/dist/{debug--QPXcpzv.js → debug-DXfQFmcM.js} +30 -20
  18. package/dist/debug-DXfQFmcM.js.map +1 -0
  19. package/dist/{defaults-CeNThA-1.js → defaults-BWLIffh5.js} +2 -2
  20. package/dist/defaults-BWLIffh5.js.map +1 -0
  21. package/dist/{environment-Xdauxvph.js → environment-F1yw21dG.js} +3 -3
  22. package/dist/{environment-Xdauxvph.js.map → environment-F1yw21dG.js.map} +1 -1
  23. package/dist/{file-utils-BJhGBl-W.js → file-utils-D-7YfJ7A.js} +2 -2
  24. package/dist/{file-utils-BJhGBl-W.js.map → file-utils-D-7YfJ7A.js.map} +1 -1
  25. package/dist/{headless-ui-XdCxxQ0b.js → headless-ui-Dni0gPND.js} +2 -2
  26. package/dist/{headless-ui-XdCxxQ0b.js.map → headless-ui-Dni0gPND.js.map} +1 -1
  27. package/dist/{interactive-CwtUeGJT.js → interactive-Bmi82rsO.js} +2 -2
  28. package/dist/{interactive-CwtUeGJT.js.map → interactive-Bmi82rsO.js.map} +1 -1
  29. package/dist/{mcp-prompt-streaming-CCS2EkfY.js → mcp-prompt-streaming-AtntLsJ8.js} +3 -3
  30. package/dist/{mcp-prompt-streaming-CCS2EkfY.js.map → mcp-prompt-streaming-AtntLsJ8.js.map} +1 -1
  31. package/dist/{mcp-DIuzSJ8f.js → mcp-xKRDnrcq.js} +2 -2
  32. package/dist/{mcp-DIuzSJ8f.js.map → mcp-xKRDnrcq.js.map} +1 -1
  33. package/dist/{non-interactive-Cjb5uLLn.js → non-interactive-BIHqcW8g.js} +2 -2
  34. package/dist/{non-interactive-Cjb5uLLn.js.map → non-interactive-BIHqcW8g.js.map} +1 -1
  35. package/dist/{package-manager-D_05Bmr0.js → package-manager-C6R_zpML.js} +2 -2
  36. package/dist/{package-manager-D_05Bmr0.js.map → package-manager-C6R_zpML.js.map} +1 -1
  37. package/dist/{playground-BtB7RvUT.js → playground-DwL36I2u.js} +7 -7
  38. package/dist/{playground-BtB7RvUT.js.map → playground-DwL36I2u.js.map} +1 -1
  39. package/dist/{posthog-integration-Cw1QDMFi.js → posthog-integration-BhLKCFsI.js} +16 -15
  40. package/dist/{posthog-integration-Cw1QDMFi.js.map → posthog-integration-BhLKCFsI.js.map} +1 -1
  41. package/dist/{provisioning-CmpiiTaR.js → provisioning-jVZm2E-A.js} +21 -14
  42. package/dist/provisioning-jVZm2E-A.js.map +1 -0
  43. package/dist/{registry-DPriFJQI.js → registry-DcoBCMQR.js} +4 -4
  44. package/dist/{registry-DPriFJQI.js.map → registry-DcoBCMQR.js.map} +1 -1
  45. package/dist/{security-DJrWWO0M.js → security-jxjVsOpd.js} +4 -4
  46. package/dist/{security-DJrWWO0M.js.map → security-jxjVsOpd.js.map} +1 -1
  47. package/dist/{setup-utils-C8yipMUt.js → setup-utils-BQCl28D8.js} +7 -7
  48. package/dist/{setup-utils-C8yipMUt.js.map → setup-utils-BQCl28D8.js.map} +1 -1
  49. package/dist/{start-tui-BMZL7mKh.js → start-tui-DgSKFMVh.js} +431 -172
  50. package/dist/start-tui-DgSKFMVh.js.map +1 -0
  51. package/dist/{steps-Dhq5VReA.js → steps-erepgD0V.js} +7 -7
  52. package/dist/{steps-Dhq5VReA.js.map → steps-erepgD0V.js.map} +1 -1
  53. package/dist/{store-Bu1xO0_5.js → store-C79GoHCQ.js} +30 -8
  54. package/dist/store-C79GoHCQ.js.map +1 -0
  55. package/dist/{subagent-mVY-kDU0.js → subagent-aDlD_Ltz.js} +2 -2
  56. package/dist/{subagent-mVY-kDU0.js.map → subagent-aDlD_Ltz.js.map} +1 -1
  57. package/dist/{task-stream-Ne-9ZOnf.js → task-stream-0Pk0tPBN.js} +2 -2
  58. package/dist/{task-stream-Ne-9ZOnf.js.map → task-stream-0Pk0tPBN.js.map} +1 -1
  59. package/dist/{tasks-2af2kDE3.js → tasks-ZkrluXCa.js} +2 -2
  60. package/dist/{tasks-2af2kDE3.js.map → tasks-ZkrluXCa.js.map} +1 -1
  61. package/dist/{telemetry-wGk3UsDw.js → telemetry-DZShaH-y.js} +3 -3
  62. package/dist/{telemetry-wGk3UsDw.js.map → telemetry-DZShaH-y.js.map} +1 -1
  63. package/dist/{terminal-CnYduoIp.js → terminal-CEhufbJ4.js} +13 -13
  64. package/dist/terminal-CEhufbJ4.js.map +1 -0
  65. package/dist/{tools-BTq5sLH9.js → tools-BIPMan6l.js} +4 -4
  66. package/dist/{tools-BTq5sLH9.js.map → tools-BIPMan6l.js.map} +1 -1
  67. package/dist/{wizard-abort-CSMnla3D.js → wizard-abort-C14PzXZ8.js} +4 -4
  68. package/dist/{wizard-abort-CSMnla3D.js.map → wizard-abort-C14PzXZ8.js.map} +1 -1
  69. package/dist/{wizard-abort-D8Lj609C.js → wizard-abort-UCm4Pd5m.js} +1 -1
  70. package/dist/{wizard-session-BudcixsA.js → wizard-session-BAZql11N.js} +3 -3
  71. package/dist/wizard-session-BAZql11N.js.map +1 -0
  72. package/dist/{wizard-session-DXivb7kv.js → wizard-session-C5lZPPEc.js} +1 -1
  73. package/dist/{wizard-tools-BBLQk1YC.js → wizard-tools-B7SLjCic.js} +5 -3
  74. package/dist/wizard-tools-B7SLjCic.js.map +1 -0
  75. package/dist/wizard-ui-WZ48rUgr.js.map +1 -1
  76. package/dist/{yara-hooks-Ciy8d0ok.js → yara-hooks-CPH8N4yz.js} +3 -3
  77. package/dist/{yara-hooks-Ciy8d0ok.js.map → yara-hooks-CPH8N4yz.js.map} +1 -1
  78. package/dist/yara-hooks-VZlj4Lib.js +2 -0
  79. package/package.json +1 -1
  80. package/dist/agent-interface-dPcuJv8g.js.map +0 -1
  81. package/dist/agent-runner-3bDJ_WLl.js.map +0 -1
  82. package/dist/analytics-B33Hy7zS.js +0 -2
  83. package/dist/debug--QPXcpzv.js.map +0 -1
  84. package/dist/defaults-CeNThA-1.js.map +0 -1
  85. package/dist/provisioning-CmpiiTaR.js.map +0 -1
  86. package/dist/start-tui-BMZL7mKh.js.map +0 -1
  87. package/dist/store-Bu1xO0_5.js.map +0 -1
  88. package/dist/terminal-CnYduoIp.js.map +0 -1
  89. package/dist/wizard-session-BudcixsA.js.map +0 -1
  90. package/dist/wizard-tools-BBLQk1YC.js.map +0 -1
  91. package/dist/yara-hooks-B42cYxIF.js +0 -2
@@ -1,20 +1,20 @@
1
- import { F as OAUTH_TIMEOUT_MS, H as POSTHOG_PRIVACY_URL, J as REMOTE_SKILLS_BASE_URL, K as POSTHOG_TERMS_URL, N as Integration, P as OAUTH_PORTS, V as POSTHOG_ORG_AI_SETTINGS_URL, at as WIZARD_TOOLS_MENU_FLAG_KEY, d as relativeToInstallDir, g as SIGNUP_WIZARD_READINESS_CONFIG, l as WIZARD_LOG_FILE, p as setUI, s as logToFile, v as getBlockingServiceKeys, z as POSTHOG_DOCS_URL } from "./debug--QPXcpzv.js";
2
- import { n as analytics } from "./analytics-jQRtyqzG.js";
3
- import { o as extractOAuthCode, t as getOrAskForProjectData } from "./setup-utils-C8yipMUt.js";
4
- import { t as ApiError } from "./api-Bweisj9K.js";
5
- import { t as ADDITIONAL_FEATURE_LABELS } from "./wizard-session-BudcixsA.js";
6
- import { i as wizardAbort } from "./wizard-abort-CSMnla3D.js";
7
- import { a as formatTokenCount, i as formatCostUsd } from "./agent-runner-3bDJ_WLl.js";
8
- import { i as fetchSkillMenu, r as downloadSkill } from "./wizard-tools-BBLQk1YC.js";
1
+ import { $ as REMOTE_SKILLS_BASE_URL, K as POSTHOG_ORG_AI_SETTINGS_URL, L as Integration, R as OAUTH_PORTS, U as POSTHOG_DOCS_URL, Z as POSTHOG_TERMS_URL, d as relativeToInstallDir, g as SIGNUP_WIZARD_READINESS_CONFIG, l as WIZARD_LOG_FILE, p as setUI, q as POSTHOG_PRIVACY_URL, s as logToFile, ut as WIZARD_TOOLS_MENU_FLAG_KEY, v as getBlockingServiceKeys, z as OAUTH_TIMEOUT_MS } from "./debug-DXfQFmcM.js";
2
+ import { n as analytics } from "./analytics-DSlQuwOT.js";
3
+ import { o as extractOAuthCode, t as getOrAskForProjectData } from "./setup-utils-BQCl28D8.js";
4
+ import { t as ApiError } from "./api-BXduJZrw.js";
5
+ import { t as ADDITIONAL_FEATURE_LABELS } from "./wizard-session-BAZql11N.js";
6
+ import { i as wizardAbort } from "./wizard-abort-C14PzXZ8.js";
7
+ import { a as formatTokenCount, i as formatCostUsd } from "./agent-runner-BF6_f8Qh.js";
8
+ import { i as fetchSkillMenu, r as downloadSkill } from "./wizard-tools-B7SLjCic.js";
9
9
  import { a as coerceAuditChecks, i as AUDIT_SEVERITY_STYLE, n as AUDIT_CHECKS_KEY, o as getAuditChecks, t as AUDIT_CHECKS_FILE } from "./types-y3HkjtSq.js";
10
- import { m as EVENT_PLAN_FILE } from "./yara-hooks-Ciy8d0ok.js";
11
- import { t as FRAMEWORK_REGISTRY } from "./registry-DPriFJQI.js";
12
- import { g as detectProjectsWithAgent, m as Icons, p as Colors, t as SETUP_REPORT_FILE } from "./posthog-integration-Cw1QDMFi.js";
10
+ import { m as EVENT_PLAN_FILE } from "./yara-hooks-CPH8N4yz.js";
11
+ import { t as FRAMEWORK_REGISTRY } from "./registry-DcoBCMQR.js";
12
+ import { g as detectProjectsWithAgent, m as Icons, p as Colors, t as SETUP_REPORT_FILE } from "./posthog-integration-BhLKCFsI.js";
13
13
  import { C as STRIPE_SDKS, S as POSTHOG_SDKS, _ as SOURCE_MAPS_CONTEXT_KEYS, b as getDetectedWarehouseSources, d as Program, f as getProgramConfig, g as DISPLAY_NAME, h as AUTOMATABLE_VARIANTS, m as SELF_DRIVING_INTEGRATE_PATH_KEY, n as useKeyBindings, p as detectSelfDrivingIntegrationProjects, t as PickerMenu, x as getContentBlocks, y as fetchHealthIssues } from "./bin.js";
14
- import { r as totalTokenCount, t as WizardStore } from "./store-Bu1xO0_5.js";
15
- import { A as ConfirmationInput, C as TabContainer, D as LinkText, E as LogViewer, F as SplitView, M as useStdoutDimensions, N as ProgressList, O as extractUrls, P as LoadingBox, S as HNViewer, T as EventPlanViewer, _ as SEVERITY_ORDER, a as useSkillEntry, b as LearnCard, c as SlackConnectScreen, d as AuditChecksViewer, f as McpSuggestedPromptsScreen, g as SEVERITY_LABEL, h as IssueTable, i as SkillSourceInfo, k as ModalOverlay, l as AUDIT_AREA_SLIDES, m as McpScreen, n as releaseTerminal, o as OutroScreen, r as AiOptInRequiredScreen, s as useDismissOnAnyKey, t as enterDarkTerminal, u as VisualBox, v as ServiceHealthList, w as ScreenContainer, y as TipsCard } from "./terminal-CnYduoIp.js";
16
- import { t as ALL_FEATURE_VALUES } from "./defaults-CeNThA-1.js";
17
- import { a as getSupportedClients, c as removeMCPServer, i as getInstalledClients, o as getSupportedPluginClients, s as installPlugins, u as isPluginCapable } from "./add-mcp-server-to-clients-fGAJ6wRG.js";
14
+ import { r as totalTokenCount, t as WizardStore } from "./store-C79GoHCQ.js";
15
+ import { A as ConfirmationInput, C as TabContainer, D as LinkText, E as LogViewer, F as SplitView, M as useStdoutDimensions, N as ProgressList, O as extractUrls, P as LoadingBox, S as HNViewer, T as EventPlanViewer, _ as SEVERITY_ORDER, a as useSkillEntry, b as LearnCard, c as SlackConnectScreen, d as AuditChecksViewer, f as McpSuggestedPromptsScreen, g as SEVERITY_LABEL, h as IssueTable, i as SkillSourceInfo, k as ModalOverlay, l as AUDIT_AREA_SLIDES, m as McpScreen, n as releaseTerminal, o as OutroScreen, r as AiOptInRequiredScreen, s as useDismissOnAnyKey, t as enterDarkTerminal, u as VisualBox, v as ServiceHealthList, w as ScreenContainer, y as TipsCard } from "./terminal-CEhufbJ4.js";
16
+ import { t as ALL_FEATURE_VALUES } from "./defaults-BWLIffh5.js";
17
+ import { a as getSupportedClients, c as removeMCPServer, i as getInstalledClients, o as getSupportedPluginClients, s as installPlugins, u as isPluginCapable } from "./add-mcp-server-to-clients-D5qsqCkj.js";
18
18
  import * as fs$1 from "fs";
19
19
  import path from "path";
20
20
  import { join as join$1 } from "node:path";
@@ -117,6 +117,9 @@ var InkUI = class {
117
117
  requestQuestion(question) {
118
118
  return this.store.requestQuestion(question);
119
119
  }
120
+ cancelPendingQuestion() {
121
+ this.store.cancelPendingQuestion();
122
+ }
120
123
  startRun() {
121
124
  this.store.setRunPhase("running");
122
125
  }
@@ -1079,7 +1082,7 @@ const FrameworkPicker = ({ store, onComplete }) => {
1079
1082
  })),
1080
1083
  onSelect: (value) => {
1081
1084
  const integration = Array.isArray(value) ? value[0] : value;
1082
- import("./registry-DPriFJQI.js").then((n) => n.n).then(({ FRAMEWORK_REGISTRY }) => {
1085
+ import("./registry-DcoBCMQR.js").then((n) => n.n).then(({ FRAMEWORK_REGISTRY }) => {
1083
1086
  const config = FRAMEWORK_REGISTRY[integration];
1084
1087
  store.setFrameworkConfig(integration, config);
1085
1088
  store.setDetectedFramework(config.metadata.name);
@@ -2589,13 +2592,202 @@ const DetectErrorBody = ({ error }) => {
2589
2592
  //#region src/ui/tui/screens/SelfDrivingIntegrationCheckScreen.tsx
2590
2593
  /**
2591
2594
  * SelfDrivingIntegrationCheckScreen — shown only when detection found no
2592
- * PostHog in the project. It's a notice, not a question: Self-driving requires
2593
- * a PostHog SDK, so the single action sets `integrate = true` and the run
2594
- * integrates first. Skipped entirely when PostHog is already present (or under
2595
- * `--integrate`).
2595
+ * PostHog in the project. Self-driving needs a PostHog SDK, so we always
2596
+ * integrate first; but a project with no SDK is often a project with no PostHog
2597
+ * account either, so this screen first asks whether the user already has one:
2598
+ *
2599
+ * - "Yes — log me in" → setIntegrate(true); auth runs the OAuth login.
2600
+ * - "No — create one for me" → collect email + region, then
2601
+ * chooseProvisionAccount(): auth provisions a new
2602
+ * account (and emails a login link) instead.
2603
+ *
2604
+ * Both answers integrate the SDK; they only differ in how auth gets credentials.
2605
+ * Skipped entirely when PostHog is already present (or under `--integrate`,
2606
+ * which forces integration + the default OAuth login).
2596
2607
  */
2608
+ const EMAIL_RE = /^[^@\s]+@[^@\s]+\.[^@\s]+$/;
2597
2609
  const SelfDrivingIntegrationCheckScreen = ({ store }) => {
2598
2610
  useSyncExternalStore((cb) => store.subscribe(cb), () => store.getSnapshot());
2611
+ const [stage, setStage] = useState("ask");
2612
+ const [email, setEmail] = useState(store.session.email ?? "");
2613
+ const [emailError, setEmailError] = useState(null);
2614
+ const [showPrivacy, setShowPrivacy] = useState(false);
2615
+ useInput((input, key) => {
2616
+ if (showPrivacy) {
2617
+ if (key.escape) setShowPrivacy(false);
2618
+ return;
2619
+ }
2620
+ if ((input === "i" || input === "I") && stage !== "email") {
2621
+ setShowPrivacy(true);
2622
+ return;
2623
+ }
2624
+ if (key.escape && stage !== "ask") {
2625
+ setEmailError(null);
2626
+ setStage(stage === "region" ? "email" : "ask");
2627
+ }
2628
+ });
2629
+ if (showPrivacy) return /* @__PURE__ */ jsx(IntroScreenLayout, {
2630
+ installDir: store.session.installDir,
2631
+ title: "Wizard privacy & usage",
2632
+ showSubtitle: false,
2633
+ showDetection: false,
2634
+ body: /* @__PURE__ */ jsx(PrivacyPanel, {}),
2635
+ menuOptions: [{
2636
+ label: "Back",
2637
+ value: "back"
2638
+ }],
2639
+ menuAlign: "left",
2640
+ onSelect: () => setShowPrivacy(false)
2641
+ });
2642
+ if (stage === "region") return /* @__PURE__ */ jsxs(Box, {
2643
+ flexDirection: "column",
2644
+ flexGrow: 1,
2645
+ children: [
2646
+ /* @__PURE__ */ jsx(Text, {
2647
+ bold: true,
2648
+ color: Colors.accent,
2649
+ children: "Where should we create your account?"
2650
+ }),
2651
+ /* @__PURE__ */ jsx(Box, {
2652
+ marginTop: 1,
2653
+ flexDirection: "column",
2654
+ children: /* @__PURE__ */ jsxs(Text, {
2655
+ dimColor: true,
2656
+ children: [
2657
+ "We'll create your PostHog account for ",
2658
+ email,
2659
+ " in this region."
2660
+ ]
2661
+ })
2662
+ }),
2663
+ /* @__PURE__ */ jsx(Box, {
2664
+ marginTop: 1,
2665
+ children: /* @__PURE__ */ jsx(PickerMenu, {
2666
+ message: "Pick your cloud region",
2667
+ options: [{
2668
+ label: "US",
2669
+ value: "us",
2670
+ hint: "us.posthog.com"
2671
+ }, {
2672
+ label: "EU",
2673
+ value: "eu",
2674
+ hint: "eu.posthog.com"
2675
+ }],
2676
+ onSelect: (value) => {
2677
+ const region = Array.isArray(value) ? value[0] : value;
2678
+ store.chooseProvisionAccount(email.trim(), region);
2679
+ }
2680
+ })
2681
+ }),
2682
+ /* @__PURE__ */ jsxs(Box, {
2683
+ marginTop: 1,
2684
+ flexDirection: "column",
2685
+ children: [
2686
+ /* @__PURE__ */ jsx(Text, {
2687
+ dimColor: true,
2688
+ children: "By creating an account you agree to our terms."
2689
+ }),
2690
+ /* @__PURE__ */ jsxs(Text, {
2691
+ dimColor: true,
2692
+ children: ["Terms: ", /* @__PURE__ */ jsx(Text, {
2693
+ color: "cyan",
2694
+ children: POSTHOG_TERMS_URL
2695
+ })]
2696
+ }),
2697
+ /* @__PURE__ */ jsxs(Text, {
2698
+ dimColor: true,
2699
+ children: ["Privacy: ", /* @__PURE__ */ jsx(Text, {
2700
+ color: "cyan",
2701
+ children: POSTHOG_PRIVACY_URL
2702
+ })]
2703
+ })
2704
+ ]
2705
+ }),
2706
+ /* @__PURE__ */ jsx(Box, {
2707
+ marginTop: 1,
2708
+ children: /* @__PURE__ */ jsxs(Text, {
2709
+ dimColor: true,
2710
+ children: [
2711
+ /* @__PURE__ */ jsx(Text, {
2712
+ color: Colors.accent,
2713
+ children: "[Esc]"
2714
+ }),
2715
+ " back",
2716
+ " · ",
2717
+ /* @__PURE__ */ jsx(Text, {
2718
+ color: Colors.accent,
2719
+ children: "[I]"
2720
+ }),
2721
+ " privacy & usage"
2722
+ ]
2723
+ })
2724
+ })
2725
+ ]
2726
+ });
2727
+ if (stage === "email") return /* @__PURE__ */ jsxs(Box, {
2728
+ flexDirection: "column",
2729
+ flexGrow: 1,
2730
+ children: [
2731
+ /* @__PURE__ */ jsx(Text, {
2732
+ bold: true,
2733
+ color: Colors.accent,
2734
+ children: "Create your PostHog account"
2735
+ }),
2736
+ /* @__PURE__ */ jsx(Box, {
2737
+ marginTop: 1,
2738
+ flexDirection: "column",
2739
+ children: /* @__PURE__ */ jsx(Text, {
2740
+ dimColor: true,
2741
+ children: "We'll create your account and email you a login link. What email should we use?"
2742
+ })
2743
+ }),
2744
+ /* @__PURE__ */ jsx(Box, {
2745
+ marginTop: 1,
2746
+ width: "100%",
2747
+ children: /* @__PURE__ */ jsx(TextInput, {
2748
+ placeholder: "you@company.com",
2749
+ defaultValue: email,
2750
+ onChange: setEmail,
2751
+ onSubmit: (value) => {
2752
+ const trimmed = value.trim();
2753
+ if (!EMAIL_RE.test(trimmed)) {
2754
+ setEmailError("Please enter a valid email address.");
2755
+ return;
2756
+ }
2757
+ setEmail(trimmed);
2758
+ setEmailError(null);
2759
+ setStage("region");
2760
+ }
2761
+ })
2762
+ }),
2763
+ emailError && /* @__PURE__ */ jsx(Box, {
2764
+ marginTop: 1,
2765
+ children: /* @__PURE__ */ jsx(Text, {
2766
+ color: "yellow",
2767
+ children: emailError
2768
+ })
2769
+ }),
2770
+ /* @__PURE__ */ jsx(Box, {
2771
+ marginTop: 1,
2772
+ children: /* @__PURE__ */ jsxs(Text, {
2773
+ dimColor: true,
2774
+ children: [
2775
+ /* @__PURE__ */ jsx(Text, {
2776
+ color: Colors.accent,
2777
+ children: "[Enter]"
2778
+ }),
2779
+ " continue",
2780
+ " · ",
2781
+ /* @__PURE__ */ jsx(Text, {
2782
+ color: Colors.accent,
2783
+ children: "[Esc]"
2784
+ }),
2785
+ " back"
2786
+ ]
2787
+ })
2788
+ })
2789
+ ]
2790
+ });
2599
2791
  return /* @__PURE__ */ jsxs(Box, {
2600
2792
  flexDirection: "column",
2601
2793
  flexGrow: 1,
@@ -2610,17 +2802,35 @@ const SelfDrivingIntegrationCheckScreen = ({ store }) => {
2610
2802
  flexDirection: "column",
2611
2803
  children: /* @__PURE__ */ jsx(Text, {
2612
2804
  dimColor: true,
2613
- children: "This will kick off an agent to explore your project and find existing PostHog integrations. Self-driving reads PostHog data, so we'll set that up first: it gives your signal sources something to watch."
2805
+ children: "This will kick off an agent to explore your project and find existing PostHog integrations. Self-driving reads PostHog data, so we'll set that up first: it gives your signal sources something to watch. To do that we need to connect to PostHog — do you already have an account?"
2614
2806
  })
2615
2807
  }),
2616
2808
  /* @__PURE__ */ jsx(Box, {
2617
2809
  marginTop: 1,
2618
2810
  children: /* @__PURE__ */ jsx(PickerMenu, {
2619
2811
  options: [{
2620
- label: "Set up PostHog [Enter]",
2621
- value: "yes"
2812
+ label: "Yes, log me in",
2813
+ value: "login",
2814
+ hint: "opens PostHog to authorize"
2815
+ }, {
2816
+ label: "No, create one for me",
2817
+ value: "provision",
2818
+ hint: "we'll email you a login link"
2622
2819
  }],
2623
- onSelect: () => store.setIntegrate(true)
2820
+ onSelect: (value) => {
2821
+ if ((Array.isArray(value) ? value[0] : value) === "login") store.setIntegrate(true);
2822
+ else setStage("email");
2823
+ }
2824
+ })
2825
+ }),
2826
+ /* @__PURE__ */ jsx(Box, {
2827
+ marginTop: 1,
2828
+ children: /* @__PURE__ */ jsxs(Text, {
2829
+ dimColor: true,
2830
+ children: [/* @__PURE__ */ jsx(Text, {
2831
+ color: Colors.accent,
2832
+ children: "[I]"
2833
+ }), " privacy & usage"]
2624
2834
  })
2625
2835
  })
2626
2836
  ]
@@ -4016,6 +4226,120 @@ const SetupScreen = ({ store }) => {
4016
4226
  });
4017
4227
  };
4018
4228
  //#endregion
4229
+ //#region src/utils/clipboard.ts
4230
+ /**
4231
+ * Best-effort platform shell-outs for making a URL usable in any terminal —
4232
+ * no third-party dependency.
4233
+ *
4234
+ * Two helpers back the `wizard_ask` link overlay, for terminals that can't
4235
+ * linkify a wrapped URL (e.g. macOS Terminal.app, which lacks OSC 8 hyperlink
4236
+ * support):
4237
+ *
4238
+ * - `copyToClipboard` — pipe the URL to the platform clipboard binary so the
4239
+ * user can paste it into a browser.
4240
+ * - `openInBrowser` — hand the URL to the platform opener so it launches
4241
+ * directly, no copy/paste needed.
4242
+ *
4243
+ * Both shell out with `spawn` and never a shell, and pass the URL as an argv
4244
+ * (clipboard via stdin) — so there's no shell-injection surface. Neither throws:
4245
+ * they return false when no command is reachable (CI, headless, or the binary
4246
+ * isn't installed).
4247
+ */
4248
+ /** Platform clipboard commands, in preference order. */
4249
+ function clipboardCommands() {
4250
+ if (process.platform === "darwin") return [{
4251
+ cmd: "pbcopy",
4252
+ args: []
4253
+ }];
4254
+ if (process.platform === "win32") return [{
4255
+ cmd: "clip",
4256
+ args: []
4257
+ }];
4258
+ return [
4259
+ {
4260
+ cmd: "wl-copy",
4261
+ args: []
4262
+ },
4263
+ {
4264
+ cmd: "xclip",
4265
+ args: ["-selection", "clipboard"]
4266
+ },
4267
+ {
4268
+ cmd: "xsel",
4269
+ args: ["--clipboard", "--input"]
4270
+ }
4271
+ ];
4272
+ }
4273
+ function writeWith({ cmd, args }, text) {
4274
+ return new Promise((resolve) => {
4275
+ try {
4276
+ const child = spawn(cmd, args);
4277
+ child.on("error", () => resolve(false));
4278
+ child.stdin.on("error", () => resolve(false));
4279
+ child.on("close", (code) => resolve(code === 0));
4280
+ child.stdin.end(text);
4281
+ } catch {
4282
+ resolve(false);
4283
+ }
4284
+ });
4285
+ }
4286
+ async function copyToClipboard(text) {
4287
+ for (const command of clipboardCommands()) if (await writeWith(command, text)) return true;
4288
+ logToFile("[clipboard] no working clipboard command found");
4289
+ return false;
4290
+ }
4291
+ /**
4292
+ * Platform browser-open commands, in preference order. The URL is one argv
4293
+ * element — never concatenated into a shell string — so a `?kind=…` query or
4294
+ * any other character can't escape into the command line.
4295
+ *
4296
+ * `win32` has no shell-free single binary for this: `start` is a `cmd` builtin,
4297
+ * so we invoke `cmd /c start "" <url>` (the empty `""` is `start`'s window-title
4298
+ * argument, which would otherwise swallow the URL). The URL is still a discrete
4299
+ * argv element, not interpolated into the command string.
4300
+ *
4301
+ * Takes `platform` as an argument (defaulting to the host) so the mapping is a
4302
+ * pure function the tests can exercise across platforms.
4303
+ */
4304
+ function browserOpenCommands(url, platform = process.platform) {
4305
+ if (platform === "darwin") return [{
4306
+ cmd: "open",
4307
+ args: [url]
4308
+ }];
4309
+ if (platform === "win32") return [{
4310
+ cmd: "cmd",
4311
+ args: [
4312
+ "/c",
4313
+ "start",
4314
+ "",
4315
+ url
4316
+ ]
4317
+ }];
4318
+ return [{
4319
+ cmd: "xdg-open",
4320
+ args: [url]
4321
+ }, {
4322
+ cmd: "x-www-browser",
4323
+ args: [url]
4324
+ }];
4325
+ }
4326
+ function spawnOpener({ cmd, args }) {
4327
+ return new Promise((resolve) => {
4328
+ try {
4329
+ const child = spawn(cmd, args, { stdio: "ignore" });
4330
+ child.on("error", () => resolve(false));
4331
+ child.on("close", (code) => resolve(code === 0));
4332
+ } catch {
4333
+ resolve(false);
4334
+ }
4335
+ });
4336
+ }
4337
+ async function openInBrowser(url) {
4338
+ for (const command of browserOpenCommands(url)) if (await spawnOpener(command)) return true;
4339
+ logToFile("[clipboard] no working browser-open command found");
4340
+ return false;
4341
+ }
4342
+ //#endregion
4019
4343
  //#region src/ui/tui/screens/AuthScreen.tsx
4020
4344
  /**
4021
4345
  * AuthScreen — Shown while waiting for OAuth authentication.
@@ -4023,23 +4347,39 @@ const SetupScreen = ({ store }) => {
4023
4347
  * Displays framework detection, a compressed privacy summary, a waiting
4024
4348
  * spinner, and the login URL when available. [I] opens the full
4025
4349
  * PrivacyPanel as an overlay. [P] (when loginUrl is set) lets the user
4026
- * paste the callback URL by hand.
4350
+ * paste the callback URL by hand. [C] copies the login URL to the
4351
+ * clipboard — the exact string, so it can't be chopped by a soft-wrap.
4027
4352
  *
4028
4353
  * The router resolves past this screen once session.credentials is set.
4029
4354
  */
4030
4355
  const AuthScreen = ({ store }) => {
4031
4356
  useSyncExternalStore((cb) => store.subscribe(cb), () => store.getSnapshot());
4032
4357
  const [showPrivacy, setShowPrivacy] = useState(false);
4358
+ const [copyStatus, setCopyStatus] = useState("idle");
4359
+ const [columns] = useStdoutDimensions();
4033
4360
  const { session } = store;
4034
- const canPasteCode = Boolean(session.loginUrl);
4361
+ const loginUrl = session.loginUrl;
4362
+ const canPasteCode = Boolean(loginUrl);
4363
+ const availableWidth = Math.min(columns, 120) - 2;
4364
+ const urlFits = loginUrl ? loginUrl.length <= availableWidth : true;
4035
4365
  const bindings = [];
4036
4366
  if (!showPrivacy) {
4037
- if (canPasteCode) bindings.push({
4038
- match: ["p", "P"],
4039
- label: "P",
4040
- action: "paste auth code",
4041
- handler: () => store.showManualAuthCode()
4042
- });
4367
+ if (canPasteCode && loginUrl) {
4368
+ bindings.push({
4369
+ match: ["p", "P"],
4370
+ label: "P",
4371
+ action: "paste auth code",
4372
+ handler: () => store.showManualAuthCode()
4373
+ });
4374
+ bindings.push({
4375
+ match: ["c", "C"],
4376
+ label: "C",
4377
+ action: "copy link",
4378
+ handler: () => {
4379
+ copyToClipboard(loginUrl).then((ok) => setCopyStatus(ok ? "copied" : "failed"));
4380
+ }
4381
+ });
4382
+ }
4043
4383
  bindings.push({
4044
4384
  match: ["i", "I"],
4045
4385
  label: "I",
@@ -4126,35 +4466,68 @@ const AuthScreen = ({ store }) => {
4126
4466
  ]
4127
4467
  }),
4128
4468
  /* @__PURE__ */ jsx(LoadingBox, { message: "Waiting for authentication..." }),
4129
- session.loginUrl && /* @__PURE__ */ jsxs(Box, {
4469
+ loginUrl && /* @__PURE__ */ jsxs(Box, {
4130
4470
  marginTop: 1,
4131
4471
  marginBottom: 1,
4132
4472
  flexDirection: "column",
4133
- children: [/* @__PURE__ */ jsxs(Text, { children: [
4134
- /* @__PURE__ */ jsx(Text, {
4135
- dimColor: true,
4136
- children: "If the browser didn't open, copy and paste this URL:"
4473
+ children: [
4474
+ urlFits ? /* @__PURE__ */ jsxs(Text, { children: [
4475
+ /* @__PURE__ */ jsx(Text, {
4476
+ dimColor: true,
4477
+ children: "If the browser didn't open, copy and paste this URL:"
4478
+ }),
4479
+ "\n\n",
4480
+ /* @__PURE__ */ jsx(Text, {
4481
+ color: "cyan",
4482
+ children: loginUrl
4483
+ })
4484
+ ] }) : /* @__PURE__ */ jsx(Text, {
4485
+ color: "yellow",
4486
+ children: "[This terminal is too small to show the full link for copying, resize your terminal]"
4137
4487
  }),
4138
- "\n\n",
4139
- /* @__PURE__ */ jsx(Text, {
4140
- color: "cyan",
4141
- children: session.loginUrl
4142
- })
4143
- ] }), /* @__PURE__ */ jsx(Box, {
4144
- marginTop: 1,
4145
- children: /* @__PURE__ */ jsxs(Text, {
4146
- dimColor: true,
4147
- children: [
4148
- "On a remote machine or devbox? Press",
4149
- " ",
4150
- /* @__PURE__ */ jsx(Text, {
4151
- color: Colors.accent,
4152
- children: "[P]"
4153
- }),
4154
- " to paste the callback URL."
4155
- ]
4488
+ /* @__PURE__ */ jsx(Box, {
4489
+ marginTop: 1,
4490
+ children: /* @__PURE__ */ jsxs(Text, {
4491
+ dimColor: true,
4492
+ children: [
4493
+ "Press ",
4494
+ /* @__PURE__ */ jsx(Text, {
4495
+ color: Colors.accent,
4496
+ children: "[C]"
4497
+ }),
4498
+ " to copy the link · on a remote machine or devbox? Press",
4499
+ " ",
4500
+ /* @__PURE__ */ jsx(Text, {
4501
+ color: Colors.accent,
4502
+ children: "[P]"
4503
+ }),
4504
+ " to paste the callback URL."
4505
+ ]
4506
+ })
4507
+ }),
4508
+ copyStatus === "copied" && /* @__PURE__ */ jsx(Box, {
4509
+ marginTop: 1,
4510
+ children: /* @__PURE__ */ jsxs(Text, {
4511
+ color: Colors.success,
4512
+ children: [Icons.check, " Link copied to clipboard."]
4513
+ })
4514
+ }),
4515
+ copyStatus === "failed" && /* @__PURE__ */ jsx(Box, {
4516
+ marginTop: 1,
4517
+ children: /* @__PURE__ */ jsxs(Text, {
4518
+ color: "yellow",
4519
+ children: [
4520
+ "Couldn't reach a clipboard on this machine — press",
4521
+ " ",
4522
+ /* @__PURE__ */ jsx(Text, {
4523
+ color: Colors.accent,
4524
+ children: "[P]"
4525
+ }),
4526
+ " to paste the callback URL instead."
4527
+ ]
4528
+ })
4156
4529
  })
4157
- })]
4530
+ ]
4158
4531
  })
4159
4532
  ]
4160
4533
  });
@@ -4622,120 +4995,6 @@ const SessionTimeoutScreen = ({ store }) => {
4622
4995
  });
4623
4996
  };
4624
4997
  //#endregion
4625
- //#region src/utils/clipboard.ts
4626
- /**
4627
- * Best-effort platform shell-outs for making a URL usable in any terminal —
4628
- * no third-party dependency.
4629
- *
4630
- * Two helpers back the `wizard_ask` link overlay, for terminals that can't
4631
- * linkify a wrapped URL (e.g. macOS Terminal.app, which lacks OSC 8 hyperlink
4632
- * support):
4633
- *
4634
- * - `copyToClipboard` — pipe the URL to the platform clipboard binary so the
4635
- * user can paste it into a browser.
4636
- * - `openInBrowser` — hand the URL to the platform opener so it launches
4637
- * directly, no copy/paste needed.
4638
- *
4639
- * Both shell out with `spawn` and never a shell, and pass the URL as an argv
4640
- * (clipboard via stdin) — so there's no shell-injection surface. Neither throws:
4641
- * they return false when no command is reachable (CI, headless, or the binary
4642
- * isn't installed).
4643
- */
4644
- /** Platform clipboard commands, in preference order. */
4645
- function clipboardCommands() {
4646
- if (process.platform === "darwin") return [{
4647
- cmd: "pbcopy",
4648
- args: []
4649
- }];
4650
- if (process.platform === "win32") return [{
4651
- cmd: "clip",
4652
- args: []
4653
- }];
4654
- return [
4655
- {
4656
- cmd: "wl-copy",
4657
- args: []
4658
- },
4659
- {
4660
- cmd: "xclip",
4661
- args: ["-selection", "clipboard"]
4662
- },
4663
- {
4664
- cmd: "xsel",
4665
- args: ["--clipboard", "--input"]
4666
- }
4667
- ];
4668
- }
4669
- function writeWith({ cmd, args }, text) {
4670
- return new Promise((resolve) => {
4671
- try {
4672
- const child = spawn(cmd, args);
4673
- child.on("error", () => resolve(false));
4674
- child.stdin.on("error", () => resolve(false));
4675
- child.on("close", (code) => resolve(code === 0));
4676
- child.stdin.end(text);
4677
- } catch {
4678
- resolve(false);
4679
- }
4680
- });
4681
- }
4682
- async function copyToClipboard(text) {
4683
- for (const command of clipboardCommands()) if (await writeWith(command, text)) return true;
4684
- logToFile("[clipboard] no working clipboard command found");
4685
- return false;
4686
- }
4687
- /**
4688
- * Platform browser-open commands, in preference order. The URL is one argv
4689
- * element — never concatenated into a shell string — so a `?kind=…` query or
4690
- * any other character can't escape into the command line.
4691
- *
4692
- * `win32` has no shell-free single binary for this: `start` is a `cmd` builtin,
4693
- * so we invoke `cmd /c start "" <url>` (the empty `""` is `start`'s window-title
4694
- * argument, which would otherwise swallow the URL). The URL is still a discrete
4695
- * argv element, not interpolated into the command string.
4696
- *
4697
- * Takes `platform` as an argument (defaulting to the host) so the mapping is a
4698
- * pure function the tests can exercise across platforms.
4699
- */
4700
- function browserOpenCommands(url, platform = process.platform) {
4701
- if (platform === "darwin") return [{
4702
- cmd: "open",
4703
- args: [url]
4704
- }];
4705
- if (platform === "win32") return [{
4706
- cmd: "cmd",
4707
- args: [
4708
- "/c",
4709
- "start",
4710
- "",
4711
- url
4712
- ]
4713
- }];
4714
- return [{
4715
- cmd: "xdg-open",
4716
- args: [url]
4717
- }, {
4718
- cmd: "x-www-browser",
4719
- args: [url]
4720
- }];
4721
- }
4722
- function spawnOpener({ cmd, args }) {
4723
- return new Promise((resolve) => {
4724
- try {
4725
- const child = spawn(cmd, args, { stdio: "ignore" });
4726
- child.on("error", () => resolve(false));
4727
- child.on("close", (code) => resolve(code === 0));
4728
- } catch {
4729
- resolve(false);
4730
- }
4731
- });
4732
- }
4733
- async function openInBrowser(url) {
4734
- for (const command of browserOpenCommands(url)) if (await spawnOpener(command)) return true;
4735
- logToFile("[clipboard] no working browser-open command found");
4736
- return false;
4737
- }
4738
- //#endregion
4739
4998
  //#region src/ui/tui/screens/WizardAskScreen.tsx
4740
4999
  /**
4741
5000
  * WizardAskScreen — Overlay for the `wizard_ask` MCP tool.
@@ -5014,7 +5273,7 @@ function createMcpSuggestedPromptsServices(store) {
5014
5273
  };
5015
5274
  }
5016
5275
  async function* runProductionPromptStreaming(args) {
5017
- const { runMcpPromptViaSdk } = await import("./mcp-prompt-streaming-CCS2EkfY.js");
5276
+ const { runMcpPromptViaSdk } = await import("./mcp-prompt-streaming-AtntLsJ8.js");
5018
5277
  yield* runMcpPromptViaSdk(args);
5019
5278
  }
5020
5279
  //#endregion
@@ -5190,4 +5449,4 @@ function startTUI(version, program = Program.PostHogIntegration) {
5190
5449
  //#endregion
5191
5450
  export { startTUI };
5192
5451
 
5193
- //# sourceMappingURL=start-tui-BMZL7mKh.js.map
5452
+ //# sourceMappingURL=start-tui-DgSKFMVh.js.map