@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
@@ -1 +1 @@
1
- {"version":3,"file":"start-tui.js","sourceRoot":"","sources":["../../../../src/ui/tui/start-tui.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,MAAM,EAAE,MAAM,KAAK,CAAC;AAC7B,OAAO,EAAE,aAAa,EAAE,MAAM,OAAO,CAAC;AACtC,OAAO,EAAE,WAAW,EAAE,IAAI,EAAE,MAAM,YAAY,CAAC;AAC/C,OAAO,EAAE,KAAK,EAAE,MAAM,aAAa,CAAC;AACpC,OAAO,EAAE,KAAK,EAAE,MAAM,aAAa,CAAC;AACpC,OAAO,EAAE,GAAG,EAAE,MAAM,UAAU,CAAC;AAE/B,wBAAwB;AACxB,MAAM,WAAW,GAAG,SAAS,CAAC;AAC9B,MAAM,YAAY,GAAG,SAAS,CAAC;AAC/B,MAAM,WAAW,GAAG,QAAQ,CAAC;AAC7B,MAAM,QAAQ,GAAG,kBAAkB,CAAC;AAEpC,sEAAsE;AACtE,MAAM,UAAU,GAAG,QAAQ,GAAG,YAAY,GAAG,WAAW,CAAC;AAEzD,MAAM,UAAU,QAAQ,CACtB,OAAe,EACf,OAAa,IAAI,CAAC,MAAM;IAMxB,qDAAqD;IACrD,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC;IAEjC,MAAM,KAAK,GAAG,IAAI,WAAW,CAAC,IAAI,CAAC,CAAC;IACpC,KAAK,CAAC,OAAO,GAAG,OAAO,CAAC;IAExB,oBAAoB;IACpB,MAAM,KAAK,GAAG,IAAI,KAAK,CAAC,KAAK,CAAC,CAAC;IAC/B,KAAK,CAAC,KAAK,CAAC,CAAC;IAEb,qBAAqB;IACrB,MAAM,EAAE,OAAO,EAAE,UAAU,EAAE,GAAG,MAAM,CAAC,aAAa,CAAC,GAAG,EAAE,EAAE,KAAK,EAAE,CAAC,CAAC,CAAC;IAEtE,yBAAyB;IACzB,MAAM,OAAO,GAAG,GAAG,EAAE;QACnB,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,WAAW,GAAG,YAAY,GAAG,WAAW,CAAC,CAAC;IACjE,CAAC,CAAC;IACF,OAAO,CAAC,EAAE,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAE5B,OAAO;QACL,OAAO,EAAE,GAAG,EAAE;YACZ,UAAU,EAAE,CAAC;YACb,OAAO,EAAE,CAAC;QACZ,CAAC;QACD,KAAK;QACL,YAAY,EAAE,GAAG,EAAE,CAAC,KAAK,CAAC,aAAa;KACxC,CAAC;AACJ,CAAC","sourcesContent":["/**\n * start-tui.ts — Sets up the Ink TUI renderer and InkUI.\n */\n\nimport { render } from 'ink';\nimport { createElement } from 'react';\nimport { WizardStore, Flow } from './store.js';\nimport { InkUI } from './ink-ui.js';\nimport { setUI } from '../index.js';\nimport { App } from './App.js';\n\n// ANSI escape sequences\nconst RESET_ATTRS = '\\x1b[0m';\nconst CLEAR_SCREEN = '\\x1b[2J';\nconst CURSOR_HOME = '\\x1b[H';\nconst BG_BLACK = '\\x1b[48;2;0;0;0m';\n\n/** Set background to true black, clear screen, cursor to top-left. */\nconst FORCE_DARK = BG_BLACK + CLEAR_SCREEN + CURSOR_HOME;\n\nexport function startTUI(\n version: string,\n flow: Flow = Flow.Wizard,\n): {\n unmount: () => void;\n store: WizardStore;\n waitForSetup: () => Promise<void>;\n} {\n // Force dark background regardless of terminal theme\n process.stdout.write(FORCE_DARK);\n\n const store = new WizardStore(flow);\n store.version = version;\n\n // Swap in the InkUI\n const inkUI = new InkUI(store);\n setUI(inkUI);\n\n // Render the Ink app\n const { unmount: inkUnmount } = render(createElement(App, { store }));\n\n // Reset terminal on exit\n const cleanup = () => {\n process.stdout.write(RESET_ATTRS + CLEAR_SCREEN + CURSOR_HOME);\n };\n process.on('exit', cleanup);\n\n return {\n unmount: () => {\n inkUnmount();\n cleanup();\n },\n store,\n waitForSetup: () => store.setupComplete,\n };\n}\n"]}
1
+ {"version":3,"file":"start-tui.js","sourceRoot":"","sources":["../../../../src/ui/tui/start-tui.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,MAAM,EAAE,MAAM,KAAK,CAAC;AAC7B,OAAO,EAAE,aAAa,EAAE,MAAM,OAAO,CAAC;AACtC,OAAO,EAAE,WAAW,EAAE,IAAI,EAAE,MAAM,YAAY,CAAC;AAC/C,OAAO,EAAE,KAAK,EAAE,MAAM,aAAa,CAAC;AACpC,OAAO,EAAE,KAAK,EAAE,MAAM,aAAa,CAAC;AACpC,OAAO,EAAE,GAAG,EAAE,MAAM,UAAU,CAAC;AAE/B,wBAAwB;AACxB,MAAM,WAAW,GAAG,SAAS,CAAC;AAC9B,MAAM,YAAY,GAAG,SAAS,CAAC;AAC/B,MAAM,WAAW,GAAG,QAAQ,CAAC;AAC7B,MAAM,QAAQ,GAAG,kBAAkB,CAAC;AAEpC,sEAAsE;AACtE,MAAM,UAAU,GAAG,QAAQ,GAAG,YAAY,GAAG,WAAW,CAAC;AAEzD,MAAM,UAAU,QAAQ,CACtB,OAAe,EACf,OAAa,IAAI,CAAC,kBAAkB;IAMpC,qDAAqD;IACrD,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC;IAEjC,MAAM,KAAK,GAAG,IAAI,WAAW,CAAC,IAAI,CAAC,CAAC;IACpC,KAAK,CAAC,OAAO,GAAG,OAAO,CAAC;IAExB,oBAAoB;IACpB,MAAM,KAAK,GAAG,IAAI,KAAK,CAAC,KAAK,CAAC,CAAC;IAC/B,KAAK,CAAC,KAAK,CAAC,CAAC;IAEb,qBAAqB;IACrB,MAAM,EAAE,OAAO,EAAE,UAAU,EAAE,GAAG,MAAM,CAAC,aAAa,CAAC,GAAG,EAAE,EAAE,KAAK,EAAE,CAAC,CAAC,CAAC;IAEtE,yBAAyB;IACzB,MAAM,OAAO,GAAG,GAAG,EAAE;QACnB,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,WAAW,GAAG,YAAY,GAAG,WAAW,CAAC,CAAC;IACjE,CAAC,CAAC;IACF,OAAO,CAAC,EAAE,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAE5B,OAAO;QACL,OAAO,EAAE,GAAG,EAAE;YACZ,UAAU,EAAE,CAAC;YACb,OAAO,EAAE,CAAC;QACZ,CAAC;QACD,KAAK;QACL,YAAY,EAAE,GAAG,EAAE,CAAC,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC;KAC3C,CAAC;AACJ,CAAC","sourcesContent":["/**\n * start-tui.ts — Sets up the Ink TUI renderer and InkUI.\n */\n\nimport { render } from 'ink';\nimport { createElement } from 'react';\nimport { WizardStore, Flow } from './store.js';\nimport { InkUI } from './ink-ui.js';\nimport { setUI } from '../index.js';\nimport { App } from './App.js';\n\n// ANSI escape sequences\nconst RESET_ATTRS = '\\x1b[0m';\nconst CLEAR_SCREEN = '\\x1b[2J';\nconst CURSOR_HOME = '\\x1b[H';\nconst BG_BLACK = '\\x1b[48;2;0;0;0m';\n\n/** Set background to true black, clear screen, cursor to top-left. */\nconst FORCE_DARK = BG_BLACK + CLEAR_SCREEN + CURSOR_HOME;\n\nexport function startTUI(\n version: string,\n flow: Flow = Flow.PostHogIntegration,\n): {\n unmount: () => void;\n store: WizardStore;\n waitForSetup: () => Promise<void>;\n} {\n // Force dark background regardless of terminal theme\n process.stdout.write(FORCE_DARK);\n\n const store = new WizardStore(flow);\n store.version = version;\n\n // Swap in the InkUI\n const inkUI = new InkUI(store);\n setUI(inkUI);\n\n // Render the Ink app\n const { unmount: inkUnmount } = render(createElement(App, { store }));\n\n // Reset terminal on exit\n const cleanup = () => {\n process.stdout.write(RESET_ATTRS + CLEAR_SCREEN + CURSOR_HOME);\n };\n process.on('exit', cleanup);\n\n return {\n unmount: () => {\n inkUnmount();\n cleanup();\n },\n store,\n waitForSetup: () => store.getGate('intro'),\n };\n}\n"]}
@@ -2,16 +2,20 @@
2
2
  * WizardStore — Nanostore-backed reactive store for the TUI.
3
3
  * React components subscribe via useSyncExternalStore.
4
4
  *
5
- * Navigation is delegated to WizardRouter.
6
- * The active screen is derived from session state not imperatively set.
7
- * Overlays (settings-override, port-conflict) are the only imperative navigation.
5
+ * The active screen is derived from session state — WizardRouter walks
6
+ * the flow and shows the first step whose `isComplete` is still false.
7
+ *
8
+ * Define a step `gate` if your screen needs to await user interactions.
9
+ * bin.ts calls `await store.getGate(stepId)` to pause until the gate
10
+ * predicate becomes true.
8
11
  *
9
12
  * All session mutations that affect screen resolution go through
10
13
  * explicit setters so emitChange() is always called.
11
14
  */
12
15
  import { TaskStatus } from '../wizard-ui.js';
13
16
  import { type WizardSession, type OutroData, type DiscoveredFeature, AdditionalFeature, McpOutcome, RunPhase } from '../../lib/wizard-session.js';
14
- import type { SettingsConflict } from '../../lib/agent-interface.js';
17
+ import type { SettingsConflict } from '../../lib/agent/agent-interface.js';
18
+ import type { WizardReadinessResult } from '../../lib/health-checks/readiness.js';
15
19
  import { WizardRouter, type ScreenName, Screen, Overlay, Flow } from './router.js';
16
20
  export { TaskStatus, Screen, Overlay, Flow, RunPhase, McpOutcome };
17
21
  export type { ScreenName, OutroData, WizardSession };
@@ -39,32 +43,52 @@ export declare class WizardStore {
39
43
  private _lastScreen;
40
44
  /** Hooks run when transitioning onto a screen. */
41
45
  private _enterScreenHooks;
46
+ /** Gate promises derived from workflow step definitions. */
47
+ private _gates;
42
48
  version: string;
43
49
  /** Navigation router — resolves active screen from session state. */
44
50
  readonly router: WizardRouter;
45
- /**
46
- * Setup promise — IntroScreen resolves this when the user confirms.
47
- * bin.ts awaits it before calling runWizard.
48
- */
49
- private _resolveSetup;
50
- readonly setupComplete: Promise<void>;
51
51
  /** Blocks agent execution until the settings-override overlay is dismissed. */
52
52
  private _resolveSettingsOverride;
53
53
  private _backupAndFixSettings;
54
54
  /** Blocks OAuth flow until the port-conflict overlay is dismissed. */
55
55
  private _resolvePortConflict;
56
+ constructor(flow?: Flow);
56
57
  /**
57
- * Resolves when the health-check screen is done either auto-advanced
58
- * (healthy) or user-dismissed (outage). bin.ts awaits this before runWizard().
58
+ * Scan workflow steps for gate predicates and onInit callbacks.
59
+ * Creates gate promises and fires init work.
59
60
  */
60
- private _resolveHealthGate;
61
- readonly healthGateComplete: Promise<void>;
62
- constructor(flow?: Flow);
61
+ private _initFromWorkflow;
62
+ /**
63
+ * Run all `onReady` hooks declared by the current flow's steps, in
64
+ * order. Must be called after `store.session = session` so hooks see
65
+ * the real installDir. bin.ts calls this generically — it doesn't
66
+ * need to know which workflow has which pre-flow work.
67
+ */
68
+ runReadyHooks(): Promise<void>;
69
+ /**
70
+ * Get a gate promise by step ID — the primary blocking checkpoint API
71
+ * for bin.ts. `await store.getGate('...')` parks the caller until the
72
+ * corresponding workflow step's gate predicate flips to true (if the
73
+ * predicate stays false, the caller stays parked indefinitely — the
74
+ * TUI keeps rendering so the user can resolve whatever is blocking).
75
+ *
76
+ * If the workflow doesn't define a step with this ID, or the step
77
+ * has no `gate` predicate, this returns an already-resolved promise
78
+ * so bin.ts flows straight through. This lets workflows opt in to
79
+ * gates on a per-step basis without bin.ts needing to know which
80
+ * gates exist in which flow.
81
+ */
82
+ getGate(stepId: string): Promise<void>;
63
83
  /**
64
- * Kick off the health check. Stores the result and resolves the
65
- * health gate if non-blocking.
84
+ * Re-evaluate every gate predicate against the current session and
85
+ * resolve any whose predicate now returns true. Called after every
86
+ * emitChange(), so gates unblock as soon as the session mutation
87
+ * that satisfies them lands. Gates only resolve once — a predicate
88
+ * that goes true → false → true will NOT re-block a caller that
89
+ * already awaited through.
66
90
  */
67
- private _initHealthCheck;
91
+ private _checkGates;
68
92
  get session(): WizardSession;
69
93
  set session(value: WizardSession);
70
94
  get statusMessages(): string[];
@@ -73,7 +97,7 @@ export declare class WizardStore {
73
97
  get statusExpanded(): boolean;
74
98
  toggleStatusExpanded(): void;
75
99
  setStatusExpanded(expanded: boolean): void;
76
- /** Unblocks bin.ts via the setupComplete promise. */
100
+ /** Sets setupConfirmed. Gate resolves via _checkGates(). */
77
101
  completeSetup(): void;
78
102
  setRunPhase(phase: RunPhase): void;
79
103
  setCredentials(credentials: WizardSession['credentials']): void;
@@ -86,8 +110,8 @@ export declare class WizardStore {
86
110
  docsUrl: string;
87
111
  }): void;
88
112
  setLoginUrl(url: string | null): void;
89
- setReadinessResult(result: import('../../lib/health-checks/readiness.js').WizardReadinessResult | null): void;
90
- /** User dismissed the blocking outage screen. Unblocks bin.ts. */
113
+ setReadinessResult(result: WizardReadinessResult | null): void;
114
+ /** User dismissed the blocking outage screen. Gate resolves via _checkGates(). */
91
115
  dismissOutage(): void;
92
116
  /**
93
117
  * Push the settings-override overlay and return a promise that blocks
@@ -133,6 +157,7 @@ export declare class WizardStore {
133
157
  /**
134
158
  * Notify React that state has changed.
135
159
  * The router re-resolves the active screen on next render.
160
+ * Gate predicates are checked and resolved if ready.
136
161
  */
137
162
  emitChange(): void;
138
163
  pushOverlay(overlay: Overlay): void;
@@ -2,9 +2,12 @@
2
2
  * WizardStore — Nanostore-backed reactive store for the TUI.
3
3
  * React components subscribe via useSyncExternalStore.
4
4
  *
5
- * Navigation is delegated to WizardRouter.
6
- * The active screen is derived from session state not imperatively set.
7
- * Overlays (settings-override, port-conflict) are the only imperative navigation.
5
+ * The active screen is derived from session state — WizardRouter walks
6
+ * the flow and shows the first step whose `isComplete` is still false.
7
+ *
8
+ * Define a step `gate` if your screen needs to await user interactions.
9
+ * bin.ts calls `await store.getGate(stepId)` to pause until the gate
10
+ * predicate becomes true.
8
11
  *
9
12
  * All session mutations that affect screen resolution go through
10
13
  * explicit setters so emitChange() is always called.
@@ -14,7 +17,7 @@ import { TaskStatus } from '../wizard-ui.js';
14
17
  import { AdditionalFeature, McpOutcome, RunPhase, buildSession, } from '../../lib/wizard-session.js';
15
18
  import { WizardRouter, Screen, Overlay, Flow, } from './router.js';
16
19
  import { analytics, sessionProperties } from '../../utils/analytics.js';
17
- import { evaluateWizardReadiness, WizardReadiness, } from '../../lib/health-checks/readiness.js';
20
+ import { WORKFLOW_STEPS } from './flows.js';
18
21
  export { TaskStatus, Screen, Overlay, Flow, RunPhase, McpOutcome };
19
22
  export class WizardStore {
20
23
  // ── Internal nanostore atoms ─────────────────────────────────────
@@ -30,61 +33,116 @@ export class WizardStore {
30
33
  _lastScreen = null;
31
34
  /** Hooks run when transitioning onto a screen. */
32
35
  _enterScreenHooks = new Map();
36
+ /** Gate promises derived from workflow step definitions. */
37
+ _gates = new Map();
33
38
  version = '';
34
39
  /** Navigation router — resolves active screen from session state. */
35
40
  router;
36
- /**
37
- * Setup promise — IntroScreen resolves this when the user confirms.
38
- * bin.ts awaits it before calling runWizard.
39
- */
40
- _resolveSetup;
41
- setupComplete = new Promise((resolve) => {
42
- this._resolveSetup = resolve;
43
- });
44
41
  /** Blocks agent execution until the settings-override overlay is dismissed. */
45
42
  _resolveSettingsOverride = null;
46
43
  _backupAndFixSettings = null;
47
44
  /** Blocks OAuth flow until the port-conflict overlay is dismissed. */
48
45
  _resolvePortConflict = null;
46
+ constructor(flow = Flow.PostHogIntegration) {
47
+ this.router = new WizardRouter(flow);
48
+ this._initFromWorkflow(flow);
49
+ }
49
50
  /**
50
- * Resolves when the health-check screen is done either auto-advanced
51
- * (healthy) or user-dismissed (outage). bin.ts awaits this before runWizard().
51
+ * Scan workflow steps for gate predicates and onInit callbacks.
52
+ * Creates gate promises and fires init work.
52
53
  */
53
- _resolveHealthGate;
54
- healthGateComplete = new Promise((resolve) => {
55
- this._resolveHealthGate = resolve;
56
- });
57
- constructor(flow = Flow.Wizard) {
58
- this.router = new WizardRouter(flow);
59
- // Fire health check immediately for Wizard flow so results arrive
60
- // while the user is still on IntroScreen.
61
- if (flow === Flow.Wizard) {
62
- this._initHealthCheck();
54
+ _initFromWorkflow(flow) {
55
+ const steps = WORKFLOW_STEPS[flow];
56
+ if (!steps)
57
+ return;
58
+ // Create gate promises from steps that define them
59
+ for (const step of steps) {
60
+ if (step.gate) {
61
+ let resolve;
62
+ const promise = new Promise((r) => {
63
+ resolve = r;
64
+ });
65
+ this._gates.set(step.id, {
66
+ predicate: step.gate,
67
+ promise,
68
+ resolve,
69
+ resolved: false,
70
+ });
71
+ }
63
72
  }
64
- else {
65
- this._resolveHealthGate();
73
+ // Run onInit callbacks with a minimal context interface.
74
+ // Arrow functions capture `this` from _initFromWorkflow so we don't
75
+ // need to alias it.
76
+ const getSession = () => this.session;
77
+ const ctx = {
78
+ get session() {
79
+ return getSession();
80
+ },
81
+ setReadinessResult: (r) => this.setReadinessResult(r),
82
+ setFrameworkContext: (k, v) => this.setFrameworkContext(k, v),
83
+ emitChange: () => this.emitChange(),
84
+ };
85
+ for (const step of steps) {
86
+ step.onInit?.(ctx);
66
87
  }
67
88
  }
68
89
  /**
69
- * Kick off the health check. Stores the result and resolves the
70
- * health gate if non-blocking.
90
+ * Run all `onReady` hooks declared by the current flow's steps, in
91
+ * order. Must be called after `store.session = session` so hooks see
92
+ * the real installDir. bin.ts calls this generically — it doesn't
93
+ * need to know which workflow has which pre-flow work.
71
94
  */
72
- _initHealthCheck() {
73
- evaluateWizardReadiness()
74
- .then((readiness) => {
75
- this.setReadinessResult(readiness);
76
- if (readiness.decision !== WizardReadiness.No) {
77
- this._resolveHealthGate();
95
+ async runReadyHooks() {
96
+ const steps = WORKFLOW_STEPS[this.router.activeFlow];
97
+ if (!steps)
98
+ return;
99
+ const ctx = {
100
+ session: this.session,
101
+ setFrameworkContext: (k, v) => this.setFrameworkContext(k, v),
102
+ setFrameworkConfig: (i, c) => this.setFrameworkConfig(i, c),
103
+ setDetectedFramework: (l) => this.setDetectedFramework(l),
104
+ setUnsupportedVersion: (info) => this.setUnsupportedVersion(info),
105
+ addDiscoveredFeature: (f) => this.addDiscoveredFeature(f),
106
+ setDetectionComplete: () => this.setDetectionComplete(),
107
+ };
108
+ for (const step of steps) {
109
+ if (step.onReady) {
110
+ await step.onReady(ctx);
78
111
  }
79
- })
80
- .catch(() => {
81
- this.setReadinessResult({
82
- decision: WizardReadiness.Yes,
83
- health: {},
84
- reasons: [],
85
- });
86
- this._resolveHealthGate();
87
- });
112
+ }
113
+ }
114
+ // ── Gate API ────────────────────────────────────────────────────
115
+ /**
116
+ * Get a gate promise by step ID — the primary blocking checkpoint API
117
+ * for bin.ts. `await store.getGate('...')` parks the caller until the
118
+ * corresponding workflow step's gate predicate flips to true (if the
119
+ * predicate stays false, the caller stays parked indefinitely — the
120
+ * TUI keeps rendering so the user can resolve whatever is blocking).
121
+ *
122
+ * If the workflow doesn't define a step with this ID, or the step
123
+ * has no `gate` predicate, this returns an already-resolved promise
124
+ * so bin.ts flows straight through. This lets workflows opt in to
125
+ * gates on a per-step basis without bin.ts needing to know which
126
+ * gates exist in which flow.
127
+ */
128
+ getGate(stepId) {
129
+ return this._gates.get(stepId)?.promise ?? Promise.resolve();
130
+ }
131
+ /**
132
+ * Re-evaluate every gate predicate against the current session and
133
+ * resolve any whose predicate now returns true. Called after every
134
+ * emitChange(), so gates unblock as soon as the session mutation
135
+ * that satisfies them lands. Gates only resolve once — a predicate
136
+ * that goes true → false → true will NOT re-block a caller that
137
+ * already awaited through.
138
+ */
139
+ _checkGates() {
140
+ for (const [, gate] of this._gates) {
141
+ if (!gate.resolved && gate.predicate(this.session)) {
142
+ gate.resolved = true;
143
+ gate.resolve();
144
+ }
145
+ }
88
146
  }
89
147
  // ── State accessors (read from atoms) ────────────────────────────
90
148
  get session() {
@@ -92,6 +150,7 @@ export class WizardStore {
92
150
  }
93
151
  set session(value) {
94
152
  this.$session.set(value);
153
+ this.emitChange();
95
154
  }
96
155
  get statusMessages() {
97
156
  return this.$statusMessages.get();
@@ -118,11 +177,10 @@ export class WizardStore {
118
177
  // ── Session setters ─────────────────────────────────────────────
119
178
  // Every setter that affects screen resolution calls emitChange().
120
179
  // Business logic calls these instead of mutating session directly.
121
- /** Unblocks bin.ts via the setupComplete promise. */
180
+ /** Sets setupConfirmed. Gate resolves via _checkGates(). */
122
181
  completeSetup() {
123
182
  this.$session.setKey('setupConfirmed', true);
124
183
  analytics.wizardCapture('setup confirmed', sessionProperties(this.session));
125
- this._resolveSetup();
126
184
  this.emitChange();
127
185
  }
128
186
  setRunPhase(phase) {
@@ -162,10 +220,9 @@ export class WizardStore {
162
220
  this.$session.setKey('readinessResult', result);
163
221
  this.emitChange();
164
222
  }
165
- /** User dismissed the blocking outage screen. Unblocks bin.ts. */
223
+ /** User dismissed the blocking outage screen. Gate resolves via _checkGates(). */
166
224
  dismissOutage() {
167
225
  this.$session.setKey('outageDismissed', true);
168
- this._resolveHealthGate();
169
226
  this.emitChange();
170
227
  }
171
228
  /**
@@ -297,10 +354,12 @@ export class WizardStore {
297
354
  /**
298
355
  * Notify React that state has changed.
299
356
  * The router re-resolves the active screen on next render.
357
+ * Gate predicates are checked and resolved if ready.
300
358
  */
301
359
  emitChange() {
302
360
  this.router._setDirection('push');
303
361
  this.$version.set(this.$version.get() + 1);
362
+ this._checkGates();
304
363
  this._detectTransition();
305
364
  }
306
365
  // ── Overlay navigation ──────────────────────────────────────────
@@ -341,6 +400,7 @@ export class WizardStore {
341
400
  }
342
401
  analytics.wizardCapture(`screen ${next}`, {
343
402
  from_screen: prev,
403
+ workflow: this.router.activeFlow,
344
404
  ...sessionProperties(this.session),
345
405
  });
346
406
  }
@@ -1 +1 @@
1
- {"version":3,"file":"store.js","sourceRoot":"","sources":["../../../../src/ui/tui/store.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * WizardStore — Nanostore-backed reactive store for the TUI.\n * React components subscribe via useSyncExternalStore.\n *\n * Navigation is delegated to WizardRouter.\n * The active screen is derived from session state — not imperatively set.\n * Overlays (settings-override, port-conflict) are the only imperative navigation.\n *\n * All session mutations that affect screen resolution go through\n * explicit setters so emitChange() is always called.\n */\n\nimport { atom, map } from 'nanostores';\nimport { TaskStatus } from '../wizard-ui.js';\nimport {\n type WizardSession,\n type OutroData,\n type DiscoveredFeature,\n AdditionalFeature,\n McpOutcome,\n RunPhase,\n buildSession,\n} from '../../lib/wizard-session.js';\nimport type { SettingsConflict } from '../../lib/agent-interface.js';\nimport {\n WizardRouter,\n type ScreenName,\n Screen,\n Overlay,\n Flow,\n} from './router.js';\nimport { analytics, sessionProperties } from '../../utils/analytics.js';\nimport {\n evaluateWizardReadiness,\n WizardReadiness,\n} from '../../lib/health-checks/readiness.js';\n\nexport { TaskStatus, Screen, Overlay, Flow, RunPhase, McpOutcome };\nexport type { ScreenName, OutroData, WizardSession };\n\nexport interface TaskItem {\n label: string;\n activeForm?: string;\n status: TaskStatus;\n /** Legacy compat */\n done: boolean;\n}\n\nexport interface PlannedEvent {\n name: string;\n description: string;\n}\n\nexport class WizardStore {\n // ── Internal nanostore atoms ─────────────────────────────────────\n private $session = map<WizardSession>(buildSession({}));\n private $statusMessages = atom<string[]>([]);\n private $statusExpanded = atom(false);\n private $tasks = atom<TaskItem[]>([]);\n private $eventPlan = atom<PlannedEvent[]>([]);\n private $learnCardBlockIdx = atom(0);\n private $learnCardComplete = atom(false);\n private $version = atom(0);\n\n /** Last screen seen — used to detect screen transitions for analytics. */\n private _lastScreen: ScreenName | null = null;\n\n /** Hooks run when transitioning onto a screen. */\n private _enterScreenHooks = new Map<ScreenName, (() => void)[]>();\n\n version = '';\n\n /** Navigation router — resolves active screen from session state. */\n readonly router: WizardRouter;\n\n /**\n * Setup promise — IntroScreen resolves this when the user confirms.\n * bin.ts awaits it before calling runWizard.\n */\n private _resolveSetup!: () => void;\n readonly setupComplete: Promise<void> = new Promise((resolve) => {\n this._resolveSetup = resolve;\n });\n\n /** Blocks agent execution until the settings-override overlay is dismissed. */\n private _resolveSettingsOverride: (() => void) | null = null;\n private _backupAndFixSettings: (() => boolean) | null = null;\n\n /** Blocks OAuth flow until the port-conflict overlay is dismissed. */\n private _resolvePortConflict: (() => void) | null = null;\n\n /**\n * Resolves when the health-check screen is done — either auto-advanced\n * (healthy) or user-dismissed (outage). bin.ts awaits this before runWizard().\n */\n private _resolveHealthGate!: () => void;\n readonly healthGateComplete: Promise<void> = new Promise((resolve) => {\n this._resolveHealthGate = resolve;\n });\n\n constructor(flow: Flow = Flow.Wizard) {\n this.router = new WizardRouter(flow);\n\n // Fire health check immediately for Wizard flow so results arrive\n // while the user is still on IntroScreen.\n if (flow === Flow.Wizard) {\n this._initHealthCheck();\n } else {\n this._resolveHealthGate();\n }\n }\n\n /**\n * Kick off the health check. Stores the result and resolves the\n * health gate if non-blocking.\n */\n private _initHealthCheck(): void {\n evaluateWizardReadiness()\n .then((readiness) => {\n this.setReadinessResult(readiness);\n if (readiness.decision !== WizardReadiness.No) {\n this._resolveHealthGate();\n }\n })\n .catch(() => {\n this.setReadinessResult({\n decision: WizardReadiness.Yes,\n health: {} as never,\n reasons: [],\n });\n this._resolveHealthGate();\n });\n }\n\n // ── State accessors (read from atoms) ────────────────────────────\n\n get session(): WizardSession {\n return this.$session.get();\n }\n\n set session(value: WizardSession) {\n this.$session.set(value);\n }\n\n get statusMessages(): string[] {\n return this.$statusMessages.get();\n }\n\n get tasks(): TaskItem[] {\n return this.$tasks.get();\n }\n\n get eventPlan(): PlannedEvent[] {\n return this.$eventPlan.get();\n }\n\n get statusExpanded(): boolean {\n return this.$statusExpanded.get();\n }\n\n toggleStatusExpanded(): void {\n this.$statusExpanded.set(!this.$statusExpanded.get());\n this.emitChange();\n }\n\n setStatusExpanded(expanded: boolean): void {\n if (this.$statusExpanded.get() !== expanded) {\n this.$statusExpanded.set(expanded);\n this.emitChange();\n }\n }\n\n // ── Session setters ─────────────────────────────────────────────\n // Every setter that affects screen resolution calls emitChange().\n // Business logic calls these instead of mutating session directly.\n\n /** Unblocks bin.ts via the setupComplete promise. */\n completeSetup(): void {\n this.$session.setKey('setupConfirmed', true);\n analytics.wizardCapture('setup confirmed', sessionProperties(this.session));\n this._resolveSetup();\n this.emitChange();\n }\n\n setRunPhase(phase: RunPhase): void {\n this.$session.setKey('runPhase', phase);\n this.emitChange();\n }\n\n setCredentials(credentials: WizardSession['credentials']): void {\n this.$session.setKey('credentials', credentials);\n analytics.wizardCapture('auth complete', {\n project_id: credentials?.projectId,\n });\n this.emitChange();\n }\n\n setFrameworkConfig(\n integration: WizardSession['integration'],\n config: WizardSession['frameworkConfig'],\n ): void {\n this.$session.setKey('integration', integration);\n this.$session.setKey('frameworkConfig', config);\n this.$session.setKey('unsupportedVersion', null);\n this.emitChange();\n }\n\n setDetectionComplete(): void {\n this.$session.setKey('detectionComplete', true);\n this.emitChange();\n }\n\n setDetectedFramework(label: string): void {\n this.$session.setKey('detectedFrameworkLabel', label);\n this.emitChange();\n }\n\n setUnsupportedVersion(info: {\n current: string;\n minimum: string;\n docsUrl: string;\n }): void {\n this.$session.setKey('unsupportedVersion', info);\n this.emitChange();\n }\n\n setLoginUrl(url: string | null): void {\n this.$session.setKey('loginUrl', url);\n this.emitChange();\n }\n\n setReadinessResult(\n result:\n | import('../../lib/health-checks/readiness.js').WizardReadinessResult\n | null,\n ): void {\n this.$session.setKey('readinessResult', result);\n this.emitChange();\n }\n\n /** User dismissed the blocking outage screen. Unblocks bin.ts. */\n dismissOutage(): void {\n this.$session.setKey('outageDismissed', true);\n this._resolveHealthGate();\n this.emitChange();\n }\n\n /**\n * Push the settings-override overlay and return a promise that blocks\n * until the user dismisses it via backupAndFixSettingsOverride().\n */\n showSettingsOverride(\n conflicts: SettingsConflict[],\n backupAndFix: () => boolean,\n ): Promise<void> {\n const allKeys = conflicts.flatMap((c) => c.keys);\n this.$session.setKey('settingsOverrideKeys', allKeys);\n this.$session.setKey('settingsConflicts', conflicts);\n this._backupAndFixSettings = backupAndFix;\n\n const hasReadOnly = conflicts.some((c) => !c.writable);\n if (hasReadOnly) {\n this.pushOverlay(Overlay.ManagedSettings);\n } else {\n this.pushOverlay(Overlay.SettingsOverride);\n }\n\n return new Promise((resolve) => {\n this._resolveSettingsOverride = resolve;\n });\n }\n\n /**\n * Push the port-conflict overlay and return a promise that blocks\n * until the user kills the blocking process or exits.\n */\n showPortConflict(processInfo: {\n command: string;\n pid: string;\n user: string;\n }): Promise<void> {\n this.$session.setKey('portConflictProcess', processInfo);\n this.pushOverlay(Overlay.PortConflict);\n return new Promise((resolve) => {\n this._resolvePortConflict = resolve;\n });\n }\n\n /** Dismiss the port-conflict overlay after the user kills the process. */\n resolvePortConflict(): void {\n this.$session.setKey('portConflictProcess', null);\n this.popOverlay();\n this._resolvePortConflict?.();\n this._resolvePortConflict = null;\n }\n\n /**\n * Back up .claude/settings.json. Dismisses the overlay on success.\n */\n backupAndFixSettingsOverride(): boolean {\n const ok = this._backupAndFixSettings?.() ?? false;\n if (ok) {\n this.$session.setKey('settingsOverrideKeys', null);\n this.$session.setKey('settingsConflicts', null);\n this.popOverlay();\n this._resolveSettingsOverride?.();\n this._resolveSettingsOverride = null;\n this._backupAndFixSettings = null;\n }\n return ok;\n }\n\n /** Push the auth-error overlay (no dismiss — user must exit). */\n showAuthError(): void {\n this.pushOverlay(Overlay.AuthError);\n }\n\n addDiscoveredFeature(feature: DiscoveredFeature): void {\n if (!this.session.discoveredFeatures.includes(feature)) {\n this.session.discoveredFeatures.push(feature);\n this.emitChange();\n }\n }\n\n /**\n * Enable an additional feature: enqueue it for the stop hook\n * and set any feature-specific session flags.\n */\n enableFeature(feature: AdditionalFeature): void {\n if (!this.session.additionalFeatureQueue.includes(feature)) {\n this.session.additionalFeatureQueue.push(feature);\n }\n // Feature-specific flags\n if (feature === AdditionalFeature.LLM) {\n this.session.llmOptIn = true;\n }\n analytics.wizardCapture('feature enabled', { feature });\n this.emitChange();\n }\n\n setMcpComplete(\n outcome: McpOutcome = McpOutcome.Skipped,\n installedClients: string[] = [],\n ): void {\n this.$session.setKey('mcpComplete', true);\n this.$session.setKey('mcpOutcome', outcome);\n this.$session.setKey('mcpInstalledClients', installedClients);\n analytics.wizardCapture('mcp complete', {\n mcp_outcome: outcome,\n mcp_installed_clients: installedClients,\n ...sessionProperties(this.session),\n });\n this.emitChange();\n }\n\n setSkillsComplete(kept: boolean): void {\n this.$session.setKey('skillsComplete', true);\n analytics.wizardCapture('skills complete', {\n skills_kept: kept,\n ...sessionProperties(this.session),\n });\n this.emitChange();\n }\n\n setOutroDismissed(): void {\n this.$session.setKey('outroDismissed', true);\n this.emitChange();\n }\n\n setOutroData(data: OutroData): void {\n this.$session.setKey('outroData', data);\n this.emitChange();\n }\n\n setFrameworkContext(key: string, value: unknown): void {\n const ctx = { ...this.$session.get().frameworkContext, [key]: value };\n this.$session.setKey('frameworkContext', ctx);\n this.emitChange();\n }\n\n // ── Derived state ───────────────────────────────────────────────\n\n /**\n * The screen that should be rendered right now.\n * Derived from session state via the router.\n */\n get currentScreen(): ScreenName {\n return this.router.resolve(this.session);\n }\n\n /** Direction hint for screen transitions. */\n get lastNavDirection(): 'push' | 'pop' | null {\n return this.router.lastNavDirection;\n }\n\n // ── Change notification ─────────────────────────────────────────\n\n getVersion(): number {\n return this.$version.get();\n }\n\n /**\n * Notify React that state has changed.\n * The router re-resolves the active screen on next render.\n */\n emitChange(): void {\n this.router._setDirection('push');\n this.$version.set(this.$version.get() + 1);\n this._detectTransition();\n }\n\n // ── Overlay navigation ──────────────────────────────────────────\n\n pushOverlay(overlay: Overlay): void {\n this.router._setDirection('push');\n this.router.pushOverlay(overlay);\n this.$version.set(this.$version.get() + 1);\n this._detectTransition();\n }\n\n popOverlay(): void {\n this.router._setDirection('pop');\n this.router.popOverlay();\n this.$version.set(this.$version.get() + 1);\n this._detectTransition();\n }\n\n // ── Screen transition analytics ─────────────────────────────────\n\n /**\n * Register a callback to run when transitioning onto the given screen.\n * Fires after every transition that lands on this screen.\n */\n onEnterScreen(screen: ScreenName, fn: () => void): void {\n const list = this._enterScreenHooks.get(screen) ?? [];\n list.push(fn);\n this._enterScreenHooks.set(screen, list);\n }\n\n /**\n * Detect screen transitions, run enter-screen hooks, and fire analytics.\n * Called at the end of emitChange/pushOverlay/popOverlay.\n */\n private _detectTransition(): void {\n const next = this.router.resolve(this.session);\n const prev = this._lastScreen;\n if (prev !== null && next !== prev) {\n const hooks = this._enterScreenHooks.get(next);\n if (hooks) {\n for (const fn of hooks) fn();\n }\n analytics.wizardCapture(`screen ${next}`, {\n from_screen: prev,\n ...sessionProperties(this.session),\n });\n }\n this._lastScreen = next;\n }\n\n // ── Agent observation state ─────────────────────────────────────\n\n pushStatus(message: string): void {\n const msgs = this.$statusMessages.get();\n // Skip consecutive duplicate messages\n if (msgs.length > 0 && msgs[msgs.length - 1] === message) return;\n this.$statusMessages.set([...msgs, message]);\n this.emitChange();\n }\n\n setTasks(tasks: TaskItem[]): void {\n this.$tasks.set(tasks);\n this.emitChange();\n }\n\n updateTask(index: number, done: boolean): void {\n const tasks = this.$tasks.get();\n if (tasks[index]) {\n const updated = [...tasks];\n updated[index] = {\n ...updated[index],\n done,\n status: done ? TaskStatus.Completed : TaskStatus.Pending,\n };\n this.$tasks.set(updated);\n this.emitChange();\n }\n }\n\n setEventPlan(events: PlannedEvent[]): void {\n this.$eventPlan.set(events);\n this.emitChange();\n }\n\n get learnCardBlockIdx(): number {\n return this.$learnCardBlockIdx.get();\n }\n\n setLearnCardBlockIdx(idx: number): void {\n this.$learnCardBlockIdx.set(idx);\n }\n\n get learnCardComplete(): boolean {\n return this.$learnCardComplete.get();\n }\n\n setLearnCardComplete(): void {\n this.$learnCardComplete.set(true);\n this.emitChange();\n }\n\n syncTodos(\n todos: Array<{ content: string; status: string; activeForm?: string }>,\n ): void {\n const incoming = todos.map((t) => ({\n label: t.content,\n activeForm: t.activeForm,\n status: (t.status as TaskStatus) || TaskStatus.Pending,\n done: t.status === TaskStatus.Completed,\n }));\n\n const incomingLabels = new Set(incoming.map((t) => t.label));\n\n const retained = this.$tasks\n .get()\n .filter((t) => t.done && !incomingLabels.has(t.label));\n\n this.$tasks.set([...retained, ...incoming]);\n this.emitChange();\n }\n\n // ── React integration ───────────────────────────────────────────\n\n subscribe(callback: () => void): () => void {\n return this.$version.listen(() => callback());\n }\n\n getSnapshot(): number {\n return this.$version.get();\n }\n}\n"]}
1
+ {"version":3,"file":"store.js","sourceRoot":"","sources":["../../../../src/ui/tui/store.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * WizardStore — Nanostore-backed reactive store for the TUI.\n * React components subscribe via useSyncExternalStore.\n *\n * The active screen is derived from session state — WizardRouter walks\n * the flow and shows the first step whose `isComplete` is still false.\n *\n * Define a step `gate` if your screen needs to await user interactions.\n * bin.ts calls `await store.getGate(stepId)` to pause until the gate\n * predicate becomes true.\n *\n * All session mutations that affect screen resolution go through\n * explicit setters so emitChange() is always called.\n */\n\nimport { atom, map } from 'nanostores';\nimport { TaskStatus } from '../wizard-ui.js';\nimport {\n type WizardSession,\n type OutroData,\n type DiscoveredFeature,\n AdditionalFeature,\n McpOutcome,\n RunPhase,\n buildSession,\n} from '../../lib/wizard-session.js';\nimport type { SettingsConflict } from '../../lib/agent/agent-interface.js';\nimport type { WizardReadinessResult } from '../../lib/health-checks/readiness.js';\nimport {\n WizardRouter,\n type ScreenName,\n Screen,\n Overlay,\n Flow,\n} from './router.js';\nimport { analytics, sessionProperties } from '../../utils/analytics.js';\nimport type {\n StoreInitContext,\n WorkflowReadyContext,\n} from '../../lib/workflows/workflow-step.js';\nimport { WORKFLOW_STEPS } from './flows.js';\n\nexport { TaskStatus, Screen, Overlay, Flow, RunPhase, McpOutcome };\nexport type { ScreenName, OutroData, WizardSession };\n\nexport interface TaskItem {\n label: string;\n activeForm?: string;\n status: TaskStatus;\n /** Legacy compat */\n done: boolean;\n}\n\nexport interface PlannedEvent {\n name: string;\n description: string;\n}\n\ninterface GateEntry {\n predicate: (session: WizardSession) => boolean;\n promise: Promise<void>;\n resolve: () => void;\n resolved: boolean;\n}\n\nexport class WizardStore {\n // ── Internal nanostore atoms ─────────────────────────────────────\n private $session = map<WizardSession>(buildSession({}));\n private $statusMessages = atom<string[]>([]);\n private $statusExpanded = atom(false);\n private $tasks = atom<TaskItem[]>([]);\n private $eventPlan = atom<PlannedEvent[]>([]);\n private $learnCardBlockIdx = atom(0);\n private $learnCardComplete = atom(false);\n private $version = atom(0);\n\n /** Last screen seen — used to detect screen transitions for analytics. */\n private _lastScreen: ScreenName | null = null;\n\n /** Hooks run when transitioning onto a screen. */\n private _enterScreenHooks = new Map<ScreenName, (() => void)[]>();\n\n /** Gate promises derived from workflow step definitions. */\n private _gates = new Map<string, GateEntry>();\n\n version = '';\n\n /** Navigation router — resolves active screen from session state. */\n readonly router: WizardRouter;\n\n /** Blocks agent execution until the settings-override overlay is dismissed. */\n private _resolveSettingsOverride: (() => void) | null = null;\n private _backupAndFixSettings: (() => boolean) | null = null;\n\n /** Blocks OAuth flow until the port-conflict overlay is dismissed. */\n private _resolvePortConflict: (() => void) | null = null;\n\n constructor(flow: Flow = Flow.PostHogIntegration) {\n this.router = new WizardRouter(flow);\n this._initFromWorkflow(flow);\n }\n\n /**\n * Scan workflow steps for gate predicates and onInit callbacks.\n * Creates gate promises and fires init work.\n */\n private _initFromWorkflow(flow: Flow): void {\n const steps = WORKFLOW_STEPS[flow];\n if (!steps) return;\n\n // Create gate promises from steps that define them\n for (const step of steps) {\n if (step.gate) {\n let resolve!: () => void;\n const promise = new Promise<void>((r) => {\n resolve = r;\n });\n this._gates.set(step.id, {\n predicate: step.gate,\n promise,\n resolve,\n resolved: false,\n });\n }\n }\n\n // Run onInit callbacks with a minimal context interface.\n // Arrow functions capture `this` from _initFromWorkflow so we don't\n // need to alias it.\n const getSession = (): WizardSession => this.session;\n const ctx: StoreInitContext = {\n get session() {\n return getSession();\n },\n setReadinessResult: (r) => this.setReadinessResult(r),\n setFrameworkContext: (k, v) => this.setFrameworkContext(k, v),\n emitChange: () => this.emitChange(),\n };\n for (const step of steps) {\n step.onInit?.(ctx);\n }\n }\n\n /**\n * Run all `onReady` hooks declared by the current flow's steps, in\n * order. Must be called after `store.session = session` so hooks see\n * the real installDir. bin.ts calls this generically — it doesn't\n * need to know which workflow has which pre-flow work.\n */\n async runReadyHooks(): Promise<void> {\n const steps = WORKFLOW_STEPS[this.router.activeFlow];\n if (!steps) return;\n const ctx: WorkflowReadyContext = {\n session: this.session,\n setFrameworkContext: (k, v) => this.setFrameworkContext(k, v),\n setFrameworkConfig: (i, c) => this.setFrameworkConfig(i, c),\n setDetectedFramework: (l) => this.setDetectedFramework(l),\n setUnsupportedVersion: (info) => this.setUnsupportedVersion(info),\n addDiscoveredFeature: (f) => this.addDiscoveredFeature(f),\n setDetectionComplete: () => this.setDetectionComplete(),\n };\n for (const step of steps) {\n if (step.onReady) {\n await step.onReady(ctx);\n }\n }\n }\n\n // ── Gate API ────────────────────────────────────────────────────\n\n /**\n * Get a gate promise by step ID — the primary blocking checkpoint API\n * for bin.ts. `await store.getGate('...')` parks the caller until the\n * corresponding workflow step's gate predicate flips to true (if the\n * predicate stays false, the caller stays parked indefinitely — the\n * TUI keeps rendering so the user can resolve whatever is blocking).\n *\n * If the workflow doesn't define a step with this ID, or the step\n * has no `gate` predicate, this returns an already-resolved promise\n * so bin.ts flows straight through. This lets workflows opt in to\n * gates on a per-step basis without bin.ts needing to know which\n * gates exist in which flow.\n */\n getGate(stepId: string): Promise<void> {\n return this._gates.get(stepId)?.promise ?? Promise.resolve();\n }\n\n /**\n * Re-evaluate every gate predicate against the current session and\n * resolve any whose predicate now returns true. Called after every\n * emitChange(), so gates unblock as soon as the session mutation\n * that satisfies them lands. Gates only resolve once — a predicate\n * that goes true → false → true will NOT re-block a caller that\n * already awaited through.\n */\n private _checkGates(): void {\n for (const [, gate] of this._gates) {\n if (!gate.resolved && gate.predicate(this.session)) {\n gate.resolved = true;\n gate.resolve();\n }\n }\n }\n\n // ── State accessors (read from atoms) ────────────────────────────\n\n get session(): WizardSession {\n return this.$session.get();\n }\n\n set session(value: WizardSession) {\n this.$session.set(value);\n this.emitChange();\n }\n\n get statusMessages(): string[] {\n return this.$statusMessages.get();\n }\n\n get tasks(): TaskItem[] {\n return this.$tasks.get();\n }\n\n get eventPlan(): PlannedEvent[] {\n return this.$eventPlan.get();\n }\n\n get statusExpanded(): boolean {\n return this.$statusExpanded.get();\n }\n\n toggleStatusExpanded(): void {\n this.$statusExpanded.set(!this.$statusExpanded.get());\n this.emitChange();\n }\n\n setStatusExpanded(expanded: boolean): void {\n if (this.$statusExpanded.get() !== expanded) {\n this.$statusExpanded.set(expanded);\n this.emitChange();\n }\n }\n\n // ── Session setters ─────────────────────────────────────────────\n // Every setter that affects screen resolution calls emitChange().\n // Business logic calls these instead of mutating session directly.\n\n /** Sets setupConfirmed. Gate resolves via _checkGates(). */\n completeSetup(): void {\n this.$session.setKey('setupConfirmed', true);\n analytics.wizardCapture('setup confirmed', sessionProperties(this.session));\n this.emitChange();\n }\n\n setRunPhase(phase: RunPhase): void {\n this.$session.setKey('runPhase', phase);\n this.emitChange();\n }\n\n setCredentials(credentials: WizardSession['credentials']): void {\n this.$session.setKey('credentials', credentials);\n analytics.wizardCapture('auth complete', {\n project_id: credentials?.projectId,\n });\n this.emitChange();\n }\n\n setFrameworkConfig(\n integration: WizardSession['integration'],\n config: WizardSession['frameworkConfig'],\n ): void {\n this.$session.setKey('integration', integration);\n this.$session.setKey('frameworkConfig', config);\n this.$session.setKey('unsupportedVersion', null);\n this.emitChange();\n }\n\n setDetectionComplete(): void {\n this.$session.setKey('detectionComplete', true);\n this.emitChange();\n }\n\n setDetectedFramework(label: string): void {\n this.$session.setKey('detectedFrameworkLabel', label);\n this.emitChange();\n }\n\n setUnsupportedVersion(info: {\n current: string;\n minimum: string;\n docsUrl: string;\n }): void {\n this.$session.setKey('unsupportedVersion', info);\n this.emitChange();\n }\n\n setLoginUrl(url: string | null): void {\n this.$session.setKey('loginUrl', url);\n this.emitChange();\n }\n\n setReadinessResult(result: WizardReadinessResult | null): void {\n this.$session.setKey('readinessResult', result);\n this.emitChange();\n }\n\n /** User dismissed the blocking outage screen. Gate resolves via _checkGates(). */\n dismissOutage(): void {\n this.$session.setKey('outageDismissed', true);\n this.emitChange();\n }\n\n /**\n * Push the settings-override overlay and return a promise that blocks\n * until the user dismisses it via backupAndFixSettingsOverride().\n */\n showSettingsOverride(\n conflicts: SettingsConflict[],\n backupAndFix: () => boolean,\n ): Promise<void> {\n const allKeys = conflicts.flatMap((c) => c.keys);\n this.$session.setKey('settingsOverrideKeys', allKeys);\n this.$session.setKey('settingsConflicts', conflicts);\n this._backupAndFixSettings = backupAndFix;\n\n const hasReadOnly = conflicts.some((c) => !c.writable);\n if (hasReadOnly) {\n this.pushOverlay(Overlay.ManagedSettings);\n } else {\n this.pushOverlay(Overlay.SettingsOverride);\n }\n\n return new Promise((resolve) => {\n this._resolveSettingsOverride = resolve;\n });\n }\n\n /**\n * Push the port-conflict overlay and return a promise that blocks\n * until the user kills the blocking process or exits.\n */\n showPortConflict(processInfo: {\n command: string;\n pid: string;\n user: string;\n }): Promise<void> {\n this.$session.setKey('portConflictProcess', processInfo);\n this.pushOverlay(Overlay.PortConflict);\n return new Promise((resolve) => {\n this._resolvePortConflict = resolve;\n });\n }\n\n /** Dismiss the port-conflict overlay after the user kills the process. */\n resolvePortConflict(): void {\n this.$session.setKey('portConflictProcess', null);\n this.popOverlay();\n this._resolvePortConflict?.();\n this._resolvePortConflict = null;\n }\n\n /**\n * Back up .claude/settings.json. Dismisses the overlay on success.\n */\n backupAndFixSettingsOverride(): boolean {\n const ok = this._backupAndFixSettings?.() ?? false;\n if (ok) {\n this.$session.setKey('settingsOverrideKeys', null);\n this.$session.setKey('settingsConflicts', null);\n this.popOverlay();\n this._resolveSettingsOverride?.();\n this._resolveSettingsOverride = null;\n this._backupAndFixSettings = null;\n }\n return ok;\n }\n\n /** Push the auth-error overlay (no dismiss — user must exit). */\n showAuthError(): void {\n this.pushOverlay(Overlay.AuthError);\n }\n\n addDiscoveredFeature(feature: DiscoveredFeature): void {\n if (!this.session.discoveredFeatures.includes(feature)) {\n this.session.discoveredFeatures.push(feature);\n this.emitChange();\n }\n }\n\n /**\n * Enable an additional feature: enqueue it for the stop hook\n * and set any feature-specific session flags.\n */\n enableFeature(feature: AdditionalFeature): void {\n if (!this.session.additionalFeatureQueue.includes(feature)) {\n this.session.additionalFeatureQueue.push(feature);\n }\n // Feature-specific flags\n if (feature === AdditionalFeature.LLM) {\n this.session.llmOptIn = true;\n }\n analytics.wizardCapture('feature enabled', { feature });\n this.emitChange();\n }\n\n setMcpComplete(\n outcome: McpOutcome = McpOutcome.Skipped,\n installedClients: string[] = [],\n ): void {\n this.$session.setKey('mcpComplete', true);\n this.$session.setKey('mcpOutcome', outcome);\n this.$session.setKey('mcpInstalledClients', installedClients);\n analytics.wizardCapture('mcp complete', {\n mcp_outcome: outcome,\n mcp_installed_clients: installedClients,\n ...sessionProperties(this.session),\n });\n this.emitChange();\n }\n\n setSkillsComplete(kept: boolean): void {\n this.$session.setKey('skillsComplete', true);\n analytics.wizardCapture('skills complete', {\n skills_kept: kept,\n ...sessionProperties(this.session),\n });\n this.emitChange();\n }\n\n setOutroDismissed(): void {\n this.$session.setKey('outroDismissed', true);\n this.emitChange();\n }\n\n setOutroData(data: OutroData): void {\n this.$session.setKey('outroData', data);\n this.emitChange();\n }\n\n setFrameworkContext(key: string, value: unknown): void {\n const ctx = { ...this.$session.get().frameworkContext, [key]: value };\n this.$session.setKey('frameworkContext', ctx);\n this.emitChange();\n }\n\n // ── Derived state ───────────────────────────────────────────────\n\n /**\n * The screen that should be rendered right now.\n * Derived from session state via the router.\n */\n get currentScreen(): ScreenName {\n return this.router.resolve(this.session);\n }\n\n /** Direction hint for screen transitions. */\n get lastNavDirection(): 'push' | 'pop' | null {\n return this.router.lastNavDirection;\n }\n\n // ── Change notification ─────────────────────────────────────────\n\n getVersion(): number {\n return this.$version.get();\n }\n\n /**\n * Notify React that state has changed.\n * The router re-resolves the active screen on next render.\n * Gate predicates are checked and resolved if ready.\n */\n emitChange(): void {\n this.router._setDirection('push');\n this.$version.set(this.$version.get() + 1);\n this._checkGates();\n this._detectTransition();\n }\n\n // ── Overlay navigation ──────────────────────────────────────────\n\n pushOverlay(overlay: Overlay): void {\n this.router._setDirection('push');\n this.router.pushOverlay(overlay);\n this.$version.set(this.$version.get() + 1);\n this._detectTransition();\n }\n\n popOverlay(): void {\n this.router._setDirection('pop');\n this.router.popOverlay();\n this.$version.set(this.$version.get() + 1);\n this._detectTransition();\n }\n\n // ── Screen transition analytics ─────────────────────────────────\n\n /**\n * Register a callback to run when transitioning onto the given screen.\n * Fires after every transition that lands on this screen.\n */\n onEnterScreen(screen: ScreenName, fn: () => void): void {\n const list = this._enterScreenHooks.get(screen) ?? [];\n list.push(fn);\n this._enterScreenHooks.set(screen, list);\n }\n\n /**\n * Detect screen transitions, run enter-screen hooks, and fire analytics.\n * Called at the end of emitChange/pushOverlay/popOverlay.\n */\n private _detectTransition(): void {\n const next = this.router.resolve(this.session);\n const prev = this._lastScreen;\n if (prev !== null && next !== prev) {\n const hooks = this._enterScreenHooks.get(next);\n if (hooks) {\n for (const fn of hooks) fn();\n }\n analytics.wizardCapture(`screen ${next}`, {\n from_screen: prev,\n workflow: this.router.activeFlow,\n ...sessionProperties(this.session),\n });\n }\n this._lastScreen = next;\n }\n\n // ── Agent observation state ─────────────────────────────────────\n\n pushStatus(message: string): void {\n const msgs = this.$statusMessages.get();\n // Skip consecutive duplicate messages\n if (msgs.length > 0 && msgs[msgs.length - 1] === message) return;\n this.$statusMessages.set([...msgs, message]);\n this.emitChange();\n }\n\n setTasks(tasks: TaskItem[]): void {\n this.$tasks.set(tasks);\n this.emitChange();\n }\n\n updateTask(index: number, done: boolean): void {\n const tasks = this.$tasks.get();\n if (tasks[index]) {\n const updated = [...tasks];\n updated[index] = {\n ...updated[index],\n done,\n status: done ? TaskStatus.Completed : TaskStatus.Pending,\n };\n this.$tasks.set(updated);\n this.emitChange();\n }\n }\n\n setEventPlan(events: PlannedEvent[]): void {\n this.$eventPlan.set(events);\n this.emitChange();\n }\n\n get learnCardBlockIdx(): number {\n return this.$learnCardBlockIdx.get();\n }\n\n setLearnCardBlockIdx(idx: number): void {\n this.$learnCardBlockIdx.set(idx);\n }\n\n get learnCardComplete(): boolean {\n return this.$learnCardComplete.get();\n }\n\n setLearnCardComplete(): void {\n this.$learnCardComplete.set(true);\n this.emitChange();\n }\n\n syncTodos(\n todos: Array<{ content: string; status: string; activeForm?: string }>,\n ): void {\n const incoming = todos.map((t) => ({\n label: t.content,\n activeForm: t.activeForm,\n status: (t.status as TaskStatus) || TaskStatus.Pending,\n done: t.status === TaskStatus.Completed,\n }));\n\n const incomingLabels = new Set(incoming.map((t) => t.label));\n\n const retained = this.$tasks\n .get()\n .filter((t) => t.done && !incomingLabels.has(t.label));\n\n this.$tasks.set([...retained, ...incoming]);\n this.emitChange();\n }\n\n // ── React integration ───────────────────────────────────────────\n\n subscribe(callback: () => void): () => void {\n return this.$version.listen(() => callback());\n }\n\n getSnapshot(): number {\n return this.$version.get();\n }\n}\n"]}
@@ -7,7 +7,9 @@
7
7
  * No prompt methods — the TUI screens own all user input.
8
8
  * Session-mutating methods trigger reactive screen resolution in the TUI.
9
9
  */
10
- import type { SettingsConflict } from '../lib/agent-interface';
10
+ import type { SettingsConflict } from '../lib/agent/agent-interface';
11
+ import type { WizardReadinessResult } from '../lib/health-checks/readiness.js';
12
+ import type { OutroData } from '../lib/wizard-session';
11
13
  export declare enum TaskStatus {
12
14
  Pending = "pending",
13
15
  InProgress = "in_progress",
@@ -20,7 +22,15 @@ export interface SpinnerHandle {
20
22
  }
21
23
  export interface WizardUI {
22
24
  intro(message: string): void;
25
+ /** Success outro with a plain text message. */
23
26
  outro(message: string): void;
27
+ /**
28
+ * Error outro. Sets structured outroData and transitions run phase so
29
+ * the router advances to the outro screen. Use for abort/failure paths
30
+ * that need a custom error render — do NOT build the outroData by
31
+ * mutating session directly (nanostore holds a shallow copy).
32
+ */
33
+ outroError(data: OutroData): void;
24
34
  cancel(message: string): void;
25
35
  log: {
26
36
  info(message: string): void;
@@ -42,9 +52,9 @@ export interface WizardUI {
42
52
  projectId: number;
43
53
  }): void;
44
54
  /** Show blocking service outage (pushes outage overlay in TUI). Blocks until dismissed. */
45
- showBlockingOutage(result: import('../lib/health-checks/readiness.js').WizardReadinessResult): Promise<void>;
55
+ showBlockingOutage(result: WizardReadinessResult): Promise<void>;
46
56
  /** Store non-blocking readiness warnings (shown as Health tab in RunScreen). */
47
- setReadinessWarnings(result: import('../lib/health-checks/readiness.js').WizardReadinessResult): void;
57
+ setReadinessWarnings(result: WizardReadinessResult): void;
48
58
  /** Warn that another process is blocking the OAuth port (pushes overlay in TUI). */
49
59
  showPortConflict(processInfo: {
50
60
  command: string;
@@ -1 +1 @@
1
- {"version":3,"file":"wizard-ui.js","sourceRoot":"","sources":["../../../src/ui/wizard-ui.ts"],"names":[],"mappings":";AAAA;;;;;;;;GAQG;;;AAIH,IAAY,UAIX;AAJD,WAAY,UAAU;IACpB,iCAAmB,CAAA;IACnB,wCAA0B,CAAA;IAC1B,qCAAuB,CAAA;AACzB,CAAC,EAJW,UAAU,0BAAV,UAAU,QAIrB","sourcesContent":["/**\n * WizardUI — abstraction layer for all user-facing operations.\n *\n * Business logic calls `getUI()` instead of importing the store directly.\n * Implementations: InkUI (TUI), LoggingUI (CI).\n *\n * No prompt methods — the TUI screens own all user input.\n * Session-mutating methods trigger reactive screen resolution in the TUI.\n */\n\nimport type { SettingsConflict } from '../lib/agent-interface';\n\nexport enum TaskStatus {\n Pending = 'pending',\n InProgress = 'in_progress',\n Completed = 'completed',\n}\n\nexport interface SpinnerHandle {\n start(message?: string): void;\n stop(message?: string): void;\n message(msg?: string): void;\n}\n\nexport interface WizardUI {\n // ── Lifecycle messages ────────────────────────────────────────────\n intro(message: string): void;\n outro(message: string): void;\n cancel(message: string): void;\n\n // ── Logging ───────────────────────────────────────────────────────\n log: {\n info(message: string): void;\n warn(message: string): void;\n error(message: string): void;\n success(message: string): void;\n step(message: string): void;\n };\n\n note(message: string): void;\n pushStatus(message: string): void;\n\n // ── Spinner ───────────────────────────────────────────────────────\n spinner(): SpinnerHandle;\n\n // ── Session state (triggers reactive screen resolution in TUI) ────\n /** Signal that the main work (agent run) has started. */\n startRun(): void;\n\n /** Store OAuth/API credentials. Resolves past AuthScreen in TUI. */\n setCredentials(credentials: {\n accessToken: string;\n projectApiKey: string;\n host: string;\n projectId: number;\n }): void;\n\n /** Show blocking service outage (pushes outage overlay in TUI). Blocks until dismissed. */\n showBlockingOutage(\n result: import('../lib/health-checks/readiness.js').WizardReadinessResult,\n ): Promise<void>;\n\n /** Store non-blocking readiness warnings (shown as Health tab in RunScreen). */\n setReadinessWarnings(\n result: import('../lib/health-checks/readiness.js').WizardReadinessResult,\n ): void;\n\n /** Warn that another process is blocking the OAuth port (pushes overlay in TUI). */\n showPortConflict(processInfo: {\n command: string;\n pid: string;\n user: string;\n }): Promise<void>;\n\n showSettingsOverride(\n conflicts: SettingsConflict[],\n backupAndFix: () => boolean,\n ): Promise<void>;\n\n /** Show auth error overlay when Anthropic API returns 401. */\n showAuthError(): void;\n\n // ── Display state ──────────────────────────────────────────────────\n /** Set the detected framework label (e.g., \"Django with Wagtail CMS\") */\n setDetectedFramework(label: string): void;\n\n /** Register a callback to run when the TUI transitions onto the given screen. */\n onEnterScreen(screen: string, fn: () => void): void;\n\n setLoginUrl(url: string | null): void;\n\n // ── Todo tracking from SDK TodoWrite events ───────────────────────\n syncTodos(\n todos: Array<{ content: string; status: string; activeForm?: string }>,\n ): void;\n\n // ── Event plan from .posthog-events.json ────────────────────\n setEventPlan(events: Array<{ name: string; description: string }>): void;\n}\n"]}
1
+ {"version":3,"file":"wizard-ui.js","sourceRoot":"","sources":["../../../src/ui/wizard-ui.ts"],"names":[],"mappings":";AAAA;;;;;;;;GAQG;;;AAMH,IAAY,UAIX;AAJD,WAAY,UAAU;IACpB,iCAAmB,CAAA;IACnB,wCAA0B,CAAA;IAC1B,qCAAuB,CAAA;AACzB,CAAC,EAJW,UAAU,0BAAV,UAAU,QAIrB","sourcesContent":["/**\n * WizardUI — abstraction layer for all user-facing operations.\n *\n * Business logic calls `getUI()` instead of importing the store directly.\n * Implementations: InkUI (TUI), LoggingUI (CI).\n *\n * No prompt methods — the TUI screens own all user input.\n * Session-mutating methods trigger reactive screen resolution in the TUI.\n */\n\nimport type { SettingsConflict } from '../lib/agent/agent-interface';\nimport type { WizardReadinessResult } from '../lib/health-checks/readiness.js';\nimport type { OutroData } from '../lib/wizard-session';\n\nexport enum TaskStatus {\n Pending = 'pending',\n InProgress = 'in_progress',\n Completed = 'completed',\n}\n\nexport interface SpinnerHandle {\n start(message?: string): void;\n stop(message?: string): void;\n message(msg?: string): void;\n}\n\nexport interface WizardUI {\n // ── Lifecycle messages ────────────────────────────────────────────\n intro(message: string): void;\n /** Success outro with a plain text message. */\n outro(message: string): void;\n /**\n * Error outro. Sets structured outroData and transitions run phase so\n * the router advances to the outro screen. Use for abort/failure paths\n * that need a custom error render — do NOT build the outroData by\n * mutating session directly (nanostore holds a shallow copy).\n */\n outroError(data: OutroData): void;\n cancel(message: string): void;\n\n // ── Logging ───────────────────────────────────────────────────────\n log: {\n info(message: string): void;\n warn(message: string): void;\n error(message: string): void;\n success(message: string): void;\n step(message: string): void;\n };\n\n note(message: string): void;\n pushStatus(message: string): void;\n\n // ── Spinner ───────────────────────────────────────────────────────\n spinner(): SpinnerHandle;\n\n // ── Session state (triggers reactive screen resolution in TUI) ────\n /** Signal that the main work (agent run) has started. */\n startRun(): void;\n\n /** Store OAuth/API credentials. Resolves past AuthScreen in TUI. */\n setCredentials(credentials: {\n accessToken: string;\n projectApiKey: string;\n host: string;\n projectId: number;\n }): void;\n\n /** Show blocking service outage (pushes outage overlay in TUI). Blocks until dismissed. */\n showBlockingOutage(result: WizardReadinessResult): Promise<void>;\n\n /** Store non-blocking readiness warnings (shown as Health tab in RunScreen). */\n setReadinessWarnings(result: WizardReadinessResult): void;\n\n /** Warn that another process is blocking the OAuth port (pushes overlay in TUI). */\n showPortConflict(processInfo: {\n command: string;\n pid: string;\n user: string;\n }): Promise<void>;\n\n showSettingsOverride(\n conflicts: SettingsConflict[],\n backupAndFix: () => boolean,\n ): Promise<void>;\n\n /** Show auth error overlay when Anthropic API returns 401. */\n showAuthError(): void;\n\n // ── Display state ──────────────────────────────────────────────────\n /** Set the detected framework label (e.g., \"Django with Wagtail CMS\") */\n setDetectedFramework(label: string): void;\n\n /** Register a callback to run when the TUI transitions onto the given screen. */\n onEnterScreen(screen: string, fn: () => void): void;\n\n setLoginUrl(url: string | null): void;\n\n // ── Todo tracking from SDK TodoWrite events ───────────────────────\n syncTodos(\n todos: Array<{ content: string; status: string; activeForm?: string }>,\n ): void;\n\n // ── Event plan from .posthog-events.json ────────────────────\n setEventPlan(events: Array<{ name: string; description: string }>): void;\n}\n"]}
@@ -1,2 +1,10 @@
1
1
  import type { WizardOptions } from './types';
2
2
  export declare function getDotGitignore({ installDir, }: Pick<WizardOptions, 'installDir'>): string | undefined;
3
+ /**
4
+ * Directory names to skip when recursively scanning a project tree.
5
+ * Used by detection logic (e.g. finding all package.json files) to avoid
6
+ * dependency directories, build output, virtual environments, etc.
7
+ *
8
+ * For fast-glob `ignore` patterns, map this to `**\/<name>/**`.
9
+ */
10
+ export declare const IGNORED_DIRS: Set<string>;