@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
@@ -13,19 +13,60 @@ export const COMMANDS = [
13
13
  { cmd: '/slack', desc: 'Set up Amplitude Slack integration' },
14
14
  {
15
15
  cmd: '/feedback',
16
- desc: 'Send product feedback (event: wizard: feedback submitted)',
16
+ desc: 'Send product feedback',
17
17
  },
18
- { cmd: '/test', desc: 'Run a prompt-skill demo (confirm + choose)' },
19
18
  { cmd: '/snake', desc: 'Play Snake' },
20
19
  { cmd: '/exit', desc: 'Exit the wizard' },
21
20
  ];
22
- export const TEST_PROMPT = 'Demo the wizard prompt tools. ' +
23
- 'First, use the wizard-tools:confirm tool to ask if I want to continue. ' +
24
- 'Then use the wizard-tools:choose tool to let me pick my favorite color from: Red, Blue, Green, Purple. ' +
25
- 'Finally, summarize what I chose in one sentence.';
26
21
  /** Returns the feedback text for the /whoami command. */
27
22
  export function getWhoamiText(session) {
28
- return `org: ${session.selectedOrgName ?? '(none)'} workspace: ${session.selectedWorkspaceName ?? '(none)'} region: ${session.region ?? '(none)'}`;
23
+ const loggedIn = session.credentials !== null && session.credentials !== undefined;
24
+ const hasAnyIdentity = loggedIn ||
25
+ session.userEmail ||
26
+ session.selectedOrgName ||
27
+ session.selectedOrgId;
28
+ if (!hasAnyIdentity) {
29
+ return 'Not logged in. Run /login to authenticate.';
30
+ }
31
+ const parts = [];
32
+ if (session.userEmail)
33
+ parts.push(session.userEmail);
34
+ if (session.selectedOrgName || session.selectedOrgId) {
35
+ const orgLabel = session.selectedOrgName ?? session.selectedOrgId ?? '(none)';
36
+ parts.push(`org: ${orgLabel}`);
37
+ }
38
+ // Show project (Amplitude calls this "workspace" internally, but users
39
+ // think of it as their project). Then show environment name + numeric ID.
40
+ if (session.selectedWorkspaceName) {
41
+ parts.push(`project: ${session.selectedWorkspaceName}`);
42
+ }
43
+ const envName = session.selectedProjectName;
44
+ const envId = session.credentials?.projectId && session.credentials.projectId !== 0
45
+ ? String(session.credentials.projectId)
46
+ : null;
47
+ if (envName && envId) {
48
+ parts.push(`env: ${envName} (${envId})`);
49
+ }
50
+ else if (envName) {
51
+ parts.push(`env: ${envName}`);
52
+ }
53
+ else if (envId) {
54
+ parts.push(`env: ${envId}`);
55
+ }
56
+ if (session.region) {
57
+ parts.push(`region: ${session.region}`);
58
+ }
59
+ // Show masked API key so the user knows which key is active
60
+ if (session.credentials?.projectApiKey) {
61
+ const key = session.credentials.projectApiKey;
62
+ const masked = key.length > 8 ? key.slice(0, 4) + '…' + key.slice(-4) : '****';
63
+ parts.push(`key: ${masked}`);
64
+ }
65
+ // If we have some identity but no credentials yet, hint that setup is in progress
66
+ if (!loggedIn && parts.length > 0) {
67
+ parts.push('(authenticating…)');
68
+ }
69
+ return parts.join(' ');
29
70
  }
30
71
  /**
31
72
  * Parses `/feedback <message>` from a slash command line.
@@ -8,7 +8,7 @@
8
8
  * optional completion predicate. The router walks the active flow
9
9
  * to resolve which screen to show.
10
10
  */
11
- import { type WizardSession } from '../../lib/wizard-session.js';
11
+ import type { WizardSession } from '../../lib/wizard-session.js';
12
12
  /** Screens that participate in linear flows */
