@posthog/wizard 2.80.0 → 2.81.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (228) hide show
  1. package/README.md +204 -72
  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 +13 -8
  5. package/dist/{agent-interface-CzyCmp7q.js → agent-interface-BFzBnz10.js} +289 -361
  6. package/dist/agent-interface-BFzBnz10.js.map +1 -0
  7. package/dist/{agent-prompt-loader-4wMxlYSX.js → agent-prompt-loader-CbCW6YbP.js} +6 -5
  8. package/dist/agent-prompt-loader-CbCW6YbP.js.map +1 -0
  9. package/dist/analytics-CGGE7OSa.js +735 -0
  10. package/dist/analytics-CGGE7OSa.js.map +1 -0
  11. package/dist/analytics-D6NAIJxP.js +2 -0
  12. package/dist/api-DM4uMJ00.js +2 -0
  13. package/dist/{api-C3Dc4LFl.js → api-ZZhiRtbb.js} +3 -3
  14. package/dist/api-ZZhiRtbb.js.map +1 -0
  15. package/dist/api-key-login-C30LRht2.js +2 -0
  16. package/dist/api-key-login-D0KBr1dx.js +55 -0
  17. package/dist/api-key-login-D0KBr1dx.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-DwL2Tasp.js} +3 -3
  21. package/dist/{bounded-fs-CC_NDtoP.js.map → bounded-fs-DwL2Tasp.js.map} +1 -1
  22. package/dist/{ci-install-DfcAMhlu.js → ci-install-DKXrt_ow.js} +21 -25
  23. package/dist/ci-install-DKXrt_ow.js.map +1 -0
  24. package/dist/console-log-DJiTqYT2.js +32 -0
  25. package/dist/console-log-DJiTqYT2.js.map +1 -0
  26. package/dist/{debug-DyARf5TF.js → debug-sB20p-Ek.js} +18 -52
  27. package/dist/debug-sB20p-Ek.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-BqLCdV8Y.js} +2 -1
  31. package/dist/{emit-BSetXzDV.js.map → emit-BqLCdV8Y.js.map} +1 -1
  32. package/dist/{errors-C2domSkK.js → errors-DhFeR8Sp.js} +5 -5
  33. package/dist/{errors-C2domSkK.js.map → errors-DhFeR8Sp.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-Dg4Fm-nC.js} +122 -11
  37. package/dist/gateway-Dg4Fm-nC.js.map +1 -0
  38. package/dist/headless-B3Ol1nkU.js +3 -0
  39. package/dist/headless-DhTDC9ga.js +10 -0
  40. package/dist/headless-DhTDC9ga.js.map +1 -0
  41. package/dist/{host-resolution-DVSb7kXb.js → host-resolution-DDYJXiAQ.js} +4 -4
  42. package/dist/{host-resolution-DVSb7kXb.js.map → host-resolution-DDYJXiAQ.js.map} +1 -1
  43. package/dist/install-CZeR38cD.js +2 -0
  44. package/dist/{install-Bk5TNk27.js → install-Dh8Z5R15.js} +62 -143
  45. package/dist/install-Dh8Z5R15.js.map +1 -0
  46. package/dist/interactive-hqHk6kz4.js +11 -0
  47. package/dist/interactive-hqHk6kz4.js.map +1 -0
  48. package/dist/{links-9LWZPSCq.js → links-rMot83W2.js} +3 -3
  49. package/dist/{links-9LWZPSCq.js.map → links-rMot83W2.js.map} +1 -1
  50. package/dist/{main-DKPjFHEV.js → main-DNIeasXx.js} +205 -470
  51. package/dist/main-DNIeasXx.js.map +1 -0
  52. package/dist/{mcp-Co8VRF62.js → mcp-SZcGfaOz.js} +3 -4
  53. package/dist/{mcp-Co8VRF62.js.map → mcp-SZcGfaOz.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-BuRMBgbo.js} +12 -12
  56. package/dist/mcp-prompt-streaming-BuRMBgbo.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-G1j-wgwe.js} +2 -2
  60. package/dist/{models-Dba8ITeo.js.map → models-G1j-wgwe.js.map} +1 -1
  61. package/dist/non-interactive-DkldwWDM.js +18 -0
  62. package/dist/non-interactive-DkldwWDM.js.map +1 -0
  63. package/dist/{oauth-session-D-RfcVmr.js → oauth-session-C2fVSGfr.js} +3 -3
  64. package/dist/{oauth-session-D-RfcVmr.js.map → oauth-session-C2fVSGfr.js.map} +1 -1
  65. package/dist/{orchestrator-tools-CVJ1F9Ub.js → orchestrator-tools-BchqG7Qi.js} +3 -3
  66. package/dist/{orchestrator-tools-CVJ1F9Ub.js.map → orchestrator-tools-BchqG7Qi.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-B3_qSybg.js +105 -0
  71. package/dist/package-manager-B3_qSybg.js.map +1 -0
  72. package/dist/{pi-B5YTBRDv.js → pi-Cw7CPXSl.js} +17 -19
  73. package/dist/pi-Cw7CPXSl.js.map +1 -0
  74. package/dist/playground-CPNrQfb3.js +12 -0
  75. package/dist/playground-CPNrQfb3.js.map +1 -0
  76. package/dist/posthog-integration-FAWfClH3.js +10304 -0
  77. package/dist/posthog-integration-FAWfClH3.js.map +1 -0
  78. package/dist/programs-DjCmEcxb.js +3 -0
  79. package/dist/programs-Ml6OLybj.js +5402 -0
  80. package/dist/programs-Ml6OLybj.js.map +1 -0
  81. package/dist/{provisioning-CLhuKqXH.js → provisioning-BTVL49jD.js} +4 -5
  82. package/dist/{provisioning-CLhuKqXH.js.map → provisioning-BTVL49jD.js.map} +1 -1
  83. package/dist/provisioning-DL0xCJXH.js +2 -0
  84. package/dist/{queue-tools-knnPQP0e.js → queue-tools-BQfRI_uD.js} +6 -8
  85. package/dist/queue-tools-BQfRI_uD.js.map +1 -0
  86. package/dist/results-ycm_Tf31.js +90 -0
  87. package/dist/results-ycm_Tf31.js.map +1 -0
  88. package/dist/run-Bgg-ctbA.js +264 -0
  89. package/dist/run-Bgg-ctbA.js.map +1 -0
  90. package/dist/run-C6Ei6vvb.js +246 -0
  91. package/dist/run-C6Ei6vvb.js.map +1 -0
  92. package/dist/run-tool-CrN2xWzU.js +2436 -0
  93. package/dist/run-tool-CrN2xWzU.js.map +1 -0
  94. package/dist/run-tool-tNjm8S-E.js +2 -0
  95. package/dist/runners-GGYJs0Ny.js +271 -0
  96. package/dist/runners-GGYJs0Ny.js.map +1 -0
  97. package/dist/{security-BvdSFDuM.js → security-C36p8lu6.js} +44 -52
  98. package/dist/security-C36p8lu6.js.map +1 -0
  99. package/dist/setup-utils-Dfgse6pY.js +118 -0
  100. package/dist/setup-utils-Dfgse6pY.js.map +1 -0
  101. package/dist/smoke-test.sh +1 -1
  102. package/dist/{playground-BLsCfHmQ.js → start-playground-D0TrdLmc.js} +44 -34
  103. package/dist/start-playground-D0TrdLmc.js.map +1 -0
  104. package/dist/{subagent-D_Sqak94.js → subagent-DR5caRzL.js} +7 -7
  105. package/dist/subagent-DR5caRzL.js.map +1 -0
  106. package/dist/{task-DiTI6Sak.js → task-C1qKgsAf.js} +18 -18
  107. package/dist/task-C1qKgsAf.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-Ch9ZJvm7.js} +2 -2
  111. package/dist/{telemetry-BNKsDxNS.js.map → telemetry-Ch9ZJvm7.js.map} +1 -1
  112. package/dist/terminal-D20JFN3J.js +16188 -0
  113. package/dist/terminal-D20JFN3J.js.map +1 -0
  114. package/dist/tools-BZseGChD.js +544 -0
  115. package/dist/tools-BZseGChD.js.map +1 -0
  116. package/dist/{tools-C8LQ8QFz.js → tools-CmSMclOD.js} +9 -9
  117. package/dist/tools-CmSMclOD.js.map +1 -0
  118. package/dist/tui-BXe1D0tc.js +25 -0
  119. package/dist/tui-BXe1D0tc.js.map +1 -0
  120. package/dist/tui-DJf3ZPRh.js +2 -0
  121. package/dist/{steps-Hc28zVc_.js → upload-step-BlAN7MC5.js} +14 -16
  122. package/dist/upload-step-BlAN7MC5.js.map +1 -0
  123. package/dist/{urls-BI4kJ4qQ.js → urls-eFaChZ9d.js} +2 -2
  124. package/dist/{urls-BI4kJ4qQ.js.map → urls-eFaChZ9d.js.map} +1 -1
  125. package/dist/warlock-smoke-test.ts +1 -2
  126. package/dist/{wizard-abort-DBKtfnBR.js → wizard-abort-BX3O4Hg4.js} +40 -33
  127. package/dist/wizard-abort-BX3O4Hg4.js.map +1 -0
  128. package/dist/{yara-hooks-C3L6lBij.js → yara-hooks-C4HOysrM.js} +283 -21
  129. package/dist/yara-hooks-C4HOysrM.js.map +1 -0
  130. package/dist/yara-hooks-DV4EkkZY.js +2 -0
  131. package/package.json +7 -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/subagent-D_Sqak94.js.map +0 -1
  209. package/dist/task-DiTI6Sak.js.map +0 -1
  210. package/dist/task-status-CmrrR7zo.js +0 -16
  211. package/dist/task-status-CmrrR7zo.js.map +0 -1
  212. package/dist/task-stream-BckhG_cB.js +0 -363
  213. package/dist/task-stream-BckhG_cB.js.map +0 -1
  214. package/dist/tasks-ChZ_F1YP.js.map +0 -1
  215. package/dist/terminal-PK9bCLRi.js +0 -7222
  216. package/dist/terminal-PK9bCLRi.js.map +0 -1
  217. package/dist/tools-C8LQ8QFz.js.map +0 -1
  218. package/dist/ui-tPNpM6vj.js +0 -15
  219. package/dist/ui-tPNpM6vj.js.map +0 -1
  220. package/dist/version-5_ydHkM6.js +0 -6
  221. package/dist/version-5_ydHkM6.js.map +0 -1
  222. package/dist/wizard-abort-BVjqLyeA.js +0 -3
  223. package/dist/wizard-abort-DBKtfnBR.js.map +0 -1
  224. package/dist/wizard-session-B7BHnay0.js +0 -2
  225. package/dist/wizard-session-BYw6LzpS.js +0 -133
  226. package/dist/wizard-session-BYw6LzpS.js.map +0 -1
  227. package/dist/yara-hooks-C3L6lBij.js.map +0 -1
  228. package/dist/yara-hooks-CF_IsoaA.js +0 -2
