@posthog/wizard 2.79.1 → 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-dG5DQCZA.js → PickerMenu-BGGeYqd-.js} +112 -12
  3. package/dist/PickerMenu-BGGeYqd-.js.map +1 -0
  4. package/dist/README.md +9 -6
  5. package/dist/{agent-interface-FkbaBJwz.js → agent-interface-CemBvTAA.js} +130 -324
  6. package/dist/agent-interface-CemBvTAA.js.map +1 -0
  7. package/dist/{agent-prompt-loader-D0weQ-7k.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-CrbCIQOz.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-vAq-T-K7.js → bounded-fs-CAsuF6al.js} +3 -3
  21. package/dist/{bounded-fs-vAq-T-K7.js.map → bounded-fs-CAsuF6al.js.map} +1 -1
  22. package/dist/{ci-install-COcV8SY2.js → ci-install-CEYE02t-.js} +22 -26
  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-kAHwWGg7.js → debug-BfQPD2Hg.js} +18 -52
  27. package/dist/debug-BfQPD2Hg.js.map +1 -0
  28. package/dist/{defaults-a9TelDhJ.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-C9-GlLO9.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-D8GhEVoX.js +114 -0
  42. package/dist/host-resolution-D8GhEVoX.js.map +1 -0
  43. package/dist/install-Bw8tvDvS.js +2 -0
  44. package/dist/{add-mcp-server-to-clients-DIaTRWMY.js → install-paPCzPHI.js} +34 -100
  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/{telemetry-B7zJdRmA.js → links-Cyj6v8kg.js} +4 -13
  49. package/dist/links-Cyj6v8kg.js.map +1 -0
  50. package/dist/{main-CgKxbwMP.js → main-0p-YxUNa.js} +233 -490
  51. package/dist/main-0p-YxUNa.js.map +1 -0
  52. package/dist/{mcp-DnAyW0-w.js → mcp-D3Z5MXhA.js} +3 -4
  53. package/dist/{mcp-DnAyW0-w.js.map → mcp-D3Z5MXhA.js.map} +1 -1
  54. package/dist/mcp-install-smoke-test.ts +2 -2
  55. package/dist/{mcp-prompt-streaming-DDWQ-FCA.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-WcwUnSKb.js → models-D1SnCzvl.js} +2 -2
  60. package/dist/{models-WcwUnSKb.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-DYM2Hrl2.js → oauth-session-Dde79Ycm.js} +3 -3
  64. package/dist/{oauth-session-DYM2Hrl2.js.map → oauth-session-Dde79Ycm.js.map} +1 -1
  65. package/dist/{orchestrator-tools-DbgNBFGA.js → orchestrator-tools-BSNhzzkT.js} +3 -3
  66. package/dist/{orchestrator-tools-DbgNBFGA.js.map → orchestrator-tools-BSNhzzkT.js.map} +1 -1
  67. package/dist/{package-json-Atg34fa4.js → package-json-2UrhE6kP.js} +1 -1
  68. package/dist/{package-json-Atg34fa4.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-8KsYsPmM.js → pi-cM_4Gd_9.js} +19 -20
  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-Bo2NRxFz.js → provisioning-JbJtq7hq.js} +5 -67
  83. package/dist/provisioning-JbJtq7hq.js.map +1 -0
  84. package/dist/{queue-tools-C8mXOh7e.js → queue-tools-BIZSJyt6.js} +7 -9
  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-C71pkwqH.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-BlYRBMj7.js → start-playground-DL4mVEUx.js} +63 -54
  103. package/dist/start-playground-DL4mVEUx.js.map +1 -0
  104. package/dist/{subagent-D1TrTchE.js → subagent-CnFvAq6E.js} +3 -3
  105. package/dist/{subagent-D1TrTchE.js.map → subagent-CnFvAq6E.js.map} +1 -1
  106. package/dist/{task-DqRlQBfs.js → task-BOScSm4W.js} +17 -18
  107. package/dist/task-BOScSm4W.js.map +1 -0
  108. package/dist/{tasks-ChWufsdO.js → tasks-BfJhVky2.js} +1 -1
  109. package/dist/tasks-BfJhVky2.js.map +1 -0
  110. package/dist/telemetry-CP4rGicd.js +13 -0
  111. package/dist/telemetry-CP4rGicd.js.map +1 -0
  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-CkJ2y9Wt.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-BPcg3_3Q.js → upload-step-CEacB2RV.js} +17 -19
  122. package/dist/upload-step-CEacB2RV.js.map +1 -0
  123. package/dist/urls-BDELGZHq.js +67 -0
  124. package/dist/urls-BDELGZHq.js.map +1 -0
  125. package/dist/warlock-smoke-test.ts +1 -2
  126. package/dist/{wizard-abort-BPdv07np.js → wizard-abort-D3-75KyV.js} +41 -32
  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-BnxejtXK.js → yara-hooks-D8YDyX7o.js} +283 -21
  130. package/dist/yara-hooks-D8YDyX7o.js.map +1 -0
  131. package/package.json +7 -8
  132. package/dist/PickerMenu-dG5DQCZA.js.map +0 -1
  133. package/dist/add-mcp-server-to-clients-DIaTRWMY.js.map +0 -1
  134. package/dist/add-mcp-server-to-clients-artmN7mz.js +0 -2
  135. package/dist/agent-BEjARD2a.js +0 -6
  136. package/dist/agent-BWFhuLgo.js +0 -3178
  137. package/dist/agent-BWFhuLgo.js.map +0 -1
  138. package/dist/agent-interface-FkbaBJwz.js.map +0 -1
  139. package/dist/agent-prompt-loader-D0weQ-7k.js.map +0 -1
  140. package/dist/analytics-DFtbRjYh.js +0 -2
  141. package/dist/analytics-DXK1gc12.js +0 -301
  142. package/dist/analytics-DXK1gc12.js.map +0 -1
  143. package/dist/api-Cm9UtKZh.js +0 -2
  144. package/dist/api-CrbCIQOz.js.map +0 -1
  145. package/dist/check-screens.tsx +0 -190
  146. package/dist/ci-install-COcV8SY2.js.map +0 -1
  147. package/dist/constants-DHCBSfnx.js +0 -260
  148. package/dist/constants-DHCBSfnx.js.map +0 -1
  149. package/dist/debug-BuYHGr6_.js +0 -2
  150. package/dist/debug-kAHwWGg7.js.map +0 -1
  151. package/dist/defaults-a9TelDhJ.js.map +0 -1
  152. package/dist/endpoints-BVMYm9F4.js +0 -108
  153. package/dist/endpoints-BVMYm9F4.js.map +0 -1
  154. package/dist/env-api-key-BP-NFFXt.js +0 -17
  155. package/dist/env-api-key-BP-NFFXt.js.map +0 -1
  156. package/dist/env-api-key-CaWEDj_9.js +0 -2
  157. package/dist/environment-BATlQxcQ.js +0 -39
  158. package/dist/environment-BATlQxcQ.js.map +0 -1
  159. package/dist/environment-CwD8OPYj.js +0 -2
  160. package/dist/file-C5JMsyR1.js +0 -2
  161. package/dist/file-DcRKycV8.js +0 -60
  162. package/dist/file-DcRKycV8.js.map +0 -1
  163. package/dist/file-watcher-Brq2nnHV.js +0 -123
  164. package/dist/file-watcher-Brq2nnHV.js.map +0 -1
  165. package/dist/gateway-C9-GlLO9.js.map +0 -1
  166. package/dist/headless-ui-CqI2gXlD.js +0 -44
  167. package/dist/headless-ui-CqI2gXlD.js.map +0 -1
  168. package/dist/interactive-B_Ti_CsS.js +0 -11
  169. package/dist/interactive-B_Ti_CsS.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-Dza4D0MK.js +0 -226
  173. package/dist/logging-ui-Dza4D0MK.js.map +0 -1
  174. package/dist/main-CgKxbwMP.js.map +0 -1
  175. package/dist/mcp-prompt-streaming-DDWQ-FCA.js.map +0 -1
  176. package/dist/mint-failure-u8xQKNOn.js +0 -6392
  177. package/dist/mint-failure-u8xQKNOn.js.map +0 -1
  178. package/dist/non-interactive-DyVC1AGc.js +0 -18
  179. package/dist/non-interactive-DyVC1AGc.js.map +0 -1
  180. package/dist/package-json-D8Ga03tK.js +0 -2
  181. package/dist/pi-8KsYsPmM.js.map +0 -1
  182. package/dist/playground-BlYRBMj7.js.map +0 -1
  183. package/dist/posthog-Bt0Aplb8.js +0 -124
  184. package/dist/posthog-Bt0Aplb8.js.map +0 -1
  185. package/dist/posthog-CUgCEhH0.js +0 -2
  186. package/dist/provisioning-Bo2NRxFz.js.map +0 -1
  187. package/dist/provisioning-OGFGlzf7.js +0 -2
  188. package/dist/queue-tools-C8mXOh7e.js.map +0 -1
  189. package/dist/registry-C06e_x-p.js +0 -2
  190. package/dist/registry-CD5RQt38.js +0 -3464
  191. package/dist/registry-CD5RQt38.js.map +0 -1
  192. package/dist/run-agent-legacy-ChacZImU.js +0 -2
  193. package/dist/run-agent-legacy-DOlM6DQu.js +0 -3540
  194. package/dist/run-agent-legacy-DOlM6DQu.js.map +0 -1
  195. package/dist/runners-ov3EXF1n.js +0 -834
  196. package/dist/runners-ov3EXF1n.js.map +0 -1
  197. package/dist/security-C71pkwqH.js.map +0 -1
  198. package/dist/setup-utils-B26Lf2yF.js +0 -1512
  199. package/dist/setup-utils-B26Lf2yF.js.map +0 -1
  200. package/dist/setup-utils-CVS86NYR.js +0 -2
  201. package/dist/start-tui-Bo2L0bar.js +0 -6962
  202. package/dist/start-tui-Bo2L0bar.js.map +0 -1
  203. package/dist/steps-BPcg3_3Q.js.map +0 -1
  204. package/dist/store-BTzcvRGT.js +0 -992
  205. package/dist/store-BTzcvRGT.js.map +0 -1
  206. package/dist/store-BpqySPXm.js +0 -5
  207. package/dist/task-DqRlQBfs.js.map +0 -1
  208. package/dist/task-stream-Bw6JaLCX.js +0 -363
  209. package/dist/task-stream-Bw6JaLCX.js.map +0 -1
  210. package/dist/tasks-ChWufsdO.js.map +0 -1
  211. package/dist/telemetry-B7zJdRmA.js.map +0 -1
  212. package/dist/terminal-zgkEfoCL.js +0 -7196
  213. package/dist/terminal-zgkEfoCL.js.map +0 -1
  214. package/dist/tools-CkJ2y9Wt.js.map +0 -1
  215. package/dist/ui-Q6-RvERF.js +0 -15
  216. package/dist/ui-Q6-RvERF.js.map +0 -1
  217. package/dist/version-CHhJjz_H.js +0 -6
  218. package/dist/version-CHhJjz_H.js.map +0 -1
  219. package/dist/wizard-abort-BPdv07np.js.map +0 -1
  220. package/dist/wizard-abort-Br1qMDNa.js +0 -3
  221. package/dist/wizard-session-2w4Ru-Wz.js +0 -131
  222. package/dist/wizard-session-2w4Ru-Wz.js.map +0 -1
  223. package/dist/wizard-session-DGaUHOF3.js +0 -2
  224. package/dist/wizard-ui-DVqrYaOM.js +0 -16
  225. package/dist/wizard-ui-DVqrYaOM.js.map +0 -1
  226. package/dist/yara-hooks-BnxejtXK.js.map +0 -1
  227. package/dist/yara-hooks-DSuExwb4.js +0 -2
