@posthog/wizard 2.74.1 → 2.76.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 (119) hide show
  1. package/README.md +31 -17
  2. package/dist/README.md +10 -0
  3. package/dist/{add-mcp-server-to-clients-CBtInAoH.js → add-mcp-server-to-clients-Exddicp2.js} +5 -5
  4. package/dist/{add-mcp-server-to-clients-CBtInAoH.js.map → add-mcp-server-to-clients-Exddicp2.js.map} +1 -1
  5. package/dist/{agent-interface-lCIi_alS.js → agent-interface-CZWRgZMc.js} +204 -376
  6. package/dist/agent-interface-CZWRgZMc.js.map +1 -0
  7. package/dist/{agent-prompt-loader-CSxm81TM.js → agent-prompt-loader-BobuLDIg.js} +5 -5
  8. package/dist/{agent-prompt-loader-CSxm81TM.js.map → agent-prompt-loader-BobuLDIg.js.map} +1 -1
  9. package/dist/{agent-runner-DVrkOFDA.js → agent-runner-C_R1X_UT.js} +158 -45
  10. package/dist/agent-runner-C_R1X_UT.js.map +1 -0
  11. package/dist/{analytics-CeVMOExk.js → analytics-C_RyE8fz.js} +7 -4
  12. package/dist/analytics-C_RyE8fz.js.map +1 -0
  13. package/dist/analytics-DXvdQqyp.js +2 -0
  14. package/dist/{api-2nAofyKY.js → api-k5aGQpIZ.js} +3 -3
  15. package/dist/{api-2nAofyKY.js.map → api-k5aGQpIZ.js.map} +1 -1
  16. package/dist/bin.js +164 -4087
  17. package/dist/bin.js.map +1 -1
  18. package/dist/{bounded-fs-DmcmFPRq.js → bounded-fs-BHLy83N9.js} +3 -3
  19. package/dist/{bounded-fs-DmcmFPRq.js.map → bounded-fs-BHLy83N9.js.map} +1 -1
  20. package/dist/{ci-install-lwYLQ4Yw.js → ci-install-CXt4c41q.js} +4 -4
  21. package/dist/{ci-install-lwYLQ4Yw.js.map → ci-install-CXt4c41q.js.map} +1 -1
  22. package/dist/{debug-BvheXnxB.js → debug-BxMMpepn.js} +1 -1
  23. package/dist/{debug-GxjVplPx.js → debug-C5Zz8hmm.js} +6 -4
  24. package/dist/debug-C5Zz8hmm.js.map +1 -0
  25. package/dist/{defaults-DI642M3n.js → defaults-DulzMJpN.js} +1 -1
  26. package/dist/{defaults-DI642M3n.js.map → defaults-DulzMJpN.js.map} +1 -1
  27. package/dist/{env-api-key-BMXH7_4u.js → env-api-key-Ca-CrkgV.js} +2 -2
  28. package/dist/{env-api-key-BMXH7_4u.js.map → env-api-key-Ca-CrkgV.js.map} +1 -1
  29. package/dist/{environment-C3nfPBu-.js → environment-B0uTamFf.js} +4 -4
  30. package/dist/{environment-C3nfPBu-.js.map → environment-B0uTamFf.js.map} +1 -1
  31. package/dist/file-CNstcW8F.js +60 -0
  32. package/dist/file-CNstcW8F.js.map +1 -0
  33. package/dist/{file-watcher-BGElIpJi.js → file-watcher-CiT-oZpu.js} +2 -2
  34. package/dist/{file-watcher-BGElIpJi.js.map → file-watcher-CiT-oZpu.js.map} +1 -1
  35. package/dist/gateway-session-BIVN_Xfr.js +2 -0
  36. package/dist/gateway-session-C3Uqwc4R.js +271 -0
  37. package/dist/gateway-session-C3Uqwc4R.js.map +1 -0
  38. package/dist/{headless-ui-jkS2Dm_G.js → headless-ui-TpSp-F43.js} +10 -5
  39. package/dist/headless-ui-TpSp-F43.js.map +1 -0
  40. package/dist/{interactive-CrQWwMr2.js → interactive-B72L-sO5.js} +2 -2
  41. package/dist/{interactive-CrQWwMr2.js.map → interactive-B72L-sO5.js.map} +1 -1
  42. package/dist/{mcp-S3yX8Uz1.js → mcp-CNc6CLK0.js} +2 -2
  43. package/dist/{mcp-S3yX8Uz1.js.map → mcp-CNc6CLK0.js.map} +1 -1
  44. package/dist/{mcp-prompt-streaming-BvvCZBYa.js → mcp-prompt-streaming-BvBNkzjv.js} +6 -5
  45. package/dist/{mcp-prompt-streaming-BvvCZBYa.js.map → mcp-prompt-streaming-BvBNkzjv.js.map} +1 -1
  46. package/dist/mint-failure-CZ5FZ0Jd.js +5739 -0
  47. package/dist/mint-failure-CZ5FZ0Jd.js.map +1 -0
  48. package/dist/{non-interactive-B-MIn3vt.js → non-interactive-UeQlnU0U.js} +2 -2
  49. package/dist/{non-interactive-B-MIn3vt.js.map → non-interactive-UeQlnU0U.js.map} +1 -1
  50. package/dist/{orchestrator-tools-CefodRf2.js → orchestrator-tools-CLADku26.js} +5 -5
  51. package/dist/orchestrator-tools-CLADku26.js.map +1 -0
  52. package/dist/{package-manager-pB6S0gyu.js → package-manager-CppzeIgu.js} +2 -2
  53. package/dist/{package-manager-pB6S0gyu.js.map → package-manager-CppzeIgu.js.map} +1 -1
  54. package/dist/{pi-Dbw8VakI.js → pi-Bs1Tbt0C.js} +35 -24
  55. package/dist/pi-Bs1Tbt0C.js.map +1 -0
  56. package/dist/{playground-C7DwGktN.js → playground-CZgZX4j0.js} +8 -8
  57. package/dist/{playground-C7DwGktN.js.map → playground-CZgZX4j0.js.map} +1 -1
  58. package/dist/{posthog-B3RuLfxH.js → posthog-BZ3NNCyh.js} +2 -2
  59. package/dist/{posthog-B3RuLfxH.js.map → posthog-BZ3NNCyh.js.map} +1 -1
  60. package/dist/{provisioning-B4Lr3-aS.js → provisioning-Ba7GWKzK.js} +3 -3
  61. package/dist/{provisioning-B4Lr3-aS.js.map → provisioning-Ba7GWKzK.js.map} +1 -1
  62. package/dist/{queue-tools-BveMVXQm.js → queue-tools-D09PNS0X.js} +17 -5
  63. package/dist/queue-tools-D09PNS0X.js.map +1 -0
  64. package/dist/{registry-D8MIZ9kJ.js → registry-COcpEsMD.js} +5 -5
  65. package/dist/{registry-D8MIZ9kJ.js.map → registry-COcpEsMD.js.map} +1 -1
  66. package/dist/{security-B_Eo15wD.js → security-CpAT0fZa.js} +5 -5
  67. package/dist/{security-B_Eo15wD.js.map → security-CpAT0fZa.js.map} +1 -1
  68. package/dist/{setup-utils-D3OK2RE_.js → setup-utils-BUAoRjw3.js} +48 -9
  69. package/dist/setup-utils-BUAoRjw3.js.map +1 -0
  70. package/dist/smoke-test-ci.sh +9 -14
  71. package/dist/{start-tui-B7u962uh.js → start-tui-Bz23_yym.js} +848 -127
  72. package/dist/start-tui-Bz23_yym.js.map +1 -0
  73. package/dist/{steps-D4mHkYX4.js → steps-DbsDish5.js} +7 -7
  74. package/dist/{steps-D4mHkYX4.js.map → steps-DbsDish5.js.map} +1 -1
  75. package/dist/{store-Cn1VK6U0.js → store-D5ROpUje.js} +63 -10
  76. package/dist/store-D5ROpUje.js.map +1 -0
  77. package/dist/{subagent-1UEmD7bE.js → subagent-CSBZnhgK.js} +2 -2
  78. package/dist/{subagent-1UEmD7bE.js.map → subagent-CSBZnhgK.js.map} +1 -1
  79. package/dist/{task-DNHNZMO0.js → task-D8sTR7jZ.js} +23 -23
  80. package/dist/task-D8sTR7jZ.js.map +1 -0
  81. package/dist/{task-stream-BJrRzR9K.js → task-stream-Dl0XEsZ9.js} +49 -7
  82. package/dist/task-stream-Dl0XEsZ9.js.map +1 -0
  83. package/dist/{tasks-DSEJ8GZC.js → tasks-BDt427kT.js} +2 -2
  84. package/dist/{tasks-DSEJ8GZC.js.map → tasks-BDt427kT.js.map} +1 -1
  85. package/dist/{telemetry-DWkTy6TJ.js → telemetry-Dp6zjZBj.js} +3 -3
  86. package/dist/{telemetry-DWkTy6TJ.js.map → telemetry-Dp6zjZBj.js.map} +1 -1
  87. package/dist/{terminal-DNnNkvFu.js → terminal-pInlleVD.js} +20 -18
  88. package/dist/{terminal-DNnNkvFu.js.map → terminal-pInlleVD.js.map} +1 -1
  89. package/dist/{tools-HHK4XbnC.js → tools-MkyMOjQI.js} +98 -28
  90. package/dist/tools-MkyMOjQI.js.map +1 -0
  91. package/dist/{wizard-abort-BVmjqUAQ.js → wizard-abort-BCnUgT9z.js} +4 -4
  92. package/dist/{wizard-abort-BVmjqUAQ.js.map → wizard-abort-BCnUgT9z.js.map} +1 -1
  93. package/dist/{wizard-abort-CG_xzEFN.js → wizard-abort-BHLKVKLN.js} +1 -1
  94. package/dist/{wizard-session-BWAQoi9q.js → wizard-session-CYvyYnti.js} +1 -1
  95. package/dist/{wizard-session-GdDN_aMS.js → wizard-session-FSJCkTcP.js} +9 -2
  96. package/dist/wizard-session-FSJCkTcP.js.map +1 -0
  97. package/dist/{yara-hooks-qRkdjYiV.js → yara-hooks-BJWVgTpU.js} +4 -4
  98. package/dist/{yara-hooks-qRkdjYiV.js.map → yara-hooks-BJWVgTpU.js.map} +1 -1
  99. package/dist/yara-hooks-Dp82xJGd.js +2 -0
  100. package/package.json +1 -1
  101. package/dist/agent-interface-lCIi_alS.js.map +0 -1
  102. package/dist/agent-runner-DVrkOFDA.js.map +0 -1
  103. package/dist/analytics-3H_AlflZ.js +0 -2
  104. package/dist/analytics-CeVMOExk.js.map +0 -1
  105. package/dist/debug-GxjVplPx.js.map +0 -1
  106. package/dist/headless-ui-jkS2Dm_G.js.map +0 -1
  107. package/dist/orchestrator-tools-CefodRf2.js.map +0 -1
  108. package/dist/pi-Dbw8VakI.js.map +0 -1
  109. package/dist/posthog-integration-su2LXi3-.js +0 -1475
  110. package/dist/posthog-integration-su2LXi3-.js.map +0 -1
  111. package/dist/queue-tools-BveMVXQm.js.map +0 -1
  112. package/dist/setup-utils-D3OK2RE_.js.map +0 -1
  113. package/dist/start-tui-B7u962uh.js.map +0 -1
  114. package/dist/store-Cn1VK6U0.js.map +0 -1
  115. package/dist/task-DNHNZMO0.js.map +0 -1
  116. package/dist/task-stream-BJrRzR9K.js.map +0 -1
  117. package/dist/tools-HHK4XbnC.js.map +0 -1
  118. package/dist/wizard-session-GdDN_aMS.js.map +0 -1
  119. package/dist/yara-hooks-BOMbtTOr.js +0 -2