package/README.md CHANGED
@@ -34,7 +34,7 @@ The wizard uses **AI models from Anthropic or OpenAI**, routed through PostHog's
34
34
  - **AI opt-in**: for existing organizations in interactive runs, the wizard checks `is_ai_data_processing_approved` and waits for approval before agent work. CI and signup runs bypass this interactive gate.
35
35
  - **Prefer your own AI?** The wizard's integration knowledge ships as a context-mill skill you can download and run inside your own agent.
36
36
 
37
- The wizard's "Privacy & data usage" menu (intro screen) and the `[I]` shortcut on the auth screen surface the same information in-terminal.
37
+ The wizard's "Privacy & data" menu (intro screen) and the `[I]` shortcut on the auth screen surface the same information in-terminal.
38
38
 
39
39
  ## MCP Commands
40
40
 
@@ -47,8 +47,15 @@ npx @posthog/wizard@latest mcp add
47
47
 
48
48
  # Remove PostHog MCP server from supported clients
49
49
  npx @posthog/wizard@latest mcp remove
50
+
51
+ # Try the PostHog MCP with your agent, no install needed
52
+ npx @posthog/wizard@latest mcp tutorial
50
53
  ```
51
54
 
55
+ These, `slack`, `doctor`, `provision`, `cli add` and `skill list` are tools:
56
+ commands that do their job without an agent run. See
57
+ [src/tools](src/tools/README.md).
58
+
52
59
  ## Wizard programs
53
60
 
54
61
  The wizard's commands are grouped into **programs** — self-contained agentic jobs that install, audit, or wire up a specific piece of PostHog. They're powered by skills from the [context mill](https://github.com/PostHog/context-mill).
@@ -61,7 +68,7 @@ Running the wizard with no arguments installs PostHog into your project. It dete
61
68
  npx @posthog/wizard@latest
62
69
  ```
63
70
 
64
- Powered by the `posthog-integration` program. Most other programs below build on it (they declare `requires: ['posthog-integration']`) and will offer to run it first if PostHog isn't already set up.
71
+ Powered by the `posthog-integration` program. Most other programs below build on it and declare `requires: ['posthog-integration']`.
65
72
 