package/README.md CHANGED
@@ -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
 
@@ -231,7 +240,7 @@ The following CLI arguments are available:
231
240
  | `--debug` | Enable verbose logging | boolean | `false` | | `POSTHOG_WIZARD_DEBUG` |
232
241
  | `--signup` | Create a new PostHog account during setup | boolean | `false` | | `POSTHOG_WIZARD_SIGNUP` |
233
242
  | `--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` |
243
+ | `--ci` | Enable CI mode for non-interactive execution (dev and test builds only) | boolean | `false` | | `POSTHOG_WIZARD_CI` |
235
244
  | `--api-key` | PostHog personal API key (phx_xxx) for authentication | string | | | `POSTHOG_WIZARD_API_KEY` |
236
245
  | `--no-telemetry` | Disable wizard run-state telemetry | boolean | `false` | | `POSTHOG_WIZARD_NO_TELEMETRY` |
237
246
 
@@ -257,7 +266,6 @@ When running in CI mode (`--ci`):
257
266
  - Bypasses OAuth login flow (uses personal API key directly)
258
267
  - Auto-selects defaults for all prompts
259
268
  - Skips MCP server installation
260
- - Auto-continues on git warnings (uncommitted/untracked files)
261
269
  - Auto-consents to AI usage
262
270
 