13
13
  export declare enum Screen {
14
14
  Intro = "intro",
@@ -8,7 +8,7 @@
8
8
  * optional completion predicate. The router walks the active flow
9
9
  * to resolve which screen to show.
10
10
  */
11
- import { RunPhase } from '../../lib/wizard-session.js';
11
+ import { RunPhase } from './session-constants.js';
12
12
  // ── Screen + Flow enums ──────────────────────────────────────────────
13
13
  /** Screens that participate in linear flows */
14
14
  export var Screen;
@@ -0,0 +1,15 @@
1
+ /**
2
+ * useAsyncEffect — AbortController-based async effect hook.
3
+ *
4
+ * Automatically aborts in-flight async work when the effect re-runs
5
+ * or the component unmounts. Prevents stale state writes from
6
+ * completed promises that arrive after the component has moved on.
7
+ *
8
+ * Usage:
9
+ * useAsyncEffect(async (signal) => {
10
+ * const data = await fetch(url, { signal });
11
+ * if (!signal.aborted) setData(data);
12
+ * }, [url]);
13
+ */
14
+ import { type DependencyList } from 'react';
15
+ export declare function useAsyncEffect(effect: (signal: AbortSignal) => Promise<void>, deps: DependencyList): void;
@@ -0,0 +1,35 @@
1
+ /**
2
+ * useAsyncEffect — AbortController-based async effect hook.
3
+ *
4
+ * Automatically aborts in-flight async work when the effect re-runs
5
+ * or the component unmounts. Prevents stale state writes from
6
+ * completed promises that arrive after the component has moved on.
7
+ *
8
+ * Usage:
9
+ * useAsyncEffect(async (signal) => {
10
+ * const data = await fetch(url, { signal });
11
+ * if (!signal.aborted) setData(data);
12
+ * }, [url]);
13
+ */
14
+ import { useEffect, useRef } from 'react';
15
+ import { logToFile } from '../../../utils/debug.js';
16
+ export function useAsyncEffect(effect, deps) {
17
+ // Use a ref to always call the latest effect without re-subscribing
18
+ const effectRef = useRef(effect);
19
+ effectRef.current = effect;
20
+ useEffect(() => {
21
+ const controller = new AbortController();
22
+ void effectRef.current(controller.signal).catch((err) => {
23
+ // Silently ignore abort errors — they're expected on cleanup
24
+ if (err instanceof DOMException && err.name === 'AbortError')
25
+ return;
26
+ if (err instanceof Error && err.name === 'AbortError')
27
+ return;
28
+ if (controller.signal.aborted)
29
+ return;
30
+ // Log other errors but don't crash — screen error boundary handles display
31
+ logToFile(`[useAsyncEffect] ${err instanceof Error ? err.message : String(err)}`);
32
+ });
33
+ return () => controller.abort();
34
+ }, deps);
35
+ }
@@ -0,0 +1,9 @@
1
+ /**
2
+ * useWizardStore — eliminates repeated useSyncExternalStore boilerplate.
3
+ *
4
+ * Every screen had the same 4-line subscription pattern. This hook
5
+ * replaces it with a single call. Uses .bind() for stable references
6
+ * to avoid unnecessary resubscription on render.
7
+ */
8
+ import type { WizardStore } from '../store.js';
9
+ export declare function useWizardStore(store: WizardStore): void;
@@ -0,0 +1,11 @@
1
+ /**
2
+ * useWizardStore — eliminates repeated useSyncExternalStore boilerplate.
3
+ *
4
+ * Every screen had the same 4-line subscription pattern. This hook
5
+ * replaces it with a single call. Uses .bind() for stable references
6
+ * to avoid unnecessary resubscription on render.
7
+ */
8
+ import { useSyncExternalStore } from 'react';
9
+ export function useWizardStore(store) {
10
+ useSyncExternalStore(store.subscribe.bind(store), store.getSnapshot.bind(store));
11
+ }
@@ -6,7 +6,7 @@
6
6
  * The router derives the active screen from session state.
7
7
  */
8
8
  import { Overlay } from './router.js';
9
- import { RunPhase, OutroKind } from '../../lib/wizard-session.js';
9
+ import { RunPhase, OutroKind } from './session-constants.js';
10
10
  // Strip ANSI escape codes (chalk formatting) from strings
11
11
  // eslint-disable-next-line no-control-regex
12
12
  const ANSI_RE = /\x1b\[[0-9;]*m/g;
@@ -13,7 +13,7 @@ import { useState, useEffect, useRef } from 'react';
13
13
  /** Shade characters in build-up order (light → solid). */
14
14
  const SHADES = ['░', '▒', '▓', '█'];
15
15
  /** How many ticks each shade character displays before advancing. */
16
- const TICKS_PER_SHADE = 2;
16
+ const TICKS_PER_SHADE = 1;
17
17
  /** Total ticks a column needs to complete its shade cycle. */
18
18
  const SHADE_CYCLE_TICKS = SHADES.length * TICKS_PER_SHADE;
19
19
  function easeInOutCirc(t) {
@@ -28,7 +28,7 @@ var TransitionPhase;
28
28
  TransitionPhase["Out"] = "out";
29
29
  TransitionPhase["In"] = "in";
30
30
  })(TransitionPhase || (TransitionPhase = {}));
31
- export const DissolveTransition = ({ transitionKey, width, height, children, direction = 'left', duration = 2, }) => {
31
+ export const DissolveTransition = ({ transitionKey, width, height, children, direction = 'left', duration = 16, }) => {
32
32
  const [phase, setPhase] = useState(TransitionPhase.Idle);
33
33
  const [tick, setTick] = useState(0);
34
34
  const [activeDir, setActiveDir] = useState(direction);
@@ -58,9 +58,8 @@ export const DissolveTransition = ({ transitionKey, width, height, children, dir
58
58
  }, duration);
59
59
  return () => clearInterval(timer);
60
60
  }, [phase, duration]);
61
- // Easer steps = width: roughly one column activates per tick.
62
- // This keeps the sweep front tight (only a few columns in-flight at once).
63
- const easerSteps = width;
61
+ // Easer steps = width / 3: ~3 columns activate per tick for a fast sweep.
62
+ const easerSteps = Math.max(Math.ceil(width / 3), 10);
64
63
  // A phase ends when the easer has completed AND all columns have finished their shade cycle.
65
64
  const maxTicks = easerSteps + SHADE_CYCLE_TICKS;
66
65
  useEffect(() => {
@@ -1,5 +1,7 @@
1
1
  /**
2
- * EventPlanViewer — Renders a table of planned analytics events.
2
+ * EventPlanViewer — Renders a list of planned analytics events.
3
+ *
4
+ * Each event shows as: ● event name — description
3
5
  */
4
6
  import type { PlannedEvent } from '../store.js';
5
7
  interface EventPlanViewerProps {
@@ -1,9 +1,14 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
2
  /**
3
- * EventPlanViewer — Renders a table of planned analytics events.
3
+ * EventPlanViewer — Renders a list of planned analytics events.
4
+ *
5
+ * Each event shows as: ● event name — description
4
6
  */
5
7
  import { Box, Text } from 'ink';
6
- import { Colors } from '../styles.js';
8
+ import { Colors, Icons } from '../styles.js';
7
9
  export const EventPlanViewer = ({ events }) => {
8
- return (_jsxs(Box, { flexDirection: "column", paddingX: 1, children: [_jsx(Text, { bold: true, children: "Event plan" }), _jsx(Box, { height: 1 }), events.map((event) => (_jsxs(Box, { children: [_jsx(Text, { bold: true, children: event.name }), _jsxs(Text, { color: Colors.muted, children: [" ", event.description] })] }, event.name)))] }));
10
+ if (events.length === 0) {
11
+ return (_jsxs(Box, { flexDirection: "column", paddingX: 1, children: [_jsx(Text, { bold: true, children: "Event plan" }), _jsx(Box, { height: 1 }), _jsx(Text, { color: Colors.muted, children: "Waiting for the agent to propose events..." })] }));
12
+ }
13
+ return (_jsxs(Box, { flexDirection: "column", paddingX: 1, children: [_jsx(Text, { bold: true, children: "Event plan" }), _jsx(Box, { height: 1 }), events.map((event) => (_jsxs(Text, { color: Colors.muted, children: [Icons.bullet, ' ', _jsx(Text, { color: Colors.accent, bold: true, children: event.name }), event.description ? ` — ${event.description}` : ''] }, event.name)))] }));
9
14
  };
@@ -10,7 +10,7 @@ import { LoadingBox } from './LoadingBox.js';
10
10
  export const ProgressList = ({ items, title }) => {
11
11
  const completed = items.filter((t) => t.status === 'completed').length;
12
12
  const total = items.length;
13
- return (_jsxs(Box, { flexDirection: "column", children: [title && (_jsxs(_Fragment, { children: [_jsx(Text, { bold: true, children: title }), _jsx(Text, { children: " " })] })), items.length === 0 && _jsx(LoadingBox, { message: "Analyzing project..." }), items.map((item, i) => {
13
+ return (_jsxs(Box, { flexDirection: "column", children: [title && (_jsxs(_Fragment, { children: [_jsx(Text, { bold: true, children: title }), _jsx(Box, { height: 1 })] })), items.length === 0 && _jsx(LoadingBox, { message: "Analyzing project..." }), items.map((item, i) => {
14
14
  const icon = item.status === 'completed'
15
15
  ? Icons.squareFilled
16
16
  : item.status === 'in_progress'
@@ -1,4 +1,4 @@
1
- import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
1
+ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
2
2
  /**
3
3
  * SlashCommandInput — Text input with slash-command picker.
4
4
  *
@@ -34,6 +34,7 @@ export const SlashCommandInput = ({ commands = [], isActive, initialValue = '',
34
34
  })
35
35
  : [];
36
36
  const clampedIndex = Math.min(selectedIndex, Math.max(0, filtered.length - 1));
37
+ const maxCmdLen = filtered.reduce((m, c) => Math.max(m, c.cmd.length), 0);
37
38
  useInput((char, key) => {
38
39
  if (key.upArrow && isSlashMode) {
39
40
  setSelectedIndex((i) => Math.max(0, i - 1));
@@ -79,7 +80,21 @@ export const SlashCommandInput = ({ commands = [], isActive, initialValue = '',
79
80
  if (!isActive) {
80
81
  return (_jsxs(Box, { gap: 1, children: [_jsx(Text, { color: Colors.muted, children: '>' }), _jsx(Text, { color: Colors.muted, inverse: false, children: ' ' })] }));
81
82
  }
82
- return (_jsxs(Box, { flexDirection: "column", children: [_jsxs(Box, { gap: 1, children: [_jsx(Text, { color: Colors.muted, children: '>' }), _jsxs(Text, { children: [value, cursorVisible ? _jsx(Text, { inverse: true, children: " " }) : _jsx(Text, { children: " " })] })] }), isSlashMode && filtered.length > 0 && (_jsx(Box, { flexDirection: "column", marginTop: 1, children: filtered.map((c, i) => (_jsxs(Box, { gap: 2, children: [_jsx(Text, { color: i === clampedIndex ? Colors.primary : undefined, bold: i === clampedIndex, children: i === clampedIndex
83
- ? Icons.triangleSmallRight + ' ' + c.cmd
84
- : ' ' + c.cmd }), _jsx(Text, { color: i !== clampedIndex ? Colors.muted : undefined, children: c.desc })] }, c.cmd))) }))] }));
83
+ return (_jsxs(Box, { flexDirection: "column", children: [_jsxs(Box, { gap: 1, children: [_jsx(Text, { color: Colors.muted, children: '>' }), _jsxs(Text, { children: [value, cursorVisible ? _jsx(Text, { inverse: true, children: " " }) : _jsx(Text, { children: " " })] })] }), isSlashMode && filtered.length > 0 && (_jsx(Box, { flexDirection: "column", marginTop: 1, children: (() => {
84
+ // Show at most MAX_VISIBLE commands, scrolling to keep selection visible
85
+ const MAX_VISIBLE = 6;
86
+ const total = filtered.length;
87
+ let startIdx = 0;
88
+ if (total > MAX_VISIBLE) {
89
+ // Keep selected item in the middle of the visible window
90
+ startIdx = Math.max(0, Math.min(clampedIndex - Math.floor(MAX_VISIBLE / 2), total - MAX_VISIBLE));
91
+ }
92
+ const visible = filtered.slice(startIdx, startIdx + MAX_VISIBLE);
93
+ const hasMore = total > MAX_VISIBLE;
94
+ return (_jsxs(_Fragment, { children: [hasMore && startIdx > 0 && (_jsxs(Text, { color: Colors.muted, children: [' ', "\u2191 ", startIdx, " more"] })), visible.map((c, vi) => {
95
+ const i = startIdx + vi;
96
+ const isFocused = i === clampedIndex;
97
+ return (_jsxs(Box, { gap: 1, children: [_jsx(Text, { color: isFocused ? Colors.primary : undefined, bold: isFocused, children: isFocused ? Icons.triangleSmallRight : ' ' }), _jsx(Text, { color: isFocused ? Colors.primary : undefined, bold: isFocused, children: c.cmd.padEnd(maxCmdLen) }), _jsx(Text, { color: !isFocused ? Colors.muted : undefined, children: c.desc })] }, c.cmd));
98
+ }), hasMore && startIdx + MAX_VISIBLE < total && (_jsxs(Text, { color: Colors.muted, children: [' ', "\u2193 ", total - startIdx - MAX_VISIBLE, " more"] }))] }));
99
+ })() }))] }));
85
100
  };
@@ -1,5 +1,6 @@
1
1
  /**
2
- * SplitView — Two-pane horizontal layout: 50/50.
2
+ * SplitView — Two-pane layout that adapts to terminal width.
3
+ * Side-by-side at ≥80 cols, stacked vertically below that.
3
4
  */
4
5
  import type { ReactNode } from 'react';
5
6
  interface SplitViewProps {
@@ -1,8 +1,16 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
2
  /**
3
- * SplitView — Two-pane horizontal layout: 50/50.
3
+ * SplitView — Two-pane layout that adapts to terminal width.
4
+ * Side-by-side at ≥80 cols, stacked vertically below that.
4
5
  */
5
6
  import { Box } from 'ink';
7
+ import { useStdoutDimensions } from '../hooks/useStdoutDimensions.js';
8
+ const STACK_THRESHOLD = 80;
6
9
  export const SplitView = ({ left, right, gap = 2 }) => {
7
- return (_jsxs(Box, { flexDirection: "row", flexGrow: 1, gap: gap, children: [_jsx(Box, { width: "50%", flexDirection: "column", children: left }), _jsx(Box, { width: "50%", flexDirection: "column", children: right })] }));
10
+ const [columns] = useStdoutDimensions();
11
+ const stacked = columns < STACK_THRESHOLD;
12
+ if (stacked) {
13
+ return (_jsxs(Box, { flexDirection: "column", flexGrow: 1, gap: 1, children: [_jsx(Box, { flexDirection: "column", children: right }), _jsx(Box, { flexDirection: "column", children: left })] }));
14
+ }
15
+ return (_jsxs(Box, { flexDirection: "row", flexGrow: 1, gap: gap, children: [_jsx(Box, { width: "50%", flexDirection: "column", overflow: "hidden", children: left }), _jsx(Box, { width: "50%", flexDirection: "column", overflow: "hidden", children: right })] }));
8
16
  };
@@ -17,14 +17,22 @@ export const TabContainer = ({ tabs, statusMessage, requestedTab, onTabConsumed,
17
17
  setActiveTab(idx);
18
18
  onTabConsumed?.();
19
19
  }, [requestedTab]);
20
- useScreenInput((_input, key) => {
20
+ useScreenInput((input, key) => {
21
+ // Arrow keys always switch tabs (Snake uses WASD for movement)
21
22
  if (key.leftArrow) {
22
23
  setActiveTab((prev) => Math.max(0, prev - 1));
24
+ return;
23
25
  }
24
26
  if (key.rightArrow) {
25
27
  setActiveTab((prev) => Math.min(tabs.length - 1, prev + 1));
28
+ return;
29
+ }
30
+ // Number keys also work for tab switching (1-indexed)
31
+ const num = parseInt(input, 10);
32
+ if (!isNaN(num) && num >= 1 && num <= tabs.length) {
33
+ setActiveTab(num - 1);
26
34
  }
27
35
  });
28
36
  const current = tabs[activeTab];
29
- return (_jsxs(Box, { flexDirection: "column", flexGrow: 1, children: [_jsx(Box, { flexDirection: "column", flexGrow: 1, children: current?.component }), statusMessage && (_jsx(Box, { borderStyle: "single", borderTop: true, borderBottom: false, borderLeft: false, borderRight: false, borderColor: Colors.muted, paddingX: 1, overflow: "hidden", children: _jsxs(Text, { color: Colors.muted, children: [Icons.diamondOpen, " ", statusMessage] }) })), _jsx(Box, { height: 1 }), _jsxs(Box, { gap: 1, paddingX: 1, justifyContent: "space-between", children: [_jsx(Box, { gap: 1, children: tabs.map((tab, i) => (_jsx(Text, { inverse: i === activeTab, color: i === activeTab ? Colors.accent : Colors.muted, bold: i === activeTab, children: ` ${tab.label} ` }, tab.id))) }), _jsx(Text, { color: Colors.muted, children: "\u2190 \u2192 to browse tabs while the wizard runs" })] })] }));
37
+ return (_jsxs(Box, { flexDirection: "column", flexGrow: 1, children: [_jsx(Box, { flexDirection: "column", flexGrow: 1, overflow: "hidden", children: current?.component }), _jsxs(Box, { flexDirection: "column", flexShrink: 0, children: [statusMessage && (_jsx(Box, { borderStyle: "single", borderTop: true, borderBottom: false, borderLeft: false, borderRight: false, borderColor: Colors.muted, paddingX: 1, overflow: "hidden", children: _jsxs(Text, { color: Colors.muted, children: [Icons.diamondOpen, " ", statusMessage] }) })), _jsx(Box, { height: 1 }), _jsxs(Box, { gap: 1, paddingX: 1, justifyContent: "space-between", children: [_jsx(Box, { gap: 1, children: tabs.map((tab, i) => (_jsx(Text, { inverse: i === activeTab, color: i === activeTab ? Colors.accent : Colors.muted, bold: i === activeTab, children: ` ${tab.label} ` }, tab.id))) }), _jsx(Text, { color: Colors.muted, children: "\u2190 \u2192 to switch tabs" })] })] })] }));
30
38
  };
@@ -15,7 +15,6 @@ export { EventPlanViewer } from './EventPlanViewer.js';
15
15
  export { ScreenErrorBoundary } from './ScreenErrorBoundary.js';
16
16
  export { TabContainer } from './TabContainer.js';
17
17
  export type { TabDefinition } from './TabContainer.js';
18
- export { KagiSmallWebViewer } from './KagiSmallWebViewer.js';
19
18
  export { SnakeGame } from './SnakeGame.js';
20
19
  export { DissolveTransition } from './DissolveTransition.js';
21
20
  export type { WipeDirection } from './DissolveTransition.js';
@@ -13,7 +13,6 @@ export { ReportViewer } from './ReportViewer.js';
13
13
  export { EventPlanViewer } from './EventPlanViewer.js';
14
14
  export { ScreenErrorBoundary } from './ScreenErrorBoundary.js';
15
15
  export { TabContainer } from './TabContainer.js';
16
- export { KagiSmallWebViewer } from './KagiSmallWebViewer.js';
17
16
  export { SnakeGame } from './SnakeGame.js';
18
17
  export { DissolveTransition } from './DissolveTransition.js';
19
18
  export { SlashCommandInput } from './SlashCommandInput.js';
@@ -11,7 +11,7 @@
11
11
  * Adding an overlay = call pushOverlay() from anywhere.
12
12
  * No switch statements, no hardcoded transitions in business logic.
13
13
  */
14
- import { OutroKind } from '../../lib/wizard-session.js';
14
+ import { OutroKind } from './session-constants.js';
15
15
  import { FLOWS, Screen, Flow } from './flows.js';
16
16
  // Re-export so existing imports from './router.js' keep working
17
17
  export { Screen, Flow };
@@ -1,12 +1,5 @@
1
1
  /**
2
2
  * Screen registry — maps screen names to React components.
3
- *
4
- * Adding a new screen:
5
- * 1. Create the component in screens/
6
- * 2. Add an entry here
7
- * 3. Add the screen name to the router flow (router.ts)
8
- *
9
- * App.tsx never needs to change.
10
3
  */
11
4
  import type { ReactNode } from 'react';
12
5
  import type { WizardStore } from './store.js';
@@ -17,7 +17,7 @@ import { LogoutScreen } from './screens/LogoutScreen.js';
17
17
  import { LoginScreen } from './screens/LoginScreen.js';
18
18
  import { OutroScreen } from './screens/OutroScreen.js';
19
19
  import { createMcpInstaller } from './services/mcp-installer.js';
20
- import { SnakeGame } from './primitives/SnakeGame.js';
20
+ import { SnakeGame } from './primitives/index.js';
21
21
  export function createServices(localMcp = false) {
22
22
  return {
23
23
  mcpInstaller: createMcpInstaller(localMcp),
@@ -28,10 +28,19 @@ export function createScreens(store, services) {
28
28
  // Overlays
29
29
  [Overlay.Outage]: _jsx(OutageScreen, { store: store }),
30
30
  [Overlay.SettingsOverride]: _jsx(SettingsOverrideScreen, { store: store }),
31
- [Overlay.Snake]: _jsx(SnakeGame, { onExit: () => store.hideSnakeOverlay() }),
31
+ [Overlay.Snake]: (_jsx(SnakeGame, { onExit: () => store.hideSnakeOverlay(), music: false })),
32
32
  [Overlay.Mcp]: (_jsx(McpScreen, { store: store, installer: services.mcpInstaller, onComplete: () => store.hideMcpOverlay() })),
33
33
  [Overlay.Slack]: (_jsx(SlackScreen, { store: store, onComplete: () => store.hideSlackOverlay() })),
34
- [Overlay.Logout]: (_jsx(LogoutScreen, { onComplete: () => store.hideLogoutOverlay(), installDir: store.session.installDir })),
34
+ [Overlay.Logout]: (_jsx(LogoutScreen, { onComplete: () => store.hideLogoutOverlay(), installDir: store.session.installDir, onLoggedOut: () => {
35
+ store.session.credentials = null;
36
+ store.session.userEmail = null;
37
+ store.session.selectedOrgId = null;
38
+ store.session.selectedOrgName = null;
39
+ store.session.selectedWorkspaceId = null;
40
+ store.session.selectedWorkspaceName = null;
41
+ store.session.selectedProjectName = null;
42
+ store.emitChange();
43
+ } })),
35
44
  [Overlay.Login]: (_jsx(LoginScreen, { store: store, onComplete: () => store.hideLoginOverlay() })),
36
45
  // Wizard flow
37
46
  [Screen.Intro]: _jsx(IntroScreen, { store: store }),
@@ -49,7 +58,7 @@ export function createScreens(store, services) {
49
58
  // Standalone MCP flows
50
59
  [Screen.McpAdd]: (_jsx(McpScreen, { store: store, installer: services.mcpInstaller, standalone: true })),
51
60
  [Screen.McpRemove]: (_jsx(McpScreen, { store: store, installer: services.mcpInstaller, mode: "remove", standalone: true })),
52
- // Slack integration (in-wizard step and standalone flow)
61
+ // Slack integration
53
62
  [Screen.Slack]: _jsx(SlackScreen, { store: store }),
54
63
  [Screen.SlackSetup]: _jsx(SlackScreen, { store: store, standalone: true }),
55
64
  };
@@ -1,8 +1,8 @@
1
1
  /**
2
- * ActivationOptionsScreen — "What would you like to do?" prompt.
2
+ * ActivationOptionsScreen — "What would you like to do?" prompt (v2).
3
3
  *
4
4
  * Shown when the user has the SDK installed but hasn't fully activated yet
5
- * (149 events). Offers next-step options without forcing a full re-run.
5
+ * (1-49 events). Offers next-step options without forcing a full re-run.
6
6
  */
7
7
  import type { WizardStore } from '../store.js';
8
8
  interface ActivationOptionsScreenProps {
@@ -1,20 +1,20 @@
1
1
  import { jsxs as _jsxs, jsx as _jsx } from "react/jsx-runtime";
2
2
  /**
3
- * ActivationOptionsScreen — "What would you like to do?" prompt.
3
+ * ActivationOptionsScreen — "What would you like to do?" prompt (v2).
4
4
  *
5
5
  * Shown when the user has the SDK installed but hasn't fully activated yet
6
- * (149 events). Offers next-step options without forcing a full re-run.
6
+ * (1-49 events). Offers next-step options without forcing a full re-run.
7
7
  */
8
8
  import { Box, Text } from 'ink';
9
- import { useSyncExternalStore } from 'react';
9
+ import { useWizardStore } from '../hooks/useWizardStore.js';
10
10
  import { PickerMenu } from '../primitives/index.js';
11
- import { Colors } from '../styles.js';
12
- import { OutroKind } from '../../../lib/wizard-session.js';
11
+ import { Colors, Icons } from '../styles.js';
12
+ import { OutroKind } from '../session-constants.js';
13
13
  import { OUTBOUND_URLS } from '../../../lib/constants.js';
14
14
  import opn from 'opn';
15
15
  const DOCS_URL = OUTBOUND_URLS.sdkDocs;
16
16
  export const ActivationOptionsScreen = ({ store, }) => {
17
- useSyncExternalStore((cb) => store.subscribe(cb), () => store.getSnapshot());
17
+ useWizardStore(store);
18
18
  const { snippetConfigured } = store.session;
19
19
  const handleSelect = (value) => {
20
20
  switch (value) {
@@ -40,13 +40,13 @@ export const ActivationOptionsScreen = ({ store, }) => {
40
40
  break;
41
41
  }
42
42
  };
43
- return (_jsxs(Box, { flexDirection: "column", flexGrow: 1, children: [_jsxs(Text, { bold: true, color: Colors.accent, children: ["Your SDK is", snippetConfigured ? ' installed' : ' partially set up', " \u2014 waiting for events"] }), _jsxs(Box, { marginTop: 1, flexDirection: "column", children: [_jsx(Text, { color: Colors.muted, children: "We can see your project is configured but hasn't received many events yet." }), _jsx(Text, { color: Colors.muted, children: "What would you like to do?" })] }), _jsx(Box, { marginTop: 1, children: _jsx(PickerMenu, { options: [
43
+ return (_jsxs(Box, { flexDirection: "column", flexGrow: 1, children: [_jsxs(Text, { bold: true, color: Colors.accent, children: ["Your SDK is", snippetConfigured ? ' installed' : ' partially set up', ' ', Icons.dash, " waiting for events"] }), _jsxs(Box, { marginTop: 1, flexDirection: "column", children: [_jsx(Text, { color: Colors.secondary, children: "We can see your project is configured but hasn't received many events yet." }), _jsx(Text, { color: Colors.body, children: "What would you like to do?" })] }), _jsx(Box, { marginTop: 1, children: _jsx(PickerMenu, { options: [
44
44
  {
45
45
  value: 'test-locally',
46
46
  label: 'Help me test locally',
47
47
  hint: 'run the setup agent',
48
48
  },
49
- { value: 'debug', label: "I'm blocked", hint: 'debug with Claude' },
49
+ { value: 'debug', label: "I'm blocked", hint: 'get help' },
50
50
  { value: 'docs', label: 'Take me to the docs', hint: DOCS_URL },
51
51
  {
52
52
  value: 'exit',
@@ -1,4 +1,4 @@
1
- import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
1
+ import { jsxs as _jsxs, jsx as _jsx } from "react/jsx-runtime";
2
2
  /**
3
3
  * AuthScreen — Multi-step authentication and account setup (SUSI flow).
4
4
  *
@@ -13,10 +13,12 @@ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-run
13
13
  * When credentials are set the router resolves past this screen.
14
14
  */
15
15
  import { Box, Text } from 'ink';
16
- import { useState, useEffect, useSyncExternalStore } from 'react';
16
+ import { useState, useEffect } from 'react';
17
17
  import { TextInput } from '@inkjs/ui';
18
- import { LoadingBox, PickerMenu } from '../primitives/index.js';
19
- import { Colors } from '../styles.js';
18
+ import { useWizardStore } from '../hooks/useWizardStore.js';
19
+ import { PickerMenu } from '../primitives/index.js';
20
+ import { Colors, Icons } from '../styles.js';
21
+ import { BrailleSpinner } from '../components/BrailleSpinner.js';
20
22
  import { DEFAULT_HOST_URL, } from '../../../lib/constants.js';
21
23
  import { analytics } from '../../../utils/analytics.js';
22
24
  /**
@@ -30,7 +32,7 @@ function getSelectableEnvironments(workspace) {
30
32
  .sort((a, b) => a.rank - b.rank);
31
33
  }
32
34
  export const AuthScreen = ({ store }) => {
33
- useSyncExternalStore((cb) => store.subscribe(cb), () => store.getSnapshot());
35
+ useWizardStore(store);
34
36
  const { session } = store;
35
37
  // Local step state — which org the user has selected in this render session
36
38
  const [selectedOrg, setSelectedOrg] = useState(null);
@@ -40,6 +42,18 @@ export const AuthScreen = ({ store }) => {
40
42
  const [apiKeyError, setApiKeyError] = useState('');
41
43
  const [savedKeySource, setSavedKeySource] = useState(null);
42
44
  const pendingOrgs = session.pendingOrgs;
45
+ // Validate pre-populated org/workspace IDs against live data.
46
+ // If the user's access changed (removed from org, switched accounts),
47
+ // stale IDs from ./ampli.json could silently select the wrong project.
48
+ useEffect(() => {
49
+ if (!pendingOrgs || pendingOrgs.length === 0)
50
+ return;
51
+ if (session.selectedOrgId &&
52
+ !pendingOrgs.some((o) => o.id === session.selectedOrgId)) {
53
+ // Stale org — clear pre-populated values so the picker shows
54
+ store.setOrgAndWorkspace({ id: '', name: '' }, { id: '', name: '' }, session.installDir);
55
+ }
56
+ }, [pendingOrgs]);
43
57
  // Resolve org: user-picked > single-org auto-select > pre-populated from session
44
58
  const prePopulatedOrg = session.selectedOrgId && pendingOrgs
45
59
  ? pendingOrgs.find((o) => o.id === session.selectedOrgId) ?? null
@@ -187,7 +201,7 @@ export const AuthScreen = ({ store }) => {
187
201
  const needsWorkspacePick = effectiveOrg !== null &&
188
202
  effectiveOrg.workspaces.length > 1 &&
189
203
  !selectedWorkspace;
190
- const needsProjectPick = workspaceChosen && hasMultipleEnvs && !selectedEnv;
204
+ const needsProjectPick = workspaceChosen && hasMultipleEnvs && !selectedEnv && !needsWorkspacePick;
191
205
  const needsApiKey = effectiveOrg !== null &&
192
206
  workspaceChosen &&
193
207
  envResolved &&
@@ -221,27 +235,43 @@ export const AuthScreen = ({ store }) => {
221
235
  setSavedKeySource(source);
222
236
  });
223
237
  };
224
- return (_jsxs(Box, { flexDirection: "column", flexGrow: 1, children: [_jsxs(Box, { flexDirection: "column", marginBottom: 1, children: [_jsx(Text, { bold: true, color: Colors.accent, children: "Amplitude Setup Wizard" }), session.detectedFrameworkLabel && (_jsxs(Text, { children: [_jsxs(Text, { color: "green", children: ['✔', " "] }), _jsxs(Text, { children: ["Framework: ", session.detectedFrameworkLabel] })] }))] }), pendingOrgs === null && (_jsxs(_Fragment, { children: [_jsx(LoadingBox, { message: "Waiting for authentication..." }), session.loginUrl && (_jsxs(Box, { marginTop: 1, flexDirection: "column", children: [_jsx(Text, { color: Colors.muted, children: "If the browser didn't open, copy and paste this URL:" }), _jsx(Text, { color: "cyan", children: session.loginUrl })] }))] })), needsOrgPick && pendingOrgs && (_jsxs(Box, { flexDirection: "column", children: [_jsx(Text, { color: Colors.muted, children: "Select your Amplitude organization:" }), _jsx(PickerMenu, { options: pendingOrgs.map((org) => ({
225
- label: org.name,
226
- value: org,
227
- })), onSelect: (value) => {
228
- const org = Array.isArray(value) ? value[0] : value;
229
- setSelectedOrg(org);
230
- } })] })), needsWorkspacePick && effectiveOrg && (_jsxs(Box, { flexDirection: "column", children: [_jsxs(Text, { color: Colors.muted, children: ["Select a workspace in ", _jsx(Text, { color: "white", children: effectiveOrg.name }), ":"] }), _jsx(PickerMenu, { options: effectiveOrg.workspaces.map((ws) => ({
231
- label: ws.name,
232
- value: ws,
233
- })), onSelect: (value) => {
234
- const ws = Array.isArray(value) ? value[0] : value;
235
- setSelectedWorkspace(ws);
236
- store.setOrgAndWorkspace(effectiveOrg, ws, session.installDir);
237
- } })] })), needsProjectPick && (_jsxs(Box, { flexDirection: "column", children: [_jsx(Text, { color: Colors.muted, children: "Select a project:" }), _jsx(PickerMenu, { options: selectableEnvs.map((env) => ({
238
- label: env.name,
239
- value: env,
240
- })), onSelect: (value) => {
241
- const env = Array.isArray(value) ? value[0] : value;
242
- setSelectedEnv(env);
243
- store.setSelectedProjectName(env.name);
244
- } })] })), needsApiKey && (_jsxs(Box, { flexDirection: "column", gap: 1, children: [_jsxs(Box, { flexDirection: "column", children: [_jsxs(Text, { children: ["Enter your Amplitude project ", _jsx(Text, { bold: true, children: "API Key" })] }), _jsx(Text, { color: Colors.muted, children: "Amplitude \u2192 Settings \u2192 Projects \u2192 [your project] \u2192 API Keys" }), session.apiKeyNotice && (_jsx(Text, { color: "yellow", children: session.apiKeyNotice }))] }), _jsx(TextInput, { placeholder: "Paste API key here\u2026", onSubmit: handleApiKeySubmit }), apiKeyError && _jsx(Text, { color: "red", children: apiKeyError }), savedKeySource && (_jsxs(Text, { color: "green", children: ['✔ ', savedKeySource === 'keychain'
238
+ // Completed-step indicators shown above the active step
239
+ const completedSteps = [];
240
+ if (session.detectedFrameworkLabel) {
241
+ completedSteps.push({
242
+ label: `Framework: ${session.detectedFrameworkLabel}`,
243
+ });
244
+ }
245
+ if (effectiveOrg && !needsOrgPick) {
246
+ completedSteps.push({ label: `Organization: ${effectiveOrg.name}` });
247
+ }
248
+ if (effectiveWorkspace && !needsWorkspacePick) {
249
+ completedSteps.push({ label: `Workspace: ${effectiveWorkspace.name}` });
250
+ }
251
+ if (selectedEnv && !needsProjectPick) {
252
+ completedSteps.push({ label: `Project: ${selectedEnv.name}` });
253
+ }
254
+ return (_jsxs(Box, { flexDirection: "column", flexGrow: 1, children: [completedSteps.length > 0 && (_jsx(Box, { flexDirection: "column", marginBottom: 1, children: completedSteps.map((step, i) => (_jsxs(Text, { children: [_jsxs(Text, { color: Colors.success, children: [Icons.checkmark, " "] }), _jsx(Text, { color: Colors.body, children: step.label })] }, i))) })), pendingOrgs === null && (_jsxs(Box, { flexDirection: "column", children: [_jsxs(Box, { gap: 1, children: [_jsx(BrailleSpinner, { color: Colors.accent }), _jsxs(Text, { color: Colors.body, children: ["Waiting for authentication", Icons.ellipsis] })] }), session.loginUrl && (_jsxs(Box, { marginTop: 1, flexDirection: "column", children: [_jsx(Text, { color: Colors.muted, children: "If the browser didn't open, copy and paste this URL:" }), _jsx(Text, { color: Colors.accent, children: session.loginUrl })] }))] })), needsOrgPick && pendingOrgs && (_jsxs(Box, { flexDirection: "column", children: [_jsx(Text, { bold: true, color: Colors.heading, children: "Select your organization" }), _jsx(Box, { marginTop: 1, children: _jsx(PickerMenu, { options: pendingOrgs.map((org) => ({
255
+ label: org.name,
256
+ value: org,
257
+ })), onSelect: (value) => {
258
+ const org = Array.isArray(value) ? value[0] : value;
259
+ setSelectedOrg(org);
260
+ } }) })] })), needsWorkspacePick && effectiveOrg && (_jsxs(Box, { flexDirection: "column", children: [_jsx(Text, { bold: true, color: Colors.heading, children: "Select a workspace" }), _jsxs(Text, { color: Colors.secondary, children: ["in ", _jsx(Text, { color: Colors.body, children: effectiveOrg.name })] }), _jsx(Box, { marginTop: 1, children: _jsx(PickerMenu, { options: effectiveOrg.workspaces.map((ws) => ({
261
+ label: ws.name,
262
+ value: ws,
263
+ })), onSelect: (value) => {
264
+ const ws = Array.isArray(value) ? value[0] : value;
265
+ setSelectedWorkspace(ws);
266
+ store.setOrgAndWorkspace(effectiveOrg, ws, session.installDir);
267
+ } }) })] })), needsProjectPick && (_jsxs(Box, { flexDirection: "column", children: [_jsx(Text, { bold: true, color: Colors.heading, children: "Select a project" }), _jsx(Box, { marginTop: 1, children: _jsx(PickerMenu, { options: selectableEnvs.map((env) => ({
268
+ label: env.name,
269
+ value: env,
270
+ })), onSelect: (value) => {
271
+ const env = Array.isArray(value) ? value[0] : value;
272
+ setSelectedEnv(env);
273
+ store.setSelectedProjectName(env.name);
274
+ } }) })] })), needsApiKey && (_jsxs(Box, { flexDirection: "column", gap: 1, children: [_jsxs(Box, { flexDirection: "column", children: [_jsx(Text, { bold: true, color: Colors.heading, children: "Enter your project API key" }), _jsxs(Text, { color: Colors.muted, children: ["Amplitude ", Icons.arrowRight, " Settings ", Icons.arrowRight, " Projects", ' ', Icons.arrowRight, " [your project] ", Icons.arrowRight, " API Keys"] }), session.apiKeyNotice && (_jsx(Box, { marginTop: 1, children: _jsx(Text, { color: Colors.warning, children: session.apiKeyNotice }) }))] }), _jsx(TextInput, { placeholder: "Paste API key here...", onSubmit: handleApiKeySubmit }), apiKeyError && _jsx(Text, { color: Colors.error, children: apiKeyError }), savedKeySource && (_jsxs(Text, { color: Colors.success, children: [Icons.checkmark, ' ', savedKeySource === 'keychain'
245
275
  ? 'API key saved to system keychain'
246
276
  : 'API key saved to .env.local'] }))] }))] }));
247
277
  };