66
73
  ### Self-driving
67
74
 
@@ -76,16 +83,17 @@ If PostHog isn't already installed, the wizard runs the default integration firs
76
83
  ### Audit
77
84
 
78
85
  Audit an existing PostHog integration for correctness and best practices. The
79
- `audit` command is a **family**. With no subcommand it runs the **events**
80
- audit (the default); pass a subcommand to run a specific one:
86
+ `audit` command is a **family**. With no subcommand, an interactive terminal
87
+ runs the audit the skill menu marks as the default (today **all**); pass a
88
+ subcommand to run a specific one:
81
89
 
82
90
  ```bash
83
- # Runs the events audit (the default) — no subcommand needed
91
+ # Runs the default audit — no subcommand needed
84
92
  npx @posthog/wizard@latest audit
85
93
 
86
94
  # Or run a specific audit directly
87
- npx @posthog/wizard@latest audit events # event capture quality + cost (default)
88
- npx @posthog/wizard@latest audit all # comprehensive audit across every area
95
+ npx @posthog/wizard@latest audit events # event capture quality + cost
96
+ npx @posthog/wizard@latest audit all # comprehensive audit across every area (default)
89
97
  npx @posthog/wizard@latest audit autocapture # autocapture setup + cost
90
98
  npx @posthog/wizard@latest audit feature-flags # feature flag usage + cost
91
99
  npx @posthog/wizard@latest audit identify # your $identify implementation
@@ -98,9 +106,9 @@ new audits appear without a wizard release (`web-analytics` is wizard-native).
98
106
 
99
107
  > **`audit <subcommand>` chooses an audit area — it does not take a skill name.**
100
108
  > The audit subcommands above *are* context-mill skills promoted to commands (via
101
- > a `cli: role: command` block); [`wizard skill <skill-name>`](#run-a-single-skill)
109
+ > a `cli: role: command` block); [`wizard skill <skill-name>`](#run-skill)
102
110
  > runs a skill that hasn't been promoted. Same machinery, two surfaces.
103
- > (`wizard audit --help` still labels the positional `[skill]` — read it as "pick
111
+ > (`wizard audit --help` labels the positional `[skill]` — read it as "pick
104
112
  > a subcommand.")
105
113
 
106
114
  ### Revenue Analytics
@@ -112,7 +120,7 @@ npx @posthog/wizard@latest revenue-analytics
112
120
  ```
113
121
 
114
122
  Requires PostHog and Stripe SDKs already installed. Supports `--ci` with the
115
- same flags as the main wizard. (Renamed from `revenue` in the CLI overhaul.)
123
+ same flags as the main wizard.
116
124
 
117
125
  ### Data Warehouse
118
126
 
@@ -166,16 +174,16 @@ route review to their owning team instead.
166
174
  | `src/programs/self-driving/` | `@PostHog/team-self-driving` |
167
175
  | `src/programs/warehouse-source/` | `@PostHog/team-warehouse-sources` |
168
176
  | `src/programs/web-analytics-doctor/` | `@PostHog/team-web-analytics` |
169
- | `src/ui/tui/decks/error-tracking-upload-source-maps/` | `@PostHog/team-error-tracking` |
170
- | `src/ui/tui/decks/revenue-analytics/` | `@PostHog/team-web-analytics` |
171
- | `src/ui/tui/decks/self-driving/` | `@PostHog/team-self-driving` |
172
- | `src/ui/tui/decks/warehouse-source/` | `@PostHog/team-warehouse-sources` |
177
+ | `src/tui/programs/error-tracking-upload-source-maps/` | `@PostHog/team-error-tracking` |
178
+ | `src/tui/programs/revenue-analytics/` | `@PostHog/team-web-analytics` |
179
+ | `src/tui/programs/self-driving/` | `@PostHog/team-self-driving` |
180
+ | `src/tui/programs/warehouse-source/` | `@PostHog/team-warehouse-sources` |
173
181
 
174
182
  Ownership is by directory. Programs not listed above
175
- (`agent-skill`, `audit`, `events-audit`, `mcp`, `migration`, `posthog-doctor`,
176
- `shared`, `slack`) fall through the default and are owned by
177
- `team-wizard-docs`. Today CODEOWNERS only auto-requests review — approval is
178
- not a merge gate.
183
+ (`agent-skill`, `audit`, `error-tracking`, `migration`), the shared program code
184
+ and the tools (`src/tools`, `src/tui/tools`) fall through the default and are
185
+ owned by `team-wizard-docs`. Today CODEOWNERS only auto-requests review —
186
+ approval is not a merge gate.
179
187
 
180
188
  ## Headless signup + install (agents / CI)
181
189
 
@@ -185,7 +193,9 @@ not a merge gate.
185
193
  For a fully non-interactive first-run (no existing PostHog account, no TTY,
186
194
  no browser), combine `--ci --signup --email`. The wizard provisions a new
187
195
  account, uses the returned personal API key to run the normal CI install,
