@amplitude/wizard 1.0.0-beta.2 → 1.0.0-beta.5

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 (391) hide show
  1. package/README.md +171 -74
  2. package/dist/bin.js +338 -222
  3. package/dist/src/lib/agent-interface.js +64 -9
  4. package/dist/src/lib/agent-runner.js +1 -10
  5. package/dist/src/lib/api.d.ts +22 -4
  6. package/dist/src/lib/api.js +114 -12
  7. package/dist/src/lib/commandments.js +14 -1
  8. package/dist/src/lib/constants.d.ts +5 -4
  9. package/dist/src/lib/constants.js +9 -11
  10. package/dist/src/lib/credential-resolution.d.ts +45 -0
  11. package/dist/src/lib/credential-resolution.js +311 -0
  12. package/dist/src/lib/exit-codes.d.ts +10 -0
  13. package/dist/src/lib/exit-codes.js +12 -0
  14. package/dist/src/lib/health-checks/statuspage.d.ts +1 -0
  15. package/dist/src/lib/health-checks/statuspage.js +5 -1
  16. package/dist/src/lib/mode-config.d.ts +14 -0
  17. package/dist/src/lib/mode-config.js +14 -0
  18. package/dist/src/lib/session-checkpoint.d.ts +27 -0
  19. package/dist/src/lib/session-checkpoint.js +134 -0
  20. package/dist/src/lib/wizard-session.d.ts +44 -1
  21. package/dist/src/lib/wizard-session.js +70 -14
  22. package/dist/src/lib/wizard-tools.js +19 -4
  23. package/dist/src/steps/add-mcp-server-to-clients/clients/claude.d.ts +3 -0
  24. package/dist/src/steps/add-mcp-server-to-clients/clients/claude.js +6 -0
  25. package/dist/src/steps/add-mcp-server-to-clients/clients/cursor.js +3 -1
  26. package/dist/src/ui/agent-ui.d.ts +91 -0
  27. package/dist/src/ui/agent-ui.js +277 -0
  28. package/dist/src/ui/logging-ui.js +1 -1
  29. package/dist/src/ui/tui/App.d.ts +12 -0
  30. package/dist/src/ui/tui/App.js +29 -18
  31. package/dist/src/ui/tui/components/AmplitudeLogo.js +16 -17
  32. package/dist/src/ui/tui/components/AmplitudeTextLogo.d.ts +0 -2
  33. package/dist/src/ui/tui/components/AmplitudeTextLogo.js +53 -18
  34. package/dist/src/ui/tui/components/BrailleSpinner.d.ts +8 -0
  35. package/dist/src/ui/tui/components/BrailleSpinner.js +15 -0
  36. package/dist/src/ui/tui/components/ConsoleView.d.ts +8 -11
  37. package/dist/src/ui/tui/components/ConsoleView.js +51 -34
  38. package/dist/src/ui/tui/components/HeaderBar.d.ts +12 -0
  39. package/dist/src/ui/tui/components/HeaderBar.js +17 -0
  40. package/dist/src/ui/tui/components/JourneyStepper.d.ts +16 -0
  41. package/dist/src/ui/tui/components/JourneyStepper.js +83 -0
  42. package/dist/src/ui/tui/components/KeyHintBar.d.ts +19 -0
  43. package/dist/src/ui/tui/components/KeyHintBar.js +20 -0
  44. package/dist/src/ui/tui/console-commands.d.ts +1 -2
  45. package/dist/src/ui/tui/console-commands.js +48 -7
  46. package/dist/src/ui/tui/flows.d.ts +1 -1
  47. package/dist/src/ui/tui/flows.js +1 -1
  48. package/dist/src/ui/tui/hooks/useAsyncEffect.d.ts +15 -0
  49. package/dist/src/ui/tui/hooks/useAsyncEffect.js +35 -0
  50. package/dist/src/ui/tui/hooks/useWizardStore.d.ts +9 -0
  51. package/dist/src/ui/tui/hooks/useWizardStore.js +11 -0
  52. package/dist/src/ui/tui/ink-ui.js +1 -1
  53. package/dist/src/ui/tui/primitives/DissolveTransition.js +4 -5
  54. package/dist/src/ui/tui/primitives/EventPlanViewer.d.ts +3 -1
  55. package/dist/src/ui/tui/primitives/EventPlanViewer.js +8 -3
  56. package/dist/src/ui/tui/primitives/ProgressList.js +1 -1
  57. package/dist/src/ui/tui/primitives/SlashCommandInput.js +19 -4
  58. package/dist/src/ui/tui/primitives/SplitView.d.ts +2 -1
  59. package/dist/src/ui/tui/primitives/SplitView.js +10 -2
  60. package/dist/src/ui/tui/primitives/TabContainer.js +10 -2
  61. package/dist/src/ui/tui/primitives/index.d.ts +0 -1
  62. package/dist/src/ui/tui/primitives/index.js +0 -1
  63. package/dist/src/ui/tui/router.js +1 -1
  64. package/dist/src/ui/tui/screen-registry.d.ts +0 -7
  65. package/dist/src/ui/tui/screen-registry.js +13 -4
  66. package/dist/src/ui/tui/screens/ActivationOptionsScreen.d.ts +2 -2
  67. package/dist/src/ui/tui/screens/ActivationOptionsScreen.js +8 -8
  68. package/dist/src/ui/tui/screens/AuthScreen.js +57 -27
  69. package/dist/src/ui/tui/screens/ChecklistScreen.d.ts +2 -12
  70. package/dist/src/ui/tui/screens/ChecklistScreen.js +22 -33
  71. package/dist/src/ui/tui/screens/DataIngestionCheckScreen.d.ts +3 -12
  72. package/dist/src/ui/tui/screens/DataIngestionCheckScreen.js +109 -39
  73. package/dist/src/ui/tui/screens/DataSetupScreen.d.ts +3 -3
  74. package/dist/src/ui/tui/screens/DataSetupScreen.js +17 -10
  75. package/dist/src/ui/tui/screens/IntroScreen.d.ts +5 -3
  76. package/dist/src/ui/tui/screens/IntroScreen.js +132 -41
  77. package/dist/src/ui/tui/screens/LoginScreen.d.ts +1 -1
  78. package/dist/src/ui/tui/screens/LoginScreen.js +4 -4
  79. package/dist/src/ui/tui/screens/LogoutScreen.d.ts +4 -2
  80. package/dist/src/ui/tui/screens/LogoutScreen.js +17 -5
  81. package/dist/src/ui/tui/screens/McpScreen.d.ts +4 -4
  82. package/dist/src/ui/tui/screens/McpScreen.js +25 -17
  83. package/dist/src/ui/tui/screens/OutageScreen.d.ts +1 -1
  84. package/dist/src/ui/tui/screens/OutageScreen.js +5 -5
  85. package/dist/src/ui/tui/screens/OutroScreen.d.ts +5 -0
  86. package/dist/src/ui/tui/screens/OutroScreen.js +21 -14
  87. package/dist/src/ui/tui/screens/RegionSelectScreen.js +15 -13
  88. package/dist/src/ui/tui/screens/RunScreen.d.ts +7 -5
  89. package/dist/src/ui/tui/screens/RunScreen.js +102 -157
  90. package/dist/src/ui/tui/screens/SettingsOverrideScreen.d.ts +1 -1
  91. package/dist/src/ui/tui/screens/SettingsOverrideScreen.js +6 -5
  92. package/dist/src/ui/tui/screens/SetupScreen.d.ts +1 -1
  93. package/dist/src/ui/tui/screens/SetupScreen.js +7 -7
  94. package/dist/src/ui/tui/screens/SlackScreen.d.ts +2 -2
  95. package/dist/src/ui/tui/screens/SlackScreen.js +60 -35
  96. package/dist/src/ui/tui/session-constants.d.ts +41 -0
  97. package/dist/src/ui/tui/session-constants.js +38 -0
  98. package/dist/src/ui/tui/start-tui.d.ts +3 -1
  99. package/dist/src/ui/tui/start-tui.js +14 -10
  100. package/dist/src/ui/tui/store.d.ts +2 -1
  101. package/dist/src/ui/tui/store.js +33 -7
  102. package/dist/src/ui/tui/styles.d.ts +75 -19
  103. package/dist/src/ui/tui/styles.js +101 -19
  104. package/dist/src/ui/tui/utils/classify-error.d.ts +14 -0
  105. package/dist/src/ui/tui/utils/classify-error.js +90 -0
  106. package/dist/src/ui/tui/utils/diagnostics.d.ts +21 -0
  107. package/dist/src/ui/tui/utils/diagnostics.js +72 -0
  108. package/dist/src/ui/tui/utils/with-retry.d.ts +12 -0
  109. package/dist/src/ui/tui/utils/with-retry.js +32 -0
  110. package/dist/src/ui/tui/utils/with-timeout.d.ts +10 -0
  111. package/dist/src/ui/tui/utils/with-timeout.js +24 -0
  112. package/dist/src/utils/ampli-settings.d.ts +1 -1
  113. package/dist/src/utils/ampli-settings.js +15 -5
  114. package/dist/src/utils/api-key-store.js +5 -5
  115. package/dist/src/utils/atomic-write.d.ts +15 -0
  116. package/dist/src/utils/atomic-write.js +34 -0
  117. package/dist/src/utils/setup-utils.js +2 -2
  118. package/dist/src/utils/token-refresh.d.ts +22 -0
  119. package/dist/src/utils/token-refresh.js +79 -0
  120. package/dist/src/utils/wizard-abort.js +6 -1
  121. package/package.json +5 -5
  122. package/skills/instrumentation/add-analytics-instrumentation/SKILL.md +142 -0
  123. package/skills/instrumentation/diff-intake/SKILL.md +128 -0
  124. package/skills/instrumentation/discover-analytics-patterns/SKILL.md +185 -0
  125. package/skills/instrumentation/discover-event-surfaces/SKILL.md +322 -0
  126. package/skills/instrumentation/discover-event-surfaces/references/best-practices.md +563 -0
  127. package/skills/instrumentation/instrument-events/SKILL.md +169 -0
  128. package/skills/instrumentation/instrument-events/references/best-practices.md +563 -0
  129. package/skills/integration/integration-android/SKILL.md +49 -0
  130. package/skills/integration/integration-android/references/EXAMPLE.md +1977 -0
  131. package/skills/integration/integration-android/references/amplitude-quickstart.md +1845 -0
  132. package/skills/integration/integration-android/references/analytics.md +1778 -0
  133. package/skills/integration/integration-android/references/basic-integration-1.0-begin.md +43 -0
  134. package/skills/integration/integration-android/references/basic-integration-1.1-edit.md +35 -0
  135. package/skills/integration/integration-android/references/basic-integration-1.2-revise.md +23 -0
  136. package/skills/integration/integration-android/references/basic-integration-1.3-conclude.md +57 -0
  137. package/skills/integration/integration-angular/SKILL.md +49 -0
  138. package/skills/integration/integration-angular/references/EXAMPLE.md +899 -0
  139. package/skills/integration/integration-angular/references/amplitude-quickstart.md +1845 -0
  140. package/skills/integration/integration-angular/references/basic-integration-1.0-begin.md +43 -0
  141. package/skills/integration/integration-angular/references/basic-integration-1.1-edit.md +35 -0
  142. package/skills/integration/integration-angular/references/basic-integration-1.2-revise.md +23 -0
  143. package/skills/integration/integration-angular/references/basic-integration-1.3-conclude.md +57 -0
  144. package/skills/integration/integration-angular/references/browser-sdk-2.md +4680 -0
  145. package/skills/integration/integration-astro-hybrid/SKILL.md +56 -0
  146. package/skills/integration/integration-astro-hybrid/references/EXAMPLE.md +1095 -0
  147. package/skills/integration/integration-astro-hybrid/references/amplitude-quickstart.md +1845 -0
  148. package/skills/integration/integration-astro-hybrid/references/basic-integration-1.0-begin.md +43 -0
  149. package/skills/integration/integration-astro-hybrid/references/basic-integration-1.1-edit.md +35 -0
  150. package/skills/integration/integration-astro-hybrid/references/basic-integration-1.2-revise.md +23 -0
  151. package/skills/integration/integration-astro-hybrid/references/basic-integration-1.3-conclude.md +57 -0
  152. package/skills/integration/integration-astro-hybrid/references/browser-sdk-2.md +4680 -0
  153. package/skills/integration/integration-astro-ssr/SKILL.md +52 -0
  154. package/skills/integration/integration-astro-ssr/references/EXAMPLE.md +1106 -0
  155. package/skills/integration/integration-astro-ssr/references/amplitude-quickstart.md +1845 -0
  156. package/skills/integration/integration-astro-ssr/references/basic-integration-1.0-begin.md +43 -0
  157. package/skills/integration/integration-astro-ssr/references/basic-integration-1.1-edit.md +35 -0
  158. package/skills/integration/integration-astro-ssr/references/basic-integration-1.2-revise.md +23 -0
  159. package/skills/integration/integration-astro-ssr/references/basic-integration-1.3-conclude.md +57 -0
  160. package/skills/integration/integration-astro-ssr/references/browser-sdk-2.md +4680 -0
  161. package/skills/integration/integration-astro-static/SKILL.md +49 -0
  162. package/skills/integration/integration-astro-static/references/EXAMPLE.md +910 -0
  163. package/skills/integration/integration-astro-static/references/amplitude-quickstart.md +1845 -0
  164. package/skills/integration/integration-astro-static/references/basic-integration-1.0-begin.md +43 -0
  165. package/skills/integration/integration-astro-static/references/basic-integration-1.1-edit.md +35 -0
  166. package/skills/integration/integration-astro-static/references/basic-integration-1.2-revise.md +23 -0
  167. package/skills/integration/integration-astro-static/references/basic-integration-1.3-conclude.md +57 -0
  168. package/skills/integration/integration-astro-static/references/browser-sdk-2.md +4680 -0
  169. package/skills/integration/integration-astro-view-transitions/SKILL.md +51 -0
  170. package/skills/integration/integration-astro-view-transitions/references/EXAMPLE.md +979 -0
  171. package/skills/integration/integration-astro-view-transitions/references/amplitude-quickstart.md +1845 -0
  172. package/skills/integration/integration-astro-view-transitions/references/basic-integration-1.0-begin.md +43 -0
  173. package/skills/integration/integration-astro-view-transitions/references/basic-integration-1.1-edit.md +35 -0
  174. package/skills/integration/integration-astro-view-transitions/references/basic-integration-1.2-revise.md +23 -0
  175. package/skills/integration/integration-astro-view-transitions/references/basic-integration-1.3-conclude.md +57 -0
  176. package/skills/integration/integration-astro-view-transitions/references/browser-sdk-2.md +4680 -0
  177. package/skills/integration/integration-django/SKILL.md +57 -0
  178. package/skills/integration/integration-django/references/EXAMPLE.md +1005 -0
  179. package/skills/integration/integration-django/references/amplitude-quickstart.md +1845 -0
  180. package/skills/integration/integration-django/references/basic-integration-1.0-begin.md +43 -0
  181. package/skills/integration/integration-django/references/basic-integration-1.1-edit.md +35 -0
  182. package/skills/integration/integration-django/references/basic-integration-1.2-revise.md +23 -0
  183. package/skills/integration/integration-django/references/basic-integration-1.3-conclude.md +57 -0
  184. package/skills/integration/integration-django/references/python.md +1424 -0
  185. package/skills/integration/integration-expo/SKILL.md +53 -0
  186. package/skills/integration/integration-expo/references/EXAMPLE.md +1291 -0
  187. package/skills/integration/integration-expo/references/amplitude-quickstart.md +1845 -0
  188. package/skills/integration/integration-expo/references/basic-integration-1.0-begin.md +43 -0
  189. package/skills/integration/integration-expo/references/basic-integration-1.1-edit.md +35 -0
  190. package/skills/integration/integration-expo/references/basic-integration-1.2-revise.md +23 -0
  191. package/skills/integration/integration-expo/references/basic-integration-1.3-conclude.md +57 -0
  192. package/skills/integration/integration-expo/references/react-native-sdk.md +2819 -0
  193. package/skills/integration/integration-fastapi/SKILL.md +57 -0
  194. package/skills/integration/integration-fastapi/references/EXAMPLE.md +1389 -0
  195. package/skills/integration/integration-fastapi/references/amplitude-quickstart.md +1845 -0
  196. package/skills/integration/integration-fastapi/references/basic-integration-1.0-begin.md +43 -0
  197. package/skills/integration/integration-fastapi/references/basic-integration-1.1-edit.md +35 -0
  198. package/skills/integration/integration-fastapi/references/basic-integration-1.2-revise.md +23 -0
  199. package/skills/integration/integration-fastapi/references/basic-integration-1.3-conclude.md +57 -0
  200. package/skills/integration/integration-fastapi/references/python.md +1424 -0
  201. package/skills/integration/integration-flask/SKILL.md +56 -0
  202. package/skills/integration/integration-flask/references/EXAMPLE.md +1130 -0
  203. package/skills/integration/integration-flask/references/amplitude-quickstart.md +1845 -0
  204. package/skills/integration/integration-flask/references/basic-integration-1.0-begin.md +43 -0
  205. package/skills/integration/integration-flask/references/basic-integration-1.1-edit.md +35 -0
  206. package/skills/integration/integration-flask/references/basic-integration-1.2-revise.md +23 -0
  207. package/skills/integration/integration-flask/references/basic-integration-1.3-conclude.md +57 -0
  208. package/skills/integration/integration-flask/references/python.md +1424 -0
  209. package/skills/integration/integration-javascript_node/SKILL.md +54 -0
  210. package/skills/integration/integration-javascript_node/references/EXAMPLE.md +365 -0
  211. package/skills/integration/integration-javascript_node/references/amplitude-quickstart.md +1845 -0
  212. package/skills/integration/integration-javascript_node/references/analytics.md +1778 -0
  213. package/skills/integration/integration-javascript_node/references/basic-integration-1.0-begin.md +43 -0
  214. package/skills/integration/integration-javascript_node/references/basic-integration-1.1-edit.md +35 -0
  215. package/skills/integration/integration-javascript_node/references/basic-integration-1.2-revise.md +23 -0
  216. package/skills/integration/integration-javascript_node/references/basic-integration-1.3-conclude.md +57 -0
  217. package/skills/integration/integration-javascript_web/SKILL.md +58 -0
  218. package/skills/integration/integration-javascript_web/references/EXAMPLE.md +451 -0
  219. package/skills/integration/integration-javascript_web/references/amplitude-quickstart.md +1845 -0
  220. package/skills/integration/integration-javascript_web/references/basic-integration-1.0-begin.md +43 -0
  221. package/skills/integration/integration-javascript_web/references/basic-integration-1.1-edit.md +35 -0
  222. package/skills/integration/integration-javascript_web/references/basic-integration-1.2-revise.md +23 -0
  223. package/skills/integration/integration-javascript_web/references/basic-integration-1.3-conclude.md +57 -0
  224. package/skills/integration/integration-javascript_web/references/browser-sdk-2.md +4680 -0
  225. package/skills/integration/integration-laravel/SKILL.md +52 -0
  226. package/skills/integration/integration-laravel/references/EXAMPLE.md +2039 -0
  227. package/skills/integration/integration-laravel/references/amplitude-quickstart.md +1845 -0
  228. package/skills/integration/integration-laravel/references/analytics.md +1778 -0
  229. package/skills/integration/integration-laravel/references/basic-integration-1.0-begin.md +43 -0
  230. package/skills/integration/integration-laravel/references/basic-integration-1.1-edit.md +35 -0
  231. package/skills/integration/integration-laravel/references/basic-integration-1.2-revise.md +23 -0
  232. package/skills/integration/integration-laravel/references/basic-integration-1.3-conclude.md +57 -0
  233. package/skills/integration/integration-nextjs-app-router/SKILL.md +54 -0
  234. package/skills/integration/integration-nextjs-app-router/references/EXAMPLE.md +673 -0
  235. package/skills/integration/integration-nextjs-app-router/references/amplitude-quickstart.md +1845 -0
  236. package/skills/integration/integration-nextjs-app-router/references/basic-integration-1.0-begin.md +43 -0
  237. package/skills/integration/integration-nextjs-app-router/references/basic-integration-1.1-edit.md +35 -0
  238. package/skills/integration/integration-nextjs-app-router/references/basic-integration-1.2-revise.md +23 -0
  239. package/skills/integration/integration-nextjs-app-router/references/basic-integration-1.3-conclude.md +57 -0
  240. package/skills/integration/integration-nextjs-app-router/references/browser-sdk-2.md +4680 -0
  241. package/skills/integration/integration-nextjs-pages-router/SKILL.md +54 -0
  242. package/skills/integration/integration-nextjs-pages-router/references/EXAMPLE.md +735 -0
  243. package/skills/integration/integration-nextjs-pages-router/references/amplitude-quickstart.md +1845 -0
  244. package/skills/integration/integration-nextjs-pages-router/references/basic-integration-1.0-begin.md +43 -0
  245. package/skills/integration/integration-nextjs-pages-router/references/basic-integration-1.1-edit.md +35 -0
  246. package/skills/integration/integration-nextjs-pages-router/references/basic-integration-1.2-revise.md +23 -0
  247. package/skills/integration/integration-nextjs-pages-router/references/basic-integration-1.3-conclude.md +57 -0
  248. package/skills/integration/integration-nextjs-pages-router/references/browser-sdk-2.md +4680 -0
  249. package/skills/integration/integration-nuxt-3.6/SKILL.md +46 -0
  250. package/skills/integration/integration-nuxt-3.6/references/EXAMPLE.md +8422 -0
  251. package/skills/integration/integration-nuxt-3.6/references/amplitude-quickstart.md +1845 -0
  252. package/skills/integration/integration-nuxt-3.6/references/basic-integration-1.0-begin.md +43 -0
  253. package/skills/integration/integration-nuxt-3.6/references/basic-integration-1.1-edit.md +35 -0
  254. package/skills/integration/integration-nuxt-3.6/references/basic-integration-1.2-revise.md +23 -0
  255. package/skills/integration/integration-nuxt-3.6/references/basic-integration-1.3-conclude.md +57 -0
  256. package/skills/integration/integration-nuxt-3.6/references/browser-sdk-2.md +4680 -0
  257. package/skills/integration/integration-nuxt-4/SKILL.md +46 -0
  258. package/skills/integration/integration-nuxt-4/references/EXAMPLE.md +8670 -0
  259. package/skills/integration/integration-nuxt-4/references/amplitude-quickstart.md +1845 -0
  260. package/skills/integration/integration-nuxt-4/references/basic-integration-1.0-begin.md +43 -0
  261. package/skills/integration/integration-nuxt-4/references/basic-integration-1.1-edit.md +35 -0
  262. package/skills/integration/integration-nuxt-4/references/basic-integration-1.2-revise.md +23 -0
  263. package/skills/integration/integration-nuxt-4/references/basic-integration-1.3-conclude.md +57 -0
  264. package/skills/integration/integration-nuxt-4/references/browser-sdk-2.md +4680 -0
  265. package/skills/integration/integration-python/SKILL.md +53 -0
  266. package/skills/integration/integration-python/references/EXAMPLE.md +445 -0
  267. package/skills/integration/integration-python/references/amplitude-quickstart.md +1845 -0
  268. package/skills/integration/integration-python/references/basic-integration-1.0-begin.md +43 -0
  269. package/skills/integration/integration-python/references/basic-integration-1.1-edit.md +35 -0
  270. package/skills/integration/integration-python/references/basic-integration-1.2-revise.md +23 -0
  271. package/skills/integration/integration-python/references/basic-integration-1.3-conclude.md +57 -0
  272. package/skills/integration/integration-python/references/python.md +1424 -0
  273. package/skills/integration/integration-react-native/SKILL.md +49 -0
  274. package/skills/integration/integration-react-native/references/EXAMPLE.md +2253 -0
  275. package/skills/integration/integration-react-native/references/amplitude-quickstart.md +1845 -0
  276. package/skills/integration/integration-react-native/references/basic-integration-1.0-begin.md +43 -0
  277. package/skills/integration/integration-react-native/references/basic-integration-1.1-edit.md +35 -0
  278. package/skills/integration/integration-react-native/references/basic-integration-1.2-revise.md +23 -0
  279. package/skills/integration/integration-react-native/references/basic-integration-1.3-conclude.md +57 -0
  280. package/skills/integration/integration-react-native/references/react-native-sdk.md +2819 -0
  281. package/skills/integration/integration-react-react-router-6/SKILL.md +53 -0
  282. package/skills/integration/integration-react-react-router-6/references/EXAMPLE.md +570 -0
  283. package/skills/integration/integration-react-react-router-6/references/amplitude-quickstart.md +1845 -0
  284. package/skills/integration/integration-react-react-router-6/references/basic-integration-1.0-begin.md +43 -0
  285. package/skills/integration/integration-react-react-router-6/references/basic-integration-1.1-edit.md +35 -0
  286. package/skills/integration/integration-react-react-router-6/references/basic-integration-1.2-revise.md +23 -0
  287. package/skills/integration/integration-react-react-router-6/references/basic-integration-1.3-conclude.md +57 -0
  288. package/skills/integration/integration-react-react-router-6/references/browser-sdk-2.md +4680 -0
  289. package/skills/integration/integration-react-react-router-7-data/SKILL.md +53 -0
  290. package/skills/integration/integration-react-react-router-7-data/references/EXAMPLE.md +830 -0
  291. package/skills/integration/integration-react-react-router-7-data/references/amplitude-quickstart.md +1845 -0
  292. package/skills/integration/integration-react-react-router-7-data/references/basic-integration-1.0-begin.md +43 -0
  293. package/skills/integration/integration-react-react-router-7-data/references/basic-integration-1.1-edit.md +35 -0
  294. package/skills/integration/integration-react-react-router-7-data/references/basic-integration-1.2-revise.md +23 -0
  295. package/skills/integration/integration-react-react-router-7-data/references/basic-integration-1.3-conclude.md +57 -0
  296. package/skills/integration/integration-react-react-router-7-data/references/browser-sdk-2.md +4680 -0
  297. package/skills/integration/integration-react-react-router-7-declarative/SKILL.md +53 -0
  298. package/skills/integration/integration-react-react-router-7-declarative/references/EXAMPLE.md +609 -0
  299. package/skills/integration/integration-react-react-router-7-declarative/references/amplitude-quickstart.md +1845 -0
  300. package/skills/integration/integration-react-react-router-7-declarative/references/basic-integration-1.0-begin.md +43 -0
  301. package/skills/integration/integration-react-react-router-7-declarative/references/basic-integration-1.1-edit.md +35 -0
  302. package/skills/integration/integration-react-react-router-7-declarative/references/basic-integration-1.2-revise.md +23 -0
  303. package/skills/integration/integration-react-react-router-7-declarative/references/basic-integration-1.3-conclude.md +57 -0
  304. package/skills/integration/integration-react-react-router-7-declarative/references/browser-sdk-2.md +4680 -0
  305. package/skills/integration/integration-react-react-router-7-framework/SKILL.md +53 -0
  306. package/skills/integration/integration-react-react-router-7-framework/references/EXAMPLE.md +1081 -0
  307. package/skills/integration/integration-react-react-router-7-framework/references/amplitude-quickstart.md +1845 -0
  308. package/skills/integration/integration-react-react-router-7-framework/references/basic-integration-1.0-begin.md +43 -0
  309. package/skills/integration/integration-react-react-router-7-framework/references/basic-integration-1.1-edit.md +35 -0
  310. package/skills/integration/integration-react-react-router-7-framework/references/basic-integration-1.2-revise.md +23 -0
  311. package/skills/integration/integration-react-react-router-7-framework/references/basic-integration-1.3-conclude.md +57 -0
  312. package/skills/integration/integration-react-react-router-7-framework/references/browser-sdk-2.md +4680 -0
  313. package/skills/integration/integration-react-tanstack-router-code-based/SKILL.md +57 -0
  314. package/skills/integration/integration-react-tanstack-router-code-based/references/EXAMPLE.md +659 -0
  315. package/skills/integration/integration-react-tanstack-router-code-based/references/amplitude-quickstart.md +1845 -0
  316. package/skills/integration/integration-react-tanstack-router-code-based/references/basic-integration-1.0-begin.md +43 -0
  317. package/skills/integration/integration-react-tanstack-router-code-based/references/basic-integration-1.1-edit.md +35 -0
  318. package/skills/integration/integration-react-tanstack-router-code-based/references/basic-integration-1.2-revise.md +23 -0
  319. package/skills/integration/integration-react-tanstack-router-code-based/references/basic-integration-1.3-conclude.md +57 -0
  320. package/skills/integration/integration-react-tanstack-router-code-based/references/browser-sdk-2.md +4680 -0
  321. package/skills/integration/integration-react-tanstack-router-file-based/SKILL.md +57 -0
  322. package/skills/integration/integration-react-tanstack-router-file-based/references/EXAMPLE.md +777 -0
  323. package/skills/integration/integration-react-tanstack-router-file-based/references/amplitude-quickstart.md +1845 -0
  324. package/skills/integration/integration-react-tanstack-router-file-based/references/basic-integration-1.0-begin.md +43 -0
  325. package/skills/integration/integration-react-tanstack-router-file-based/references/basic-integration-1.1-edit.md +35 -0
  326. package/skills/integration/integration-react-tanstack-router-file-based/references/basic-integration-1.2-revise.md +23 -0
  327. package/skills/integration/integration-react-tanstack-router-file-based/references/basic-integration-1.3-conclude.md +57 -0
  328. package/skills/integration/integration-react-tanstack-router-file-based/references/browser-sdk-2.md +4680 -0
  329. package/skills/integration/integration-react-vite/SKILL.md +53 -0
  330. package/skills/integration/integration-react-vite/references/EXAMPLE.md +542 -0
  331. package/skills/integration/integration-react-vite/references/amplitude-quickstart.md +1845 -0
  332. package/skills/integration/integration-react-vite/references/basic-integration-1.0-begin.md +43 -0
  333. package/skills/integration/integration-react-vite/references/basic-integration-1.1-edit.md +35 -0
  334. package/skills/integration/integration-react-vite/references/basic-integration-1.2-revise.md +23 -0
  335. package/skills/integration/integration-react-vite/references/basic-integration-1.3-conclude.md +57 -0
  336. package/skills/integration/integration-react-vite/references/browser-sdk-2.md +4680 -0
  337. package/skills/integration/integration-ruby/SKILL.md +50 -0
  338. package/skills/integration/integration-ruby/references/EXAMPLE.md +420 -0
  339. package/skills/integration/integration-ruby/references/amplitude-quickstart.md +1845 -0
  340. package/skills/integration/integration-ruby/references/analytics.md +1778 -0
  341. package/skills/integration/integration-ruby/references/basic-integration-1.0-begin.md +43 -0
  342. package/skills/integration/integration-ruby/references/basic-integration-1.1-edit.md +35 -0
  343. package/skills/integration/integration-ruby/references/basic-integration-1.2-revise.md +23 -0
  344. package/skills/integration/integration-ruby/references/basic-integration-1.3-conclude.md +57 -0
  345. package/skills/integration/integration-ruby-on-rails/SKILL.md +55 -0
  346. package/skills/integration/integration-ruby-on-rails/references/EXAMPLE.md +1013 -0
  347. package/skills/integration/integration-ruby-on-rails/references/amplitude-quickstart.md +1845 -0
  348. package/skills/integration/integration-ruby-on-rails/references/analytics.md +1778 -0
  349. package/skills/integration/integration-ruby-on-rails/references/basic-integration-1.0-begin.md +43 -0
  350. package/skills/integration/integration-ruby-on-rails/references/basic-integration-1.1-edit.md +35 -0
  351. package/skills/integration/integration-ruby-on-rails/references/basic-integration-1.2-revise.md +23 -0
  352. package/skills/integration/integration-ruby-on-rails/references/basic-integration-1.3-conclude.md +57 -0
  353. package/skills/integration/integration-sveltekit/SKILL.md +47 -0
  354. package/skills/integration/integration-sveltekit/references/EXAMPLE.md +14121 -0
  355. package/skills/integration/integration-sveltekit/references/amplitude-quickstart.md +1845 -0
  356. package/skills/integration/integration-sveltekit/references/basic-integration-1.0-begin.md +43 -0
  357. package/skills/integration/integration-sveltekit/references/basic-integration-1.1-edit.md +35 -0
  358. package/skills/integration/integration-sveltekit/references/basic-integration-1.2-revise.md +23 -0
  359. package/skills/integration/integration-sveltekit/references/basic-integration-1.3-conclude.md +57 -0
  360. package/skills/integration/integration-sveltekit/references/browser-sdk-2.md +4680 -0
  361. package/skills/integration/integration-swift/SKILL.md +49 -0
  362. package/skills/integration/integration-swift/references/EXAMPLE.md +660 -0
  363. package/skills/integration/integration-swift/references/amplitude-quickstart.md +1845 -0
  364. package/skills/integration/integration-swift/references/analytics.md +1778 -0
  365. package/skills/integration/integration-swift/references/basic-integration-1.0-begin.md +43 -0
  366. package/skills/integration/integration-swift/references/basic-integration-1.1-edit.md +35 -0
  367. package/skills/integration/integration-swift/references/basic-integration-1.2-revise.md +23 -0
  368. package/skills/integration/integration-swift/references/basic-integration-1.3-conclude.md +57 -0
  369. package/skills/integration/integration-tanstack-start/SKILL.md +58 -0
  370. package/skills/integration/integration-tanstack-start/references/EXAMPLE.md +998 -0
  371. package/skills/integration/integration-tanstack-start/references/amplitude-quickstart.md +1845 -0
  372. package/skills/integration/integration-tanstack-start/references/basic-integration-1.0-begin.md +43 -0
  373. package/skills/integration/integration-tanstack-start/references/basic-integration-1.1-edit.md +35 -0
  374. package/skills/integration/integration-tanstack-start/references/basic-integration-1.2-revise.md +23 -0
  375. package/skills/integration/integration-tanstack-start/references/basic-integration-1.3-conclude.md +57 -0
  376. package/skills/integration/integration-tanstack-start/references/browser-sdk-2.md +4680 -0
  377. package/skills/integration/integration-vue-3/SKILL.md +46 -0
  378. package/skills/integration/integration-vue-3/references/EXAMPLE.md +846 -0
  379. package/skills/integration/integration-vue-3/references/amplitude-quickstart.md +1845 -0
  380. package/skills/integration/integration-vue-3/references/basic-integration-1.0-begin.md +43 -0
  381. package/skills/integration/integration-vue-3/references/basic-integration-1.1-edit.md +35 -0
  382. package/skills/integration/integration-vue-3/references/basic-integration-1.2-revise.md +23 -0
  383. package/skills/integration/integration-vue-3/references/basic-integration-1.3-conclude.md +57 -0
  384. package/skills/integration/integration-vue-3/references/browser-sdk-2.md +4680 -0
  385. package/skills/taxonomy/amplitude-quickstart-taxonomy-agent/SKILL.md +228 -0
  386. package/dist/src/ui/tui/components/TitleBar.d.ts +0 -8
  387. package/dist/src/ui/tui/components/TitleBar.js +0 -27
  388. package/dist/src/ui/tui/primitives/KagiSmallWebViewer.d.ts +0 -7
  389. package/dist/src/ui/tui/primitives/KagiSmallWebViewer.js +0 -101
  390. package/dist/src/utils/anthropic-status.d.ts +0 -17
  391. package/dist/src/utils/anthropic-status.js +0 -51