@@ -1,33 +1,35 @@
1
1
  import { d as ErrorCodes } from "./errors--OqLxmWR.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, d as relativeToInstallDir, g as SIGNUP_WIZARD_READINESS_CONFIG, l as WIZARD_LOG_FILE, p as setUI, q as POSTHOG_ORG_AI_SETTINGS_URL, s as logToFile, v as getBlockingServiceKeys } from "./debug-GxjVplPx.js";
3
- import { t as ADDITIONAL_FEATURE_LABELS } from "./wizard-session-GdDN_aMS.js";
4
- import { n as analytics } from "./analytics-CeVMOExk.js";
5
- import { n as openTrackedLink } from "./telemetry-DWkTy6TJ.js";
6
- import { i as readProjectFile, t as IGNORED_DIRS } from "./bounded-fs-DmcmFPRq.js";
7
- import { o as extractOAuthCode, t as getOrAskForProjectData } from "./setup-utils-D3OK2RE_.js";
8
- import { c as getIntegrationAuthorizeUrl, i as requestDeepLink } from "./provisioning-B4Lr3-aS.js";
9
- import { r as fetchGithubConnected, t as ApiError } from "./api-2nAofyKY.js";
10
- import { i as wizardAbort } from "./wizard-abort-BVmjqUAQ.js";
11
- import { N as downloadSkill, P as fetchSkillMenu } from "./agent-interface-lCIi_alS.js";
12
- import { a as formatCostUsd, f as getDetectedWarehouseSources, m as detectProjectsWithAgent, o as formatTokenCount } from "./agent-runner-DVrkOFDA.js";
13
- import { t as FRAMEWORK_REGISTRY } from "./registry-D8MIZ9kJ.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-qRkdjYiV.js";
15
- import { h as Icons, m as Colors, t as SETUP_REPORT_FILE } from "./posthog-integration-su2LXi3-.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-Cn1VK6U0.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-DNnNkvFu.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-BGElIpJi.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-CBtInAoH.js";
2
+ import { H as OAUTH_PORTS, J as POSTHOG_ORG_AI_SETTINGS_URL, K as POSTHOG_DOCS_URL, N as GITHUB_SKILLS_BASE_URL, Q as POSTHOG_TERMS_URL, U as OAUTH_TIMEOUT_MS, V as Integration, Y as POSTHOG_PRIVACY_URL, _ as SIGNUP_WIZARD_READINESS_CONFIG, a as getLogFilePath, f as relativeToInstallDir, l as WIZARD_LOG_FILE, m as setUI, mt as getSkillsBaseUrl, s as logToFile, y as getBlockingServiceKeys } from "./debug-C5Zz8hmm.js";
3
+ import { t as ADDITIONAL_FEATURE_LABELS } from "./wizard-session-FSJCkTcP.js";
4
+ import { n as analytics } from "./analytics-C_RyE8fz.js";
5
+ import { n as openTrackedLink } from "./telemetry-Dp6zjZBj.js";
6
+ import { i as readProjectFile, t as IGNORED_DIRS } from "./bounded-fs-BHLy83N9.js";
7
+ import { o as extractOAuthCode, t as getOrAskForProjectData } from "./setup-utils-BUAoRjw3.js";
8
+ import { c as getIntegrationAuthorizeUrl, i as requestDeepLink } from "./provisioning-Ba7GWKzK.js";
9
+ import { r as fetchGithubConnected, t as ApiError } from "./api-k5aGQpIZ.js";
10
+ import { i as wizardAbort } from "./wizard-abort-BCnUgT9z.js";
11
+ import { G as fetchSkillMenu, U as downloadSkill } from "./agent-interface-CZWRgZMc.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-C_R1X_UT.js";
13
+ import { t as FRAMEWORK_REGISTRY } from "./registry-COcpEsMD.js";
14
+ import { x as getAuditChecks, y as AUDIT_SEVERITY_STYLE } from "./yara-hooks-BJWVgTpU.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-CZ5FZ0Jd.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-D5ROpUje.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-pInlleVD.js";
19
+ import { c as namesWithStatus, d as toClientResult, l as redactSecrets, t as ALL_FEATURE_VALUES } from "./defaults-DulzMJpN.js";
20
+ 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-Exddicp2.js";
22
21
  import { existsSync, readFileSync, readdirSync } from "fs";
23
22
  import path, { join } from "path";
24
- import { join as join$1 } from "node:path";
23
+ import { tmpdir } from "node:os";
24
+ import path$1, { join as join$1 } from "node:path";
25
25
  import { spawn } from "node:child_process";
26
+ import { constants } from "node:fs";
27
+ import fs$1 from "fs/promises";
26
28
  import { Box, Text, render, useInput } from "ink";
27
29
  import { Fragment, createElement, useEffect, useMemo, useRef, useState, useSyncExternalStore } from "react";
28
30
  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";
31
+ import { access, mkdtemp, readdir, rm, writeFile } from "node:fs/promises";
32
+ import { PasswordInput, Spinner, TextInput } from "@inkjs/ui";
31
33
  //#region src/ui/tui/ink-ui.ts
