@posthog/wizard 2.74.0 → 2.75.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 (117) hide show
  1. package/README.md +41 -27
  2. package/dist/README.md +10 -0
  3. package/dist/{add-mcp-server-to-clients-BtWwRG7O.js → add-mcp-server-to-clients-CjfnPMbO.js} +5 -5
  4. package/dist/{add-mcp-server-to-clients-BtWwRG7O.js.map → add-mcp-server-to-clients-CjfnPMbO.js.map} +1 -1
  5. package/dist/{agent-interface-CK6pmvkF.js → agent-interface-BKLTDSyN.js} +144 -338
  6. package/dist/agent-interface-BKLTDSyN.js.map +1 -0
  7. package/dist/{agent-prompt-loader-CPCNMvGh.js → agent-prompt-loader-DAagxT3p.js} +5 -5
  8. package/dist/{agent-prompt-loader-CPCNMvGh.js.map → agent-prompt-loader-DAagxT3p.js.map} +1 -1
  9. package/dist/{agent-runner-jz4yiJfh.js → agent-runner-BkQontri.js} +136 -46
  10. package/dist/agent-runner-BkQontri.js.map +1 -0
  11. package/dist/{analytics-DZNb3aRN.js → analytics-DSK0GXg1.js} +6 -4
  12. package/dist/analytics-DSK0GXg1.js.map +1 -0
  13. package/dist/analytics-yurAACt5.js +2 -0
  14. package/dist/{api-DXGaiK94.js → api-CwNulLDK.js} +3 -3
  15. package/dist/{api-DXGaiK94.js.map → api-CwNulLDK.js.map} +1 -1
  16. package/dist/bin.js +125 -4072
  17. package/dist/bin.js.map +1 -1
  18. package/dist/{bounded-fs-CErPpkN2.js → bounded-fs-D85Tk3nS.js} +3 -3
  19. package/dist/{bounded-fs-CErPpkN2.js.map → bounded-fs-D85Tk3nS.js.map} +1 -1
  20. package/dist/{ci-install-CzWzi_qu.js → ci-install-CQLi_a-r.js} +4 -4
  21. package/dist/{ci-install-CzWzi_qu.js.map → ci-install-CQLi_a-r.js.map} +1 -1
  22. package/dist/{debug-D4y9vVWt.js → debug-CBmI5YUF.js} +1 -1
  23. package/dist/{debug-ECdmmlDM.js → debug-DUmMVUHn.js} +14 -335
  24. package/dist/debug-DUmMVUHn.js.map +1 -0
  25. package/dist/{defaults-DI642M3n.js → defaults-DDDwYTN5.js} +1 -1
  26. package/dist/{defaults-DI642M3n.js.map → defaults-DDDwYTN5.js.map} +1 -1
  27. package/dist/{env-api-key-g5w775Ve.js → env-api-key-CGC1Bqwq.js} +2 -2
  28. package/dist/{env-api-key-g5w775Ve.js.map → env-api-key-CGC1Bqwq.js.map} +1 -1
  29. package/dist/{environment-DDkdsWUr.js → environment-DC4RDnzR.js} +4 -4
  30. package/dist/{environment-DDkdsWUr.js.map → environment-DC4RDnzR.js.map} +1 -1
  31. package/dist/{file-watcher-BNdFPlI8.js → file-watcher-hafFFQib.js} +2 -2
  32. package/dist/{file-watcher-BNdFPlI8.js.map → file-watcher-hafFFQib.js.map} +1 -1
  33. package/dist/gateway-session-Ctc2xaz7.js +271 -0
  34. package/dist/gateway-session-Ctc2xaz7.js.map +1 -0
  35. package/dist/gateway-session-zwwZAyTt.js +2 -0
  36. package/dist/{headless-ui-DBZCl4CG.js → headless-ui-CQ46FOTh.js} +2 -2
  37. package/dist/{headless-ui-DBZCl4CG.js.map → headless-ui-CQ46FOTh.js.map} +1 -1
  38. package/dist/{interactive-BKxXUB0T.js → interactive-5O4XQf59.js} +2 -2
  39. package/dist/{interactive-BKxXUB0T.js.map → interactive-5O4XQf59.js.map} +1 -1
  40. package/dist/{mcp-CwM45_Kp.js → mcp-D0Dni4tL.js} +2 -2
  41. package/dist/{mcp-CwM45_Kp.js.map → mcp-D0Dni4tL.js.map} +1 -1
  42. package/dist/{mcp-prompt-streaming-R8H7uhuO.js → mcp-prompt-streaming-DNCDeU51.js} +6 -5
  43. package/dist/{mcp-prompt-streaming-R8H7uhuO.js.map → mcp-prompt-streaming-DNCDeU51.js.map} +1 -1
  44. package/dist/mint-failure-CQqypC_v.js +5718 -0
  45. package/dist/mint-failure-CQqypC_v.js.map +1 -0
  46. package/dist/{non-interactive-DxzBwNxJ.js → non-interactive-D5-lCBy6.js} +2 -2
  47. package/dist/{non-interactive-DxzBwNxJ.js.map → non-interactive-D5-lCBy6.js.map} +1 -1
  48. package/dist/{orchestrator-tools-CTpKnk5-.js → orchestrator-tools-D8ZQS2DM.js} +5 -5
  49. package/dist/orchestrator-tools-D8ZQS2DM.js.map +1 -0
  50. package/dist/{package-manager-Bi6gaPa4.js → package-manager-hyP-CPSZ.js} +2 -2
  51. package/dist/{package-manager-Bi6gaPa4.js.map → package-manager-hyP-CPSZ.js.map} +1 -1
  52. package/dist/{pi-DpWFwz5u.js → pi-DARAk2I_.js} +35 -24
  53. package/dist/pi-DARAk2I_.js.map +1 -0
  54. package/dist/{playground-BtTCVaSD.js → playground-Djabnagq.js} +13 -65
  55. package/dist/playground-Djabnagq.js.map +1 -0
  56. package/dist/{posthog-B99H8Zyk.js → posthog-C3Sncfan.js} +2 -2
  57. package/dist/{posthog-B99H8Zyk.js.map → posthog-C3Sncfan.js.map} +1 -1
  58. package/dist/{provisioning-BewSEuFX.js → provisioning-B74q1uSQ.js} +3 -3
  59. package/dist/{provisioning-BewSEuFX.js.map → provisioning-B74q1uSQ.js.map} +1 -1
  60. package/dist/{queue-tools-CbRM-OET.js → queue-tools-FLMG8hcB.js} +34 -9
  61. package/dist/queue-tools-FLMG8hcB.js.map +1 -0
  62. package/dist/{registry-Bt2Mc4vC.js → registry-DZoReEU3.js} +5 -5
  63. package/dist/{registry-Bt2Mc4vC.js.map → registry-DZoReEU3.js.map} +1 -1
  64. package/dist/{security-Cmxb64bz.js → security-DiBFYwh7.js} +5 -5
  65. package/dist/{security-Cmxb64bz.js.map → security-DiBFYwh7.js.map} +1 -1
  66. package/dist/{setup-utils-CCphwDIz.js → setup-utils-C3tsa6D6.js} +48 -9
  67. package/dist/setup-utils-C3tsa6D6.js.map +1 -0
  68. package/dist/smoke-test-ci.sh +9 -14
  69. package/dist/{start-tui-BRwZzlWb.js → start-tui-BXjJGNx2.js} +849 -115
  70. package/dist/start-tui-BXjJGNx2.js.map +1 -0
  71. package/dist/{steps-CJrx1t72.js → steps-CeFanezY.js} +7 -7
  72. package/dist/{steps-CJrx1t72.js.map → steps-CeFanezY.js.map} +1 -1
  73. package/dist/{store-BhcCTIn4.js → store-DN_6FaoQ.js} +66 -28
  74. package/dist/store-DN_6FaoQ.js.map +1 -0
  75. package/dist/{subagent-BeMPBF5r.js → subagent-BzhCH9c3.js} +2 -2
  76. package/dist/{subagent-BeMPBF5r.js.map → subagent-BzhCH9c3.js.map} +1 -1
  77. package/dist/{task-DX3eZgBL.js → task-DZKmaWYF.js} +19 -22
  78. package/dist/task-DZKmaWYF.js.map +1 -0
  79. package/dist/{task-stream-BW7BG70C.js → task-stream-h-b1nWdM.js} +5 -5
  80. package/dist/{task-stream-BW7BG70C.js.map → task-stream-h-b1nWdM.js.map} +1 -1
  81. package/dist/{tasks-Did1AR7v.js → tasks-0Rb5AXpz.js} +2 -2
  82. package/dist/{tasks-Did1AR7v.js.map → tasks-0Rb5AXpz.js.map} +1 -1
  83. package/dist/{telemetry-CPWHrsXK.js → telemetry-QpeVhVtU.js} +3 -3
  84. package/dist/{telemetry-CPWHrsXK.js.map → telemetry-QpeVhVtU.js.map} +1 -1
  85. package/dist/{terminal-CpVFsbGu.js → terminal-dLoYiXsd.js} +24 -65
  86. package/dist/terminal-dLoYiXsd.js.map +1 -0
  87. package/dist/{tools-DjiwCd53.js → tools-DmwO0eBZ.js} +22 -16
  88. package/dist/tools-DmwO0eBZ.js.map +1 -0
  89. package/dist/{wizard-abort-RUnY1Dax.js → wizard-abort-B0c5VDie.js} +4 -4
  90. package/dist/{wizard-abort-RUnY1Dax.js.map → wizard-abort-B0c5VDie.js.map} +1 -1
  91. package/dist/{wizard-abort-DjJ-6y6S.js → wizard-abort-C9Jbm-m7.js} +1 -1
  92. package/dist/{wizard-session-BWAQoi9q.js → wizard-session-CYvyYnti.js} +1 -1
  93. package/dist/{wizard-session-GdDN_aMS.js → wizard-session-FSJCkTcP.js} +9 -2
  94. package/dist/wizard-session-FSJCkTcP.js.map +1 -0
  95. package/dist/yara-hooks-B7prW1Ng.js +2 -0
  96. package/dist/{yara-hooks-jBqAkgxw.js → yara-hooks-uCiAIcqU.js} +4 -4
  97. package/dist/{yara-hooks-jBqAkgxw.js.map → yara-hooks-uCiAIcqU.js.map} +1 -1
  98. package/package.json +1 -1
  99. package/dist/agent-interface-CK6pmvkF.js.map +0 -1
  100. package/dist/agent-runner-jz4yiJfh.js.map +0 -1
  101. package/dist/analytics-CfadnLFG.js +0 -2
  102. package/dist/analytics-DZNb3aRN.js.map +0 -1
  103. package/dist/debug-ECdmmlDM.js.map +0 -1
  104. package/dist/orchestrator-tools-CTpKnk5-.js.map +0 -1
  105. package/dist/pi-DpWFwz5u.js.map +0 -1
  106. package/dist/playground-BtTCVaSD.js.map +0 -1
  107. package/dist/posthog-integration-CxvkKY1j.js +0 -1475
  108. package/dist/posthog-integration-CxvkKY1j.js.map +0 -1
  109. package/dist/queue-tools-CbRM-OET.js.map +0 -1
  110. package/dist/setup-utils-CCphwDIz.js.map +0 -1
  111. package/dist/start-tui-BRwZzlWb.js.map +0 -1
  112. package/dist/store-BhcCTIn4.js.map +0 -1
  113. package/dist/task-DX3eZgBL.js.map +0 -1
  114. package/dist/terminal-CpVFsbGu.js.map +0 -1
  115. package/dist/tools-DjiwCd53.js.map +0 -1
  116. package/dist/wizard-session-GdDN_aMS.js.map +0 -1
  117. package/dist/yara-hooks-CBMSmD9F.js +0 -2