@@ -1,79 +1,170 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
2
  /**
3
- * IntroScreen — Welcome, framework detection, and continue/cancel prompt.
3
+ * IntroScreen (v2) Clean, minimal welcome with framework detection.
4
4
  *
5
- * Three states:
5
+ * Four states:
6
+ * 0. Checkpoint restored: resume / start fresh / cancel picker
6
7
  * 1. Detecting: spinner while bin.ts runs detection
7
8
  * 2. Detection failed: auto-selects Generic, then continue/cancel
8
9
  * 3. Detection succeeded: show result, then continue/cancel
9
10
  *
10
- * Calls store.completeSetup() which unblocks bin.ts to start runWizard.
11
+ * Shows the AmplitudeTextLogo when terminal is wide/tall enough (>=75x20).
12
+ * Calls store.concludeIntro() to advance past this screen.
11
13
  */
12
14
  import path from 'path';
13
15
  import { Box, Text } from 'ink';
14
- import { useState, useEffect, useSyncExternalStore } from 'react';
15
- import { OutroKind } from '../../../lib/wizard-session.js';
16
+ import { useState, useEffect } from 'react';
17
+ import { useWizardStore } from '../hooks/useWizardStore.js';
18
+ import { OutroKind } from '../session-constants.js';
16
19
  import { Integration } from '../../../lib/constants.js';
