@posthog/wizard 2.8.0 → 2.9.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 (240) hide show
  1. package/README.md +11 -0
  2. package/dist/bin.js +286 -167
  3. package/dist/bin.js.map +1 -1
  4. package/dist/src/__tests__/cli.test.js +92 -59
  5. package/dist/src/__tests__/cli.test.js.map +1 -1
  6. package/dist/src/__tests__/wizard-abort.test.js +34 -13
  7. package/dist/src/__tests__/wizard-abort.test.js.map +1 -1
  8. package/dist/src/frameworks/android/android-wizard-agent.js +2 -2
  9. package/dist/src/frameworks/android/android-wizard-agent.js.map +1 -1
  10. package/dist/src/frameworks/angular/angular-wizard-agent.js +2 -2
  11. package/dist/src/frameworks/angular/angular-wizard-agent.js.map +1 -1
  12. package/dist/src/frameworks/astro/astro-wizard-agent.js +2 -2
  13. package/dist/src/frameworks/astro/astro-wizard-agent.js.map +1 -1
  14. package/dist/src/frameworks/django/django-wizard-agent.js +2 -2
  15. package/dist/src/frameworks/django/django-wizard-agent.js.map +1 -1
  16. package/dist/src/frameworks/fastapi/fastapi-wizard-agent.js +2 -2
  17. package/dist/src/frameworks/fastapi/fastapi-wizard-agent.js.map +1 -1
  18. package/dist/src/frameworks/flask/flask-wizard-agent.js +2 -2
  19. package/dist/src/frameworks/flask/flask-wizard-agent.js.map +1 -1
  20. package/dist/src/frameworks/javascript-node/javascript-node-wizard-agent.js +2 -2
  21. package/dist/src/frameworks/javascript-node/javascript-node-wizard-agent.js.map +1 -1
  22. package/dist/src/frameworks/javascript-web/javascript-web-wizard-agent.js +2 -2
  23. package/dist/src/frameworks/javascript-web/javascript-web-wizard-agent.js.map +1 -1
  24. package/dist/src/frameworks/laravel/laravel-wizard-agent.js +2 -2
  25. package/dist/src/frameworks/laravel/laravel-wizard-agent.js.map +1 -1
  26. package/dist/src/frameworks/nextjs/nextjs-wizard-agent.js +2 -2
  27. package/dist/src/frameworks/nextjs/nextjs-wizard-agent.js.map +1 -1
  28. package/dist/src/frameworks/nuxt/nuxt-wizard-agent.js +2 -2
  29. package/dist/src/frameworks/nuxt/nuxt-wizard-agent.js.map +1 -1
  30. package/dist/src/frameworks/python/python-wizard-agent.js +2 -2
  31. package/dist/src/frameworks/python/python-wizard-agent.js.map +1 -1
  32. package/dist/src/frameworks/rails/rails-wizard-agent.js +2 -2
  33. package/dist/src/frameworks/rails/rails-wizard-agent.js.map +1 -1
  34. package/dist/src/frameworks/react-native/react-native-wizard-agent.js +2 -2
  35. package/dist/src/frameworks/react-native/react-native-wizard-agent.js.map +1 -1
  36. package/dist/src/frameworks/react-router/react-router-wizard-agent.js +2 -2
  37. package/dist/src/frameworks/react-router/react-router-wizard-agent.js.map +1 -1
  38. package/dist/src/frameworks/ruby/ruby-wizard-agent.js +2 -2
  39. package/dist/src/frameworks/ruby/ruby-wizard-agent.js.map +1 -1
  40. package/dist/src/frameworks/svelte/svelte-wizard-agent.js +2 -2
  41. package/dist/src/frameworks/svelte/svelte-wizard-agent.js.map +1 -1
  42. package/dist/src/frameworks/swift/swift-wizard-agent.js +2 -2
  43. package/dist/src/frameworks/swift/swift-wizard-agent.js.map +1 -1
  44. package/dist/src/frameworks/tanstack-router/tanstack-router-wizard-agent.js +2 -2
  45. package/dist/src/frameworks/tanstack-router/tanstack-router-wizard-agent.js.map +1 -1
  46. package/dist/src/frameworks/tanstack-start/tanstack-start-wizard-agent.js +2 -2
  47. package/dist/src/frameworks/tanstack-start/tanstack-start-wizard-agent.js.map +1 -1
  48. package/dist/src/frameworks/vue/vue-wizard-agent.js +2 -2
  49. package/dist/src/frameworks/vue/vue-wizard-agent.js.map +1 -1
  50. package/dist/src/lib/__tests__/agent-interface.test.js +29 -1
  51. package/dist/src/lib/__tests__/agent-interface.test.js.map +1 -1
  52. package/dist/src/lib/agent/__tests__/agent-prompt.test.js +57 -0
  53. package/dist/src/lib/agent/__tests__/agent-prompt.test.js.map +1 -0
  54. package/dist/src/lib/{agent-interface.d.ts → agent/agent-interface.d.ts} +18 -6
  55. package/dist/src/lib/{agent-interface.js → agent/agent-interface.js} +63 -13
  56. package/dist/src/lib/agent/agent-interface.js.map +1 -0
  57. package/dist/src/lib/agent/agent-prompt.d.ts +23 -0
  58. package/dist/src/lib/agent/agent-prompt.js +47 -0
  59. package/dist/src/lib/agent/agent-prompt.js.map +1 -0
  60. package/dist/src/lib/agent/agent-runner.d.ts +78 -0
  61. package/dist/src/lib/agent/agent-runner.js +325 -0
  62. package/dist/src/lib/agent/agent-runner.js.map +1 -0
  63. package/dist/src/lib/agent/commandments.js.map +1 -0
  64. package/dist/src/lib/constants.d.ts +10 -1
  65. package/dist/src/lib/constants.js +13 -1
  66. package/dist/src/lib/constants.js.map +1 -1
  67. package/dist/src/lib/detection/__tests__/context.test.js +72 -0
  68. package/dist/src/lib/detection/__tests__/context.test.js.map +1 -0
  69. package/dist/src/lib/detection/__tests__/features.test.d.ts +1 -0
  70. package/dist/src/lib/detection/__tests__/features.test.js +75 -0
  71. package/dist/src/lib/detection/__tests__/features.test.js.map +1 -0
  72. package/dist/src/lib/detection/__tests__/package-manager.test.d.ts +1 -0
  73. package/dist/src/lib/{__tests__/package-manager-detection.test.js → detection/__tests__/package-manager.test.js} +25 -25
  74. package/dist/src/lib/detection/__tests__/package-manager.test.js.map +1 -0
  75. package/dist/src/lib/detection/context.d.ts +31 -0
  76. package/dist/src/lib/detection/context.js +92 -0
  77. package/dist/src/lib/detection/context.js.map +1 -0
  78. package/dist/src/lib/detection/features.d.ts +16 -0
  79. package/dist/src/lib/detection/features.js +56 -0
  80. package/dist/src/lib/detection/features.js.map +1 -0
  81. package/dist/src/lib/detection/framework.d.ts +14 -0
  82. package/dist/src/lib/detection/framework.js +35 -0
  83. package/dist/src/lib/detection/framework.js.map +1 -0
  84. package/dist/src/lib/detection/index.d.ts +3 -0
  85. package/dist/src/lib/detection/index.js +11 -0
  86. package/dist/src/lib/detection/index.js.map +1 -0
  87. package/dist/src/lib/{package-manager-detection.js → detection/package-manager.js} +3 -3
  88. package/dist/src/lib/detection/package-manager.js.map +1 -0
  89. package/dist/src/lib/framework-config.d.ts +1 -1
  90. package/dist/src/lib/framework-config.js.map +1 -1
  91. package/dist/src/lib/health-checks/endpoints.js +2 -1
  92. package/dist/src/lib/health-checks/endpoints.js.map +1 -1
  93. package/dist/src/lib/middleware/benchmark.js +1 -1
  94. package/dist/src/lib/middleware/benchmark.js.map +1 -1
  95. package/dist/src/lib/middleware/benchmarks/compaction-tracker.js +1 -1
  96. package/dist/src/lib/middleware/benchmarks/compaction-tracker.js.map +1 -1
  97. package/dist/src/lib/middleware/benchmarks/json-writer.js +1 -1
  98. package/dist/src/lib/middleware/benchmarks/json-writer.js.map +1 -1
  99. package/dist/src/lib/middleware/benchmarks/summary.js +1 -1
  100. package/dist/src/lib/middleware/benchmarks/summary.js.map +1 -1
  101. package/dist/src/lib/middleware/config.js +1 -1
  102. package/dist/src/lib/middleware/config.js.map +1 -1
  103. package/dist/src/lib/version.d.ts +1 -1
  104. package/dist/src/lib/version.js +1 -1
  105. package/dist/src/lib/version.js.map +1 -1
  106. package/dist/src/lib/wizard-session.d.ts +16 -7
  107. package/dist/src/lib/wizard-session.js +2 -0
  108. package/dist/src/lib/wizard-session.js.map +1 -1
  109. package/dist/src/lib/wizard-tools.d.ts +28 -1
  110. package/dist/src/lib/wizard-tools.js +24 -0
  111. package/dist/src/lib/wizard-tools.js.map +1 -1
  112. package/dist/src/lib/workflows/__tests__/agent-skill.test.d.ts +1 -0
  113. package/dist/src/lib/workflows/__tests__/agent-skill.test.js +73 -0
  114. package/dist/src/lib/workflows/__tests__/agent-skill.test.js.map +1 -0
  115. package/dist/src/lib/workflows/__tests__/revenue-analytics-detect.test.d.ts +1 -0
  116. package/dist/src/lib/workflows/__tests__/revenue-analytics-detect.test.js +101 -0
  117. package/dist/src/lib/workflows/__tests__/revenue-analytics-detect.test.js.map +1 -0
  118. package/dist/src/lib/workflows/__tests__/workflow-registry.test.d.ts +1 -0
  119. package/dist/src/lib/workflows/__tests__/workflow-registry.test.js +32 -0
  120. package/dist/src/lib/workflows/__tests__/workflow-registry.test.js.map +1 -0
  121. package/dist/src/lib/workflows/__tests__/workflow-step.test.d.ts +1 -0
  122. package/dist/src/lib/workflows/__tests__/workflow-step.test.js +54 -0
  123. package/dist/src/lib/workflows/__tests__/workflow-step.test.js.map +1 -0
  124. package/dist/src/lib/workflows/agent-skill/index.d.ts +44 -0
  125. package/dist/src/lib/workflows/agent-skill/index.js +47 -0
  126. package/dist/src/lib/workflows/agent-skill/index.js.map +1 -0
  127. package/dist/src/lib/workflows/agent-skill/steps.d.ts +8 -0
  128. package/dist/src/lib/workflows/agent-skill/steps.js +43 -0
  129. package/dist/src/lib/workflows/agent-skill/steps.js.map +1 -0
  130. package/dist/src/lib/workflows/posthog-integration/detect.d.ts +12 -0
  131. package/dist/src/lib/workflows/posthog-integration/detect.js +57 -0
  132. package/dist/src/lib/workflows/posthog-integration/detect.js.map +1 -0
  133. package/dist/src/lib/workflows/posthog-integration/index.d.ts +3 -0
  134. package/dist/src/lib/workflows/posthog-integration/index.js +152 -0
  135. package/dist/src/lib/workflows/posthog-integration/index.js.map +1 -0
  136. package/dist/src/lib/workflows/posthog-integration/steps.d.ts +9 -0
  137. package/dist/src/lib/workflows/posthog-integration/steps.js +100 -0
  138. package/dist/src/lib/workflows/posthog-integration/steps.js.map +1 -0
  139. package/dist/src/lib/workflows/revenue-analytics/detect.d.ts +40 -0
  140. package/dist/src/lib/workflows/revenue-analytics/detect.js +156 -0
  141. package/dist/src/lib/workflows/revenue-analytics/detect.js.map +1 -0
  142. package/dist/src/lib/workflows/revenue-analytics/index.d.ts +4 -0
  143. package/dist/src/lib/workflows/revenue-analytics/index.js +30 -0
  144. package/dist/src/lib/workflows/revenue-analytics/index.js.map +1 -0
  145. package/dist/src/lib/workflows/revenue-analytics/steps.d.ts +8 -0
  146. package/dist/src/lib/workflows/revenue-analytics/steps.js +53 -0
  147. package/dist/src/lib/workflows/revenue-analytics/steps.js.map +1 -0
  148. package/dist/src/lib/workflows/workflow-registry.d.ts +18 -0
  149. package/dist/src/lib/workflows/workflow-registry.js +32 -0
  150. package/dist/src/lib/workflows/workflow-registry.js.map +1 -0
  151. package/dist/src/lib/workflows/workflow-step.d.ts +126 -0
  152. package/dist/src/lib/workflows/workflow-step.js +28 -0
  153. package/dist/src/lib/workflows/workflow-step.js.map +1 -0
  154. package/dist/src/steps/add-mcp-server-to-clients/index.d.ts +2 -1
  155. package/dist/src/steps/add-mcp-server-to-clients/index.js.map +1 -1
  156. package/dist/src/ui/logging-ui.d.ts +6 -3
  157. package/dist/src/ui/logging-ui.js +7 -0
  158. package/dist/src/ui/logging-ui.js.map +1 -1
  159. package/dist/src/ui/tui/__tests__/flows.test.d.ts +1 -0
  160. package/dist/src/ui/tui/__tests__/flows.test.js +115 -0
  161. package/dist/src/ui/tui/__tests__/flows.test.js.map +1 -0
  162. package/dist/src/ui/tui/__tests__/router.test.d.ts +1 -0
  163. package/dist/src/ui/tui/__tests__/router.test.js +87 -0
  164. package/dist/src/ui/tui/__tests__/router.test.js.map +1 -0
  165. package/dist/src/ui/tui/__tests__/store.test.js +149 -13
  166. package/dist/src/ui/tui/__tests__/store.test.js.map +1 -1
  167. package/dist/src/ui/tui/flows.d.ts +19 -7
  168. package/dist/src/ui/tui/flows.js +30 -53
  169. package/dist/src/ui/tui/flows.js.map +1 -1
  170. package/dist/src/ui/tui/ink-ui.d.ts +6 -3
  171. package/dist/src/ui/tui/ink-ui.js +7 -0
  172. package/dist/src/ui/tui/ink-ui.js.map +1 -1
  173. package/dist/src/ui/tui/playground/PlaygroundApp.js +6 -0
  174. package/dist/src/ui/tui/playground/PlaygroundApp.js.map +1 -1
  175. package/dist/src/ui/tui/playground/demos/McpDemo.d.ts +12 -0
  176. package/dist/src/ui/tui/playground/demos/McpDemo.js +27 -0
  177. package/dist/src/ui/tui/playground/demos/McpDemo.js.map +1 -0
  178. package/dist/src/ui/tui/router.js +1 -1
  179. package/dist/src/ui/tui/router.js.map +1 -1
  180. package/dist/src/ui/tui/screen-registry.js +8 -4
  181. package/dist/src/ui/tui/screen-registry.js.map +1 -1
  182. package/dist/src/ui/tui/screens/AgentSkillIntroScreen.d.ts +12 -0
  183. package/dist/src/ui/tui/screens/AgentSkillIntroScreen.js +75 -0
  184. package/dist/src/ui/tui/screens/AgentSkillIntroScreen.js.map +1 -0
  185. package/dist/src/ui/tui/screens/IntroScreenLayout.d.ts +46 -0
  186. package/dist/src/ui/tui/screens/IntroScreenLayout.js +33 -0
  187. package/dist/src/ui/tui/screens/IntroScreenLayout.js.map +1 -0
  188. package/dist/src/ui/tui/screens/{SkillsScreen.d.ts → KeepSkillsScreen.d.ts} +3 -3
  189. package/dist/src/ui/tui/screens/{SkillsScreen.js → KeepSkillsScreen.js} +8 -5
  190. package/dist/src/ui/tui/screens/KeepSkillsScreen.js.map +1 -0
  191. package/dist/src/ui/tui/screens/ManagedSettingsScreen.js.map +1 -1
  192. package/dist/src/ui/tui/screens/McpScreen.js +4 -1
  193. package/dist/src/ui/tui/screens/McpScreen.js.map +1 -1
  194. package/dist/src/ui/tui/screens/OutroScreen.js +1 -1
  195. package/dist/src/ui/tui/screens/OutroScreen.js.map +1 -1
  196. package/dist/src/ui/tui/screens/PostHogIntegrationIntroScreen.d.ts +15 -0
  197. package/dist/src/ui/tui/screens/PostHogIntegrationIntroScreen.js +135 -0
  198. package/dist/src/ui/tui/screens/PostHogIntegrationIntroScreen.js.map +1 -0
  199. package/dist/src/ui/tui/screens/RevenueIntroScreen.d.ts +16 -0
  200. package/dist/src/ui/tui/screens/RevenueIntroScreen.js +89 -0
  201. package/dist/src/ui/tui/screens/RevenueIntroScreen.js.map +1 -0
  202. package/dist/src/ui/tui/screens/SettingsOverrideScreen.js.map +1 -1
  203. package/dist/src/ui/tui/screens/health/HealthCheckScreen.js +2 -2
  204. package/dist/src/ui/tui/screens/health/HealthCheckScreen.js.map +1 -1
  205. package/dist/src/ui/tui/start-tui.js +2 -2
  206. package/dist/src/ui/tui/start-tui.js.map +1 -1
  207. package/dist/src/ui/tui/store.d.ts +46 -21
  208. package/dist/src/ui/tui/store.js +107 -47
  209. package/dist/src/ui/tui/store.js.map +1 -1
  210. package/dist/src/ui/wizard-ui.d.ts +13 -3
  211. package/dist/src/ui/wizard-ui.js.map +1 -1
  212. package/dist/src/utils/file-utils.d.ts +8 -0
  213. package/dist/src/utils/file-utils.js +32 -0
  214. package/dist/src/utils/file-utils.js.map +1 -1
  215. package/dist/src/utils/wizard-abort.d.ts +3 -0
  216. package/dist/src/utils/wizard-abort.js +5 -3
  217. package/dist/src/utils/wizard-abort.js.map +1 -1
  218. package/npm-shrinkwrap.json +2 -2
  219. package/package.json +1 -1
  220. package/dist/src/__tests__/run.test.js +0 -95
  221. package/dist/src/__tests__/run.test.js.map +0 -1
  222. package/dist/src/lib/__tests__/package-manager-detection.test.js.map +0 -1
  223. package/dist/src/lib/agent-interface.js.map +0 -1
  224. package/dist/src/lib/agent-runner.d.ts +0 -9
  225. package/dist/src/lib/agent-runner.js +0 -385
  226. package/dist/src/lib/agent-runner.js.map +0 -1
  227. package/dist/src/lib/commandments.js.map +0 -1
  228. package/dist/src/lib/package-manager-detection.js.map +0 -1
  229. package/dist/src/run.d.ts +0 -23
  230. package/dist/src/run.js +0 -154
  231. package/dist/src/run.js.map +0 -1
  232. package/dist/src/ui/tui/screens/IntroScreen.d.ts +0 -16
  233. package/dist/src/ui/tui/screens/IntroScreen.js +0 -79
  234. package/dist/src/ui/tui/screens/IntroScreen.js.map +0 -1
  235. package/dist/src/ui/tui/screens/SkillsScreen.js.map +0 -1
  236. /package/dist/src/{__tests__/run.test.d.ts → lib/agent/__tests__/agent-prompt.test.d.ts} +0 -0
  237. /package/dist/src/lib/{commandments.d.ts → agent/commandments.d.ts} +0 -0
  238. /package/dist/src/lib/{commandments.js → agent/commandments.js} +0 -0
  239. /package/dist/src/lib/{__tests__/package-manager-detection.test.d.ts → detection/__tests__/context.test.d.ts} +0 -0
  240. /package/dist/src/lib/{package-manager-detection.d.ts → detection/package-manager.d.ts} +0 -0
