@amplitude/wizard 1.0.0-beta.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 (333) hide show
  1. package/LICENSE +47 -0
  2. package/README.md +119 -0
  3. package/dist/bin.d.ts +2 -0
  4. package/dist/bin.js +763 -0
  5. package/dist/package.json +144 -0
  6. package/dist/src/frameworks/android/android-wizard-agent.d.ts +6 -0
  7. package/dist/src/frameworks/android/android-wizard-agent.js +72 -0
  8. package/dist/src/frameworks/android/utils.d.ts +11 -0
  9. package/dist/src/frameworks/android/utils.js +32 -0
  10. package/dist/src/frameworks/django/django-wizard-agent.d.ts +8 -0
  11. package/dist/src/frameworks/django/django-wizard-agent.js +171 -0
  12. package/dist/src/frameworks/django/utils.d.ts +31 -0
  13. package/dist/src/frameworks/django/utils.js +305 -0
  14. package/dist/src/frameworks/fastapi/fastapi-wizard-agent.d.ts +11 -0
  15. package/dist/src/frameworks/fastapi/fastapi-wizard-agent.js +189 -0
  16. package/dist/src/frameworks/fastapi/utils.d.ts +26 -0
  17. package/dist/src/frameworks/fastapi/utils.js +257 -0
  18. package/dist/src/frameworks/flask/flask-wizard-agent.d.ts +8 -0
  19. package/dist/src/frameworks/flask/flask-wizard-agent.js +177 -0
  20. package/dist/src/frameworks/flask/utils.d.ts +28 -0
  21. package/dist/src/frameworks/flask/utils.js +343 -0
  22. package/dist/src/frameworks/flutter/flutter-wizard-agent.d.ts +4 -0
  23. package/dist/src/frameworks/flutter/flutter-wizard-agent.js +57 -0
  24. package/dist/src/frameworks/flutter/utils.d.ts +7 -0
  25. package/dist/src/frameworks/flutter/utils.js +64 -0
  26. package/dist/src/frameworks/generic/generic-wizard-agent.d.ts +2 -0
  27. package/dist/src/frameworks/generic/generic-wizard-agent.js +176 -0
  28. package/dist/src/frameworks/go/go-wizard-agent.d.ts +4 -0
  29. package/dist/src/frameworks/go/go-wizard-agent.js +57 -0
  30. package/dist/src/frameworks/go/utils.d.ts +5 -0
  31. package/dist/src/frameworks/go/utils.js +44 -0
  32. package/dist/src/frameworks/java/java-wizard-agent.d.ts +7 -0
  33. package/dist/src/frameworks/java/java-wizard-agent.js +73 -0
  34. package/dist/src/frameworks/java/utils.d.ts +15 -0
  35. package/dist/src/frameworks/java/utils.js +64 -0
  36. package/dist/src/frameworks/javascript-node/javascript-node-wizard-agent.d.ts +4 -0
  37. package/dist/src/frameworks/javascript-node/javascript-node-wizard-agent.js +57 -0
  38. package/dist/src/frameworks/javascript-web/javascript-web-wizard-agent.d.ts +3 -0
  39. package/dist/src/frameworks/javascript-web/javascript-web-wizard-agent.js +151 -0
  40. package/dist/src/frameworks/javascript-web/utils.d.ts +28 -0
  41. package/dist/src/frameworks/javascript-web/utils.js +153 -0
  42. package/dist/src/frameworks/nextjs/nextjs-wizard-agent.d.ts +7 -0
  43. package/dist/src/frameworks/nextjs/nextjs-wizard-agent.js +98 -0
  44. package/dist/src/frameworks/nextjs/utils.d.ts +12 -0
  45. package/dist/src/frameworks/nextjs/utils.js +51 -0
  46. package/dist/src/frameworks/python/python-wizard-agent.d.ts +7 -0
  47. package/dist/src/frameworks/python/python-wizard-agent.js +193 -0
  48. package/dist/src/frameworks/python/utils.d.ts +28 -0
  49. package/dist/src/frameworks/python/utils.js +146 -0
  50. package/dist/src/frameworks/react-native/react-native-wizard-agent.d.ts +6 -0
  51. package/dist/src/frameworks/react-native/react-native-wizard-agent.js +84 -0
  52. package/dist/src/frameworks/react-native/utils.d.ts +21 -0
  53. package/dist/src/frameworks/react-native/utils.js +82 -0
  54. package/dist/src/frameworks/react-router/react-router-wizard-agent.d.ts +7 -0
  55. package/dist/src/frameworks/react-router/react-router-wizard-agent.js +98 -0
  56. package/dist/src/frameworks/react-router/utils.d.ts +13 -0
  57. package/dist/src/frameworks/react-router/utils.js +160 -0
  58. package/dist/src/frameworks/swift/swift-wizard-agent.d.ts +7 -0
  59. package/dist/src/frameworks/swift/swift-wizard-agent.js +72 -0
  60. package/dist/src/frameworks/swift/utils.d.ts +12 -0
  61. package/dist/src/frameworks/swift/utils.js +82 -0
  62. package/dist/src/frameworks/unity/unity-wizard-agent.d.ts +6 -0
  63. package/dist/src/frameworks/unity/unity-wizard-agent.js +79 -0
  64. package/dist/src/frameworks/unity/utils.d.ts +12 -0
  65. package/dist/src/frameworks/unity/utils.js +66 -0
  66. package/dist/src/frameworks/unreal/unreal-wizard-agent.d.ts +6 -0
  67. package/dist/src/frameworks/unreal/unreal-wizard-agent.js +77 -0
  68. package/dist/src/frameworks/unreal/utils.d.ts +10 -0
  69. package/dist/src/frameworks/unreal/utils.js +29 -0
  70. package/dist/src/frameworks/vue/vue-wizard-agent.d.ts +4 -0
  71. package/dist/src/frameworks/vue/vue-wizard-agent.js +64 -0
  72. package/dist/src/lib/agent-hooks.d.ts +26 -0
  73. package/dist/src/lib/agent-hooks.js +118 -0
  74. package/dist/src/lib/agent-interface.d.ts +175 -0
  75. package/dist/src/lib/agent-interface.js +1217 -0
  76. package/dist/src/lib/agent-runner.d.ts +9 -0
  77. package/dist/src/lib/agent-runner.js +415 -0
  78. package/dist/src/lib/ampli-config.d.ts +105 -0
  79. package/dist/src/lib/ampli-config.js +178 -0
  80. package/dist/src/lib/api.d.ts +107 -0
  81. package/dist/src/lib/api.js +442 -0
  82. package/dist/src/lib/commandments.d.ts +1 -0
  83. package/dist/src/lib/commandments.js +24 -0
  84. package/dist/src/lib/console-query.d.ts +27 -0
  85. package/dist/src/lib/console-query.js +121 -0
  86. package/dist/src/lib/constants.d.ts +124 -0
  87. package/dist/src/lib/constants.js +170 -0
  88. package/dist/src/lib/detect-amplitude.d.ts +31 -0
  89. package/dist/src/lib/detect-amplitude.js +407 -0
  90. package/dist/src/lib/framework-config.d.ts +188 -0
  91. package/dist/src/lib/framework-config.js +21 -0
  92. package/dist/src/lib/health-checks/endpoints.d.ts +3 -0
  93. package/dist/src/lib/health-checks/endpoints.js +45 -0
  94. package/dist/src/lib/health-checks/index.d.ts +4 -0
  95. package/dist/src/lib/health-checks/index.js +22 -0
  96. package/dist/src/lib/health-checks/readiness.d.ts +24 -0
  97. package/dist/src/lib/health-checks/readiness.js +118 -0
  98. package/dist/src/lib/health-checks/statuspage.d.ts +9 -0
  99. package/dist/src/lib/health-checks/statuspage.js +104 -0
  100. package/dist/src/lib/health-checks/types.d.ts +31 -0
  101. package/dist/src/lib/health-checks/types.js +9 -0
  102. package/dist/src/lib/helper-functions.d.ts +1 -0
  103. package/dist/src/lib/helper-functions.js +5 -0
  104. package/dist/src/lib/middleware/benchmark.d.ts +54 -0
  105. package/dist/src/lib/middleware/benchmark.js +48 -0
  106. package/dist/src/lib/middleware/benchmarks/cache-tracker.d.ts +44 -0
  107. package/dist/src/lib/middleware/benchmarks/cache-tracker.js +80 -0
  108. package/dist/src/lib/middleware/benchmarks/compaction-tracker.d.ts +29 -0
  109. package/dist/src/lib/middleware/benchmarks/compaction-tracker.js +59 -0
  110. package/dist/src/lib/middleware/benchmarks/context-size-tracker.d.ts +26 -0
  111. package/dist/src/lib/middleware/benchmarks/context-size-tracker.js +55 -0
  112. package/dist/src/lib/middleware/benchmarks/cost-tracker.d.ts +16 -0
  113. package/dist/src/lib/middleware/benchmarks/cost-tracker.js +75 -0
  114. package/dist/src/lib/middleware/benchmarks/duration-tracker.d.ts +20 -0
  115. package/dist/src/lib/middleware/benchmarks/duration-tracker.js +39 -0
  116. package/dist/src/lib/middleware/benchmarks/index.d.ts +9 -0
  117. package/dist/src/lib/middleware/benchmarks/index.js +67 -0
  118. package/dist/src/lib/middleware/benchmarks/json-writer.d.ts +15 -0
  119. package/dist/src/lib/middleware/benchmarks/json-writer.js +144 -0
  120. package/dist/src/lib/middleware/benchmarks/summary.d.ts +9 -0
  121. package/dist/src/lib/middleware/benchmarks/summary.js +105 -0
  122. package/dist/src/lib/middleware/benchmarks/token-tracker.d.ts +40 -0
  123. package/dist/src/lib/middleware/benchmarks/token-tracker.js +76 -0
  124. package/dist/src/lib/middleware/benchmarks/turn-counter.d.ts +34 -0
  125. package/dist/src/lib/middleware/benchmarks/turn-counter.js +58 -0
  126. package/dist/src/lib/middleware/config.d.ts +24 -0
  127. package/dist/src/lib/middleware/config.js +96 -0
  128. package/dist/src/lib/middleware/index.d.ts +11 -0
  129. package/dist/src/lib/middleware/index.js +17 -0
  130. package/dist/src/lib/middleware/phase-detector.d.ts +8 -0
  131. package/dist/src/lib/middleware/phase-detector.js +63 -0
  132. package/dist/src/lib/middleware/pipeline.d.ts +29 -0
  133. package/dist/src/lib/middleware/pipeline.js +81 -0
  134. package/dist/src/lib/middleware/schemas.d.ts +27 -0
  135. package/dist/src/lib/middleware/schemas.js +84 -0
  136. package/dist/src/lib/middleware/types.d.ts +94 -0
  137. package/dist/src/lib/middleware/types.js +8 -0
  138. package/dist/src/lib/package-manager-detection.d.ts +42 -0
  139. package/dist/src/lib/package-manager-detection.js +292 -0
  140. package/dist/src/lib/registry.d.ts +3 -0
  141. package/dist/src/lib/registry.js +42 -0
  142. package/dist/src/lib/safe-tools.d.ts +2 -0
  143. package/dist/src/lib/safe-tools.js +214 -0
  144. package/dist/src/lib/wizard-session.d.ts +220 -0
  145. package/dist/src/lib/wizard-session.js +127 -0
  146. package/dist/src/lib/wizard-tools.d.ts +82 -0
  147. package/dist/src/lib/wizard-tools.js +499 -0
  148. package/dist/src/run.d.ts +19 -0
  149. package/dist/src/run.js +151 -0
  150. package/dist/src/steps/add-mcp-server-to-clients/MCPClient.d.ts +30 -0
  151. package/dist/src/steps/add-mcp-server-to-clients/MCPClient.js +141 -0
  152. package/dist/src/steps/add-mcp-server-to-clients/clients/claude-code.d.ts +29 -0
  153. package/dist/src/steps/add-mcp-server-to-clients/clients/claude-code.js +180 -0
  154. package/dist/src/steps/add-mcp-server-to-clients/clients/claude.d.ts +20 -0
  155. package/dist/src/steps/add-mcp-server-to-clients/clients/claude.js +63 -0
  156. package/dist/src/steps/add-mcp-server-to-clients/clients/codex.d.ts +28 -0
  157. package/dist/src/steps/add-mcp-server-to-clients/clients/codex.js +77 -0
  158. package/dist/src/steps/add-mcp-server-to-clients/clients/cursor.d.ts +24 -0
  159. package/dist/src/steps/add-mcp-server-to-clients/clients/cursor.js +60 -0
  160. package/dist/src/steps/add-mcp-server-to-clients/clients/visual-studio-code.d.ts +27 -0
  161. package/dist/src/steps/add-mcp-server-to-clients/clients/visual-studio-code.js +101 -0
  162. package/dist/src/steps/add-mcp-server-to-clients/clients/zed.d.ts +26 -0
  163. package/dist/src/steps/add-mcp-server-to-clients/clients/zed.js +102 -0
  164. package/dist/src/steps/add-mcp-server-to-clients/defaults.d.ts +44 -0
  165. package/dist/src/steps/add-mcp-server-to-clients/defaults.js +123 -0
  166. package/dist/src/steps/add-mcp-server-to-clients/index.d.ts +19 -0
  167. package/dist/src/steps/add-mcp-server-to-clients/index.js +110 -0
  168. package/dist/src/steps/add-or-update-environment-variables.d.ts +10 -0
  169. package/dist/src/steps/add-or-update-environment-variables.js +188 -0
  170. package/dist/src/steps/index.d.ts +4 -0
  171. package/dist/src/steps/index.js +20 -0
  172. package/dist/src/steps/run-prettier.d.ts +5 -0
  173. package/dist/src/steps/run-prettier.js +90 -0
  174. package/dist/src/steps/upload-environment-variables/EnvironmentProvider.d.ts +11 -0
  175. package/dist/src/steps/upload-environment-variables/EnvironmentProvider.js +11 -0
  176. package/dist/src/steps/upload-environment-variables/index.d.ts +6 -0
  177. package/dist/src/steps/upload-environment-variables/index.js +37 -0
  178. package/dist/src/steps/upload-environment-variables/providers/vercel.d.ts +15 -0
  179. package/dist/src/steps/upload-environment-variables/providers/vercel.js +145 -0
  180. package/dist/src/telemetry.d.ts +2 -0
  181. package/dist/src/telemetry.js +12 -0
  182. package/dist/src/ui/index.d.ts +8 -0
  183. package/dist/src/ui/index.js +16 -0
  184. package/dist/src/ui/logging-ui.d.ts +56 -0
  185. package/dist/src/ui/logging-ui.js +157 -0
  186. package/dist/src/ui/tui/App.d.ts +6 -0
  187. package/dist/src/ui/tui/App.js +34 -0
  188. package/dist/src/ui/tui/components/AmplitudeLogo.d.ts +5 -0
  189. package/dist/src/ui/tui/components/AmplitudeLogo.js +81 -0
  190. package/dist/src/ui/tui/components/AmplitudeTextLogo.d.ts +3 -0
  191. package/dist/src/ui/tui/components/AmplitudeTextLogo.js +31 -0
  192. package/dist/src/ui/tui/components/ConsoleView.d.ts +23 -0
  193. package/dist/src/ui/tui/components/ConsoleView.js +220 -0
  194. package/dist/src/ui/tui/components/TitleBar.d.ts +6 -0
  195. package/dist/src/ui/tui/components/TitleBar.js +16 -0
  196. package/dist/src/ui/tui/console-commands.d.ts +16 -0
  197. package/dist/src/ui/tui/console-commands.js +31 -0
  198. package/dist/src/ui/tui/context/CommandModeContext.d.ts +2 -0
  199. package/dist/src/ui/tui/context/CommandModeContext.js +3 -0
  200. package/dist/src/ui/tui/flows.d.ts +48 -0
  201. package/dist/src/ui/tui/flows.js +154 -0
  202. package/dist/src/ui/tui/hooks/useScreenInput.d.ts +13 -0
  203. package/dist/src/ui/tui/hooks/useScreenInput.js +18 -0
  204. package/dist/src/ui/tui/hooks/useStdoutDimensions.d.ts +9 -0
  205. package/dist/src/ui/tui/hooks/useStdoutDimensions.js +29 -0
  206. package/dist/src/ui/tui/ink-ui.d.ts +62 -0
  207. package/dist/src/ui/tui/ink-ui.js +142 -0
  208. package/dist/src/ui/tui/primitives/CardLayout.d.ts +12 -0
  209. package/dist/src/ui/tui/primitives/CardLayout.js +9 -0
  210. package/dist/src/ui/tui/primitives/ConfirmationInput.d.ts +13 -0
  211. package/dist/src/ui/tui/primitives/ConfirmationInput.js +35 -0
  212. package/dist/src/ui/tui/primitives/DissolveTransition.d.ts +21 -0
  213. package/dist/src/ui/tui/primitives/DissolveTransition.js +143 -0
  214. package/dist/src/ui/tui/primitives/EventPlanViewer.d.ts +9 -0
  215. package/dist/src/ui/tui/primitives/EventPlanViewer.js +9 -0
  216. package/dist/src/ui/tui/primitives/KagiSmallWebViewer.d.ts +7 -0
  217. package/dist/src/ui/tui/primitives/KagiSmallWebViewer.js +101 -0
  218. package/dist/src/ui/tui/primitives/LoadingBox.d.ts +8 -0
  219. package/dist/src/ui/tui/primitives/LoadingBox.js +9 -0
  220. package/dist/src/ui/tui/primitives/LogViewer.d.ts +11 -0
  221. package/dist/src/ui/tui/primitives/LogViewer.js +55 -0
  222. package/dist/src/ui/tui/primitives/PickerMenu.d.ts +20 -0
  223. package/dist/src/ui/tui/primitives/PickerMenu.js +212 -0
  224. package/dist/src/ui/tui/primitives/ProgressList.d.ts +15 -0
  225. package/dist/src/ui/tui/primitives/ProgressList.js +29 -0
  226. package/dist/src/ui/tui/primitives/PromptLabel.d.ts +11 -0
  227. package/dist/src/ui/tui/primitives/PromptLabel.js +12 -0
  228. package/dist/src/ui/tui/primitives/ReportViewer.d.ts +12 -0
  229. package/dist/src/ui/tui/primitives/ReportViewer.js +99 -0
  230. package/dist/src/ui/tui/primitives/ScreenErrorBoundary.d.ts +26 -0
  231. package/dist/src/ui/tui/primitives/ScreenErrorBoundary.js +29 -0
  232. package/dist/src/ui/tui/primitives/SlashCommandInput.d.ts +21 -0
  233. package/dist/src/ui/tui/primitives/SlashCommandInput.js +85 -0
  234. package/dist/src/ui/tui/primitives/SnakeGame.d.ts +1 -0
  235. package/dist/src/ui/tui/primitives/SnakeGame.js +1 -0
  236. package/dist/src/ui/tui/primitives/SplitView.d.ts +11 -0
  237. package/dist/src/ui/tui/primitives/SplitView.js +8 -0
  238. package/dist/src/ui/tui/primitives/TabContainer.d.ts +18 -0
  239. package/dist/src/ui/tui/primitives/TabContainer.js +30 -0
  240. package/dist/src/ui/tui/primitives/index.d.ts +23 -0
  241. package/dist/src/ui/tui/primitives/index.js +19 -0
  242. package/dist/src/ui/tui/router.d.ts +61 -0
  243. package/dist/src/ui/tui/router.js +104 -0
  244. package/dist/src/ui/tui/screen-registry.d.ts +19 -0
  245. package/dist/src/ui/tui/screen-registry.js +56 -0
  246. package/dist/src/ui/tui/screens/ActivationOptionsScreen.d.ts +12 -0
  247. package/dist/src/ui/tui/screens/ActivationOptionsScreen.js +57 -0
  248. package/dist/src/ui/tui/screens/AuthScreen.d.ts +18 -0
  249. package/dist/src/ui/tui/screens/AuthScreen.js +107 -0
  250. package/dist/src/ui/tui/screens/ChecklistScreen.d.ts +22 -0
  251. package/dist/src/ui/tui/screens/ChecklistScreen.js +122 -0
  252. package/dist/src/ui/tui/screens/DataIngestionCheckScreen.d.ts +24 -0
  253. package/dist/src/ui/tui/screens/DataIngestionCheckScreen.js +113 -0
  254. package/dist/src/ui/tui/screens/DataSetupScreen.d.ts +17 -0
  255. package/dist/src/ui/tui/screens/DataSetupScreen.js +73 -0
  256. package/dist/src/ui/tui/screens/IntroScreen.d.ts +16 -0
  257. package/dist/src/ui/tui/screens/IntroScreen.js +86 -0
  258. package/dist/src/ui/tui/screens/LoginScreen.d.ts +15 -0
  259. package/dist/src/ui/tui/screens/LoginScreen.js +65 -0
  260. package/dist/src/ui/tui/screens/LogoutScreen.d.ts +12 -0
  261. package/dist/src/ui/tui/screens/LogoutScreen.js +28 -0
  262. package/dist/src/ui/tui/screens/McpScreen.d.ts +26 -0
  263. package/dist/src/ui/tui/screens/McpScreen.js +148 -0
  264. package/dist/src/ui/tui/screens/OutageScreen.d.ts +10 -0
  265. package/dist/src/ui/tui/screens/OutageScreen.js +17 -0
  266. package/dist/src/ui/tui/screens/OutroScreen.d.ts +11 -0
  267. package/dist/src/ui/tui/screens/OutroScreen.js +69 -0
  268. package/dist/src/ui/tui/screens/RegionSelectScreen.d.ts +17 -0
  269. package/dist/src/ui/tui/screens/RegionSelectScreen.js +40 -0
  270. package/dist/src/ui/tui/screens/RunScreen.d.ts +16 -0
  271. package/dist/src/ui/tui/screens/RunScreen.js +212 -0
  272. package/dist/src/ui/tui/screens/SettingsOverrideScreen.d.ts +10 -0
  273. package/dist/src/ui/tui/screens/SettingsOverrideScreen.js +23 -0
  274. package/dist/src/ui/tui/screens/SetupScreen.d.ts +13 -0
  275. package/dist/src/ui/tui/screens/SetupScreen.js +73 -0
  276. package/dist/src/ui/tui/screens/SlackScreen.d.ts +25 -0
  277. package/dist/src/ui/tui/screens/SlackScreen.js +97 -0
  278. package/dist/src/ui/tui/services/mcp-installer.d.ts +25 -0
  279. package/dist/src/ui/tui/services/mcp-installer.js +82 -0
  280. package/dist/src/ui/tui/start-tui.d.ts +10 -0
  281. package/dist/src/ui/tui/start-tui.js +50 -0
  282. package/dist/src/ui/tui/store.d.ts +231 -0
  283. package/dist/src/ui/tui/store.js +568 -0
  284. package/dist/src/ui/tui/styles.d.ts +31 -0
  285. package/dist/src/ui/tui/styles.js +33 -0
  286. package/dist/src/ui/wizard-ui.d.ts +110 -0
  287. package/dist/src/ui/wizard-ui.js +18 -0
  288. package/dist/src/utils/ampli-settings.d.ts +37 -0
  289. package/dist/src/utils/ampli-settings.js +182 -0
  290. package/dist/src/utils/analytics.d.ts +35 -0
  291. package/dist/src/utils/analytics.js +133 -0
  292. package/dist/src/utils/anthropic-status.d.ts +17 -0
  293. package/dist/src/utils/anthropic-status.js +51 -0
  294. package/dist/src/utils/api-key-store.d.ts +35 -0
  295. package/dist/src/utils/api-key-store.js +176 -0
  296. package/dist/src/utils/bash.d.ts +2 -0
  297. package/dist/src/utils/bash.js +53 -0
  298. package/dist/src/utils/custom-headers.d.ts +9 -0
  299. package/dist/src/utils/custom-headers.js +23 -0
  300. package/dist/src/utils/debug.d.ts +23 -0
  301. package/dist/src/utils/debug.js +86 -0
  302. package/dist/src/utils/environment.d.ts +4 -0
  303. package/dist/src/utils/environment.js +76 -0
  304. package/dist/src/utils/file-utils.d.ts +2 -0
  305. package/dist/src/utils/file-utils.js +16 -0
  306. package/dist/src/utils/get-api-key.d.ts +17 -0
  307. package/dist/src/utils/get-api-key.js +50 -0
  308. package/dist/src/utils/logging.d.ts +9 -0
  309. package/dist/src/utils/logging.js +48 -0
  310. package/dist/src/utils/oauth.d.ts +53 -0
  311. package/dist/src/utils/oauth.js +354 -0
  312. package/dist/src/utils/package-json.d.ts +25 -0
  313. package/dist/src/utils/package-json.js +26 -0
  314. package/dist/src/utils/package-manager.d.ts +21 -0
  315. package/dist/src/utils/package-manager.js +208 -0
  316. package/dist/src/utils/semver.d.ts +21 -0
  317. package/dist/src/utils/semver.js +61 -0
  318. package/dist/src/utils/setup-utils.d.ts +82 -0
  319. package/dist/src/utils/setup-utils.js +467 -0
  320. package/dist/src/utils/shell-completions.d.ts +10 -0
  321. package/dist/src/utils/shell-completions.js +199 -0
  322. package/dist/src/utils/string.d.ts +1 -0
  323. package/dist/src/utils/string.js +8 -0
  324. package/dist/src/utils/types.d.ts +72 -0
  325. package/dist/src/utils/types.js +2 -0
  326. package/dist/src/utils/urls.d.ts +14 -0
  327. package/dist/src/utils/urls.js +69 -0
  328. package/dist/src/utils/vendor/is-unicorn-supported.d.ts +1 -0
  329. package/dist/src/utils/vendor/is-unicorn-supported.js +23 -0
  330. package/dist/src/utils/wizard-abort.d.ts +13 -0
  331. package/dist/src/utils/wizard-abort.js +56 -0
  332. package/man/amplitude-wizard.1 +170 -0
  333. package/package.json +144 -0