32
34
  const ANSI_RE = /\x1b\[[0-9;]*m/g;
33
35
  function stripAnsi(s) {
@@ -1009,6 +1011,20 @@ const PrivacyPanel = ({ canOptOut = false } = {}) => {
1009
1011
  * children — between detection rows and menu (extra info, warnings)
1010
1012
  * errorView — replaces the entire body for fatal error states
1011
1013
  */
1014
+ /** Pads to the widest label passed, so every tick lands in one column. */
1015
+ function detectionLabelWidth(rows) {
1016
+ return Math.max(9, ...(rows ?? []).map((row) => row.label.length));
1017
+ }
1018
+ const DetectionLine = ({ label, width, children }) => /* @__PURE__ */ jsxs(Text, { children: [
1019
+ label.padEnd(width),
1020
+ " ",
1021
+ /* @__PURE__ */ jsx(Text, {
1022
+ color: "green",
1023
+ children: "✔"
1024
+ }),
1025
+ " ",
1026
+ /* @__PURE__ */ jsx(Text, { children })
1027
+ ] });
1012
1028
  const WizardTitle = ({ title }) => /* @__PURE__ */ jsxs(Text, {
1013
1029
  bold: true,
1014
1030
  children: [
@@ -1082,6 +1098,7 @@ const IntroScreenLayout = ({ installDir, title = "PostHog Wizard 🦔", showSubt
1082
1098
  showingPrivacy,
1083
1099
  privacyOptions
1084
1100
  });
1101
+ const labelWidth = detectionLabelWidth(detectionRows);
1085
1102
  const handleSelect = (value) => {
1086
1103
  if (value === "privacy") return setShowingPrivacy(true);
1087
1104
  if (value === "privacy-back") return setShowingPrivacy(false);
@@ -1134,43 +1151,26 @@ const IntroScreenLayout = ({ installDir, title = "PostHog Wizard 🦔", showSubt
1134
1151
  flexDirection: "column",
1135
1152
  marginTop: 1,
1136
1153
  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
- ] })
1154
+ /* @__PURE__ */ jsxs(DetectionLine, {
1155
+ label: "Directory",
1156
+ width: labelWidth,
1157
+ children: ["/", path.basename(installDir)]
1158
+ }),
1159
+ detectionRows?.map((row) => /* @__PURE__ */ jsxs(DetectionLine, {
1160
+ label: row.label,
1161
+ width: labelWidth,
1162
+ children: [row.value, row.suffix ? ` ${row.suffix}` : ""]
1163
+ }, row.label)),
1164
+ programLabel && /* @__PURE__ */ jsx(DetectionLine, {
1165
+ label: "Program",
1166
+ width: labelWidth,
1167
+ children: programLabel
1168
+ }),
1169
+ programLabel === "agent-skill" && skillId && /* @__PURE__ */ jsx(DetectionLine, {
1170
+ label: "Skill",
1171
+ width: labelWidth,
1172
+ children: skillId
1173
+ })
1174
1174
  ]
1175
1175
  }),
1176
1176
  /* @__PURE__ */ jsx(Box, {
@@ -1190,6 +1190,45 @@ const IntroScreenLayout = ({ installDir, title = "PostHog Wizard 🦔", showSubt
1190
1190
  }) });
1191
1191
  };
1192
1192
  //#endregion
1193
+ //#region src/ui/tui/posthog-integration-intro.ts
1194
+ const CONTINUE_LABEL = "Continue";
1195
+ const CONTINUE_ANYWAY_LABEL = "Continue anyway";
1196
+ const DEFAULT_HEADLINE = "Let's do two hours of work in eight minutes.";
1197
+ 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."];
1198
+ function introHeadline(posthogSdkDetected) {
1199
+ return posthogSdkDetected ? DETECTED_HEADLINE : [DEFAULT_HEADLINE];
1200
+ }
1201
+ function introMenuOptions({ view, showContinue, posthogSdkDetected }) {
1202
+ if (view === "commands") return null;
1203
+ if (view === "more-info") return [{
1204
+ label: "Back",
1205
+ value: "back"
1206
+ }];
1207
+ if (showContinue) return [
1208
+ ...posthogSdkDetected ? [{
1209
+ label: "Explore spell book",
1210
+ value: "commands"
1211
+ }] : [],
1212
+ {
1213
+ label: posthogSdkDetected ? CONTINUE_ANYWAY_LABEL : CONTINUE_LABEL,
1214
+ value: "continue"
1215
+ },
1216
+ {
1217
+ label: "Change framework",
1218
+ value: "framework"
1219
+ },
1220
+ {
1221
+ label: "More info",
1222
+ value: "more-info"
1223
+ },
1224
+ {
1225
+ label: "Cancel",
1226
+ value: "cancel"
1227
+ }
1228
+ ];
1229
+ return null;
1230
+ }
1231
+ //#endregion
1193
1232
  //#region src/ui/tui/screens/PostHogIntegrationIntroScreen.tsx
1194
1233
  /**
1195
1234
  * PostHogIntegrationIntroScreen — Intro screen for the core PostHog integration.
@@ -1226,29 +1265,6 @@ const SUBTITLE = /* @__PURE__ */ jsxs(Fragment$1, { children: [
1226
1265
  })
1227
1266
  ] });
1228
1267
  /**
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
1268
  * A blank, unselectable row. Navigation skips disabled options, so this is a
1253
1269
  * margin the menu can hold rather than one the layout has to special-case.
1254
1270
  */
@@ -1293,7 +1309,7 @@ const FrameworkPicker = ({ store, onComplete }) => {
1293
1309
  })),