263
271
  The CLI args override environment variables in CI mode.
@@ -279,8 +287,8 @@ health_issue:read wizard_session:read wizard_session:write wizard_run:write
279
287
 
280
288
  The source of truth is `WIZARD_OAUTH_SCOPES` in `src/shared/constants.ts`, which
281
289
  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
290
+ Some programs request more on top (`oauthScopeAdditions` on the program's
291
+ config); the default integration flow adds
284
292
  `integration:read` and `external_data_source:read` /
285
293
  `external_data_source:write`.
286
294
 
@@ -294,12 +302,11 @@ for limits, shutdown behavior, migration compatibility, and deployment checks.
294
302
  ### OAuth app scope ceiling
295
303
 
296
304
  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.
305
+ in every deployed region. Run synchronization needs no read scope.
299
306
 
300
307
  The wizard's OAuth app on the PostHog side caps the scopes its tokens may
301
308
  carry (`OAuthApplication.scopes`). Any scope requested in this repo (see
302
- `src/programs/oauth/program-scopes.ts`) must be grantable under that ceiling, or
309
+ the programs' `oauthScopeAdditions`) must be grantable under that ceiling, or
303
310
  `/authorize` drops it and the call that needs it 403s.
304
311
 
305
312
  **A granted token can be narrower than the request even with a correct