@@ -0,0 +1,87 @@
1
+ import { buildSession, RunPhase } from '../../../lib/wizard-session.js';
2
+ import { WizardReadiness } from '../../../lib/health-checks/readiness.js';
3
+ import { WizardRouter, Flow, Screen, Overlay } from '../router.js';
4
+ function baseWizardSession() {
5
+ return buildSession({});
6
+ }
7
+ describe('WizardRouter', () => {
8
+ describe('resolve', () => {
9
+ it('returns the first incomplete visible screen for the wizard flow', () => {
10
+ const router = new WizardRouter(Flow.PostHogIntegration);
11
+ const session = baseWizardSession();
12
+ expect(router.resolve(session)).toBe(Screen.Intro);
13
+ session.setupConfirmed = true;
14
+ session.readinessResult = {
15
+ decision: WizardReadiness.Yes,
16
+ health: {},
17
+ reasons: [],
18
+ };
19
+ session.credentials = {
20
+ accessToken: 'tok',
21
+ projectApiKey: 'pk',
22
+ host: 'https://app.posthog.com',
23
+ projectId: 1,
24
+ };
25
+ expect(router.resolve(session)).toBe(Screen.Run);
26
+ });
27
+ it('skips the setup screen when there are no unanswered framework questions', () => {
28
+ const router = new WizardRouter(Flow.PostHogIntegration);
29
+ const session = baseWizardSession();
30
+ session.setupConfirmed = true;
31
+ session.readinessResult = {
32
+ decision: WizardReadiness.Yes,
33
+ health: {},
34
+ reasons: [],
35
+ };
36
+ session.frameworkConfig = {
37
+ metadata: {
38
+ setup: {
39
+ questions: [{ key: 'packageManager' }],
40
+ },
41
+ },
42
+ };
43
+ session.frameworkContext = { packageManager: 'pnpm' };
44
+ expect(router.resolve(session)).toBe(Screen.Auth);
45
+ });
46
+ it('returns the last flow screen when every entry is complete', () => {
47
+ const router = new WizardRouter(Flow.PostHogIntegration);
48
+ const session = baseWizardSession();
49
+ session.setupConfirmed = true;
50
+ session.readinessResult = {
51
+ decision: WizardReadiness.Yes,
52
+ health: {},
53
+ reasons: [],
54
+ };
55
+ session.credentials = {
56
+ accessToken: 'tok',
57
+ projectApiKey: 'pk',
58
+ host: 'https://app.posthog.com',
59
+ projectId: 1,
60
+ };
61
+ session.runPhase = RunPhase.Completed;
62
+ session.mcpComplete = true;
63
+ expect(router.resolve(session)).toBe(Screen.Outro);
64
+ });
65
+ it('gives the topmost overlay precedence over the flow screen', () => {
66
+ const router = new WizardRouter(Flow.PostHogIntegration);
67
+ const session = baseWizardSession();
68
+ router.pushOverlay(Overlay.SettingsOverride);
69
+ router.pushOverlay(Overlay.AuthError);
70
+ expect(router.resolve(session)).toBe(Overlay.AuthError);
71
+ router.popOverlay();
72
+ expect(router.resolve(session)).toBe(Overlay.SettingsOverride);
73
+ });
74
+ });
75
+ describe('activeScreen', () => {
76
+ it('defaults to the first screen in the active flow', () => {
77
+ const router = new WizardRouter(Flow.McpRemove);
78
+ expect(router.activeScreen).toBe(Screen.McpRemove);
79
+ });
80
+ it('returns the top overlay when overlays are active', () => {
81
+ const router = new WizardRouter(Flow.PostHogIntegration);
82
+ router.pushOverlay(Overlay.ManagedSettings);
83
+ expect(router.activeScreen).toBe(Overlay.ManagedSettings);
84
+ });
85
+ });
86
+ });
87
+ //# sourceMappingURL=router.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"router.test.js","sourceRoot":"","sources":["../../../../../src/ui/tui/__tests__/router.test.ts"],"names":[],"mappings":"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","sourcesContent":["import { buildSession, RunPhase } from '../../../lib/wizard-session.js';\nimport { WizardReadiness } from '../../../lib/health-checks/readiness.js';\nimport { WizardRouter, Flow, Screen, Overlay } from '../router.js';\n\nfunction baseWizardSession() {\n return buildSession({});\n}\n\ndescribe('WizardRouter', () => {\n describe('resolve', () => {\n it('returns the first incomplete visible screen for the wizard flow', () => {\n const router = new WizardRouter(Flow.PostHogIntegration);\n const session = baseWizardSession();\n\n expect(router.resolve(session)).toBe(Screen.Intro);\n\n session.setupConfirmed = true;\n session.readinessResult = {\n decision: WizardReadiness.Yes,\n health: {} as never,\n reasons: [],\n };\n session.credentials = {\n accessToken: 'tok',\n projectApiKey: 'pk',\n host: 'https://app.posthog.com',\n projectId: 1,\n };\n\n expect(router.resolve(session)).toBe(Screen.Run);\n });\n\n it('skips the setup screen when there are no unanswered framework questions', () => {\n const router = new WizardRouter(Flow.PostHogIntegration);\n const session = baseWizardSession();\n\n session.setupConfirmed = true;\n session.readinessResult = {\n decision: WizardReadiness.Yes,\n health: {} as never,\n reasons: [],\n };\n session.frameworkConfig = {\n metadata: {\n setup: {\n questions: [{ key: 'packageManager' }],\n },\n },\n } as never;\n session.frameworkContext = { packageManager: 'pnpm' };\n\n expect(router.resolve(session)).toBe(Screen.Auth);\n });\n\n it('returns the last flow screen when every entry is complete', () => {\n const router = new WizardRouter(Flow.PostHogIntegration);\n const session = baseWizardSession();\n\n session.setupConfirmed = true;\n session.readinessResult = {\n decision: WizardReadiness.Yes,\n health: {} as never,\n reasons: [],\n };\n session.credentials = {\n accessToken: 'tok',\n projectApiKey: 'pk',\n host: 'https://app.posthog.com',\n projectId: 1,\n };\n session.runPhase = RunPhase.Completed;\n session.mcpComplete = true;\n\n expect(router.resolve(session)).toBe(Screen.Outro);\n });\n\n it('gives the topmost overlay precedence over the flow screen', () => {\n const router = new WizardRouter(Flow.PostHogIntegration);\n const session = baseWizardSession();\n\n router.pushOverlay(Overlay.SettingsOverride);\n router.pushOverlay(Overlay.AuthError);\n\n expect(router.resolve(session)).toBe(Overlay.AuthError);\n\n router.popOverlay();\n expect(router.resolve(session)).toBe(Overlay.SettingsOverride);\n });\n });\n\n describe('activeScreen', () => {\n it('defaults to the first screen in the active flow', () => {\n const router = new WizardRouter(Flow.McpRemove);\n\n expect(router.activeScreen).toBe(Screen.McpRemove);\n });\n\n it('returns the top overlay when overlays are active', () => {\n const router = new WizardRouter(Flow.PostHogIntegration);\n\n router.pushOverlay(Overlay.ManagedSettings);\n\n expect(router.activeScreen).toBe(Overlay.ManagedSettings);\n });\n });\n});\n"]}
@@ -1,6 +1,6 @@
1
1
  import { WizardStore, TaskStatus, Flow, Screen, Overlay, RunPhase, McpOutcome, } from '../store.js';
