@posthog/wizard 2.80.0 → 2.80.1

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 (227) hide show
  1. package/README.md +187 -57
  2. package/dist/{PickerMenu-m4CCPX4f.js → PickerMenu-BGGeYqd-.js} +104 -4
  3. package/dist/PickerMenu-BGGeYqd-.js.map +1 -0
  4. package/dist/README.md +9 -6
  5. package/dist/{agent-interface-CzyCmp7q.js → agent-interface-CemBvTAA.js} +115 -346
  6. package/dist/agent-interface-CemBvTAA.js.map +1 -0
  7. package/dist/{agent-prompt-loader-4wMxlYSX.js → agent-prompt-loader-DPnj6SwU.js} +6 -5
  8. package/dist/agent-prompt-loader-DPnj6SwU.js.map +1 -0
  9. package/dist/analytics-B3ROGuIr.js +2 -0
  10. package/dist/analytics-D21z3E5l.js +732 -0
  11. package/dist/analytics-D21z3E5l.js.map +1 -0
  12. package/dist/{api-C3Dc4LFl.js → api-DtGIqQ2U.js} +2 -3
  13. package/dist/api-DtGIqQ2U.js.map +1 -0
  14. package/dist/api-IhROOQNv.js +2 -0
  15. package/dist/api-key-login-OEntFvu5.js +2 -0
  16. package/dist/api-key-login-h3E2G3zu.js +55 -0
  17. package/dist/api-key-login-h3E2G3zu.js.map +1 -0
  18. package/dist/bin.js +2 -2
  19. package/dist/bin.js.map +1 -1
  20. package/dist/{bounded-fs-CC_NDtoP.js → bounded-fs-CAsuF6al.js} +3 -3
  21. package/dist/{bounded-fs-CC_NDtoP.js.map → bounded-fs-CAsuF6al.js.map} +1 -1
  22. package/dist/{ci-install-DfcAMhlu.js → ci-install-CEYE02t-.js} +21 -25
  23. package/dist/ci-install-CEYE02t-.js.map +1 -0
  24. package/dist/console-log-O828zyiq.js +32 -0
  25. package/dist/console-log-O828zyiq.js.map +1 -0
  26. package/dist/{debug-DyARf5TF.js → debug-BfQPD2Hg.js} +18 -52
  27. package/dist/debug-BfQPD2Hg.js.map +1 -0
  28. package/dist/{defaults-DpfMnH2q.js → defaults-DDVl3tKN.js} +2 -51
  29. package/dist/defaults-DDVl3tKN.js.map +1 -0
  30. package/dist/{emit-BSetXzDV.js → emit-RfAewcWv.js} +1 -1
  31. package/dist/{emit-BSetXzDV.js.map → emit-RfAewcWv.js.map} +1 -1
  32. package/dist/{errors-C2domSkK.js → errors-CHrJzAZb.js} +4 -4
  33. package/dist/{errors-C2domSkK.js.map → errors-CHrJzAZb.js.map} +1 -1
  34. package/dist/family-picker-BKs-tTyu.js +46 -0
  35. package/dist/family-picker-BKs-tTyu.js.map +1 -0
  36. package/dist/{gateway-BmjYUSua.js → gateway-D3gIlR6b.js} +122 -11
  37. package/dist/gateway-D3gIlR6b.js.map +1 -0
  38. package/dist/headless-BJjhP0SI.js +10 -0
  39. package/dist/headless-BJjhP0SI.js.map +1 -0
  40. package/dist/headless-DIX68UUA.js +3 -0
  41. package/dist/{host-resolution-DVSb7kXb.js → host-resolution-D8GhEVoX.js} +4 -4
  42. package/dist/{host-resolution-DVSb7kXb.js.map → host-resolution-D8GhEVoX.js.map} +1 -1
  43. package/dist/install-Bw8tvDvS.js +2 -0
  44. package/dist/{install-Bk5TNk27.js → install-paPCzPHI.js} +26 -93
  45. package/dist/install-paPCzPHI.js.map +1 -0
  46. package/dist/interactive-tdxZKWax.js +11 -0
  47. package/dist/interactive-tdxZKWax.js.map +1 -0
  48. package/dist/{links-9LWZPSCq.js → links-Cyj6v8kg.js} +3 -3
  49. package/dist/{links-9LWZPSCq.js.map → links-Cyj6v8kg.js.map} +1 -1
  50. package/dist/{main-DKPjFHEV.js → main-0p-YxUNa.js} +204 -469
  51. package/dist/main-0p-YxUNa.js.map +1 -0
  52. package/dist/{mcp-Co8VRF62.js → mcp-D3Z5MXhA.js} +3 -4
  53. package/dist/{mcp-Co8VRF62.js.map → mcp-D3Z5MXhA.js.map} +1 -1
  54. package/dist/mcp-install-smoke-test.ts +2 -2
  55. package/dist/{mcp-prompt-streaming-ljCVoQ9I.js → mcp-prompt-streaming-COVbWnHt.js} +12 -12
  56. package/dist/mcp-prompt-streaming-COVbWnHt.js.map +1 -0
  57. package/dist/mode-label-DB3ol_sj.js +9 -0
  58. package/dist/mode-label-DB3ol_sj.js.map +1 -0
  59. package/dist/{models-Dba8ITeo.js → models-D1SnCzvl.js} +2 -2
  60. package/dist/{models-Dba8ITeo.js.map → models-D1SnCzvl.js.map} +1 -1
  61. package/dist/non-interactive-DxRBc73O.js +18 -0
  62. package/dist/non-interactive-DxRBc73O.js.map +1 -0
  63. package/dist/{oauth-session-D-RfcVmr.js → oauth-session-Dde79Ycm.js} +3 -3
  64. package/dist/{oauth-session-D-RfcVmr.js.map → oauth-session-Dde79Ycm.js.map} +1 -1
  65. package/dist/{orchestrator-tools-CVJ1F9Ub.js → orchestrator-tools-BSNhzzkT.js} +3 -3
  66. package/dist/{orchestrator-tools-CVJ1F9Ub.js.map → orchestrator-tools-BSNhzzkT.js.map} +1 -1
  67. package/dist/{package-json-Cowya9-3.js → package-json-2UrhE6kP.js} +1 -1
  68. package/dist/{package-json-Cowya9-3.js.map → package-json-2UrhE6kP.js.map} +1 -1
  69. package/dist/package-json-Dblip2_X.js +2 -0
  70. package/dist/package-manager-BRXlXo0p.js +105 -0
  71. package/dist/package-manager-BRXlXo0p.js.map +1 -0
  72. package/dist/{pi-B5YTBRDv.js → pi-cM_4Gd_9.js} +16 -18
  73. package/dist/pi-cM_4Gd_9.js.map +1 -0
  74. package/dist/playground-DTKy0XHT.js +12 -0
  75. package/dist/playground-DTKy0XHT.js.map +1 -0
  76. package/dist/posthog-integration-bwHwE87a.js +10291 -0
  77. package/dist/posthog-integration-bwHwE87a.js.map +1 -0
  78. package/dist/programs-BhtyA3lE.js +3 -0
  79. package/dist/programs-SeT1qNik.js +5348 -0
  80. package/dist/programs-SeT1qNik.js.map +1 -0
  81. package/dist/provisioning-BcXfeCMc.js +2 -0
  82. package/dist/{provisioning-CLhuKqXH.js → provisioning-JbJtq7hq.js} +4 -5
  83. package/dist/{provisioning-CLhuKqXH.js.map → provisioning-JbJtq7hq.js.map} +1 -1
  84. package/dist/{queue-tools-knnPQP0e.js → queue-tools-BIZSJyt6.js} +6 -8
  85. package/dist/queue-tools-BIZSJyt6.js.map +1 -0
  86. package/dist/results-DtKICAdz.js +55 -0
  87. package/dist/results-DtKICAdz.js.map +1 -0
  88. package/dist/run-CDurA5tO.js +248 -0
  89. package/dist/run-CDurA5tO.js.map +1 -0
  90. package/dist/run-DDCvLILJ.js +246 -0
  91. package/dist/run-DDCvLILJ.js.map +1 -0
  92. package/dist/run-tool-CTq9OOdT.js +2 -0
  93. package/dist/run-tool-DML8JJvt.js +2420 -0
  94. package/dist/run-tool-DML8JJvt.js.map +1 -0
  95. package/dist/runners-Dhu4pZTN.js +253 -0
  96. package/dist/runners-Dhu4pZTN.js.map +1 -0
  97. package/dist/{security-BvdSFDuM.js → security-DEH8Rn0_.js} +5 -5
  98. package/dist/security-DEH8Rn0_.js.map +1 -0
  99. package/dist/setup-utils-C5-WM-hS.js +118 -0
  100. package/dist/setup-utils-C5-WM-hS.js.map +1 -0
  101. package/dist/smoke-test.sh +1 -1
  102. package/dist/{playground-BLsCfHmQ.js → start-playground-DL4mVEUx.js} +43 -34
  103. package/dist/start-playground-DL4mVEUx.js.map +1 -0
  104. package/dist/{subagent-D_Sqak94.js → subagent-CnFvAq6E.js} +3 -3
  105. package/dist/{subagent-D_Sqak94.js.map → subagent-CnFvAq6E.js.map} +1 -1
  106. package/dist/{task-DiTI6Sak.js → task-BOScSm4W.js} +16 -17
  107. package/dist/task-BOScSm4W.js.map +1 -0
  108. package/dist/{tasks-ChZ_F1YP.js → tasks-BfJhVky2.js} +1 -1
  109. package/dist/tasks-BfJhVky2.js.map +1 -0
  110. package/dist/{telemetry-BNKsDxNS.js → telemetry-CP4rGicd.js} +2 -2
  111. package/dist/{telemetry-BNKsDxNS.js.map → telemetry-CP4rGicd.js.map} +1 -1
  112. package/dist/terminal-J3OD3dN0.js +16162 -0
  113. package/dist/terminal-J3OD3dN0.js.map +1 -0
  114. package/dist/tools-CCMV3DmB.js +544 -0
  115. package/dist/tools-CCMV3DmB.js.map +1 -0
  116. package/dist/{tools-C8LQ8QFz.js → tools-Cz8tDptL.js} +9 -9
  117. package/dist/tools-Cz8tDptL.js.map +1 -0
  118. package/dist/tui-BUZ2PWqN.js +2 -0
  119. package/dist/tui-Csf7VJxt.js +25 -0
  120. package/dist/tui-Csf7VJxt.js.map +1 -0
  121. package/dist/{steps-Hc28zVc_.js → upload-step-CEacB2RV.js} +14 -16
  122. package/dist/upload-step-CEacB2RV.js.map +1 -0
  123. package/dist/{urls-BI4kJ4qQ.js → urls-BDELGZHq.js} +2 -2
  124. package/dist/{urls-BI4kJ4qQ.js.map → urls-BDELGZHq.js.map} +1 -1
  125. package/dist/warlock-smoke-test.ts +1 -2
  126. package/dist/{wizard-abort-DBKtfnBR.js → wizard-abort-D3-75KyV.js} +40 -33
  127. package/dist/wizard-abort-D3-75KyV.js.map +1 -0
  128. package/dist/yara-hooks-CZ1tKxy_.js +2 -0
  129. package/dist/{yara-hooks-C3L6lBij.js → yara-hooks-D8YDyX7o.js} +283 -21
  130. package/dist/yara-hooks-D8YDyX7o.js.map +1 -0
  131. package/package.json +6 -6
  132. package/dist/PickerMenu-m4CCPX4f.js.map +0 -1
  133. package/dist/agent-BkBbVuNq.js +0 -3189
  134. package/dist/agent-BkBbVuNq.js.map +0 -1
  135. package/dist/agent-QGK2YzlX.js +0 -6
  136. package/dist/agent-interface-CzyCmp7q.js.map +0 -1
  137. package/dist/agent-prompt-loader-4wMxlYSX.js.map +0 -1
  138. package/dist/analytics-B6q5PN7a.js +0 -301
  139. package/dist/analytics-B6q5PN7a.js.map +0 -1
  140. package/dist/analytics-BXtfK9o7.js +0 -2
  141. package/dist/api-C3Dc4LFl.js.map +0 -1
  142. package/dist/api-yNjrfZs2.js +0 -2
  143. package/dist/check-screens.tsx +0 -190
  144. package/dist/ci-install-DfcAMhlu.js.map +0 -1
  145. package/dist/constants-DO4X70po.js +0 -260
  146. package/dist/constants-DO4X70po.js.map +0 -1
  147. package/dist/debug-BueK5mRR.js +0 -2
  148. package/dist/debug-DyARf5TF.js.map +0 -1
  149. package/dist/defaults-DpfMnH2q.js.map +0 -1
  150. package/dist/endpoints-D-4KxZiB.js +0 -108
  151. package/dist/endpoints-D-4KxZiB.js.map +0 -1
  152. package/dist/env-api-key-CHGLe0iz.js +0 -2
  153. package/dist/env-api-key-COf0U-Au.js +0 -17
  154. package/dist/env-api-key-COf0U-Au.js.map +0 -1
  155. package/dist/environment-DrLaSsA8.js +0 -39
  156. package/dist/environment-DrLaSsA8.js.map +0 -1
  157. package/dist/environment-hBj7ngmO.js +0 -2
  158. package/dist/file-CVA9ocIC.js +0 -60
  159. package/dist/file-CVA9ocIC.js.map +0 -1
  160. package/dist/file-CmoKK_Pp.js +0 -2
  161. package/dist/file-watcher-C3Su8vXm.js +0 -123
  162. package/dist/file-watcher-C3Su8vXm.js.map +0 -1
  163. package/dist/gateway-BmjYUSua.js.map +0 -1
  164. package/dist/headless-ui-CUbv12Yx.js +0 -44
  165. package/dist/headless-ui-CUbv12Yx.js.map +0 -1
  166. package/dist/install-Bk5TNk27.js.map +0 -1
  167. package/dist/install-F4wm3RSl.js +0 -2
  168. package/dist/interactive-C5LNvDj6.js +0 -11
  169. package/dist/interactive-C5LNvDj6.js.map +0 -1
  170. package/dist/local-dev-McsurOC-.js +0 -135
  171. package/dist/local-dev-McsurOC-.js.map +0 -1
  172. package/dist/logging-ui-p6XKVmTx.js +0 -226
  173. package/dist/logging-ui-p6XKVmTx.js.map +0 -1
  174. package/dist/main-DKPjFHEV.js.map +0 -1
  175. package/dist/mcp-prompt-streaming-ljCVoQ9I.js.map +0 -1
  176. package/dist/mint-failure-C0HyvEwO.js +0 -6403
  177. package/dist/mint-failure-C0HyvEwO.js.map +0 -1
  178. package/dist/non-interactive-CLMJrj_7.js +0 -18
  179. package/dist/non-interactive-CLMJrj_7.js.map +0 -1
  180. package/dist/package-json--ppioh2F.js +0 -2
  181. package/dist/pi-B5YTBRDv.js.map +0 -1
  182. package/dist/playground-BLsCfHmQ.js.map +0 -1
  183. package/dist/posthog-B2E0hpZt.js +0 -2
  184. package/dist/posthog-B42rt_1S.js +0 -124
  185. package/dist/posthog-B42rt_1S.js.map +0 -1
  186. package/dist/project-data--L-WZyvj.js +0 -2
  187. package/dist/project-data-BO9IXn9y.js +0 -1131
  188. package/dist/project-data-BO9IXn9y.js.map +0 -1
  189. package/dist/provisioning-C01REIU2.js +0 -2
  190. package/dist/queue-tools-knnPQP0e.js.map +0 -1
  191. package/dist/registry-B3rC5U4b.js +0 -3464
  192. package/dist/registry-B3rC5U4b.js.map +0 -1
  193. package/dist/registry-BamsM7J9.js +0 -2
  194. package/dist/run-agent-legacy-CwUmPfQF.js +0 -2
  195. package/dist/run-agent-legacy-DWBajsMh.js +0 -3467
  196. package/dist/run-agent-legacy-DWBajsMh.js.map +0 -1
  197. package/dist/runners-D1PqqpjA.js +0 -834
  198. package/dist/runners-D1PqqpjA.js.map +0 -1
  199. package/dist/security-BvdSFDuM.js.map +0 -1
  200. package/dist/setup-utils-ChXXTi1m.js +0 -301
  201. package/dist/setup-utils-ChXXTi1m.js.map +0 -1
  202. package/dist/start-tui-DicLfgsj.js +0 -6964
  203. package/dist/start-tui-DicLfgsj.js.map +0 -1
  204. package/dist/steps-Hc28zVc_.js.map +0 -1
  205. package/dist/store-COCO6U0P.js +0 -5
  206. package/dist/store-D3509G87.js +0 -1030
  207. package/dist/store-D3509G87.js.map +0 -1
  208. package/dist/task-DiTI6Sak.js.map +0 -1
  209. package/dist/task-status-CmrrR7zo.js +0 -16
  210. package/dist/task-status-CmrrR7zo.js.map +0 -1
  211. package/dist/task-stream-BckhG_cB.js +0 -363
  212. package/dist/task-stream-BckhG_cB.js.map +0 -1
  213. package/dist/tasks-ChZ_F1YP.js.map +0 -1
  214. package/dist/terminal-PK9bCLRi.js +0 -7222
  215. package/dist/terminal-PK9bCLRi.js.map +0 -1
  216. package/dist/tools-C8LQ8QFz.js.map +0 -1
  217. package/dist/ui-tPNpM6vj.js +0 -15
  218. package/dist/ui-tPNpM6vj.js.map +0 -1
  219. package/dist/version-5_ydHkM6.js +0 -6
  220. package/dist/version-5_ydHkM6.js.map +0 -1
  221. package/dist/wizard-abort-BVjqLyeA.js +0 -3
  222. package/dist/wizard-abort-DBKtfnBR.js.map +0 -1
  223. package/dist/wizard-session-B7BHnay0.js +0 -2
  224. package/dist/wizard-session-BYw6LzpS.js +0 -133
  225. package/dist/wizard-session-BYw6LzpS.js.map +0 -1
  226. package/dist/yara-hooks-C3L6lBij.js.map +0 -1
  227. package/dist/yara-hooks-CF_IsoaA.js +0 -2