17
- import { PickerMenu, LoadingBox } from '../primitives/index.js';
20
+ import { clearCheckpoint } from '../../../lib/session-checkpoint.js';
21
+ import { PickerMenu } from '../primitives/index.js';
22
+ import { Colors, Icons } from '../styles.js';
23
+ import { BrailleSpinner } from '../components/BrailleSpinner.js';
18
24
  import { AmplitudeTextLogo } from '../components/AmplitudeTextLogo.js';
19
- import { Colors } from '../styles.js';
25
+ import { useStdoutDimensions } from '../hooks/useStdoutDimensions.js';
20
26
  import { analytics } from '../../../utils/analytics.js';
27
+ const LOGO_MIN_COLS = 75;
28
+ const LOGO_MIN_ROWS = 20;
21
29
  export const IntroScreen = ({ store }) => {
22
- useSyncExternalStore((cb) => store.subscribe(cb), () => store.getSnapshot());
30
+ useWizardStore(store);
31
+ const [cols, rows] = useStdoutDimensions();
23
32
  const [pickingFramework, setPickingFramework] = useState(false);
24
33
  const [manuallySelected, setManuallySelected] = useState(false);
34
+ const [showResume, setShowResume] = useState(() => store.session._restoredFromCheckpoint);
25
35
  const { session } = store;
26
36
  const config = session.frameworkConfig;
27
37
  const frameworkLabel = session.detectedFrameworkLabel ?? config?.metadata.name;
28
38
  const detecting = !session.detectionComplete;
29
39
  const needsFrameworkPick = session.detectionComplete && !session.frameworkConfig;
40
+ // Hide logo when framework picker is open — the long list overlaps in Ink.
41
+ const pickerVisible = pickingFramework || (session.menu && needsFrameworkPick);
42
+ const showLogo = cols >= LOGO_MIN_COLS && rows >= LOGO_MIN_ROWS && !pickerVisible;
30
43
  // When detection fails and the user hasn't explicitly opened the picker,
31
44
  // auto-select the generic integration so the wizard can proceed.
32
45
  useEffect(() => {
33
- if (needsFrameworkPick && !session.menu) {
46
+ if (needsFrameworkPick && !session.menu && !showResume) {
34
47
  void import('../../../lib/registry.js').then(({ FRAMEWORK_REGISTRY }) => {
35
48
  const genericConfig = FRAMEWORK_REGISTRY[Integration.generic];
36
49
  store.setFrameworkConfig(Integration.generic, genericConfig);
37
50
  store.setDetectedFramework(genericConfig.metadata.name);
38
51
  });
39
52
  }
40
- }, [needsFrameworkPick, session.menu]);
53
+ }, [needsFrameworkPick, session.menu, showResume]);
41
54
  const showContinue = session.frameworkConfig !== null && !detecting && !pickingFramework;