@@ -1,33 +1,36 @@
1
1
  import { d as ErrorCodes } from "./errors--OqLxmWR.js";
2
- import { B as OAUTH_PORTS, K as POSTHOG_ORG_AI_SETTINGS_URL, V as OAUTH_TIMEOUT_MS, W as POSTHOG_DOCS_URL, X as POSTHOG_TERMS_URL, d as relativeToInstallDir, g as SIGNUP_WIZARD_READINESS_CONFIG, j as GITHUB_SKILLS_BASE_URL, l as WIZARD_LOG_FILE, p as setUI, q as POSTHOG_PRIVACY_URL, s as logToFile, v as getBlockingServiceKeys, z as Integration } from "./debug-ECdmmlDM.js";
3
- import { t as ADDITIONAL_FEATURE_LABELS } from "./wizard-session-GdDN_aMS.js";
4
- import { n as analytics } from "./analytics-DZNb3aRN.js";
5
- import { n as openTrackedLink } from "./telemetry-CPWHrsXK.js";
6
- import { i as readProjectFile, t as IGNORED_DIRS } from "./bounded-fs-CErPpkN2.js";
7
- import { o as extractOAuthCode, t as getOrAskForProjectData } from "./setup-utils-CCphwDIz.js";
8
- import { c as getIntegrationAuthorizeUrl, i as requestDeepLink } from "./provisioning-BewSEuFX.js";
9
- import { r as fetchGithubConnected, t as ApiError } from "./api-DXGaiK94.js";
10
- import { i as wizardAbort } from "./wizard-abort-RUnY1Dax.js";
11
- import { N as downloadSkill, P as fetchSkillMenu } from "./agent-interface-CK6pmvkF.js";
12
- import { a as formatCostUsd, f as getDetectedWarehouseSources, m as detectProjectsWithAgent, o as formatTokenCount } from "./agent-runner-jz4yiJfh.js";
13
- import { t as FRAMEWORK_REGISTRY } from "./registry-Bt2Mc4vC.js";
14
- import { _ as AUDIT_CHECKS_KEY, b as coerceAuditChecks, g as AUDIT_CHECKS_FILE, x as getAuditChecks, y as AUDIT_SEVERITY_STYLE } from "./yara-hooks-jBqAkgxw.js";
15
- import { h as Icons, m as Colors, t as SETUP_REPORT_FILE } from "./posthog-integration-CxvkKY1j.js";
16
- import { A as fetchHealthIssues, C as DISPLAY_NAME, E as MANUAL_SDK_VARIANTS, M as POSTHOG_SDKS, N as STRIPE_SDKS, O as SOURCE_MAPS_CONTEXT_KEYS, S as AUTOMATABLE_VARIANTS, T as MANUAL_SDK_INSTALL, _ as PRICING_SHORT, a as useStdoutDimensions, b as GITHUB_REQUIRED_MESSAGE, g as PRICING_LONG, h as NO_DEFAULT_LIMIT, j as getContentBlocks, m as getProgramConfig, n as useKeyBindings, p as Program, t as PickerMenu, v as detectSelfDrivingIntegrationProjects, x as SELF_DRIVING_INTEGRATE_PATH_KEY, y as GITHUB_REQUIRED_BODY } from "./bin.js";
17
- import { r as totalTokenCount, t as WizardStore } from "./store-BhcCTIn4.js";
18
- import { B as SplitView, C as VisualizerTab, D as HNViewer, F as ModalOverlay, I as ConfirmationInput, M as LogViewer, N as LinkText, O as TabContainer, P as extractUrls, R as ProgressList, S as ServiceHealthList, T as LearnCard, a as useSkillEntry, b as SEVERITY_LABEL, c as SlackConnectScreen, d as AuditChecksViewer, f as seedDemoEvents, g as probeProjectData, i as SkillSourceInfo, j as EventPlanViewer, k as ScreenContainer, l as AUDIT_AREA_SLIDES, m as McpSuggestedPromptsScreen, n as releaseTerminal, o as OutroScreen, r as AiOptInRequiredScreen, s as useDismissOnAnyKey, t as enterDarkTerminal, u as VisualBox, v as McpScreen, w as TipsCard, x as SEVERITY_ORDER, y as IssueTable, z as LoadingBox } from "./terminal-CpVFsbGu.js";
19
- import { c as namesWithStatus, d as toClientResult, l as redactSecrets, t as ALL_FEATURE_VALUES } from "./defaults-DI642M3n.js";
20
- import { t as startFileWatcher } from "./file-watcher-BNdFPlI8.js";
21
- 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-BtWwRG7O.js";
2
+ import { B as Integration, G as POSTHOG_DOCS_URL, H as OAUTH_TIMEOUT_MS, J as POSTHOG_PRIVACY_URL, M as GITHUB_SKILLS_BASE_URL, V as OAUTH_PORTS, Z as POSTHOG_TERMS_URL, a as getLogFilePath, d as relativeToInstallDir, g as SIGNUP_WIZARD_READINESS_CONFIG, l as WIZARD_LOG_FILE, p as setUI, pt as getSkillsBaseUrl, q as POSTHOG_ORG_AI_SETTINGS_URL, s as logToFile, v as getBlockingServiceKeys } from "./debug-DUmMVUHn.js";
3
+ import { t as ADDITIONAL_FEATURE_LABELS } from "./wizard-session-FSJCkTcP.js";
4
+ import { n as analytics } from "./analytics-DSK0GXg1.js";
5
+ import { n as openTrackedLink } from "./telemetry-QpeVhVtU.js";
6
+ import { i as readProjectFile, t as IGNORED_DIRS } from "./bounded-fs-D85Tk3nS.js";
7
+ import { o as extractOAuthCode, t as getOrAskForProjectData } from "./setup-utils-C3tsa6D6.js";
8
+ import { c as getIntegrationAuthorizeUrl, i as requestDeepLink } from "./provisioning-B74q1uSQ.js";
9
+ import { r as fetchGithubConnected, t as ApiError } from "./api-CwNulLDK.js";
10
+ import { i as wizardAbort } from "./wizard-abort-B0c5VDie.js";
11
+ import { F as downloadSkill, L as fetchSkillMenu } from "./agent-interface-BKLTDSyN.js";
12
+ import { _ as detectProjectsWithAgent, a as formatCostUsd, d as STRIPE_SDKS, h as getDetectedWarehouseSources, o as formatTokenCount, u as POSTHOG_SDKS } from "./agent-runner-BkQontri.js";
13
+ import { t as FRAMEWORK_REGISTRY } from "./registry-DZoReEU3.js";
14
+ import { _ as AUDIT_CHECKS_KEY, b as coerceAuditChecks, g as AUDIT_CHECKS_FILE, x as getAuditChecks, y as AUDIT_SEVERITY_STYLE } from "./yara-hooks-uCiAIcqU.js";
15
+ import { C as ERROR_TRACKING_PROJECT_PATH_KEY, F as MANUAL_SDK_INSTALL, I as MANUAL_SDK_VARIANTS, J as getContentBlocks, M as AUTOMATABLE_VARIANTS, N as DISPLAY_NAME, R as SOURCE_MAPS_CONTEXT_KEYS, U as fetchHealthIssues, Y as SETUP_REPORT_FILE, _ as PRICING_SHORT, b as GITHUB_REQUIRED_MESSAGE, c as getCommandPath, g as PRICING_LONG, h as NO_DEFAULT_LIMIT, i as isRunFailure, it as Icons, l as getLaunchablePrograms, n as MINT_FAILURE_CONTACT, o as Program, r as MINT_FAILURE_MESSAGE, rt as Colors, t as MINT_FAILURE_BODY, u as getProgramConfig, v as detectSelfDrivingIntegrationProjects, w as detectErrorTrackingProjects, x as SELF_DRIVING_INTEGRATE_PATH_KEY, y as GITHUB_REQUIRED_BODY } from "./mint-failure-CQqypC_v.js";
16
+ import { a as useStdoutDimensions, n as useKeyBindings, t as PickerMenu } from "./bin.js";
17
+ import { r as totalTokenCount, t as WizardStore } from "./store-DN_6FaoQ.js";
18
+ import { B as SplitView, C as VisualizerTab, D as HNViewer, F as ModalOverlay, I as ConfirmationInput, M as LogViewer, N as LinkText, O as TabContainer, P as extractUrls, R as ProgressList, S as ServiceHealthList, T as LearnCard, a as useSkillEntry, b as SEVERITY_LABEL, c as SlackConnectScreen, d as AuditChecksViewer, f as seedDemoEvents, g as probeProjectData, i as SkillSourceInfo, j as EventPlanViewer, k as ScreenContainer, l as AUDIT_AREA_SLIDES, m as McpSuggestedPromptsScreen, n as releaseTerminal, o as OutroScreen, r as AiOptInRequiredScreen, s as useDismissOnAnyKey, t as enterDarkTerminal, u as VisualBox, v as McpScreen, w as TipsCard, x as SEVERITY_ORDER, y as IssueTable, z as LoadingBox } from "./terminal-dLoYiXsd.js";
19
+ import { c as namesWithStatus, d as toClientResult, l as redactSecrets, t as ALL_FEATURE_VALUES } from "./defaults-DDDwYTN5.js";
20
+ import { t as startFileWatcher } from "./file-watcher-hafFFQib.js";
21
+ 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-CjfnPMbO.js";
22
22
  import { existsSync, readFileSync, readdirSync } from "fs";