188
- and wires PostHog into the project at `--install-dir`:
196
+ and wires PostHog into the project at `--install-dir`. Like every `--ci` run, it
197
+ needs the gateway token file from [local
198
+ credentials](docs/local-dev.md#credentials-for-local-ci-and-headless-runs):
189
199
 
190
200
  ```bash
191
201
  npx @posthog/wizard@latest --ci --signup \
@@ -193,8 +203,7 @@ npx @posthog/wizard@latest --ci --signup \
193
203
  --install-dir .
194
204
  ```
195
205
 
196
- Optional flags: `--name "Your Name"`, `--region eu` (default `us`),
197
- `--integration nextjs` (else auto-detected).
206
+ Optional flags: `--name "Your Name"`, `--region eu` (default `us`).
198
207
 
199
208
  ### Provision only
200
209
 
@@ -210,11 +219,12 @@ npx @posthog/wizard@latest provision --email user@example.com --region us
210
219
  npx @posthog/wizard@latest provision --email user@example.com --region eu --json
211
220
  ```
212
221
 
213
- Success prints the full `ProvisioningResult` (`projectApiKey`, `host`,
214
- `projectId`, `accountId`, `accessToken`, `refreshToken`, and
215
- `personalApiKey` if present). Failure exits 1; in `--json` mode the error
216
- is emitted to stderr as `{"error":"...","code":"..."}`, with `code` set to
217
- `email_exists` when the address is already registered.
222
+ Success prints `projectApiKey`, `host`, `projectId`, `accountId`, `accessToken`,
223
+ `refreshToken`, and `personalApiKey` if present. `--json` prints the full
224
+ `ProvisioningResult`, which also has `expiresAt` and `oauthClientId`. Failure
225
+ exits 1; in `--json` mode the error is emitted to stderr as
226
+ `{"error":"...","code":"..."}`, with `code` set to `email_exists` when the
227
+ address is already registered.
218
228
 
219
229
  > ⚠️ **Output contains live credentials.** Pipe it into a secrets store —
220
230
  > do not let it be captured by shared CI logs. Mask the step output or
@@ -231,7 +241,7 @@ The following CLI arguments are available:
231
241
  | `--debug` | Enable verbose logging | boolean | `false` | | `POSTHOG_WIZARD_DEBUG` |
232
242
  | `--signup` | Create a new PostHog account during setup | boolean | `false` | | `POSTHOG_WIZARD_SIGNUP` |
233
243
  | `--install-dir` | Directory to install PostHog in | string | | | `POSTHOG_WIZARD_INSTALL_DIR` |
234
- | `--ci` | Enable CI mode for non-interactive execution | boolean | `false` | | `POSTHOG_WIZARD_CI` |
244
+ | `--ci` | Enable CI mode for non-interactive execution (dev and test builds only) | boolean | `false` | | `POSTHOG_WIZARD_CI` |
235
245
  | `--api-key` | PostHog personal API key (phx_xxx) for authentication | string | | | `POSTHOG_WIZARD_API_KEY` |
236
246
  | `--no-telemetry` | Disable wizard run-state telemetry | boolean | `false` | | `POSTHOG_WIZARD_NO_TELEMETRY` |
237
247
 
@@ -241,8 +251,9 @@ The following CLI arguments are available:
241
251
  **CI mode is available only in development/test builds.** Published builds
242
252
  reject `--ci`; use an interactive terminal for `npx @posthog/wizard@latest`.
243
253
 
244
- Local CI runs require a PostHog personal API key **and a separate gateway
245
- token file**, plus the target project ID. See
254
+ Local CI runs require a PostHog personal API key for MCP access **and a
255
+ separate gateway token file** holding the gateway service key from 1Password,
256
+ plus the target project ID. See
246
257
  [local credentials](docs/local-dev.md#credentials-for-local-ci-and-headless-runs)
247
258
  for setup and the CI secret names. With both secrets configured:
248
259
 
@@ -257,7 +268,6 @@ When running in CI mode (`--ci`):
257
268
  - Bypasses OAuth login flow (uses personal API key directly)
258
269
  - Auto-selects defaults for all prompts
259
270
  - Skips MCP server installation
260
- - Auto-continues on git warnings (uncommitted/untracked files)
261
271
  - Auto-consents to AI usage
262
272
 
263
273
  The CLI args override environment variables in CI mode.
@@ -279,8 +289,8 @@ health_issue:read wizard_session:read wizard_session:write wizard_run:write
279
289
 
280
290
  The source of truth is `WIZARD_OAUTH_SCOPES` in `src/shared/constants.ts`, which
281
291
  documents why each scope is needed — if this block drifts, trust the code.
282
- Some programs request more on top (`PROGRAM_SCOPE_ADDITIONS` in
283
- `src/programs/oauth/program-scopes.ts`); the default integration flow adds
292
+ Some programs request more on top (`oauthScopeAdditions` on the program's
293
+ config); the default integration flow adds
284
294
  `integration:read` and `external_data_source:read` /
285
295
  `external_data_source:write`.
286
296
 
@@ -294,12 +304,11 @@ for limits, shutdown behavior, migration compatibility, and deployment checks.
294
304
  ### OAuth app scope ceiling
295
305
 
296
306
  Both the interactive and cloud Wizard OAuth apps must allow `wizard_run:write`
297
- in every deployed region. Existing tokens need renewed authorization; refresh
298
- does not add the grant. Run synchronization needs no read scope.
307
+ in every deployed region. Run synchronization needs no read scope.
299
308
 
300
309
  The wizard's OAuth app on the PostHog side caps the scopes its tokens may
301
310
  carry (`OAuthApplication.scopes`). Any scope requested in this repo (see
302
- `src/programs/oauth/program-scopes.ts`) must be grantable under that ceiling, or
311
+ the programs' `oauthScopeAdditions`) must be grantable under that ceiling, or
303
312
  `/authorize` drops it and the call that needs it 403s.
304
313
 
305
314
  **A granted token can be narrower than the request even with a correct
@@ -309,8 +318,8 @@ are clamped silently (`clamp_scopes_to_ceiling`) — neither path errors;
309
318
  `/oauth/token` just returns a smaller `scope`. So never assume the token
310
319
  carries what was requested: the token response's `scope` field is the truth.
311
320
  The wizard diffs granted vs requested at login (`missingOAuthScopes` in
312
- `src/shared/utils/oauth.ts`), warns the user which permissions are missing, and emits
313
- `wizard: oauth grant narrowed` so narrowed runs are countable in analytics.
321
+ `src/programs/oauth/tokens.ts`), warns the user which permissions are missing, and
322
+ emits `wizard: oauth grant narrowed` so narrowed runs are countable in analytics.
314
323
  The diff also rides on the session (`credentials.missingScopes`), so when a
315
324
  run does fail on a scope-gated step, the error names the missing permission
316
325
  and the fix instead of the generic report-a-bug line.
@@ -406,10 +415,103 @@ that conventional code implies.
406
415
  If you want to use this code as a starting place for your own project, here's a
407
416
  quick explainer on its structure.
408
417
 
409
- ## Entrypoint: `run.ts`
418
+ ## What calls what
419
+
420
+ ```mermaid
421
+ %%{init: {"block": {"padding": 20}}}%%
422
+ block-beta
423
+ columns 18
424
+ user["a user at a terminal"]:3 ci["CI or a sandbox"]:3 embedder["your program"]:3 space:3 toolUser["a user or a script"]:3 caller["your code or a test"]:3
425
+ cliBand["src/cli picks a host, owns the signals and the exit"]:6 space:12
426
+ runWizard["runWizard"]:3 runWizardCI["runWizardCI<br/>runWizardHeadless"]:3 space:6 toolCmd["src/cli<br/>a tool's command"]:3 space:3
427
+ hostBand["src/tui · src/headless the two hosts"]:6 space:12
428
+ runTui["runTui"]:3 runHeadless["runHeadless"]:3 space:6 runTool["runTuiTool<br/>or an @tools runner"]:3 space:3
429
+ wizardStore["WizardStore<br/>display over the store"]:3 space:15
430
+ programsBand["@programs"]:12 space:6
431
+ tuiStore["SessionStore"]:3 headlessStore["SessionStore"]:3 ownStore["SessionStore"]:3 detect["detectProjectsWithAgent"]:3 space:6
432
+ tuiRun["runProgram"]:3 headlessRun["runProgram"]:3 ownRun["runProgram"]:3 space:9
433
+ agentBand["@agent"]:18
434
+ tuiAgent["runAgent"]:3 headlessAgent["runAgent"]:3 ownAgent["runAgent"]:3 detectAgent["runAgent"]:3 mcpStream["streamMcpPrompt"]:3 callerAgent["runAgent"]:3
435
+
436
+ user --> runWizard
437
+ runWizard --> runTui
438
+ runTui --> wizardStore
439
+ wizardStore --> tuiStore
440
+ tuiStore --> tuiRun
441
+ tuiRun --> tuiAgent
442
+
443
+ ci --> runWizardCI
444
+ runWizardCI --> runHeadless
445
+ runHeadless --> headlessStore
446
+ headlessStore --> headlessRun
447
+ headlessRun --> headlessAgent
448
+
449
+ embedder -- "builds and owns the store" --> ownStore
450
+ ownStore --> ownRun
451
+ ownRun --> ownAgent
452
+
453
+ detect --> detectAgent
454
+
455
+ toolUser --> toolCmd
456
+ toolCmd --> runTool
457
+ runTool -- "the MCP tutorial only" --> mcpStream
458
+
459
+ caller -- "runAgent(config, input)" --> callerAgent
460
+
461
+ classDef code fill:#3b82f626,stroke:#3b82f6,stroke-width:2px
462
+ classDef ext fill:none,stroke:#9ca3af,stroke-dasharray:4 3
463
+ classDef band fill:#3b82f640,stroke:none
464
+ class runWizard,runWizardCI,runTui,runHeadless,wizardStore,tuiStore,headlessStore,ownStore,tuiRun,headlessRun,ownRun,tuiAgent,headlessAgent,ownAgent,detect,detectAgent,toolCmd,runTool,mcpStream,callerAgent code
465
+ class user,ci,embedder,toolUser,caller ext
466
+ class cliBand,hostBand,programsBand,agentBand band
467
+ ```
410
468
 
411
- The entrypoint for this tool is `run.ts`. Use this file to interpret arguments
412
- and set up the general flow of the application.
469
+ Each column is one way in, read top to bottom. A box that repeats across columns
470
+ is the same code. The CLI calls one of two hosts, the TUI or headless. They
471
+ share only the kind of session store they build: each builds its own, calls
472
+ `runProgram` with it, and `runProgram` writes the run into it. The TUI draws its
473
+ screens from the `WizardStore` on top of its store, and headless prints and
474
+ streams the run.
475
+
476
+ A tool's command runs no program. The CLI calls the TUI's `runTuiTool` for the
477
+ tool's screens, or a console runner from `@tools`. Only the MCP tutorial reaches
478
+ the agent, through `streamMcpPrompt`. The TUI's intro can also hand off to a
479
+ tool's screens, such as `doctor`, in the same process. See
480
+ [src/tools](src/tools/README.md).
481
+
482
+ Detection calls `runAgent` directly. `detectProjectsWithAgent` builds its own
483
+ run config for a project scan. It runs from a program's `ciPreRun`, which
484
+ `runProgram` calls as a CI run's detection, and from the TUI's detect screens.
485
+
486
+ Dashed boxes are callers that build against a checkout of this repository, not
487
+ the npm package. Your program can build a store and call
488
+ `runProgram(id, { store })` itself. Your code can call `runAgent` with no
489
+ program at all.
490
+
491
+ | Box | What it is | Where |
492
+ | --------------------------------- | ----------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------- |
493
+ | `runWizard` | Builds the launch values from the arguments and starts the TUI host | [src/cli/runners](src/cli/runners/run-wizard.ts) |
494
+ | `runWizardCI · runWizardHeadless` | Checks the non-interactive arguments and starts the headless host | [src/cli/runners](src/cli/runners) |
495
+ | `a tool's command` | Parses the tool's arguments and calls its runner | [src/cli/commands](src/cli/commands) |
496
+ | `runTui` | The full-screen wizard: OAuth login, the WizardAsk screen as the answerer, the flow's screens as the workflow | [src/tui/run.ts](src/tui/run.ts) |
497
+ | `runHeadless` | A run with no screens: API-key login, no answerer, log lines and the task stream | [src/headless/run.ts](src/headless/run.ts) |
498
+ | `runTuiTool` | Shows a tool's screens on their own store and resolves the code a screen exits with; it runs no program | [src/tui/run-tool.ts](src/tui/run-tool.ts) |
499
+ | `@tools` runner | A tool that runs on the console, such as `addMCPServerToClientsStep`, `runDoctorReport`, `runProvision` or `listSkills` | [src/tools](src/tools/README.md) |
500
+ | `WizardStore` | The TUI's own state (the screens' answers), router, gates, overlays and display state, over its session store | [src/tui/store.ts](src/tui/store.ts) |
501
+ | `SessionStore` | Launch values, detection, the login and the run's progress; each host builds its own | [src/programs/session](src/programs/session) |
502
+ | `runProgram` | Runs a registered program: detection, readiness, login, the host's steps, then each agent run | [src/programs/run-program.ts](src/programs/run-program.ts) |
503
+ | `detectProjectsWithAgent` | A project scan: one `runAgent` call per attempt, with its own route and deadline | [src/programs/detection/agentic.ts](src/programs/detection/agentic.ts) |
504
+ | `runAgent` | One agent run from a `RunConfig` and `RunInput`; complete on its own | [src/agent](src/agent/README.md) |
505
+ | `streamMcpPrompt` | The MCP tutorial's prompt stream: one prompt against the PostHog MCP server, with its own SDK call | [src/agent/mcp-prompt-streaming.ts](src/agent/mcp-prompt-streaming.ts) |
506
+
507
+ ## Entrypoint: `bin.ts`
508
+
509
+ The entrypoint for this tool is `bin.ts`. It checks the Node version, and only
510
+ then loads `main.ts` with a dynamic import, so no dependency runs on an old
511
+ Node. `main.ts` sets the HTTP/1.1 dispatcher, restores any Claude settings
512
+ backup an interrupted run left behind, and calls `runCli()` from
513
+ `src/cli/index.ts`. `runCli` registers each command on the yargs setup in
514
+ `src/cli/wizard.ts` and runs the one that `process.argv` names.
413
515
 
