@posthog/wizard 2.80.0 → 2.80.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (227) hide show
  1. package/README.md +187 -57
  2. package/dist/{PickerMenu-m4CCPX4f.js → PickerMenu-BGGeYqd-.js} +104 -4
  3. package/dist/PickerMenu-BGGeYqd-.js.map +1 -0
  4. package/dist/README.md +9 -6
  5. package/dist/{agent-interface-CzyCmp7q.js → agent-interface-CemBvTAA.js} +115 -346
  6. package/dist/agent-interface-CemBvTAA.js.map +1 -0
  7. package/dist/{agent-prompt-loader-4wMxlYSX.js → agent-prompt-loader-DPnj6SwU.js} +6 -5
  8. package/dist/agent-prompt-loader-DPnj6SwU.js.map +1 -0
  9. package/dist/analytics-B3ROGuIr.js +2 -0
  10. package/dist/analytics-D21z3E5l.js +732 -0
  11. package/dist/analytics-D21z3E5l.js.map +1 -0
  12. package/dist/{api-C3Dc4LFl.js → api-DtGIqQ2U.js} +2 -3
  13. package/dist/api-DtGIqQ2U.js.map +1 -0
  14. package/dist/api-IhROOQNv.js +2 -0
  15. package/dist/api-key-login-OEntFvu5.js +2 -0
  16. package/dist/api-key-login-h3E2G3zu.js +55 -0
  17. package/dist/api-key-login-h3E2G3zu.js.map +1 -0
  18. package/dist/bin.js +2 -2
  19. package/dist/bin.js.map +1 -1
  20. package/dist/{bounded-fs-CC_NDtoP.js → bounded-fs-CAsuF6al.js} +3 -3
  21. package/dist/{bounded-fs-CC_NDtoP.js.map → bounded-fs-CAsuF6al.js.map} +1 -1
  22. package/dist/{ci-install-DfcAMhlu.js → ci-install-CEYE02t-.js} +21 -25
  23. package/dist/ci-install-CEYE02t-.js.map +1 -0
  24. package/dist/console-log-O828zyiq.js +32 -0
  25. package/dist/console-log-O828zyiq.js.map +1 -0
  26. package/dist/{debug-DyARf5TF.js → debug-BfQPD2Hg.js} +18 -52
  27. package/dist/debug-BfQPD2Hg.js.map +1 -0
  28. package/dist/{defaults-DpfMnH2q.js → defaults-DDVl3tKN.js} +2 -51
  29. package/dist/defaults-DDVl3tKN.js.map +1 -0
  30. package/dist/{emit-BSetXzDV.js → emit-RfAewcWv.js} +1 -1
  31. package/dist/{emit-BSetXzDV.js.map → emit-RfAewcWv.js.map} +1 -1
  32. package/dist/{errors-C2domSkK.js → errors-CHrJzAZb.js} +4 -4
  33. package/dist/{errors-C2domSkK.js.map → errors-CHrJzAZb.js.map} +1 -1
  34. package/dist/family-picker-BKs-tTyu.js +46 -0
  35. package/dist/family-picker-BKs-tTyu.js.map +1 -0
  36. package/dist/{gateway-BmjYUSua.js → gateway-D3gIlR6b.js} +122 -11
  37. package/dist/gateway-D3gIlR6b.js.map +1 -0
  38. package/dist/headless-BJjhP0SI.js +10 -0
  39. package/dist/headless-BJjhP0SI.js.map +1 -0
  40. package/dist/headless-DIX68UUA.js +3 -0
  41. package/dist/{host-resolution-DVSb7kXb.js → host-resolution-D8GhEVoX.js} +4 -4
  42. package/dist/{host-resolution-DVSb7kXb.js.map → host-resolution-D8GhEVoX.js.map} +1 -1
  43. package/dist/install-Bw8tvDvS.js +2 -0
  44. package/dist/{install-Bk5TNk27.js → install-paPCzPHI.js} +26 -93
  45. package/dist/install-paPCzPHI.js.map +1 -0
  46. package/dist/interactive-tdxZKWax.js +11 -0
  47. package/dist/interactive-tdxZKWax.js.map +1 -0
  48. package/dist/{links-9LWZPSCq.js → links-Cyj6v8kg.js} +3 -3
  49. package/dist/{links-9LWZPSCq.js.map → links-Cyj6v8kg.js.map} +1 -1
  50. package/dist/{main-DKPjFHEV.js → main-0p-YxUNa.js} +204 -469
  51. package/dist/main-0p-YxUNa.js.map +1 -0
  52. package/dist/{mcp-Co8VRF62.js → mcp-D3Z5MXhA.js} +3 -4
  53. package/dist/{mcp-Co8VRF62.js.map → mcp-D3Z5MXhA.js.map} +1 -1
  54. package/dist/mcp-install-smoke-test.ts +2 -2
  55. package/dist/{mcp-prompt-streaming-ljCVoQ9I.js → mcp-prompt-streaming-COVbWnHt.js} +12 -12
  56. package/dist/mcp-prompt-streaming-COVbWnHt.js.map +1 -0
  57. package/dist/mode-label-DB3ol_sj.js +9 -0
  58. package/dist/mode-label-DB3ol_sj.js.map +1 -0
  59. package/dist/{models-Dba8ITeo.js → models-D1SnCzvl.js} +2 -2
  60. package/dist/{models-Dba8ITeo.js.map → models-D1SnCzvl.js.map} +1 -1
  61. package/dist/non-interactive-DxRBc73O.js +18 -0
  62. package/dist/non-interactive-DxRBc73O.js.map +1 -0
  63. package/dist/{oauth-session-D-RfcVmr.js → oauth-session-Dde79Ycm.js} +3 -3
  64. package/dist/{oauth-session-D-RfcVmr.js.map → oauth-session-Dde79Ycm.js.map} +1 -1
  65. package/dist/{orchestrator-tools-CVJ1F9Ub.js → orchestrator-tools-BSNhzzkT.js} +3 -3
  66. package/dist/{orchestrator-tools-CVJ1F9Ub.js.map → orchestrator-tools-BSNhzzkT.js.map} +1 -1
  67. package/dist/{package-json-Cowya9-3.js → package-json-2UrhE6kP.js} +1 -1
  68. package/dist/{package-json-Cowya9-3.js.map → package-json-2UrhE6kP.js.map} +1 -1
  69. package/dist/package-json-Dblip2_X.js +2 -0
  70. package/dist/package-manager-BRXlXo0p.js +105 -0
  71. package/dist/package-manager-BRXlXo0p.js.map +1 -0
  72. package/dist/{pi-B5YTBRDv.js → pi-cM_4Gd_9.js} +16 -18
  73. package/dist/pi-cM_4Gd_9.js.map +1 -0
  74. package/dist/playground-DTKy0XHT.js +12 -0
  75. package/dist/playground-DTKy0XHT.js.map +1 -0
  76. package/dist/posthog-integration-bwHwE87a.js +10291 -0
  77. package/dist/posthog-integration-bwHwE87a.js.map +1 -0
  78. package/dist/programs-BhtyA3lE.js +3 -0
  79. package/dist/programs-SeT1qNik.js +5348 -0
  80. package/dist/programs-SeT1qNik.js.map +1 -0
  81. package/dist/provisioning-BcXfeCMc.js +2 -0
  82. package/dist/{provisioning-CLhuKqXH.js → provisioning-JbJtq7hq.js} +4 -5
  83. package/dist/{provisioning-CLhuKqXH.js.map → provisioning-JbJtq7hq.js.map} +1 -1
  84. package/dist/{queue-tools-knnPQP0e.js → queue-tools-BIZSJyt6.js} +6 -8
  85. package/dist/queue-tools-BIZSJyt6.js.map +1 -0
  86. package/dist/results-DtKICAdz.js +55 -0
  87. package/dist/results-DtKICAdz.js.map +1 -0
  88. package/dist/run-CDurA5tO.js +248 -0
  89. package/dist/run-CDurA5tO.js.map +1 -0
  90. package/dist/run-DDCvLILJ.js +246 -0
  91. package/dist/run-DDCvLILJ.js.map +1 -0
  92. package/dist/run-tool-CTq9OOdT.js +2 -0
  93. package/dist/run-tool-DML8JJvt.js +2420 -0
  94. package/dist/run-tool-DML8JJvt.js.map +1 -0
  95. package/dist/runners-Dhu4pZTN.js +253 -0
  96. package/dist/runners-Dhu4pZTN.js.map +1 -0
  97. package/dist/{security-BvdSFDuM.js → security-DEH8Rn0_.js} +5 -5
  98. package/dist/security-DEH8Rn0_.js.map +1 -0
  99. package/dist/setup-utils-C5-WM-hS.js +118 -0
  100. package/dist/setup-utils-C5-WM-hS.js.map +1 -0
  101. package/dist/smoke-test.sh +1 -1
  102. package/dist/{playground-BLsCfHmQ.js → start-playground-DL4mVEUx.js} +43 -34
  103. package/dist/start-playground-DL4mVEUx.js.map +1 -0
  104. package/dist/{subagent-D_Sqak94.js → subagent-CnFvAq6E.js} +3 -3
  105. package/dist/{subagent-D_Sqak94.js.map → subagent-CnFvAq6E.js.map} +1 -1
  106. package/dist/{task-DiTI6Sak.js → task-BOScSm4W.js} +16 -17
  107. package/dist/task-BOScSm4W.js.map +1 -0
  108. package/dist/{tasks-ChZ_F1YP.js → tasks-BfJhVky2.js} +1 -1
  109. package/dist/tasks-BfJhVky2.js.map +1 -0
  110. package/dist/{telemetry-BNKsDxNS.js → telemetry-CP4rGicd.js} +2 -2
  111. package/dist/{telemetry-BNKsDxNS.js.map → telemetry-CP4rGicd.js.map} +1 -1
  112. package/dist/terminal-J3OD3dN0.js +16162 -0
  113. package/dist/terminal-J3OD3dN0.js.map +1 -0
  114. package/dist/tools-CCMV3DmB.js +544 -0
  115. package/dist/tools-CCMV3DmB.js.map +1 -0
  116. package/dist/{tools-C8LQ8QFz.js → tools-Cz8tDptL.js} +9 -9
  117. package/dist/tools-Cz8tDptL.js.map +1 -0
  118. package/dist/tui-BUZ2PWqN.js +2 -0
  119. package/dist/tui-Csf7VJxt.js +25 -0
  120. package/dist/tui-Csf7VJxt.js.map +1 -0
  121. package/dist/{steps-Hc28zVc_.js → upload-step-CEacB2RV.js} +14 -16
  122. package/dist/upload-step-CEacB2RV.js.map +1 -0
  123. package/dist/{urls-BI4kJ4qQ.js → urls-BDELGZHq.js} +2 -2
  124. package/dist/{urls-BI4kJ4qQ.js.map → urls-BDELGZHq.js.map} +1 -1
  125. package/dist/warlock-smoke-test.ts +1 -2
  126. package/dist/{wizard-abort-DBKtfnBR.js → wizard-abort-D3-75KyV.js} +40 -33
  127. package/dist/wizard-abort-D3-75KyV.js.map +1 -0
  128. package/dist/yara-hooks-CZ1tKxy_.js +2 -0
  129. package/dist/{yara-hooks-C3L6lBij.js → yara-hooks-D8YDyX7o.js} +283 -21
  130. package/dist/yara-hooks-D8YDyX7o.js.map +1 -0
  131. package/package.json +6 -6
  132. package/dist/PickerMenu-m4CCPX4f.js.map +0 -1
  133. package/dist/agent-BkBbVuNq.js +0 -3189
  134. package/dist/agent-BkBbVuNq.js.map +0 -1
  135. package/dist/agent-QGK2YzlX.js +0 -6
  136. package/dist/agent-interface-CzyCmp7q.js.map +0 -1
  137. package/dist/agent-prompt-loader-4wMxlYSX.js.map +0 -1
  138. package/dist/analytics-B6q5PN7a.js +0 -301
  139. package/dist/analytics-B6q5PN7a.js.map +0 -1
  140. package/dist/analytics-BXtfK9o7.js +0 -2
  141. package/dist/api-C3Dc4LFl.js.map +0 -1
  142. package/dist/api-yNjrfZs2.js +0 -2
  143. package/dist/check-screens.tsx +0 -190
  144. package/dist/ci-install-DfcAMhlu.js.map +0 -1
  145. package/dist/constants-DO4X70po.js +0 -260
  146. package/dist/constants-DO4X70po.js.map +0 -1
  147. package/dist/debug-BueK5mRR.js +0 -2
  148. package/dist/debug-DyARf5TF.js.map +0 -1
  149. package/dist/defaults-DpfMnH2q.js.map +0 -1
  150. package/dist/endpoints-D-4KxZiB.js +0 -108
  151. package/dist/endpoints-D-4KxZiB.js.map +0 -1
  152. package/dist/env-api-key-CHGLe0iz.js +0 -2
  153. package/dist/env-api-key-COf0U-Au.js +0 -17
  154. package/dist/env-api-key-COf0U-Au.js.map +0 -1
  155. package/dist/environment-DrLaSsA8.js +0 -39
  156. package/dist/environment-DrLaSsA8.js.map +0 -1
  157. package/dist/environment-hBj7ngmO.js +0 -2
  158. package/dist/file-CVA9ocIC.js +0 -60
  159. package/dist/file-CVA9ocIC.js.map +0 -1
  160. package/dist/file-CmoKK_Pp.js +0 -2
  161. package/dist/file-watcher-C3Su8vXm.js +0 -123
  162. package/dist/file-watcher-C3Su8vXm.js.map +0 -1
  163. package/dist/gateway-BmjYUSua.js.map +0 -1
  164. package/dist/headless-ui-CUbv12Yx.js +0 -44
  165. package/dist/headless-ui-CUbv12Yx.js.map +0 -1
  166. package/dist/install-Bk5TNk27.js.map +0 -1
  167. package/dist/install-F4wm3RSl.js +0 -2
  168. package/dist/interactive-C5LNvDj6.js +0 -11
  169. package/dist/interactive-C5LNvDj6.js.map +0 -1
  170. package/dist/local-dev-McsurOC-.js +0 -135
  171. package/dist/local-dev-McsurOC-.js.map +0 -1
  172. package/dist/logging-ui-p6XKVmTx.js +0 -226
  173. package/dist/logging-ui-p6XKVmTx.js.map +0 -1
  174. package/dist/main-DKPjFHEV.js.map +0 -1
  175. package/dist/mcp-prompt-streaming-ljCVoQ9I.js.map +0 -1
  176. package/dist/mint-failure-C0HyvEwO.js +0 -6403
  177. package/dist/mint-failure-C0HyvEwO.js.map +0 -1
  178. package/dist/non-interactive-CLMJrj_7.js +0 -18
  179. package/dist/non-interactive-CLMJrj_7.js.map +0 -1
  180. package/dist/package-json--ppioh2F.js +0 -2
  181. package/dist/pi-B5YTBRDv.js.map +0 -1
  182. package/dist/playground-BLsCfHmQ.js.map +0 -1
  183. package/dist/posthog-B2E0hpZt.js +0 -2
  184. package/dist/posthog-B42rt_1S.js +0 -124
  185. package/dist/posthog-B42rt_1S.js.map +0 -1
  186. package/dist/project-data--L-WZyvj.js +0 -2
  187. package/dist/project-data-BO9IXn9y.js +0 -1131
  188. package/dist/project-data-BO9IXn9y.js.map +0 -1
  189. package/dist/provisioning-C01REIU2.js +0 -2
  190. package/dist/queue-tools-knnPQP0e.js.map +0 -1
  191. package/dist/registry-B3rC5U4b.js +0 -3464
  192. package/dist/registry-B3rC5U4b.js.map +0 -1
  193. package/dist/registry-BamsM7J9.js +0 -2
  194. package/dist/run-agent-legacy-CwUmPfQF.js +0 -2
  195. package/dist/run-agent-legacy-DWBajsMh.js +0 -3467
  196. package/dist/run-agent-legacy-DWBajsMh.js.map +0 -1
  197. package/dist/runners-D1PqqpjA.js +0 -834
  198. package/dist/runners-D1PqqpjA.js.map +0 -1
  199. package/dist/security-BvdSFDuM.js.map +0 -1
  200. package/dist/setup-utils-ChXXTi1m.js +0 -301
  201. package/dist/setup-utils-ChXXTi1m.js.map +0 -1
  202. package/dist/start-tui-DicLfgsj.js +0 -6964
  203. package/dist/start-tui-DicLfgsj.js.map +0 -1
  204. package/dist/steps-Hc28zVc_.js.map +0 -1
  205. package/dist/store-COCO6U0P.js +0 -5
  206. package/dist/store-D3509G87.js +0 -1030
  207. package/dist/store-D3509G87.js.map +0 -1
  208. package/dist/task-DiTI6Sak.js.map +0 -1
  209. package/dist/task-status-CmrrR7zo.js +0 -16
  210. package/dist/task-status-CmrrR7zo.js.map +0 -1
  211. package/dist/task-stream-BckhG_cB.js +0 -363
  212. package/dist/task-stream-BckhG_cB.js.map +0 -1
  213. package/dist/tasks-ChZ_F1YP.js.map +0 -1
  214. package/dist/terminal-PK9bCLRi.js +0 -7222
  215. package/dist/terminal-PK9bCLRi.js.map +0 -1
  216. package/dist/tools-C8LQ8QFz.js.map +0 -1
  217. package/dist/ui-tPNpM6vj.js +0 -15
  218. package/dist/ui-tPNpM6vj.js.map +0 -1
  219. package/dist/version-5_ydHkM6.js +0 -6
  220. package/dist/version-5_ydHkM6.js.map +0 -1
  221. package/dist/wizard-abort-BVjqLyeA.js +0 -3
  222. package/dist/wizard-abort-DBKtfnBR.js.map +0 -1
  223. package/dist/wizard-session-B7BHnay0.js +0 -2
  224. package/dist/wizard-session-BYw6LzpS.js +0 -133
  225. package/dist/wizard-session-BYw6LzpS.js.map +0 -1
  226. package/dist/yara-hooks-C3L6lBij.js.map +0 -1
  227. package/dist/yara-hooks-CF_IsoaA.js +0 -2