23
23
  import path, { join } from "path";
24
- import { join as join$1 } from "node:path";
24
+ import { tmpdir } from "node:os";
25
+ import path$1, { join as join$1 } from "node:path";
25
26
  import { spawn } from "node:child_process";
27
+ import { constants } from "node:fs";
28
+ import fs$1 from "fs/promises";
26
29
  import { Box, Text, render, useInput } from "ink";
27
30
  import { Fragment, createElement, useEffect, useMemo, useRef, useState, useSyncExternalStore } from "react";
28
31
  import { Fragment as Fragment$1, jsx, jsxs } from "react/jsx-runtime";
29
- import { access, readdir, rm } from "node:fs/promises";
30
- import { Spinner, TextInput } from "@inkjs/ui";
32
+ import { access, mkdtemp, readdir, rm, writeFile } from "node:fs/promises";
33
+ import { PasswordInput, Spinner, TextInput } from "@inkjs/ui";
31
34
  //#region src/ui/tui/ink-ui.ts
32
35
  const ANSI_RE = /\x1b\[[0-9;]*m/g;
33
36
  function stripAnsi(s) {
@@ -1009,6 +1012,20 @@ const PrivacyPanel = ({ canOptOut = false } = {}) => {
1009
1012
  * children — between detection rows and menu (extra info, warnings)
1010
1013
  * errorView — replaces the entire body for fatal error states
1011
1014
  */
1015
+ /** Pads to the widest label passed, so every tick lands in one column. */
1016
+ function detectionLabelWidth(rows) {
1017
+ return Math.max(9, ...(rows ?? []).map((row) => row.label.length));
1018
+ }
1019
+ const DetectionLine = ({ label, width, children }) => /* @__PURE__ */ jsxs(Text, { children: [
1020
+ label.padEnd(width),
1021
+ " ",
1022
+ /* @__PURE__ */ jsx(Text, {
1023
+ color: "green",
1024
+ children: "✔"
1025
+ }),
1026
+ " ",
1027
+ /* @__PURE__ */ jsx(Text, { children })
1028
+ ] });
1012
1029
  const WizardTitle = ({ title }) => /* @__PURE__ */ jsxs(Text, {
1013
1030
  bold: true,
1014
1031
  children: [
@@ -1082,6 +1099,7 @@ const IntroScreenLayout = ({ installDir, title = "PostHog Wizard 🦔", showSubt
1082
1099
  showingPrivacy,
1083
1100
  privacyOptions
1084
1101
  });
1102
+ const labelWidth = detectionLabelWidth(detectionRows);
1085
1103
  const handleSelect = (value) => {
1086
1104
  if (value === "privacy") return setShowingPrivacy(true);
1087
1105
  if (value === "privacy-back") return setShowingPrivacy(false);
@@ -1134,43 +1152,26 @@ const IntroScreenLayout = ({ installDir, title = "PostHog Wizard 🦔", showSubt
1134
1152
  flexDirection: "column",
1135
1153
  marginTop: 1,
1136
1154
  children: [
1137
- /* @__PURE__ */ jsxs(Text, { children: [/* @__PURE__ */ jsxs(Text, { children: [
1138
- "Directory ",
1139
- /* @__PURE__ */ jsx(Text, {
1140
- color: "green",
1141
- children: "✔"
1142
- }),
1143
- " "
1144
- ] }), /* @__PURE__ */ jsxs(Text, { children: ["/", path.basename(installDir)] })] }),
1145
- detectionRows?.map((row) => /* @__PURE__ */ jsxs(Text, { children: [/* @__PURE__ */ jsxs(Text, { children: [
1146
- row.label,
1147
- " ",
1148
- /* @__PURE__ */ jsx(Text, {
1149
- color: "green",
1150
- children: "✔"
1151
- }),
1152
- " "
1153
- ] }), /* @__PURE__ */ jsxs(Text, { children: [row.value, row.suffix ? ` ${row.suffix}` : ""] })] }, row.label)),
1154
- programLabel && /* @__PURE__ */ jsxs(Text, { children: [
1155
- "Program",
1156
- " ",
1157
- /* @__PURE__ */ jsx(Text, {
1158
- color: "green",
1159
- children: "✔"
1160
- }),
1161
- " ",
1162
- programLabel
1163
- ] }),
1164
- programLabel === "agent-skill" && skillId && /* @__PURE__ */ jsxs(Text, { children: [
1165
- "Skill",
1166
- " ",
1167
- /* @__PURE__ */ jsx(Text, {
1168
- color: "green",
1169
- children: "✔"
1170
- }),
1171
- " ",
1172
- skillId
1173
- ] })
1155
+ /* @__PURE__ */ jsxs(DetectionLine, {
1156
+ label: "Directory",
1157
+ width: labelWidth,
1158
+ children: ["/", path.basename(installDir)]
1159
+ }),
1160
+ detectionRows?.map((row) => /* @__PURE__ */ jsxs(DetectionLine, {
1161
+ label: row.label,
1162
+ width: labelWidth,
1163
+ children: [row.value, row.suffix ? ` ${row.suffix}` : ""]
1164
+ }, row.label)),
1165
+ programLabel && /* @__PURE__ */ jsx(DetectionLine, {
1166
+ label: "Program",
1167
+ width: labelWidth,
1168
+ children: programLabel
1169
+ }),
1170
+ programLabel === "agent-skill" && skillId && /* @__PURE__ */ jsx(DetectionLine, {
1171
+ label: "Skill",
1172
+ width: labelWidth,
1173
+ children: skillId
1174
+ })
1174
1175
  ]
1175
1176
  }),
1176
1177
  /* @__PURE__ */ jsx(Box, {
@@ -1190,6 +1191,45 @@ const IntroScreenLayout = ({ installDir, title = "PostHog Wizard 🦔", showSubt
1190
1191
  }) });
1191
1192
  };
1192
1193
  //#endregion
1194
+ //#region src/ui/tui/posthog-integration-intro.ts
1195
+ const CONTINUE_LABEL = "Continue";
1196
+ const CONTINUE_ANYWAY_LABEL = "Continue anyway";
1197
+ const DEFAULT_HEADLINE = "Let's do two hours of work in eight minutes.";
1198
+ const DETECTED_HEADLINE = ["It looks like PostHog is already installed. The Wizard has many tricks up its sleeve, like auditing, uploading source maps, or making your product self-drive.", "You can still rerun the installation, but it might overwrite some of your work."];
1199
+ function introHeadline(posthogSdkDetected) {
1200
+ return posthogSdkDetected ? DETECTED_HEADLINE : [DEFAULT_HEADLINE];
1201
+ }
1202
+ function introMenuOptions({ view, showContinue, posthogSdkDetected }) {
1203
+ if (view === "commands") return null;
1204
+ if (view === "more-info") return [{
1205
+ label: "Back",
1206
+ value: "back"
1207
+ }];
1208
+ if (showContinue) return [
1209
+ ...posthogSdkDetected ? [{
1210
+ label: "Explore spell book",
1211
+ value: "commands"
1212
+ }] : [],
1213
+ {
1214
+ label: posthogSdkDetected ? CONTINUE_ANYWAY_LABEL : CONTINUE_LABEL,
1215
+ value: "continue"
1216
+ },
1217
+ {
1218
+ label: "Change framework",
1219
+ value: "framework"
1220
+ },
1221
+ {
1222
+ label: "More info",
1223
+ value: "more-info"
1224
+ },
1225
+ {
1226
+ label: "Cancel",
1227
+ value: "cancel"
1228
+ }
1229
+ ];
1230
+ return null;
1231
+ }
1232
+ //#endregion
1193
1233
  //#region src/ui/tui/screens/PostHogIntegrationIntroScreen.tsx
1194
1234
  /**
1195
1235
  * PostHogIntegrationIntroScreen — Intro screen for the core PostHog integration.
@@ -1226,29 +1266,6 @@ const SUBTITLE = /* @__PURE__ */ jsxs(Fragment$1, { children: [
1226
1266
  })
1227
1267
  ] });
1228
1268
  /**
1229
- * Exported so a test can measure every label against the menu's column.
1230
- * `Privacy & data` is not here: IntroScreenLayout appends it to every intro
1231
- * menu, so no screen carries its own copy.
1232
- */
1233
- const CONTINUE_MENU_OPTIONS = [
1234
- {
1235
- label: "Continue",
1236
- value: "continue"
1237
- },
1238
- {
1239
- label: "Change framework",
1240
- value: "framework"
1241
- },
1242
- {
1243
- label: "More info",
1244
- value: "more-info"
1245
- },
1246
- {
1247
- label: "Cancel",
1248
- value: "cancel"
1249
- }
1250
- ];
1251
- /**
1252
1269
  * A blank, unselectable row. Navigation skips disabled options, so this is a
1253
1270
  * margin the menu can hold rather than one the layout has to special-case.
1254
1271
  */
@@ -1293,7 +1310,7 @@ const FrameworkPicker = ({ store, onComplete }) => {
1293
1310
  })),
1294
1311
  onSelect: (value) => {
1295
1312
  const integration = Array.isArray(value) ? value[0] : value;
1296
- import("./registry-Bt2Mc4vC.js").then((n) => n.n).then(({ FRAMEWORK_REGISTRY }) => {
1313
+ import("./registry-DZoReEU3.js").then((n) => n.n).then(({ FRAMEWORK_REGISTRY }) => {
1297
1314
  const config = FRAMEWORK_REGISTRY[integration];
1298
1315
  store.setFrameworkConfig(integration, config);
1299
1316
  store.setDetectedFramework(config.metadata.name);
@@ -1316,6 +1333,12 @@ const PostHogIntegrationIntroScreen = ({ store }) => {
1316
1333
  const needsFrameworkPick = session.detectionComplete && !session.frameworkConfig;
1317
1334
  const unsupported = session.unsupportedVersion;
1318
1335
  const showContinue = session.frameworkConfig !== null && !detecting && !pickingFramework && view === "default" && !unsupported;
1336
+ useKeyBindings("posthog-integration-intro", view === "commands" ? [{
1337
+ match: "escape",
1338
+ label: "esc",
1339
+ action: "back",
1340
+ handler: () => setView("default")
1341
+ }] : []);
1319
1342
  const title = detecting ? "PostHog Wizard starting up" : "PostHog Wizard 🦔";
1320
1343
  let body = null;
1321
1344
  if (detecting) body = /* @__PURE__ */ jsx(Box, {
@@ -1385,7 +1408,34 @@ const PostHogIntegrationIntroScreen = ({ store }) => {
1385
1408
  })
1386
1409
  ]
1387
1410
  });
1388
- else if (showContinue) body = /* @__PURE__ */ jsx(Box, { children: /* @__PURE__ */ jsx(Text, { children: "Let's do two hours of work in eight minutes." }) });
1411
+ else if (view === "commands") body = /* @__PURE__ */ jsx(PickerMenu, {
1412
+ message: "The Wizard can do more than integrate with your project:",
1413
+ options: getLaunchablePrograms().map((program) => ({
1414
+ label: `${getCommandPath(program).padEnd(21)}${program.description}`,
1415
+ value: program.id
1416
+ })),
1417
+ onSelect: (value) => {
1418
+ const id = Array.isArray(value) ? value[0] : value;
1419
+ analytics.wizardCapture("intro menu selected", {
1420
+ value: id,
1421
+ view
1422
+ });
1423
+ store.switchProgram(id);
1424
+ }
1425
+ });
1426
+ else if (showContinue) {
1427
+ const paragraphs = introHeadline(session.posthogSdkDetected);
1428
+ body = /* @__PURE__ */ jsx(Box, {
1429
+ flexDirection: "column",
1430
+ width: 64,
1431
+ flexShrink: 0,
1432
+ alignItems: paragraphs.length > 1 ? void 0 : "center",
1433
+ children: paragraphs.map((paragraph, i) => /* @__PURE__ */ jsx(Box, {
1434
+ marginTop: i === 0 ? 0 : 1,
1435
+ children: /* @__PURE__ */ jsx(Text, { children: paragraph })
1436
+ }, paragraph))
1437
+ });
1438
+ }
1389
1439
  const detectionRows = [];
1390
1440
  if (frameworkLabel) {
1391
1441
  const suffixParts = [];
@@ -1397,6 +1447,10 @@ const PostHogIntegrationIntroScreen = ({ store }) => {
1397
1447
  suffix: suffixParts.join(" ") || void 0
1398
1448
  });
1399
1449
  }
1450
+ if (session.posthogSdkDetected) detectionRows.push({
1451
+ label: "PostHog",
1452
+ value: "detected in package.json"
1453
+ });
1400
1454
  let bodyChildren = null;
1401
1455
  if (config?.metadata.preRunNotice) bodyChildren = /* @__PURE__ */ jsx(Text, {
1402
1456
  color: "yellow",
@@ -1444,12 +1498,11 @@ const PostHogIntegrationIntroScreen = ({ store }) => {
1444
1498
  })
1445
1499
  ]
1446
1500
  });
1447
- let menuOptions = null;
1448
- if (view === "more-info") menuOptions = [{
1449
- label: "Back",
1450
- value: "back"
1451
- }];
1452
- else if (showContinue) menuOptions = CONTINUE_MENU_OPTIONS;
1501
+ const menuOptions = introMenuOptions({
1502
+ view,
1503
+ showContinue,
1504
+ posthogSdkDetected: session.posthogSdkDetected
1505
+ });
1453
1506
  const handleSelect = (value) => {
1454
1507
  analytics.wizardCapture("intro menu selected", {
1455
1508
  value,
@@ -1460,6 +1513,7 @@ const PostHogIntegrationIntroScreen = ({ store }) => {
1460
1513
  setPickingFramework(true);
1461
1514
  setManuallySelected(true);
1462
1515
  } else if (value === "more-info") setView("more-info");
1516
+ else if (value === "commands") setView("commands");
1463
1517
  else if (value === "back") setView("default");
1464
1518
  else if (value === "share") store.grantSharing();
1465
1519
  else if (value === "no-share") store.declineSharing();
@@ -2286,9 +2340,9 @@ async function detectSourceMapsProjects(session, onEvent) {
2286
2340
  *
2287
2341
  * Runs after auth — the detection agent needs credentials.
2288
2342
  */
2289
- const EXIT = "__exit";
2290
- const MAX_ACTIVITY_LINES$1 = 8;
2291
- function projectLabel$1(p) {
2343
+ const EXIT$1 = "__exit";
2344
+ const MAX_ACTIVITY_LINES$2 = 8;
2345
+ function projectLabel$2(p) {
2292
2346
  const name = p.variant ? DISPLAY_NAME[p.variant] : p.framework;
2293
2347
  const where = p.path === "." ? "repo root" : p.path;
2294
2348
  return `${name} ${Icons.bullet} ${where}`;
@@ -2307,7 +2361,7 @@ const SourceMapsDetectScreen = ({ store }) => {
2307
2361
  (async () => {
2308
2362
  try {
2309
2363
  const report = await detectSourceMapsProjects(store.session, (line) => {
2310
- if (!cancelled) setActivity((prev) => [...prev, line].slice(-MAX_ACTIVITY_LINES$1));
2364
+ if (!cancelled) setActivity((prev) => [...prev, line].slice(-MAX_ACTIVITY_LINES$2));
2311
2365
  });
2312
2366
  if (!cancelled) setState({
2313
2367
  kind: "ready",
@@ -2371,7 +2425,7 @@ const SourceMapsDetectScreen = ({ store }) => {
2371
2425
  }), /* @__PURE__ */ jsx(PickerMenu, {
2372
2426
  options: [{
2373
2427
  label: "Exit",
2374
- value: EXIT
2428
+ value: EXIT$1
2375
2429
  }],
2376
2430
  onSelect: () => process.exit(1)
2377
2431
  })]
@@ -2404,7 +2458,7 @@ const SourceMapsDetectScreen = ({ store }) => {
2404
2458
  children: /* @__PURE__ */ jsx(PickerMenu, {
2405
2459
  options: [{
2406
2460
  label: "Exit",
2407
- value: EXIT
2461
+ value: EXIT$1
2408
2462
  }],
2409
2463
  onSelect: () => process.exit(0)
2410
2464
  })
@@ -2412,11 +2466,11 @@ const SourceMapsDetectScreen = ({ store }) => {
2412
2466
  ]
2413
2467
  });
2414
2468
  const options = [...instrumentable.map((p) => ({
2415
- label: projectLabel$1(p),
2469
+ label: projectLabel$2(p),
2416
2470
  value: p.path
2417
2471
  })), {
2418
2472
  label: "Cancel",
2419
- value: EXIT
2473
+ value: EXIT$1
2420
2474
  }];
2421
2475
  return /* @__PURE__ */ jsxs(Box, {
2422
2476
  flexDirection: "column",
@@ -2440,7 +2494,7 @@ const SourceMapsDetectScreen = ({ store }) => {
2440
2494
  options,
2441
2495
  onSelect: (value) => {
2442
2496
  const path = Array.isArray(value) ? value[0] : value;
2443
- if (path === EXIT) {
2497
+ if (path === EXIT$1) {
2444
2498
  process.exit(0);
2445
2499
  return;
2446
2500
  }
@@ -2906,6 +2960,266 @@ const MetricsIntroScreen = ({ store }) => {
2906
2960
  });
2907
2961
  };
2908
2962
  //#endregion
2963
+ //#region src/ui/tui/screens/ErrorTrackingIntroScreen.tsx
2964
+ const ErrorTrackingIntroScreen = ({ store }) => {
2965
+ useSyncExternalStore((cb) => store.subscribe(cb), () => store.getSnapshot());
2966
+ const [showingMoreInfo, setShowingMoreInfo] = useState(false);
2967
+ const { session } = store;
2968
+ const skillId = "integration-v2-error-tracking-step";
2969
+ const { skillEntry, fetchFailed } = useSkillEntry(skillId);
2970
+ const body = showingMoreInfo ? /* @__PURE__ */ jsxs(Box, {
2971
+ flexDirection: "column",
2972
+ width: 56,
2973
+ children: [
2974
+ /* @__PURE__ */ jsx(Box, {
2975
+ marginBottom: 1,
2976
+ children: /* @__PURE__ */ jsxs(Text, { children: [
2977
+ "The Wizard is an agent, it's here to help you setup PostHog. Its code is open source:",
2978
+ " ",
2979
+ /* @__PURE__ */ jsx(Text, {
2980
+ color: "cyan",
2981
+ children: "https://github.com/PostHog/wizard"
2982
+ })
2983
+ ] })
2984
+ }),
2985
+ /* @__PURE__ */ jsxs(Text, { children: [
2986
+ "The",
2987
+ " ",
2988
+ /* @__PURE__ */ jsx(Text, {
2989
+ color: "cyan",
2990
+ italic: true,
2991
+ children: "error-tracking"
2992
+ }),
2993
+ " ",
2994
+ "program makes uncaught errors reach PostHog with readable stack traces. It installs and initializes the PostHog, wires up exception capture, and sets up source-map uploading when necessary. In PostHog, you can analyze these errors and have agents proactively suggest fixes in self-driving."
2995
+ ] }),
2996
+ /* @__PURE__ */ jsx(Box, {
2997
+ marginTop: 1,
2998
+ children: /* @__PURE__ */ jsx(SkillSourceInfo, {
2999
+ skillId,
3000
+ skillEntry,
3001
+ fetchFailed
3002
+ })
3003
+ })
3004
+ ]
3005
+ }) : /* @__PURE__ */ jsx(Box, {
3006
+ flexDirection: "column",
3007
+ alignItems: "center",
3008
+ children: /* @__PURE__ */ jsx(Text, { children: "Let's make uncaught errors reach PostHog with readable stack traces." })
3009
+ });
3010
+ const menuOptions = showingMoreInfo ? [{
3011
+ label: "Back",
3012
+ value: "back"
3013
+ }] : [
3014
+ {
3015
+ label: "Continue",
3016
+ value: "continue"
3017
+ },
3018
+ {
3019
+ label: "More info",
3020
+ value: "more-info"
3021
+ },
3022
+ {
3023
+ label: "Cancel",
3024
+ value: "cancel"
3025
+ }
3026
+ ];
3027
+ const handleSelect = (value) => {
3028
+ if (value === "cancel") process.exit(0);
3029
+ else if (value === "more-info") setShowingMoreInfo(true);
3030
+ else if (value === "back") setShowingMoreInfo(false);
3031
+ else store.completeSetup();
3032
+ };
3033
+ return /* @__PURE__ */ jsx(IntroScreenLayout, {
3034
+ installDir: session.installDir,
3035
+ body,
3036
+ showDetection: !showingMoreInfo,
3037
+ programLabel: session.programLabel,
3038
+ skillId: session.skillId,
3039
+ menuOptions,
3040
+ onSelect: handleSelect
3041
+ });
3042
+ };
3043
+ //#endregion
3044
+ //#region src/ui/tui/screens/ErrorTrackingDetectScreen.tsx
3045
+ /**
3046
+ * ErrorTrackingDetectScreen — after login, runs the detection agent over the
3047
+ * repo, streams its progress, and lets the user pick the project to set error
3048
+ * tracking up in. Mirrors the legacy SourceMapsDetectScreen.
3049
+ */
3050
+ const EXIT = "__exit";
3051
+ const MAX_ACTIVITY_LINES$1 = 8;
3052
+ function projectLabel$1(p) {
3053
+ const where = p.path === "." ? "repo root" : p.path;
3054
+ return `${p.framework} ${Icons.bullet} ${where}`;
3055
+ }
3056
+ const ErrorTrackingDetectScreen = ({ store }) => {
3057
+ useSyncExternalStore((cb) => store.subscribe(cb), () => store.getSnapshot());
3058
+ const { credentials } = store.session;
3059
+ const accessToken = credentials?.accessToken;
3060
+ const [state, setState] = useState({ kind: "loading" });
3061
+ const [activity, setActivity] = useState([]);
3062
+ const started = useRef(false);
3063
+ useEffect(() => {
3064
+ if (!accessToken || started.current) return;
3065
+ started.current = true;
3066
+ let cancelled = false;
3067
+ (async () => {
3068
+ try {
3069
+ const report = await detectErrorTrackingProjects(store.session, (line) => {
3070
+ if (!cancelled) setActivity((prev) => [...prev, line].slice(-MAX_ACTIVITY_LINES$1));
3071
+ });
3072
+ if (!cancelled) setState({
3073
+ kind: "ready",
3074
+ report
3075
+ });
3076
+ } catch (err) {
3077
+ if (!cancelled) setState({
3078
+ kind: "error",
3079
+ message: err instanceof Error ? err.message : String(err)
3080
+ });
3081
+ }
3082
+ })();
3083
+ return () => {
3084
+ cancelled = true;
3085
+ };
3086
+ }, [accessToken, store]);
3087
+ if (!credentials) return /* @__PURE__ */ jsx(LoadingBox, { message: "Waiting for authentication..." });
3088
+ if (state.kind === "loading") return /* @__PURE__ */ jsxs(Box, {
3089
+ flexDirection: "column",
3090
+ children: [
3091
+ /* @__PURE__ */ jsx(Text, {
3092
+ bold: true,
3093
+ color: Colors.accent,
3094
+ children: "Detecting your project..."
3095
+ }),
3096
+ /* @__PURE__ */ jsx(Box, {
3097
+ marginY: 1,
3098
+ children: /* @__PURE__ */ jsx(LoadingBox, { message: "Scanning the repo for frameworks and PostHog SDKs..." })
3099
+ }),
3100
+ /* @__PURE__ */ jsx(Box, {
3101
+ flexDirection: "column",
3102
+ children: activity.length === 0 ? /* @__PURE__ */ jsxs(Text, {
3103
+ dimColor: true,
3104
+ children: [" ", "Starting up the detection agent…"]
3105
+ }) : activity.map((line, i) => /* @__PURE__ */ jsxs(Text, {
3106
+ dimColor: i < activity.length - 1,
3107
+ color: i === activity.length - 1 ? Colors.primary : void 0,
3108
+ children: [
3109
+ " ",
3110
+ Icons.triangleSmallRight,
3111
+ " ",
3112
+ line
3113
+ ]
3114
+ }, `${i}-${line}`))
3115
+ })
3116
+ ]
3117
+ });
3118
+ if (state.kind === "error") return /* @__PURE__ */ jsxs(Box, {
3119
+ flexDirection: "column",
3120
+ children: [/* @__PURE__ */ jsxs(Box, {
3121
+ flexDirection: "column",
3122
+ marginY: 1,
3123
+ children: [/* @__PURE__ */ jsxs(Text, {
3124
+ color: Colors.error,
3125
+ bold: true,
3126
+ children: [Icons.squareFilled, " Detection failed"]
3127
+ }), /* @__PURE__ */ jsx(Text, {
3128
+ dimColor: true,
3129
+ children: state.message
3130
+ })]
3131
+ }), /* @__PURE__ */ jsx(PickerMenu, {
3132
+ options: [{
3133
+ label: "Exit",
3134
+ value: EXIT
3135
+ }],
3136
+ onSelect: () => process.exit(1)
3137
+ })]
3138
+ });
3139
+ const { report } = state;
3140
+ const instrumentable = report.projects.filter((p) => p.instrumentable);
3141
+ const unsupported = report.projects.length - instrumentable.length;
3142
+ if (instrumentable.length === 0) return /* @__PURE__ */ jsxs(Box, {
3143
+ flexDirection: "column",
3144
+ children: [/* @__PURE__ */ jsxs(Box, {
3145
+ flexDirection: "column",
3146
+ marginBottom: 1,
3147
+ children: [/* @__PURE__ */ jsxs(Text, {
3148
+ color: Colors.error,
3149
+ bold: true,
3150
+ children: [Icons.squareFilled, " Nothing to set up here"]
3151
+ }), /* @__PURE__ */ jsxs(Text, {
3152
+ dimColor: true,
3153
+ children: [
3154
+ "None of the ",
3155
+ report.projects.length,
3156
+ " projects found uses a framework the wizard can set up error tracking for."
3157
+ ]
3158
+ })]
3159
+ }), /* @__PURE__ */ jsx(PickerMenu, {
3160
+ options: [{
3161
+ label: "Exit",
3162
+ value: EXIT
3163
+ }],
3164
+ onSelect: () => process.exit(0)
3165
+ })]
3166
+ });
3167
+ const options = [...instrumentable.map((p) => ({
3168
+ label: projectLabel$1(p),
3169
+ value: p.path
3170
+ })), {
3171
+ label: "Cancel",
3172
+ value: EXIT
3173
+ }];
3174
+ return /* @__PURE__ */ jsxs(Box, {
3175
+ flexDirection: "column",
3176
+ children: [
3177
+ /* @__PURE__ */ jsx(Box, {
3178
+ flexDirection: "column",
3179
+ marginBottom: 1,
3180
+ children: /* @__PURE__ */ jsxs(Text, {
3181
+ bold: true,
3182
+ color: Colors.accent,
3183
+ children: [
3184
+ Icons.check,
3185
+ " Found",
3186
+ " ",
3187
+ report.repoType === "monorepo" ? "a monorepo" : "your project"
3188
+ ]
3189
+ })
3190
+ }),
3191
+ /* @__PURE__ */ jsx(PickerMenu, {
3192
+ message: "Which project would you like to set up error tracking for?",
3193
+ options,
3194
+ onSelect: (value) => {
3195
+ const path = Array.isArray(value) ? value[0] : value;
3196
+ if (path === EXIT) {
3197
+ process.exit(0);
3198
+ return;
3199
+ }
3200
+ const chosen = instrumentable.find((p) => p.path === path);
3201
+ if (!chosen?.integration) return;
3202
+ store.setFrameworkContext(ERROR_TRACKING_PROJECT_PATH_KEY, chosen.path);
3203
+ store.setFrameworkConfig(chosen.integration, FRAMEWORK_REGISTRY[chosen.integration]);
3204
+ }
3205
+ }),
3206
+ unsupported > 0 && /* @__PURE__ */ jsx(Box, {
3207
+ marginTop: 1,
3208
+ children: /* @__PURE__ */ jsxs(Text, {
3209
+ dimColor: true,
3210
+ children: [
3211
+ "(… ",
3212
+ unsupported,
3213
+ " other project",
3214
+ unsupported === 1 ? "" : "s",
3215
+ " not supported)"
3216
+ ]
3217
+ })
3218
+ })
3219
+ ]
3220
+ });
3221
+ };
3222
+ //#endregion
2909
3223
  //#region src/ui/tui/screens/SelfDrivingIntroScreen.tsx
2910
3224
  /**
2911
3225
  * SelfDrivingIntroScreen — Welcome screen for the self-driving flow.
@@ -5313,19 +5627,23 @@ const KeepSkillsScreen = ({ store }) => {
5313
5627
  }
5314
5628
  if (result.length === 0) {
5315
5629
  store.setSkillsComplete(true);
5316
- process.exit(0);
5630
+ exit();
5631
+ return;
5317
5632
  }
5318
5633
  setSkills(result);
5319
5634
  setPhase("ask");
5320
5635
  } catch {
5321
5636
  store.setSkillsComplete(true);
5322
- process.exit(0);
5637
+ exit();
5323
5638
  }
5324
5639
  })();
5325
5640
  }, []);
5641
+ const exit = () => {
5642
+ if (!store.session.mintHandoff) process.exit(0);
5643
+ };
5326
5644
  const handleKeep = () => {
5327
5645
  store.setSkillsComplete(true);
5328
- process.exit(0);
5646
+ exit();
5329
5647
  };
5330
5648
  const handleRemove = async () => {
5331
5649
  setPhase("removing");
@@ -5344,7 +5662,7 @@ const KeepSkillsScreen = ({ store }) => {
5344
5662
  setPhase("done");
5345
5663
  setTimeout(() => {
5346
5664
  store.setSkillsComplete(false);
5347
- process.exit(0);
5665
+ exit();
5348
5666
  }, 600);
5349
5667
  };
5350
5668
  return /* @__PURE__ */ jsxs(Box, {
@@ -5430,6 +5748,340 @@ const KeepSkillsScreen = ({ store }) => {
5430
5748
  });
5431
5749
  };
5432
5750
  //#endregion
5751
+ //#region src/ui/tui/screens/MintFailureScreen.tsx
5752
+ /** Two blocks of the PostHog flag, left of the headline. */
5753
+ const Mark = () => /* @__PURE__ */ jsxs(Text, { children: [/* @__PURE__ */ jsx(Text, {
5754
+ color: "#1D4AFF",
5755
+ children: "█"
5756
+ }), /* @__PURE__ */ jsx(Text, {
5757
+ color: Colors.accent,
5758
+ children: "█"
5759
+ })] });
5760
+ function MintFailureScreen({ store, services }) {
5761
+ const [columns] = useStdoutDimensions();
5762
+ useSyncExternalStore((cb) => store.subscribe(cb), () => store.getSnapshot());
5763
+ const busy = useRef(false);
5764
+ const [working, setWorking] = useState(null);
5765
+ const [error, setError] = useState(null);
5766
+ const [report, setReport] = useState(false);
5767
+ const [retry, setRetry] = useState("save");
5768
+ const { spellbook } = store.session;
5769
+ const select = async (action) => {
5770
+ if (busy.current) return;
5771
+ if (action === "exit" || action === "continue") return store.setMintHandoff(action);
5772
+ if (action === "report") return setReport(true);
5773
+ const task = action === "retry" ? retry : action;
5774
+ setRetry(task);
5775
+ busy.current = true;
5776
+ setError(null);
5777
+ setWorking("Saving skill...");
5778
+ try {
5779
+ const saved = store.session.spellbook ?? await services.leaveSpellbook();
5780
+ store.setSpellbook(saved);
5781
+ if (task !== "save") {
5782
+ setWorking(`Opening ${task === "claude" ? "Claude Code" : "Codex"}...`);
5783
+ await services.openAgent(task, saved.path);
5784
+ store.setMintHandoff("continue");
5785
+ }
5786
+ } catch (err) {
5787
+ setError(store.session.spellbook ? err instanceof Error ? err.message : "Could not open your agent." : "Could not save the skill. Check this folder is writable and try again.");
5788
+ } finally {
5789
+ busy.current = false;
5790
+ setWorking(null);
5791
+ }
5792
+ };
5793
+ const options = error ? [
5794
+ {
5795
+ label: "Try again",
5796
+ value: "retry"
5797
+ },
5798
+ ...spellbook ? [{
5799
+ label: "Continue setup",
5800
+ value: "continue"
5801
+ }] : [],
5802
+ {
5803
+ label: "Exit",
5804
+ value: "exit"
5805
+ }
5806
+ ] : spellbook ? [{
5807
+ label: "Continue",
5808
+ value: "continue"
5809
+ }, {
5810
+ label: "Exit",
5811
+ value: "exit"
5812
+ }] : report ? [{
5813
+ label: "Save skill",
5814
+ value: "save"
5815
+ }, {
5816
+ label: "Exit",
5817
+ value: "exit"
5818
+ }] : [
5819
+ {
5820
+ label: "Save skill",
5821
+ value: "save"
5822
+ },
5823
+ {
5824
+ label: "Open in Claude Code",
5825
+ value: "claude"
5826
+ },
5827
+ {
5828
+ label: "Open in Codex",
5829
+ value: "codex"
5830
+ },
5831
+ {
5832
+ label: "Report this issue",
5833
+ value: "report"
5834
+ },
5835
+ {
5836
+ label: "Exit",
5837
+ value: "exit"
5838
+ }
5839
+ ];
5840
+ return /* @__PURE__ */ jsx(Box, {
5841
+ flexDirection: "column",
5842
+ flexGrow: 1,
5843
+ alignItems: "center",
5844
+ justifyContent: "center",
5845
+ children: /* @__PURE__ */ jsxs(Box, {
5846
+ width: Math.max(1, Math.min(78, columns - 4)),
5847
+ flexDirection: "column",
5848
+ alignItems: "center",
5849
+ children: [
5850
+ /* @__PURE__ */ jsxs(Text, {
5851
+ bold: true,
5852
+ children: [
5853
+ /* @__PURE__ */ jsx(Mark, {}),
5854
+ " ",
5855
+ spellbook ? "Skill saved" : MINT_FAILURE_MESSAGE,
5856
+ " 🦔"
5857
+ ]
5858
+ }),
5859
+ /* @__PURE__ */ jsx(Box, {
5860
+ marginTop: 1,
5861
+ children: /* @__PURE__ */ jsx(Text, { children: spellbook ? spellbook.skillsIncluded ? "Ask your agent to read this file and complete the task." : "The skill could not be downloaded. This file has instructions and links for your agent." : report ? MINT_FAILURE_CONTACT : MINT_FAILURE_BODY })
5862
+ }),
5863
+ report && !spellbook && /* @__PURE__ */ jsx(Box, {
5864
+ marginTop: 1,
5865
+ children: /* @__PURE__ */ jsx(Text, {
5866
+ color: "cyan",
5867
+ wrap: "wrap",
5868
+ children: services.logPath
5869
+ })
5870
+ }),
5871
+ spellbook && /* @__PURE__ */ jsx(Box, {
5872
+ marginTop: 1,
5873
+ children: /* @__PURE__ */ jsx(Text, {
5874
+ color: "cyan",
5875
+ wrap: "wrap",
5876
+ children: spellbook.path
5877
+ })
5878
+ }),
5879
+ error && /* @__PURE__ */ jsx(Box, {
5880
+ marginTop: 1,
5881
+ children: /* @__PURE__ */ jsx(Text, {
5882
+ color: Colors.error,
5883
+ children: error
5884
+ })
5885
+ }),
5886
+ /* @__PURE__ */ jsx(Box, {
5887
+ marginTop: 1,
5888
+ flexDirection: "column",
5889
+ children: working ? /* @__PURE__ */ jsx(Text, { children: working }) : /* @__PURE__ */ jsx(PickerMenu, {
5890
+ options,
5891
+ onSelect: (action) => void select(action)
5892
+ }, [
5893
+ report,
5894
+ Boolean(spellbook),
5895
+ Boolean(error)
5896
+ ].join("-"))
5897
+ })
5898
+ ]
5899
+ })
5900
+ });
5901
+ }
5902
+ //#endregion
5903
+ //#region src/ui/tui/services/coding-agent-launcher.ts
5904
+ const quote = (value) => `'${value.replace(/'/g, `'"'"'`)}'`;
5905
+ const batchQuote = (value) => `"${value.replace(/%/g, "%%")}"`;
5906
+ async function executable(name) {
5907
+ const extensions = process.platform === "win32" ? [
5908
+ ".exe",
5909
+ ".cmd",
5910
+ ".bat"
5911
+ ] : [""];
5912
+ for (const directory of (process.env.PATH ?? "").split(path$1.delimiter)) {
5913
+ if (!path$1.isAbsolute(directory)) continue;
5914
+ for (const extension of extensions) {
5915
+ const candidate = path$1.join(directory, name + extension);
5916
+ try {
5917
+ await access(candidate, constants.X_OK);
5918
+ return candidate;
5919
+ } catch {
5920
+ continue;
5921
+ }
5922
+ }
5923
+ }
5924
+ throw new Error(`${name === "claude" ? "Claude Code" : name === "codex" ? "Codex" : name} is not installed or could not be found.`);
5925
+ }
5926
+ function launch(command, args, cwd, verbatim = false) {
5927
+ return new Promise((resolve, reject) => {
5928
+ const child = spawn(command, args, {
5929
+ cwd,
5930
+ stdio: "ignore",
5931
+ detached: true,
5932
+ shell: false,
5933
+ windowsVerbatimArguments: verbatim
5934
+ });
5935
+ const timer = setTimeout(() => {
5936
+ child.unref();
5937
+ resolve();
5938
+ }, 500);
5939
+ child.once("error", (error) => {
5940
+ clearTimeout(timer);
5941
+ reject(error);
5942
+ });
5943
+ child.once("exit", (code) => {
5944
+ clearTimeout(timer);
5945
+ if (code === 0) resolve();
5946
+ else reject(/* @__PURE__ */ new Error("Could not open a terminal for your agent."));
5947
+ });
5948
+ });
5949
+ }
5950
+ async function openCodingAgent(agent, directory, spellbookPath) {
5951
+ const cwd = path$1.resolve(directory);
5952
+ const command = await executable(agent);
5953
+ const prompt = `Read <${path$1.resolve(spellbookPath)}> and complete the task described in the Wizard's spell books. Inspect what has already been done before making changes.`;
5954
+ if (process.platform === "linux") {
5955
+ await launch(await executable("x-terminal-emulator"), [
5956
+ "-e",
5957
+ command,
5958
+ prompt
5959
+ ], cwd);
5960
+ return;
5961
+ }
5962
+ const mac = process.platform === "darwin";
5963
+ if (!mac && process.platform !== "win32") throw new Error("Opening an agent is not supported on this system. Use the saved skill path to continue.");
5964
+ const folder = await mkdtemp(path$1.join(tmpdir(), "wizard-handoff-"));
5965
+ const script = path$1.join(folder, mac ? "open-agent.command" : "open-agent.cmd");
5966
+ try {
5967
+ await writeFile(script, (mac ? [
5968
+ "#!/bin/sh",
5969
+ `rm -f ${quote(script)}`,
5970
+ `rmdir ${quote(folder)}`,
5971
+ `export PATH=${quote(process.env.PATH ?? "")}`,
5972
+ `cd ${quote(cwd)} || exit 1`,
5973
+ `exec ${quote(command)} ${quote(prompt)}`
5974
+ ] : [
5975
+ "@echo off",
5976
+ "chcp 65001 >nul",
5977
+ "setlocal DisableDelayedExpansion",
5978
+ `cd /d ${batchQuote(cwd)} || exit /b 1`,
5979
+ `del "%~f0" & rmdir ${batchQuote(folder)} & ${batchQuote(command)} ${batchQuote(prompt)}`
5980
+ ]).join(mac ? "\n" : "\r\n") + "\n", { mode: 448 });
5981
+ if (mac) {
5982
+ await launch("/usr/bin/open", [script], cwd);
5983
+ return;
5984
+ }
5985
+ const shell = process.env.ComSpec ?? "cmd.exe";
5986
+ await launch(shell, [
5987
+ "/d",
5988
+ "/s",
5989
+ "/c",
5990
+ `"start "" ${shell} /d /c "${script}""`
5991
+ ], folder, true);
5992
+ } catch (error) {
5993
+ await rm(folder, {
5994
+ recursive: true,
5995
+ force: true
5996
+ });
5997
+ throw error;
5998
+ }
5999
+ }
6000
+ //#endregion
6001
+ //#region src/lib/wizard-spellbook.ts
6002
+ function selectSkills(menu, session, program) {
6003
+ const entries = Object.values(menu.categories).flat().filter((entry) => /^[a-z0-9]+(?:-[a-z0-9]+)*$/.test(entry.id));
6004
+ const skillId = program.skillId ?? session.skillId;
6005
+ const exact = entries.find((entry) => entry.id === skillId);
6006
+ if (exact) return [exact];
6007
+ const framework = session.integration;
6008
+ const referenceGroup = skillId === framework ? "integration" : skillId;
6009
+ const references = entries.filter((entry) => entry.group === referenceGroup && entry.framework === framework);
6010
+ const reference = references.find((entry) => entry.default) ?? references[0];
6011
+ if (reference) return [reference];
6012
+ const flow = program.agentFlow ?? program.id;
6013
+ const groups = /* @__PURE__ */ new Map();
6014
+ for (const entry of entries) {
6015
+ const group = entry.group;
6016
+ if (!group || group !== flow && !group.startsWith(`${flow}-`) || entry.framework && entry.framework !== framework) continue;
6017
+ if (!groups.has(group) || entry.default) groups.set(group, entry);
6018
+ }
6019
+ return [...groups.values()];
6020
+ }
6021
+ function spellbookText(session, program, skills) {
6022
+ const framework = session.frameworkConfig?.metadata;
6023
+ const runDocs = typeof program.run === "object" ? program.run.docsUrl : void 0;
6024
+ const docs = [...new Set([
6025
+ framework?.docsUrl,
6026
+ runDocs,
6027
+ POSTHOG_DOCS_URL
6028
+ ])].filter((url) => Boolean(url));
6029
+ return [
6030
+ "# Wizard spell book",
6031
+ "",
6032
+ "Complete this task in the project containing this spell book:",
6033
+ "",
6034
+ program.description,
6035
+ "",
6036
+ `Wizard program: ${program.id}`,
6037
+ ...framework ? [`Detected framework: ${framework.name}`] : [],
6038
+ "",
6039
+ "Inspect the existing project and its instructions before making changes. Check what has already been done, complete the requested task within its stated scope, then run the relevant checks and explain any remaining manual steps.",
6040
+ "",
6041
+ "Use your own coding agent and its authentication. The Wizard could not continue its inference session. No Wizard credentials are included; ask the user for any credentials the task requires and keep them out of source code.",
6042
+ "",
6043
+ "## Setup instructions",
6044
+ "",
6045
+ ...skills.length ? [
6046
+ "Read the downloaded skills and their referenced files:",
6047
+ "",
6048
+ ...skills.map((skill) => `- [${skill.id}](skills/${skill.id}/SKILL.md)`),
6049
+ "",
6050
+ "Downloaded skills may cover only part of the task. Use the official documentation below to fill any gaps."
6051
+ ] : ["No matching skills could be downloaded. Use the official documentation below to complete the task."],
6052
+ "",
6053
+ "## Official documentation",
6054
+ "",
6055
+ ...docs.map((url) => `- ${url}`),
6056
+ ""
6057
+ ].join("\n");
6058
+ }
6059
+ async function writeWizardSpellbook(session, program) {
6060
+ const parent = path.join(session.installDir, ".posthog");
6061
+ await fs$1.mkdir(parent, { recursive: true });
6062
+ const directory = await fs$1.mkdtemp(path.join(parent, "wizard-spellbook-"));
6063
+ const readme = path.join(directory, "README.md");
6064
+ await fs$1.writeFile(readme, spellbookText(session, program, []));
6065
+ const menu = await fetchSkillMenu(getSkillsBaseUrl(), {
6066
+ timeoutMs: 1e4,
6067
+ maxAttempts: 1
6068
+ });
6069
+ const installed = [];
6070
+ for (const skill of menu ? selectSkills(menu, session, program) : []) if ((await downloadSkill(skill, directory, {
6071
+ skillsRoot: "skills",
6072
+ triage: void 0
6073
+ })).success) installed.push(skill);
6074
+ else await fs$1.rm(path.join(directory, "skills", skill.id), {
6075
+ recursive: true,
6076
+ force: true
6077
+ });
6078
+ await fs$1.writeFile(readme, spellbookText(session, program, installed));
6079
+ return {
6080
+ path: readme,
6081
+ skillsIncluded: installed.length > 0
6082
+ };
6083
+ }
6084
+ //#endregion
5433
6085
  //#region src/ui/tui/screens/ExitScreen.tsx
5434
6086
  /**
5435
6087
  * ExitScreen — Final step in every program.
@@ -5437,9 +6089,9 @@ const KeepSkillsScreen = ({ store }) => {
5437
6089
  * Renders nothing. Immediately exits the process.
5438
6090
  * The cleanup handler in start-tui.ts handles the exit summary line.
5439
6091
  */
5440
- const ExitScreen = () => {
6092
+ const ExitScreen = ({ store }) => {
5441
6093
  useEffect(() => {
5442
- process.exit(0);
6094
+ if (!store?.session.mintHandoff) process.exit(0);
5443
6095
  }, []);
5444
6096
  return null;
5445
6097
  };
@@ -5705,6 +6357,42 @@ function handleAskKey(key, store) {
5705
6357
  if (key.escape) store.cancelPendingQuestion();
5706
6358
  }
5707
6359
  /**
6360
+ * What pressing Esc actually does, phrased for the footer hint.
6361
+ *
6362
+ * Esc declines the *whole* request — {@link WizardStore.cancelPendingQuestion}
6363
+ * builds a cancelled answer for every question, so the ones already typed are
6364
+ * discarded too. The footer used to label that "skip", which on a multi-question
6365
+ * request reads as "skip this field": the warehouse task walks a source's
6366
+ * credentials one field at a time, several of them optional, and a user who
6367
+ * pressed Esc to pass on an optional field instead threw away the whole source
6368
+ * and dropped the agent onto its browser-handoff fallback. Naming the scope
6369
+ * costs a few characters and makes the destructive key read as destructive.
6370
+ */
6371
+ function askEscapeHint(total, answered) {
6372
+ if (total <= 1) return "skip";
6373
+ if (answered <= 0) return `skip all ${total} questions`;
6374
+ return `skip all ${total} questions, discarding the ${answered} you answered`;
6375
+ }
6376
+ /**
6377
+ * Whether the overlay must mask what the user types for this question.
6378
+ *
6379
+ * A `sensitive` answer is one the wizard has already promised to treat as a
6380
+ * secret: `wizard_ask` vaults it and hands the agent an opaque `secretRef`, so
6381
+ * the raw string never enters the model's conversation. Every other boundary
6382
+ * guards it the same way — the skip events carry no free text, handoff prose is
6383
+ * kept out of telemetry — but the overlay that collects it echoed it back in
6384
+ * plain text as it was typed, which is the one place a database password or an
6385
+ * API key is read by a person other than its owner: a shared screen, a pairing
6386
+ * session, a recorded terminal.
6387
+ *
6388
+ * `kind` is checked as well as the flag. The tool already rejects `sensitive`
6389
+ * on a picker, and a picker has nothing to mask, so this keeps the predicate
6390
+ * total over a question rather than relying on that rejection.
6391
+ */
6392
+ function shouldMaskAnswer(question) {
6393
+ return question.kind === "text" && question.sensitive === true;
6394
+ }
6395
+ /**
5708
6396
  * Whether an answer would leave a required question effectively unanswered.
5709
6397
  *
5710
6398
  * The `wizard_ask` schema marks fields `required` (defaulting to true), but the
@@ -5776,6 +6464,8 @@ const WizardAskScreen = ({ store }) => {
5776
6464
  if (!question) return null;
5777
6465
  const total = pending.questions.length;
5778
6466
  const progress = total > 1 ? `Question ${index + 1} of ${total}` : null;
6467
+ const escapeHint = askEscapeHint(total, index);
6468
+ const canSkipOne = question.kind === "text" && question.required === false;
5779
6469
  const submit = (value) => {
5780
6470
  if (isRequiredButEmpty(question, value)) {
5781
6471
  setRequiredHint(true);
@@ -5850,17 +6540,40 @@ const WizardAskScreen = ({ store }) => {
5850
6540
  marginTop: 1,
5851
6541
  children: /* @__PURE__ */ jsxs(Text, {
5852
6542
  color: Colors.accent,
5853
- children: [Icons.warning, " This field is required — type an answer, or press ESC to skip."]
6543
+ children: [
6544
+ Icons.warning,
6545
+ " This field is required — type an answer, or press ESC to ",
6546
+ escapeHint,
6547
+ "."
6548
+ ]
6549
+ })
6550
+ }),
6551
+ canSkipOne && /* @__PURE__ */ jsx(Box, {
6552
+ marginTop: 1,
6553
+ children: /* @__PURE__ */ jsxs(Text, {
6554
+ dimColor: true,
6555
+ children: [
6556
+ "Optional — press ",
6557
+ /* @__PURE__ */ jsx(Text, {
6558
+ color: Colors.accent,
6559
+ children: "ENTER"
6560
+ }),
6561
+ " on an empty answer to skip just this one."
6562
+ ]
5854
6563
  })
5855
6564
  }),
5856
6565
  /* @__PURE__ */ jsx(Box, {
5857
6566
  marginTop: 1,
5858
6567
  children: /* @__PURE__ */ jsxs(Text, {
5859
6568
  dimColor: true,
5860
- children: [/* @__PURE__ */ jsx(Text, {
5861
- color: Colors.accent,
5862
- children: "ESC"
5863
- }), " skip"]
6569
+ children: [
6570
+ /* @__PURE__ */ jsx(Text, {
6571
+ color: Colors.accent,
6572
+ children: "ESC"
6573
+ }),
6574
+ " ",
6575
+ escapeHint
6576
+ ]
5864
6577
  })
5865
6578
  })
5866
6579
  ]
@@ -5895,7 +6608,7 @@ const QuestionInput = ({ question, onSubmit }) => {
5895
6608
  case "text": return /* @__PURE__ */ jsxs(Box, {
5896
6609
  flexDirection: "column",
5897
6610
  width: "100%",
5898
- children: [/* @__PURE__ */ jsx(TextInput, {
6611
+ children: [/* @__PURE__ */ jsx(shouldMaskAnswer(question) ? PasswordInput : TextInput, {
5899
6612
  placeholder: "Type your answer",
5900
6613
  onSubmit: (value) => onSubmit(value)
5901
6614
  }), /* @__PURE__ */ jsx(Box, {
@@ -6048,13 +6761,18 @@ function createMcpSuggestedPromptsServices(store) {
6048
6761
  };
6049
6762
  }
6050
6763
  async function* runProductionPromptStreaming(args) {
6051
- const { runMcpPromptViaSdk } = await import("./mcp-prompt-streaming-R8H7uhuO.js");
6764
+ const { runMcpPromptViaSdk } = await import("./mcp-prompt-streaming-DNCDeU51.js");
6052
6765
  yield* runMcpPromptViaSdk(args);
6053
6766
  }
6054
6767
  //#endregion
6055
6768
  //#region src/ui/tui/screen-registry.tsx
6056
6769
  function createServices(store) {
6057
6770
  return {
6771
+ get logPath() {
6772
+ return path$1.resolve(getLogFilePath());
6773
+ },
6774
+ openAgent: (agent, spellbookPath) => openCodingAgent(agent, store.session.installDir, spellbookPath),
6775
+ leaveSpellbook: () => writeWizardSpellbook(store.session, getProgramConfig(store.router.activeProgram)),
6058
6776
  mcpInstaller: createMcpInstaller(),
6059
6777
  mcpSuggestedPromptsServices: createMcpSuggestedPromptsServices(store)
6060
6778
  };
@@ -6079,6 +6797,8 @@ function createScreens(store, services) {
6079
6797
  ["agent-skill-intro"]: /* @__PURE__ */ jsx(AgentSkillIntroScreen, { store }),
6080
6798
  ["ai-observability-intro"]: /* @__PURE__ */ jsx(AiObservabilityIntroScreen, { store }),
6081
6799
  ["metrics-intro"]: /* @__PURE__ */ jsx(MetricsIntroScreen, { store }),
6800
+ ["error-tracking-intro"]: /* @__PURE__ */ jsx(ErrorTrackingIntroScreen, { store }),
6801
+ ["error-tracking-detect"]: /* @__PURE__ */ jsx(ErrorTrackingDetectScreen, { store }),
6082
6802
  ["self-driving-intro"]: /* @__PURE__ */ jsx(SelfDrivingIntroScreen, { store }),
6083
6803
  ["self-driving-integration-check"]: /* @__PURE__ */ jsx(SelfDrivingIntegrationCheckScreen, { store }),
6084
6804
  ["self-driving-integration-detect"]: /* @__PURE__ */ jsx(SelfDrivingIntegrationDetectScreen, { store }),
@@ -6105,7 +6825,11 @@ function createScreens(store, services) {
6105
6825
  ["slack-connect"]: /* @__PURE__ */ jsx(SlackConnectScreen, { store }),
6106
6826
  ["keep-skills"]: /* @__PURE__ */ jsx(KeepSkillsScreen, { store }),
6107
6827
  ["outro"]: /* @__PURE__ */ jsx(OutroScreen, { store }),
6108
- ["exit"]: /* @__PURE__ */ jsx(ExitScreen, {}),
6828
+ ["mint-failure"]: /* @__PURE__ */ jsx(MintFailureScreen, {
6829
+ store,
6830
+ services
6831
+ }),
6832
+ ["exit"]: /* @__PURE__ */ jsx(ExitScreen, { store }),
6109
6833
  ["mcp-add"]: /* @__PURE__ */ jsx(McpScreen, {
6110
6834
  store,
6111
6835
  installer: services.mcpInstaller
@@ -6177,6 +6901,16 @@ function getExitLine(store) {
6177
6901
  const label = store.session.programLabel ?? "Wizard";
6178
6902
  const costLine = tokenCostLine(store);
6179
6903
  const loginBlock = mcpLoginBlock(store);
6904
+ if (isRunFailure(store.session)) {
6905
+ const spellbook = store.session.spellbook;
6906
+ return [
6907
+ "The wizard is unavailable. Setup has not been completed.",
6908
+ spellbook && `${DIM}Point your agent at this skill (triple-click to select):${RESET_ATTRS}\n${spellbook.path}`,
6909
+ `${DIM}${MINT_FAILURE_CONTACT}${RESET_ATTRS}\n${getLogFilePath()}`,
6910
+ loginBlock,
6911
+ costLine
6912
+ ].filter(Boolean).join("\n\n");
6913
+ }
6180
6914
  if (outro?.kind === "success") {
6181
6915
  const message = outro.message ?? `${label} completed successfully.`;
6182
6916
  const parts = [`${GREEN}${BOLD}✔${RESET_ATTRS} ${message}${outro.reportFile && !message.includes(outro.reportFile) ? ` Check ./${outro.reportFile} for details.` : ""}`];
@@ -6242,4 +6976,4 @@ function startTUI(version, program = Program.PostHogIntegration) {
6242
6976
  //#endregion
6243
6977
  export { startTUI };
6244
6978
 
6245
- //# sourceMappingURL=start-tui-BRwZzlWb.js.map
6979
+ //# sourceMappingURL=start-tui-BXjJGNx2.js.map