@@ -0,0 +1,57 @@
1
+ import { jsxs as _jsxs, jsx as _jsx } from "react/jsx-runtime";
2
+ /**
3
+ * ActivationOptionsScreen — "What would you like to do?" prompt.
4
+ *
5
+ * Shown when the user has the SDK installed but hasn't fully activated yet
6
+ * (1–49 events). Offers next-step options without forcing a full re-run.
7
+ */
8
+ import { Box, Text } from 'ink';
9
+ import { useSyncExternalStore } from 'react';
10
+ import { PickerMenu } from '../primitives/index.js';
11
+ import { Colors } from '../styles.js';
12
+ import { OutroKind } from '../../../lib/wizard-session.js';
13
+ import { OUTBOUND_URLS } from '../../../lib/constants.js';
14
+ import opn from 'opn';
15
+ const DOCS_URL = OUTBOUND_URLS.sdkDocs;
16
+ export const ActivationOptionsScreen = ({ store, }) => {
17
+ useSyncExternalStore((cb) => store.subscribe(cb), () => store.getSnapshot());
18
+ const { snippetConfigured } = store.session;
19
+ const handleSelect = (value) => {
20
+ switch (value) {
21
+ case 'test-locally':
22
+ // Route to Framework Detection by treating this as a new project
23
+ store.setActivationOptionsComplete();
24
+ break;
25
+ case 'debug':
26
+ // Run the agent in debug mode
27
+ store.setActivationOptionsComplete();
28
+ break;
29
+ case 'docs':
30
+ opn(DOCS_URL, { wait: false }).catch(() => {
31
+ /* fire-and-forget */
32
+ });
33
+ // Stay on screen — don't advance
34
+ break;
35
+ case 'exit':
36
+ store.setOutroData({
37
+ kind: OutroKind.Cancel,
38
+ message: 'Come back once your app is deployed and sending events.',
39
+ });
40
+ break;
41
+ }
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: [
44
+ {
45
+ value: 'test-locally',
46
+ label: 'Help me test locally',
47
+ hint: 'run the setup agent',
48
+ },
49
+ { value: 'debug', label: "I'm blocked", hint: 'debug with Claude' },
50
+ { value: 'docs', label: 'Take me to the docs', hint: DOCS_URL },
51
+ {
52
+ value: 'exit',
53
+ label: "I'm done for now",
54
+ hint: 'exit and resume later',
55
+ },
56
+ ], onSelect: (v) => handleSelect(v) }) })] }));
57
+ };
@@ -0,0 +1,18 @@
1
+ /**
2
+ * AuthScreen — Multi-step authentication and account setup (SUSI flow).
3
+ *
4
+ * Steps:
5
+ * 1. OAuth waiting — spinner + login URL while browser auth happens
6
+ * 2. Org selection — picker if the user belongs to multiple orgs
7
+ * 3. Workspace selection — picker if the org has multiple workspaces
8
+ * 4. API key entry — text input for the Amplitude analytics write key
9
+ *
10
+ * The screen drives itself from session.pendingOrgs + session.credentials.
11
+ * When credentials are set the router resolves past this screen.
12
+ */
13
+ import type { WizardStore } from '../store.js';
14
+ interface AuthScreenProps {
15
+ store: WizardStore;
16
+ }
17
+ export declare const AuthScreen: ({ store }: AuthScreenProps) => import("react/jsx-runtime").JSX.Element;
18
+ export {};
@@ -0,0 +1,107 @@
1
+ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
2
+ /**
3
+ * AuthScreen — Multi-step authentication and account setup (SUSI flow).
4
+ *
5
+ * Steps:
6
+ * 1. OAuth waiting — spinner + login URL while browser auth happens
7
+ * 2. Org selection — picker if the user belongs to multiple orgs
8
+ * 3. Workspace selection — picker if the org has multiple workspaces
9
+ * 4. API key entry — text input for the Amplitude analytics write key
10
+ *
11
+ * The screen drives itself from session.pendingOrgs + session.credentials.
12
+ * When credentials are set the router resolves past this screen.
13
+ */
14
+ import { Box, Text } from 'ink';
15
+ import { useState, useEffect, useSyncExternalStore } from 'react';
16
+ import { TextInput } from '@inkjs/ui';
17
+ import { LoadingBox, PickerMenu } from '../primitives/index.js';
18
+ import { Colors } from '../styles.js';
19
+ import { DEFAULT_HOST_URL } from '../../../lib/constants.js';
20
+ import { analytics } from '../../../utils/analytics.js';
21
+ export const AuthScreen = ({ store }) => {
22
+ useSyncExternalStore((cb) => store.subscribe(cb), () => store.getSnapshot());
23
+ const { session } = store;
24
+ // Local step state — which org the user has selected in this render session
25
+ const [selectedOrg, setSelectedOrg] = useState(null);
26
+ const [apiKeyError, setApiKeyError] = useState('');
27
+ const [savedKeySource, setSavedKeySource] = useState(null);
28
+ const pendingOrgs = session.pendingOrgs;
29
+ // Auto-select the org when there's only one
30
+ const effectiveOrg = selectedOrg ?? (pendingOrgs?.length === 1 ? pendingOrgs[0] : null);
31
+ // Auto-select workspace when org has only one
32
+ const singleWorkspace = effectiveOrg?.workspaces.length === 1 ? effectiveOrg.workspaces[0] : null;
33
+ useEffect(() => {
34
+ if (effectiveOrg && singleWorkspace && !session.selectedWorkspaceId) {
35
+ store.setOrgAndWorkspace(effectiveOrg, singleWorkspace, session.installDir);
36
+ }
37
+ }, [effectiveOrg?.id, singleWorkspace?.id, session.selectedWorkspaceId]);
38
+ const workspaceChosen = session.selectedWorkspaceId !== null ||
39
+ (effectiveOrg !== null && effectiveOrg.workspaces.length === 1);
40
+ // Auto-advance past API key step if a saved key exists for this project
41
+ useEffect(() => {
42
+ if (!workspaceChosen || session.credentials !== null)
43
+ return;
44
+ void import('../../../utils/api-key-store.js').then(({ readApiKeyWithSource }) => {
45
+ const result = readApiKeyWithSource(session.installDir);
46
+ if (result) {
47
+ setSavedKeySource(result.source);
48
+ analytics.wizardCapture('api key submitted', {
49
+ key_source: result.source,
50
+ });
51
+ store.setCredentials({
52
+ accessToken: session.pendingAuthAccessToken ?? '',
53
+ idToken: session.pendingAuthIdToken ?? undefined,
54
+ projectApiKey: result.key,
55
+ host: DEFAULT_HOST_URL,
56
+ projectId: 0,
57
+ });
58
+ store.setProjectHasData(false);
59
+ }
60
+ });
61
+ }, [workspaceChosen, session.credentials]);
62
+ const needsOrgPick = pendingOrgs !== null && pendingOrgs.length > 1 && effectiveOrg === null;
63
+ const needsWorkspacePick = effectiveOrg !== null &&
64
+ effectiveOrg.workspaces.length > 1 &&
65
+ !session.selectedWorkspaceId;
66
+ const needsApiKey = effectiveOrg !== null && workspaceChosen && session.credentials === null;
67
+ const handleApiKeySubmit = (value) => {
68
+ const trimmed = value.trim();
69
+ if (!trimmed) {
70
+ setApiKeyError('API key cannot be empty');
71
+ return;
72
+ }
73
+ setApiKeyError('');
74
+ analytics.wizardCapture('api key submitted', {
75
+ key_source: 'manual_entry',
76
+ });
77
+ store.setCredentials({
78
+ accessToken: session.pendingAuthAccessToken ?? '',
79
+ idToken: session.pendingAuthIdToken ?? undefined,
80
+ projectApiKey: trimmed,
81
+ host: DEFAULT_HOST_URL,
82
+ projectId: 0,
83
+ });
84
+ // Fresh project: no existing event data — advance past DataSetup
85
+ store.setProjectHasData(false);
86
+ // Persist so the user doesn't have to enter it again
87
+ void import('../../../utils/api-key-store.js').then(({ persistApiKey }) => {
88
+ const source = persistApiKey(trimmed, session.installDir);
89
+ setSavedKeySource(source);
90
+ });
91
+ };
92
+ 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) => ({
93
+ label: org.name,
94
+ value: org,
95
+ })), onSelect: (value) => {
96
+ const org = Array.isArray(value) ? value[0] : value;
97
+ setSelectedOrg(org);
98
+ } })] })), 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) => ({
99
+ label: ws.name,
100
+ value: ws,
101
+ })), onSelect: (value) => {
102
+ const ws = Array.isArray(value) ? value[0] : value;
103
+ store.setOrgAndWorkspace(effectiveOrg, ws, session.installDir);
104
+ } })] })), 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'
105
+ ? 'API key saved to system keychain'
106
+ : 'API key saved to .env.local'] }))] }))] }));
107
+ };
@@ -0,0 +1,22 @@
1
+ /**
2
+ * ChecklistScreen — Post-setup checklist for first chart and first dashboard.
3
+ *
4
+ * Shown after DataIngestionCheckScreen confirms events are flowing.
5
+ *
6
+ * Items:
7
+ * [ ] Taxonomy agent — @todo (in progress in parallel work)
8
+ * [ ] First chart — opens Amplitude in browser; marks complete on return
9
+ * [ ] First dashboard — unlocked after chart; opens Amplitude in browser
10
+ *
11
+ * The user can "Continue" at any time to skip remaining items and advance
12
+ * to Slack setup.
13
+ *
14
+ * Chart/dashboard creation via direct GraphQL API call is planned as a
15
+ * follow-up; for now the action opens the Amplitude web UI.
16
+ */
17
+ import type { WizardStore } from '../store.js';
18
+ interface ChecklistScreenProps {
19
+ store: WizardStore;
20
+ }
21
+ export declare const ChecklistScreen: ({ store }: ChecklistScreenProps) => import("react/jsx-runtime").JSX.Element;
22
+ export {};
@@ -0,0 +1,122 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ /**
3
+ * ChecklistScreen — Post-setup checklist for first chart and first dashboard.
4
+ *
5
+ * Shown after DataIngestionCheckScreen confirms events are flowing.
6
+ *
7
+ * Items:
8
+ * [ ] Taxonomy agent — @todo (in progress in parallel work)
9
+ * [ ] First chart — opens Amplitude in browser; marks complete on return
10
+ * [ ] First dashboard — unlocked after chart; opens Amplitude in browser
11
+ *
12
+ * The user can "Continue" at any time to skip remaining items and advance
13
+ * to Slack setup.
14
+ *
15
+ * Chart/dashboard creation via direct GraphQL API call is planned as a
16
+ * follow-up; for now the action opens the Amplitude web UI.
17
+ */
18
+ import { Box, Text } from 'ink';
19
+ import { useEffect, useState, useSyncExternalStore } from 'react';
20
+ import { PickerMenu } from '../primitives/index.js';
21
+ import { Colors, Icons } from '../styles.js';
22
+ import { OUTBOUND_URLS } from '../../../lib/constants.js';
23
+ import opn from 'opn';
24
+ import { analytics } from '../../../utils/analytics.js';
25
+ import { fetchOwnedDashboards } from '../../../lib/api.js';
26
+ export const ChecklistScreen = ({ store }) => {
27
+ useSyncExternalStore((cb) => store.subscribe(cb), () => store.getSnapshot());
28
+ const { session } = store;
29
+ const { checklistChartComplete, checklistDashboardComplete, region, selectedOrgId, } = session;
30
+ const [opening, setOpening] = useState(null);
31
+ const zone = (region ?? 'us');
32
+ // On mount, detect any charts/dashboards the user already owns in their org
33
+ // so a returning user sees the correct state without re-doing completed steps.
34
+ // Detection is org-scoped (Thunder has no project-level listing API); for a
35
+ // new-project user this is equivalent.
36
+ useEffect(() => {
37
+ const { credentials, selectedOrgId, checklistChartComplete, checklistDashboardComplete, } = store.session;
38
+ if (!credentials || !selectedOrgId)
39
+ return;
40
+ if (checklistChartComplete && checklistDashboardComplete)
41
+ return;
42
+ const idToken = credentials.idToken ?? credentials.accessToken;
43
+ const sessionZone = (store.session.region ?? 'us');
44
+ fetchOwnedDashboards(idToken, sessionZone, selectedOrgId)
45
+ .then(({ hasCharts, hasDashboards }) => {
46
+ if (hasCharts)
47
+ store.setChecklistChartComplete();
48
+ if (hasDashboards)
49
+ store.setChecklistDashboardComplete();
50
+ })
51
+ .catch(() => {
52
+ // fetchOwnedDashboards never rejects — handled defensively
53
+ });
54
+ }, []);
55
+ const chartUrl = OUTBOUND_URLS.newChart(zone, selectedOrgId);
56
+ const dashboardUrl = OUTBOUND_URLS.newDashboard(zone, selectedOrgId);
57
+ function openInBrowser(url, item) {
58
+ setOpening(item);
59
+ analytics.wizardCapture('checklist item opened', { item });
60
+ opn(url, { wait: false })
61
+ .catch(() => {
62
+ /* fire-and-forget */
63
+ })
64
+ .finally(() => {
65
+ setOpening(null);
66
+ if (item === 'chart')
67
+ store.setChecklistChartComplete();
68
+ if (item === 'dashboard')
69
+ store.setChecklistDashboardComplete();
70
+ });
71
+ }
72
+ function handleSelect(value) {
73
+ switch (value) {
74
+ case 'chart':
75
+ openInBrowser(chartUrl, 'chart');
76
+ break;
77
+ case 'dashboard':
78
+ openInBrowser(dashboardUrl, 'dashboard');
79
+ break;
80
+ case 'continue':
81
+ store.setChecklistComplete();
82
+ break;
83
+ }
84
+ }
85
+ const allDone = checklistChartComplete && checklistDashboardComplete;
86
+ const options = [
87
+ {
88
+ value: 'chart',
89
+ label: checklistChartComplete
90
+ ? `${Icons.check} First chart — done`
91
+ : `${Icons.squareOpen} Create your first chart`,
92
+ hint: checklistChartComplete ? undefined : 'opens in browser',
93
+ disabled: checklistChartComplete,
94
+ },
95
+ {
96
+ value: 'dashboard',
97
+ label: checklistDashboardComplete
98
+ ? `${Icons.check} First dashboard — done`
99
+ : checklistChartComplete
100
+ ? `${Icons.squareOpen} Create your first dashboard`
101
+ : `${Icons.squareOpen} Create your first dashboard`,
102
+ hint: checklistDashboardComplete
103
+ ? undefined
104
+ : checklistChartComplete
105
+ ? 'opens in browser'
106
+ : 'create a chart first',
107
+ disabled: checklistDashboardComplete || !checklistChartComplete,
108
+ },
109
+ {
110
+ value: 'taxonomy',
111
+ label: `${Icons.squareOpen} Set up taxonomy`,
112
+ hint: 'coming soon',
113
+ disabled: true,
114
+ },
115
+ {
116
+ value: 'continue',
117
+ label: allDone ? 'Done — continue' : 'Skip remaining and continue',
118
+ hint: allDone ? undefined : 'you can always do these in Amplitude later',
119
+ },
120
+ ];
121
+ return (_jsxs(Box, { flexDirection: "column", flexGrow: 1, paddingX: 2, paddingY: 1, children: [_jsx(Box, { marginBottom: 1, children: _jsx(Text, { bold: true, color: Colors.accent, children: "Set up your analytics" }) }), _jsxs(Box, { flexDirection: "column", gap: 1, marginBottom: 2, children: [_jsx(Text, { children: "Your events are flowing. Now let's build some views of your data." }), opening && (_jsx(Text, { color: Colors.muted, children: "Opening Amplitude in your browser..." }))] }), _jsx(PickerMenu, { options: options, onSelect: (v) => handleSelect(v) })] }));
122
+ };
@@ -0,0 +1,24 @@
1
+ /**
2
+ * DataIngestionCheckScreen — "Waiting for your events..." polling screen.
3
+ *
4
+ * Shown after MCP setup. Polls the activation API every 30 seconds until the
5
+ * project starts receiving events, then auto-advances to the Checklist.
6
+ *
7
+ * For users who were already fully activated (activationLevel === 'full') when
8
+ * the wizard started, this screen confirms immediately on mount without polling.
9
+ *
10
+ * The user can exit and come back later — next time through, DataSetupScreen
11
+ * will re-check activation and this screen will confirm immediately if events
12
+ * have arrived.
13
+ *
14
+ * When the activation API is unavailable (e.g. external users hitting Thunder
15
+ * endpoints that require browser session auth), the screen falls back to showing
16
+ * cataloged event types from the data API so the user can verify events arrived,
17
+ * then manually confirms with Enter.
18
+ */
19
+ import type { WizardStore } from '../store.js';
20
+ interface DataIngestionCheckScreenProps {
21
+ store: WizardStore;
22
+ }
23
+ export declare const DataIngestionCheckScreen: ({ store, }: DataIngestionCheckScreenProps) => import("react/jsx-runtime").JSX.Element;
24
+ export {};
@@ -0,0 +1,113 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ /**
3
+ * DataIngestionCheckScreen — "Waiting for your events..." polling screen.
4
+ *
5
+ * Shown after MCP setup. Polls the activation API every 30 seconds until the
6
+ * project starts receiving events, then auto-advances to the Checklist.
7
+ *
8
+ * For users who were already fully activated (activationLevel === 'full') when
9
+ * the wizard started, this screen confirms immediately on mount without polling.
10
+ *
11
+ * The user can exit and come back later — next time through, DataSetupScreen
12
+ * will re-check activation and this screen will confirm immediately if events
13
+ * have arrived.
14
+ *
15
+ * When the activation API is unavailable (e.g. external users hitting Thunder
16
+ * endpoints that require browser session auth), the screen falls back to showing
17
+ * cataloged event types from the data API so the user can verify events arrived,
18
+ * then manually confirms with Enter.
19
+ */
20
+ import { Box, Text } from 'ink';
21
+ import { useEffect, useRef, useState, useSyncExternalStore } from 'react';
22
+ import { Colors, Icons } from '../styles.js';
23
+ import { fetchProjectActivationStatus, fetchWorkspaceEventTypes, } from '../../../lib/api.js';
24
+ import { logToFile } from '../../../utils/debug.js';
25
+ import { OutroKind } from '../../../lib/wizard-session.js';
26
+ import { useScreenInput } from '../hooks/useScreenInput.js';
27
+ const POLL_INTERVAL_MS = 30_000;
28
+ const MAX_EVENTS_SHOWN = 8;
29
+ export const DataIngestionCheckScreen = ({ store, }) => {
30
+ useSyncExternalStore((cb) => store.subscribe(cb), () => store.getSnapshot());
31
+ const { session } = store;
32
+ const { credentials, region, activationLevel } = session;
33
+ const pollingRef = useRef(null);
34
+ const [apiUnavailable, setApiUnavailable] = useState(false);
35
+ const [eventTypes, setEventTypes] = useState(null);
36
+ async function checkIngestion() {
37
+ if (!credentials) {
38
+ setApiUnavailable(true);
39
+ return;
40
+ }
41
+ // credentials.projectId is 0 for OAuth users; fall back to workspace UUID
42
+ const appId = credentials.projectId || session.selectedWorkspaceId;
43
+ if (!appId) {
44
+ setApiUnavailable(true);
45
+ return;
46
+ }
47
+ const zone = (region ?? 'us');
48
+ try {
49
+ const status = await fetchProjectActivationStatus(credentials.idToken ?? credentials.accessToken, zone, appId, session.selectedOrgId);
50
+ logToFile(`[DataIngestionCheck] poll result: hasAnyEvents=${status.hasAnyEvents} hasDetSource=${status.hasDetSource}`);
51
+ if (status.hasAnyEvents) {
52
+ store.setDataIngestionConfirmed();
53
+ }
54
+ }
55
+ catch (err) {
56
+ logToFile(`[DataIngestionCheck] poll error: ${err instanceof Error ? err.message : String(err)}`);
57
+ setApiUnavailable(true);
58
+ // Fetch cataloged event types from the data API as a proxy for "events arrived"
59
+ if (session.selectedOrgId && session.selectedWorkspaceId) {
60
+ const idToken = credentials.idToken ?? credentials.accessToken;
61
+ fetchWorkspaceEventTypes(idToken, zone, session.selectedOrgId, session.selectedWorkspaceId)
62
+ .then((names) => {
63
+ setEventTypes(names);
64
+ })
65
+ .catch(() => {
66
+ setEventTypes([]);
67
+ });
68
+ }
69
+ else {
70
+ setEventTypes([]);
71
+ }
72
+ }
73
+ }
74
+ useEffect(() => {
75
+ // Already fully activated — confirm immediately and skip polling
76
+ if (activationLevel === 'full') {
77
+ store.setDataIngestionConfirmed();
78
+ return;
79
+ }
80
+ // Run once immediately, then set up the interval
81
+ void checkIngestion();
82
+ pollingRef.current = setInterval(() => {
83
+ void checkIngestion();
84
+ }, POLL_INTERVAL_MS);
85
+ return () => {
86
+ if (pollingRef.current !== null) {
87
+ clearInterval(pollingRef.current);
88
+ }
89
+ };
90
+ }, []);
91
+ useScreenInput((_char, key) => {
92
+ if (key.escape || _char === 'q') {
93
+ if (pollingRef.current !== null)
94
+ clearInterval(pollingRef.current);
95
+ store.setOutroData({
96
+ kind: OutroKind.Cancel,
97
+ message: 'Come back once your app is running and sending events. Your SDK is installed — you just need to trigger some actions.',
98
+ });
99
+ return;
100
+ }
101
+ // Manual confirmation when API is unavailable
102
+ if (apiUnavailable && key.return) {
103
+ if (pollingRef.current !== null)
104
+ clearInterval(pollingRef.current);
105
+ store.setDataIngestionConfirmed();
106
+ }
107
+ });
108
+ const shown = eventTypes?.slice(0, MAX_EVENTS_SHOWN) ?? [];
109
+ const overflow = (eventTypes?.length ?? 0) - MAX_EVENTS_SHOWN;
110
+ return (_jsxs(Box, { flexDirection: "column", flexGrow: 1, paddingX: 2, paddingY: 1, children: [_jsx(Box, { marginBottom: 1, children: _jsx(Text, { bold: true, color: Colors.accent, children: "Waiting for your events" }) }), _jsxs(Box, { flexDirection: "column", gap: 1, marginBottom: 2, children: [_jsx(Text, { children: "Your SDK is installed. Once you run your app and trigger some actions, events will start flowing into Amplitude." }), !apiUnavailable && (_jsx(Text, { color: Colors.muted, children: "Checking every 30 seconds \u2014 this screen will advance automatically." }))] }), apiUnavailable && eventTypes === null && (_jsxs(Box, { gap: 2, alignItems: "center", children: [_jsx(Text, { color: Colors.accent, children: Icons.diamond }), _jsx(Text, { color: Colors.muted, children: "Checking your event catalog..." })] })), apiUnavailable && eventTypes !== null && eventTypes.length > 0 && (_jsxs(Box, { flexDirection: "column", marginBottom: 1, children: [_jsx(Text, { color: Colors.muted, dimColor: true, children: "Events cataloged in your workspace:" }), _jsxs(Box, { flexDirection: "column", marginTop: 1, marginLeft: 2, children: [shown.map((name) => (_jsxs(Box, { gap: 2, children: [_jsx(Text, { color: Colors.accent, children: Icons.diamond }), _jsx(Text, { children: name })] }, name))), overflow > 0 && (_jsxs(Text, { color: Colors.muted, dimColor: true, children: ["... and ", overflow, " more"] }))] })] })), apiUnavailable && eventTypes !== null && eventTypes.length === 0 && (_jsxs(Box, { gap: 2, alignItems: "center", marginBottom: 1, children: [_jsx(Text, { color: Colors.accent, children: Icons.diamond }), _jsx(Text, { color: Colors.muted, children: "Waiting for your events..." })] })), !apiUnavailable && (_jsxs(Box, { gap: 2, alignItems: "center", children: [_jsx(Text, { color: Colors.accent, children: Icons.diamond }), _jsx(Text, { color: Colors.muted, children: "Waiting for your events..." })] })), _jsxs(Box, { marginTop: 2, flexDirection: "column", gap: 1, children: [apiUnavailable && (_jsxs(Text, { color: Colors.muted, dimColor: true, children: ["Press", ' ', _jsx(Text, { bold: true, color: Colors.muted, children: "Enter" }), ' ', eventTypes && eventTypes.length > 0
111
+ ? 'to continue'
112
+ : 'once you see events in your Amplitude dashboard'] })), _jsxs(Text, { color: Colors.muted, dimColor: true, children: ["Press", ' ', _jsx(Text, { bold: true, color: Colors.muted, children: "q" }), ' ', "or", ' ', _jsx(Text, { bold: true, color: Colors.muted, children: "Esc" }), ' ', "to exit and resume later"] })] })] }));
113
+ };
@@ -0,0 +1,17 @@
1
+ /**
2
+ * DataSetupScreen — Checks whether the connected Amplitude project has event data.
3
+ *
4
+ * Calls the Amplitude Data API to determine the project's activation level:
5
+ * 'full' — 50+ events / well-established data → Options menu
6
+ * 'partial' — snippet installed but few events → ActivationOptions screen
7
+ * 'none' — no events, no snippet → Framework Detection
8
+ *
9
+ * The router's isComplete predicate (projectHasData !== null) advances past
10
+ * this screen automatically once the value is set.
11
+ */
12
+ import type { WizardStore } from '../store.js';
13
+ interface DataSetupScreenProps {
14
+ store: WizardStore;
15
+ }
16
+ export declare const DataSetupScreen: ({ store }: DataSetupScreenProps) => import("react/jsx-runtime").JSX.Element;
17
+ export {};
@@ -0,0 +1,73 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ /**
3
+ * DataSetupScreen — Checks whether the connected Amplitude project has event data.
4
+ *
5
+ * Calls the Amplitude Data API to determine the project's activation level:
6
+ * 'full' — 50+ events / well-established data → Options menu
7
+ * 'partial' — snippet installed but few events → ActivationOptions screen
8
+ * 'none' — no events, no snippet → Framework Detection
9
+ *
10
+ * The router's isComplete predicate (projectHasData !== null) advances past
11
+ * this screen automatically once the value is set.
12
+ */
13
+ import { Box } from 'ink';
14
+ import { useEffect, useSyncExternalStore } from 'react';
15
+ import { LoadingBox } from '../primitives/index.js';
16
+ import { fetchProjectActivationStatus } from '../../../lib/api.js';
17
+ import { detectAmplitudeInProject } from '../../../lib/detect-amplitude.js';
18
+ import { logToFile } from '../../../utils/debug.js';
19
+ export const DataSetupScreen = ({ store }) => {
20
+ useSyncExternalStore((cb) => store.subscribe(cb), () => store.getSnapshot());
21
+ useEffect(() => {
22
+ if (store.session.projectHasData !== null)
23
+ return;
24
+ const { credentials, region, selectedOrgId, selectedWorkspaceId } = store.session;
25
+ // credentials.projectId is 0 for OAuth users; fall back to the workspace UUID
26
+ const appId = store.session.credentials?.projectId || selectedWorkspaceId || null;
27
+ // No credentials or project ID — can't check, fall through to Framework Detection
28
+ if (!credentials || !appId || !selectedOrgId) {
29
+ logToFile('[DataSetup] no credentials/appId — skipping activation check');
30
+ store.setActivationLevel('none');
31
+ return;
32
+ }
33
+ const zone = (region ?? 'us');
34
+ logToFile(`[DataSetup] checking activation for appId=${appId} zone=${zone}`);
35
+ // Run local static check in parallel with the API call.
36
+ const localDetection = detectAmplitudeInProject(store.session.installDir);
37
+ logToFile(`[DataSetup] local detection: confidence=${localDetection.confidence} reason=${localDetection.reason ?? 'none'}`);
38
+ void fetchProjectActivationStatus(credentials.idToken ?? credentials.accessToken, zone, appId, selectedOrgId)
39
+ .then((status) => {
40
+ logToFile(`[DataSetup] activation status: ${JSON.stringify(status)}`);
41
+ store.setSnippetConfigured(status.hasDetSource);
42
+ if (status.hasAnyEvents && status.hasDetSource) {
43
+ // Has both SDK and events — use a heuristic: if all three core event types
44
+ // are present, call it full.
45
+ const isFull = status.hasPageViewedEvent &&
46
+ status.hasSessionStartEvent &&
47
+ status.hasSessionEndEvent;
48
+ store.setActivationLevel(isFull ? 'full' : 'partial');
49
+ }
50
+ else if (status.hasDetSource) {
51
+ // SDK installed but no events yet
52
+ store.setActivationLevel('partial');
53
+ }
54
+ else if (localDetection.confidence !== 'none') {
55
+ // API sees no SDK, but local files suggest Amplitude is already installed.
56
+ // Treat as partial so the wizard asks what they need rather than running
57
+ // the full install agent.
58
+ logToFile(`[DataSetup] upgrading to partial via local detection: ${localDetection.reason}`);
59
+ store.setActivationLevel('partial');
60
+ }
61
+ else {
62
+ // No SDK, no events, no local evidence — full install needed
63
+ store.setActivationLevel('none');
64
+ }
65
+ })
66
+ .catch((err) => {
67
+ logToFile(`[DataSetup] activation check failed: ${err instanceof Error ? err.message : String(err)} — falling back to local detection`);
68
+ // If the API fails, use local detection as a fallback.
69
+ store.setActivationLevel(localDetection.confidence !== 'none' ? 'partial' : 'none');
70
+ });
71
+ }, []);
72
+ return (_jsx(Box, { flexDirection: "column", flexGrow: 1, children: _jsx(LoadingBox, { message: "Checking project setup\u2026" }) }));
73
+ };
@@ -0,0 +1,16 @@
1
+ /**
2
+ * IntroScreen — Welcome, framework detection, and continue/cancel prompt.
3
+ *
4
+ * Three states:
5
+ * 1. Detecting: spinner while bin.ts runs detection
6
+ * 2. Detection failed: auto-selects Generic, then continue/cancel
7
+ * 3. Detection succeeded: show result, then continue/cancel
8
+ *
9
+ * Calls store.completeSetup() which unblocks bin.ts to start runWizard.
10
+ */
11
+ import type { WizardStore } from '../store.js';
12
+ interface IntroScreenProps {
13
+ store: WizardStore;
14
+ }
15
+ export declare const IntroScreen: ({ store }: IntroScreenProps) => import("react/jsx-runtime").JSX.Element;
16
+ export {};