@@ -1,1030 +0,0 @@
1
- import { s as logToFile } from "./debug-DyARf5TF.js";
2
- import "./constants-DO4X70po.js";
3
- import { t as buildSession } from "./wizard-session-BYw6LzpS.js";
4
- import { i as sessionProperties, n as analytics } from "./analytics-B6q5PN7a.js";
5
- import { n as isTaskStatus } from "./task-status-CmrrR7zo.js";
6
- import { a as getBlockingServiceKeys } from "./logging-ui-p6XKVmTx.js";
7
- import { o as computeTokenCostUsd } from "./agent-BkBbVuNq.js";
8
- import { p as appendStatus } from "./pi-B5YTBRDv.js";
9
- import { a as PROGRAM_REGISTRY, i as isRunFailure, o as Program, ot as reportWarehouseSourcesDetected, u as getProgramConfig } from "./mint-failure-C0HyvEwO.js";
10
- import { atom, map } from "nanostores";
11
- //#region src/tui/token-usage.ts
12
- const EMPTY_TOKEN_USAGE = {
13
- inputTokens: 0,
14
- outputTokens: 0,
15
- cacheReadTokens: 0,
16
- cacheCreationTokens: 0,
17
- costUsd: 0,
18
- costIsFinal: false
19
- };
20
- /** Total tokens across all counters in a `TokenUsageSnapshot` — used by
21
- * both `TokenCostHud` and `exit-line.ts` to detect "no agent turns yet". */
22
- function totalTokenCount(usage) {
23
- return usage.inputTokens + usage.outputTokens + usage.cacheReadTokens + usage.cacheCreationTokens;
24
- }
25
- //#endregion
26
- //#region src/tui/flow.ts
27
- /**
28
- * Project program steps into the narrower Screen shape the router consumes.
29
- *
30
- * Two things happen here:
31
- * 1. Headless steps (no `screenId`) are filtered out. The router walks
32
- * visible screens; gate-only steps like `detect` are store concerns.
33
- * 2. The step is narrowed to just { id, show, isComplete } — the
34
- * router has no business touching gate, onInit, or label.
35
- *
36
- * This intentional separation keeps the router focused on one question:
37
- * "Which screen should be rendered right now?"
38
- */
39
- function createProgramSequence(steps) {
40
- const entries = steps.filter((step) => step.screenId != null).map((step) => ({
41
- id: step.screenId,
42
- show: step.show,
43
- isComplete: step.isComplete ?? step.gate
44
- }));
45
- entries.push({
46
- id: "exit",
47
- show: void 0,
48
- isComplete: void 0
49
- });
50
- return entries;
51
- }
52
- //#endregion
53
- //#region src/tui/ai-opt-in-gate.ts
54
- /** Step id — also the ScreenId.AiOptIn enum value in screen-sequences. */
55
- const AI_OPT_IN_STEP_ID = "ai-opt-in";
56
- function aiApproved(session) {
57
- return !!session.apiUser?.organization?.is_ai_data_processing_approved;
58
- }
59
- /**
60
- * Returns the program's steps with the AI opt-in gate injected after
61
- * `auth`. Programs with `requiresAi: false` or no auth step pass
62
- * through unchanged — without auth, `apiUser` would never be populated
63
- * for evaluation anyway.
64
- */
65
- function withAiOptInGate(config) {
66
- if (config.requiresAi === false) return config.steps;
67
- const authIdx = config.steps.findIndex((s) => s.id === "auth");
68
- if (authIdx === -1) return config.steps;
69
- const gateStep = {
70
- id: AI_OPT_IN_STEP_ID,
71
- label: "AI opt-in check",
72
- screenId: AI_OPT_IN_STEP_ID,
73
- show: (session) => !session.ci && !session.signup && session.apiUser != null && !aiApproved(session),
74
- isComplete: (session) => session.ci || session.signup || aiApproved(session),
75
- gate: (session) => session.ci || session.signup || aiApproved(session)
76
- };
77
- return [
78
- ...config.steps.slice(0, authIdx + 1),
79
- gateStep,
80
- ...config.steps.slice(authIdx + 1)
81
- ];
82
- }
83
- //#endregion
84
- //#region src/ui/tui/screen-sequences.ts
85
- /** Post-run steps a mint-failure handoff continues through; ends on exit. */
86
- const MINT_HANDOFF_SEQUENCE = [
87
- {
88
- id: "mcp",
89
- isComplete: (s) => s.mcpComplete
90
- },
91
- {
92
- id: "slack-connect",
93
- isComplete: (s) => s.slackStepDismissed
94
- },
95
- {
96
- id: "keep-skills",
97
- isComplete: (s) => s.skillsComplete
98
- },
99
- { id: "exit" }
100
- ];
101
- /** All program screen sequences keyed by program id. */
102
- const PROGRAM_SEQUENCES = Object.fromEntries(PROGRAM_REGISTRY.map((c) => [c.id, createProgramSequence(withAiOptInGate(c))]));
103
- //#endregion
104
- //#region src/tui/router.ts
105
- var WizardRouter = class {
106
- sequence;
107
- programId;
108
- overlays = [];
109
- constructor(programId = Program.PostHogIntegration) {
110
- this.setProgram(programId);
111
- }
112
- /** Point the router at a different program. */
113
- setProgram(programId) {
114
- this.programId = programId;
115
- this.sequence = PROGRAM_SEQUENCES[programId];
116
- this.overlays = [];
117
- }
118
- /**
119
- * Resolve which screen should be active based on session state.
120
- * Walks the program sequence, skipping hidden entries and completed entries,
121
- * returns the first incomplete screen.
122
- */
123
- resolve(session) {
124
- const runFailed = isRunFailure(session);
125
- if (runFailed && session.mintHandoff === "exit") return "exit";
126
- if (runFailed && !session.mintHandoff) return "mint-failure";
127
- if (this.overlays.length > 0) return this.overlays[this.overlays.length - 1];
128
- const sequence = runFailed ? MINT_HANDOFF_SEQUENCE : this.sequence;
129
- for (const entry of sequence) {
130
- if (entry.show && !entry.show(session)) continue;
131
- if (entry.isComplete && entry.isComplete(session)) continue;
132
- if (entry.id === "auth" && session.runPhase === "error" && session.outroData) return "outro";
133
- return entry.id;
134
- }
135
- return sequence[sequence.length - 1].id;
136
- }
137
- /** The screen that should be rendered right now. */
138
- get activeScreen() {
139
- if (this.overlays.length > 0) return this.overlays[this.overlays.length - 1];
140
- return this.sequence[0].id;
141
- }
142
- /** The id of the active program. */
143
- get activeProgram() {
144
- return this.programId;
145
- }
146
- /** Whether an overlay is currently active. */
147
- get hasOverlay() {
148
- return this.overlays.length > 0;
149
- }
150
- /**
151
- * Push an overlay that interrupts the current program.
152
- * The program resumes when the overlay is dismissed via popOverlay().
153
- */
154
- pushOverlay(overlay) {
155
- this.overlays.push(overlay);
156
- }
157
- /**
158
- * Dismiss the topmost overlay. The program screen underneath resumes.
159
- */
160
- popOverlay() {
161
- this.overlays.pop();
162
- }
163
- /**
164
- * Direction hint for screen transitions.
165
- */
166
- _lastDirection = null;
167
- get lastNavDirection() {
168
- return this._lastDirection;
169
- }
170
- /** @internal — called by store wrapper to track direction */
171
- _setDirection(dir) {
172
- this._lastDirection = dir;
173
- }
174
- };
175
- //#endregion
176
- //#region src/tui/store.ts
177
- /**
178
- * WizardStore — Nanostore-backed reactive store for the TUI.
179
- * React components subscribe via useSyncExternalStore.
180
- *
181
- * The active screen is derived from session state — WizardRouter walks
182
- * the flow and shows the first step whose `isComplete` is still false.
183
- *
184
- * Define a step `gate` if your screen needs to await user interactions.
185
- * bin.ts calls `await store.getGate(stepId)` to pause until the gate
186
- * predicate becomes true.
187
- *
188
- * All session mutations that affect screen resolution go through
189
- * explicit setters so emitChange() is always called.
190
- */
191
- function captureHealthCheckBlocked(result) {
192
- try {
193
- const health = result.health;
194
- const blockingKeys = getBlockingServiceKeys(health);
195
- const attempts = health.skillsOrigin.rawIndicator?.match(/attempts=(\d+)/);
196
- const retriesUsed = Math.max(0, attempts ? Number(attempts[1]) - 1 : 0);
197
- analytics.wizardCapture("health check blocked", {
198
- decision: "skills-origin-down",
199
- blocking_keys: blockingKeys,
200
- retries_used: retriesUsed
201
- });
202
- } catch (err) {
203
- logToFile(`[health-checks] failed to capture analytics: ${err instanceof Error ? err.message : String(err)}`);
204
- }
205
- }
206
- var WizardStore = class {
207
- $session = map(buildSession({}));
208
- $statusMessages = atom([]);
209
- $statusExpanded = atom(false);
210
- $tasks = atom([]);
211
- $eventPlan = atom([]);
212
- $handoffText = atom(null);
213
- $learnCardBlockIdx = atom(0);
214
- $learnCardComplete = atom(false);
215
- $version = atom(0);
216
- $currentStage = atom(null);
217
- $tokenUsage = atom(EMPTY_TOKEN_USAGE);
218
- $tokenHudVisible = atom(false);
219
- _onTasksChanged = null;
220
- /** Last screen seen — used to detect screen transitions for analytics. */
221
- _lastScreen = null;
222
- /** Hooks run when transitioning onto a screen. */
223
- _enterScreenHooks = /* @__PURE__ */ new Map();
224
- /** Gate promises derived from program step definitions. */
225
- _gates = /* @__PURE__ */ new Map();
226
- version = "";
227
- /** Navigation router — resolves active screen from session state. */
228
- router;
229
- /** Blocks agent execution until the settings-override overlay is dismissed. */
230
- _resolveSettingsOverride = null;
231
- _backupAndFixSettings = null;
232
- /** Blocks the run until an optional step's notice is answered. */
233
- _resolveTaskNotice = null;
234
- /** Blocks OAuth flow until the port-conflict overlay is dismissed. */
235
- _resolvePortConflict = null;
236
- /** Resolves the OAuth flow with a manually-entered authorization code. */
237
- _resolveManualAuthCode = null;
238
- /** Resolves the in-flight wizard_ask request. */
239
- _noteAskProgress = null;
240
- _resolvePendingQuestion = null;
241
- constructor(program = Program.PostHogIntegration) {
242
- this.router = new WizardRouter(program);
243
- this._initFromProgram(program);
244
- }
245
- /**
246
- * Scan program steps for gate predicates and create gate promises.
247
- *
248
- * Steps are wrapped with withAiOptInGate so the injected ai-opt-in
249
- * step's gate registers here — the agent runner awaits it (via
250
- * WizardUI.waitForAiOptIn) before any source leaves the machine.
251
- * Same wrapper screen-sequences.ts uses, so the gate and its screen
252
- * can't drift apart.
253
- */
254
- _initFromProgram(program) {
255
- const steps = withAiOptInGate(getProgramConfig(program));
256
- for (const step of steps) if (step.gate) {
257
- let resolve;
258
- const promise = new Promise((r) => {
259
- resolve = r;
260
- });
261
- this._gates.set(step.id, {
262
- predicate: step.gate,
263
- promise,
264
- resolve,
265
- resolved: false
266
- });
267
- }
268
- }
269
- /**
270
- * Run the program steps' onInit callbacks. startTUI calls this once
271
- * the screens are actually rendering — constructing a store alone
272
- * (tests, playground) must not fire init work like the health-check
273
- * pre-flight, whose probes belong only to flows that show its screen.
274
- */
275
- runInitHooks() {
276
- const steps = getProgramConfig(this.router.activeProgram).steps;
277
- const getSession = () => this.session;
278
- const ctx = {
279
- get session() {
280
- return getSession();
281
- },
282
- setReadinessResult: (r) => this.setReadinessResult(r),
283
- setFrameworkContext: (k, v) => this.setFrameworkContext(k, v),
284
- emitChange: () => this.emitChange()
285
- };
286
- for (const step of steps) step.onInit?.(ctx);
287
- }
288
- /**
289
- * Run all `onReady` hooks declared by the current flow's steps, in
290
- * order. Must be called after `store.session = session` so hooks see
291
- * the real installDir. bin.ts calls this generically — it doesn't
292
- * need to know which program has which pre-flow work.
293
- */
294
- async runReadyHooks() {
295
- const steps = getProgramConfig(this.router.activeProgram).steps;
296
- const ctx = {
297
- session: this.session,
298
- setFrameworkContext: (k, v) => this.setFrameworkContext(k, v),
299
- setFrameworkConfig: (i, c) => this.setFrameworkConfig(i, c),
300
- setDetectedFramework: (l) => this.setDetectedFramework(l),
301
- setPosthogSdkDetected: (d) => this.setPosthogSdkDetected(d),
302
- setSkillId: (id) => this.setSkillId(id),
303
- setUnsupportedVersion: (info) => this.setUnsupportedVersion(info),
304
- addDiscoveredFeature: (f) => this.addDiscoveredFeature(f),
305
- setDetectionComplete: () => this.setDetectionComplete()
306
- };
307
- for (const step of steps) if (step.onReady) await step.onReady(ctx);
308
- }
309
- /**
310
- * Get a gate promise by step ID — the primary blocking checkpoint API
311
- * for bin.ts. `await store.getGate('...')` parks the caller until the
312
- * corresponding program step's gate predicate flips to true (if the
313
- * predicate stays false, the caller stays parked indefinitely — the
314
- * TUI keeps rendering so the user can resolve whatever is blocking).
315
- *
316
- * If the program doesn't define a step with this ID, or the step
317
- * has no `gate` predicate, this returns an already-resolved promise
318
- * so bin.ts flows straight through. This lets programs opt in to
319
- * gates on a per-step basis without bin.ts needing to know which
320
- * gates exist in which flow.
321
- */
322
- getGate(stepId) {
323
- return this._gates.get(stepId)?.promise ?? Promise.resolve();
324
- }
325
- /**
326
- * Resolve once `predicate(session)` is true. Unlike a gate, this is created
327
- * at the await point and evaluated live against the current session, so it
328
- * never latches on a startup value — the orchestrator uses it to wait for a
329
- * decision (a project picked, a handoff acknowledged) without the "true while
330
- * undecided" trap that latched gate predicates have.
331
- */
332
- waitUntil(predicate) {
333
- if (predicate(this.session)) return Promise.resolve();
334
- return new Promise((resolve) => {
335
- const unsub = this.subscribe(() => {
336
- if (predicate(this.session)) {
337
- unsub();
338
- resolve();
339
- }
340
- });
341
- });
342
- }
343
- /**
344
- * Re-evaluate every gate predicate against the current session and
345
- * resolve any whose predicate now returns true. Called after every
346
- * emitChange(), so gates unblock as soon as the session mutation
347
- * that satisfies them lands. Gates only resolve once — a predicate
348
- * that goes true → false → true will NOT re-block a caller that
349
- * already awaited through.
350
- */
351
- _checkGates() {
352
- for (const [, gate] of this._gates) if (!gate.resolved && gate.predicate(this.session)) {
353
- gate.resolved = true;
354
- gate.resolve();
355
- }
356
- }
357
- get session() {
358
- return this.$session.get();
359
- }
360
- set session(value) {
361
- this.$session.set(value);
362
- this.emitChange();
363
- }
364
- get statusMessages() {
365
- return this.$statusMessages.get();
366
- }
367
- get tasks() {
368
- return this.$tasks.get();
369
- }
370
- get eventPlan() {
371
- return this.$eventPlan.get();
372
- }
373
- get handoffText() {
374
- return this.$handoffText.get();
375
- }
376
- get currentStage() {
377
- return this.$currentStage.get();
378
- }
379
- /** No-op when the stage hasn't changed, so `startedAt` survives across
380
- * re-renders and tab switches and measures real stage time. */
381
- setCurrentStage(stage) {
382
- if (this.$currentStage.get()?.stage === stage) return;
383
- this.$currentStage.set({
384
- stage,
385
- startedAt: Date.now()
386
- });
387
- this.emitChange();
388
- }
389
- get statusExpanded() {
390
- return this.$statusExpanded.get();
391
- }
392
- toggleStatusExpanded() {
393
- this.$statusExpanded.set(!this.$statusExpanded.get());
394
- this.emitChange();
395
- }
396
- setStatusExpanded(expanded) {
397
- if (this.$statusExpanded.get() !== expanded) {
398
- this.$statusExpanded.set(expanded);
399
- this.emitChange();
400
- }
401
- }
402
- /** Sets setupConfirmed, and is the point consent becomes final. */
403
- completeSetup() {
404
- this.$session.setKey("setupConfirmed", true);
405
- this._markWarehouseSourcesReportedIfNeeded();
406
- analytics.wizardCapture("setup confirmed", sessionProperties(this.session));
407
- this.emitChange();
408
- }
409
- /**
410
- * Sharing is on: either the user turned it back on in the panel, or they
411
- * pressed Continue without ever touching it. Both are reversible until
412
- * completeSetup() resolves the intro gate and reports.
413
- */
414
- grantSharing() {
415
- this.$session.setKey("scanConsent", "granted");
416
- this.emitChange();
417
- }
418
- /**
419
- * Sharing is off. Suppresses reporting only — local detection still ran and
420
- * the results stay in the session, so the outro suggestion and the warehouse
421
- * task are unaffected; see `scanConsent` on `WizardSession`.
422
- *
423
- * Deliberately does not report. The panel's toggle can come back here, so
424
- * marking the run reported would strand a user who turns sharing off and
425
- * then on again. completeSetup() owns the single report.
426
- */
427
- declineSharing() {
428
- this.$session.setKey("scanConsent", "declined");
429
- this.emitChange();
430
- }
431
- /**
432
- * reportWarehouseSourcesDetected() is the single place scan results turn
433
- * into telemetry; this just supplies its idempotency flag via the normal
434
- * setter path (never mutate session directly). A no-op once
435
- * `warehouseSourcesReported` is set, or for any program that never
436
- * populated a warehouse-scan result in the first place.
437
- */
438
- _markWarehouseSourcesReportedIfNeeded() {
439
- if (reportWarehouseSourcesDetected(this.session)) this.$session.setKey("warehouseSourcesReported", true);
440
- }
441
- setRunPhase(phase) {
442
- this.$session.setKey("runPhase", phase);
443
- analytics.setTag("run_phase", phase);
444
- this.emitChange();
445
- }
446
- setCredentials(credentials) {
447
- this.$session.setKey("credentials", credentials);
448
- if (credentials?.projectId) analytics.setTag("project_id", credentials.projectId);
449
- analytics.wizardCapture("auth complete", { project_id: credentials?.projectId });
450
- this.emitChange();
451
- }
452
- /** Post-refresh credential swap. No `auth complete` — see WizardUI. */
453
- setAccessToken(credentials) {
454
- this.$session.setKey("credentials", credentials);
455
- this.emitChange();
456
- }
457
- setRoleAtOrganization(role) {
458
- this.$session.setKey("roleAtOrganization", role);
459
- this.emitChange();
460
- }
461
- setApiUser(user) {
462
- this.$session.setKey("apiUser", user);
463
- this.emitChange();
464
- }
465
- setFrameworkConfig(integration, config) {
466
- this.$session.setKey("integration", integration);
467
- this.$session.setKey("frameworkConfig", config);
468
- this.$session.setKey("unsupportedVersion", null);
469
- if (integration) analytics.setTag("integration", integration);
470
- this.emitChange();
471
- }
472
- setDetectionComplete() {
473
- this.$session.setKey("detectionComplete", true);
474
- this.emitChange();
475
- }
476
- setDetectedFramework(label) {
477
- this.$session.setKey("detectedFrameworkLabel", label);
478
- analytics.setTag("detected_framework", label);
479
- this.emitChange();
480
- }
481
- setPosthogSdkDetected(detected) {
482
- this.$session.setKey("posthogSdkDetected", detected);
483
- this.emitChange();
484
- }
485
- setSpellbook(spellbook) {
486
- this.$session.setKey("spellbook", spellbook);
487
- this.emitChange();
488
- }
489
- setMintHandoff(action) {
490
- this.cancelPendingQuestion();
491
- if (this.session.taskNotice) this.resolveTaskNotice(false);
492
- this.$session.setKey("mintHandoff", action);
493
- this.emitChange();
494
- }
495
- setSkillId(skillId) {
496
- this.$session.setKey("skillId", skillId);
497
- this.emitChange();
498
- }
499
- setUnsupportedVersion(info) {
500
- this.$session.setKey("unsupportedVersion", info);
501
- this.emitChange();
502
- }
503
- setLoginUrl(url) {
504
- this.$session.setKey("loginUrl", url);
505
- this.emitChange();
506
- }
507
- setAuthorizeUrl(url) {
508
- this.$session.setKey("authorizeUrl", url);
509
- this.emitChange();
510
- }
511
- setReadinessResult(result) {
512
- this.$session.setKey("readinessResult", result);
513
- if (result && result.decision === "no") captureHealthCheckBlocked(result);
514
- this.emitChange();
515
- }
516
- /** User dismissed the blocking outage screen. Gate resolves via _checkGates(). */
517
- dismissOutage() {
518
- logToFile("[health-checks] user dismissed outage screen, continuing");
519
- this.$session.setKey("outageDismissed", true);
520
- this.emitChange();
521
- }
522
- /**
523
- * Push the settings-override overlay and return a promise that blocks
524
- * until the user dismisses it via backupAndFixSettingsOverride().
525
- */
526
- showSettingsOverride(conflicts, backupAndFix) {
527
- const allKeys = conflicts.flatMap((c) => c.keys);
528
- this.$session.setKey("settingsOverrideKeys", allKeys);
529
- this.$session.setKey("settingsConflicts", conflicts);
530
- this._backupAndFixSettings = backupAndFix;
531
- if (conflicts.some((c) => !c.writable)) this.pushOverlay("managed-settings");
532
- else this.pushOverlay("settings-override");
533
- return new Promise((resolve) => {
534
- this._resolveSettingsOverride = resolve;
535
- });
536
- }
537
- /**
538
- * Push the port-conflict overlay and return a promise that blocks
539
- * until the user frees the ports and retries, or exits.
540
- */
541
- showPortConflict(processInfo) {
542
- this.$session.setKey("portConflictProcess", processInfo);
543
- this.pushOverlay("port-conflict");
544
- return new Promise((resolve) => {
545
- this._resolvePortConflict = resolve;
546
- });
547
- }
548
- /** Dismiss the port-conflict overlay and retry the OAuth port loop. */
549
- resolvePortConflict() {
550
- this.$session.setKey("portConflictProcess", null);
551
- this.popOverlay();
552
- this._resolvePortConflict?.();
553
- this._resolvePortConflict = null;
554
- }
555
- /**
556
- * Show an optional step's notice and return whether to keep that step.
557
- * Asked before the step runs, so nobody is surprised by a prompt mid-run.
558
- */
559
- showTaskNotice(notice) {
560
- this.$session.setKey("taskNotice", notice);
561
- this.pushOverlay("task-notice");
562
- return new Promise((resolve) => {
563
- this._resolveTaskNotice = resolve;
564
- });
565
- }
566
- /** Dismiss the notice, keeping (`true`) or skipping (`false`) the step. */
567
- resolveTaskNotice(keep) {
568
- this.$session.setKey("taskNotice", null);
569
- this.popOverlay();
570
- this._resolveTaskNotice?.(keep);
571
- this._resolveTaskNotice = null;
572
- }
573
- /**
574
- * Return a promise that resolves when the user submits a manually-entered
575
- * OAuth code via the paste modal. The OAuth flow races this against the
576
- * local callback server — see `performOAuthFlow`.
577
- */
578
- waitForManualAuthCode() {
579
- return new Promise((resolve) => {
580
- this._resolveManualAuthCode = resolve;
581
- });
582
- }
583
- /** Open the manual OAuth code-entry overlay over the auth screen. */
584
- showManualAuthCode() {
585
- this.pushOverlay("manual-auth-code");
586
- }
587
- /** Dismiss the manual OAuth code overlay without submitting. */
588
- dismissManualAuthCode() {
589
- this.popOverlay();
590
- }
591
- /**
592
- * Submit a manually-entered authorization code: dismiss the overlay and
593
- * resolve the in-flight OAuth flow so it can exchange the code for a token.
594
- */
595
- submitManualAuthCode(code) {
596
- this.popOverlay();
597
- this._resolveManualAuthCode?.(code);
598
- this._resolveManualAuthCode = null;
599
- }
600
- /**
601
- * Open the WizardAsk overlay with a set of questions and return a promise
602
- * that resolves once the user submits answers (or the request is cancelled).
603
- *
604
- * Only one request is in flight at a time — calling this while a request
605
- * is already pending throws.
606
- */
607
- requestQuestion(question, onAnswer) {
608
- if (this._resolvePendingQuestion) throw new Error("requestQuestion called while another wizard_ask request is pending");
609
- this._noteAskProgress = onAnswer ?? null;
610
- this.$session.setKey("pendingQuestion", question);
611
- this.pushOverlay("wizard-ask");
612
- analytics.wizardCapture("wizard_ask shown", {
613
- source: question.source,
614
- question_count: question.questions.length,
615
- kinds: question.questions.map((q) => q.kind)
616
- });
617
- return new Promise((resolve) => {
618
- this._resolvePendingQuestion = resolve;
619
- });
620
- }
621
- /**
622
- * Report that the user answered one question of the in-flight request and
623
- * another is coming — the ask bridge's timeout heartbeat.
624
- */
625
- noteAskProgress() {
626
- this._noteAskProgress?.();
627
- }
628
- /**
629
- * Resolve the in-flight wizard_ask request with the user's answers and
630
- * dismiss the overlay. Answers flow back to the agent as the tool result.
631
- */
632
- resolvePendingQuestion(answers) {
633
- const resolve = this._resolvePendingQuestion;
634
- this._resolvePendingQuestion = null;
635
- this._noteAskProgress = null;
636
- this.$session.setKey("pendingQuestion", null);
637
- this.popOverlay();
638
- resolve?.(answers);
639
- }
640
- /**
641
- * Cancel the in-flight wizard_ask request — the bridge sends a sentinel
642
- * answer ("__cancelled__") so the skill can decide how to handle it.
643
- */
644
- cancelPendingQuestion() {
645
- const pending = this.session.pendingQuestion;
646
- if (!pending) return;
647
- const cancelled = {};
648
- for (const q of pending.questions) cancelled[q.id] = "__cancelled__";
649
- this.resolvePendingQuestion(cancelled);
650
- }
651
- /**
652
- * Back up .claude/settings.json. Dismisses the overlay on success.
653
- */
654
- backupAndFixSettingsOverride() {
655
- const ok = this._backupAndFixSettings?.() ?? false;
656
- if (ok) {
657
- this.$session.setKey("settingsOverrideKeys", null);
658
- this.$session.setKey("settingsConflicts", null);
659
- this.popOverlay();
660
- this._resolveSettingsOverride?.();
661
- this._resolveSettingsOverride = null;
662
- this._backupAndFixSettings = null;
663
- }
664
- return ok;
665
- }
666
- /** Push the auth-error overlay (no dismiss — user must exit). */
667
- showAuthError(detail) {
668
- this.$session.setKey("authErrorDetail", detail ?? null);
669
- this.pushOverlay("auth-error");
670
- }
671
- /** Push the session-timeout overlay (no dismiss — user must exit). */
672
- showSessionTimeout() {
673
- this.pushOverlay("session-timeout");
674
- }
675
- addDiscoveredFeature(feature) {
676
- if (!this.session.discoveredFeatures.includes(feature)) {
677
- this.session.discoveredFeatures.push(feature);
678
- this.emitChange();
679
- }
680
- }
681
- setMcpComplete(outcome = "skipped", installedClients = [], featuresSelected, loginCommands = []) {
682
- this.$session.setKey("mcpComplete", true);
683
- this.$session.setKey("mcpOutcome", outcome);
684
- this.$session.setKey("mcpInstalledClients", installedClients);
685
- this.$session.setKey("mcpLoginCommands", loginCommands);
686
- const featuresPayload = outcome === "installed" && featuresSelected !== void 0 ? { mcp_features_selected: featuresSelected } : {};
687
- analytics.wizardCapture("mcp complete", {
688
- mcp_outcome: outcome,
689
- mcp_installed_clients: installedClients,
690
- ...featuresPayload,
691
- ...sessionProperties(this.session)
692
- });
693
- this.emitChange();
694
- }
695
- setSkillsComplete(kept) {
696
- this.$session.setKey("skillsComplete", true);
697
- analytics.wizardCapture("skills complete", {
698
- skills_kept: kept,
699
- ...sessionProperties(this.session)
700
- });
701
- this.emitChange();
702
- }
703
- setMcpSuggestedPromptsDismissed() {
704
- this.$session.setKey("mcpSuggestedPromptsDismissed", true);
705
- this.emitChange();
706
- }
707
- setSlackStepDismissed() {
708
- this.$session.setKey("slackStepDismissed", true);
709
- this.emitChange();
710
- }
711
- setSlackConnected(connected) {
712
- this.$session.setKey("slackConnected", connected);
713
- this.emitChange();
714
- }
715
- setGithubConnected(connected) {
716
- this.$session.setKey("githubConnected", connected);
717
- this.emitChange();
718
- }
719
- /**
720
- * Self-driving GitHub gate declined. Carries the outro the user lands on,
721
- * since declining ends the flow before the agent runs and there is no abort
722
- * case to render one.
723
- */
724
- declineGithub(outroData) {
725
- this.$session.setKey("githubDeclined", true);
726
- this.$session.setKey("outroData", outroData);
727
- this.emitChange();
728
- }
729
- /**
730
- * Self-driving integration-check answer. `true` → integrate the SDK as part
731
- * of this run; `false` → PostHog is already set up, go straight to
732
- * Self-driving. Resolves `session.integrate` from null.
733
- */
734
- setIntegrate(integrate, extra) {
735
- this.$session.setKey("integrate", integrate);
736
- analytics.wizardCapture("self-driving integration check", {
737
- self_driving_integrate: integrate,
738
- ...extra?.via ? { self_driving_integrate_via: extra.via } : {},
739
- ...extra?.path ? { self_driving_integrate_path: extra.path } : {},
740
- ...sessionProperties(this.session)
741
- });
742
- this.emitChange();
743
- }
744
- /**
745
- * Self-driving "no PostHog account" branch of the integration check. The
746
- * project has no SDK, so we always integrate (`integrate = true`); and since
747
- * the user has no account, we flip `signup` and record the `email` / `region`
748
- * collected on the screen so `authenticate` → `getOrAskForProjectData` takes
749
- * the provisioning path (create account + email a login link) instead of
750
- * OAuth. The "yes, I have an account" branch uses `setIntegrate(true)` and
751
- * leaves `signup` false so auth runs the normal OAuth login.
752
- */
753
- chooseProvisionAccount(email, region) {
754
- this.$session.setKey("signup", true);
755
- this.$session.setKey("email", email);
756
- this.$session.setKey("region", region);
757
- this.$session.setKey("integrate", true);
758
- analytics.wizardCapture("self-driving integration check", {
759
- self_driving_integrate: true,
760
- self_driving_has_account: false,
761
- provision_region: region,
762
- ...sessionProperties(this.session)
763
- });
764
- this.emitChange();
765
- }
766
- /**
767
- * Self-driving handoff confirmed — the user acknowledged the post-integration
768
- * screen, so the Self-driving run can begin. Gate resolves via _checkGates().
769
- */
770
- confirmSelfDrivingHandoff() {
771
- this.$session.setKey("selfDrivingHandoffConfirmed", true);
772
- this.emitChange();
773
- }
774
- /**
775
- * Mark a composed run step complete (e.g. self-driving's `integrate-run`).
776
- * Records the step id so its `isComplete` predicate holds, clears the task
777
- * list, and resets run phase to Idle so the next run step starts fresh.
778
- */
779
- completeRunStep(stepId) {
780
- const done = this.session.completedRuns;
781
- if (!done.includes(stepId)) this.$session.setKey("completedRuns", [...done, stepId]);
782
- this.$tasks.set([]);
783
- this.setRunPhase("idle");
784
- }
785
- setOutroDismissed(dismissed = true) {
786
- this.$session.setKey("outroDismissed", dismissed);
787
- this.emitChange();
788
- }
789
- setOutroData(data) {
790
- this.$session.setKey("outroData", data);
791
- this.emitChange();
792
- }
793
- setDashboardUrl(url) {
794
- logToFile(`store.setDashboardUrl: ${url}`);
795
- this.$session.setKey("dashboardUrl", url);
796
- this.emitChange();
797
- }
798
- setNotebookUrl(url) {
799
- logToFile(`store.setNotebookUrl: ${url}`);
800
- this.$session.setKey("notebookUrl", url);
801
- this.emitChange();
802
- }
803
- setFrameworkContext(key, value) {
804
- const ctx = {
805
- ...this.$session.get().frameworkContext,
806
- [key]: value
807
- };
808
- this.$session.setKey("frameworkContext", ctx);
809
- this.emitChange();
810
- }
811
- switchProgram(program) {
812
- if (program === this.router.activeProgram) return;
813
- for (const gate of this._gates.values()) gate.resolve();
814
- this._gates.clear();
815
- this.router.setProgram(program);
816
- this._initFromProgram(program);
817
- analytics.setTag("program_id", program);
818
- const config = getProgramConfig(program);
819
- this.$session.setKey("setupConfirmed", false);
820
- this.$session.setKey("programLabel", config.id);
821
- this.$session.setKey("skillId", config.skillId ?? null);
822
- this.emitChange();
823
- }
824
- /**
825
- * The screen that should be rendered right now.
826
- * Derived from session state via the router.
827
- */
828
- get currentScreen() {
829
- return this.router.resolve(this.session);
830
- }
831
- /** Direction hint for screen transitions. */
832
- get lastNavDirection() {
833
- return this.router.lastNavDirection;
834
- }
835
- getVersion() {
836
- return this.$version.get();
837
- }
838
- /**
839
- * Notify React that state has changed.
840
- * The router re-resolves the active screen on next render.
841
- * Gate predicates are checked and resolved if ready.
842
- */
843
- emitChange() {
844
- this.router._setDirection("push");
845
- this.$version.set(this.$version.get() + 1);
846
- this._checkGates();
847
- this._detectTransition();
848
- }
849
- pushOverlay(overlay) {
850
- this.router._setDirection("push");
851
- this.router.pushOverlay(overlay);
852
- this.$version.set(this.$version.get() + 1);
853
- this._detectTransition();
854
- }
855
- popOverlay() {
856
- this.router._setDirection("pop");
857
- this.router.popOverlay();
858
- this.$version.set(this.$version.get() + 1);
859
- this._detectTransition();
860
- }
861
- /**
862
- * Register a callback to run when transitioning onto the given screen.
863
- * Fires after every transition that lands on this screen.
864
- */
865
- onEnterScreen(screen, fn) {
866
- const list = this._enterScreenHooks.get(screen) ?? [];
867
- list.push(fn);
868
- this._enterScreenHooks.set(screen, list);
869
- }
870
- /**
871
- * The program `screen` reports under — its step's `reportsAsProgramId` if it
872
- * claims one, else the running program (also the fallback for overlays and
873
- * screens with no owning step).
874
- */
875
- _programIdForScreen(screen) {
876
- const program = this.router.activeProgram;
877
- return getProgramConfig(program).steps.find((s) => s.screenId === screen)?.reportsAsProgramId ?? program;
878
- }
879
- /** The program the visible screen reports under; screens stamp this on their
880
- * own events rather than relying on the run-level `program_id` tag. */
881
- get analyticsProgramId() {
882
- return this._programIdForScreen(this.router.resolve(this.session));
883
- }
884
- /**
885
- * Detect screen transitions, run enter-screen hooks, and fire analytics.
886
- * Called at the end of emitChange/pushOverlay/popOverlay.
887
- */
888
- _detectTransition() {
889
- const next = this.router.resolve(this.session);
890
- const prev = this._lastScreen;
891
- if (next !== prev) analytics.setTag("$screen_name", next);
892
- if (prev !== null && next !== prev) {
893
- const hooks = this._enterScreenHooks.get(next);
894
- if (hooks) for (const fn of hooks) fn();
895
- analytics.wizardCapture(`screen ${next}`, {
896
- from_screen: prev,
897
- program_id: this._programIdForScreen(next),
898
- ...sessionProperties(this.session)
899
- });
900
- }
901
- this._lastScreen = next;
902
- }
903
- pushStatus(message) {
904
- const msgs = this.$statusMessages.get();
905
- const next = appendStatus(msgs, message);
906
- if (next === msgs) return;
907
- this.$statusMessages.set(next);
908
- this.emitChange();
909
- }
910
- get tokenUsage() {
911
- return this.$tokenUsage.get();
912
- }
913
- get tokenHudVisible() {
914
- return this.$tokenHudVisible.get();
915
- }
916
- /** Hidden Ctrl+T shortcut — see ScreenContainer. Not registered as a
917
- * keyboard hint, so it never shows in the hints bar. */
918
- toggleTokenHud() {
919
- this.$tokenHudVisible.set(!this.$tokenHudVisible.get());
920
- this.emitChange();
921
- }
922
- /**
923
- * Accumulate one assistant turn's token usage into the running estimate.
924
- * Approximate by design (no dedup for SDK-retried/replayed turns, unlike
925
- * the benchmark middleware's TurnCounterPlugin) — it's a live indicator
926
- * for a hidden debug HUD, not a billing record, and `setFinalTokenCostUsd`
927
- * corrects the total once the run's authoritative cost is known.
928
- */
929
- addTokenUsage(delta) {
930
- const cur = this.$tokenUsage.get();
931
- if (cur.costIsFinal) return;
932
- const deltaCostUsd = computeTokenCostUsd(delta);
933
- this.$tokenUsage.set({
934
- inputTokens: cur.inputTokens + delta.inputTokens,
935
- outputTokens: cur.outputTokens + delta.outputTokens,
936
- cacheReadTokens: cur.cacheReadTokens + delta.cacheReadTokens,
937
- cacheCreationTokens: cur.cacheCreationTokens + delta.cacheCreationTokens,
938
- costUsd: cur.costUsd + deltaCostUsd,
939
- costIsFinal: false
940
- });
941
- this.emitChange();
942
- }
943
- /** Reconcile the running cost estimate to the SDK's authoritative total
944
- * once the agent run completes — same trick the benchmark's
945
- * CostTrackerPlugin.onFinalize uses to correct any per-turn drift. */
946
- setFinalTokenCostUsd(costUsd) {
947
- const cur = this.$tokenUsage.get();
948
- this.$tokenUsage.set({
949
- ...cur,
950
- costUsd,
951
- costIsFinal: true
952
- });
953
- this.emitChange();
954
- }
955
- setTasks(tasks) {
956
- this.$tasks.set(tasks);
957
- this.emitChange();
958
- }
959
- updateTask(index, done) {
960
- const tasks = this.$tasks.get();
961
- if (tasks[index]) {
962
- const updated = [...tasks];
963
- updated[index] = {
964
- ...updated[index],
965
- done,
966
- status: done ? "completed" : "pending"
967
- };
968
- this.$tasks.set(updated);
969
- this.emitChange();
970
- }
971
- }
972
- setEventPlan(events) {
973
- this.$eventPlan.set(events);
974
- this.emitChange();
975
- }
976
- /** No-op on identical text: an emit here means a network push downstream. */
977
- setHandoffText(text) {
978
- if (this.$handoffText.get() === text) return;
979
- logToFile(`store.setHandoffText: ${text.length} chars`);
980
- this.$handoffText.set(text);
981
- this.emitChange();
982
- }
983
- get learnCardBlockIdx() {
984
- return this.$learnCardBlockIdx.get();
985
- }
986
- setLearnCardBlockIdx(idx) {
987
- this.$learnCardBlockIdx.set(idx);
988
- }
989
- get learnCardComplete() {
990
- return this.$learnCardComplete.get();
991
- }
992
- setLearnCardComplete() {
993
- this.$learnCardComplete.set(true);
994
- this.emitChange();
995
- }
996
- syncTodos(todos) {
997
- const incoming = todos.map((t) => {
998
- const status = isTaskStatus(t.status) ? t.status : "pending";
999
- return {
1000
- id: t.id,
1001
- source: t.source,
1002
- sourceStatus: isTaskStatus(t.status) ? void 0 : t.status,
1003
- label: t.content,
1004
- activeForm: t.activeForm,
1005
- status,
1006
- done: status === "completed"
1007
- };
1008
- });
1009
- const incomingLabels = new Set(incoming.map((t) => t.label));
1010
- const sources = new Set(todos.map((t) => t.source));
1011
- const retained = this.$tasks.get().filter((t) => (t.status === "completed" || t.status === "failed" || t.status === "skipped") && (t.source ? !sources.has(t.source) : !incomingLabels.has(t.label)));
1012
- this.$tasks.set([...retained, ...incoming]);
1013
- this.emitChange();
1014
- this._onTasksChanged?.();
1015
- }
1016
- /** Register a listener for task state changes (e.g. task stream push). */
1017
- set onTasksChanged(fn) {
1018
- this._onTasksChanged = fn;
1019
- }
1020
- subscribe(callback) {
1021
- return this.$version.listen(() => callback());
1022
- }
1023
- getSnapshot() {
1024
- return this.$version.get();
1025
- }
1026
- };
1027
- //#endregion
1028
- export { totalTokenCount as n, WizardStore as t };
1029
-
1030
- //# sourceMappingURL=store-D3509G87.js.map