@@ -0,0 +1 @@
1
+ {"version":3,"file":"run-tool-DML8JJvt.js","names":["getSkillContentBlocks","join","path","runPluginInstall","path"],"sources":["../src/tui/screens/health/HealthCheckScreen.tsx","../src/tui/screens/SettingsOverrideScreen.tsx","../src/tui/screens/ManagedSettingsScreen.tsx","../src/tui/screens/PortConflictScreen.tsx","../src/tui/screens/TaskNoticeScreen.tsx","../src/tui/screens/ManualAuthCodeScreen.tsx","../src/tui/screens/SetupScreen.tsx","../src/shared/utils/clipboard.ts","../src/tui/screens/AuthScreen.tsx","../src/tui/screens/RunScreen.tsx","../src/tui/screens/KeepSkillsScreen.tsx","../src/tui/screens/MintFailureScreen.tsx","../src/tui/services/coding-agent-launcher.ts","../src/tui/services/wizard-spellbook.ts","../src/tui/screens/ExitScreen.tsx","../src/tui/screens/AuthErrorScreen.tsx","../src/tui/screens/SessionTimeoutScreen.tsx","../src/tui/screens/WizardAskScreen.tsx","../src/shared/mcp-clients/login-client.ts","../src/shared/mcp-clients/browser-client.ts","../src/tui/services/mcp-installer.ts","../src/tui/screen-registry.tsx","../src/tui/auth/login.ts","../src/tui/App.tsx","../src/tui/exit-line.ts","../src/tui/start-tui.ts","../src/tui/run-tool.ts"],"sourcesContent":["/**\n * HealthCheckScreen — Program screen between Intro and Auth.\n *\n * Three states:\n * 1. Checking: spinner while health check runs\n * 2. Healthy: isComplete returns true, router auto-advances to Auth\n * 3. Blocking outage: shows affected services with Continue/Exit\n */\n\nimport { Box, Text } from 'ink';\nimport { useState, useSyncExternalStore } from 'react';\nimport type { WizardStore } from '@tui/store';\nimport {\n ConfirmationInput,\n LoadingBox,\n ModalOverlay,\n} from '@tui/primitives/index';\nimport { Colors, Icons } from '@tui/styles';\nimport { ServiceHealthList } from '@tui/components/ServiceHealthList';\nimport {\n getBlockingServiceKeys,\n SIGNUP_WIZARD_READINESS_CONFIG,\n} from '@shared/health-checks/readiness';\nimport { ServiceHealthStatus } from '@shared/health-checks/types';\nimport { abortOnScreens } from '@tui/abort';\nimport { ErrorCodes } from '@shared/errors';\nimport { scanInstalledSkill } from '@programs';\nimport { downloadSkill } from '@shared/skill-install';\nimport { fetchSkillMenu } from '@shared/skill-menu';\nimport { GITHUB_SKILLS_BASE_URL } from '@shared/constants';\nimport { useDismissOnAnyKey } from '@tui/hooks/useDismissOnAnyKey';\n\ninterface HealthCheckScreenProps {\n store: WizardStore;\n}\n\nconst EXAMPLE_PROMPT =\n 'Integrate PostHog into this project using the skill files in .posthog/skills/. Read SKILL.md first, then follow the numbered program files in order.';\n\nconst SkillsDownloadedScreen = ({ store }: HealthCheckScreenProps) => {\n useDismissOnAnyKey(() => store.requestExit(0));\n\n return (\n <Box flexDirection=\"column\" flexGrow={1}>\n <Text color=\"green\" bold>\n {Icons.check} Skills downloaded to .posthog/skills/\n </Text>\n\n <Box marginTop={1} flexDirection=\"column\">\n <Text>\n You can continue setup with another agent using this prompt:\n </Text>\n <Box marginTop={1} paddingLeft={2}>\n <Text color=\"cyan\">{EXAMPLE_PROMPT}</Text>\n </Box>\n </Box>\n\n <Box marginTop={1}>\n <Text color={Colors.muted}>Press any key to exit</Text>\n </Box>\n </Box>\n );\n};\n\nexport const HealthCheckScreen = ({ store }: HealthCheckScreenProps) => {\n useSyncExternalStore(\n (cb) => store.subscribe(cb),\n () => store.getSnapshot(),\n );\n\n const [downloaded, setDownloaded] = useState(false);\n const [downloading, setDownloading] = useState(false);\n\n const result = store.session.readinessResult;\n\n if (downloaded) {\n return <SkillsDownloadedScreen store={store} />;\n }\n\n // Still checking — show spinner\n if (!result) {\n return (\n <Box\n flexDirection=\"column\"\n flexGrow={1}\n alignItems=\"center\"\n justifyContent=\"center\"\n >\n <LoadingBox message=\"Checking service status...\" />\n </Box>\n );\n }\n\n const isSignup = store.session.signup;\n const blockingKeys = getBlockingServiceKeys(\n result.health,\n isSignup ? SIGNUP_WIZARD_READINESS_CONFIG : undefined,\n );\n\n // Signup has a narrower block list (only posthog + llm-gateway), so\n // services like Anthropic can be degraded without blocking. Surface\n // those as dismissable warnings instead of silently proceeding.\n const warningKeys = isSignup\n ? getBlockingServiceKeys(result.health).filter(\n (k) => !blockingKeys.includes(k),\n )\n : [];\n\n const hasHardBlock = blockingKeys.length > 0;\n const displayKeys = hasHardBlock ? blockingKeys : warningKeys;\n if (displayKeys.length === 0) return null;\n\n const isSkillsOriginDown =\n hasHardBlock && blockingKeys.includes('skillsOrigin');\n const canDownloadSkills =\n result.health.skillsOrigin.status === ServiceHealthStatus.Healthy;\n const integration = store.session.integration;\n\n // If every blocking row is `NoConnection` (probe failed, no status-page\n // corroboration), reframe the screen to point at the user's network\n // instead of accusing PostHog of an outage. Mixed Down + NoConnection\n // falls through to the confirmed-outage framing because there's still\n // a real incident underneath.\n const allBlockingHaveNoConnection =\n hasHardBlock &&\n displayKeys.every(\n (k) => result.health[k].status === ServiceHealthStatus.NoConnection,\n );\n\n const title = isSkillsOriginDown\n ? 'Ongoing service disruptions'\n : allBlockingHaveNoConnection\n ? \"Couldn't reach PostHog\"\n : hasHardBlock\n ? 'Ongoing service disruptions'\n : 'Service disruption detected';\n\n const docsUrl = store.session.frameworkConfig?.metadata.docsUrl;\n const description = isSkillsOriginDown\n ? \"The Wizard can't download the skills it needs — neither GitHub Releases nor PostHog's mirror is reachable right now.\"\n : allBlockingHaveNoConnection\n ? \"We couldn't reach these services from this machine. PostHog's status page shows no incidents, so this is most likely a network issue — VPN, firewall, captive portal, or flaky Wi-Fi.\"\n : hasHardBlock\n ? 'The Wizard cannot start while these services are down.'\n : 'Some services are degraded. You can continue, but parts of the wizard may not work reliably.';\n\n const handleDownloadAndExit = async () => {\n if (downloading) return;\n setDownloading(true);\n // Primary origin — fetchSkillMenu/downloadSkill fail over to AWS themselves.\n const menu = await fetchSkillMenu(GITHUB_SKILLS_BASE_URL);\n if (menu) {\n const prefix = `integration-${integration}`;\n const skills = (menu.categories['integration'] ?? []).filter((s) =>\n s.id.startsWith(prefix),\n );\n for (const skill of skills) {\n // Pre-auth outage cache: no gateway, so a flagged skill fails closed.\n await downloadSkill(skill, store.session.installDir, {\n skillsRoot: '.posthog/skills',\n scan: (dir) => scanInstalledSkill(dir, undefined),\n });\n }\n }\n setDownloaded(true);\n };\n\n const handleCancel =\n canDownloadSkills && !isSkillsOriginDown\n ? () => void handleDownloadAndExit()\n : () =>\n void abortOnScreens(store, {\n code: ErrorCodes.EnvServiceOutage,\n message: 'Exited due to service outage.',\n });\n\n const cancelLabel =\n canDownloadSkills && !isSkillsOriginDown\n ? downloading\n ? 'Downloading...'\n : 'Download skills & Exit [Esc]'\n : 'Exit [Esc]';\n\n return (\n <ModalOverlay\n borderColor={\n hasHardBlock && !allBlockingHaveNoConnection ? 'red' : 'yellow'\n }\n title={title}\n width={72}\n footer={\n isSkillsOriginDown ? (\n <ConfirmationInput\n message=\"\"\n confirmLabel=\"\"\n cancelLabel=\"Exit [Esc]\"\n onConfirm={() =>\n void abortOnScreens(store, {\n code: ErrorCodes.EnvServiceOutage,\n message: 'Exited due to service outage.',\n })\n }\n onCancel={() =>\n void abortOnScreens(store, {\n code: ErrorCodes.EnvServiceOutage,\n message: 'Exited due to service outage.',\n })\n }\n />\n ) : (\n <ConfirmationInput\n message=\"Continue anyway?\"\n confirmLabel=\"Continue [Enter]\"\n cancelLabel={cancelLabel}\n onConfirm={() => store.dismissOutage()}\n onCancel={handleCancel}\n />\n )\n }\n >\n <Box flexDirection=\"column\" marginBottom={1}>\n <Box marginBottom={1}>\n <Text>\n <Text color=\"red\">{Icons.squareFilled}</Text>\n <Text dimColor> Down </Text>\n <Text color=\"#DC9300\">{Icons.squareFilled}</Text>\n <Text dimColor> Degraded </Text>\n <Text color=\"gray\">{Icons.squareFilled}</Text>\n <Text dimColor> No connection</Text>\n </Text>\n </Box>\n\n <ServiceHealthList\n health={result.health}\n filterKeys={displayKeys}\n showHealthy={false}\n />\n </Box>\n\n <Text dimColor>{description}</Text>\n\n {isSkillsOriginDown && docsUrl && (\n <Box marginTop={1}>\n <Text>\n Set up manually: <Text color=\"cyan\">{docsUrl}</Text>\n </Text>\n </Box>\n )}\n\n {canDownloadSkills && !isSkillsOriginDown && (\n <Box marginTop={1}>\n <Text>\n You can still download the PostHog integration skills and continue\n with another agent.\n </Text>\n </Box>\n )}\n </ModalOverlay>\n );\n};\n","import { Box, Text } from 'ink';\nimport { useEffect, useState, useSyncExternalStore } from 'react';\nimport type { WizardStore } from '@tui/store';\nimport { ConfirmationInput, ModalOverlay } from '@tui/primitives/index';\nimport { Icons } from '@tui/styles';\nimport { analytics } from '@utils/analytics';\n\ninterface SettingsOverrideScreenProps {\n store: WizardStore;\n}\n\nexport const SettingsOverrideScreen = ({\n store,\n}: SettingsOverrideScreenProps) => {\n useSyncExternalStore(\n (cb) => store.subscribe(cb),\n () => store.getSnapshot(),\n );\n\n const [feedback, setFeedback] = useState<string | null>(null);\n const conflicts = store.settingsConflicts?.filter((c) => c.writable);\n\n const hasConflicts = Boolean(conflicts && conflicts.length > 0);\n useEffect(() => {\n if (hasConflicts) {\n analytics.wizardCapture('settings conflict shown', { kind: 'override' });\n }\n }, [hasConflicts]);\n\n if (!conflicts || conflicts.length === 0) {\n return null;\n }\n\n return (\n <ModalOverlay\n borderColor=\"red\"\n title={`${Icons.warning} Settings conflict`}\n width={64}\n feedback={feedback ? `${Icons.warning} ${feedback}` : null}\n footer={\n <ConfirmationInput\n message=\"Back up to .wizard-backup and continue?\"\n confirmLabel=\"Backup & continue [Enter]\"\n cancelLabel=\"Exit [Esc]\"\n onConfirm={() => {\n analytics.wizardCapture('settings conflict accepted', {\n kind: 'override',\n });\n const ok = store.backupAndFixSettingsOverride();\n if (!ok) {\n setFeedback('Could not back up the settings file.');\n }\n }}\n onCancel={() => store.requestExit(1)}\n />\n }\n >\n {conflicts.map((conflict) => (\n <Box key={conflict.path} flexDirection=\"column\" marginBottom={1}>\n <Text>\n Your settings file at <Text bold>{conflict.path}</Text> sets:\n </Text>\n <Box flexDirection=\"column\" paddingLeft={2}>\n {conflict.keys.map((key) => (\n <Text key={key}>\n {Icons.bullet}{' '}\n <Text color=\"yellow\" bold>\n {key}\n </Text>\n </Text>\n ))}\n </Box>\n </Box>\n ))}\n <Text dimColor>\n These settings override credentials and prevent the Wizard from reaching\n the PostHog LLM Gateway. We can back up the file and continue.\n </Text>\n </ModalOverlay>\n );\n};\n","/**\n * ManagedSettingsScreen — Modal for read-only settings conflicts that block\n * the Wizard from reaching the PostHog LLM Gateway: org-managed settings, the\n * user's global `~/.claude` config, and gitignored project-local overrides.\n *\n * Unlike SettingsOverrideScreen, the wizard cannot safely back up or remove\n * these files for the user, so it names the exact file and key and asks the\n * user to fix it and re-run. Managed (root-owned) files need an IT admin; the\n * rest the user can edit themselves.\n */\n\nimport { Box, Text } from 'ink';\nimport { useEffect, useSyncExternalStore } from 'react';\nimport type { WizardStore } from '@tui/store';\nimport { ConfirmationInput, ModalOverlay } from '@tui/primitives/index';\nimport { Icons } from '@tui/styles';\nimport type { SettingsConflict } from '@shared/claude-settings';\nimport { analytics } from '@utils/analytics';\n\nfunction sourceLabel(source: SettingsConflict['source']): string {\n switch (source) {\n case 'managed':\n return 'Organization-managed settings';\n case 'user':\n return 'Your global Claude Code settings';\n case 'project-local':\n return 'Project-local settings';\n default:\n return source;\n }\n}\n\ninterface ManagedSettingsScreenProps {\n store: WizardStore;\n}\n\nexport const ManagedSettingsScreen = ({\n store,\n}: ManagedSettingsScreenProps) => {\n useSyncExternalStore(\n (cb) => store.subscribe(cb),\n () => store.getSnapshot(),\n );\n\n const conflicts = store.settingsConflicts;\n const readOnlyConflicts = conflicts?.filter((c) => !c.writable);\n\n const hasManaged = Boolean(\n readOnlyConflicts?.some((c) => c.source === 'managed'),\n );\n const hasReadOnly = Boolean(\n readOnlyConflicts && readOnlyConflicts.length > 0,\n );\n useEffect(() => {\n // Read-only conflict — nothing to accept, so impression only.\n if (hasReadOnly) {\n analytics.wizardCapture('settings conflict shown', {\n kind: 'managed',\n has_managed: hasManaged,\n });\n }\n }, [hasReadOnly, hasManaged]);\n\n if (!readOnlyConflicts || readOnlyConflicts.length === 0) {\n return null;\n }\n\n return (\n <ModalOverlay\n borderColor=\"red\"\n title={`${Icons.warning} Settings conflict`}\n width={72}\n footer={\n <ConfirmationInput\n message=\"Fix the file(s) above, then re-run the Wizard.\"\n confirmLabel=\"\"\n cancelLabel=\"Exit [Esc]\"\n onConfirm={() => store.requestExit(1)}\n onCancel={() => store.requestExit(1)}\n />\n }\n >\n <Text dimColor>\n These Claude Code settings override credentials and prevent the Wizard\n from reaching the PostHog LLM Gateway.\n </Text>\n {readOnlyConflicts.map((conflict) => (\n <Box key={conflict.path} flexDirection=\"column\" marginTop={1}>\n <Text bold>{sourceLabel(conflict.source)}</Text>\n <Text dimColor>{conflict.path}</Text>\n <Box flexDirection=\"column\" paddingLeft={2}>\n {conflict.keys.map((key) => (\n <Text key={key}>\n {Icons.bullet}{' '}\n <Text color=\"yellow\" bold>\n {key}\n </Text>\n </Text>\n ))}\n </Box>\n </Box>\n ))}\n <Box marginTop={1}>\n <Text dimColor>\n {hasManaged\n ? 'Remove these keys (or run \"claude auth logout\"). Managed files are root-owned — ask your IT administrator.'\n : 'Remove these keys, or run \"claude auth logout\", then re-run the Wizard.'}\n </Text>\n </Box>\n </ModalOverlay>\n );\n};\n","/**\n * PortConflictScreen — Modal when all OAuth port candidates are occupied.\n *\n * Shows every port the wizard tried and asks the user to free them manually.\n */\n\nimport { Box, Text } from 'ink';\nimport { useSyncExternalStore } from 'react';\nimport type { WizardStore } from '@tui/store';\nimport { OAUTH_PORTS } from '@shared/constants';\nimport { ConfirmationInput, ModalOverlay } from '@tui/primitives/index';\n\ninterface PortConflictScreenProps {\n store: WizardStore;\n}\n\nexport const PortConflictScreen = ({ store }: PortConflictScreenProps) => {\n useSyncExternalStore(\n (cb) => store.subscribe(cb),\n () => store.getSnapshot(),\n );\n\n const processInfo = store.portConflictProcess;\n\n if (!processInfo) return null;\n\n return (\n <ModalOverlay\n borderColor=\"#DC9300\"\n title=\"OAuth ports in use\"\n width={72}\n footer={\n <ConfirmationInput\n message=\"Retry after freeing ports?\"\n confirmLabel=\"Retry [Enter]\"\n cancelLabel=\"Exit [Esc]\"\n onConfirm={() => store.resolvePortConflict()}\n onCancel={() => store.requestExit(1)}\n />\n }\n >\n <Text>\n The wizard needs a local port for OAuth. We tried these ports which are\n all in use:\n </Text>\n <Box flexDirection=\"column\" marginY={1} paddingLeft={2} gap={0}>\n {OAUTH_PORTS.map((port) => (\n <Text key={port}>\n <Text dimColor>Port </Text>\n <Text bold>{port}</Text>\n </Text>\n ))}\n </Box>\n <Text dimColor>Please free one of these ports and retry.</Text>\n </ModalOverlay>\n );\n};\n","/**\n * TaskNoticeScreen — Modal shown before an optional step runs.\n *\n * Some steps stop to ask the user for something. This tells them so before the\n * step starts, and lets them decline it. The copy comes from the program that\n * owns the step; this screen only renders what it is given.\n */\n\nimport { Box, Text } from 'ink';\nimport { useSyncExternalStore } from 'react';\nimport type { WizardStore } from '@tui/store';\nimport { Colors } from '@tui/styles';\nimport { ConfirmationInput, ModalOverlay } from '@tui/primitives/index';\n\ninterface TaskNoticeScreenProps {\n store: WizardStore;\n}\n\nexport const TaskNoticeScreen = ({ store }: TaskNoticeScreenProps) => {\n useSyncExternalStore(\n (cb) => store.subscribe(cb),\n () => store.getSnapshot(),\n );\n\n const notice = store.session.taskNotice;\n if (!notice) return null;\n\n return (\n <ModalOverlay\n borderColor={Colors.primary}\n title={notice.title}\n width={76}\n footer={\n <ConfirmationInput\n message={notice.prompt}\n confirmLabel={notice.confirmLabel}\n cancelLabel={notice.cancelLabel}\n onConfirm={() => store.resolveTaskNotice(true)}\n onCancel={() => store.resolveTaskNotice(false)}\n />\n }\n >\n <Box flexDirection=\"column\" gap={1}>\n {notice.body.map((paragraph) => (\n <Text key={paragraph}>{paragraph}</Text>\n ))}\n </Box>\n {notice.items && notice.items.length > 0 && (\n <Box marginTop={1} paddingLeft={2}>\n <Text bold>{notice.items.join(', ')}</Text>\n </Box>\n )}\n {notice.docsUrl && (\n <Box marginTop={1}>\n <Text dimColor>\n {notice.docsLabel ?? 'Learn more'}: {notice.docsUrl}\n </Text>\n </Box>\n )}\n </ModalOverlay>\n );\n};\n","/**\n * ManualAuthCodeScreen — Paste an OAuth authorization code by hand.\n *\n * Fallback for headless/remote shells where the browser can't reach the\n * wizard's local callback server. Shows the direct authorize URL (the localhost\n * one is unreachable from another machine), then the user pastes either the\n * full callback URL the browser was redirected to\n * (`http://localhost:8239/callback?code=...`) or just the code. On submit we\n * extract the code and resolve the in-flight OAuth flow; bad input shows inline\n * feedback without leaving the screen.\n *\n * Opened from AuthScreen via a keypress; Esc dismisses it.\n */\n\nimport { Box, Text, useInput } from 'ink';\nimport { TextInput } from '@inkjs/ui';\nimport { useState, useSyncExternalStore } from 'react';\nimport type { WizardStore } from '@tui/store';\nimport { Colors, Icons } from '@tui/styles';\nimport { extractOAuthCode } from '@tui/auth/oauth';\n\ninterface ManualAuthCodeScreenProps {\n store: WizardStore;\n}\n\nexport const ManualAuthCodeScreen = ({ store }: ManualAuthCodeScreenProps) => {\n useSyncExternalStore(\n (cb) => store.subscribe(cb),\n () => store.getSnapshot(),\n );\n\n const { authorizeUrl } = store;\n const [error, setError] = useState<string | null>(null);\n\n // Esc cancels and returns to the waiting auth screen.\n useInput((_input, key) => {\n if (key.escape) {\n store.dismissManualAuthCode();\n }\n });\n\n const handleSubmit = (value: string): void => {\n const code = extractOAuthCode(value);\n if (!code) {\n setError(\n \"Couldn't find a code in that input. Paste the full callback URL or just the code.\",\n );\n return;\n }\n store.submitManualAuthCode(code);\n };\n\n return (\n <Box flexDirection=\"column\" flexGrow={1}>\n <Box marginBottom={1}>\n <Text bold color={Colors.accent}>\n {Icons.diamond} Paste authorization code\n </Text>\n </Box>\n\n {authorizeUrl && (\n <Box flexDirection=\"column\" marginBottom={1}>\n <Text dimColor>\n On a remote/headless machine the local login link won't open. Open\n this URL in a browser on any machine to authorize:\n </Text>\n {/* No border + flexShrink={0}: Ink won't hard-wrap the URL, so it\n stays one continuous string the terminal soft-wraps — copies clean\n instead of being chopped across bordered, indented rows. */}\n <Box flexShrink={0} marginTop={1}>\n <Text color=\"cyan\">{authorizeUrl}</Text>\n </Box>\n </Box>\n )}\n\n <Text>\n After authorizing, paste the callback URL it lands on — or just the code\n from it — here:\n </Text>\n <Box marginTop={1} width=\"100%\">\n <TextInput\n placeholder=\"http://localhost:8239/callback?code=… or the code\"\n onSubmit={handleSubmit}\n />\n </Box>\n\n {error && (\n <Box marginTop={1}>\n <Text color=\"yellow\">{error}</Text>\n </Box>\n )}\n\n <Box marginTop={1}>\n <Text>\n <Text color={Colors.accent}>ENTER</Text>\n <Text dimColor> submit</Text>\n <Text dimColor> · </Text>\n <Text color={Colors.accent}>ESC</Text>\n <Text dimColor> cancel</Text>\n </Text>\n </Box>\n </Box>\n );\n};\n","/**\n * SetupScreen — Generic framework disambiguation.\n *\n * Iterates unresolved setup questions from the FrameworkConfig\n * and renders a PickerMenu for each. If all questions are auto-resolved,\n * this screen is skipped entirely (the router skips it via its show() predicate).\n */\n\nimport { Box, Text } from 'ink';\nimport { useState, useEffect } from 'react';\nimport { useSyncExternalStore } from 'react';\nimport type { WizardStore } from '@tui/store';\nimport { PickerMenu } from '@tui/primitives/index';\nimport { Colors } from '@tui/styles';\nimport type { SetupQuestion } from '@programs/types';\n\ninterface SetupScreenProps {\n store: WizardStore;\n}\n\nexport const SetupScreen = ({ store }: SetupScreenProps) => {\n useSyncExternalStore(\n (cb) => store.subscribe(cb),\n () => store.getSnapshot(),\n );\n\n const config = store.session.frameworkConfig;\n const questions = config?.metadata.setup?.questions ?? [];\n\n // Track which question index we're currently showing\n const [currentIndex, setCurrentIndex] = useState(0);\n const [resolving, setResolving] = useState(true);\n\n // On mount, run auto-detection for all questions\n useEffect(() => {\n void (async () => {\n for (const q of questions) {\n // Skip if already resolved (e.g. by CLI arg)\n if (q.key in store.session.frameworkContext) continue;\n\n try {\n const detected = await q.detect({\n installDir: store.session.installDir,\n });\n if (detected !== null) {\n store.setFrameworkContext(q.key, detected);\n }\n } catch {\n // Detection failed — will ask the user\n }\n }\n setResolving(false);\n\n // If all resolved, the router's isComplete predicate will\n // resolve past this screen on the next render cycle.\n })();\n }, []);\n\n if (resolving) {\n return (\n <Box flexDirection=\"column\" flexGrow={1}>\n <Text dimColor>Detecting project configuration...</Text>\n </Box>\n );\n }\n\n // Get unresolved questions\n const unresolved = questions.filter(\n (q: SetupQuestion) => !(q.key in store.session.frameworkContext),\n );\n\n if (unresolved.length === 0) {\n // All resolved — should have already advanced\n return null;\n }\n\n const question = unresolved[currentIndex] ?? unresolved[0];\n if (!question) return null;\n\n return (\n <Box flexDirection=\"column\" flexGrow={1}>\n <Box flexDirection=\"column\" marginBottom={1}>\n <Text bold color={Colors.accent}>\n Project Setup\n </Text>\n {config && (\n <Text dimColor>Configuring {config.metadata.name} integration</Text>\n )}\n </Box>\n\n <PickerMenu<string>\n message={question.message}\n options={question.options.map((o) => ({\n label: o.label,\n value: o.value,\n hint: o.hint,\n }))}\n onSelect={(value) => {\n const selected = Array.isArray(value) ? value[0] : value;\n store.setFrameworkContext(question.key, selected);\n\n // Check if more unresolved questions remain\n const remaining = unresolved.filter(\n (q: SetupQuestion) =>\n q.key !== question.key &&\n !(q.key in store.session.frameworkContext),\n );\n\n if (remaining.length > 0) {\n setCurrentIndex((i) => i + 1);\n }\n // When no remaining questions, setFrameworkContext already\n // triggered emitChange — router resolves past this screen.\n }}\n />\n </Box>\n );\n};\n","/**\n * Best-effort platform shell-outs for making a URL usable in any terminal —\n * no third-party dependency.\n *\n * Two helpers back the `wizard_ask` link overlay, for terminals that can't\n * linkify a wrapped URL (e.g. macOS Terminal.app, which lacks OSC 8 hyperlink\n * support):\n *\n * - `copyToClipboard` — pipe the URL to the platform clipboard binary so the\n * user can paste it into a browser.\n * - `openInBrowser` — hand the URL to the platform opener so it launches\n * directly, no copy/paste needed.\n *\n * Both shell out with `spawn` and never a shell, and pass the URL as an argv\n * (clipboard via stdin) — so there's no shell-injection surface. Neither throws:\n * they return false when no command is reachable (CI, headless, or the binary\n * isn't installed).\n */\nimport { spawn } from 'node:child_process';\nimport { logToFile } from './debug.js';\n\ninterface ClipboardCommand {\n cmd: string;\n args: string[];\n}\n\n/** Platform clipboard commands, in preference order. */\nfunction clipboardCommands(): ClipboardCommand[] {\n if (process.platform === 'darwin') return [{ cmd: 'pbcopy', args: [] }];\n if (process.platform === 'win32') return [{ cmd: 'clip', args: [] }];\n // Linux / BSD: try Wayland first, then the common X11 utilities.\n return [\n { cmd: 'wl-copy', args: [] },\n { cmd: 'xclip', args: ['-selection', 'clipboard'] },\n { cmd: 'xsel', args: ['--clipboard', '--input'] },\n ];\n}\n\nfunction writeWith(\n { cmd, args }: ClipboardCommand,\n text: string,\n): Promise<boolean> {\n return new Promise((resolve) => {\n try {\n const child = spawn(cmd, args);\n // ENOENT (missing binary) and EPIPE surface as 'error' events.\n child.on('error', () => resolve(false));\n child.stdin.on('error', () => resolve(false));\n child.on('close', (code) => resolve(code === 0));\n child.stdin.end(text);\n } catch {\n resolve(false);\n }\n });\n}\n\nexport async function copyToClipboard(text: string): Promise<boolean> {\n for (const command of clipboardCommands()) {\n if (await writeWith(command, text)) return true;\n }\n logToFile('[clipboard] no working clipboard command found');\n return false;\n}\n\n/**\n * Platform browser-open commands, in preference order. The URL is one argv\n * element — never concatenated into a shell string — so a `?kind=…` query or\n * any other character can't escape into the command line.\n *\n * `win32` has no shell-free single binary for this: `start` is a `cmd` builtin,\n * so we invoke `cmd /c start \"\" <url>` (the empty `\"\"` is `start`'s window-title\n * argument, which would otherwise swallow the URL). The URL is still a discrete\n * argv element, not interpolated into the command string.\n *\n * Takes `platform` as an argument (defaulting to the host) so the mapping is a\n * pure function the tests can exercise across platforms.\n */\nexport function browserOpenCommands(\n url: string,\n platform: NodeJS.Platform = process.platform,\n): ClipboardCommand[] {\n if (platform === 'darwin') return [{ cmd: 'open', args: [url] }];\n if (platform === 'win32') {\n return [{ cmd: 'cmd', args: ['/c', 'start', '', url] }];\n }\n // Linux / BSD: xdg-open is the freedesktop standard; x-www-browser is the\n // Debian alternatives fallback.\n return [\n { cmd: 'xdg-open', args: [url] },\n { cmd: 'x-www-browser', args: [url] },\n ];\n}\n\nfunction spawnOpener({ cmd, args }: ClipboardCommand): Promise<boolean> {\n return new Promise((resolve) => {\n try {\n // Detach the opener's stdio so it can't write over the Ink TUI, and\n // resolve on a clean exit. ENOENT (missing binary) surfaces as 'error'.\n const child = spawn(cmd, args, { stdio: 'ignore' });\n child.on('error', () => resolve(false));\n child.on('close', (code) => resolve(code === 0));\n } catch {\n resolve(false);\n }\n });\n}\n\nexport async function openInBrowser(url: string): Promise<boolean> {\n for (const command of browserOpenCommands(url)) {\n if (await spawnOpener(command)) return true;\n }\n logToFile('[clipboard] no working browser-open command found');\n return false;\n}\n","/**\n * AuthScreen — Shown while waiting for OAuth authentication.\n *\n * Displays framework detection, a compressed privacy summary, a waiting\n * spinner, and the login URL when available. [I] opens the full\n * PrivacyPanel as an overlay. [P] (when loginUrl is set) lets the user\n * paste the callback URL by hand. [C] copies the login URL to the\n * clipboard — the exact string, so it can't be chopped by a soft-wrap.\n *\n * The router resolves past this screen once session.credentials is set.\n */\n\nimport { Box, Text } from 'ink';\nimport { useState, useSyncExternalStore } from 'react';\nimport type { WizardStore } from '@tui/store';\nimport { LoadingBox } from '@tui/primitives/index';\nimport { MAX_WIDTH } from '@tui/primitives/ScreenContainer';\nimport {\n PrivacyPanel,\n PRIVACY_PANEL_LABEL,\n} from '@tui/components/PrivacyPanel';\nimport { IntroScreenLayout } from '@tui/screens/IntroScreenLayout';\nimport { useKeyBindings, type KeyBinding } from '@tui/hooks/useKeyBindings';\nimport { useStdoutDimensions } from '@tui/hooks/useStdoutDimensions';\nimport { Colors, Icons } from '@tui/styles';\nimport { copyToClipboard } from '@utils/clipboard';\n\ninterface AuthScreenProps {\n store: WizardStore;\n}\n\nexport const AuthScreen = ({ store }: AuthScreenProps) => {\n useSyncExternalStore(\n (cb) => store.subscribe(cb),\n () => store.getSnapshot(),\n );\n\n const [showPrivacy, setShowPrivacy] = useState(false);\n const [copyStatus, setCopyStatus] = useState<'idle' | 'copied' | 'failed'>(\n 'idle',\n );\n const [columns] = useStdoutDimensions();\n const { session } = store;\n\n // While the OAuth flow is waiting (loginUrl set), let the user paste the\n // callback URL/code by hand — the fallback for headless/remote shells where\n // the browser can't reach the local callback server.\n const loginUrl = store.loginUrl;\n const canPasteCode = Boolean(loginUrl);\n\n // The URL renders on its own line; ScreenContainer clamps content to\n // MAX_WIDTH and pads one column each side, so this is the room a single\n // unwrapped line has. A URL wider than this soft-wraps, and a wrapped URL\n // copies with a line break baked in — the exact broken-link (\"invalid\n // scope\") breakage users hit on small terminals. Show a resize hint instead.\n const availableWidth = Math.min(columns, MAX_WIDTH) - 2;\n const urlFits = loginUrl ? loginUrl.length <= availableWidth : true;\n\n // Build bindings imperatively: while the privacy view is open, the\n // screen registers NO bindings (IntroScreenLayout's menu owns input).\n const bindings: KeyBinding[] = [];\n if (!showPrivacy) {\n if (canPasteCode && loginUrl) {\n bindings.push({\n match: ['p', 'P'],\n label: 'P',\n action: 'paste auth code',\n handler: () => store.showManualAuthCode(),\n });\n // Copy the exact URL string — immune to the soft-wrap that breaks\n // hand-selection on narrow terminals. May no-op on a remote shell with\n // no clipboard binary; the 'failed' status points the user to [P] then.\n bindings.push({\n match: ['c', 'C'],\n label: 'C',\n action: 'copy link',\n handler: () => {\n void copyToClipboard(loginUrl).then((ok) =>\n setCopyStatus(ok ? 'copied' : 'failed'),\n );\n },\n });\n }\n bindings.push({\n match: ['i', 'I'],\n label: 'I',\n action: PRIVACY_PANEL_LABEL.toLowerCase(),\n handler: () => setShowPrivacy(true),\n });\n }\n useKeyBindings('auth', bindings);\n\n if (showPrivacy) {\n return (\n <IntroScreenLayout\n installDir={session.installDir}\n title={PRIVACY_PANEL_LABEL}\n showSubtitle={false}\n showDetection={false}\n body={<PrivacyPanel />}\n showPrivacy={false}\n menuOptions={[{ label: 'Back', value: 'back' }]}\n menuAlign=\"left\"\n onSelect={() => setShowPrivacy(false)}\n />\n );\n }\n\n const config = session.frameworkConfig;\n const frameworkLabel =\n session.detectedFrameworkLabel ?? config?.metadata.name;\n\n return (\n <Box flexDirection=\"column\" flexGrow={1}>\n <Box flexDirection=\"column\" marginBottom={1}>\n <Text bold color={Colors.accent}>\n PostHog Setup Wizard\n </Text>\n\n {frameworkLabel && (\n <Text>\n <Text color=\"green\">{'✔'} </Text>\n <Text>Framework: {frameworkLabel}</Text>\n </Text>\n )}\n\n {/* Dead path today — every framework went GA, so no config has\n metadata.beta = true. Kept intentionally for the next time we\n ship a framework integration in beta. Set `beta: true` on the\n framework's config and this rendering re-activates. */}\n {config?.metadata.beta && (\n <Text color=\"yellow\">\n [BETA] The {config.metadata.name} wizard is in beta. Questions or\n feedback? Email wizard@posthog.com\n </Text>\n )}\n\n {config?.metadata.preRunNotice && (\n <Text color=\"yellow\">{config.metadata.preRunNotice}</Text>\n )}\n </Box>\n\n <Box flexDirection=\"column\" marginBottom={1}>\n <Text bold dimColor>\n {PRIVACY_PANEL_LABEL}\n </Text>\n <Text dimColor>\n {'•'} Source files are read by Claude for AI context\n </Text>\n <Text dimColor>{'•'} .env* and secrets stay on your machine</Text>\n <Text dimColor>\n {'•'} Press <Text color={Colors.accent}>[I]</Text> for full privacy &\n usage info\n </Text>\n </Box>\n\n <LoadingBox message=\"Waiting for authentication...\" />\n\n {loginUrl && (\n <Box marginTop={1} marginBottom={1} flexDirection=\"column\">\n {urlFits ? (\n // Literal \\n — sibling <Box> spacers squeeze to 0 under flex\n // height pressure, letting cmd-click slurp /authorize + 'y'.\n <Text>\n <Text dimColor>\n If the browser didn't open, copy and paste this URL:\n </Text>\n {'\\n\\n'}\n <Text color=\"cyan\">{loginUrl}</Text>\n </Text>\n ) : (\n <Text color=\"yellow\">\n [This terminal is too small to show the full link for copying,\n resize your terminal]\n </Text>\n )}\n <Box marginTop={1}>\n <Text dimColor>\n Press <Text color={Colors.accent}>[C]</Text> to copy the link · on\n a remote machine or devbox? Press{' '}\n <Text color={Colors.accent}>[P]</Text> to paste the callback URL.\n </Text>\n </Box>\n {copyStatus === 'copied' && (\n <Box marginTop={1}>\n <Text color={Colors.success}>\n {Icons.check} Link copied to clipboard.\n </Text>\n </Box>\n )}\n {copyStatus === 'failed' && (\n <Box marginTop={1}>\n <Text color=\"yellow\">\n Couldn't reach a clipboard on this machine — press{' '}\n <Text color={Colors.accent}>[P]</Text> to paste the callback URL\n instead.\n </Text>\n </Box>\n )}\n </Box>\n )}\n </Box>\n );\n};\n","/**\n * RunScreen — Default observational view of the agent run.\n *\n * Tabs: Status (LearnCard + ProgressList), Event plan (when present),\n * Tail logs, HN. Programs that need a different tab list ship their own\n * screen component (see audit/AuditRunScreen.tsx).\n */\n\nimport { useMemo, useSyncExternalStore } from 'react';\nimport { Box } from 'ink';\nimport type { WizardStore } from '@tui/store';\nimport {\n TabContainer,\n SplitView,\n ProgressList,\n LogViewer,\n EventPlanViewer,\n HNViewer,\n} from '@tui/primitives/index';\nimport type { ProgressItem } from '@tui/primitives/index';\nimport { LearnCard } from '@tui/components/LearnCard';\nimport { VisualizerTab } from '@tui/components/PhaseVisuals';\nimport { TipsCard } from '@tui/components/TipsCard';\nimport { useStdoutDimensions } from '@tui/hooks/useStdoutDimensions';\n\nimport { flowOwner } from '@tui/flow-owner';\nimport { getContentBlocks as getSkillContentBlocks } from '@tui/programs/shared/skill-deck';\n\nimport { getLogFilePath } from '@utils/debug';\n\ninterface RunScreenProps {\n store: WizardStore;\n}\n\nexport const RunScreen = ({ store }: RunScreenProps) => {\n useSyncExternalStore(\n (cb) => store.subscribe(cb),\n () => store.getSnapshot(),\n );\n\n const [columns] = useStdoutDimensions();\n\n const progressItems: ProgressItem[] = store.tasks.map((t) => ({\n label: t.label,\n activeForm: t.activeForm,\n status: t.status,\n }));\n\n const statuses =\n store.statusMessages.length > 0 ? store.statusMessages : undefined;\n\n // Each program's deck lives in its TUI folder (`programs/<id>/deck`). Fall\n // back to the agent-skill deck for programs without one and for\n // runtime-created configs (e.g. `wizard skill <id>`).\n const activeProgram = store.router.activeProgram;\n const learnBlocks = useMemo(() => {\n const getBlocks = flowOwner(activeProgram).deck ?? getSkillContentBlocks;\n return getBlocks(store);\n }, [store, activeProgram]);\n\n // Program-supplied tips for the right pane; undefined falls back to\n // DEFAULT_TIPS inside TipsCard, so non-self-driving programs are unaffected.\n const programTips = flowOwner(activeProgram).tips?.(store);\n\n const leftPane = store.learnCardComplete ? (\n <TipsCard store={store} tips={programTips} />\n ) : (\n <LearnCard\n store={store}\n blocks={learnBlocks}\n onComplete={() => store.setLearnCardComplete()}\n />\n );\n const progressList = <ProgressList items={progressItems} title=\"Tasks\" />;\n\n const statusComponent =\n columns < 80 ? (\n <Box flexDirection=\"column\" flexGrow={1}>\n {progressList}\n </Box>\n ) : (\n <SplitView left={leftPane} right={progressList} />\n );\n\n const tabs = [\n { id: 'status', label: 'Status', component: statusComponent },\n ...(store.eventPlan.length > 0\n ? [\n {\n id: 'events',\n label: 'Event plan',\n component: <EventPlanViewer events={store.eventPlan} />,\n },\n ]\n : []),\n {\n id: 'logs',\n label: 'Tail logs',\n component: <LogViewer filePath={getLogFilePath()} />,\n },\n {\n id: 'visualizer',\n label: 'Visualizer',\n component: <VisualizerTab store={store} />,\n },\n { id: 'hn', label: 'HN', component: <HNViewer /> },\n ];\n\n return (\n <TabContainer\n tabs={tabs}\n statusMessage={statuses}\n expandableStatus\n store={store}\n />\n );\n};\n","/**\n * KeepSkillsScreen — Ask whether to keep installed skills in .claude/skills/.\n *\n * Shown after the outro summary so users see the agent's output first,\n * then decide whether to keep the skills that powered it.\n *\n * When done, calls store.setSkillsComplete() and exits the process.\n */\n\nimport { Box, Text } from 'ink';\nimport { useState, useEffect } from 'react';\nimport { useSyncExternalStore } from 'react';\nimport { readdir, rm, access } from 'node:fs/promises';\nimport { join } from 'node:path';\n\nconst WIZARD_MARKER = '.posthog-wizard';\nimport type { WizardStore } from '@tui/store';\nimport { ConfirmationInput } from '@tui/primitives/index';\nimport { Colors } from '@tui/styles';\nimport { CONTEXT_MILL_URL } from '@shared/constants';\n\ninterface KeepSkillsScreenProps {\n store: WizardStore;\n}\n\ninterface SkillEntry {\n name: string;\n children: string[];\n}\n\nenum Phase {\n Loading = 'loading',\n Ask = 'ask',\n Removing = 'removing',\n Done = 'done',\n}\n\nexport const KeepSkillsScreen = ({ store }: KeepSkillsScreenProps) => {\n useSyncExternalStore(\n (cb) => store.subscribe(cb),\n () => store.getSnapshot(),\n );\n\n const [phase, setPhase] = useState<Phase>(Phase.Loading);\n const [skills, setSkills] = useState<SkillEntry[]>([]);\n\n const skillsDir = join(store.session.installDir, '.claude', 'skills');\n\n useEffect(() => {\n void (async () => {\n try {\n const entries = await readdir(skillsDir, { withFileTypes: true });\n const dirs = entries.filter((e) => e.isDirectory());\n const result: SkillEntry[] = [];\n for (const dir of dirs) {\n try {\n await access(join(skillsDir, dir.name, WIZARD_MARKER));\n } catch {\n continue;\n }\n const children = (await readdir(join(skillsDir, dir.name))).filter(\n (c) => c !== WIZARD_MARKER,\n );\n result.push({ name: dir.name, children });\n }\n if (result.length === 0) {\n store.setSkillsComplete(true);\n exit();\n return;\n }\n setSkills(result);\n setPhase(Phase.Ask);\n } catch {\n store.setSkillsComplete(true);\n exit();\n }\n })();\n }, []); // eslint-disable-line\n\n // After a mint failure the host owns the end (status 1, analytics).\n const exit = () => {\n if (!store.mintHandoff) store.requestExit(0);\n };\n\n const handleKeep = () => {\n store.setSkillsComplete(true);\n exit();\n };\n\n const handleRemove = async () => {\n setPhase(Phase.Removing);\n for (const skill of skills) {\n try {\n await rm(join(skillsDir, skill.name), {\n recursive: true,\n force: true,\n });\n } catch {\n // Best-effort removal\n }\n }\n try {\n const remaining = await readdir(skillsDir);\n if (remaining.length === 0) {\n await rm(skillsDir, { recursive: true, force: true });\n }\n } catch {\n // Best-effort cleanup\n }\n setPhase(Phase.Done);\n // Give React a tick to paint the \"Skills removed.\" message before exit\n setTimeout(() => {\n store.setSkillsComplete(false);\n exit();\n }, 600);\n };\n\n return (\n <Box flexDirection=\"column\" flexGrow={1}>\n <Text bold color={Colors.accent}>\n Keep the skills?\n </Text>\n\n <Box marginTop={1} flexDirection=\"column\">\n {phase === Phase.Loading && (\n <Text dimColor>Checking installed skills...</Text>\n )}\n\n {phase === Phase.Ask && (\n <>\n <Text dimColor>\n The wizard installed open-source skills that help AI coding agents\n integrate PostHog into your project:\n </Text>\n <Box marginTop={1} flexDirection=\"column\" marginLeft={2}>\n <Text dimColor>.claude/</Text>\n <Text dimColor> skills/</Text>\n {skills.map((skill) => (\n <Box key={skill.name} flexDirection=\"column\">\n <Text dimColor> {skill.name}/</Text>\n {skill.children.map((child) => (\n <Text key={child} dimColor>\n {' '}\n {child}\n </Text>\n ))}\n </Box>\n ))}\n </Box>\n <Box marginTop={1}>\n <Text dimColor>\n Source: <Text color=\"cyan\">{CONTEXT_MILL_URL}</Text>\n </Text>\n </Box>\n <Box marginTop={1}>\n <ConfirmationInput\n message=\"Keep the installed skills?\"\n confirmLabel=\"Keep [Enter]\"\n cancelLabel=\"Remove [Esc]\"\n onConfirm={handleKeep}\n onCancel={() => void handleRemove()}\n />\n </Box>\n </>\n )}\n\n {phase === Phase.Removing && <Text dimColor>Removing skills...</Text>}\n\n {phase === Phase.Done && <Text dimColor>Skills removed.</Text>}\n </Box>\n </Box>\n );\n};\n","import { Box, Text } from 'ink';\nimport { useRef, useState, useSyncExternalStore } from 'react';\nimport type { WizardStore } from '@tui/store';\nimport { PickerMenu } from '@tui/primitives/index';\nimport { useStdoutDimensions } from '@tui/hooks/useStdoutDimensions';\nimport { Colors } from '@tui/styles';\nimport {\n MINT_FAILURE_MESSAGE,\n MINT_FAILURE_BODY,\n MINT_FAILURE_CONTACT,\n} from '@tui/mint-failure';\nimport type { WizardSpellbook } from '@tui/services/wizard-spellbook';\nimport type { CodingAgent } from '../services/coding-agent-launcher';\n\nexport type MintFailureServices = {\n leaveSpellbook: () => Promise<WizardSpellbook>;\n openAgent: (agent: CodingAgent, spellbookPath: string) => Promise<void>;\n logPath: string;\n};\n\ntype Action = 'save' | CodingAgent | 'report' | 'continue' | 'exit' | 'retry';\n\n/** Two blocks of the PostHog flag, left of the headline. */\nconst Mark = () => (\n <Text>\n <Text color=\"#1D4AFF\">█</Text>\n <Text color={Colors.accent}>█</Text>\n </Text>\n);\n\nexport function MintFailureScreen({\n store,\n services,\n}: {\n store: WizardStore;\n services: MintFailureServices;\n}) {\n const [columns] = useStdoutDimensions();\n useSyncExternalStore(\n (cb) => store.subscribe(cb),\n () => store.getSnapshot(),\n );\n const busy = useRef(false);\n const [working, setWorking] = useState<string | null>(null);\n const [error, setError] = useState<string | null>(null);\n const [report, setReport] = useState(false);\n const [retry, setRetry] = useState<'save' | CodingAgent>('save');\n const { spellbook } = store;\n\n const select = async (action: Action) => {\n if (busy.current) return;\n if (action === 'exit' || action === 'continue')\n return store.setMintHandoff(action);\n if (action === 'report') return setReport(true);\n const task = action === 'retry' ? retry : action;\n setRetry(task);\n busy.current = true;\n setError(null);\n setWorking('Saving skill...');\n try {\n const saved = store.spellbook ?? (await services.leaveSpellbook());\n store.setSpellbook(saved);\n if (task !== 'save') {\n setWorking(`Opening ${task === 'claude' ? 'Claude Code' : 'Codex'}...`);\n await services.openAgent(task, saved.path);\n store.setMintHandoff('continue');\n }\n } catch (err) {\n setError(\n store.spellbook\n ? err instanceof Error\n ? err.message\n : 'Could not open your agent.'\n : 'Could not save the skill. Check this folder is writable and try again.',\n );\n } finally {\n busy.current = false;\n setWorking(null);\n }\n };\n\n const options: { label: string; value: Action }[] = error\n ? [\n { label: 'Try again', value: 'retry' },\n ...(spellbook\n ? [{ label: 'Continue setup', value: 'continue' as const }]\n : []),\n { label: 'Exit', value: 'exit' },\n ]\n : spellbook\n ? [\n { label: 'Continue', value: 'continue' },\n { label: 'Exit', value: 'exit' },\n ]\n : report\n ? [\n { label: 'Save skill', value: 'save' },\n { label: 'Exit', value: 'exit' },\n ]\n : [\n { label: 'Save skill', value: 'save' },\n { label: 'Open in Claude Code', value: 'claude' },\n { label: 'Open in Codex', value: 'codex' },\n { label: 'Report this issue', value: 'report' },\n { label: 'Exit', value: 'exit' },\n ];\n\n return (\n <Box\n flexDirection=\"column\"\n flexGrow={1}\n alignItems=\"center\"\n justifyContent=\"center\"\n >\n <Box\n width={Math.max(1, Math.min(78, columns - 4))}\n flexDirection=\"column\"\n alignItems=\"center\"\n >\n <Text bold>\n <Mark /> {spellbook ? 'Skill saved' : MINT_FAILURE_MESSAGE} 🦔\n </Text>\n <Box marginTop={1}>\n <Text>\n {spellbook\n ? spellbook.skillsIncluded\n ? 'Ask your agent to read this file and complete the task.'\n : 'The skill could not be downloaded. This file has instructions and links for your agent.'\n : report\n ? MINT_FAILURE_CONTACT\n : MINT_FAILURE_BODY}\n </Text>\n </Box>\n {report && !spellbook && (\n <Box marginTop={1}>\n <Text color=\"cyan\" wrap=\"wrap\">\n {services.logPath}\n </Text>\n </Box>\n )}\n {spellbook && (\n <Box marginTop={1}>\n <Text color=\"cyan\" wrap=\"wrap\">\n {spellbook.path}\n </Text>\n </Box>\n )}\n {error && (\n <Box marginTop={1}>\n <Text color={Colors.error}>{error}</Text>\n </Box>\n )}\n <Box marginTop={1} flexDirection=\"column\">\n {working ? (\n <Text>{working}</Text>\n ) : (\n <PickerMenu\n key={[report, Boolean(spellbook), Boolean(error)].join('-')}\n options={options}\n onSelect={(action) => void select(action as Action)}\n />\n )}\n </Box>\n </Box>\n </Box>\n );\n}\n","import { spawn } from 'node:child_process';\nimport { constants } from 'node:fs';\nimport { access, mkdtemp, writeFile, rm } from 'node:fs/promises';\nimport { tmpdir } from 'node:os';\nimport path from 'node:path';\n\nexport type CodingAgent = 'claude' | 'codex';\nconst quote = (value: string): string => `'${value.replace(/'/g, `'\"'\"'`)}'`;\nconst batchQuote = (value: string): string => `\"${value.replace(/%/g, '%%')}\"`;\n\nasync function executable(name: string): Promise<string> {\n const extensions =\n process.platform === 'win32' ? ['.exe', '.cmd', '.bat'] : [''];\n for (const directory of (process.env.PATH ?? '').split(path.delimiter)) {\n if (!path.isAbsolute(directory)) continue;\n for (const extension of extensions) {\n const candidate = path.join(directory, name + extension);\n try {\n await access(candidate, constants.X_OK);\n return candidate;\n } catch {\n continue;\n }\n }\n }\n throw new Error(\n `${\n name === 'claude' ? 'Claude Code' : name === 'codex' ? 'Codex' : name\n } is not installed or could not be found.`,\n );\n}\n\nfunction launch(\n command: string,\n args: string[],\n cwd: string,\n verbatim = false,\n): Promise<void> {\n return new Promise((resolve, reject) => {\n const child = spawn(command, args, {\n cwd,\n stdio: 'ignore',\n detached: true,\n shell: false,\n windowsVerbatimArguments: verbatim,\n });\n const timer = setTimeout(() => {\n child.unref();\n resolve();\n }, 500);\n child.once('error', (error) => {\n clearTimeout(timer);\n reject(error);\n });\n child.once('exit', (code) => {\n clearTimeout(timer);\n if (code === 0) resolve();\n else reject(new Error('Could not open a terminal for your agent.'));\n });\n });\n}\n\nexport async function openCodingAgent(\n agent: CodingAgent,\n directory: string,\n spellbookPath: string,\n): Promise<void> {\n const cwd = path.resolve(directory);\n const command = await executable(agent);\n const prompt = `Read <${path.resolve(\n spellbookPath,\n )}> and complete the task described in the Wizard's spell books. Inspect what has already been done before making changes.`;\n if (process.platform === 'linux') {\n await launch(\n await executable('x-terminal-emulator'),\n ['-e', command, prompt],\n cwd,\n );\n return;\n }\n const mac = process.platform === 'darwin';\n if (!mac && process.platform !== 'win32') {\n throw new Error(\n 'Opening an agent is not supported on this system. Use the saved skill path to continue.',\n );\n }\n const folder = await mkdtemp(path.join(tmpdir(), 'wizard-handoff-'));\n const script = path.join(\n folder,\n mac ? 'open-agent.command' : 'open-agent.cmd',\n );\n try {\n const lines = mac\n ? [\n '#!/bin/sh',\n `rm -f ${quote(script)}`,\n `rmdir ${quote(folder)}`,\n `export PATH=${quote(process.env.PATH ?? '')}`,\n `cd ${quote(cwd)} || exit 1`,\n `exec ${quote(command)} ${quote(prompt)}`,\n ]\n : [\n '@echo off',\n 'chcp 65001 >nul',\n 'setlocal DisableDelayedExpansion',\n `cd /d ${batchQuote(cwd)} || exit /b 1`,\n `del \"%~f0\" & rmdir ${batchQuote(folder)} & ${batchQuote(\n command,\n )} ${batchQuote(prompt)}`,\n ];\n await writeFile(script, lines.join(mac ? '\\n' : '\\r\\n') + '\\n', {\n mode: 0o700,\n });\n\n if (mac) {\n // The system default handler for `.command` files (Terminal unless the\n // user has changed it).\n await launch('/usr/bin/open', [script], cwd);\n return;\n }\n\n const shell = process.env.ComSpec ?? 'cmd.exe';\n // `start` opens the system default terminal application. /s strips the\n // outer quotes so the inner ones survive intact.\n await launch(\n shell,\n ['/d', '/s', '/c', `\"start \"\" ${shell} /d /c \"${script}\"\"`],\n folder,\n true,\n );\n } catch (error) {\n await rm(folder, { recursive: true, force: true });\n throw error;\n }\n}\n","import fs from 'fs/promises';\nimport path from 'path';\nimport { getSkillsBaseUrl, POSTHOG_DOCS_URL } from '@shared/constants';\nimport type { ProgramConfig, WizardSession } from '@programs/types';\nimport { scanInstalledSkill } from '@programs';\nimport { downloadSkill } from '@shared/skill-install';\nimport {\n fetchSkillMenu,\n type SkillEntry,\n type SkillMenu,\n} from '@shared/skill-menu';\n\nexport type WizardSpellbook = { path: string; skillsIncluded: boolean };\ntype SpellbookSession = Pick<\n WizardSession,\n 'installDir' | 'integration' | 'skillId' | 'frameworkConfig'\n>;\n\nfunction selectSkills(\n menu: SkillMenu,\n session: SpellbookSession,\n program: ProgramConfig,\n): SkillEntry[] {\n const entries = Object.values(menu.categories)\n .flat()\n .filter((entry) => /^[a-z0-9]+(?:-[a-z0-9]+)*$/.test(entry.id));\n const skillId = program.skillId ?? session.skillId;\n const exact = entries.find((entry) => entry.id === skillId);\n if (exact) return [exact];\n\n const framework = session.integration;\n const referenceGroup = skillId === framework ? 'integration' : skillId;\n const references = entries.filter(\n (entry) => entry.group === referenceGroup && entry.framework === framework,\n );\n const reference = references.find((entry) => entry.default) ?? references[0];\n if (reference) return [reference];\n\n const flow = program.agentFlow ?? program.id;\n const groups = new Map<string, SkillEntry>();\n for (const entry of entries) {\n const group = entry.group;\n if (\n !group ||\n (group !== flow && !group.startsWith(`${flow}-`)) ||\n (entry.framework && entry.framework !== framework)\n ) {\n continue;\n }\n if (!groups.has(group) || entry.default) groups.set(group, entry);\n }\n return [...groups.values()];\n}\n\nfunction spellbookText(\n session: SpellbookSession,\n program: ProgramConfig,\n skills: SkillEntry[],\n): string {\n const framework = session.frameworkConfig?.metadata;\n const runDocs =\n typeof program.run === 'object' ? program.run.docsUrl : undefined;\n const docs = [\n ...new Set([framework?.docsUrl, runDocs, POSTHOG_DOCS_URL]),\n ].filter((url): url is string => Boolean(url));\n\n return [\n '# Wizard spell book',\n '',\n 'Complete this task in the project containing this spell book:',\n '',\n program.description,\n '',\n `Wizard program: ${program.id}`,\n ...(framework ? [`Detected framework: ${framework.name}`] : []),\n '',\n '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.',\n '',\n '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.',\n '',\n '## Setup instructions',\n '',\n ...(skills.length\n ? [\n 'Read the downloaded skills and their referenced files:',\n '',\n ...skills.map(\n (skill) => `- [${skill.id}](skills/${skill.id}/SKILL.md)`,\n ),\n '',\n 'Downloaded skills may cover only part of the task. Use the official documentation below to fill any gaps.',\n ]\n : [\n 'No matching skills could be downloaded. Use the official documentation below to complete the task.',\n ]),\n '',\n '## Official documentation',\n '',\n ...docs.map((url) => `- ${url}`),\n '',\n ].join('\\n');\n}\n\nexport async function writeWizardSpellbook(\n session: SpellbookSession,\n program: ProgramConfig,\n): Promise<WizardSpellbook> {\n const parent = path.join(session.installDir, '.posthog');\n await fs.mkdir(parent, { recursive: true });\n const directory = await fs.mkdtemp(path.join(parent, 'wizard-spellbook-'));\n const readme = path.join(directory, 'README.md');\n await fs.writeFile(readme, spellbookText(session, program, []));\n\n const menu = await fetchSkillMenu(getSkillsBaseUrl(), {\n timeoutMs: 10_000,\n maxAttempts: 1,\n });\n const installed: SkillEntry[] = [];\n for (const skill of menu ? selectSkills(menu, session, program) : []) {\n const result = await downloadSkill(skill, directory, {\n skillsRoot: 'skills',\n // No gateway here, so a flagged skill fails closed.\n scan: (dir) => scanInstalledSkill(dir, undefined),\n });\n if (result.success) {\n installed.push(skill);\n } else {\n await fs.rm(path.join(directory, 'skills', skill.id), {\n recursive: true,\n force: true,\n });\n }\n }\n await fs.writeFile(readme, spellbookText(session, program, installed));\n return { path: readme, skillsIncluded: installed.length > 0 };\n}\n","/**\n * ExitScreen — Final step in every program.\n *\n * Renders nothing. Immediately asks the host to end the run with 0.\n * The cleanup handler in start-tui.ts handles the exit summary line.\n */\n\nimport { useEffect } from 'react';\nimport type { WizardStore } from '../store';\n\nexport const ExitScreen = ({ store }: { store: WizardStore }) => {\n useEffect(() => {\n // After a mint failure the host owns the end (status 1, analytics).\n if (!store.mintHandoff) store.requestExit(0);\n }, []);\n\n return null;\n};\n","/**\n * AuthErrorScreen — Shown when the PostHog LLM Gateway returns a 401.\n *\n * Distinct causes, most specific first:\n * 0. The OAuth grant is gone — a pre-run refresh already got `invalid_grant`\n * from the token endpoint. The only branch backed by a server verdict\n * rather than inference, so it wins; re-running is the whole fix.\n * 1. Claude Code settings.json / managed-settings overrides ANTHROPIC_*\n * env vars — auth conflict. Tell the user to log out of Claude Code.\n * 2. The PostHog API key itself was rejected — bad prefix, missing scope,\n * expired, or wrong region. Don't blame Claude Code in this case.\n */\n\nimport { Box, Text } from 'ink';\nimport { useSyncExternalStore } from 'react';\nimport type { WizardStore } from '@tui/store';\nimport { Colors } from '@tui/styles';\nimport { useDismissOnAnyKey } from '@tui/hooks/useDismissOnAnyKey';\n\ninterface AuthErrorScreenProps {\n store: WizardStore;\n}\n\nexport const AuthErrorScreen = ({ store }: AuthErrorScreenProps) => {\n useSyncExternalStore(\n (cb) => store.subscribe(cb),\n () => store.getSnapshot(),\n );\n\n useDismissOnAnyKey(() => store.requestExit(1));\n\n const detail = store.authErrorDetail;\n const hasSettingsConflict = detail?.hasSettingsConflict ?? true;\n const conflicts = detail?.conflicts ?? [];\n const usingManagedLogin = detail?.usingManagedLogin ?? false;\n const credentialPlaces = detail?.credentialPlaces ?? [];\n const sessionExpired = detail?.sessionExpired ?? false;\n const logFilePath = detail?.logFilePath;\n\n return (\n <Box flexDirection=\"column\" flexGrow={1}>\n <Text color=\"red\" bold>\n {'✘'} Authentication error\n </Text>\n\n {sessionExpired ? (\n <>\n <Box flexDirection=\"column\" marginTop={1}>\n <Text>\n Your PostHog login expired while the wizard was running, so the\n LLM Gateway rejected it (401). Nothing on this machine is\n misconfigured — the session simply ran out.\n </Text>\n </Box>\n\n <Box marginTop={1}>\n <Text dimColor>Re-run the wizard and log in again:</Text>\n </Box>\n\n <Box flexDirection=\"column\" marginTop={1} paddingLeft={2}>\n <Text color=\"cyan\">npx @posthog/wizard</Text>\n </Box>\n\n <Box marginTop={1}>\n <Text dimColor>\n Any files the agent already wrote are still in your project.\n </Text>\n </Box>\n </>\n ) : usingManagedLogin ? (\n <>\n <Box flexDirection=\"column\" marginTop={1}>\n <Text>\n Conflicting Anthropic credentials. The agent signed in with an\n existing Claude login instead of the PostHog token the Wizard\n provided, so the LLM Gateway rejected it (401).\n </Text>\n </Box>\n\n {credentialPlaces.length > 0 && (\n <Box flexDirection=\"column\" marginTop={1} paddingLeft={2}>\n <Text dimColor>Conflicting credentials may come from:</Text>\n {credentialPlaces.map((place) => (\n <Text key={place}>\n {'•'} {place}\n </Text>\n ))}\n </Box>\n )}\n\n <Box marginTop={1}>\n <Text dimColor>\n Log out of Claude Code (clears the stored login), then re-run the\n Wizard:\n </Text>\n </Box>\n\n <Box flexDirection=\"column\" marginTop={1} paddingLeft={2}>\n <Text color=\"cyan\">claude auth logout</Text>\n </Box>\n </>\n ) : hasSettingsConflict ? (\n <>\n <Box flexDirection=\"column\" marginTop={1}>\n <Text>\n The Wizard couldn't connect to the PostHog LLM Gateway. Claude\n Code settings on this machine override the Wizard's credentials.\n </Text>\n </Box>\n\n {conflicts.length > 0 && (\n <Box flexDirection=\"column\" marginTop={1} paddingLeft={2}>\n {conflicts.map((conflict) => (\n <Text key={conflict.path}>\n {'•'} <Text bold>{conflict.path}</Text> sets{' '}\n <Text color=\"yellow\">{conflict.keys.join(', ')}</Text>\n </Text>\n ))}\n </Box>\n )}\n\n <Box marginTop={1}>\n <Text dimColor>\n Remove those keys from the file(s) above, or log out of Claude\n Code, then re-run the Wizard:\n </Text>\n </Box>\n\n <Box flexDirection=\"column\" marginTop={1} paddingLeft={2}>\n <Text color=\"cyan\">claude auth logout</Text>\n </Box>\n </>\n ) : (\n <>\n <Box flexDirection=\"column\" marginTop={1}>\n <Text>\n The PostHog LLM Gateway rejected the API key. Common causes:\n </Text>\n </Box>\n\n <Box flexDirection=\"column\" marginTop={1} paddingLeft={2}>\n <Text>\n {'•'} Wrong key type — pass a personal API key (\n <Text color=\"cyan\">phx_xxx</Text>).\n </Text>\n <Text dimColor>\n {' '}pha_ is an OAuth access token, phc_ is a project key.\n </Text>\n <Text>\n {'•'} Missing scope — the key needs{' '}\n <Text color=\"cyan\">llm_gateway:read</Text>.\n </Text>\n <Text>{'•'} Expired or revoked key.</Text>\n <Text>\n {'•'} Region mismatch — <Text color=\"cyan\">--region</Text> must\n match where the key was issued (us vs eu).\n </Text>\n </Box>\n </>\n )}\n\n {logFilePath && (\n <Box marginTop={1}>\n <Text dimColor>Verbose log: {logFilePath}</Text>\n </Box>\n )}\n\n <Box marginTop={1}>\n <Text color={Colors.muted}>Press any key to exit</Text>\n </Box>\n </Box>\n );\n};\n","/**\n * SessionTimeoutScreen — shown when the OAuth login window expires before the\n * user completes authorization.\n *\n * Pushed as an overlay so it takes priority over the gated AuthScreen (which\n * never completes without credentials). Terminal state: any key exits, since\n * the only way forward is to re-run the wizard for a fresh login window.\n */\n\nimport { Box, Text } from 'ink';\nimport { useSyncExternalStore } from 'react';\nimport type { WizardStore } from '@tui/store';\nimport { Colors } from '@tui/styles';\nimport { OAUTH_TIMEOUT_MS } from '@shared/constants';\nimport { useDismissOnAnyKey } from '@tui/hooks/useDismissOnAnyKey';\n\ninterface SessionTimeoutScreenProps {\n store: WizardStore;\n}\n\nconst TIMEOUT_MINUTES = Math.round(OAUTH_TIMEOUT_MS / 60_000);\n\nexport const SessionTimeoutScreen = ({ store }: SessionTimeoutScreenProps) => {\n useSyncExternalStore(\n (cb) => store.subscribe(cb),\n () => store.getSnapshot(),\n );\n\n useDismissOnAnyKey(() => store.requestExit(1));\n\n return (\n <Box flexDirection=\"column\" flexGrow={1}>\n <Text color=\"red\" bold>\n {'✘'} Login timed out\n </Text>\n\n <Box marginTop={1}>\n <Text>The OAuth link timed out after {TIMEOUT_MINUTES} minutes.</Text>\n </Box>\n\n <Box marginTop={1}>\n <Text>Re-run the wizard to get a fresh link and try again.</Text>\n </Box>\n\n <Box marginTop={1}>\n <Text color={Colors.muted}>Press any key to exit</Text>\n </Box>\n </Box>\n );\n};\n","/**\n * WizardAskScreen — Overlay for the `wizard_ask` MCP tool.\n *\n * Walks the agent's question list one at a time and accumulates answers.\n * When the user submits the last question, the store resolves the\n * pending request and the overlay pops, returning the agent to its run.\n */\n\nimport { Box, Text, useInput } from 'ink';\nimport { PasswordInput, TextInput } from '@inkjs/ui';\nimport { useEffect, useState, useSyncExternalStore } from 'react';\nimport type { WizardStore } from '@tui/store';\nimport {\n LinkText,\n ModalOverlay,\n PickerMenu,\n extractUrls,\n} from '@tui/primitives/index';\nimport { Colors, Icons } from '@tui/styles';\nimport { copyToClipboard, openInBrowser } from '@utils/clipboard';\nimport { useKeyBindings } from '@tui/hooks/useKeyBindings';\nimport type { AskAnswers, AskQuestion } from '@agent/types';\n\ninterface WizardAskScreenProps {\n store: WizardStore;\n}\n\n/**\n * Key policy for the ask overlay: Esc declines the whole request, everything\n * else is left to the focused input. Extracted so the wiring is unit-testable\n * without a live Ink render (the test suite stubs `useInput` to a no-op).\n */\nexport function handleAskKey(\n key: { escape?: boolean },\n store: Pick<WizardStore, 'cancelPendingQuestion'>,\n): void {\n if (key.escape) store.cancelPendingQuestion();\n}\n\n/**\n * What pressing Esc actually does, phrased for the footer hint.\n *\n * Esc declines the *whole* request — {@link WizardStore.cancelPendingQuestion}\n * builds a cancelled answer for every question, so the ones already typed are\n * discarded too. The footer used to label that \"skip\", which on a multi-question\n * request reads as \"skip this field\": the warehouse task walks a source's\n * credentials one field at a time, several of them optional, and a user who\n * pressed Esc to pass on an optional field instead threw away the whole source\n * and dropped the agent onto its browser-handoff fallback. Naming the scope\n * costs a few characters and makes the destructive key read as destructive.\n */\nexport function askEscapeHint(total: number, answered: number): string {\n if (total <= 1) return 'skip';\n if (answered <= 0) return `skip all ${total} questions`;\n return `skip all ${total} questions, discarding the ${answered} you answered`;\n}\n\n/**\n * Whether the overlay must mask what the user types for this question.\n *\n * A `sensitive` answer is one the wizard has already promised to treat as a\n * secret: `wizard_ask` vaults it and hands the agent an opaque `secretRef`, so\n * the raw string never enters the model's conversation. Every other boundary\n * guards it the same way — the skip events carry no free text, handoff prose is\n * kept out of telemetry — but the overlay that collects it echoed it back in\n * plain text as it was typed, which is the one place a database password or an\n * API key is read by a person other than its owner: a shared screen, a pairing\n * session, a recorded terminal.\n *\n * `kind` is checked as well as the flag. The tool already rejects `sensitive`\n * on a picker, and a picker has nothing to mask, so this keeps the predicate\n * total over a question rather than relying on that rejection.\n */\nexport function shouldMaskAnswer(\n question: Pick<AskQuestion, 'kind' | 'sensitive'>,\n): boolean {\n return question.kind === 'text' && question.sensitive === true;\n}\n\n/**\n * Whether an answer would leave a required question effectively unanswered.\n *\n * The `wizard_ask` schema marks fields `required` (defaulting to true), but the\n * overlay used to submit whatever the input held — so pressing Enter on an empty\n * required credential field sent an empty string on to the agent. A blank host\n * or password is indistinguishable there from a real answer, so the warehouse\n * task ran on it, failed source creation, and dead-ended with no signal that the\n * user had in effect declined. Blocking the empty submit keeps the contract the\n * schema already advertises; Esc stays the way to skip. Optional fields\n * (`required === false`) are never blocked, and pickers always yield a value.\n */\nexport function isRequiredButEmpty(\n question: Pick<AskQuestion, 'required'>,\n value: string | string[],\n): boolean {\n if (question.required === false) return false;\n return Array.isArray(value) ? value.length === 0 : value.trim().length === 0;\n}\n\nexport const WizardAskScreen = ({ store }: WizardAskScreenProps) => {\n useSyncExternalStore(\n (cb) => store.subscribe(cb),\n () => store.getSnapshot(),\n );\n\n const pending = store.session.pendingQuestion;\n\n // Index of the question currently being answered. Resets when a fresh\n // pending request arrives.\n const [index, setIndex] = useState(0);\n const [answers, setAnswers] = useState<AskAnswers>({});\n const [lastPendingId, setLastPendingId] = useState<string | null>(null);\n // Set when the user tries to submit an empty required field, cleared once a\n // real answer goes through. Drives the inline \"this field is required\" nudge.\n const [requiredHint, setRequiredHint] = useState(false);\n // What the user last did with the link, so the overlay can confirm it. The\n // auto-copy below seeds 'copied'; pressing `o`/`c` overrides it.\n const [linkStatus, setLinkStatus] = useState<'idle' | 'copied' | 'opened'>(\n 'idle',\n );\n\n // For rich-link prompts (opt-in programs only) copy a lone URL to the\n // clipboard, so users on terminals without OSC 8 support can still paste it.\n // Only fires when the current question has exactly one URL, to avoid\n // clobbering the clipboard ambiguously. `soleUrl` is the sole effect dep.\n const richLinks = pending?.richLinks ?? false;\n const currentPrompt = pending?.questions[index]?.prompt ?? '';\n const promptUrls = richLinks ? extractUrls(currentPrompt) : [];\n const soleUrl = promptUrls.length === 1 ? promptUrls[0] : null;\n\n // The `o`/`c` keybinds would steal keystrokes from a free-text answer, so\n // only offer them on picker questions (where the user isn't typing).\n const isTextQuestion = pending?.questions[index]?.kind === 'text';\n const canActOnLink = !!soleUrl && !isTextQuestion;\n\n // Split the prompt at the link so the o/c hint sits right under it, with\n // trailing text below. Falls back to the whole prompt when there's no\n // single-link split.\n const linkSplitIndex =\n canActOnLink && soleUrl ? currentPrompt.indexOf(soleUrl) : -1;\n const splitLink = soleUrl !== null && linkSplitIndex !== -1;\n const linkEnd = splitLink && soleUrl ? linkSplitIndex + soleUrl.length : 0;\n const promptHead = splitLink\n ? currentPrompt.slice(0, linkEnd)\n : currentPrompt;\n const linkTrailingText = splitLink\n ? currentPrompt.slice(linkEnd).replace(/^\\s+/, '')\n : '';\n\n useEffect(() => {\n setLinkStatus('idle');\n if (!soleUrl) return;\n // Seed the clipboard silently for terminals without OSC 8. Status stays\n // 'idle' so the o/c hint shows until the user acts.\n void copyToClipboard(soleUrl);\n }, [soleUrl]);\n\n // Explicit, discoverable link actions. OSC 8 makes the link clickable only on\n // terminals that support it (not macOS Terminal.app), so `o` opens it in the\n // browser directly — the one path that works everywhere — and `c` copies it\n // as a fallback. Both register hints in the bar via useKeyBindings.\n useKeyBindings(\n 'wizard-ask-link',\n canActOnLink && soleUrl\n ? [\n {\n match: 'o',\n label: 'o',\n action: 'open in browser',\n handler: () => {\n void openInBrowser(soleUrl).then((ok) => {\n if (ok) setLinkStatus('opened');\n });\n },\n },\n {\n match: 'c',\n label: 'c',\n action: 'copy link',\n handler: () => {\n void copyToClipboard(soleUrl).then((ok) => {\n if (ok) setLinkStatus('copied');\n });\n },\n },\n ]\n : [],\n );\n\n // Esc declines the whole request. Cancellation is a first-class outcome the\n // ask bridge and the wizard_ask tool already expect (a task treats it as \"the\n // user declined\" and falls back — e.g. to a browser setup link), so without\n // this a user who can't answer has no exit but typing placeholders or waiting\n // out the multi-minute per-question timeout. Every field comes back cancelled.\n useInput((_input, key) => handleAskKey(key, store));\n\n if (!pending) return null;\n\n // Reset accumulator state when the agent opens a new request mid-session.\n if (pending.id !== lastPendingId) {\n setLastPendingId(pending.id);\n setIndex(0);\n setAnswers({});\n setRequiredHint(false);\n return null;\n }\n\n const question = pending.questions[index];\n if (!question) return null;\n\n const total = pending.questions.length;\n const progress = total > 1 ? `Question ${index + 1} of ${total}` : null;\n const escapeHint = askEscapeHint(total, index);\n // An optional text field already accepts an empty Enter (see\n // `isRequiredButEmpty`) — it just never said so, leaving Esc as the only\n // visible exit from a question the user did not want to answer.\n const canSkipOne = question.kind === 'text' && question.required === false;\n\n const submit = (value: string | string[]) => {\n // Don't let a required field go through empty — it would reach the agent as\n // a blank answer it can't tell from a real one. Nudge instead; Esc skips.\n if (isRequiredButEmpty(question, value)) {\n setRequiredHint(true);\n return;\n }\n setRequiredHint(false);\n const next: AskAnswers = { ...answers, [question.id]: value };\n if (index + 1 < total) {\n setAnswers(next);\n setIndex(index + 1);\n // The request's timeout is armed per question, and only this screen\n // knows a question was answered — the request itself resolves once, at\n // the end of the walk.\n store.noteAskProgress();\n return;\n }\n store.resolvePendingQuestion(next);\n };\n\n return (\n <ModalOverlay\n borderColor={Colors.accent}\n title={`${Icons.diamond} ${pending.source}`}\n titleColor={Colors.accent}\n width={72}\n >\n {progress && (\n <Box marginBottom={1}>\n <Text dimColor>{progress}</Text>\n </Box>\n )}\n <Box flexDirection=\"column\">\n {pending.richLinks ? (\n <LinkText text={promptHead} />\n ) : (\n <Text>{question.prompt}</Text>\n )}\n </Box>\n {/* o/c hint until the user acts, then a confirmation. */}\n {canActOnLink && (\n <Box marginTop={1}>\n {linkStatus === 'idle' ? (\n <Text dimColor>\n Press <Text color={Colors.accent}>o</Text> to open it in your\n browser, or <Text color={Colors.accent}>c</Text> to copy the link.\n </Text>\n ) : linkStatus === 'opened' ? (\n <Text color={Colors.success}>\n {Icons.check} Opening the link in your browser…\n </Text>\n ) : (\n <Text color={Colors.success}>\n {Icons.check} Link copied to clipboard. Paste it in your browser.\n </Text>\n )}\n </Box>\n )}\n {/* Prompt text after the link */}\n {linkTrailingText && (\n <Box marginTop={1}>\n <Text>{linkTrailingText}</Text>\n </Box>\n )}\n <Box marginTop={1}>\n {/* `key` forces React to remount the input when the question changes\n so per-question internal state (typed buffer, picker focus) doesn't\n bleed across questions. */}\n <QuestionInput\n key={`${pending.id}:${question.id}`}\n question={question}\n onSubmit={submit}\n />\n </Box>\n {requiredHint && (\n <Box marginTop={1}>\n <Text color={Colors.accent}>\n {Icons.warning} This field is required — type an answer, or press\n ESC to {escapeHint}.\n </Text>\n </Box>\n )}\n {canSkipOne && (\n <Box marginTop={1}>\n <Text dimColor>\n Optional — press <Text color={Colors.accent}>ENTER</Text> on an\n empty answer to skip just this one.\n </Text>\n </Box>\n )}\n <Box marginTop={1}>\n <Text dimColor>\n <Text color={Colors.accent}>ESC</Text> {escapeHint}\n </Text>\n </Box>\n </ModalOverlay>\n );\n};\n\ninterface QuestionInputProps {\n question: AskQuestion;\n onSubmit: (value: string | string[]) => void;\n}\n\nconst QuestionInput = ({ question, onSubmit }: QuestionInputProps) => {\n switch (question.kind) {\n case 'single':\n return (\n <PickerMenu<string>\n options={(question.options ?? []).map((o) => ({\n label: o.label,\n value: o.value,\n }))}\n onSelect={(value) => {\n const v = Array.isArray(value) ? value[0] : value;\n onSubmit(v);\n }}\n />\n );\n\n case 'multi': {\n const multiOptions = (question.options ?? []).map((o) => ({\n label: o.label,\n value: o.value,\n description: o.description,\n }));\n // Add vertical breathing room between options only when at least one\n // carries a description — keeps every description-less multi-select\n // (every other program) spaced exactly as before.\n const hasDescriptions = multiOptions.some((o) => o.description);\n return (\n <PickerMenu<string>\n mode=\"multi\"\n optionMarginBottom={hasDescriptions ? 1 : 0}\n options={multiOptions}\n onSelect={(value) => {\n const v = Array.isArray(value) ? value : [value];\n onSubmit(v);\n }}\n />\n );\n }\n\n case 'text': {\n const Input = shouldMaskAnswer(question) ? PasswordInput : TextInput;\n return (\n // `width=\"100%\"` on both the column and the hint row anchors them to\n // the modal's content width — without it, Ink/Yoga shrinks the column\n // to fit its widest child, so the right-aligned hint walks left/right\n // as the typed text changes width.\n <Box flexDirection=\"column\" width=\"100%\">\n <Input\n placeholder=\"Type your answer\"\n onSubmit={(value) => onSubmit(value)}\n />\n <Box marginTop={1} width=\"100%\" justifyContent=\"flex-end\">\n <Text>\n <Text color={Colors.accent}>ENTER</Text>\n <Text dimColor> submit</Text>\n </Text>\n </Box>\n </Box>\n );\n }\n }\n};\n","/**\n * Capability for MCP clients whose editor CLI has its own login command\n * (`claude mcp login`, `codex mcp login`). The editor owns the OAuth token and\n * its refresh, and its login command requires a real terminal — so the wizard\n * never runs it, it surfaces the exact command for the user to run.\n */\nexport interface LoginCapable {\n /** The editor's login command (e.g. `claude mcp login posthog`), or null when unusable right now (CLI absent). */\n loginCommand(local?: boolean): string | null;\n /** The login command when the server comes from the editor's plugin (e.g. `plugin:posthog:posthog`), or null when unusable. */\n pluginLoginCommand?(): string | null;\n}\n\nexport function isLoginCapable<T>(client: T): client is T & LoginCapable {\n return (\n typeof client === 'object' && client !== null && 'loginCommand' in client\n );\n}\n","/**\n * Capability for MCP clients that are connected by opening a hosted page in\n * the browser rather than writing a local config or running a CLI install.\n *\n * Mirrors the PluginCapable pattern in plugin-client.ts: the client carries the\n * URL and instruction text (product knowledge); the TUI renders whatever the\n * capability surfaces (generic machinery).\n */\n\nexport interface BrowserFinishable {\n /** URL the user opens to finish connecting (also shown as copy-paste fallback). */\n connectorUrl: string;\n /** One-line instruction shown after the page opens. */\n finishInstruction: string;\n}\n\nexport function isBrowserFinishable<T>(c: T): c is T & BrowserFinishable {\n return (\n typeof c === 'object' &&\n c !== null &&\n 'connectorUrl' in c &&\n 'finishInstruction' in c\n );\n}\n","/**\n * McpInstaller — service layer between McpScreen and MCP business logic.\n *\n * Decouples the screen from step internals. Testable, swappable,\n * no dynamic imports in React components.\n */\n\nimport {\n getSupportedClients,\n removeMCPServer,\n getInstalledClients,\n getSupportedPluginClients,\n installPlugins as runPluginInstall,\n} from '@shared/mcp-clients/install';\nimport { ALL_FEATURE_VALUES } from '@shared/mcp-clients/defaults';\nimport {\n McpClientStatus,\n namesWithStatus,\n redactSecrets,\n toClientResult,\n type McpClientResult,\n} from '@shared/mcp-clients/results';\nimport { isPluginCapable } from '@shared/mcp-clients/plugin-client';\nimport { isLoginCapable } from '@shared/mcp-clients/login-client';\nimport { isBrowserFinishable } from '@shared/mcp-clients/browser-client';\nimport { logToFile } from '@utils/debug';\nimport { analytics } from '@utils/analytics';\n\nexport interface McpClientInfo {\n name: string;\n supportsPlugin: boolean;\n /** True when the plugin already ships the posthog MCP server (no direct entry needed). */\n pluginBundlesMcp: boolean;\n /**\n * Set for clients connected by opening a hosted page in the browser. The\n * Done screen renders this so the user knows to finish setup in the browser.\n */\n finish?: { url: string; instruction: string };\n /** The editor's own login command (e.g. `claude mcp login posthog`), the one manual step left. */\n loginCommand?: string;\n /** Same, for the plugin-provided server (e.g. `claude mcp login plugin:posthog:posthog`). */\n pluginLoginCommand?: string;\n}\n\nexport { McpClientStatus };\nexport type { McpClientResult };\n\nexport interface McpInstaller {\n /** Detect which MCP-capable editors are available on this machine. */\n detectClients(): Promise<McpClientInfo[]>;\n\n /**\n * Install the PostHog MCP server to the given clients. Returns one result per\n * client — including the ones that were already installed and the ones that\n * failed, so the screen can say which happened and why.\n */\n install(\n clientNames: string[],\n features?: string[],\n apiKey?: string,\n ): Promise<McpClientResult[]>;\n\n /**\n * Remove the PostHog MCP server from every client that has it. Returns one\n * result per client so a failed removal isn't reported as a success.\n */\n remove(local?: boolean): Promise<McpClientResult[]>;\n\n /** Install the PostHog AI plugin to supported clients. Best-effort: failures do not affect MCP outcome. */\n installPlugins(clientNames: string[]): Promise<McpClientResult[]>;\n}\n\n/**\n * Production McpInstaller backed by real MCP client detection and installation.\n */\nexport function createMcpInstaller(): McpInstaller {\n // Cache the raw MCPClient objects so install() can reference them by name\n let cachedClients: Array<{ name: string; raw: unknown }> = [];\n\n return {\n async detectClients(): Promise<McpClientInfo[]> {\n const supported = await getSupportedClients();\n cachedClients = supported.map((c) => ({ name: c.name, raw: c }));\n return supported.map((c) => ({\n name: c.name,\n supportsPlugin: isPluginCapable(c) && c.supportsPlugin(),\n pluginBundlesMcp: isPluginCapable(c) && c.pluginBundlesMcpServer(),\n finish: isBrowserFinishable(c)\n ? { url: c.connectorUrl, instruction: c.finishInstruction }\n : undefined,\n loginCommand: (isLoginCapable(c) && c.loginCommand(false)) || undefined,\n pluginLoginCommand:\n (isLoginCapable(c) && c.pluginLoginCommand?.()) || undefined,\n }));\n },\n\n async install(\n clientNames: string[],\n features?: string[],\n apiKey?: string,\n ): Promise<McpClientResult[]> {\n const resolvedFeatures = features ?? [...ALL_FEATURE_VALUES];\n const toInstall = cachedClients\n .filter((c) => clientNames.includes(c.name))\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n .map((c) => c.raw as any);\n\n if (toInstall.length === 0) {\n logToFile(\n `[McpInstaller] No clients matched. clientNames=${JSON.stringify(\n clientNames,\n )}, cached=${JSON.stringify(cachedClients.map((c) => c.name))}`,\n );\n return [];\n }\n\n const results: McpClientResult[] = [];\n for (const client of toInstall) {\n const name = client.name as string;\n try {\n const result = await client.addServer(\n apiKey,\n resolvedFeatures,\n false,\n );\n results.push(toClientResult(name, result));\n if (!result?.success) {\n // redactSecrets, not the raw reason: the CLIs we shell out to echo\n // the Authorization header back in their error output.\n logToFile(\n `[McpInstaller] addServer returned success=false for ${name}: ${redactSecrets(\n result?.reason ?? 'no reason given',\n )}`,\n );\n }\n } catch (err) {\n const reason = err instanceof Error ? err.message : String(err);\n logToFile(\n `[McpInstaller] addServer threw for ${name}: ${redactSecrets(\n reason,\n )}`,\n );\n results.push(toClientResult(name, { success: false, reason }));\n }\n }\n return results;\n },\n\n async remove(local?: boolean): Promise<McpClientResult[]> {\n // `local` was dropped here, so `mcp remove --local` looked at (and\n // reported on) the wrong server name.\n const installed = await getInstalledClients(local);\n if (installed.length === 0) return [];\n return removeMCPServer(installed, local);\n },\n\n async installPlugins(clientNames: string[]): Promise<McpClientResult[]> {\n const rawClients = cachedClients\n .filter((c) => clientNames.includes(c.name))\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n .map((c) => c.raw as any);\n\n const pluginClients = getSupportedPluginClients(rawClients);\n const results = await runPluginInstall(pluginClients);\n\n const already = namesWithStatus(results, McpClientStatus.Unchanged);\n analytics.wizardCapture('mcp plugins installed', {\n // `clients` keeps its original meaning — every client that ended up with\n // the plugin — so existing insights don't dip when a re-run reports\n // already-installed instead of a fresh write.\n clients: [\n ...namesWithStatus(results, McpClientStatus.Changed),\n ...already,\n ],\n already_installed: already,\n attempted: pluginClients.map((c) => c.name),\n });\n\n return results;\n },\n };\n}\n","/**\n * Screen registry — maps screen names to React components.\n *\n * The core mounts its own screens and overlays here. Each program's screens\n * come from its TUI entry (`programs/<id>/index.ts`, `screens`), so adding a\n * program screen touches only that program's folder:\n * 1. Create the component in programs/<id>/screens/.\n * 2. Name its id in programs/<id>/screen-ids.ts.\n * 3. Map the id to the component in the entry's `screens`.\n * 4. Reference the id by `screenId` in the program's flow.\n */\n\nimport type { ReactNode } from 'react';\nimport path from 'node:path';\nimport { getLogFilePath } from '@utils/debug';\nimport type { WizardStore } from './store.js';\nimport { ScreenId, Overlay, type ScreenName } from './router.js';\nimport { listFlowOwners } from './flow-owner.js';\n\nimport { HealthCheckScreen } from './screens/health/HealthCheckScreen.js';\nimport { SettingsOverrideScreen } from './screens/SettingsOverrideScreen.js';\nimport { ManagedSettingsScreen } from './screens/ManagedSettingsScreen.js';\nimport { PortConflictScreen } from './screens/PortConflictScreen.js';\nimport { TaskNoticeScreen } from './screens/TaskNoticeScreen.js';\nimport { ManualAuthCodeScreen } from './screens/ManualAuthCodeScreen.js';\nimport { SetupScreen } from './screens/SetupScreen.js';\nimport { AuthScreen } from './screens/AuthScreen.js';\nimport { AiOptInRequiredScreen } from './screens/AiOptInRequiredScreen.js';\nimport { RunScreen } from './screens/RunScreen.js';\nimport { McpScreen } from './screens/McpScreen.js';\nimport { SlackConnectScreen } from './screens/SlackConnectScreen.js';\nimport { KeepSkillsScreen } from './screens/KeepSkillsScreen.js';\nimport { OutroScreen } from './screens/OutroScreen.js';\nimport { MintFailureScreen } from './screens/MintFailureScreen.js';\nimport type { MintFailureServices } from './screens/MintFailureScreen.js';\nimport { openCodingAgent } from './services/coding-agent-launcher.js';\nimport { writeWizardSpellbook } from '@tui/services/wizard-spellbook';\nimport { getProgramConfig } from '@programs';\nimport { ExitScreen } from './screens/ExitScreen.js';\nimport { AuthErrorScreen } from './screens/AuthErrorScreen.js';\nimport { SessionTimeoutScreen } from './screens/SessionTimeoutScreen.js';\nimport { WizardAskScreen } from './screens/WizardAskScreen.js';\nimport { createMcpInstaller } from './services/mcp-installer.js';\nimport type { McpInstaller } from './services/mcp-installer.js';\n\nexport interface ScreenServices extends MintFailureServices {\n mcpInstaller: McpInstaller;\n}\n\nexport function createServices(store: WizardStore): ScreenServices {\n return {\n get logPath() {\n return path.resolve(getLogFilePath());\n },\n openAgent: (agent, spellbookPath) =>\n openCodingAgent(agent, store.session.installDir, spellbookPath),\n leaveSpellbook: () =>\n writeWizardSpellbook(\n store.session,\n getProgramConfig(store.router.activeProgram),\n ),\n mcpInstaller: createMcpInstaller(),\n };\n}\n\nexport function createScreens(\n store: WizardStore,\n services: ScreenServices,\n): Record<ScreenName, ReactNode> {\n const programScreens: Record<string, ReactNode> = {};\n for (const program of listFlowOwners()) {\n for (const [id, render] of Object.entries(program.screens ?? {})) {\n programScreens[id] ??= render(store, services);\n }\n }\n // Typed on the core ids, so a core screen without a mount fails to compile.\n const core: Record<ScreenId | Overlay, ReactNode> = {\n // Overlays\n [Overlay.SettingsOverride]: <SettingsOverrideScreen store={store} />,\n [Overlay.ManagedSettings]: <ManagedSettingsScreen store={store} />,\n [Overlay.PortConflict]: <PortConflictScreen store={store} />,\n [Overlay.TaskNotice]: <TaskNoticeScreen store={store} />,\n [Overlay.ManualAuthCode]: <ManualAuthCodeScreen store={store} />,\n [Overlay.AuthError]: <AuthErrorScreen store={store} />,\n [Overlay.SessionTimeout]: <SessionTimeoutScreen store={store} />,\n [Overlay.WizardAsk]: <WizardAskScreen store={store} />,\n\n // Core flow screens\n [ScreenId.HealthCheck]: <HealthCheckScreen store={store} />,\n [ScreenId.Setup]: <SetupScreen store={store} />,\n [ScreenId.Auth]: <AuthScreen store={store} />,\n [ScreenId.AiOptIn]: <AiOptInRequiredScreen store={store} />,\n [ScreenId.Run]: <RunScreen store={store} />,\n [ScreenId.Mcp]: (\n <McpScreen store={store} installer={services.mcpInstaller} />\n ),\n [ScreenId.SlackConnect]: <SlackConnectScreen store={store} />,\n [ScreenId.KeepSkills]: <KeepSkillsScreen store={store} />,\n [ScreenId.Outro]: <OutroScreen store={store} />,\n [ScreenId.MintFailure]: (\n <MintFailureScreen store={store} services={services} />\n ),\n [ScreenId.Exit]: <ExitScreen store={store} />,\n };\n return { ...programScreens, ...core };\n}\n","/** The TUI's login: the browser OAuth flow, shown on the auth screen, as a credentials provider. */\nimport type {\n CredentialsProvider,\n ResolvedProgramCredentials,\n WizardSession,\n} from '@programs/types';\nimport { analytics } from '@utils/analytics';\nimport { logToFile } from '@utils/debug';\nimport type { WizardStore } from '@tui/store';\nimport { getOrAskForProjectData } from './project-data.js';\n\n/** Log in once through OAuth for the session's launch values. */\nexport async function oauthLogin(\n session: WizardSession,\n programId: string,\n store: WizardStore,\n): Promise<ResolvedProgramCredentials> {\n logToFile('[agent-runner] starting OAuth');\n const data = await getOrAskForProjectData({\n store,\n signup: session.signup,\n projectId: session.projectId,\n email: session.email,\n region: session.region,\n baseUrl: session.baseUrl,\n localMcp: session.localMcp,\n programId,\n });\n analytics.wizardCapture('auth complete', { project_id: data.projectId });\n return {\n posthog: {\n accessToken: data.accessToken,\n refreshToken: data.refreshToken,\n expiresAt: data.expiresAt,\n oauthClientId: data.oauthClientId,\n projectApiKey: data.projectApiKey,\n host: data.host,\n projectId: data.projectId,\n missingScopes: data.missingScopes,\n },\n project: data.project,\n apiUser: data.user,\n roleAtOrganization: data.roleAtOrganization,\n };\n}\n\n/** The OAuth login as `runProgram`'s provider, reading the store's session when it is asked. */\nexport function oauthCredentials(store: WizardStore): CredentialsProvider {\n return {\n resolve: (programId) => oauthLogin(store.session, programId, store),\n };\n}\n","import { useMemo } from 'react';\nimport { ScreenContainer } from './primitives/index.js';\nimport type { WizardStore } from './store.js';\nimport { createScreens, createServices } from './screen-registry.js';\n\ninterface AppProps {\n store: WizardStore;\n}\n\nexport const App = ({ store }: AppProps) => {\n const services = useMemo(() => createServices(store), [store]);\n const screens = useMemo(\n () => createScreens(store, services),\n [store, services],\n );\n\n return <ScreenContainer store={store} screens={screens} />;\n};\n","/**\n * exit-line.ts — builds the text printed to the MAIN terminal buffer after the\n * wizard leaves the alternate screen on exit.\n *\n * The TUI renders in the alternate screen buffer, which is torn down on exit —\n * everything the wizard drew (including the outro screen) is wiped. This line,\n * printed AFTER releaseTerminal(), is the only output that survives into the\n * user's scrollback. So the coding-agent handoff prompt is echoed here, on its\n * own plain line (no border, no bullets), which is what a terminal can\n * triple-click-select cleanly.\n *\n * Kept free of `ink`/`@inkjs/ui` imports so it stays a pure, unit-testable\n * function (start-tui.ts itself pulls in the whole render tree).\n */\n\nimport { type WizardStore } from './store.js';\nimport { totalTokenCount } from '@tui/token-usage';\nimport { OutroKind } from '@shared/outro';\nimport { isRunFailure, MINT_FAILURE_CONTACT } from '@tui/mint-failure';\nimport { formatTokenCount, formatCostUsd } from '@shared/token-pricing';\nimport { getLogFilePath } from '@utils/debug';\n\nconst RESET_ATTRS = '\\x1b[0m';\nconst GREEN = '\\x1b[32m';\nconst BOLD = '\\x1b[1m';\nconst DIM = '\\x1b[2m';\n\n/**\n * Mirrors the hidden Ctrl+T HUD's tally into post-exit scrollback — but only\n * when the HUD is actually visible at exit (`store.tokenHudVisible`, which\n * defaults on in dev/test and off in production; `useDismissOnAnyKey`\n * already keeps Ctrl+T from also dismissing the outro screen underneath\n * it). A production run where the user never toggled it on shouldn't have a\n * cost number appear from nowhere once the TUI tears down. `null` when the\n * HUD is hidden, or the run never produced any usage (e.g. non-agent\n * programs).\n */\nfunction tokenCostLine(store: WizardStore): string | null {\n if (!store.tokenHudVisible) return null;\n const usage = store.tokenUsage;\n if (totalTokenCount(usage) === 0) return null;\n\n const label = usage.costIsFinal ? 'Final cost' : 'Cost (estimate)';\n return (\n `${DIM}${label}: ${formatCostUsd(usage.costUsd)}` +\n ` (in ${formatTokenCount(usage.inputTokens)}` +\n ` · out ${formatTokenCount(usage.outputTokens)}` +\n ` · cache read ${formatTokenCount(usage.cacheReadTokens)}` +\n ` · cache write ${formatTokenCount(\n usage.cacheCreationTokens,\n )})${RESET_ATTRS}`\n );\n}\n\n/**\n * The one manual step the wizard can't do itself: the editor's own MCP login.\n * Echoed into scrollback like the handoff prompt — command on its own plain\n * line so a terminal can triple-click-select it.\n */\nfunction mcpLoginBlock(store: WizardStore): string | null {\n const commands = store.mcpLoginCommands;\n if (!commands || commands.length === 0) return null;\n return (\n `${GREEN}${BOLD}\\u2714 Authenticate to finish (opens your browser):${RESET_ATTRS}\\n` +\n commands.join('\\n')\n );\n}\n\nexport function getExitLine(store: WizardStore): string {\n const outro = store.session.outroData;\n const label = store.programLabel ?? 'Wizard';\n const costLine = tokenCostLine(store);\n const loginBlock = mcpLoginBlock(store);\n\n if (isRunFailure(store.session)) {\n const spellbook = store.spellbook;\n return [\n 'The wizard is unavailable. Setup has not been completed.',\n spellbook &&\n `${DIM}Point your agent at this skill (triple-click to select):${RESET_ATTRS}\\n${spellbook.path}`,\n `${DIM}${MINT_FAILURE_CONTACT}${RESET_ATTRS}\\n${getLogFilePath()}`,\n loginBlock,\n costLine,\n ]\n .filter(Boolean)\n .join('\\n\\n');\n }\n\n if (outro?.kind === OutroKind.Success) {\n const message = outro.message ?? `${label} completed successfully.`;\n const reportSuffix =\n outro.reportFile && !message.includes(outro.reportFile)\n ? ` Check ./${outro.reportFile} for details.`\n : '';\n const headline = `${GREEN}${BOLD}✔${RESET_ATTRS} ${message}${reportSuffix}`;\n\n const parts = [headline];\n\n // The alt-screen outro is wiped on exit, so a program's primary\n // next-action link (e.g. the Self-driving inbox) only survives in\n // scrollback if echoed here. URL on its own line → clean triple-click.\n if (outro.primaryLink) {\n parts.push(\n `${DIM}${outro.primaryLink.label}:${RESET_ATTRS}\\n${outro.primaryLink.url}`,\n );\n }\n\n if (outro.nextSteps) {\n const bullets = outro.nextSteps.items\n .map((item) => `${DIM} • ${item}${RESET_ATTRS}`)\n .join('\\n');\n parts.push(`${DIM}${outro.nextSteps.heading}${RESET_ATTRS}\\n${bullets}`);\n }\n\n if (outro.handoffPrompt) {\n parts.push(\n `${DIM}Hand this to your coding agent to finish up (triple-click to select):${RESET_ATTRS}\\n` +\n outro.handoffPrompt,\n );\n }\n\n if (loginBlock) parts.push(loginBlock);\n if (costLine) parts.push(costLine);\n\n return parts.join('\\n\\n');\n }\n\n const parts = loginBlock\n ? [loginBlock]\n : [`${DIM}${label} exited.${RESET_ATTRS}`];\n if (costLine) parts.push(costLine);\n return parts.join('\\n\\n');\n}\n","/**\n * start-tui.ts — Sets up the Ink TUI renderer over a new store.\n *\n * Renders in the terminal's alternate screen buffer so the wizard\n * doesn't pollute scrollback history. On exit, the previous terminal\n * content is restored and a single exit summary line is printed.\n */\n\nimport { render } from 'ink';\nimport { createElement } from 'react';\nimport { WizardStore, type ProgramId } from './store.js';\nimport { App } from './App.js';\nimport { enterDarkTerminal, releaseTerminal } from './terminal.js';\nimport { analytics } from '@utils/analytics';\nimport { logToFile } from '@utils/debug';\nimport { getExitLine } from './exit-line.js';\nimport { ErrorCodes, WizardError } from '@shared/errors';\n\nexport { releaseTerminal };\n\n/** Render the app for `program`. `onInterrupt` runs when Ink tears itself down on Ctrl+C; the caller ends the run. */\nexport function startTUI(\n version: string,\n program: ProgramId,\n onInterrupt: () => void,\n): {\n unmount: () => void;\n store: WizardStore;\n waitForSetup: () => Promise<void>;\n} {\n // Ink needs raw mode on stdin and otherwise fails later as an unhandled rejection.\n if (!process.stdin.isTTY) {\n throw new WizardError(\n 'This command needs an interactive terminal (stdin is not a TTY). Run the wizard directly in a terminal, not through a pipe or script.',\n undefined,\n ErrorCodes.CliInteractiveRequired,\n );\n }\n\n enterDarkTerminal();\n\n const store = new WizardStore(program);\n store.version = version;\n\n const { unmount: inkUnmount, waitUntilExit } = render(\n createElement(App, { store }),\n );\n\n analytics.setTag('program_id', program);\n // The launch marker — the first event of every TUI run, captured under\n // the run's anonymous id and merged into the user once they log in.\n analytics.wizardCapture('started', { program_id: program });\n\n // Fire the program steps' init work (e.g. the health-check pre-flight)\n // now that the screens are rendering — store construction alone must\n // not trigger it.\n store.runInitHooks();\n\n // Tearing down raw mode with a TTY read still pending surfaces a\n // benign 'read EIO' on stdin (macOS); without a handler Node treats\n // it as an uncaught exception and prints a stack over the exit line.\n process.stdin.on('error', (err: NodeJS.ErrnoException) => {\n if (err.code !== 'EIO') throw err;\n });\n\n // On exit: unmount Ink, leave alt screen (restores previous content),\n // then print exit summary line into the main buffer.\n let cleaned = false;\n const cleanup = () => {\n if (cleaned) return;\n cleaned = true;\n // Timestamp the teardown — everything printed into the alt screen dies here.\n logToFile(\n `[start-tui] unmounting TUI, leaving alt screen (exitCode=${\n process.exitCode ?? 'unset'\n })`,\n );\n inkUnmount();\n releaseTerminal();\n process.stdout.write(getExitLine(store) + '\\n');\n };\n process.on('exit', cleanup);\n\n // Ink unmounts itself on ctrl+c (exitOnCtrlC) but that alone doesn't\n // end the process: background handles (e.g. the OAuth callback server)\n // keep the event loop alive. `cleaned` still false means Ink tore itself\n // down rather than the host, so the caller ends the run.\n void waitUntilExit().then(() => {\n if (!cleaned) onInterrupt();\n });\n\n return {\n unmount: cleanup,\n store,\n waitForSetup: () => store.getGate('intro'),\n };\n}\n","/**\n * The TUI host for a tool: its screens on their own store, with no program\n * run, no task stream and no WizardRun. The CLI builds the launch values, owns\n * the signals and applies the exit code.\n */\n/* eslint-disable no-console */\nimport { buildSession, logIn } from '@programs';\nimport type { ToolId } from '@tools';\nimport { classifyRunFailure, emitWizardError } from '@shared/errors';\nimport { checkLocalServices, getLocalDev } from '@shared/local-dev';\nimport { VERSION } from '@shared/version';\nimport { analytics } from '@utils/analytics';\nimport { runCleanups } from '@utils/cleanup';\nimport { getLogFilePath, logToFile } from '@utils/debug';\nimport { flushAnalytics } from '@utils/flush-analytics';\nimport { startHostExit, wizardAbort } from '@host/wizard-abort';\nimport { printAbortOutro } from '@shared/console-log';\nimport { getTuiTool } from '@tui/tools/index';\nimport { oauthCredentials } from './auth/login.js';\nimport { startTUI } from './start-tui.js';\nimport type { WizardStore } from './store.js';\nimport type { TuiTool } from './tools/types.js';\nimport type { TuiToolLaunch } from './launch.js';\n\n/**\n * Run `toolId`'s screens. Resolves with the code a screen ends them with\n * (after the analytics flush), an abort's, 1 on a crash, or 130 or 143 on a\n * signal. Rejects when the TUI cannot start, as with no terminal.\n */\nexport async function runTuiTool(\n toolId: ToolId,\n launch: TuiToolLaunch,\n): Promise<number> {\n const exit = startHostExit();\n // A signal before the TUI mounts has nothing to unmount.\n let unmountTui = (): void => undefined;\n let stopping = false;\n // Ctrl+C or a signal: restore the terminal, flush the cancelled event, then end.\n const stop = (code: number): void => {\n if (stopping || exit.ended) return;\n stopping = true;\n unmountTui();\n void (async () => {\n try {\n await analytics.shutdown('cancelled');\n } catch {\n // never block the end on a flush failure\n }\n exit.end(code);\n })();\n };\n const onAbort = (): void =>\n stop(launch.signal.reason === 'SIGTERM' ? 143 : 130);\n // A signal that landed before this host subscribed ends the run too.\n if (launch.signal.aborted) onAbort();\n else launch.signal.addEventListener('abort', onAbort, { once: true });\n\n // Doctor ran as a program, so it probed the local services and labelled its exit line; the other tools did neither.\n const isDoctor = toolId === 'posthog-doctor';\n const localError = isDoctor\n ? await localServicesError(launch.session.baseUrl)\n : undefined;\n if (stopping) return exit.exited;\n if (localError) {\n wizardAbort(\n { present: printAbortOutro, exit },\n { message: localError },\n ).catch((error: unknown) => exit.fail(error));\n return exit.exited;\n }\n const tool = getTuiTool(toolId);\n if (!tool) throw new Error(`The ${toolId} tool has no screens.`);\n\n const tui = startTUI(VERSION, toolId, () => stop(130));\n unmountTui = () => tui.unmount();\n tui.store.launch(\n buildSession(launch.session),\n launch.session,\n isDoctor ? toolId : null,\n );\n\n driveTuiTool(tui.store, tool, {\n toolId,\n signal: launch.signal,\n }).then(\n async (code) => {\n if (stopping || exit.ended) return;\n stopping = true;\n tui.unmount();\n await flushAnalytics();\n exit.end(code);\n },\n (error: unknown) => {\n if (stopping || exit.ended) return;\n stopping = true;\n logToFile('[run-wizard] FATAL:', error);\n runCleanups();\n try {\n tui.unmount();\n } catch {\n // terminal may already be torn down\n }\n reportFatal(error);\n exit.end(1);\n },\n );\n return exit.exited;\n}\n\n/**\n * Drive a tool's screens on a mounted store: run its `start`, and resolve with\n * the code the first screen exit request carries. Rejects when `start` does.\n * The intro hands off to a tool through here too.\n */\nexport function driveTuiTool(\n store: WizardStore,\n tool: TuiTool,\n { toolId, signal }: { toolId: string; signal: AbortSignal },\n): Promise<number> {\n return new Promise<number>((resolve, reject) => {\n const settle = (): void => {\n const code = store.exitRequest;\n if (code === null) return;\n unsubscribe();\n resolve(code);\n };\n const unsubscribe = store.subscribe(settle);\n settle();\n tool\n .start?.({\n store,\n signal,\n logIn: async () => {\n await logIn(toolId, store.sessions, {\n provider: oauthCredentials(store),\n signal,\n });\n },\n })\n .catch((error: unknown) => {\n unsubscribe();\n reject(error);\n });\n });\n}\n\n/** Before the TUI mounts: the local dev services this run points at, if one is down. */\nexport function localServicesError(\n baseUrl: string | undefined,\n): Promise<string | undefined> {\n const local = getLocalDev();\n return checkLocalServices({\n ...local,\n // An explicit --base-url wins over --local-posthog (see buildSession),\n // so don't probe :8010 when one was given.\n localPosthog: local.localPosthog && !baseUrl,\n });\n}\n\n/** Print a crash with the log path and the PHW line. */\nexport function reportFatal(error: unknown): void {\n // Print after unmount: anything printed into the alt screen is wiped.\n // A coded failure is a decision with its own message; anything else is\n // unexpected and goes out whole.\n const failure = classifyRunFailure(error);\n if (failure.coded) {\n console.error(failure.message);\n } else {\n console.error('Wizard run failed:', error);\n }\n console.error(`Full logs: ${getLogFilePath()}`);\n emitWizardError({ code: failure.code, message: failure.message });\n}\n"],"mappings":"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"}