@@ -309,8 +316,8 @@ are clamped silently (`clamp_scopes_to_ceiling`) — neither path errors;
309
316
  `/oauth/token` just returns a smaller `scope`. So never assume the token
310
317
  carries what was requested: the token response's `scope` field is the truth.
311
318
  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.
319
+ `src/programs/oauth/tokens.ts`), warns the user which permissions are missing, and
320
+ emits `wizard: oauth grant narrowed` so narrowed runs are countable in analytics.
314
321
  The diff also rides on the session (`credentials.missingScopes`), so when a
315
322
  run does fail on a scope-gated step, the error names the missing permission
316
323
  and the fix instead of the generic report-a-bug line.
@@ -406,10 +413,103 @@ that conventional code implies.
406
413
  If you want to use this code as a starting place for your own project, here's a
407
414
  quick explainer on its structure.
408
415
 
409
- ## Entrypoint: `run.ts`
416
+ ## What calls what
417
+
418
+ ```mermaid
419
+ %%{init: {"block": {"padding": 20}}}%%
420
+ block-beta
421
+ columns 18
422
+ 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
423
+ cliBand["src/cli picks a host, owns the signals and the exit"]:6 space:12
424
+ runWizard["runWizard"]:3 runWizardCI["runWizardCI<br/>runWizardHeadless"]:3 space:6 toolCmd["src/cli<br/>a tool's command"]:3 space:3
425
+ hostBand["src/tui · src/headless the two hosts"]:6 space:12
426
+ runTui["runTui"]:3 runHeadless["runHeadless"]:3 space:6 runTool["runTuiTool<br/>or an @tools runner"]:3 space:3
427
+ wizardStore["WizardStore<br/>display over the store"]:3 space:15
428
+ programsBand["@programs"]:12 space:6
429
+ tuiStore["SessionStore"]:3 headlessStore["SessionStore"]:3 ownStore["SessionStore"]:3 detect["detectProjectsWithAgent"]:3 space:6
430
+ tuiRun["runProgram"]:3 headlessRun["runProgram"]:3 ownRun["runProgram"]:3 space:9
431
+ agentBand["@agent"]:18
432
+ tuiAgent["runAgent"]:3 headlessAgent["runAgent"]:3 ownAgent["runAgent"]:3 detectAgent["runAgent"]:3 mcpStream["streamMcpPrompt"]:3 callerAgent["runAgent"]:3
433
+
434
+ user --> runWizard
435
+ runWizard --> runTui
436
+ runTui --> wizardStore
437
+ wizardStore --> tuiStore
438
+ tuiStore --> tuiRun
439
+ tuiRun --> tuiAgent
440
+
441
+ ci --> runWizardCI
442
+ runWizardCI --> runHeadless
443
+ runHeadless --> headlessStore
444
+ headlessStore --> headlessRun
445
+ headlessRun --> headlessAgent
446
+
447
+ embedder -- "builds and owns the store" --> ownStore
448
+ ownStore --> ownRun
449
+ ownRun --> ownAgent
450
+
451
+ detect --> detectAgent
452
+
453
+ toolUser --> toolCmd
454
+ toolCmd --> runTool
455
+ runTool -- "the MCP tutorial only" --> mcpStream
456
+
457
+ caller -- "runAgent(config, input)" --> callerAgent
458
+
459
+ classDef code fill:#3b82f626,stroke:#3b82f6,stroke-width:2px
460
+ classDef ext fill:none,stroke:#9ca3af,stroke-dasharray:4 3
461
+ classDef band fill:#3b82f640,stroke:none
462
+ class runWizard,runWizardCI,runTui,runHeadless,wizardStore,tuiStore,headlessStore,ownStore,tuiRun,headlessRun,ownRun,tuiAgent,headlessAgent,ownAgent,detect,detectAgent,toolCmd,runTool,mcpStream,callerAgent code
463
+ class user,ci,embedder,toolUser,caller ext
464
+ class cliBand,hostBand,programsBand,agentBand band
465
+ ```
410
466
 
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.
467
+ Each column is one way in, read top to bottom. A box that repeats across columns
468
+ is the same code. The CLI calls one of two hosts, the TUI or headless. They
469
+ share only the kind of session store they build: each builds its own, calls
470
+ `runProgram` with it, and `runProgram` writes the run into it. The TUI draws its
471
+ screens from the `WizardStore` on top of its store, and headless prints and
472
+ streams the run.
473
+
474
+ A tool's command runs no program. The CLI calls the TUI's `runTuiTool` for the
475
+ tool's screens, or a console runner from `@tools`. Only the MCP tutorial reaches
476
+ the agent, through `streamMcpPrompt`. The TUI's intro can also hand off to a
477
+ tool's screens, such as `doctor`, in the same process. See
478
+ [src/tools](src/tools/README.md).
479
+
480
+ Detection calls `runAgent` directly. `detectProjectsWithAgent` builds its own
481
+ run config for a project scan. It runs from a program's `ciPreRun`, which
482
+ `runProgram` calls as a CI run's detection, and from the TUI's detect screens.
483
+
484
+ Dashed boxes are callers that build against a checkout of this repository, not
485
+ the npm package. Your program can build a store and call
486
+ `runProgram(id, { store })` itself. Your code can call `runAgent` with no
487
+ program at all.
488
+
489
+ | Box | What it is | Where |
490
+ | --------------------------------- | ----------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------- |
491
+ | `runWizard` | Builds the launch values from the arguments and starts the TUI host | [src/cli/runners](src/cli/runners/run-wizard.ts) |
492
+ | `runWizardCI · runWizardHeadless` | Checks the non-interactive arguments and starts the headless host | [src/cli/runners](src/cli/runners/run-non-interactive.ts) |
493
+ | `a tool's command` | Parses the tool's arguments and calls its runner | [src/cli/commands](src/cli/commands) |
494
+ | `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) |
495
+ | `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) |
496
+ | `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) |
497
+ | `@tools` runner | A tool that runs on the console, such as `addMCPServerToClientsStep`, `runDoctorReport`, `runProvision` or `listSkills` | [src/tools](src/tools/README.md) |
498
+ | `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) |
499
+ | `SessionStore` | Launch values, detection, the login and the run's progress; each host builds its own | [src/programs/session](src/programs/session) |
500
+ | `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) |
501
+ | `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) |
502
+ | `runAgent` | One agent run from a `RunConfig` and `RunInput`; complete on its own | [src/agent](src/agent/README.md) |
503
+ | `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) |
504
+
505
+ ## Entrypoint: `bin.ts`
506
+
507
+ The entrypoint for this tool is `bin.ts`. It checks the Node version, and only
508
+ then loads `main.ts` with a dynamic import, so no dependency runs on an old
509
+ Node. `main.ts` sets the HTTP/1.1 dispatcher, restores any Claude settings
510
+ backup an interrupted run left behind, and calls `runCli()` from
511
+ `src/cli/index.ts`. `runCli` registers each command on the yargs setup in
512
+ `src/cli/wizard.ts` and runs the one that `process.argv` names.
413
513
 
414
514
  ## Analytics
415
515
 
@@ -447,12 +547,13 @@ existing code at scale and then modify it reliably.
447
547
 
448
548
  _If_ they are well prompted.
449
549
 
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.
550
+ `src/agent/agent-prompt.ts` demonstrates how to wrap a deterministic fence
551
+ around a chaotic process. Every wizard session gets the same prompt, tailored to
552
+ the specific files in the project.
453
553
 
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
554
+ These prompts go to the PostHog LLM gateway, an LLM interface we
555
+ host, with a scoped token that `src/agent/gateway-session.ts` mints for each
556
+ run. This gives us more control: we can be certain of the model version and
456
557
  provider which interpret the prompts and modify the files. This way, we can find
457
558
  the right tools for the job and again, apply them consistently.
458
559
 
@@ -493,45 +594,73 @@ Built with [tsdown](https://tsdown.dev/) (Rolldown). `pnpm build` bundles `bin.t
493
594
 