42
- const showDescription = showContinue;
43
- return (_jsxs(Box, { flexDirection: "column", flexGrow: 1, alignItems: "center", justifyContent: "center", children: [_jsxs(Box, { flexDirection: "column", alignItems: "center", marginBottom: 1, children: [_jsx(Box, { flexDirection: "row", gap: 2, alignItems: "center", children: _jsx(AmplitudeTextLogo, {}) }), _jsx(Box, { marginBottom: 1 }), _jsx(Text, { bold: true, children: detecting ? 'Amplitude Wizard starting up' : 'Amplitude Wizard' }), _jsx(Box, { marginBottom: 1 }), showDescription && (_jsxs(Box, { flexDirection: "column", alignItems: "center", marginTop: 1, children: [_jsx(Text, { color: Colors.muted, children: "We'll use AI to analyze your project and integrate Amplitude." }), _jsx(Text, { color: Colors.muted, children: ".env* file contents will not leave your machine." }), _jsx(Box, { marginTop: 1, children: _jsx(Text, { children: "From zero to first tracked event in 5 minutes." }) })] }))] }), detecting && (_jsx(Box, { marginY: 1, children: _jsx(LoadingBox, { message: "Detecting project framework..." }) })), config?.metadata.preRunNotice && (_jsx(Text, { color: "yellow", children: config.metadata.preRunNotice })), (pickingFramework || (session.menu && needsFrameworkPick)) && (_jsx(FrameworkPicker, { store: store, onComplete: () => setPickingFramework(false) })), !detecting && !pickingFramework && (_jsxs(Box, { flexDirection: "column", children: [_jsxs(Text, { children: [_jsxs(Text, { children: ["Directory ", _jsx(Text, { color: "green", children: '\u2714' }), ' '] }), _jsxs(Text, { children: ['/', path.basename(session.installDir), ' '] })] }), frameworkLabel && (_jsxs(Text, { children: [_jsxs(Text, { children: ["Framework ", _jsx(Text, { color: "green", children: '\u2714' }), ' '] }), _jsxs(Text, { children: [frameworkLabel, !manuallySelected && ' (detected)', ' ', config?.metadata.beta && '[BETA]'] })] })), showContinue && (_jsx(PickerMenu, { options: [
44
- { label: 'Continue', value: 'continue' },
45
- { label: 'Change framework', value: 'framework' },
46
- { label: 'Cancel', value: 'cancel' },
47
- ], onSelect: (value) => {
48
- const choice = Array.isArray(value) ? value[0] : value;
49
- analytics.wizardCapture('Intro Action', {
50
- action: choice,
51
- integration: session.integration,
52
- detected_framework: session.detectedFrameworkLabel,
53
- });
54
- if (choice === 'cancel') {
55
- store.setOutroData({
56
- kind: OutroKind.Cancel,
57
- message: 'Setup cancelled.',
55
+ // ── Resume-from-checkpoint prompt ─────────────────────────────────
56
+ if (showResume) {
57
+ const orgLabel = session.selectedOrgName ?? session.selectedWorkspaceName ?? null;
58
+ return (_jsxs(Box, { flexDirection: "column", flexGrow: 1, alignItems: "center", justifyContent: "flex-start", paddingTop: 2, children: [showLogo && _jsx(AmplitudeTextLogo, {}), _jsx(Box, { flexDirection: "column", alignItems: "center", marginBottom: 1, children: _jsx(Text, { bold: true, color: Colors.heading, children: "Amplitude Wizard" }) }), _jsxs(Box, { flexDirection: "column", alignItems: "flex-start", children: [_jsx(Text, { color: Colors.body, children: "A previous session was interrupted." }), frameworkLabel && (_jsxs(Text, { children: [_jsx(Text, { color: Colors.body, children: " Framework: " }), _jsx(Text, { color: Colors.secondary, children: frameworkLabel })] })), orgLabel && (_jsxs(Text, { children: [_jsx(Text, { color: Colors.body, children: " Organization: " }), _jsx(Text, { color: Colors.secondary, children: orgLabel })] })), _jsx(Box, { marginTop: 1, children: _jsx(PickerMenu, { options: [
59
+ { label: 'Resume where you left off', value: 'resume' },
60
+ { label: 'Start fresh', value: 'fresh' },
61
+ { label: 'Cancel', value: 'cancel', hint: 'exit wizard' },
62
+ ], onSelect: (value) => {
63
+ const choice = Array.isArray(value) ? value[0] : value;
64
+ analytics.wizardCapture('Checkpoint Resume Action', {
65
+ action: choice,
66
+ integration: session.integration,
67
+ detected_framework: session.detectedFrameworkLabel,
68
+ });
69
+ if (choice === 'resume') {
70
+ store.concludeIntro();
71
+ }
72
+ else if (choice === 'fresh') {
73
+ // Clear checkpoint and reset restored flag so normal flow takes over
74
+ clearCheckpoint(store.session.installDir);
75
+ store.session = {
76
+ ...store.session,
77
+ _restoredFromCheckpoint: false,
78
+ introConcluded: false,
79
+ detectionComplete: false,
80
+ detectedFrameworkLabel: null,
81
+ integration: null,
82
+ frameworkConfig: null,
83
+ frameworkContext: {},
84
+ region: null,
85
+ selectedOrgId: null,
86
+ selectedOrgName: null,
87
+ selectedWorkspaceId: null,
88
+ selectedWorkspaceName: null,
89
+ selectedProjectName: null,
90
+ };
91
+ setShowResume(false);
92
+ }
93
+ else {
94
+ store.setOutroData({
95
+ kind: OutroKind.Cancel,
96
+ message: 'Setup cancelled.',
97
+ });
98
+ }
99
+ } }) })] })] }));
100
+ }
101
+ return (_jsxs(Box, { flexDirection: "column", flexGrow: 1, alignItems: "center", justifyContent: "flex-start", paddingTop: 2, children: [showLogo && _jsx(AmplitudeTextLogo, {}), _jsxs(Box, { flexDirection: "column", alignItems: "center", marginBottom: 1, children: [_jsx(Text, { bold: true, color: Colors.heading, children: "Amplitude Wizard" }), _jsx(Text, { color: Colors.muted, children: "AI-powered analytics setup in minutes" }), _jsx(Text, { color: Colors.secondary, children: "Installs the SDK, adds events, and verifies data is flowing." })] }), detecting && (_jsxs(Box, { marginY: 1, gap: 1, children: [_jsx(BrailleSpinner, {}), _jsxs(Text, { color: Colors.secondary, children: ["Detecting project framework", Icons.ellipsis] })] })), config?.metadata.preRunNotice && (_jsx(Box, { marginBottom: 1, children: _jsx(Text, { color: Colors.warning, children: config.metadata.preRunNotice }) })), (pickingFramework || (session.menu && needsFrameworkPick)) && (_jsx(FrameworkPicker, { store: store, onComplete: () => setPickingFramework(false) })), !detecting && !pickingFramework && (_jsxs(Box, { flexDirection: "column", alignItems: "flex-start", children: [_jsxs(Text, { children: [_jsx(Text, { color: Colors.body, children: "Directory " }), _jsxs(Text, { color: Colors.secondary, children: ["/", path.basename(session.installDir)] }), _jsxs(Text, { color: Colors.success, children: [" ", Icons.checkmark] })] }), frameworkLabel && (_jsxs(Text, { children: [_jsx(Text, { color: Colors.body, children: "Framework " }), _jsxs(Text, { color: Colors.secondary, children: [frameworkLabel, !manuallySelected && ' (detected)', config?.metadata.beta && ' [BETA]'] }), _jsxs(Text, { color: Colors.success, children: [" ", Icons.checkmark] })] })), showContinue && (_jsx(Box, { marginTop: 1, children: _jsx(PickerMenu, { options: [
102
+ { label: 'Continue', value: 'continue' },
103
+ {
104
+ label: 'Change framework',
105
+ value: 'framework',
106
+ hint: 'pick manually',
107
+ },
108
+ { label: 'Cancel', value: 'cancel', hint: 'exit wizard' },
109
+ ], onSelect: (value) => {
110
+ const choice = Array.isArray(value) ? value[0] : value;
111
+ analytics.wizardCapture('Intro Action', {
112
+ action: choice,
113
+ integration: session.integration,
114
+ detected_framework: session.detectedFrameworkLabel,
58
115
  });
59
- }
60
- else if (choice === 'framework') {
61
- setPickingFramework(true);
62
- setManuallySelected(true);
63
- }
64
- else {
65
- store.concludeIntro();
66
- }
67
- } }))] }))] }));
116
+ if (choice === 'cancel') {
117
+ store.setOutroData({
118
+ kind: OutroKind.Cancel,
119
+ message: 'Setup cancelled.',
120
+ });
121
+ }
122
+ else if (choice === 'framework') {
123
+ setPickingFramework(true);
124
+ setManuallySelected(true);
125
+ }
126
+ else {
127
+ store.concludeIntro();
128
+ }
129
+ } }) }))] }))] }));
68
130
  };
131
+ /**
132
+ * Popularity-ordered list for the manual framework picker.
133
+ * Excludes `generic` — the wizard auto-selects it when detection fails.
134
+ */
135
+ const PICKER_ORDER = [
136
+ Integration.nextjs,
137
+ Integration.reactRouter,
138
+ Integration.vue,
139
+ Integration.reactNative,
140
+ Integration.python,
141
+ Integration.django,
142
+ Integration.flask,
143
+ Integration.fastapi,
144
+ Integration.javascript_web,
145
+ Integration.javascriptNode,
146
+ Integration.swift,
147
+ Integration.android,
148
+ Integration.flutter,
149
+ Integration.go,
150
+ Integration.java,
151
+ Integration.unity,
152
+ Integration.unreal,
153
+ ];
69
154
  /** Framework picker shown when auto-detection fails. */
70
155
  const FrameworkPicker = ({ store, onComplete, }) => {
71
- // Build options from the framework registry (loaded dynamically to avoid circular deps)
72
- const options = Object.values(Integration).map((value) => ({
73
- label: value,
74
- value,
75
- }));
76
- return (_jsx(PickerMenu, { centered: true, columns: 2, message: "Select your framework", options: options, onSelect: (value) => {
156
+ const [options, setOptions] = useState([]);
157
+ useEffect(() => {
158
+ void import('../../../lib/registry.js').then(({ FRAMEWORK_REGISTRY }) => {
159
+ setOptions(PICKER_ORDER.map((integration) => ({
160
+ label: FRAMEWORK_REGISTRY[integration].metadata.name,
161
+ value: integration,
162
+ })));
163
+ });
164
+ }, []);
165
+ if (options.length === 0)
166
+ return null;
167
+ return (_jsx(PickerMenu, { centered: true, message: "Select your framework", options: options, onSelect: (value) => {
77
168
  const integration = Array.isArray(value) ? value[0] : value;
78
169
  analytics.wizardCapture('Framework Manually Selected', { integration });
79
170
  void import('../../../lib/registry.js').then(({ FRAMEWORK_REGISTRY }) => {
@@ -1,5 +1,5 @@
1
1
  /**
2
- * LoginScreen — Silent token refresh overlay for the /login slash command.
2
+ * LoginScreen — Silent token refresh overlay for the /login slash command (v2).
3
3
  *
4
4
  * On mount, reads the stored refresh token from ~/.ampli.json and exchanges
5
5
  * it for a new access token via the Amplitude OAuth2 token endpoint.
@@ -1,6 +1,6 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
2
  /**
3
- * LoginScreen — Silent token refresh overlay for the /login slash command.
3
+ * LoginScreen — Silent token refresh overlay for the /login slash command (v2).
4
4
  *
5
5
  * On mount, reads the stored refresh token from ~/.ampli.json and exchanges
6
6
  * it for a new access token via the Amplitude OAuth2 token endpoint.
@@ -9,8 +9,8 @@ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
9
9
  */
10
10
  import { Box, Text } from 'ink';
11
11
  import { useState, useEffect } from 'react';
12
- import { Spinner } from '@inkjs/ui';
13
- import { Colors } from '../styles.js';
12
+ import { Colors, Icons } from '../styles.js';
13
+ import { BrailleSpinner } from '../components/BrailleSpinner.js';
14
14
  var Phase;
15
15
  (function (Phase) {
16
16
  Phase["Refreshing"] = "refreshing";
@@ -61,5 +61,5 @@ export const LoginScreen = ({ store, onComplete }) => {
61
61
  }
62
62
  })();
63
63
  }, []);
64
- return (_jsxs(Box, { flexDirection: "column", flexGrow: 1, children: [_jsx(Text, { bold: true, color: Colors.accent, children: "Re-authenticate" }), _jsxs(Box, { marginTop: 1, flexDirection: "column", children: [phase === Phase.Refreshing && (_jsxs(Box, { gap: 1, children: [_jsx(Spinner, {}), _jsx(Text, { color: Colors.muted, children: "Refreshing credentials..." })] })), phase === Phase.Success && (_jsxs(Text, { color: "green", children: ['\u2714', " Credentials refreshed."] })), phase === Phase.NoToken && (_jsx(Text, { color: Colors.muted, children: "No stored credentials found. Restart the wizard to re-authenticate." })), phase === Phase.Error && (_jsxs(Box, { flexDirection: "column", children: [_jsxs(Text, { color: Colors.error, children: ["Refresh failed: ", errorMsg] }), _jsx(Text, { color: Colors.muted, children: "Restart the wizard to re-authenticate." })] }))] })] }));
64
+ return (_jsxs(Box, { flexDirection: "column", flexGrow: 1, children: [_jsx(Text, { bold: true, color: Colors.accent, children: "Re-authenticate" }), _jsxs(Box, { marginTop: 1, flexDirection: "column", children: [phase === Phase.Refreshing && (_jsxs(Box, { gap: 1, children: [_jsx(BrailleSpinner, {}), _jsxs(Text, { color: Colors.active, children: ["Refreshing credentials", Icons.ellipsis] })] })), phase === Phase.Success && (_jsxs(Text, { color: Colors.success, children: [Icons.checkmark, " Credentials refreshed."] })), phase === Phase.NoToken && (_jsx(Text, { color: Colors.secondary, children: "No stored credentials found. Restart the wizard to re-authenticate." })), phase === Phase.Error && (_jsxs(Box, { flexDirection: "column", children: [_jsxs(Text, { color: Colors.error, children: ["Refresh failed: ", errorMsg] }), _jsx(Text, { color: Colors.secondary, children: "Restart the wizard to re-authenticate." })] }))] })] }));
65
65
  };
@@ -1,5 +1,5 @@
1
1
  /**
2
- * LogoutScreen — Confirms and clears stored OAuth credentials.
2
+ * LogoutScreen — Confirms and clears stored OAuth credentials (v2).
3
3
  *
4
4
  * Used as an overlay triggered by the /logout slash command.
5
5
  * Calls clearStoredCredentials() on confirm, then pops the overlay.
@@ -7,6 +7,8 @@
7
7
  interface LogoutScreenProps {
8
8
  onComplete: () => void;
9
9
  installDir: string;
10
+ /** Called to clear in-memory session state after disk credentials are wiped. */
11
+ onLoggedOut?: () => void;
10
12
  }
11
- export declare const LogoutScreen: ({ onComplete, installDir }: LogoutScreenProps) => import("react/jsx-runtime").JSX.Element;
13
+ export declare const LogoutScreen: ({ onComplete, installDir, onLoggedOut, }: LogoutScreenProps) => import("react/jsx-runtime").JSX.Element;
12
14
  export {};
@@ -1,28 +1,40 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
2
  /**
3
- * LogoutScreen — Confirms and clears stored OAuth credentials.
3
+ * LogoutScreen — Confirms and clears stored OAuth credentials (v2).
4
4
  *
5
5
  * Used as an overlay triggered by the /logout slash command.
6
6
  * Calls clearStoredCredentials() on confirm, then pops the overlay.
7
7
  */
8
8
  import { Box, Text } from 'ink';
9
- import { useState } from 'react';
9
+ import { useState, useEffect, useRef } from 'react';
10
10
  import { ConfirmationInput } from '../primitives/index.js';
11
11
  import { Colors } from '../styles.js';
12
12
  import { clearStoredCredentials } from '../../../utils/ampli-settings.js';
13
13
  import { clearApiKey } from '../../../utils/api-key-store.js';
14
+ import { clearCheckpoint } from '../../../lib/session-checkpoint.js';
14
15
  var Phase;
15
16
  (function (Phase) {
16
17
  Phase["Confirm"] = "confirm";
17
18
  Phase["Done"] = "done";
18
19
  })(Phase || (Phase = {}));
19
- export const LogoutScreen = ({ onComplete, installDir }) => {
20
+ export const LogoutScreen = ({ onComplete, installDir, onLoggedOut, }) => {
20
21
  const [phase, setPhase] = useState(Phase.Confirm);
22
+ const timerRef = useRef(null);
23
+ // Clear any pending timer on unmount
24
+ useEffect(() => {
25
+ return () => {
26
+ if (timerRef.current !== null)
27
+ clearTimeout(timerRef.current);
28
+ };
29
+ }, []);
21
30
  const handleConfirm = () => {
22
31
  clearStoredCredentials();
23
32
  clearApiKey(installDir);
33
+ clearCheckpoint(installDir);
34
+ onLoggedOut?.();
24
35
  setPhase(Phase.Done);
25
- setTimeout(onComplete, 1500);
36
+ // Exit after a short delay so the user sees the confirmation
37
+ timerRef.current = setTimeout(() => process.exit(0), 1500);
26
38
  };
27
- return (_jsxs(Box, { flexDirection: "column", flexGrow: 1, children: [_jsx(Text, { bold: true, color: Colors.accent, children: "Log Out" }), _jsxs(Box, { marginTop: 1, flexDirection: "column", children: [phase === Phase.Confirm && (_jsx(ConfirmationInput, { message: "Clear stored Amplitude credentials from ~/.ampli.json?", confirmLabel: "Log out", cancelLabel: "Cancel", onConfirm: handleConfirm, onCancel: onComplete })), phase === Phase.Done && (_jsx(Text, { color: Colors.muted, children: "Logged out. Restart the wizard to re-authenticate." }))] })] }));
39
+ return (_jsxs(Box, { flexDirection: "column", flexGrow: 1, children: [_jsx(Text, { bold: true, color: Colors.accent, children: "Log Out" }), _jsxs(Box, { marginTop: 1, flexDirection: "column", children: [phase === Phase.Confirm && (_jsx(ConfirmationInput, { message: "Clear stored Amplitude credentials from ~/.ampli.json?", confirmLabel: "Log out", cancelLabel: "Cancel", onConfirm: handleConfirm, onCancel: onComplete })), phase === Phase.Done && (_jsx(Text, { color: Colors.secondary, children: "Logged out. Restart the wizard to re-authenticate." }))] })] }));
28
40
  };
@@ -1,16 +1,16 @@
1
1
  /**
2
- * McpScreen — MCP server install/remove flow.
2
+ * McpScreen — MCP server install/remove flow (v2).
3
3
  *
4
4
  * Uses an McpInstaller service (passed via props) instead of
5
5
  * importing business logic directly. Testable, no dynamic imports.
6
6
  *
7
7
  * Supports two modes via the `mode` prop:
8
- * - 'install': detect clients confirm install
9
- * - 'remove': detect installed clients confirm remove
8
+ * - 'install': detect clients -> confirm -> install
9
+ * - 'remove': detect installed clients -> confirm -> remove
10
10
  *
11
11
  * When done, calls store.setMcpComplete(). The router resolves to outro.
12
12
  */
13
- import { type WizardStore } from '../store.js';
13
+ import type { WizardStore } from '../store.js';
14
14
  import type { McpInstaller } from '../services/mcp-installer.js';
15
15
  export type McpMode = 'install' | 'remove';
16
16
  interface McpScreenProps {
@@ -1,22 +1,22 @@
1
- import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
1
+ import { jsxs as _jsxs, jsx as _jsx, Fragment as _Fragment } from "react/jsx-runtime";
2
2
  /**
3
- * McpScreen — MCP server install/remove flow.
3
+ * McpScreen — MCP server install/remove flow (v2).
4
4
  *
5
5
  * Uses an McpInstaller service (passed via props) instead of
6
6
  * importing business logic directly. Testable, no dynamic imports.
7
7
  *
8
8
  * Supports two modes via the `mode` prop:
9
- * - 'install': detect clients confirm install
10
- * - 'remove': detect installed clients confirm remove
9
+ * - 'install': detect clients -> confirm -> install
10
+ * - 'remove': detect installed clients -> confirm -> remove
11
11
  *
12
12
  * When done, calls store.setMcpComplete(). The router resolves to outro.
13
13
  */
14
14
  import { Box, Text } from 'ink';
15
- import { useState, useEffect } from 'react';
16
- import { useSyncExternalStore } from 'react';
15
+ import { useState, useEffect, useRef } from 'react';
17
16
  import { McpOutcome, RunPhase } from '../store.js';
17
+ import { useWizardStore } from '../hooks/useWizardStore.js';
18
18
  import { ConfirmationInput, PickerMenu } from '../primitives/index.js';
19
- import { Colors } from '../styles.js';
19
+ import { Colors, Icons } from '../styles.js';
20
20
  import { analytics, captureWizardError } from '../../../utils/analytics.js';
21
21
  var Phase;
22
22
  (function (Phase) {
@@ -39,8 +39,16 @@ const markDone = (store, outcome, clients = [], standalone = false, onComplete)
39
39
  }
40
40
  };
41
41
  export const McpScreen = ({ store, installer, mode = 'install', standalone = false, onComplete, }) => {
42
- useSyncExternalStore((cb) => store.subscribe(cb), () => store.getSnapshot());
42
+ useWizardStore(store);
43
43
  const isRemove = mode === 'remove';
44
+ const timerRef = useRef(null);
45
+ // Clear any pending timer on unmount
46
+ useEffect(() => {
47
+ return () => {
48
+ if (timerRef.current !== null)
49
+ clearTimeout(timerRef.current);
50
+ };
51
+ }, []);
44
52
  const { runPhase, amplitudePreDetected, amplitudePreDetectedChoicePending } = store.session;
45
53
  const dataSetupComplete = runPhase === RunPhase.Completed;
46
54
  const [phase, setPhase] = useState(Phase.Detecting);
@@ -56,7 +64,7 @@ export const McpScreen = ({ store, installer, mode = 'install', standalone = fal
56
64
  if (detected.length === 0) {
57
65
  analytics.wizardCapture('MCP No Clients Detected', { mode });
58
66
  setPhase(Phase.None);
59
- setTimeout(() => markDone(store, McpOutcome.NoClients, [], standalone, onComplete), 1500);
67
+ timerRef.current = setTimeout(() => markDone(store, McpOutcome.NoClients, [], standalone, onComplete), 1500);
60
68
  }
61
69
  else {
62
70
  analytics.wizardCapture('MCP Clients Detected', {
@@ -71,7 +79,7 @@ export const McpScreen = ({ store, installer, mode = 'install', standalone = fal
71
79
  catch {
72
80
  captureWizardError('MCP Client Detection', 'Editor client detection failed', 'McpScreen', { mode });
73
81
  setPhase(Phase.None);
74
- setTimeout(() => markDone(store, McpOutcome.Failed, [], standalone, onComplete), 1500);
82
+ timerRef.current = setTimeout(() => markDone(store, McpOutcome.Failed, [], standalone, onComplete), 1500);
75
83
  }
76
84
  })();
77
85
  }, [installer, amplitudePreDetectedChoicePending]);
@@ -114,7 +122,7 @@ export const McpScreen = ({ store, installer, mode = 'install', standalone = fal
114
122
  });
115
123
  setPhase(Phase.Done);
116
124
  const outcome = result.length > 0 ? McpOutcome.Installed : McpOutcome.Failed;
117
- setTimeout(() => markDone(store, outcome, result, standalone, onComplete), 2000);
125
+ timerRef.current = setTimeout(() => markDone(store, outcome, result, standalone, onComplete), 2000);
118
126
  };
119
127
  const doRemove = async () => {
120
128
  setPhase(Phase.Working);
@@ -129,11 +137,11 @@ export const McpScreen = ({ store, installer, mode = 'install', standalone = fal
129
137
  analytics.wizardCapture('MCP Remove Complete', { removed: result });
130
138
  setPhase(Phase.Done);
131
139
  const outcome = result.length > 0 ? McpOutcome.Installed : McpOutcome.Failed;
132
- setTimeout(() => markDone(store, outcome, result, standalone, onComplete), 2000);
140
+ timerRef.current = setTimeout(() => markDone(store, outcome, result, standalone, onComplete), 2000);
133
141
  };
134
- return (_jsxs(Box, { flexDirection: "column", flexGrow: 1, children: [dataSetupComplete && (_jsx(Box, { marginBottom: 1, children: _jsx(Text, { color: "green", bold: true, children: amplitudePreDetected
135
- ? '\u2714 Amplitude is already configured in this project!'
136
- : '\u2714 Data setup complete!' }) })), amplitudePreDetectedChoicePending && !isRemove && (_jsxs(Box, { marginBottom: 1, flexDirection: "column", children: [_jsx(Text, { color: Colors.muted, children: "The installer skipped the automated setup step because Amplitude is already present. You can continue to editor MCP setup, or run the full setup wizard if you want to review or change the integration." }), _jsx(Box, { marginTop: 1, children: _jsx(PickerMenu, { message: "How would you like to proceed?", options: [
142
+ return (_jsxs(Box, { flexDirection: "column", flexGrow: 1, children: [dataSetupComplete && (_jsx(Box, { marginBottom: 1, children: _jsxs(Text, { color: Colors.success, bold: true, children: [Icons.checkmark, ' ', amplitudePreDetected
143
+ ? 'Amplitude is already configured in this project!'
144
+ : 'Data setup complete!'] }) })), amplitudePreDetectedChoicePending && !isRemove && (_jsxs(Box, { marginBottom: 1, flexDirection: "column", children: [_jsx(Text, { color: Colors.secondary, children: "The installer skipped the automated setup step because Amplitude is already present. You can continue to editor MCP setup, or run the full setup wizard if you want to review or change the integration." }), _jsx(Box, { marginTop: 1, children: _jsx(PickerMenu, { message: "How would you like to proceed?", options: [
137
145
  { label: 'Continue to MCP setup', value: 'continue' },
138
146
  {
139
147
  label: 'Run setup wizard anyway',
@@ -145,7 +153,7 @@ export const McpScreen = ({ store, installer, mode = 'install', standalone = fal
145
153
  run_wizard_anyway: runWizard,
146
154
  });
147
155
  store.resolvePreDetectedChoice(runWizard);
148
- } }) })] })), !amplitudePreDetectedChoicePending && (_jsxs(_Fragment, { children: [_jsxs(Text, { bold: true, color: Colors.accent, children: ["MCP Server ", isRemove ? 'Removal' : 'Setup'] }), _jsxs(Box, { marginTop: 1, flexDirection: "column", children: [phase === Phase.Detecting && (_jsx(Text, { color: Colors.muted, children: "Detecting supported editors..." })), phase === Phase.None && (_jsxs(Text, { color: Colors.muted, children: ["No ", isRemove ? 'installed' : 'supported', " MCP clients detected. Skipping..."] })), phase === Phase.Ask && (_jsxs(_Fragment, { children: [_jsxs(Text, { color: Colors.muted, children: ["Detected: ", clients.map((c) => c.name).join(', ')] }), _jsx(Box, { marginTop: 1, children: _jsx(ConfirmationInput, { message: isRemove
156
+ } }) })] })), !amplitudePreDetectedChoicePending && (_jsxs(_Fragment, { children: [_jsxs(Text, { bold: true, color: Colors.accent, children: ["MCP Server ", isRemove ? 'Removal' : 'Setup'] }), _jsxs(Box, { marginTop: 1, flexDirection: "column", children: [phase === Phase.Detecting && (_jsxs(Text, { color: Colors.muted, children: ["Detecting supported editors", Icons.ellipsis] })), phase === Phase.None && (_jsxs(Text, { color: Colors.muted, children: ["No ", isRemove ? 'installed' : 'supported', " MCP clients detected. Skipping", Icons.ellipsis] })), phase === Phase.Ask && (_jsxs(_Fragment, { children: [_jsxs(Text, { color: Colors.secondary, children: ["Detected: ", clients.map((c) => c.name).join(', ')] }), _jsx(Box, { marginTop: 1, children: _jsx(ConfirmationInput, { message: isRemove
149
157
  ? 'Remove the Amplitude MCP server from your editor?'
150
158
  : 'Install the Amplitude MCP server to your editor?', confirmLabel: isRemove ? 'Remove MCP' : 'Install MCP', cancelLabel: "No thanks", onConfirm: handleConfirm, onCancel: handleSkip }) })] })), phase === Phase.Pick && (_jsx(PickerMenu, { message: "Select editor to install MCP server", options: clients.map((c) => ({
151
159
  label: c.name,
@@ -159,5 +167,5 @@ export const McpScreen = ({ store, installer, mode = 'install', standalone = fal
159
167
  available_clients: clients.map((c) => c.name),
160
168
  });
161
169
  void doInstall(names);
162
- } })), phase === Phase.Working && (_jsxs(Text, { color: Colors.muted, children: [isRemove ? 'Removing' : 'Installing', " MCP server..."] })), phase === Phase.Done && (_jsx(Box, { flexDirection: "column", children: resultClients.length > 0 ? (_jsxs(_Fragment, { children: [_jsxs(Text, { color: "green", bold: true, children: ['\u2714', " MCP server", ' ', isRemove ? 'removed from' : 'installed for', ":"] }), resultClients.map((name, i) => (_jsxs(Text, { children: [' ', '\u2022', " ", name] }, i)))] })) : (_jsxs(Text, { color: Colors.muted, children: [isRemove ? 'Removal' : 'Installation', " skipped."] })) }))] })] }))] }));
170
+ } })), phase === Phase.Working && (_jsxs(Text, { color: Colors.active, children: [isRemove ? 'Removing' : 'Installing', " MCP server", Icons.ellipsis] })), phase === Phase.Done && (_jsx(Box, { flexDirection: "column", children: resultClients.length > 0 ? (_jsxs(_Fragment, { children: [_jsxs(Text, { color: Colors.success, bold: true, children: [Icons.checkmark, " MCP server", ' ', isRemove ? 'removed from' : 'installed for', ":"] }), resultClients.map((name, i) => (_jsxs(Text, { color: Colors.body, children: [' ', Icons.bullet, " ", name] }, i)))] })) : (_jsxs(Text, { color: Colors.muted, children: [isRemove ? 'Removal' : 'Installation', " skipped."] })) }))] })] }))] }));
163
171
  };
@@ -1,5 +1,5 @@
1
1
  /**
2
- * OutageScreen — Shown when Claude/Anthropic services are degraded.
2
+ * OutageScreen — Shown when AI services are degraded (v2).
3
3
  * Reads session.serviceStatus and provides a ConfirmationInput to continue or exit.
4
4
  */
5
5
  import type { WizardStore } from '../store.js';
@@ -1,17 +1,17 @@
1
1
  import { jsxs as _jsxs, jsx as _jsx } from "react/jsx-runtime";
2
2
  /**
3
- * OutageScreen — Shown when Claude/Anthropic services are degraded.
3
+ * OutageScreen — Shown when AI services are degraded (v2).
4
4
  * Reads session.serviceStatus and provides a ConfirmationInput to continue or exit.
5
5
  */
6
6
  import { Box, Text } from 'ink';
7
- import { useSyncExternalStore } from 'react';
7
+ import { useWizardStore } from '../hooks/useWizardStore.js';
8
8
  import { ConfirmationInput } from '../primitives/index.js';
9
- import { Colors } from '../styles.js';
9
+ import { Colors, Icons } from '../styles.js';
10
10
  export const OutageScreen = ({ store }) => {
11
- useSyncExternalStore((cb) => store.subscribe(cb), () => store.getSnapshot());
11
+ useWizardStore(store);
12
12
  const serviceStatus = store.session.serviceStatus;
13
13
  if (!serviceStatus) {
14
14
  return null;
15
15
  }
16
- return (_jsxs(Box, { flexDirection: "column", flexGrow: 1, children: [_jsxs(Box, { flexDirection: "column", marginBottom: 1, children: [_jsxs(Text, { color: "yellow", bold: true, children: ['\u26A0', " Claude/Anthropic services are experiencing issues."] }), _jsx(Text, { children: " " }), _jsxs(Text, { children: [_jsx(Text, { color: "yellow", children: "Status:" }), " ", serviceStatus.description] }), _jsxs(Text, { children: [_jsx(Text, { color: "yellow", children: "Status page:" }), ' ', _jsx(Text, { color: "cyan", children: serviceStatus.statusPageUrl })] }), _jsx(Text, { children: " " }), _jsx(Text, { color: Colors.muted, children: "The wizard may not work reliably while services are affected." })] }), _jsx(ConfirmationInput, { message: "Continue anyway?", onConfirm: () => store.popOverlay(), onCancel: () => process.exit(0) })] }));
16
+ return (_jsxs(Box, { flexDirection: "column", flexGrow: 1, children: [_jsxs(Box, { flexDirection: "column", marginBottom: 1, children: [_jsxs(Text, { color: Colors.warning, bold: true, children: [Icons.diamond, " The setup agent is temporarily unavailable."] }), _jsx(Text, { children: " " }), _jsxs(Text, { color: Colors.body, children: [_jsx(Text, { color: Colors.warning, children: "Status:" }), ' ', serviceStatus.description] }), _jsxs(Text, { color: Colors.body, children: [_jsx(Text, { color: Colors.warning, children: "Status page:" }), ' ', _jsx(Text, { color: Colors.accent, children: serviceStatus.statusPageUrl })] }), _jsx(Text, { children: " " }), _jsx(Text, { color: Colors.secondary, children: "The wizard may not work reliably while services are affected." })] }), _jsx(ConfirmationInput, { message: "Continue anyway?", onConfirm: () => store.popOverlay(), onCancel: () => process.exit(0) })] }));
17
17
  };
@@ -1,7 +1,12 @@
1
1
  /**
2
2
  * OutroScreen — Summary after the agent run.
3
+ *
3
4
  * Reads store.session.outroData to render success, error, or cancel view.
4
5
  * Keeps the process alive until the user presses a key to exit.
6
+ *
7
+ * Success: bold green heading, compact changes + events list, PickerMenu.
8
+ * Error: red heading with error message and suggested fixes.
9
+ * Cancel: clean warning-colored cancel message.
5
10
  */
6
11
  import type { WizardStore } from '../store.js';
7
12
  interface OutroScreenProps {
@@ -1,27 +1,32 @@
1
- import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
1
+ import { jsxs as _jsxs, jsx as _jsx } from "react/jsx-runtime";
2
2
  /**
3
3
  * OutroScreen — Summary after the agent run.
4
+ *
4
5
  * Reads store.session.outroData to render success, error, or cancel view.
5
6
  * Keeps the process alive until the user presses a key to exit.
7
+ *
8
+ * Success: bold green heading, compact changes + events list, PickerMenu.
9
+ * Error: red heading with error message and suggested fixes.
10
+ * Cancel: clean warning-colored cancel message.
6
11
  */
7
12
  import { Box, Text } from 'ink';
8
13
  import { useState } from 'react';
9
- import { useScreenInput } from '../hooks/useScreenInput.js';
10
- import { useSyncExternalStore } from 'react';
11
- import { OutroKind } from '../../../lib/wizard-session.js';
12
- import { Colors } from '../styles.js';
14
+ import { useWizardStore } from '../hooks/useWizardStore.js';
15
+ import { OutroKind } from '../session-constants.js';
16
+ import { Colors, Icons } from '../styles.js';
13
17
  import { PickerMenu, ReportViewer } from '../primitives/index.js';
18
+ import { useScreenInput } from '../hooks/useScreenInput.js';
14
19
  import { OUTBOUND_URLS } from '../../../lib/constants.js';
15
20
  import opn from 'opn';
16
21
  import path from 'path';
17
22
  import { analytics } from '../../../utils/analytics.js';
18
23
  const REPORT_FILE = 'amplitude-setup-report.md';
19
24
  export const OutroScreen = ({ store }) => {
20
- useSyncExternalStore((cb) => store.subscribe(cb), () => store.getSnapshot());
25
+ useWizardStore(store);
21
26
  const [showReport, setShowReport] = useState(false);
22
27
  const isSuccess = store.session.outroData?.kind === OutroKind.Success;
23
- // Any-key-to-exit only for non-success states; success uses a picker.
24
- useScreenInput((input, key) => {
28
+ // Any-key-to-exit for non-success states; success uses the picker.
29
+ useScreenInput((_input, key) => {
25
30
  if (!isSuccess)
26
31
  process.exit(0);
27
32
  if (showReport && key.escape)
@@ -29,19 +34,21 @@ export const OutroScreen = ({ store }) => {
29
34
  });
30
35
  const outroData = store.session.outroData;
31
36
  if (!outroData) {
32
- return (_jsx(Box, { flexDirection: "column", flexGrow: 1, children: _jsx(Text, { color: Colors.muted, children: "Finishing up..." }) }));
37
+ return (_jsx(Box, { flexDirection: "column", flexGrow: 1, children: _jsxs(Text, { color: Colors.muted, children: ["Finishing up", Icons.ellipsis] }) }));
33
38
  }
34
- // installDir comes from --install-dir CLI flag (defaults to process.cwd()).
35
- // REPORT_FILE is a compile-time constant with no path separators, so string
36
- // concatenation is safe and avoids path.join/path.resolve on user-supplied input.
39
+ // Build the report file path from the install directory.
37
40
  const installDir = store.session.installDir;
38
41
  const reportPath = installDir.endsWith(path.sep)
39
42
  ? `${installDir}${REPORT_FILE}`
40
43
  : `${installDir}${path.sep}${REPORT_FILE}`;
44
+ // ── Report sub-view ──────────────────────────────────────────────────
41
45
  if (showReport) {
42
- return (_jsxs(Box, { flexDirection: "column", flexGrow: 1, children: [_jsxs(Box, { marginBottom: 1, children: [_jsx(Text, { bold: true, color: Colors.accent, children: "Setup Report" }), _jsx(Text, { color: Colors.muted, children: " (Esc to go back)" })] }), _jsx(ReportViewer, { filePath: reportPath })] }));
46
+ return (_jsxs(Box, { flexDirection: "column", flexGrow: 1, paddingX: 2, paddingY: 1, children: [_jsxs(Box, { marginBottom: 1, children: [_jsx(Text, { bold: true, color: Colors.accent, children: "Setup Report" }), _jsx(Text, { color: Colors.muted, children: " (Esc to go back)" })] }), _jsx(ReportViewer, { filePath: reportPath })] }));
43
47
  }
44
- return (_jsxs(Box, { flexDirection: "column", flexGrow: 1, children: [outroData.kind === OutroKind.Success && (_jsxs(Box, { flexDirection: "column", children: [_jsxs(Text, { color: "green", bold: true, children: ['\u2714', " Successfully installed Amplitude!"] }), _jsx(Box, { marginTop: 1, children: _jsxs(Text, { children: ["Check ", _jsx(Text, { bold: true, children: "./amplitude-setup-report.md" }), " for details about your integration"] }) }), outroData.changes && outroData.changes.length > 0 && (_jsxs(Box, { flexDirection: "column", marginTop: 1, children: [_jsx(Text, { color: "cyan", bold: true, children: "What the agent did:" }), outroData.changes.map((change, i) => (_jsxs(Text, { children: ['\u2022', " ", change] }, i)))] })), store.eventPlan.length > 0 && (_jsxs(Box, { flexDirection: "column", marginTop: 1, children: [_jsx(Text, { color: "cyan", bold: true, children: "Events added:" }), store.eventPlan.map((event) => (_jsxs(Text, { children: ['\u2022', " ", _jsx(Text, { bold: true, children: event.name }), _jsxs(Text, { color: Colors.muted, children: [" ", event.description] })] }, event.name)))] })), outroData.docsUrl && (_jsx(Box, { marginTop: 1, children: _jsxs(Text, { children: ["Learn more: ", _jsx(Text, { color: "cyan", children: outroData.docsUrl })] }) })), outroData.continueUrl && (_jsx(Box, { children: _jsxs(Text, { children: ["Continue onboarding:", ' ', _jsx(Text, { color: "cyan", children: outroData.continueUrl })] }) })), _jsx(Box, { marginTop: 1, children: _jsx(Text, { color: Colors.muted, children: "Note: This wizard uses an LLM agent to analyze and modify your project. Please review the changes made." }) }), _jsx(Box, { children: _jsx(Text, { color: Colors.muted, children: "How did this work for you? Drop us a line: wizard@amplitude.com" }) })] })), outroData.kind === OutroKind.Error && (_jsx(Box, { flexDirection: "column", children: _jsxs(Text, { color: "red", bold: true, children: ['\u2718', " ", outroData.message || 'An error occurred'] }) })), outroData.kind === OutroKind.Cancel && (_jsxs(Box, { flexDirection: "column", children: [_jsxs(Text, { color: "yellow", bold: true, children: ['\u25A0', " ", outroData.message || 'Cancelled'] }), outroData.docsUrl && (_jsx(Box, { marginTop: 1, children: _jsxs(Text, { children: ["Manual setup guide:", ' ', _jsx(Text, { color: "cyan", children: outroData.docsUrl })] }) }))] })), _jsx(Box, { marginTop: 1, children: isSuccess ? (_jsx(PickerMenu, { options: [
48
+ // ── Main outro views ─────────────────────────────────────────────────
49
+ return (_jsxs(Box, { flexDirection: "column", flexGrow: 1, paddingX: 2, paddingY: 1, children: [outroData.kind === OutroKind.Success && (_jsxs(Box, { flexDirection: "column", children: [_jsxs(Text, { color: Colors.success, bold: true, children: [Icons.checkmark, " Amplitude is live!"] }), store.eventPlan.length > 0 && (_jsxs(Text, { color: Colors.body, children: [store.eventPlan.length, " event", store.eventPlan.length !== 1 ? 's' : '', " instrumented", store.session.selectedProjectName
50
+ ? ` in ${store.session.selectedProjectName}`
51
+ : '', "."] })), outroData.changes && outroData.changes.length > 0 && (_jsx(Box, { flexDirection: "column", marginTop: 1, children: outroData.changes.map((change, i) => (_jsxs(Text, { color: Colors.body, children: [Icons.bullet, " ", change] }, i))) })), store.eventPlan.length > 0 && (_jsxs(Box, { flexDirection: "column", marginTop: 1, children: [_jsx(Text, { color: Colors.secondary, bold: true, children: "Events" }), store.eventPlan.map((event) => (_jsxs(Text, { color: Colors.body, children: [Icons.diamond, " ", _jsx(Text, { bold: true, children: event.name }), _jsxs(Text, { color: Colors.muted, children: [" ", event.description] })] }, event.name)))] })), _jsx(Box, { marginTop: 1, children: _jsxs(Text, { color: Colors.muted, children: ["Review changes in", ' ', _jsx(Text, { bold: true, color: Colors.secondary, children: "./amplitude-setup-report.md" })] }) })] })), outroData.kind === OutroKind.Error && (_jsxs(Box, { flexDirection: "column", children: [_jsxs(Text, { color: Colors.error, bold: true, children: [Icons.cross, " Setup failed"] }), outroData.message && (_jsx(Box, { marginTop: 1, children: _jsx(Text, { color: Colors.body, children: outroData.message }) })), _jsxs(Box, { marginTop: 1, flexDirection: "column", children: [_jsxs(Text, { color: Colors.secondary, children: [Icons.arrowRight, " Check your API key and network connection"] }), _jsxs(Text, { color: Colors.secondary, children: [Icons.arrowRight, " Run the wizard again with", ' ', _jsx(Text, { bold: true, children: "--debug" }), " for more detail"] }), outroData.docsUrl && (_jsxs(Text, { color: Colors.secondary, children: [Icons.arrowRight, " Docs:", ' ', _jsx(Text, { color: Colors.accent, children: outroData.docsUrl })] }))] })] })), outroData.kind === OutroKind.Cancel && (_jsxs(Box, { flexDirection: "column", children: [_jsxs(Text, { color: Colors.warning, bold: true, children: [Icons.dash, " Setup cancelled"] }), outroData.message && (_jsx(Box, { marginTop: 1, children: _jsx(Text, { color: Colors.body, children: outroData.message }) })), outroData.docsUrl && (_jsx(Box, { marginTop: 1, children: _jsxs(Text, { color: Colors.secondary, children: ["Manual setup:", ' ', _jsx(Text, { color: Colors.accent, children: outroData.docsUrl })] }) }))] })), _jsx(Box, { marginTop: 1, children: isSuccess ? (_jsx(PickerMenu, { options: [
45
52
  { label: 'View setup report', value: 'report' },
46
53
  { label: 'Open Amplitude dashboard', value: 'dashboard' },
47
54
  { label: 'Exit', value: 'exit' },