@amplitude/wizard 1.0.0-beta.2 → 1.0.0

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 +6 -5
  9. package/dist/src/lib/constants.js +13 -13
  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 +6 -6
  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
package/dist/bin.js CHANGED
@@ -37,12 +37,127 @@ if (!(0, semver_1.satisfies)(process.version, NODE_VERSION_RANGE)) {
37
37
  (0, logging_1.red)(`Amplitude wizard requires Node.js ${NODE_VERSION_RANGE}. You are using Node.js ${process.version}. Please upgrade your Node.js version.`);
38
38
  process.exit(1);
39
39
  }
40
- const run_1 = require("./src/run");
41
40
  const environment_1 = require("./src/utils/environment");
42
41
  const ui_1 = require("./src/ui");
43
42
  const logging_ui_1 = require("./src/ui/logging-ui");
44
43
  const shell_completions_1 = require("./src/utils/shell-completions");
45
- const api_key_store_1 = require("./src/utils/api-key-store");
44
+ const exit_codes_1 = require("./src/lib/exit-codes");
45
+ // Dynamic import to avoid preloading wizard-session.ts as CJS, which
46
+ // prevents the TUI's ESM dynamic imports from resolving named exports.
47
+ const lazyRunWizard = async (...args) => {
48
+ const { runWizard } = await import('./src/run.js');
49
+ return runWizard(...args);
50
+ };
51
+ /**
52
+ * Build a WizardSession from CLI argv, avoiding the repeated 12-field literal.
53
+ */
54
+ const buildSessionFromOptions = async (options, overrides) => {
55
+ const { buildSession } = await import('./src/lib/wizard-session.js');
56
+ return buildSession({
57
+ debug: options.debug,
58
+ verbose: options.verbose,
59
+ forceInstall: options.forceInstall,
60
+ installDir: options.installDir,
61
+ ci: overrides?.ci ?? false,
62
+ signup: options.signup,
63
+ localMcp: options.localMcp,
64
+ apiKey: options.apiKey,
65
+ menu: options.menu,
66
+ integration: options.integration,
67
+ benchmark: options.benchmark,
68
+ projectId: options.projectId,
69
+ });
70
+ };
71
+ /**
72
+ * Shared credential resolution for non-interactive modes (agent + CI).
73
+ * Handles --api-key shortcut, OAuth token refresh, and pendingOrgs.
74
+ *
75
+ * @param mode - 'agent' prompts via AgentUI, 'ci' auto-selects first env
76
+ */
77
+ const resolveNonInteractiveCredentials = async (session, options, mode, agentUI) => {
78
+ // If --api-key was provided, skip OAuth entirely
79
+ if (session.apiKey) {
80
+ const { DEFAULT_HOST_URL } = await import('./src/lib/constants.js');
81
+ session.credentials = {
82
+ accessToken: session.apiKey,
83
+ projectApiKey: session.apiKey,
84
+ host: DEFAULT_HOST_URL,
85
+ projectId: session.projectId ?? 0,
86
+ };
87
+ session.projectHasData = false;
88
+ return;
89
+ }
90
+ // Resolve credentials from stored OAuth tokens
91
+ const { resolveCredentials, resolveEnvironmentSelection } = await import('./src/lib/credential-resolution.js');
92
+ await resolveCredentials(session, {
93
+ requireOrgId: false,
94
+ org: options.org,
95
+ env: options.env,
96
+ });
97
+ // Handle multiple environments
98
+ if (session.pendingOrgs && !session.credentials) {
99
+ if (mode === 'ci') {
100
+ // CI mode: auto-select first environment with an API key
101
+ for (const org of session.pendingOrgs) {
102
+ for (const ws of org.workspaces) {
103
+ const env = (ws.environments ?? [])
104
+ .filter((e) => e.app?.apiKey)
105
+ .sort((a, b) => a.rank - b.rank)[0];
106
+ if (env) {
107
+ await resolveEnvironmentSelection(session, {
108
+ orgId: org.id,
109
+ workspaceId: ws.id,
110
+ env: env.name,
111
+ });
112
+ (0, ui_1.getUI)().log.info(`Resolved Amplitude API key non-interactively (CI mode): ${org.name} / ${ws.name} / ${env.name}`);
113
+ break;
114
+ }
115
+ }
116
+ if (session.credentials)
117
+ break;
118
+ }
119
+ }
120
+ else if (agentUI) {
121
+ // Agent mode: list envs and prompt via stdin
122
+ const envList = [];
123
+ for (const org of session.pendingOrgs) {
124
+ for (const ws of org.workspaces) {
125
+ for (const env of ws.environments ?? []) {
126
+ if (env.app?.apiKey) {
127
+ envList.push(` --env "${env.name}" (${org.name} / ${ws.name})`);
128
+ }
129
+ }
130
+ }
131
+ }
132
+ (0, ui_1.getUI)().log.info(`Multiple environments found. Re-run with one of:\n${envList.join('\n')}`);
133
+ const selection = await agentUI.promptEnvironmentSelection(session.pendingOrgs);
134
+ const resolved = await resolveEnvironmentSelection(session, selection);
135
+ if (!resolved) {
136
+ process.exit(exit_codes_1.ExitCode.AUTH_REQUIRED);
137
+ }
138
+ }
139
+ }
140
+ // If we still don't have credentials, auth is required
141
+ if (!session.credentials) {
142
+ if (mode === 'agent') {
143
+ (0, ui_1.getUI)().log.error('Could not resolve credentials. ' +
144
+ 'Please log in first by running: amplitude-wizard login');
145
+ process.exit(exit_codes_1.ExitCode.AUTH_REQUIRED);
146
+ }
147
+ // CI mode falls through — runWizard will handle missing credentials
148
+ }
149
+ // Log what was resolved so the caller can see it
150
+ if (mode === 'agent' && session.credentials) {
151
+ const parts = [
152
+ session.selectedOrgName,
153
+ session.selectedWorkspaceName,
154
+ session.selectedProjectName,
155
+ ].filter(Boolean);
156
+ if (parts.length > 0) {
157
+ (0, ui_1.getUI)().log.info(`Using: ${parts.join(' / ')}`);
158
+ }
159
+ }
160
+ };
46
161
  if (process.env.NODE_ENV === 'test') {
47
162
  void (async () => {
48
163
  try {
@@ -98,6 +213,14 @@ void (0, yargs_1.default)((0, helpers_1.hideBin)(process.argv))
98
213
  describe: 'Amplitude project ID to use (optional; when not set, uses default from API key or OAuth)\nenv: AMPLITUDE_WIZARD_PROJECT_ID',
99
214
  type: 'string',
100
215
  },
216
+ org: {
217
+ describe: 'Amplitude org name to use (for multi-org accounts)\nenv: AMPLITUDE_WIZARD_ORG',
218
+ type: 'string',
219
+ },
220
+ env: {
221
+ describe: 'Environment name to use (e.g. "Production", "Development")\nenv: AMPLITUDE_WIZARD_ENV',
222
+ type: 'string',
223
+ },
101
224
  })
102
225
  .command(['$0'], 'Run the Amplitude setup wizard', (yargs) => {
103
226
  return yargs.options({
@@ -135,30 +258,62 @@ void (0, yargs_1.default)((0, helpers_1.hideBin)(process.argv))
135
258
  describe: 'Run in benchmark mode with per-phase token tracking\nenv: AMPLITUDE_WIZARD_BENCHMARK',
136
259
  type: 'boolean',
137
260
  },
261
+ agent: {
262
+ default: false,
263
+ describe: 'Run in agent mode with structured JSON output\nenv: AMPLITUDE_WIZARD_AGENT',
264
+ type: 'boolean',
265
+ },
266
+ yes: {
267
+ alias: 'y',
268
+ default: false,
269
+ describe: 'Skip all prompts and use defaults (same as --ci)',
270
+ type: 'boolean',
271
+ },
272
+ classic: {
273
+ default: false,
274
+ describe: 'Use the classic prompt-based UI instead of the rich TUI\nenv: AMPLITUDE_WIZARD_CLASSIC',
275
+ type: 'boolean',
276
+ },
138
277
  });
139
278
  }, (argv) => {
140
279
  const options = { ...argv };
141
280
  // CI mode validation and TTY check
142
- if (options.ci) {
143
- // Use LoggingUI for CI mode (no dependencies, no prompts)
281
+ if (options.agent ||
282
+ process.env.AMPLITUDE_WIZARD_AGENT === '1' ||
283
+ (!options.ci &&
284
+ !options.yes &&
285
+ !options.classic &&
286
+ process.env.AMPLITUDE_WIZARD_CLASSIC !== '1' &&
287
+ (0, environment_1.isNonInteractiveEnvironment)())) {
288
+ // Agent mode (explicit --agent or auto-detected non-TTY)
289
+ if (!options.agent)
290
+ options.agent = true;
291
+ void (async () => {
292
+ const { AgentUI } = await import('./src/ui/agent-ui.js');
293
+ const agentUI = new AgentUI();
294
+ (0, ui_1.setUI)(agentUI);
295
+ if (!options.installDir)
296
+ options.installDir = process.cwd();
297
+ const session = await buildSessionFromOptions(options);
298
+ await resolveNonInteractiveCredentials(session, options, 'agent', agentUI);
299
+ await lazyRunWizard(options, session);
300
+ })();
301
+ }
302
+ else if (options.ci || options.yes) {
303
+ // CI mode: no prompts, auto-select first environment
144
304
  (0, ui_1.setUI)(new logging_ui_1.LoggingUI());
145
- if (!options.installDir) {
146
- (0, ui_1.getUI)().intro(chalk_1.default.inverse(`Amplitude Wizard`));
147
- (0, ui_1.getUI)().log.error('CI mode requires --install-dir (directory to install Amplitude in)');
148
- process.exit(1);
149
- }
150
- void (0, run_1.runWizard)(options);
305
+ if (!options.installDir)
306
+ options.installDir = process.cwd();
307
+ void (async () => {
308
+ const session = await buildSessionFromOptions(options, { ci: true });
309
+ await resolveNonInteractiveCredentials(session, options, 'ci');
310
+ await lazyRunWizard(options, session);
311
+ })();
151
312
  }
152
- else if ((0, environment_1.isNonInteractiveEnvironment)()) {
153
- // Non-interactive non-CI: error out
154
- (0, ui_1.getUI)().intro(chalk_1.default.inverse(`Amplitude Wizard`));
155
- (0, ui_1.getUI)().log.error('This installer requires an interactive terminal (TTY) to run.\n' +
156
- 'It appears you are running in a non-interactive environment.\n' +
157
- 'Please run the wizard in an interactive terminal.\n\n' +
158
- 'For CI/CD environments, use --ci mode:\n' +
159
- ' npx @amplitude/wizard --ci --install-dir . [--api-key <your-key>]\n' +
160
- ' (--api-key is optional when a key can be resolved from env or stored credentials.)');
161
- process.exit(1);
313
+ else if (options.classic ||
314
+ process.env.AMPLITUDE_WIZARD_CLASSIC === '1') {
315
+ // Classic mode: interactive prompts without the rich TUI
316
+ void lazyRunWizard(options);
162
317
  }
163
318
  else {
164
319
  // Interactive TTY: launch the Ink TUI
@@ -168,23 +323,9 @@ void (0, yargs_1.default)((0, helpers_1.hideBin)(process.argv))
168
323
  installCompletions();
169
324
  try {
170
325
  const { startTUI } = await import('./src/ui/tui/start-tui.js');
171
- const { buildSession } = await import('./src/lib/wizard-session.js');
172
326
  const tui = startTUI(WIZARD_VERSION);
173
327
  // Build session from CLI args and attach to store
174
- const session = buildSession({
175
- debug: options.debug,
176
- verbose: options.verbose,
177
- forceInstall: options.forceInstall,
178
- installDir: options.installDir,
179
- ci: false,
180
- signup: options.signup,
181
- localMcp: options.localMcp,
182
- apiKey: options.apiKey,
183
- menu: options.menu,
184
- integration: options.integration,
185
- benchmark: options.benchmark,
186
- projectId: options.projectId,
187
- });
328
+ const session = await buildSessionFromOptions(options);
188
329
  // If --api-key was provided, skip the OAuth/TUI auth flow entirely.
189
330
  if (session.apiKey) {
190
331
  const { DEFAULT_HOST_URL } = await import('./src/lib/constants.js');
@@ -197,170 +338,56 @@ void (0, yargs_1.default)((0, helpers_1.hideBin)(process.argv))
197
338
  session.projectHasData = false;
198
339
  }
199
340
  else {
200
- // Pre-populate region + credentials from all available sources for
201
- // returning users. This skips RegionSelect and Auth without requiring
202
- // a persisted OAuth token.
203
- const installDir = session.installDir;
204
- const [{ getStoredUser, getStoredToken }, { readAmpliConfig }, { getAPIKey }, { getHostFromRegion }, { logToFile }, { fetchAmplitudeUser },] = await Promise.all([
205
- import('./src/utils/ampli-settings.js'),
206
- import('./src/lib/ampli-config.js'),
207
- import('./src/utils/get-api-key.js'),
208
- import('./src/utils/urls.js'),
209
- import('./src/utils/debug.js'),
210
- import('./src/lib/api.js'),
211
- ]);
212
- // Zone: prefer a real (non-pending) stored user, fall back to
213
- // the Zone field in the project-level ampli.json.
214
- const storedUser = getStoredUser();
215
- const realUser = storedUser && storedUser.id !== 'pending' ? storedUser : null;
216
- const projectConfig = readAmpliConfig(installDir);
217
- const projectZone = projectConfig.ok
218
- ? projectConfig.config.Zone
219
- : undefined;
220
- const zone = realUser?.zone ?? projectZone ?? null;
221
- if (zone) {
222
- session.region = zone;
223
- }
224
- // Skip Auth when we have a stored OAuth token — use it to fetch
225
- // (or look up) the project API key, then pre-populate credentials.
226
- // When the workspace has multiple environments (projects), defer to
227
- // AuthScreen so the user can pick which project to instrument.
228
- if (zone) {
229
- const storedToken = realUser
230
- ? getStoredToken(realUser.id, realUser.zone)
231
- : getStoredToken(undefined, zone);
232
- if (storedToken) {
233
- // Check local storage first — if a key is already persisted
234
- // for this install dir, use it without fetching user data.
235
- const { readApiKeyWithSource } = await import('./src/utils/api-key-store.js');
236
- const localKey = readApiKeyWithSource(installDir);
237
- if (localKey) {
238
- logToFile('[bin] using locally stored API key');
239
- session.credentials = {
240
- accessToken: storedToken.idToken,
241
- idToken: storedToken.idToken,
242
- projectApiKey: localKey.key,
243
- host: getHostFromRegion(zone),
244
- projectId: 0,
245
- };
246
- session.activationLevel = 'none';
247
- session.projectHasData = false;
248
- }
249
- else {
250
- // Fetch user data to check how many environments are available.
251
- const { fetchAmplitudeUser } = await import('./src/lib/api.js');
252
- try {
253
- const userInfo = await fetchAmplitudeUser(storedToken.idToken, zone);
254
- const workspaceId = session.selectedWorkspaceId ?? undefined;
255
- // Find the relevant workspace and its environments
256
- let envsWithKey = [];
257
- for (const org of userInfo.orgs) {
258
- const ws = workspaceId
259
- ? org.workspaces.find((w) => w.id === workspaceId)
260
- : org.workspaces[0];
261
- if (ws?.environments) {
262
- envsWithKey = ws.environments
263
- .filter((env) => env.app?.apiKey)
264
- .sort((a, b) => a.rank - b.rank);
265
- break;
266
- }
267
- }
268
- if (envsWithKey.length === 1) {
269
- // Single environment — auto-select as before
270
- const apiKey = envsWithKey[0].app.apiKey;
271
- session.selectedProjectName = envsWithKey[0].name;
272
- logToFile('[bin] single environment — auto-selecting API key');
273
- (0, api_key_store_1.persistApiKey)(apiKey, installDir);
274
- session.credentials = {
275
- accessToken: storedToken.idToken,
276
- idToken: storedToken.idToken,
277
- projectApiKey: apiKey,
278
- host: getHostFromRegion(zone),
279
- projectId: 0,
280
- };
281
- session.activationLevel = 'none';
282
- session.projectHasData = false;
283
- }
284
- else if (envsWithKey.length > 1) {
285
- // Multiple environments — show the project picker via
286
- // AuthScreen instead of auto-selecting.
287
- logToFile(`[bin] ${envsWithKey.length} environments found — deferring to project picker`);
288
- session.pendingOrgs = userInfo.orgs;
289
- session.pendingAuthIdToken = storedToken.idToken;
290
- session.pendingAuthAccessToken = storedToken.idToken;
291
- }
292
- else {
293
- logToFile('[bin] no environments with API keys — showing apiKeyNotice');
294
- session.apiKeyNotice =
295
- "Your API key couldn't be fetched automatically. " +
296
- 'Only organization admins can access project API keys — ' +
297
- 'if you need one, ask an admin to share it with you.';
298
- }
299
- }
300
- catch (err) {
301
- logToFile(`[bin] fetchAmplitudeUser failed: ${err instanceof Error ? err.message : 'unknown'}`);
302
- // Fall back to getAPIKey for backward compatibility
303
- const projectApiKey = await getAPIKey({
304
- installDir,
305
- idToken: storedToken.idToken,
306
- zone,
307
- workspaceId: session.selectedWorkspaceId ?? undefined,
308
- });
309
- if (projectApiKey) {
310
- (0, api_key_store_1.persistApiKey)(projectApiKey, installDir);
311
- session.credentials = {
312
- accessToken: storedToken.idToken,
313
- idToken: storedToken.idToken,
314
- projectApiKey,
315
- host: getHostFromRegion(zone),
316
- projectId: 0,
317
- };
318
- session.activationLevel = 'none';
319
- session.projectHasData = false;
320
- }
321
- else {
322
- session.apiKeyNotice =
323
- "Your API key couldn't be fetched automatically. " +
324
- 'Only organization admins can access project API keys — ' +
325
- 'if you need one, ask an admin to share it with you.';
326
- }
327
- }
328
- }
329
- }
330
- }
331
- // Pre-populate org/workspace from ampli.json so activation checks
332
- // (DataSetupScreen, DataIngestionCheckScreen) have the IDs they need
333
- // even when the SUSI flow was skipped.
334
- if (projectConfig.ok && projectConfig.config.OrgId) {
335
- session.selectedOrgId = String(projectConfig.config.OrgId);
336
- }
337
- if (projectConfig.ok && projectConfig.config.WorkspaceId) {
338
- session.selectedWorkspaceId = projectConfig.config.WorkspaceId;
341
+ // Pre-populate region + credentials from stored OAuth tokens.
342
+ const { logToFile } = await import('./src/utils/debug.js');
343
+ // Check for crash-recovery checkpoint
344
+ const { loadCheckpoint } = await import('./src/lib/session-checkpoint.js');
345
+ const checkpoint = loadCheckpoint(session.installDir);
346
+ if (checkpoint) {
347
+ Object.assign(session, checkpoint);
348
+ session.introConcluded = false;
349
+ session._restoredFromCheckpoint = true;
350
+ logToFile('[bin] restored session from crash-recovery checkpoint');
339
351
  }
352
+ // Resolve credentials using shared logic (token refresh,
353
+ // env auto-select, pendingOrgs population)
354
+ const { resolveCredentials } = await import('./src/lib/credential-resolution.js');
355
+ await resolveCredentials(session);
340
356
  // Resolve org/workspace display names so /whoami shows them.
341
- // Uses the stored token to fetch user info — fire-and-forget so it
342
- // doesn't block startup.
343
- if (zone && session.selectedOrgId) {
357
+ // Fire-and-forget so it doesn't block startup.
358
+ if (session.region && session.selectedOrgId) {
359
+ const { getStoredUser, getStoredToken } = await import('./src/utils/ampli-settings.js');
360
+ const { fetchAmplitudeUser } = await import('./src/lib/api.js');
361
+ const storedUser = getStoredUser();
362
+ const realUser = storedUser && storedUser.id !== 'pending' ? storedUser : null;
363
+ const zone = session.region;
344
364
  const storedToken = realUser
345
365
  ? getStoredToken(realUser.id, realUser.zone)
346
366
  : getStoredToken(undefined, zone);
347
367
  if (storedToken) {
348
368
  fetchAmplitudeUser(storedToken.idToken, zone)
349
369
  .then((userInfo) => {
350
- const org = userInfo.orgs.find((o) => o.id === session.selectedOrgId);
351
- if (org) {
352
- session.selectedOrgName = org.name;
353
- const ws = session.selectedWorkspaceId
354
- ? org.workspaces.find((w) => w.id === session.selectedWorkspaceId)
355
- : undefined;
356
- if (ws) {
357
- session.selectedWorkspaceName = ws.name;
358
- }
359
- // Update the store if it's already been assigned
360
- if (tui.store.session === session) {
361
- tui.store.emitChange();
370
+ let changed = false;
371
+ if (userInfo.email && !session.userEmail) {
372
+ session.userEmail = userInfo.email;
373
+ changed = true;
374
+ }
375
+ if (session.selectedOrgId) {
376
+ const org = userInfo.orgs.find((o) => o.id === session.selectedOrgId);
377
+ if (org) {
378
+ session.selectedOrgName = org.name;
379
+ changed = true;
380
+ const ws = session.selectedWorkspaceId
381
+ ? org.workspaces.find((w) => w.id === session.selectedWorkspaceId)
382
+ : undefined;
383
+ if (ws) {
384
+ session.selectedWorkspaceName = ws.name;
385
+ }
362
386
  }
363
387
  }
388
+ if (changed && tui.store.session === session) {
389
+ tui.store.emitChange();
390
+ }
364
391
  })
365
392
  .catch(() => {
366
393
  // Non-fatal — /whoami will just show (none)
@@ -369,6 +396,30 @@ void (0, yargs_1.default)((0, helpers_1.hideBin)(process.argv))
369
396
  }
370
397
  }
371
398
  tui.store.session = session;
399
+ // Load event plan from a previous run (if it exists) so the
400
+ // Events tab is available immediately on returning runs.
401
+ try {
402
+ const fs = await import('fs');
403
+ const evtPath = (0, path_1.resolve)(session.installDir, '.amplitude-events.json');
404
+ const evtContent = fs.readFileSync(evtPath, 'utf-8');
405
+ const evtSchema = zod_1.z.array(zod_1.z.object({
406
+ name: zod_1.z.string().optional(),
407
+ event: zod_1.z.string().optional(),
408
+ eventName: zod_1.z.string().optional(),
409
+ description: zod_1.z.string().optional(),
410
+ eventDescriptionAndReasoning: zod_1.z.string().optional(),
411
+ }));
412
+ const evtResult = evtSchema.safeParse(JSON.parse(evtContent));
413
+ if (evtResult.success && evtResult.data.length > 0) {
414
+ tui.store.setEventPlan(evtResult.data.map((e) => ({
415
+ name: e.name ?? e.event ?? e.eventName ?? '',
416
+ description: e.description ?? e.eventDescriptionAndReasoning ?? '',
417
+ })));
418
+ }
419
+ }
420
+ catch {
421
+ // No event plan file yet — that's fine
422
+ }
372
423
  // Initialize Amplitude Experiment feature flags (non-blocking).
373
424
  const { initFeatureFlags } = await import('./src/lib/feature-flags.js');
374
425
  await initFeatureFlags().catch(() => {
@@ -411,16 +462,18 @@ void (0, yargs_1.default)((0, helpers_1.hideBin)(process.argv))
411
462
  const { DEFAULT_AMPLITUDE_ZONE } = await import('./src/lib/constants.js');
412
463
  const { storeToken } = await import('./src/utils/ampli-settings.js');
413
464
  const forceFresh = !ampliConfigExists(installDir);
414
- // Wait for the user to pick a region (or for it to be pre-populated
415
- // from ~/.ampli.json for returning users) before opening the OAuth URL,
416
- // since the auth endpoint differs between US and EU.
465
+ // Wait for the user to dismiss the welcome screen AND pick a
466
+ // region before opening the OAuth URL. This ensures the logo
467
+ // and intro are visible before the browser opens.
417
468
  await new Promise((resolve) => {
418
- if (tui.store.session.region !== null) {
469
+ if (tui.store.session.introConcluded &&
470
+ tui.store.session.region !== null) {
419
471
  resolve();
420
472
  return;
421
473
  }
422
474
  const unsub = tui.store.subscribe(() => {
423
- if (tui.store.session.region !== null) {
475
+ if (tui.store.session.introConcluded &&
476
+ tui.store.session.region !== null) {
424
477
  unsub();
425
478
  resolve();
426
479
  }
@@ -460,6 +513,8 @@ void (0, yargs_1.default)((0, helpers_1.hideBin)(process.argv))
460
513
  refreshToken: auth.refreshToken,
461
514
  expiresAt: new Date(Date.now() + 3600 * 1000).toISOString(),
462
515
  });
516
+ // Populate user email for /whoami display
517
+ session.userEmail = userInfo.email;
463
518
  // Signal AuthScreen — triggers org/workspace/API key pickers
464
519
  tui.store.setOAuthComplete({
465
520
  accessToken: auth.accessToken,
@@ -564,6 +619,47 @@ void (0, yargs_1.default)((0, helpers_1.hideBin)(process.argv))
564
619
  // auth, data check, and any setup questions are all complete.
565
620
  const { Screen } = await import('./src/ui/tui/router.js');
566
621
  tui.store.onEnterScreen(Screen.Run, () => tui.store.completeSetup());
622
+ // Session checkpointing — save at key transitions so crash
623
+ // recovery can skip already-completed steps.
624
+ const { saveCheckpoint, clearCheckpoint } = await import('./src/lib/session-checkpoint.js');
625
+ // After auth completes (most expensive step to repeat)
626
+ tui.store.onEnterScreen(Screen.DataSetup, () => {
627
+ saveCheckpoint(tui.store.session);
628
+ });
629
+ // Before agent starts (captures all setup state)
630
+ tui.store.onEnterScreen(Screen.Run, () => {
631
+ saveCheckpoint(tui.store.session);
632
+ });
633
+ // Clear checkpoint only on successful completion — error/cancel
634
+ // should preserve the checkpoint so users can resume next run.
635
+ tui.store.onEnterScreen(Screen.Outro, () => {
636
+ if (tui.store.session.outroData?.kind === 'success') {
637
+ clearCheckpoint(tui.store.session.installDir);
638
+ }
639
+ });
640
+ // Save checkpoint on unexpected termination (Ctrl+C).
641
+ // First Ctrl+C saves checkpoint and exits promptly.
642
+ // Second Ctrl+C within the grace window force-kills immediately.
643
+ let sigintReceived = false;
644
+ process.on('SIGINT', () => {
645
+ if (sigintReceived) {
646
+ // Second Ctrl+C — force-kill without waiting
647
+ process.exit(130);
648
+ }
649
+ sigintReceived = true;
650
+ // Force-kill after 1 second if checkpoint save hangs
651
+ const forceTimer = setTimeout(() => process.exit(130), 1_000);
652
+ // Unref so it doesn't keep the event loop alive
653
+ if (forceTimer.unref)
654
+ forceTimer.unref();
655
+ try {
656
+ saveCheckpoint(tui.store.session);
657
+ }
658
+ catch {
659
+ // Best-effort — don't block exit
660
+ }
661
+ process.exit(130);
662
+ });
567
663
  // Wait for auth and framework detection to finish concurrently.
568
664
  await Promise.all([authTask, detectionTask]);
569
665
  if (session.verbose || session.debug) {
@@ -589,14 +685,14 @@ void (0, yargs_1.default)((0, helpers_1.hideBin)(process.argv))
589
685
  if (runWizardAnyway) {
590
686
  log('[bin] user chose to run setup wizard despite pre-detection');
591
687
  tui.store.resetForAgentAfterPreDetected();
592
- await (0, run_1.runWizard)(options, tui.store.session);
688
+ await lazyRunWizard(options, tui.store.session);
593
689
  }
594
690
  else {
595
691
  tui.store.setOutroData({ kind: OutroKind.Success });
596
692
  }
597
693
  }
598
694
  else {
599
- await (0, run_1.runWizard)(options, tui.store.session);
695
+ await lazyRunWizard(options, tui.store.session);
600
696
  }
601
697
  // Keep the outro screen visible — let process.exit() handle cleanup
602
698
  }
@@ -605,7 +701,7 @@ void (0, yargs_1.default)((0, helpers_1.hideBin)(process.argv))
605
701
  if (process.env.DEBUG || process.env.AMPLITUDE_WIZARD_DEBUG) {
606
702
  console.error('TUI init failed:', err);
607
703
  }
608
- await (0, run_1.runWizard)(options);
704
+ await lazyRunWizard(options);
609
705
  }
610
706
  })();
611
707
  }
@@ -669,11 +765,13 @@ void (0, yargs_1.default)((0, helpers_1.hideBin)(process.argv))
669
765
  void (async () => {
670
766
  const { getStoredUser, clearStoredCredentials } = await import('./src/utils/ampli-settings.js');
671
767
  const { clearApiKey } = await import('./src/utils/api-key-store.js');
768
+ const { clearCheckpoint } = await import('./src/lib/session-checkpoint.js');
672
769
  const installDir = argv.installDir ?? process.cwd();
673
770
  const user = getStoredUser();
674
771
  try {
675
772
  clearStoredCredentials();
676
773
  clearApiKey(installDir);
774
+ clearCheckpoint(installDir);
677
775
  if (user) {
678
776
  console.log(chalk_1.default.green(`✔ Logged out ${user.email}`));
679
777
  }
@@ -703,7 +801,7 @@ void (0, yargs_1.default)((0, helpers_1.hideBin)(process.argv))
703
801
  process.exit(0);
704
802
  })();
705
803
  })
706
- .command('feedback', 'Send product feedback (Amplitude event: wizard: Feedback Submitted)', (yargs) => {
804
+ .command('feedback', 'Send product feedback', (yargs) => {
707
805
  return yargs.options({
708
806
  message: {
709
807
  alias: 'm',
@@ -734,39 +832,52 @@ void (0, yargs_1.default)((0, helpers_1.hideBin)(process.argv))
734
832
  }
735
833
  })();
736
834
  })
737
- .command('slack', 'Set up Amplitude Slack integration', (y) => y, (argv) => {
835
+ .command('slack', 'Set up Amplitude Slack integration', (y) => y, (_argv) => {
738
836
  void (async () => {
837
+ // Dynamic imports may land named exports on `.default` under tsx
838
+ // CJS/ESM interop. This helper normalises that.
839
+ const cjs = (mod) => (mod.default ?? mod);
739
840
  try {
740
- const { startTUI } = await import('./src/ui/tui/start-tui.js');
741
- const { buildSession } = await import('./src/lib/wizard-session.js');
742
- const { Flow } = await import('./src/ui/tui/router.js');
743
- const { getStoredUser, getStoredToken } = await import('./src/utils/ampli-settings.js');
744
- const { getHostFromRegion } = await import('./src/utils/urls.js');
745
- const session = buildSession({
746
- debug: typeof argv['debug'] === 'boolean' ? argv['debug'] : undefined,
747
- });
748
- // Pre-populate credentials from ~/.ampli.json so SlackScreen can
749
- // resolve the org name via fetchAmplitudeUser.
841
+ const { getStoredUser, getStoredToken } = cjs(await import('./src/utils/ampli-settings.js'));
842
+ const { readAmpliConfig } = cjs(await import('./src/lib/ampli-config.js'));
843
+ const { fetchSlackInstallUrl, fetchSlackConnectionStatus } = cjs(await import('./src/lib/api.js'));
844
+ const { OUTBOUND_URLS } = cjs(await import('./src/lib/constants.js'));
845
+ const opn = (await import('opn')).default;
750
846
  const storedUser = getStoredUser();
751
847
  const zone = storedUser?.zone ?? 'us';
752
848
  const storedToken = getStoredToken(storedUser?.id, zone);
753
- if (storedToken) {
754
- session.region = zone;
755
- session.credentials = {
756
- accessToken: storedToken.idToken,
757
- projectApiKey: '',
758
- host: getHostFromRegion(zone),
759
- projectId: 0,
760
- };
849
+ // Thunder validates access_tokens via Hydra, not id_tokens.
850
+ const accessToken = storedToken?.accessToken;
851
+ // Read orgId from project-level ampli.json
852
+ const ampliConfig = readAmpliConfig(process.cwd());
853
+ const orgId = ampliConfig.ok ? ampliConfig.config.OrgId : undefined;
854
+ if (!accessToken || !orgId) {
855
+ (0, ui_1.setUI)(new logging_ui_1.LoggingUI());
856
+ (0, ui_1.getUI)().log.info('No Amplitude session found. Run `npx @amplitude/wizard` first to log in and set up your project.');
857
+ process.exit(1);
858
+ }
859
+ // Check if Slack is already connected before prompting install.
860
+ const isConnected = await fetchSlackConnectionStatus(accessToken, zone, orgId);
861
+ if (isConnected) {
862
+ (0, ui_1.setUI)(new logging_ui_1.LoggingUI());
863
+ (0, ui_1.getUI)().log.info('Slack is already connected to your Amplitude workspace.');
864
+ process.exit(0);
761
865
  }
762
- // Pass the pre-populated session so it's available before the first render.
763
- startTUI(WIZARD_VERSION, Flow.SlackSetup, session);
866
+ const settingsUrl = OUTBOUND_URLS.slackSettings(zone, orgId);
867
+ let url = settingsUrl;
868
+ // Try to get the direct Slack OAuth URL from Thunder.
869
+ const directUrl = await fetchSlackInstallUrl(accessToken, zone, orgId, settingsUrl);
870
+ if (directUrl)
871
+ url = directUrl;
872
+ (0, ui_1.setUI)(new logging_ui_1.LoggingUI());
873
+ (0, ui_1.getUI)().log.info(`Opening Slack integration: ${url}`);
874
+ await opn(url, { wait: false });
764
875
  }
765
876
  catch {
766
877
  (0, ui_1.setUI)(new logging_ui_1.LoggingUI());
767
- const { getCloudUrlFromRegion } = await import('./src/utils/urls.js');
878
+ const { getCloudUrlFromRegion } = cjs(await import('./src/utils/urls.js'));
768
879
  const opn = (await import('opn')).default;
769
- const url = `${getCloudUrlFromRegion('us')}/settings/profile`;
880
+ const url = `${getCloudUrlFromRegion('us')}/analytics/settings/profile`;
770
881
  (0, ui_1.getUI)().log.info(`Opening Amplitude Settings to connect Slack: ${url}`);
771
882
  await opn(url, { wait: false });
772
883
  }
@@ -791,7 +902,7 @@ void (0, yargs_1.default)((0, helpers_1.hideBin)(process.argv))
791
902
  const storedToken = getStoredToken(storedUser?.id, zone);
792
903
  if (storedToken) {
793
904
  session.credentials = {
794
- accessToken: storedToken.idToken,
905
+ accessToken: storedToken.accessToken,
795
906
  projectApiKey: '',
796
907
  host: getHostFromRegion(zone),
797
908
  projectId: 0,
@@ -900,6 +1011,11 @@ void (0, yargs_1.default)((0, helpers_1.hideBin)(process.argv))
900
1011
  process.stdout.write(script + '\n');
901
1012
  process.exit(0);
902
1013
  })
1014
+ .example('$0', 'Run the interactive setup wizard')
1015
+ .example('$0 --ci --api-key <key> --install-dir .', 'Run in CI mode')
1016
+ .example('$0 --agent --install-dir .', 'Run with structured JSON output for automation')
1017
+ .epilogue('Docs: https://amplitude.com/docs/wizard\nFeedback: wizard@amplitude.com')
1018
+ .recommendCommands()
903
1019
  .help()
904
1020
  .alias('help', 'h')
905
1021
  .version()