494
595
  ### Environment variables
495
596
 
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.
597
+ **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
598
 
498
599
  To add a new build-time constant, add it to `env` in `tsdown.config.ts` and export it from `src/env.ts`.
499
600
 
500
- **Runtime (allowlisted).** Runtime env reads go through `runtimeEnv()` in `src/env.ts`, which only accepts keys in the `RuntimeEnvKey` union:
601
+ **Runtime (allowlisted).** Most runtime env reads go through `runtimeEnv()` in `src/env.ts`, which only accepts keys in the `RuntimeEnvKey` union:
501
602
 
502
603
  | Variable | Purpose |
503
604
  |---|---|
504
605
  | `POSTHOG_WIZARD_BENCHMARK_CONFIG` | Path to benchmark config file |
505
606
  | `POSTHOG_WIZARD_BENCHMARK_FILE` | Output path for benchmark results |
506
607
  | `POSTHOG_WIZARD_LOG_DIR` | Log directory override |
507
- | `POSTHOG_WIZARD_DEBUG` / `DEBUG` | Enable debug output |
608
+ | `POSTHOG_WIZARD_RUN_ID` | Assigned cloud WizardRun id |
609
+ | `POSTHOG_TASK_RUN_ID`, `POSTHOG_TASK_ID`, `POSTHOG_HANDOFF_OUTPUT_PATH` | The PostHog task run that launched the wizard |
610
+ | `WIZARD_CI_GATEWAY_TOKEN_FILE`, `WIZARD_CI_GATEWAY_URL` | The gateway token and URL for `--ci` runs |
611
+ | `WIZARD_CI_FLAG_OVERRIDES`, `WIZARD_CI_EXCLUDE_TASKS` | Flag and task overrides for CI builds |
508
612
  | `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 |
613
+ | `APPDATA`, `XDG_CONFIG_HOME`, `OPENCODE_CONFIG_DIR` | Platform path resolution |
512
614
 
513
615
  To add a new runtime env var, add its key to `RuntimeEnvKey` in `src/env.ts`.
616
+ The CLI reads every `POSTHOG_WIZARD_*` variable as an option and rejects unknown
617
+ ones, so a CLI run with `POSTHOG_WIZARD_BENCHMARK_CONFIG`,
618
+ `POSTHOG_WIZARD_BENCHMARK_FILE` or `POSTHOG_WIZARD_WARLOCK_DISABLED` set exits
619
+ with `Unknown argument`. `POSTHOG_WIZARD_LOG_FILE` is the exception: it is the
620
+ env form of `--log-file`, a declared option that moves the debug log from its
621
+ default, `posthog-wizard.log` in the temp directory.
514
622
 
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.
623
+ **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
624
 
517
625
  ### Import aliases
518
626
 
519
- Path aliases defined in `tsconfig.build.json`, resolved by tsdown:
627
+ Path aliases defined in `tsconfig.base.json`, resolved by tsdown and `tsx`:
520
628
 
521
629
  | Alias | Maps to |
522
630
  |---|---|
523
631
  | `@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 |