414
516
  ## Analytics
415
517
 
@@ -435,8 +537,8 @@ set `POSTHOG_WIZARD_NO_TELEMETRY=1`) to disable either remote transport.
435
537
  Supporting agent sessions after we leave is important. There are plenty of ways
436
538
  to break or misconfigure PostHog, so guarding against this is key.
437
539
 
438
- `src/shared/utils/rules/add-editor-rules.ts` demonstrates how to dynamically construct
439
- rules files and store them in the project's `.cursor/rules` directory.
540
+ `src/shared/utils/rules/` holds per-framework rule templates in Markdown. No
541
+ code reads them or writes them into a project today.
440
542
 
441
543
  ## Prompts and LLM interactions
442
544
 
@@ -447,12 +549,13 @@ existing code at scale and then modify it reliably.
447
549
 
448
550
  _If_ they are well prompted.
449
551
 
450
- `src/lib/prompts.ts` demonstrates how to wrap a deterministic fence around a
451
- chaotic process. Every wizard session gets the same prompt, tailored to the
452
- specific files in the project.
552
+ `src/agent/agent-prompt.ts` demonstrates how to wrap a deterministic fence
553
+ around a chaotic process. Every wizard session gets the same prompt, tailored to
554
+ the specific files in the project.
453
555
 