1294
1310
  onSelect: (value) => {
1295
1311
  const integration = Array.isArray(value) ? value[0] : value;
1296
- import("./registry-D8MIZ9kJ.js").then((n) => n.n).then(({ FRAMEWORK_REGISTRY }) => {
1312
+ import("./registry-COcpEsMD.js").then((n) => n.n).then(({ FRAMEWORK_REGISTRY }) => {
1297
1313
  const config = FRAMEWORK_REGISTRY[integration];
1298
1314
  store.setFrameworkConfig(integration, config);
1299
1315
  store.setDetectedFramework(config.metadata.name);
@@ -1316,6 +1332,12 @@ const PostHogIntegrationIntroScreen = ({ store }) => {
1316
1332
  const needsFrameworkPick = session.detectionComplete && !session.frameworkConfig;
1317
1333
  const unsupported = session.unsupportedVersion;
1318
1334
  const showContinue = session.frameworkConfig !== null && !detecting && !pickingFramework && view === "default" && !unsupported;
1335
+ useKeyBindings("posthog-integration-intro", view === "commands" ? [{
1336
+ match: "escape",
1337
+ label: "esc",
1338
+ action: "back",
1339
+ handler: () => setView("default")
1340
+ }] : []);
1319
1341
  const title = detecting ? "PostHog Wizard starting up" : "PostHog Wizard 🦔";
1320
1342
  let body = null;
1321
1343
  if (detecting) body = /* @__PURE__ */ jsx(Box, {
@@ -1385,7 +1407,34 @@ const PostHogIntegrationIntroScreen = ({ store }) => {
1385
1407
  })
1386
1408
  ]
1387
1409
  });
1388
- else if (showContinue) body = /* @__PURE__ */ jsx(Box, { children: /* @__PURE__ */ jsx(Text, { children: "Let's do two hours of work in eight minutes." }) });
1410
+ else if (view === "commands") body = /* @__PURE__ */ jsx(PickerMenu, {
1411
+ message: "The Wizard can do more than integrate with your project:",
1412
+ options: getLaunchablePrograms().map((program) => ({
1413
+ label: `${getCommandPath(program).padEnd(21)}${program.description}`,
1414
+ value: program.id
1415
+ })),
1416
+ onSelect: (value) => {
1417
+ const id = Array.isArray(value) ? value[0] : value;
1418
+ analytics.wizardCapture("intro menu selected", {
1419
+ value: id,
1420
+ view
1421
+ });
1422
+ store.switchProgram(id);
1423
+ }
1424
+ });
1425
+ else if (showContinue) {
1426
+ const paragraphs = introHeadline(session.posthogSdkDetected);
1427
+ body = /* @__PURE__ */ jsx(Box, {
1428
+ flexDirection: "column",
1429
+ width: 64,
1430
+ flexShrink: 0,
1431
+ alignItems: paragraphs.length > 1 ? void 0 : "center",
1432
+ children: paragraphs.map((paragraph, i) => /* @__PURE__ */ jsx(Box, {
1433
+ marginTop: i === 0 ? 0 : 1,
1434
+ children: /* @__PURE__ */ jsx(Text, { children: paragraph })
1435
+ }, paragraph))
1436
+ });
1437
+ }
1389
1438
  const detectionRows = [];
1390
1439
  if (frameworkLabel) {
1391
1440
  const suffixParts = [];
@@ -1397,6 +1446,10 @@ const PostHogIntegrationIntroScreen = ({ store }) => {
1397
1446
  suffix: suffixParts.join(" ") || void 0
1398
1447
  });
1399
1448
  }
1449
+ if (session.posthogSdkDetected) detectionRows.push({
1450
+ label: "PostHog",
1451
+ value: "detected in package.json"
1452
+ });
1400
1453
  let bodyChildren = null;
1401
1454
  if (config?.metadata.preRunNotice) bodyChildren = /* @__PURE__ */ jsx(Text, {
1402
1455
  color: "yellow",
@@ -1444,12 +1497,11 @@ const PostHogIntegrationIntroScreen = ({ store }) => {
1444
1497
  })
1445
1498
  ]
1446
1499
  });
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;
1500
+ const menuOptions = introMenuOptions({
1501
+ view,
1502
+ showContinue,
1503
+ posthogSdkDetected: session.posthogSdkDetected
1504
+ });
1453
1505
  const handleSelect = (value) => {
1454
1506
  analytics.wizardCapture("intro menu selected", {
1455
1507
  value,
@@ -1460,6 +1512,7 @@ const PostHogIntegrationIntroScreen = ({ store }) => {
1460
1512
  setPickingFramework(true);
1461
1513
  setManuallySelected(true);
1462
1514
  } else if (value === "more-info") setView("more-info");
1515
+ else if (value === "commands") setView("commands");
1463
1516
  else if (value === "back") setView("default");
1464
1517
  else if (value === "share") store.grantSharing();
1465
1518
  else if (value === "no-share") store.declineSharing();
@@ -2286,9 +2339,9 @@ async function detectSourceMapsProjects(session, onEvent) {
2286
2339
  *
2287
2340
  * Runs after auth — the detection agent needs credentials.
2288
2341
  */
2289
- const EXIT = "__exit";
2290
- const MAX_ACTIVITY_LINES$1 = 8;
2291
- function projectLabel$1(p) {
2342
+ const EXIT$1 = "__exit";
2343
+ const MAX_ACTIVITY_LINES$2 = 8;
2344
+ function projectLabel$2(p) {
2292
2345
  const name = p.variant ? DISPLAY_NAME[p.variant] : p.framework;
2293
2346
  const where = p.path === "." ? "repo root" : p.path;
2294
2347
  return `${name} ${Icons.bullet} ${where}`;
@@ -2307,7 +2360,7 @@ const SourceMapsDetectScreen = ({ store }) => {
2307
2360
  (async () => {
2308
2361
  try {
2309
2362
  const report = await detectSourceMapsProjects(store.session, (line) => {
2310
- if (!cancelled) setActivity((prev) => [...prev, line].slice(-MAX_ACTIVITY_LINES$1));
2363
+ if (!cancelled) setActivity((prev) => [...prev, line].slice(-MAX_ACTIVITY_LINES$2));
2311
2364
  });
2312
2365
  if (!cancelled) setState({
2313
2366
  kind: "ready",
@@ -2371,7 +2424,7 @@ const SourceMapsDetectScreen = ({ store }) => {
2371
2424
  }), /* @__PURE__ */ jsx(PickerMenu, {
2372
2425
  options: [{
2373
2426
  label: "Exit",
2374
- value: EXIT
2427
+ value: EXIT$1
2375
2428
  }],
2376
2429
  onSelect: () => process.exit(1)
2377
2430
  })]
@@ -2404,7 +2457,7 @@ const SourceMapsDetectScreen = ({ store }) => {
2404
2457
  children: /* @__PURE__ */ jsx(PickerMenu, {
2405
2458
  options: [{
2406
2459
  label: "Exit",
2407
- value: EXIT
2460
+ value: EXIT$1
2408
2461
  }],
2409
2462
  onSelect: () => process.exit(0)
2410
2463
  })
@@ -2412,11 +2465,11 @@ const SourceMapsDetectScreen = ({ store }) => {
2412
2465
  ]
2413
2466
  });
2414
2467
  const options = [...instrumentable.map((p) => ({
2415
- label: projectLabel$1(p),
2468
+ label: projectLabel$2(p),
2416
2469
  value: p.path
2417
2470
  })), {
2418
2471
  label: "Cancel",
2419
- value: EXIT
2472
+ value: EXIT$1
2420
2473
  }];
2421
2474
  return /* @__PURE__ */ jsxs(Box, {
2422
2475
  flexDirection: "column",
@@ -2440,7 +2493,7 @@ const SourceMapsDetectScreen = ({ store }) => {
2440
2493
  options,
2441
2494
  onSelect: (value) => {
2442
2495
  const path = Array.isArray(value) ? value[0] : value;
2443
- if (path === EXIT) {
2496
+ if (path === EXIT$1) {
2444
2497
  process.exit(0);
2445
2498
  return;
2446
2499
  }
@@ -2906,6 +2959,266 @@ const MetricsIntroScreen = ({ store }) => {
2906
2959
  });
2907
2960
  };
2908
2961
  //#endregion
2962
+ //#region src/ui/tui/screens/ErrorTrackingIntroScreen.tsx
2963
+ const ErrorTrackingIntroScreen = ({ store }) => {
2964
+ useSyncExternalStore((cb) => store.subscribe(cb), () => store.getSnapshot());
2965
+ const [showingMoreInfo, setShowingMoreInfo] = useState(false);
2966
+ const { session } = store;
2967
+ const skillId = "integration-v2-error-tracking-step";
2968
+ const { skillEntry, fetchFailed } = useSkillEntry(skillId);
2969
+ const body = showingMoreInfo ? /* @__PURE__ */ jsxs(Box, {
2970
+ flexDirection: "column",
2971
+ width: 56,
2972
+ children: [
2973
+ /* @__PURE__ */ jsx(Box, {
2974
+ marginBottom: 1,
2975
+ children: /* @__PURE__ */ jsxs(Text, { children: [
2976
+ "The Wizard is an agent, it's here to help you setup PostHog. Its code is open source:",
2977
+ " ",
2978
+ /* @__PURE__ */ jsx(Text, {
2979
+ color: "cyan",
2980
+ children: "https://github.com/PostHog/wizard"
2981
+ })
2982
+ ] })
2983
+ }),
2984
+ /* @__PURE__ */ jsxs(Text, { children: [
2985
+ "The",
2986
+ " ",
2987
+ /* @__PURE__ */ jsx(Text, {
2988
+ color: "cyan",
2989
+ italic: true,
2990
+ children: "error-tracking"
2991
+ }),
2992
+ " ",
2993
+ "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."
2994
+ ] }),
2995
+ /* @__PURE__ */ jsx(Box, {
2996
+ marginTop: 1,
2997
+ children: /* @__PURE__ */ jsx(SkillSourceInfo, {
2998
+ skillId,
2999
+ skillEntry,
3000
+ fetchFailed
3001
+ })
3002
+ })
3003
+ ]
3004
+ }) : /* @__PURE__ */ jsx(Box, {
3005
+ flexDirection: "column",
3006
+ alignItems: "center",
3007
+ children: /* @__PURE__ */ jsx(Text, { children: "Let's make uncaught errors reach PostHog with readable stack traces." })
3008
+ });
3009
+ const menuOptions = showingMoreInfo ? [{
3010
+ label: "Back",
3011
+ value: "back"
3012
+ }] : [
3013
+ {
3014
+ label: "Continue",
3015
+ value: "continue"
3016
+ },
3017
+ {
3018
+ label: "More info",
3019
+ value: "more-info"
3020
+ },
3021
+ {
3022
+ label: "Cancel",
3023
+ value: "cancel"
3024
+ }
3025
+ ];
3026
+ const handleSelect = (value) => {
3027
+ if (value === "cancel") process.exit(0);
3028
+ else if (value === "more-info") setShowingMoreInfo(true);
3029
+ else if (value === "back") setShowingMoreInfo(false);
3030
+ else store.completeSetup();
3031
+ };
3032
+ return /* @__PURE__ */ jsx(IntroScreenLayout, {
3033
+ installDir: session.installDir,
3034
+ body,
3035
+ showDetection: !showingMoreInfo,
3036
+ programLabel: session.programLabel,
3037
+ skillId: session.skillId,
3038
+ menuOptions,
3039
+ onSelect: handleSelect
3040
+ });
3041
+ };
3042
+ //#endregion
3043
+ //#region src/ui/tui/screens/ErrorTrackingDetectScreen.tsx
3044
+ /**
3045
+ * ErrorTrackingDetectScreen — after login, runs the detection agent over the
3046
+ * repo, streams its progress, and lets the user pick the project to set error
3047
+ * tracking up in. Mirrors the legacy SourceMapsDetectScreen.
3048
+ */
3049
+ const EXIT = "__exit";
3050
+ const MAX_ACTIVITY_LINES$1 = 8;
3051
+ function projectLabel$1(p) {
3052
+ const where = p.path === "." ? "repo root" : p.path;
3053
+ return `${p.framework} ${Icons.bullet} ${where}`;
3054
+ }
3055
+ const ErrorTrackingDetectScreen = ({ store }) => {
3056
+ useSyncExternalStore((cb) => store.subscribe(cb), () => store.getSnapshot());
3057
+ const { credentials } = store.session;
3058
+ const accessToken = credentials?.accessToken;
3059
+ const [state, setState] = useState({ kind: "loading" });
3060
+ const [activity, setActivity] = useState([]);
3061
+ const started = useRef(false);
3062
+ useEffect(() => {
3063
+ if (!accessToken || started.current) return;
3064
+ started.current = true;
3065
+ let cancelled = false;
3066
+ (async () => {
3067
+ try {
3068
+ const report = await detectErrorTrackingProjects(store.session, (line) => {
3069
+ if (!cancelled) setActivity((prev) => [...prev, line].slice(-MAX_ACTIVITY_LINES$1));
3070
+ });
3071
+ if (!cancelled) setState({
3072
+ kind: "ready",
3073
+ report
3074
+ });
3075
+ } catch (err) {
3076
+ if (!cancelled) setState({
3077
+ kind: "error",
3078
+ message: err instanceof Error ? err.message : String(err)
3079
+ });
3080
+ }
3081
+ })();
3082
+ return () => {
3083
+ cancelled = true;
3084
+ };
3085
+ }, [accessToken, store]);
3086
+ if (!credentials) return /* @__PURE__ */ jsx(LoadingBox, { message: "Waiting for authentication..." });
3087
+ if (state.kind === "loading") return /* @__PURE__ */ jsxs(Box, {
3088
+ flexDirection: "column",
3089
+ children: [
3090
+ /* @__PURE__ */ jsx(Text, {
3091
+ bold: true,
3092
+ color: Colors.accent,
3093
+ children: "Detecting your project..."
3094
+ }),
3095
+ /* @__PURE__ */ jsx(Box, {
3096
+ marginY: 1,
3097
+ children: /* @__PURE__ */ jsx(LoadingBox, { message: "Scanning the repo for frameworks and PostHog SDKs..." })
3098
+ }),
3099
+ /* @__PURE__ */ jsx(Box, {
3100
+ flexDirection: "column",
3101
+ children: activity.length === 0 ? /* @__PURE__ */ jsxs(Text, {
3102
+ dimColor: true,
3103
+ children: [" ", "Starting up the detection agent…"]
3104
+ }) : activity.map((line, i) => /* @__PURE__ */ jsxs(Text, {
3105
+ dimColor: i < activity.length - 1,
3106
+ color: i === activity.length - 1 ? Colors.primary : void 0,
3107
+ children: [
3108
+ " ",
3109
+ Icons.triangleSmallRight,
3110
+ " ",
3111
+ line
3112
+ ]
3113
+ }, `${i}-${line}`))
3114
+ })
3115
+ ]
3116
+ });
3117
+ if (state.kind === "error") return /* @__PURE__ */ jsxs(Box, {
3118
+ flexDirection: "column",
3119
+ children: [/* @__PURE__ */ jsxs(Box, {
3120
+ flexDirection: "column",
3121
+ marginY: 1,
3122
+ children: [/* @__PURE__ */ jsxs(Text, {
3123
+ color: Colors.error,
3124
+ bold: true,
3125
+ children: [Icons.squareFilled, " Detection failed"]
3126
+ }), /* @__PURE__ */ jsx(Text, {
3127
+ dimColor: true,
3128
+ children: state.message
3129
+ })]
3130
+ }), /* @__PURE__ */ jsx(PickerMenu, {
3131
+ options: [{
3132
+ label: "Exit",
3133
+ value: EXIT
3134
+ }],
3135
+ onSelect: () => process.exit(1)
3136
+ })]
3137
+ });
3138
+ const { report } = state;
3139
+ const instrumentable = report.projects.filter((p) => p.instrumentable);
3140
+ const unsupported = report.projects.length - instrumentable.length;
3141
+ if (instrumentable.length === 0) return /* @__PURE__ */ jsxs(Box, {
3142
+ flexDirection: "column",
3143
+ children: [/* @__PURE__ */ jsxs(Box, {
3144
+ flexDirection: "column",
3145
+ marginBottom: 1,
3146
+ children: [/* @__PURE__ */ jsxs(Text, {
3147
+ color: Colors.error,
3148
+ bold: true,
3149
+ children: [Icons.squareFilled, " Nothing to set up here"]
3150
+ }), /* @__PURE__ */ jsxs(Text, {
3151
+ dimColor: true,
3152
+ children: [
3153
+ "None of the ",
3154
+ report.projects.length,
3155
+ " projects found uses a framework the wizard can set up error tracking for."
3156
+ ]
3157
+ })]
3158
+ }), /* @__PURE__ */ jsx(PickerMenu, {
3159
+ options: [{
3160
+ label: "Exit",
3161
+ value: EXIT
3162
+ }],
3163
+ onSelect: () => process.exit(0)
3164
+ })]
3165
+ });
3166
+ const options = [...instrumentable.map((p) => ({
3167
+ label: projectLabel$1(p),
3168
+ value: p.path
3169
+ })), {
3170
+ label: "Cancel",
3171
+ value: EXIT
3172
+ }];
3173
+ return /* @__PURE__ */ jsxs(Box, {
3174
+ flexDirection: "column",
3175
+ children: [
3176
+ /* @__PURE__ */ jsx(Box, {
3177
+ flexDirection: "column",
3178
+ marginBottom: 1,
3179
+ children: /* @__PURE__ */ jsxs(Text, {
3180
+ bold: true,
3181
+ color: Colors.accent,
3182
+ children: [
3183
+ Icons.check,
3184
+ " Found",
3185
+ " ",
3186
+ report.repoType === "monorepo" ? "a monorepo" : "your project"
3187
+ ]
3188
+ })
3189
+ }),
3190
+ /* @__PURE__ */ jsx(PickerMenu, {
3191
+ message: "Which project would you like to set up error tracking for?",
3192
+ options,
3193
+ onSelect: (value) => {
3194
+ const path = Array.isArray(value) ? value[0] : value;
3195
+ if (path === EXIT) {
3196
+ process.exit(0);
3197
+ return;
3198
+ }
3199
+ const chosen = instrumentable.find((p) => p.path === path);
3200
+ if (!chosen?.integration) return;
3201
+ store.setFrameworkContext(ERROR_TRACKING_PROJECT_PATH_KEY, chosen.path);
3202
+ store.setFrameworkConfig(chosen.integration, FRAMEWORK_REGISTRY[chosen.integration]);
3203
+ }
3204
+ }),
3205
+ unsupported > 0 && /* @__PURE__ */ jsx(Box, {
3206
+ marginTop: 1,
3207
+ children: /* @__PURE__ */ jsxs(Text, {
3208
+ dimColor: true,
3209
+ children: [
3210
+ "(… ",
3211
+ unsupported,
3212
+ " other project",
3213
+ unsupported === 1 ? "" : "s",
3214
+ " not supported)"
3215
+ ]
3216
+ })
3217
+ })
3218
+ ]
3219
+ });
3220
+ };
3221
+ //#endregion
2909
3222
  //#region src/ui/tui/screens/SelfDrivingIntroScreen.tsx
2910
3223
  /**
2911
3224
  * SelfDrivingIntroScreen — Welcome screen for the self-driving flow.
@@ -3993,17 +4306,6 @@ const AuditIntroScreen = ({ store }) => {
3993
4306
  });
3994
4307
  };
3995
4308
  //#endregion
3996
- //#region src/ui/tui/hooks/file-watcher.ts
3997
- /** React hook wrapping `startFileWatcher`. Starts on mount, stops on unmount
3998
- * or when `path` changes. `onUpdate` and `options` are captured at mount
3999
- * time — change `path` to restart with a new callback. */
4000
- function useFileWatcher(path, onUpdate, options = {}) {
4001
- useEffect(() => {
4002
- const handle = startFileWatcher(path, onUpdate, options);
4003
- return () => handle.stop();
4004
- }, [path]);
4005
- }
4006
- //#endregion
4007
4309
  //#region src/ui/tui/screens/audit/AuditAreaPane.tsx
4008
4310
  /**
4009
4311
  * AuditAreaPane — left-pane slide that follows whatever area the agent is
@@ -4582,7 +4884,6 @@ const PendingChecksList = ({ checks }) => {
4582
4884
  //#region src/ui/tui/screens/audit/AuditRunScreen.tsx
4583
4885
  const AuditRunScreen = ({ store }) => {
4584
4886
  useSyncExternalStore((cb) => store.subscribe(cb), () => store.getSnapshot());
4585
- useFileWatcher(join$1(store.session.installDir, AUDIT_CHECKS_FILE), (parsed) => store.setFrameworkContext(AUDIT_CHECKS_KEY, coerceAuditChecks(parsed)));
4586
4887
  const statuses = store.statusMessages.length > 0 ? store.statusMessages : void 0;
4587
4888
  const [columns] = useStdoutDimensions();
4588
4889
  const checks = getAuditChecks(store.session);
@@ -5313,19 +5614,23 @@ const KeepSkillsScreen = ({ store }) => {
5313
5614
  }
5314
5615
  if (result.length === 0) {
5315
5616
  store.setSkillsComplete(true);
5316
- process.exit(0);
5617
+ exit();
5618
+ return;
5317
5619
  }
5318
5620
  setSkills(result);
5319
5621
  setPhase("ask");
5320
5622
  } catch {
5321
5623
  store.setSkillsComplete(true);
5322
- process.exit(0);
5624
+ exit();
5323
5625
  }
5324
5626
  })();
5325
5627
  }, []);
5628
+ const exit = () => {
5629
+ if (!store.session.mintHandoff) process.exit(0);
5630
+ };
5326
5631
  const handleKeep = () => {
5327
5632
  store.setSkillsComplete(true);
5328
- process.exit(0);
5633
+ exit();
5329
5634
  };
5330
5635
  const handleRemove = async () => {
5331
5636
  setPhase("removing");
@@ -5344,7 +5649,7 @@ const KeepSkillsScreen = ({ store }) => {
5344
5649
  setPhase("done");
5345
5650
  setTimeout(() => {
5346
5651
  store.setSkillsComplete(false);
5347
- process.exit(0);
5652
+ exit();
5348
5653
  }, 600);
5349
5654
  };
5350
5655
  return /* @__PURE__ */ jsxs(Box, {
@@ -5430,6 +5735,340 @@ const KeepSkillsScreen = ({ store }) => {
5430
5735
  });
5431
5736
  };
5432
5737
  //#endregion
5738
+ //#region src/ui/tui/screens/MintFailureScreen.tsx
5739
+ /** Two blocks of the PostHog flag, left of the headline. */
5740
+ const Mark = () => /* @__PURE__ */ jsxs(Text, { children: [/* @__PURE__ */ jsx(Text, {
5741
+ color: "#1D4AFF",
5742
+ children: "█"
5743
+ }), /* @__PURE__ */ jsx(Text, {
5744
+ color: Colors.accent,
5745
+ children: "█"
5746
+ })] });
5747
+ function MintFailureScreen({ store, services }) {
5748
+ const [columns] = useStdoutDimensions();
5749
+ useSyncExternalStore((cb) => store.subscribe(cb), () => store.getSnapshot());
5750
+ const busy = useRef(false);
5751
+ const [working, setWorking] = useState(null);
5752
+ const [error, setError] = useState(null);
5753
+ const [report, setReport] = useState(false);
5754
+ const [retry, setRetry] = useState("save");
5755
+ const { spellbook } = store.session;
5756
+ const select = async (action) => {
5757
+ if (busy.current) return;
5758
+ if (action === "exit" || action === "continue") return store.setMintHandoff(action);
5759
+ if (action === "report") return setReport(true);
5760
+ const task = action === "retry" ? retry : action;
5761
+ setRetry(task);
5762
+ busy.current = true;
5763
+ setError(null);
5764
+ setWorking("Saving skill...");
5765
+ try {
5766
+ const saved = store.session.spellbook ?? await services.leaveSpellbook();
5767
+ store.setSpellbook(saved);
5768
+ if (task !== "save") {
5769
+ setWorking(`Opening ${task === "claude" ? "Claude Code" : "Codex"}...`);
5770
+ await services.openAgent(task, saved.path);
5771
+ store.setMintHandoff("continue");
5772
+ }
5773
+ } catch (err) {
5774
+ 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.");
5775
+ } finally {
5776
+ busy.current = false;
5777
+ setWorking(null);
5778
+ }
5779
+ };
5780
+ const options = error ? [
5781
+ {
5782
+ label: "Try again",
5783
+ value: "retry"
5784
+ },
5785
+ ...spellbook ? [{
5786
+ label: "Continue setup",
5787
+ value: "continue"
5788
+ }] : [],
5789
+ {
5790
+ label: "Exit",
5791
+ value: "exit"
5792
+ }
5793
+ ] : spellbook ? [{
5794
+ label: "Continue",
5795
+ value: "continue"
5796
+ }, {
5797
+ label: "Exit",
5798
+ value: "exit"
5799
+ }] : report ? [{
5800
+ label: "Save skill",
5801
+ value: "save"
5802
+ }, {
5803
+ label: "Exit",
5804
+ value: "exit"
5805
+ }] : [
5806
+ {
5807
+ label: "Save skill",
5808
+ value: "save"
5809
+ },
5810
+ {
5811
+ label: "Open in Claude Code",
5812
+ value: "claude"
5813
+ },
5814
+ {
5815
+ label: "Open in Codex",
5816
+ value: "codex"
5817
+ },
5818
+ {
5819
+ label: "Report this issue",
5820
+ value: "report"
5821
+ },
5822
+ {
5823
+ label: "Exit",
5824
+ value: "exit"
5825
+ }
5826
+ ];
5827
+ return /* @__PURE__ */ jsx(Box, {
5828
+ flexDirection: "column",
5829
+ flexGrow: 1,
5830
+ alignItems: "center",
5831
+ justifyContent: "center",
5832
+ children: /* @__PURE__ */ jsxs(Box, {
5833
+ width: Math.max(1, Math.min(78, columns - 4)),
5834
+ flexDirection: "column",
5835
+ alignItems: "center",
5836
+ children: [
5837
+ /* @__PURE__ */ jsxs(Text, {
5838
+ bold: true,
5839
+ children: [
5840
+ /* @__PURE__ */ jsx(Mark, {}),
5841
+ " ",
5842
+ spellbook ? "Skill saved" : MINT_FAILURE_MESSAGE,
5843
+ " 🦔"
5844
+ ]
5845
+ }),
5846
+ /* @__PURE__ */ jsx(Box, {
5847
+ marginTop: 1,
5848
+ 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 })
5849
+ }),
5850
+ report && !spellbook && /* @__PURE__ */ jsx(Box, {
5851
+ marginTop: 1,
5852
+ children: /* @__PURE__ */ jsx(Text, {
5853
+ color: "cyan",
5854
+ wrap: "wrap",
5855
+ children: services.logPath
5856
+ })
5857
+ }),
5858
+ spellbook && /* @__PURE__ */ jsx(Box, {
5859
+ marginTop: 1,
5860
+ children: /* @__PURE__ */ jsx(Text, {
5861
+ color: "cyan",
5862
+ wrap: "wrap",
5863
+ children: spellbook.path
5864
+ })
5865
+ }),
5866
+ error && /* @__PURE__ */ jsx(Box, {
5867
+ marginTop: 1,
5868
+ children: /* @__PURE__ */ jsx(Text, {
5869
+ color: Colors.error,
5870
+ children: error
5871
+ })
5872
+ }),
5873
+ /* @__PURE__ */ jsx(Box, {
5874
+ marginTop: 1,
5875
+ flexDirection: "column",
5876
+ children: working ? /* @__PURE__ */ jsx(Text, { children: working }) : /* @__PURE__ */ jsx(PickerMenu, {
5877
+ options,
5878
+ onSelect: (action) => void select(action)
5879
+ }, [
5880
+ report,
5881
+ Boolean(spellbook),
5882
+ Boolean(error)
5883
+ ].join("-"))
5884
+ })
5885
+ ]
5886
+ })
5887
+ });
5888
+ }
5889
+ //#endregion
5890
+ //#region src/ui/tui/services/coding-agent-launcher.ts
5891
+ const quote = (value) => `'${value.replace(/'/g, `'"'"'`)}'`;
5892
+ const batchQuote = (value) => `"${value.replace(/%/g, "%%")}"`;
5893
+ async function executable(name) {
5894
+ const extensions = process.platform === "win32" ? [
5895
+ ".exe",
5896
+ ".cmd",
5897
+ ".bat"
5898
+ ] : [""];
5899
+ for (const directory of (process.env.PATH ?? "").split(path$1.delimiter)) {
5900
+ if (!path$1.isAbsolute(directory)) continue;
5901
+ for (const extension of extensions) {
5902
+ const candidate = path$1.join(directory, name + extension);
5903
+ try {
5904
+ await access(candidate, constants.X_OK);
5905
+ return candidate;
5906
+ } catch {
5907
+ continue;
5908
+ }
5909
+ }
5910
+ }
5911
+ throw new Error(`${name === "claude" ? "Claude Code" : name === "codex" ? "Codex" : name} is not installed or could not be found.`);
5912
+ }
5913
+ function launch(command, args, cwd, verbatim = false) {
5914
+ return new Promise((resolve, reject) => {
5915
+ const child = spawn(command, args, {
5916
+ cwd,
5917
+ stdio: "ignore",
5918
+ detached: true,
5919
+ shell: false,
5920
+ windowsVerbatimArguments: verbatim
5921
+ });
5922
+ const timer = setTimeout(() => {
5923
+ child.unref();
5924
+ resolve();
5925
+ }, 500);
5926
+ child.once("error", (error) => {
5927
+ clearTimeout(timer);
5928
+ reject(error);
5929
+ });
5930
+ child.once("exit", (code) => {
5931
+ clearTimeout(timer);
5932
+ if (code === 0) resolve();
5933
+ else reject(/* @__PURE__ */ new Error("Could not open a terminal for your agent."));
5934
+ });
5935
+ });
5936
+ }
5937
+ async function openCodingAgent(agent, directory, spellbookPath) {
5938
+ const cwd = path$1.resolve(directory);
5939
+ const command = await executable(agent);
5940
+ 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.`;
5941
+ if (process.platform === "linux") {
5942
+ await launch(await executable("x-terminal-emulator"), [
5943
+ "-e",
5944
+ command,
5945
+ prompt
5946
+ ], cwd);
5947
+ return;
5948
+ }
5949
+ const mac = process.platform === "darwin";
5950
+ if (!mac && process.platform !== "win32") throw new Error("Opening an agent is not supported on this system. Use the saved skill path to continue.");
5951
+ const folder = await mkdtemp(path$1.join(tmpdir(), "wizard-handoff-"));
5952
+ const script = path$1.join(folder, mac ? "open-agent.command" : "open-agent.cmd");
5953
+ try {
5954
+ await writeFile(script, (mac ? [
5955
+ "#!/bin/sh",
5956
+ `rm -f ${quote(script)}`,
5957
+ `rmdir ${quote(folder)}`,
5958
+ `export PATH=${quote(process.env.PATH ?? "")}`,
5959
+ `cd ${quote(cwd)} || exit 1`,
5960
+ `exec ${quote(command)} ${quote(prompt)}`
5961
+ ] : [
5962
+ "@echo off",
5963
+ "chcp 65001 >nul",
5964
+ "setlocal DisableDelayedExpansion",
5965
+ `cd /d ${batchQuote(cwd)} || exit /b 1`,
5966
+ `del "%~f0" & rmdir ${batchQuote(folder)} & ${batchQuote(command)} ${batchQuote(prompt)}`
5967
+ ]).join(mac ? "\n" : "\r\n") + "\n", { mode: 448 });
5968
+ if (mac) {
5969
+ await launch("/usr/bin/open", [script], cwd);
5970
+ return;
5971
+ }
5972
+ const shell = process.env.ComSpec ?? "cmd.exe";
5973
+ await launch(shell, [
5974
+ "/d",
5975
+ "/s",
5976
+ "/c",
5977
+ `"start "" ${shell} /d /c "${script}""`
5978
+ ], folder, true);
5979
+ } catch (error) {
5980
+ await rm(folder, {
5981
+ recursive: true,
5982
+ force: true
5983
+ });
5984
+ throw error;
5985
+ }
5986
+ }
5987
+ //#endregion
5988
+ //#region src/lib/wizard-spellbook.ts
5989
+ function selectSkills(menu, session, program) {
5990
+ const entries = Object.values(menu.categories).flat().filter((entry) => /^[a-z0-9]+(?:-[a-z0-9]+)*$/.test(entry.id));
5991
+ const skillId = program.skillId ?? session.skillId;
5992
+ const exact = entries.find((entry) => entry.id === skillId);
5993
+ if (exact) return [exact];
5994
+ const framework = session.integration;
5995
+ const referenceGroup = skillId === framework ? "integration" : skillId;
5996
+ const references = entries.filter((entry) => entry.group === referenceGroup && entry.framework === framework);
5997
+ const reference = references.find((entry) => entry.default) ?? references[0];
5998
+ if (reference) return [reference];
5999
+ const flow = program.agentFlow ?? program.id;
6000
+ const groups = /* @__PURE__ */ new Map();
6001
+ for (const entry of entries) {
6002
+ const group = entry.group;
6003
+ if (!group || group !== flow && !group.startsWith(`${flow}-`) || entry.framework && entry.framework !== framework) continue;
6004
+ if (!groups.has(group) || entry.default) groups.set(group, entry);
6005
+ }
6006
+ return [...groups.values()];
6007
+ }
6008
+ function spellbookText(session, program, skills) {
6009
+ const framework = session.frameworkConfig?.metadata;
6010
+ const runDocs = typeof program.run === "object" ? program.run.docsUrl : void 0;
6011
+ const docs = [...new Set([
6012
+ framework?.docsUrl,
6013
+ runDocs,
6014
+ POSTHOG_DOCS_URL
6015
+ ])].filter((url) => Boolean(url));
6016
+ return [
6017
+ "# Wizard spell book",
6018
+ "",
6019
+ "Complete this task in the project containing this spell book:",
6020
+ "",
6021
+ program.description,
6022
+ "",
6023
+ `Wizard program: ${program.id}`,
6024
+ ...framework ? [`Detected framework: ${framework.name}`] : [],
6025
+ "",
6026
+ "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.",
6027
+ "",
6028
+ "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.",
6029
+ "",
6030
+ "## Setup instructions",
6031
+ "",
6032
+ ...skills.length ? [
6033
+ "Read the downloaded skills and their referenced files:",
6034
+ "",
6035
+ ...skills.map((skill) => `- [${skill.id}](skills/${skill.id}/SKILL.md)`),
6036
+ "",
6037
+ "Downloaded skills may cover only part of the task. Use the official documentation below to fill any gaps."
6038
+ ] : ["No matching skills could be downloaded. Use the official documentation below to complete the task."],
6039
+ "",
6040
+ "## Official documentation",
6041
+ "",
6042
+ ...docs.map((url) => `- ${url}`),
6043
+ ""
6044
+ ].join("\n");
6045
+ }
6046
+ async function writeWizardSpellbook(session, program) {
6047
+ const parent = path.join(session.installDir, ".posthog");
6048
+ await fs$1.mkdir(parent, { recursive: true });
6049
+ const directory = await fs$1.mkdtemp(path.join(parent, "wizard-spellbook-"));
6050
+ const readme = path.join(directory, "README.md");
6051
+ await fs$1.writeFile(readme, spellbookText(session, program, []));
6052
+ const menu = await fetchSkillMenu(getSkillsBaseUrl(), {
6053
+ timeoutMs: 1e4,
6054
+ maxAttempts: 1
6055
+ });
6056
+ const installed = [];
6057
+ for (const skill of menu ? selectSkills(menu, session, program) : []) if ((await downloadSkill(skill, directory, {
6058
+ skillsRoot: "skills",
6059
+ triage: void 0
6060
+ })).success) installed.push(skill);
6061
+ else await fs$1.rm(path.join(directory, "skills", skill.id), {
6062
+ recursive: true,
6063
+ force: true
6064
+ });
6065
+ await fs$1.writeFile(readme, spellbookText(session, program, installed));
6066
+ return {
6067
+ path: readme,
6068
+ skillsIncluded: installed.length > 0
6069
+ };
6070
+ }
6071
+ //#endregion
5433
6072
  //#region src/ui/tui/screens/ExitScreen.tsx
5434
6073
  /**
5435
6074
  * ExitScreen — Final step in every program.
@@ -5437,9 +6076,9 @@ const KeepSkillsScreen = ({ store }) => {
5437
6076
  * Renders nothing. Immediately exits the process.
5438
6077
  * The cleanup handler in start-tui.ts handles the exit summary line.
5439
6078
  */
5440
- const ExitScreen = () => {
6079
+ const ExitScreen = ({ store }) => {
5441
6080
  useEffect(() => {
5442
- process.exit(0);
6081
+ if (!store?.session.mintHandoff) process.exit(0);
5443
6082
  }, []);
5444
6083
  return null;
5445
6084
  };
@@ -5705,6 +6344,42 @@ function handleAskKey(key, store) {
5705
6344
  if (key.escape) store.cancelPendingQuestion();
5706
6345
  }
5707
6346
  /**
6347
+ * What pressing Esc actually does, phrased for the footer hint.
6348
+ *
6349
+ * Esc declines the *whole* request — {@link WizardStore.cancelPendingQuestion}
6350
+ * builds a cancelled answer for every question, so the ones already typed are
6351
+ * discarded too. The footer used to label that "skip", which on a multi-question
6352
+ * request reads as "skip this field": the warehouse task walks a source's
6353
+ * credentials one field at a time, several of them optional, and a user who
6354
+ * pressed Esc to pass on an optional field instead threw away the whole source
6355
+ * and dropped the agent onto its browser-handoff fallback. Naming the scope
6356
+ * costs a few characters and makes the destructive key read as destructive.
6357
+ */
6358
+ function askEscapeHint(total, answered) {
6359
+ if (total <= 1) return "skip";
6360
+ if (answered <= 0) return `skip all ${total} questions`;
6361
+ return `skip all ${total} questions, discarding the ${answered} you answered`;
6362
+ }
6363
+ /**
6364
+ * Whether the overlay must mask what the user types for this question.
6365
+ *
6366
+ * A `sensitive` answer is one the wizard has already promised to treat as a
6367
+ * secret: `wizard_ask` vaults it and hands the agent an opaque `secretRef`, so
6368
+ * the raw string never enters the model's conversation. Every other boundary
6369
+ * guards it the same way — the skip events carry no free text, handoff prose is
6370
+ * kept out of telemetry — but the overlay that collects it echoed it back in
6371
+ * plain text as it was typed, which is the one place a database password or an
6372
+ * API key is read by a person other than its owner: a shared screen, a pairing
6373
+ * session, a recorded terminal.
6374
+ *
6375
+ * `kind` is checked as well as the flag. The tool already rejects `sensitive`
6376
+ * on a picker, and a picker has nothing to mask, so this keeps the predicate
6377
+ * total over a question rather than relying on that rejection.
6378
+ */
6379
+ function shouldMaskAnswer(question) {
6380
+ return question.kind === "text" && question.sensitive === true;
6381
+ }
6382
+ /**
5708
6383
  * Whether an answer would leave a required question effectively unanswered.
5709
6384
  *
5710
6385
  * The `wizard_ask` schema marks fields `required` (defaulting to true), but the
@@ -5776,6 +6451,8 @@ const WizardAskScreen = ({ store }) => {
5776
6451
  if (!question) return null;
5777
6452
  const total = pending.questions.length;
5778
6453
  const progress = total > 1 ? `Question ${index + 1} of ${total}` : null;
6454
+ const escapeHint = askEscapeHint(total, index);
6455
+ const canSkipOne = question.kind === "text" && question.required === false;
5779
6456
  const submit = (value) => {
5780
6457
  if (isRequiredButEmpty(question, value)) {
5781
6458
  setRequiredHint(true);
@@ -5850,17 +6527,40 @@ const WizardAskScreen = ({ store }) => {
5850
6527
  marginTop: 1,
5851
6528
  children: /* @__PURE__ */ jsxs(Text, {
5852
6529
  color: Colors.accent,
5853
- children: [Icons.warning, " This field is required — type an answer, or press ESC to skip."]
6530
+ children: [
6531
+ Icons.warning,
6532
+ " This field is required — type an answer, or press ESC to ",
6533
+ escapeHint,
6534
+ "."
6535
+ ]
6536
+ })
6537
+ }),
6538
+ canSkipOne && /* @__PURE__ */ jsx(Box, {
6539
+ marginTop: 1,
6540
+ children: /* @__PURE__ */ jsxs(Text, {
6541
+ dimColor: true,
6542
+ children: [
6543
+ "Optional — press ",
6544
+ /* @__PURE__ */ jsx(Text, {
6545
+ color: Colors.accent,
6546
+ children: "ENTER"
6547
+ }),
6548
+ " on an empty answer to skip just this one."
6549
+ ]
5854
6550
  })
5855
6551
  }),
5856
6552
  /* @__PURE__ */ jsx(Box, {
5857
6553
  marginTop: 1,
5858
6554
  children: /* @__PURE__ */ jsxs(Text, {
5859
6555
  dimColor: true,
5860
- children: [/* @__PURE__ */ jsx(Text, {
5861
- color: Colors.accent,
5862
- children: "ESC"
5863
- }), " skip"]
6556
+ children: [
6557
+ /* @__PURE__ */ jsx(Text, {
6558
+ color: Colors.accent,
6559
+ children: "ESC"
6560
+ }),
6561
+ " ",
6562
+ escapeHint
6563
+ ]
5864
6564
  })
5865
6565
  })
5866
6566
  ]
@@ -5895,7 +6595,7 @@ const QuestionInput = ({ question, onSubmit }) => {
5895
6595
  case "text": return /* @__PURE__ */ jsxs(Box, {
5896
6596
  flexDirection: "column",
5897
6597
  width: "100%",
5898
- children: [/* @__PURE__ */ jsx(TextInput, {
6598
+ children: [/* @__PURE__ */ jsx(shouldMaskAnswer(question) ? PasswordInput : TextInput, {
5899
6599
  placeholder: "Type your answer",
5900
6600
  onSubmit: (value) => onSubmit(value)
5901
6601
  }), /* @__PURE__ */ jsx(Box, {
@@ -6048,13 +6748,18 @@ function createMcpSuggestedPromptsServices(store) {
6048
6748
  };
6049
6749
  }
6050
6750
  async function* runProductionPromptStreaming(args) {
6051
- const { runMcpPromptViaSdk } = await import("./mcp-prompt-streaming-BvvCZBYa.js");
6751
+ const { runMcpPromptViaSdk } = await import("./mcp-prompt-streaming-BvBNkzjv.js");
6052
6752
  yield* runMcpPromptViaSdk(args);
6053
6753
  }
6054
6754
  //#endregion
6055
6755
  //#region src/ui/tui/screen-registry.tsx
6056
6756
  function createServices(store) {
6057
6757
  return {
6758
+ get logPath() {
6759
+ return path$1.resolve(getLogFilePath());
6760
+ },
6761
+ openAgent: (agent, spellbookPath) => openCodingAgent(agent, store.session.installDir, spellbookPath),
6762
+ leaveSpellbook: () => writeWizardSpellbook(store.session, getProgramConfig(store.router.activeProgram)),
6058
6763
  mcpInstaller: createMcpInstaller(),
6059
6764
  mcpSuggestedPromptsServices: createMcpSuggestedPromptsServices(store)
6060
6765
  };
@@ -6079,6 +6784,8 @@ function createScreens(store, services) {
6079
6784
  ["agent-skill-intro"]: /* @__PURE__ */ jsx(AgentSkillIntroScreen, { store }),
6080
6785
  ["ai-observability-intro"]: /* @__PURE__ */ jsx(AiObservabilityIntroScreen, { store }),
6081
6786
  ["metrics-intro"]: /* @__PURE__ */ jsx(MetricsIntroScreen, { store }),
6787
+ ["error-tracking-intro"]: /* @__PURE__ */ jsx(ErrorTrackingIntroScreen, { store }),
6788
+ ["error-tracking-detect"]: /* @__PURE__ */ jsx(ErrorTrackingDetectScreen, { store }),
6082
6789
  ["self-driving-intro"]: /* @__PURE__ */ jsx(SelfDrivingIntroScreen, { store }),
6083
6790
  ["self-driving-integration-check"]: /* @__PURE__ */ jsx(SelfDrivingIntegrationCheckScreen, { store }),
6084
6791
  ["self-driving-integration-detect"]: /* @__PURE__ */ jsx(SelfDrivingIntegrationDetectScreen, { store }),
@@ -6105,7 +6812,11 @@ function createScreens(store, services) {
6105
6812
  ["slack-connect"]: /* @__PURE__ */ jsx(SlackConnectScreen, { store }),
6106
6813
  ["keep-skills"]: /* @__PURE__ */ jsx(KeepSkillsScreen, { store }),
6107
6814
  ["outro"]: /* @__PURE__ */ jsx(OutroScreen, { store }),
6108
- ["exit"]: /* @__PURE__ */ jsx(ExitScreen, {}),
6815
+ ["mint-failure"]: /* @__PURE__ */ jsx(MintFailureScreen, {
6816
+ store,
6817
+ services
6818
+ }),
6819
+ ["exit"]: /* @__PURE__ */ jsx(ExitScreen, { store }),
6109
6820
  ["mcp-add"]: /* @__PURE__ */ jsx(McpScreen, {
6110
6821
  store,
6111
6822
  installer: services.mcpInstaller
@@ -6177,6 +6888,16 @@ function getExitLine(store) {
6177
6888
  const label = store.session.programLabel ?? "Wizard";
6178
6889
  const costLine = tokenCostLine(store);
6179
6890
  const loginBlock = mcpLoginBlock(store);
6891
+ if (isRunFailure(store.session)) {
6892
+ const spellbook = store.session.spellbook;
6893
+ return [
6894
+ "The wizard is unavailable. Setup has not been completed.",
6895
+ spellbook && `${DIM}Point your agent at this skill (triple-click to select):${RESET_ATTRS}\n${spellbook.path}`,
6896
+ `${DIM}${MINT_FAILURE_CONTACT}${RESET_ATTRS}\n${getLogFilePath()}`,
6897
+ loginBlock,
6898
+ costLine
6899
+ ].filter(Boolean).join("\n\n");
6900
+ }
6180
6901
  if (outro?.kind === "success") {
6181
6902
  const message = outro.message ?? `${label} completed successfully.`;
6182
6903
  const parts = [`${GREEN}${BOLD}✔${RESET_ATTRS} ${message}${outro.reportFile && !message.includes(outro.reportFile) ? ` Check ./${outro.reportFile} for details.` : ""}`];
@@ -6242,4 +6963,4 @@ function startTUI(version, program = Program.PostHogIntegration) {
6242
6963
  //#endregion
6243
6964
  export { startTUI };
6244
6965
 
6245
- //# sourceMappingURL=start-tui-B7u962uh.js.map
6966
+ //# sourceMappingURL=start-tui-Bz23_yym.js.map