632
+ | `@shared/*` | `src/shared/*` |
633
+ | `@utils/*` | `src/shared/utils/*` |
634
+ | `@host/*` | `src/host/*`, how a run ends (`startHostExit`, `wizardAbort`, `registerShutdown`), for headless, the TUI, the CLI and the e2e harness |
635
+ | `@agent` | `src/agent/index.ts`, the agent's runtime entry |
526
636
  | `@agent/types` | `src/agent/types.ts`, type-only |
527
- | `@agent/*` | `src/agent/*`, inside `src/agent` and its tests only |
637
+ | `@agent/*` | `src/agent/*`, for the agent's tests. The agent imports its own modules by relative path, and no other layer maps it |
528
638
  | `@programs` | `src/programs/index.ts`, the programs runtime entry |
529
639
  | `@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/*` |
640
+ | `@programs/<id>` | `src/programs/<id>/index.ts`, one program's entry. Other layers reach nothing else in a program folder |
641
+ | `@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 |
642
+ | `@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 |
643
+ | `@tui` | `src/tui/index.ts`, the TUI's one entry, for the CLI and the e2e harness |
644
+ | `@tui/*` | `src/tui/*`. Only the TUI's own projects may use it |
645
+ | `@headless` | `src/headless/index.ts`, headless's one entry, for the CLI |
646
+ | `@cli` | `src/cli/index.ts`, the CLI's one entry, for `main.ts` |
647
+ | `@cli/*` | `src/cli/*`. Only the CLI may use it |
648
+ | `@e2e-harness/*` | `e2e-harness/*`, for the harness, scripts and tests |
649
+
650
+ Each layer's tsconfig project `references` only the layers it may import, so
651
+ `pnpm typecheck` rejects an import of any other. Outside the TUI, `ink`,
652
+ `react`, `@inkjs/ui` and `ink-testing-library` resolve to a fence that fails
653
+ every import form, and no layer imports JSON. `pnpm lint` rejects the paths the
654
+ compiler can't see: a relative import that leaves its layer's folder, a deep
655
+ alias outside its own layer, a `.tsbuild/` or `node_modules/` path, `module`
656
+ loaders and a bare `require`, triple-slash references, and the hosts importing
657
+ the agent's runtime. See
658
+ [layer boundaries](.claude/skills/wizard-development/references/ARCHITECTURE.md#layer-boundaries)
659
+ for what each layer may import and why each rule exists. Code outside a layer
660
+ imports it only through the entries above. The e2e harness, scripts and
661
+ `docs/examples` are one layer project, `e2e-harness/tsconfig.json`. Tests follow
662
+ the same rule: each layer's tests sit in its project, and a test mocks another
663
+ layer through its entry.
535
664
 
536
665
  ## Running locally
537
666
 
@@ -613,7 +742,8 @@ Example prompt — explore against
613
742
  > for any setup question, then `run_agent` at auth.
614
743
  > 4. Poll `read_state` until `integration` is `done` (or `failed` — then report
615
744
  > `integrationError`), snapshotting as the run screen progresses.
616
- > 5. Finish the tail: dismiss outro / mcp / slack, then `keep_skills`.
745
+ > 5. Finish the tail: `dismiss_outro`, `set_mcp_outcome`, `dismiss_slack`, then
746
+ > `keep_skills`.
617
747
  >
618
748
  > Then show me the saved snapshots in order, the screen path, whether `posthog`
619
749
  > landed in the app, and anything that broke.
@@ -635,7 +765,7 @@ The entry point is `evaluateWizardReadiness()`, which only blocks on skill downl
635
765
  | Decision | Meaning |
636
766
  | ------------------- | --------------------------------------------------------------- |
637
767
  | `yes` | Skills are reachable — proceed without outage warnings. |
638
- | `no` | Neither skills origin is reachable — do not run. |
768
+ | `no` | Neither skills origin is reachable. Interactive runs show the outage and stop; non-interactive runs report it and continue. |
639
769
 
640
770
  ### Module layout
641
771
 
@@ -649,8 +779,8 @@ The entry point is `evaluateWizardReadiness()`, which only blocks on skill downl
649
779
 
650
780
  ## What blocks a run
651
781
 
652
- The `DEFAULT_WIZARD_READINESS_CONFIG` in `readiness.ts` controls this. It has
653
- two arrays:
782
+ The `DEFAULT_WIZARD_READINESS_CONFIG` in `readiness.ts` controls this. Its type
783
+ has two arrays, and the default sets only `downBlocksRun`:
654
784
 
655
785
  - **`downBlocksRun`** — if any of these report status **Down**, readiness is
656
786
  **No**.
@@ -1,9 +1,29 @@
1
- import { $ as wordWrap, it as Icons, rt as Colors } from "./mint-failure-u8xQKNOn.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";
6
- //#region src/ui/tui/primitives/picker-filter.ts
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
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
9
29
  * ranking is testable on its own — the component only decides when to call it.
@@ -78,7 +98,7 @@ function rankOptions(fuse, options, query) {
78
98
  return [...surviving ?? []].sort(([, a], [, b]) => a - b).map(([option]) => option);
79
99
  }
80
100
  //#endregion
81
- //#region src/ui/tui/primitives/PromptLabel.tsx
101
+ //#region src/tui/primitives/PromptLabel.tsx
82
102
  /**
83
103
  * PromptLabel — Compact inline label for input prompts.
84
104
  *
@@ -94,7 +114,7 @@ const PromptLabel = ({ message }) => {
94
114
  }) });
95
115
  };
96
116
  //#endregion
97
- //#region src/ui/tui/primitives/ConfirmButton.tsx
117
+ //#region src/tui/primitives/ConfirmButton.tsx
98
118
  /**
99
119
  * ConfirmButton — the confirm row used to submit a selection.
100
120
  *
@@ -122,7 +142,87 @@ const ConfirmButton = ({ label = "Confirm", focused, count }) => {
122
142
  });
123
143
  };
124
144
  //#endregion
125
- //#region src/ui/tui/hooks/useStdoutDimensions.ts
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
225
+ //#region src/tui/hooks/useStdoutDimensions.ts
126
226
  /**
127
227
  * useStdoutDimensions — Returns [columns, rows] and re-renders on terminal resize.
128
228
  *
@@ -151,7 +251,7 @@ function useStdoutDimensions() {
151
251
  return size;
152
252
  }
153
253
  //#endregion
154
- //#region src/ui/tui/hooks/keyboard-hints-utils.ts
254
+ //#region src/tui/hooks/keyboard-hints-utils.ts
155
255
  /** Default priorities by key type. */
156
256
  const DEFAULT_PRIORITY = {
157
257
  ["upArrow"]: 0,
@@ -202,7 +302,7 @@ function deduplicateAndSort(hints) {
202
302
  return deduped;
203
303
  }
204
304
  //#endregion
205
- //#region src/ui/tui/hooks/useKeyboardHints.tsx
305
+ //#region src/tui/hooks/useKeyboardHints.tsx
206
306
  /**
207
307
  * KeyboardHintsProvider — Context for collecting and displaying keyboard hints.
208
308
  *
@@ -248,7 +348,7 @@ const KeyboardHintsProvider = ({ children }) => {
248
348
  });
249
349
  };
250
350
  //#endregion
251
- //#region src/ui/tui/hooks/useKeyBindings.ts
351
+ //#region src/tui/hooks/useKeyBindings.ts
252
352
  /**
253
353
  * useKeyBindings — Declarative keyboard input + automatic hint registration.
254
354
  *
@@ -287,7 +387,7 @@ function useKeyBindings(id, bindings) {
287
387
  });
288
388
  }
289
389
  //#endregion
290
- //#region src/ui/tui/primitives/PickerMenu.tsx
390
+ //#region src/tui/primitives/PickerMenu.tsx
291
391
  /**
292
392
  * PickerMenu — Single and multi select.
293
393
  * Single mode: custom renderer with small triangle indicator; enter selects.
@@ -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-dG5DQCZA.js.map
858
+ //# sourceMappingURL=PickerMenu-BGGeYqd-.js.map