454
- These prompts are channeled using `src/shared/utils/query.ts` to an LLM interface we
455
- host. This gives us more control: we can be certain of the model version and
556
+ These prompts go to the PostHog LLM gateway, an LLM interface we
557
+ host, with a scoped token that `src/agent/gateway-session.ts` mints for each
558
+ run. This gives us more control: we can be certain of the model version and
456
559
  provider which interpret the prompts and modify the files. This way, we can find
457
560
  the right tools for the job and again, apply them consistently.
458
561
 
@@ -493,45 +596,73 @@ Built with [tsdown](https://tsdown.dev/) (Rolldown). `pnpm build` bundles `bin.t
493
596
 
494
597
  ### Environment variables
495
598
 
496
- **Build-time (locked).** `NODE_ENV` is replaced with `"production"` at compile time. It cannot be overridden at runtime. All URLs, OAuth client IDs, and dev-mode code paths resolve to their production values unconditionally.
599
+ **Build-time (locked).** `pnpm build` replaces `NODE_ENV` with `"production"` at compile time. It cannot be overridden at runtime. All URLs, OAuth client IDs, and dev-mode code paths resolve to their production values. `pnpm build:ci` inlines `ci` instead, which keeps dev and test flags such as `--ci`.
497
600
 
498
601
  To add a new build-time constant, add it to `env` in `tsdown.config.ts` and export it from `src/env.ts`.
499
602
 
500
- **Runtime (allowlisted).** Runtime env reads go through `runtimeEnv()` in `src/env.ts`, which only accepts keys in the `RuntimeEnvKey` union:
603
+ **Runtime (allowlisted).** Most runtime env reads go through `runtimeEnv()` in `src/env.ts`, which only accepts keys in the `RuntimeEnvKey` union:
501
604
 
502
605
  | Variable | Purpose |
503
606
  |---|---|
504
607
  | `POSTHOG_WIZARD_BENCHMARK_CONFIG` | Path to benchmark config file |
505
608
  | `POSTHOG_WIZARD_BENCHMARK_FILE` | Output path for benchmark results |
506
609
  | `POSTHOG_WIZARD_LOG_DIR` | Log directory override |
507
- | `POSTHOG_WIZARD_DEBUG` / `DEBUG` | Enable debug output |
610
+ | `POSTHOG_WIZARD_RUN_ID` | Assigned cloud WizardRun id |
611
+ | `POSTHOG_TASK_RUN_ID`, `POSTHOG_TASK_ID`, `POSTHOG_HANDOFF_OUTPUT_PATH` | The PostHog task run that launched the wizard |
612
+ | `WIZARD_CI_GATEWAY_TOKEN_FILE`, `WIZARD_CI_GATEWAY_URL` | The gateway token and URL for `--ci` runs |
613
+ | `WIZARD_CI_FLAG_OVERRIDES`, `WIZARD_CI_EXCLUDE_TASKS` | Flag and task overrides for CI builds |
508
614
  | `MCP_URL` | Override MCP server URL |
509
- | `POSTHOG_API_KEY` | API key for MCP subprocess auth |
510
- | `TERM`, `TERM_PROGRAM`, `CI`, etc. | Terminal/platform detection |
511
- | `APPDATA`, `XDG_CONFIG_HOME` | Platform path resolution |
615
+ | `APPDATA`, `XDG_CONFIG_HOME`, `OPENCODE_CONFIG_DIR` | Platform path resolution |
512
616
 
513
617
  To add a new runtime env var, add its key to `RuntimeEnvKey` in `src/env.ts`.
618
+ The CLI reads every `POSTHOG_WIZARD_*` variable as an option and rejects unknown
619
+ ones, so a CLI run with `POSTHOG_WIZARD_BENCHMARK_CONFIG`,
620
+ `POSTHOG_WIZARD_BENCHMARK_FILE` or `POSTHOG_WIZARD_WARLOCK_DISABLED` set exits
621
+ with `Unknown argument`. `POSTHOG_WIZARD_LOG_FILE` is the exception: it is the
622
+ env form of `--log-file`, a declared option that moves the debug log from its
623
+ default, `posthog-wizard.log` in the temp directory.
514
624
 
515
- **Direct `process.env` access** is only used for subprocess environment writes (e.g. `agent-interface.ts` setting `ANTHROPIC_BASE_URL`), vendored code, and tests.
625
+ **Direct `process.env` access** covers terminal detection (`TERM`, `TERM_PROGRAM`, `CI`, …), subprocess environment writes (e.g. `agent-interface.ts` setting `ANTHROPIC_BASE_URL`), a few launch-time reads, vendored code, and tests.
516
626
 
517
627
  ### Import aliases
518
628
 
519
- Path aliases defined in `tsconfig.build.json`, resolved by tsdown:
629
+ Path aliases defined in `tsconfig.base.json`, resolved by tsdown and `tsx`:
520
630
 
521
631
  | Alias | Maps to |
522
632
  |---|---|
523
633
  | `@env` | `src/env.ts` |
524
- | `@lib/*` | `src/lib/*` |
525
- | `@agent` | `src/agent/index.ts`, the agent's runtime entry; the only agent import outside `src/agent` besides types |
634
+ | `@shared/*` | `src/shared/*` |
635
+ | `@utils/*` | `src/shared/utils/*` |
636
+ | `@host/*` | `src/host/*`, how a run ends (`startHostExit`, `wizardAbort`, `registerShutdown`), for headless, the TUI, the CLI and the e2e harness |
637
+ | `@agent` | `src/agent/index.ts`, the agent's runtime entry |
526
638
  | `@agent/types` | `src/agent/types.ts`, type-only |
527
- | `@agent/*` | `src/agent/*`, inside `src/agent` and its tests only |
639
+ | `@agent/*` | `src/agent/*`, for the agent's tests. The agent imports its own modules by relative path, and no other layer maps it |
528
640
  | `@programs` | `src/programs/index.ts`, the programs runtime entry |
529
641
  | `@programs/types` | `src/programs/types.ts`, type-only |
530
- | `@programs/*` | `src/programs/*`, retained for internal imports and tracked migration edges |
531
- | `@shared/*` | `src/shared/*` |
532
- | `@utils/*` | `src/shared/utils/*` |
533
- | `@ui/*` | `src/ui/*` |
534
- | `@steps/*` | `src/steps/*` |
642
+ | `@programs/<id>` | `src/programs/<id>/index.ts`, one program's entry. Other layers reach nothing else in a program folder |
643
+ | `@programs/*` | `src/programs/*`. Other layers reach only the `@programs/<id>` entries; the programs import their own code by relative path, and only their tests use this alias |
644
+ | `@tools` | `src/tools/index.ts`, the tools' one entry: the commands that run no agent. The TUI and the CLI import it; programs never do |
645
+ | `@tui` | `src/tui/index.ts`, the TUI's one entry, for the CLI and the e2e harness |
646
+ | `@tui/*` | `src/tui/*`. Only the TUI's own projects may use it |
647
+ | `@headless` | `src/headless/index.ts`, headless's one entry, for the CLI |
648
+ | `@cli` | `src/cli/index.ts`, the CLI's one entry, for `main.ts` |
649
+ | `@cli/*` | `src/cli/*`. Only the CLI may use it |
650
+ | `@e2e-harness/*` | `e2e-harness/*`, for the harness, scripts and tests |
651
+
652
+ Each layer's tsconfig project `references` only the layers it may import, so
653
+ `pnpm typecheck` rejects an import of any other. Outside the TUI, `ink`,
654
+ `react`, `@inkjs/ui` and `ink-testing-library` resolve to a fence that fails
655
+ every import form, and no layer imports JSON. `pnpm lint` rejects the paths the
656
+ compiler can't see: a relative import that leaves its layer's folder, a deep
657
+ alias outside its own layer, a `.tsbuild/` or `node_modules/` path, `module`
658
+ loaders and a bare `require`, triple-slash references, and the hosts importing
659
+ the agent's runtime. See
660
+ [layer boundaries](.claude/skills/wizard-development/references/ARCHITECTURE.md#layer-boundaries)
661
+ for what each layer may import and why each rule exists. Code outside a layer
662
+ imports it only through the entries above. The e2e harness, scripts and
663
+ `docs/examples` are one layer project, `e2e-harness/tsconfig.json`. Tests follow
664
+ the same rule: each layer's tests sit in its project, and a test mocks another
665
+ layer through its entry.
535
666
 
536
667
  ## Running locally
537
668
 
@@ -554,12 +685,12 @@ pnpm run dev
554
685
  This builds, links globally, and watches for changes. Leave it running - any `.ts` file changes will auto-rebuild. Then from any project:
555
686
 
556
687
  ```bash
557
- wizard --integration=nextjs
688
+ wizard
558
689
 
559
690
  # Point individual services at local dev servers:
560
- wizard --integration=nextjs --local-context-mill # skills from localhost:8765
561
- wizard --integration=nextjs --local-mcp # MCP from localhost:8787
562
- wizard --integration=nextjs --local-dev # context-mill + MCP + PostHog
691
+ wizard --local-context-mill # skills from localhost:8765
692
+ wizard --local-mcp # MCP from localhost:8787
693
+ wizard --local-dev # context-mill + MCP + PostHog
563
694
  ```
564
695
 
565
696
  See [`docs/local-dev.md`](docs/local-dev.md) for the full catalog.
@@ -613,7 +744,8 @@ Example prompt — explore against
613
744
  > for any setup question, then `run_agent` at auth.
614
745
  > 4. Poll `read_state` until `integration` is `done` (or `failed` — then report
615
746
  > `integrationError`), snapshotting as the run screen progresses.
616
- > 5. Finish the tail: dismiss outro / mcp / slack, then `keep_skills`.
747
+ > 5. Finish the tail: `dismiss_outro`, `set_mcp_outcome`, then
748
+ > `keep_skills`.
617
749
  >
618
750
  > Then show me the saved snapshots in order, the screen path, whether `posthog`
619
751
  > landed in the app, and anything that broke.
@@ -635,7 +767,7 @@ The entry point is `evaluateWizardReadiness()`, which only blocks on skill downl
635
767
  | Decision | Meaning |
636
768
  | ------------------- | --------------------------------------------------------------- |
637
769
  | `yes` | Skills are reachable — proceed without outage warnings. |
638
- | `no` | Neither skills origin is reachable — do not run. |
770
+ | `no` | Neither skills origin is reachable. Interactive runs show the outage and stop; non-interactive runs report it and continue. |
639
771
 
640
772
  ### Module layout
641
773
 
@@ -649,8 +781,8 @@ The entry point is `evaluateWizardReadiness()`, which only blocks on skill downl
649
781
 
650
782
  ## What blocks a run
651
783
 
652
- The `DEFAULT_WIZARD_READINESS_CONFIG` in `readiness.ts` controls this. It has
653
- two arrays:
784
+ The `DEFAULT_WIZARD_READINESS_CONFIG` in `readiness.ts` controls this. Its type
785
+ has two arrays, and the default sets only `downBlocksRun`:
654
786
 
655
787
  - **`downBlocksRun`** — if any of these report status **Down**, readiness is
656
788
  **No**.
@@ -686,7 +818,7 @@ This repo includes a helper script to run a full end‑to‑end smoke test of th
686
818
  - Cloning `wizard-workbench` next to this repo (so it lives at `../wizard-workbench`).
687
819
  - Set `POSTHOG_PERSONAL_API_KEY` either in your shell or in `../wizard-workbench/.env`.
688
820
  - Set `WIZARD_CI_GATEWAY_TOKEN_FILE` to an absolute path containing the separate
689
- AI gateway token. See [local credentials](docs/local-dev.md#credentials-for-local-ci-and-headless-runs).
821
+ gateway service key from 1Password. See [local credentials](docs/local-dev.md#credentials-for-local-ci-and-headless-runs).
690
822
  - Set `POSTHOG_WIZARD_PROJECT_ID` to the intended test project and
691
823
  `POSTHOG_WIZARD_REGION` to `us` or `eu` (CI uses `us`). The helper also accepts
692
824
  `POSTHOG_PROJECT_ID` and `POSTHOG_REGION` as fallback names.
@@ -1,8 +1,28 @@
1
- import { $ as wordWrap, it as Icons, rt as Colors } from "./mint-failure-C0HyvEwO.js";
2
1
  import { Box, Text, useInput, useStdout } from "ink";
3
2
  import { createContext, useCallback, useContext, useEffect, useMemo, useRef, useState } from "react";
4
- import { jsx, jsxs } from "react/jsx-runtime";
5
3
  import Fuse from "fuse.js";
4
+ import { jsx, jsxs } from "react/jsx-runtime";
5
+ //#region src/tui/styles.ts
6
+ const Colors = {
7
+ primary: "cyan",
8
+ accent: "#DC9300",
9
+ titleColor: "#3D2800",
10
+ success: "green",
11
+ error: "red",
12
+ muted: "gray"
13
+ };
14
+ const Icons = {
15
+ diamond: "◆",
16
+ diamondOpen: "◇",
17
+ check: "✔",
18
+ warning: "⚠",
19
+ squareFilled: "◼",
20
+ squareOpen: "◻",
21
+ triangleRight: "▶",
22
+ triangleSmallRight: "▸",
23
+ bullet: "•"
24
+ };
25
+ //#endregion
6
26
  //#region src/tui/primitives/picker-filter.ts
7
27
  /**
8
28
  * Filter-as-you-type matching for PickerMenu. Split out from the component so the
@@ -122,6 +142,86 @@ const ConfirmButton = ({ label = "Confirm", focused, count }) => {
122
142
  });
123
143
  };
124
144
  //#endregion
145
+ //#region src/tui/primitives/content-types.ts
146
+ /** Type guard for lines blocks. */
147
+ function isLinesBlock(block) {
148
+ return typeof block !== "string" && "type" in block && block.type === "lines";
149
+ }
150
+ /** Type guard for clear blocks. */
151
+ function isClearBlock(block) {
152
+ return typeof block !== "string" && "type" in block && block.type === "clear";
153
+ }
154
+ /** Type guard for object blocks (text or node content). */
155
+ function isObjectBlock(block) {
156
+ return typeof block !== "string" && !("type" in block);
157
+ }
158
+ //#endregion
159
+ //#region src/tui/primitives/layout-helpers.ts
160
+ /**
161
+ * Estimate the number of terminal rows a content block will occupy,
162
+ * including 1 row of marginBottom.
163
+ */
164
+ function estimateBlockHeight(block, availableWidth) {
165
+ if (typeof block === "string") return wordWrap(block, availableWidth).length + 1;
166
+ if (isClearBlock(block)) return 0;
167
+ if (isLinesBlock(block)) return block.lines.length + 1;
168
+ if (isObjectBlock(block)) {
169
+ if (typeof block.content === "string") return wordWrap(block.content, availableWidth).length + 1;
170
+ return 4;
171
+ }
172
+ return 1;
173
+ }
174
+ /**
175
+ * Given all blocks, the active index, available width, and a row budget,
176
+ * return [startIdx, endIdx] — the range of blocks to render.
177
+ *
178
+ * Always includes activeIdx. Walks backward to include as many completed
179
+ * blocks as fit within maxHeight.
180
+ */
181
+ function computeVisibleRange(blocks, activeIdx, availableWidth, maxHeight) {
182
+ const budget = Math.max(4, maxHeight - 2);
183
+ let totalHeight = estimateBlockHeight(blocks[activeIdx], availableWidth);
184
+ let start = activeIdx;
185
+ for (let i = activeIdx - 1; i >= 0; i--) {
186
+ if (isClearBlock(blocks[i])) break;
187
+ const h = estimateBlockHeight(blocks[i], availableWidth);
188
+ if (totalHeight + h > budget) break;
189
+ totalHeight += h;
190
+ start = i;
191
+ }
192
+ return [start, activeIdx];
193
+ }
194
+ /**
195
+ * Word-wrap text at clean word boundaries. Always returns pre-wrapped text
196
+ * joined with \n — this avoids Ink's native wrap which can leave leading
197
+ * spaces on continuation lines.
198
+ *
199
+ * Uses a 1-char safety margin so slight width estimate mismatches don't
200
+ * cause Ink to re-wrap our already-wrapped lines.
201
+ */
202
+ function wordWrap(text, availableWidth) {
203
+ const safeWidth = Math.max(10, availableWidth - 1);
204
+ const words = text.split(/\s+/);
205
+ const lines = [];
206
+ let currentLine = "";
207
+ for (const word of words) if (currentLine.length + word.length + 1 > safeWidth && currentLine.length > 0) {
208
+ lines.push(currentLine);
209
+ currentLine = word;
210
+ } else currentLine += (currentLine.length > 0 ? " " : "") + word;
211
+ if (currentLine.length > 0) lines.push(currentLine);
212
+ return lines;
213
+ }
214
+ /**
215
+ * Word-wrap text and return only the last `maxRows` lines.
216
+ * Used for intra-block truncation when a single text block exceeds the viewport.
217
+ * Also used for normal rendering to avoid Ink's leading-space wrap artifacts.
218
+ */
219
+ function wrapAndTruncate(text, availableWidth, maxRows) {
220
+ const lines = wordWrap(text, availableWidth);
221
+ if (lines.length <= maxRows) return lines.join("\n");
222
+ return lines.slice(-maxRows).join("\n");
223
+ }
224
+ //#endregion
125
225
  //#region src/tui/hooks/useStdoutDimensions.ts
126
226
  /**
127
227
  * useStdoutDimensions — Returns [columns, rows] and re-renders on terminal resize.
@@ -753,6 +853,6 @@ const MultiPickerMenu = ({ message, options, centered = false, columns = 1, opti
753
853
  });
754
854
  };
755
855
  //#endregion
756
- export { useStdoutDimensions as a, useKeyboardHintsContext as i, useKeyBindings as n, ConfirmButton as o, KeyboardHintsProvider as r, PromptLabel as s, PickerMenu as t };
856
+ export { useStdoutDimensions as a, wrapAndTruncate as c, isObjectBlock as d, ConfirmButton as f, Icons as h, useKeyboardHintsContext as i, isClearBlock as l, Colors as m, useKeyBindings as n, computeVisibleRange as o, PromptLabel as p, KeyboardHintsProvider as r, wordWrap as s, PickerMenu as t, isLinesBlock as u };
757
857
 
758
- //# sourceMappingURL=PickerMenu-m4CCPX4f.js.map
858
+ //# sourceMappingURL=PickerMenu-BGGeYqd-.js.map