2
2
  import { OutroKind, AdditionalFeature } from '../../../lib/wizard-session.js';
3
- import { WizardReadiness } from '../../../lib/health-checks/readiness.js';
3
+ import { WizardReadiness, evaluateWizardReadiness, } from '../../../lib/health-checks/readiness.js';
4
4
  import { buildSession } from '../../../lib/wizard-session.js';
5
5
  import { Integration } from '../../../lib/constants.js';
6
6
  import { analytics } from '../../../utils/analytics.js';
@@ -30,9 +30,19 @@ function createStore(flow) {
30
30
  return new WizardStore(flow);
31
31
  }
32
32
  const wizardCaptureMock = analytics.wizardCapture;
33
+ const evaluateWizardReadinessMock = evaluateWizardReadiness;
34
+ async function flushMicrotasks() {
35
+ await Promise.resolve();
36
+ await Promise.resolve();
37
+ }
33
38
  describe('WizardStore', () => {
34
39
  beforeEach(() => {
35
40
  jest.clearAllMocks();
41
+ evaluateWizardReadinessMock.mockResolvedValue({
42
+ decision: WizardReadiness.Yes,
43
+ health: {},
44
+ reasons: [],
45
+ });
36
46
  });
37
47
  // ── Construction ─────────────────────────────────────────────────
38
48
  describe('constructor', () => {
@@ -45,7 +55,7 @@ describe('WizardStore', () => {
45
55
  });
46
56
  it('defaults to Wizard flow', () => {
47
57
  const store = createStore();
48
- expect(store.router.activeFlow).toBe(Flow.Wizard);
58
+ expect(store.router.activeFlow).toBe(Flow.PostHogIntegration);
49
59
  });
50
60
  it('accepts a custom flow', () => {
51
61
  const store = createStore(Flow.McpAdd);
@@ -112,13 +122,13 @@ describe('WizardStore', () => {
112
122
  });
113
123
  // ── Session setters ──────────────────────────────────────────────
114
124
  describe('session setters', () => {
115
- it('completeSetup sets setupConfirmed and resolves setupComplete promise', async () => {
125
+ it('completeSetup sets setupConfirmed and resolves intro gate', async () => {
116
126
  const store = createStore();
117
127
  const cb = jest.fn();
118
128
  store.subscribe(cb);
119
129
  store.completeSetup();
120
130
  expect(store.session.setupConfirmed).toBe(true);
121
- await store.setupComplete;
131
+ await store.getGate('intro');
122
132
  expect(cb).toHaveBeenCalled();
123
133
  });
124
134
  it('setRunPhase updates session.runPhase', () => {
@@ -342,7 +352,7 @@ describe('WizardStore', () => {
342
352
  store.setRunPhase(RunPhase.Completed);
343
353
  store.setMcpComplete();
344
354
  store.setOutroDismissed();
345
- expect(store.currentScreen).toBe(Screen.Skills);
355
+ expect(store.currentScreen).toBe(Screen.KeepSkills);
346
356
  });
347
357
  it('starts at McpAdd for McpAdd flow', () => {
348
358
  const store = createStore(Flow.McpAdd);
@@ -720,7 +730,7 @@ describe('WizardStore', () => {
720
730
  const store = createStore();
721
731
  store.completeSetup();
722
732
  store.completeSetup(); // second call — promise already resolved
723
- await store.setupComplete;
733
+ await store.getGate('intro');
724
734
  expect(store.session.setupConfirmed).toBe(true);
725
735
  });
726
736
  it('version property (string) is independent from internal _version counter', () => {
@@ -735,7 +745,7 @@ describe('WizardStore', () => {
735
745
  });
736
746
  // ── Full wizard flow simulation ──────────────────────────────────
737
747
  describe('full wizard flow', () => {
738
- it('walks through the entire wizard flow correctly', () => {
748
+ it('walks through the posthog integration flow correctly', () => {
739
749
  const store = createStore();
740
750
  const screenHistory = [];
741
751
  store.subscribe(() => screenHistory.push(store.currentScreen));
@@ -768,30 +778,156 @@ describe('WizardStore', () => {
768
778
  expect(store.currentScreen).toBe(Screen.Outro);
769
779
  // Step 6: Dismiss outro
770
780
  store.setOutroDismissed();
771
- expect(store.currentScreen).toBe(Screen.Skills);
781
+ expect(store.currentScreen).toBe(Screen.KeepSkills);
772
782
  // Verify version was bumped for each setter call
773
783
  expect(store.getVersion()).toBe(7);
774
784
  });
785
+ it('walks through the revenue analytics flow correctly', () => {
786
+ const store = createStore(Flow.RevenueAnalyticsSetup);
787
+ expect(store.currentScreen).toBe(Screen.RevenueIntro);
788
+ // Step 1: Confirm intro
789
+ store.completeSetup();
790
+ expect(store.currentScreen).toBe(Screen.Auth);
791
+ // Step 2: Authenticate
792
+ store.setCredentials({
793
+ accessToken: 'tok',
794
+ projectApiKey: 'pk',
795
+ host: 'https://app.posthog.com',
796
+ projectId: 1,
797
+ });
798
+ expect(store.currentScreen).toBe(Screen.Run);
799
+ // Step 3: Start and complete run
800
+ store.setRunPhase(RunPhase.Running);
801
+ expect(store.currentScreen).toBe(Screen.Run);
802
+ store.setRunPhase(RunPhase.Completed);
803
+ expect(store.currentScreen).toBe(Screen.Outro);
804
+ // Step 4: Dismiss outro
805
+ store.setOutroDismissed();
806
+ expect(store.currentScreen).toBe('skills');
807
+ });
808
+ it('walks through the agent skill flow correctly', () => {
809
+ const store = createStore(Flow.AgentSkill);
810
+ expect(store.currentScreen).toBe(Screen.AgentSkillIntro);
811
+ // Step 1: Confirm intro
812
+ store.completeSetup();
813
+ expect(store.currentScreen).toBe(Screen.Auth);
814
+ // Step 2: Authenticate
815
+ store.setCredentials({
816
+ accessToken: 'tok',
817
+ projectApiKey: 'pk',
818
+ host: 'https://app.posthog.com',
819
+ projectId: 1,
820
+ });
821
+ expect(store.currentScreen).toBe(Screen.Run);
822
+ // Step 3: Start and complete run
823
+ store.setRunPhase(RunPhase.Running);
824
+ expect(store.currentScreen).toBe(Screen.Run);
825
+ store.setRunPhase(RunPhase.Completed);
826
+ expect(store.currentScreen).toBe(Screen.Outro);
827
+ // Step 4: Dismiss outro
828
+ store.setOutroDismissed();
829
+ expect(store.currentScreen).toBe('skills');
830
+ });
831
+ });
832
+ // ── health-check gate ────────────────────────────────────────────
833
+ describe('health-check gate', () => {
834
+ it('resolves immediately for non-Wizard flows', async () => {
835
+ const store = createStore(Flow.McpAdd);
836
+ await expect(store.getGate('health-check')).resolves.toBeUndefined();
837
+ });
838
+ it('resolves automatically when readiness is non-blocking', async () => {
839
+ evaluateWizardReadinessMock.mockResolvedValueOnce({
840
+ decision: WizardReadiness.Yes,
841
+ health: {},
842
+ reasons: [],
843
+ });
844
+ const store = createStore();
845
+ let resolved = false;
846
+ void store.getGate('health-check').then(() => {
847
+ resolved = true;
848
+ });
849
+ await flushMicrotasks();
850
+ expect(resolved).toBe(true);
851
+ expect(store.session.readinessResult).toEqual({
852
+ decision: WizardReadiness.Yes,
853
+ health: {},
854
+ reasons: [],
855
+ });
856
+ });
857
+ it('stays pending for blocking readiness until outage is dismissed', async () => {
858
+ evaluateWizardReadinessMock.mockResolvedValueOnce({
859
+ decision: WizardReadiness.No,
860
+ health: {},
861
+ reasons: ['Anthropic: down'],
862
+ });
863
+ const store = createStore();
864
+ let resolved = false;
865
+ void store.getGate('health-check').then(() => {
866
+ resolved = true;
867
+ });
868
+ await flushMicrotasks();
869
+ expect(resolved).toBe(false);
870
+ expect(store.currentScreen).toBe(Screen.Intro);
871
+ store.dismissOutage();
872
+ await store.getGate('health-check');
873
+ expect(resolved).toBe(true);
874
+ expect(store.session.outageDismissed).toBe(true);
875
+ });
876
+ });
877
+ // ── Screen transition analytics ───────────────────────────────────
878
+ describe('screen transition analytics', () => {
879
+ it('fires when a real screen transition occurs after the initial screen', () => {
880
+ const store = createStore();
881
+ store.completeSetup();
882
+ wizardCaptureMock.mockClear();
883
+ store.setReadinessResult({
884
+ decision: WizardReadiness.Yes,
885
+ health: {},
886
+ reasons: [],
887
+ });
888
+ expect(wizardCaptureMock).toHaveBeenCalledWith('screen auth', expect.objectContaining({
889
+ from_screen: Screen.HealthCheck,
890
+ }));
891
+ });
892
+ it('does not fire a screen event when the visible screen stays the same', () => {
893
+ const store = createStore();
894
+ store.completeSetup();
895
+ store.setReadinessResult({
896
+ decision: WizardReadiness.Yes,
897
+ health: {},
898
+ reasons: [],
899
+ });
900
+ store.setCredentials({
901
+ accessToken: 'tok',
902
+ projectApiKey: 'pk',
903
+ host: 'h',
904
+ projectId: 1,
905
+ });
906
+ wizardCaptureMock.mockClear();
907
+ store.setRunPhase(RunPhase.Running);
908
+ expect(store.currentScreen).toBe(Screen.Run);
909
+ expect(wizardCaptureMock.mock.calls.some(([event]) => typeof event === 'string' && event.startsWith('screen '))).toBe(false);
910
+ });
775
911
  });
776
- // ── setupComplete promise ────────────────────────────────────────
777
- describe('setupComplete', () => {
912
+ // ── intro gate ──────────────────────────────────────────────────
913
+ describe('intro gate', () => {
778
914
  it('resolves when completeSetup is called', async () => {
779
915
  const store = createStore();
780
916
  store.completeSetup();
781
- await store.setupComplete;
917
+ await store.getGate('intro');
782
918
  expect(store.session.setupConfirmed).toBe(true);
783
919
  });
784
920
  it('is a promise that can be awaited before completeSetup is called', async () => {
785
921
  const store = createStore();
786
922
  let resolved = false;
787
- void store.setupComplete.then(() => {
923
+ void store.getGate('intro').then(() => {
788
924
  resolved = true;
789
925
  });
790
926
  // Not yet resolved
791
927
  await Promise.resolve(); // flush microtasks
792
928
  expect(resolved).toBe(false);
793
929
  store.completeSetup();
794
- await store.setupComplete;
930
+ await store.getGate('intro');
795
931
  expect(resolved).toBe(true);
796
932
  });
797
933
  });