@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,61 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.fulfillsVersionRange = fulfillsVersionRange;
4
+ exports.createVersionBucket = createVersionBucket;
5
+ const semver_1 = require("semver");
6
+ function fulfillsVersionRange({ version, acceptableVersions, canBeLatest, }) {
7
+ if (version === 'latest') {
8
+ return canBeLatest;
9
+ }
10
+ let cleanedUserVersion, isRange;
11
+ if ((0, semver_1.valid)(version)) {
12
+ cleanedUserVersion = (0, semver_1.valid)(version);
13
+ isRange = false;
14
+ }
15
+ else if ((0, semver_1.validRange)(version)) {
16
+ cleanedUserVersion = (0, semver_1.validRange)(version);
17
+ isRange = true;
18
+ }
19
+ return (
20
+ // If the given version is a bogus format, this will still be undefined and we'll automatically reject it
21
+ !!cleanedUserVersion &&
22
+ (isRange
23
+ ? (0, semver_1.subset)(cleanedUserVersion, acceptableVersions)
24
+ : (0, semver_1.satisfies)(cleanedUserVersion, acceptableVersions)));
25
+ }
26
+ /**
27
+ * Creates a version bucket function for analytics.
28
+ * Converts versions like "1.2.3" to "1.x" for grouping in analytics.
29
+ *
30
+ * @param minMajorVersion - Optional minimum major version threshold.
31
+ * Versions below this will be bucketed as "<{min}.0.0"
32
+ *
33
+ * @example
34
+ * const getVersionBucket = createVersionBucket(); // no minimum
35
+ * getVersionBucket("1.2.3") // "1.x"
36
+ *
37
+ * const getVersionBucket = createVersionBucket(11);
38
+ * getVersionBucket("15.3.0") // "15.x"
39
+ * getVersionBucket("10.0.0") // "<11.0.0"
40
+ */
41
+ function createVersionBucket(minMajorVersion) {
42
+ return (version) => {
43
+ if (!version) {
44
+ return 'none';
45
+ }
46
+ try {
47
+ const minVer = (0, semver_1.minVersion)(version);
48
+ if (!minVer) {
49
+ return 'invalid';
50
+ }
51
+ const majorVersion = (0, semver_1.major)(minVer);
52
+ if (minMajorVersion !== undefined && majorVersion < minMajorVersion) {
53
+ return `<${minMajorVersion}.0.0`;
54
+ }
55
+ return `${majorVersion}.x`;
56
+ }
57
+ catch {
58
+ return 'unknown';
59
+ }
60
+ };
61
+ }
@@ -0,0 +1,82 @@
1
+ import type { PackageDotJson } from './package-json';
2
+ import { type PackageManager } from './package-manager';
3
+ import type { CloudRegion, WizardOptions } from './types';
4
+ export interface CliSetupConfig {
5
+ filename: string;
6
+ name: string;
7
+ gitignore: boolean;
8
+ likelyAlreadyHasAuthToken(contents: string): boolean;
9
+ tokenContent(authToken: string): string;
10
+ likelyAlreadyHasOrgAndProject(contents: string): boolean;
11
+ orgAndProjContent(org: string, project: string): string;
12
+ likelyAlreadyHasUrl?(contents: string): boolean;
13
+ urlContent?(url: string): string;
14
+ }
15
+ export interface CliSetupConfigContent {
16
+ authToken: string;
17
+ org?: string;
18
+ project?: string;
19
+ url?: string;
20
+ }
21
+ /** @deprecated Use wizardAbort() directly for new code. */
22
+ export declare function abort(message?: string, status?: number): Promise<never>;
23
+ export declare function isInGitRepo(): boolean;
24
+ export declare function getUncommittedOrUntrackedFiles(): string[];
25
+ export declare function isReact19Installed({ installDir, }: Pick<WizardOptions, 'installDir'>): Promise<boolean>;
26
+ /**
27
+ * Installs or updates a package with the user's package manager.
28
+ *
29
+ * IMPORTANT: This function modifies the `package.json`! Be sure to re-read
30
+ * it if you make additional modifications to it after calling this function!
31
+ */
32
+ export declare function installPackage({ packageName, alreadyInstalled, packageNameDisplayLabel, packageManager, forceInstall, integration, installDir, }: {
33
+ packageName: string;
34
+ alreadyInstalled: boolean;
35
+ packageNameDisplayLabel?: string;
36
+ packageManager?: PackageManager;
37
+ forceInstall?: boolean;
38
+ integration?: string;
39
+ installDir: string;
40
+ }): Promise<{
41
+ packageManager?: PackageManager;
42
+ }>;
43
+ /**
44
+ * Get package.json or abort the wizard if not found.
45
+ * Only use where package.json is required (e.g., package install, overrides).
46
+ * For detection/version-checks, use tryGetPackageJson() instead.
47
+ */
48
+ export declare function getPackageDotJson({ installDir, }: Pick<WizardOptions, 'installDir'>): Promise<PackageDotJson>;
49
+ /**
50
+ * Try to get package.json, returning null if it doesn't exist.
51
+ * Use this for detection purposes where missing package.json is expected (e.g., Python projects).
52
+ */
53
+ export declare function tryGetPackageJson({ installDir, }: Pick<WizardOptions, 'installDir'>): Promise<PackageDotJson | null>;
54
+ export declare function updatePackageDotJson(packageDotJson: PackageDotJson, { installDir }: Pick<WizardOptions, 'installDir'>): Promise<void>;
55
+ /**
56
+ * Detect and return the package manager. Pure — no prompts.
57
+ * Falls back to first detected or npm if ambiguous.
58
+ */
59
+ export declare function getPackageManager(options: Pick<WizardOptions, 'installDir'> & {
60
+ ci?: boolean;
61
+ }): Promise<PackageManager>;
62
+ export declare function isUsingTypeScript({ installDir, }: Pick<WizardOptions, 'installDir'>): boolean;
63
+ /**
64
+ * Get project data for the wizard via Amplitude OAuth or CI API key.
65
+ *
66
+ * Pass installDir to enable fresh-auth detection: when no local ampli.json
67
+ * exists, the cached ~/.ampli.json token is bypassed so the user explicitly
68
+ * authenticates and picks the right Amplitude account for this project.
69
+ */
70
+ export declare function getOrAskForProjectData(_options: Pick<WizardOptions, 'signup' | 'ci' | 'apiKey' | 'projectId'> & {
71
+ installDir?: string;
72
+ }): Promise<{
73
+ host: string;
74
+ projectApiKey: string;
75
+ accessToken: string;
76
+ projectId: number;
77
+ cloudRegion: CloudRegion;
78
+ }>;
79
+ /**
80
+ * Creates a new config file with the given filepath and codeSnippet.
81
+ */
82
+ export declare function createNewConfigFile(filepath: string, codeSnippet: string, { installDir }: Pick<WizardOptions, 'installDir'>, moreInformation?: string): Promise<boolean>;
@@ -0,0 +1,467 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ var __importDefault = (this && this.__importDefault) || function (mod) {
36
+ return (mod && mod.__esModule) ? mod : { "default": mod };
37
+ };
38
+ Object.defineProperty(exports, "__esModule", { value: true });
39
+ exports.abort = abort;
40
+ exports.isInGitRepo = isInGitRepo;
41
+ exports.getUncommittedOrUntrackedFiles = getUncommittedOrUntrackedFiles;
42
+ exports.isReact19Installed = isReact19Installed;
43
+ exports.installPackage = installPackage;
44
+ exports.getPackageDotJson = getPackageDotJson;
45
+ exports.tryGetPackageJson = tryGetPackageJson;
46
+ exports.updatePackageDotJson = updatePackageDotJson;
47
+ exports.getPackageManager = getPackageManager;
48
+ exports.isUsingTypeScript = isUsingTypeScript;
49
+ exports.getOrAskForProjectData = getOrAskForProjectData;
50
+ exports.createNewConfigFile = createNewConfigFile;
51
+ const childProcess = __importStar(require("node:child_process"));
52
+ const fs = __importStar(require("node:fs"));
53
+ const os = __importStar(require("node:os"));
54
+ const node_path_1 = require("node:path");
55
+ const chalk_1 = __importDefault(require("chalk"));
56
+ const telemetry_1 = require("../telemetry");
57
+ const debug_1 = require("./debug");
58
+ const package_manager_1 = require("./package-manager");
59
+ const package_json_1 = require("./package-json");
60
+ const constants_1 = require("../lib/constants");
61
+ const analytics_1 = require("./analytics");
62
+ const ui_1 = require("../ui");
63
+ const oauth_1 = require("./oauth");
64
+ const api_1 = require("../lib/api");
65
+ const ampli_settings_1 = require("./ampli-settings");
66
+ const constants_2 = require("../lib/constants");
67
+ const urls_1 = require("./urls");
68
+ const semver_1 = require("./semver");
69
+ const wizard_abort_1 = require("./wizard-abort");
70
+ /** @deprecated Use wizardAbort() directly for new code. */
71
+ async function abort(message, status) {
72
+ return (0, wizard_abort_1.wizardAbort)({ message, exitCode: status });
73
+ }
74
+ function isInGitRepo() {
75
+ try {
76
+ childProcess.execSync('git rev-parse --is-inside-work-tree', {
77
+ stdio: 'ignore',
78
+ });
79
+ return true;
80
+ }
81
+ catch {
82
+ return false;
83
+ }
84
+ }
85
+ function getUncommittedOrUntrackedFiles() {
86
+ try {
87
+ const gitStatus = childProcess
88
+ .execSync('git status --porcelain=v1', {
89
+ // we only care about stdout
90
+ stdio: ['ignore', 'pipe', 'ignore'],
91
+ })
92
+ .toString();
93
+ const files = gitStatus
94
+ .split(os.EOL)
95
+ .map((line) => line.trim())
96
+ .filter(Boolean)
97
+ .map((f) => `- ${f.split(/\s+/)[1]}`);
98
+ return files;
99
+ }
100
+ catch {
101
+ return [];
102
+ }
103
+ }
104
+ async function isReact19Installed({ installDir, }) {
105
+ try {
106
+ const packageJson = await tryGetPackageJson({ installDir });
107
+ if (!packageJson)
108
+ return false;
109
+ const reactVersion = (0, package_json_1.getPackageVersion)('react', packageJson);
110
+ if (!reactVersion) {
111
+ return false;
112
+ }
113
+ return (0, semver_1.fulfillsVersionRange)({
114
+ version: reactVersion,
115
+ acceptableVersions: '>=19.0.0',
116
+ canBeLatest: true,
117
+ });
118
+ }
119
+ catch {
120
+ return false;
121
+ }
122
+ }
123
+ /**
124
+ * Installs or updates a package with the user's package manager.
125
+ *
126
+ * IMPORTANT: This function modifies the `package.json`! Be sure to re-read
127
+ * it if you make additional modifications to it after calling this function!
128
+ */
129
+ async function installPackage({ packageName, alreadyInstalled, packageNameDisplayLabel, packageManager, forceInstall = false, integration, installDir, }) {
130
+ return (0, telemetry_1.traceStep)('install-package', async () => {
131
+ const sdkInstallSpinner = (0, ui_1.getUI)().spinner();
132
+ const pkgManager = packageManager || (await getPackageManager({ installDir }));
133
+ const isReact19 = await isReact19Installed({ installDir });
134
+ const legacyPeerDepsFlag = isReact19 && pkgManager.name === 'npm' ? '--legacy-peer-deps' : '';
135
+ sdkInstallSpinner.start(`${alreadyInstalled ? 'Updating' : 'Installing'} ${chalk_1.default.bold.cyan(packageNameDisplayLabel ?? packageName)} with ${chalk_1.default.bold(pkgManager.label)}.`);
136
+ try {
137
+ await new Promise((resolve, reject) => {
138
+ childProcess.exec(`${pkgManager.installCommand} ${packageName} ${pkgManager.flags} ${forceInstall ? pkgManager.forceInstallFlag : ''} ${legacyPeerDepsFlag}`.trim(), { cwd: installDir }, (err, stdout, stderr) => {
139
+ if (err) {
140
+ fs.writeFileSync((0, node_path_1.join)(process.cwd(), `amplitude-wizard-installation-error-${Date.now()}.log`), JSON.stringify({
141
+ stdout,
142
+ stderr,
143
+ }), { encoding: 'utf8' });
144
+ reject(err);
145
+ }
146
+ else {
147
+ resolve();
148
+ }
149
+ });
150
+ });
151
+ }
152
+ catch (e) {
153
+ sdkInstallSpinner.stop('Installation failed.');
154
+ (0, ui_1.getUI)().log.error(`${chalk_1.default.red('Encountered the following error during installation:')}\n\n${e}\n\n${chalk_1.default.dim(`The wizard has created a \`amplitude-wizard-installation-error-*.log\` file. If you think this issue is caused by the Amplitude wizard, create an issue on GitHub and include the log file's content:\n${constants_1.ISSUES_URL}`)}`);
155
+ await abort();
156
+ }
157
+ sdkInstallSpinner.stop(`${alreadyInstalled ? 'Updated' : 'Installed'} ${chalk_1.default.bold.cyan(packageNameDisplayLabel ?? packageName)} with ${chalk_1.default.bold(pkgManager.label)}.`);
158
+ analytics_1.analytics.wizardCapture('package installed', {
159
+ package_name: packageName,
160
+ package_manager: pkgManager.name,
161
+ integration,
162
+ });
163
+ return { packageManager: pkgManager };
164
+ });
165
+ }
166
+ /**
167
+ * Get package.json or abort the wizard if not found.
168
+ * Only use where package.json is required (e.g., package install, overrides).
169
+ * For detection/version-checks, use tryGetPackageJson() instead.
170
+ */
171
+ async function getPackageDotJson({ installDir, }) {
172
+ const packageJsonFileContents = await fs.promises
173
+ .readFile((0, node_path_1.join)(installDir, 'package.json'), 'utf8')
174
+ .catch(() => {
175
+ (0, ui_1.getUI)().log.error('Could not find package.json. Make sure to run the wizard in the root of your app!');
176
+ return abort();
177
+ });
178
+ let packageJson = undefined;
179
+ try {
180
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
181
+ packageJson = JSON.parse(packageJsonFileContents);
182
+ }
183
+ catch {
184
+ (0, ui_1.getUI)().log.error(`Unable to parse your ${chalk_1.default.cyan('package.json')}. Make sure it has a valid format!`);
185
+ await abort();
186
+ }
187
+ return packageJson || {};
188
+ }
189
+ /**
190
+ * Try to get package.json, returning null if it doesn't exist.
191
+ * Use this for detection purposes where missing package.json is expected (e.g., Python projects).
192
+ */
193
+ async function tryGetPackageJson({ installDir, }) {
194
+ try {
195
+ const packageJsonFileContents = await fs.promises.readFile((0, node_path_1.join)(installDir, 'package.json'), 'utf8');
196
+ return JSON.parse(packageJsonFileContents);
197
+ }
198
+ catch {
199
+ return null;
200
+ }
201
+ }
202
+ async function updatePackageDotJson(packageDotJson, { installDir }) {
203
+ try {
204
+ await fs.promises.writeFile((0, node_path_1.join)(installDir, 'package.json'), JSON.stringify(packageDotJson, null, 2), {
205
+ encoding: 'utf8',
206
+ flag: 'w',
207
+ });
208
+ }
209
+ catch {
210
+ (0, ui_1.getUI)().log.error(`Unable to update your ${chalk_1.default.cyan('package.json')}.`);
211
+ await abort();
212
+ }
213
+ }
214
+ /**
215
+ * Detect and return the package manager. Pure — no prompts.
216
+ * Falls back to first detected or npm if ambiguous.
217
+ */
218
+ // eslint-disable-next-line @typescript-eslint/require-await
219
+ async function getPackageManager(options) {
220
+ const detectedPackageManagers = (0, package_manager_1.detectAllPackageManagers)({
221
+ installDir: options.installDir,
222
+ });
223
+ if (detectedPackageManagers.length >= 1) {
224
+ const selected = detectedPackageManagers[0];
225
+ analytics_1.analytics.setTag('package-manager', selected.name);
226
+ return selected;
227
+ }
228
+ // No package manager detected — default to npm
229
+ analytics_1.analytics.setTag('package-manager', package_manager_1.NPM.name);
230
+ return package_manager_1.NPM;
231
+ }
232
+ function isUsingTypeScript({ installDir, }) {
233
+ try {
234
+ return fs.existsSync((0, node_path_1.join)(installDir, 'tsconfig.json'));
235
+ }
236
+ catch {
237
+ return false;
238
+ }
239
+ }
240
+ /**
241
+ * Get project data for the wizard via Amplitude OAuth or CI API key.
242
+ *
243
+ * Pass installDir to enable fresh-auth detection: when no local ampli.json
244
+ * exists, the cached ~/.ampli.json token is bypassed so the user explicitly
245
+ * authenticates and picks the right Amplitude account for this project.
246
+ */
247
+ async function getOrAskForProjectData(_options) {
248
+ // If an API key is provided (via --api-key flag, any mode), bypass OAuth entirely.
249
+ if (_options.apiKey) {
250
+ if (_options.ci) {
251
+ (0, ui_1.getUI)().log.info('Using provided API key (CI mode - OAuth bypassed)');
252
+ }
253
+ return {
254
+ host: constants_1.DEFAULT_HOST_URL,
255
+ projectApiKey: _options.apiKey,
256
+ accessToken: _options.apiKey,
257
+ projectId: _options.projectId ?? 0,
258
+ cloudRegion: 'us',
259
+ };
260
+ }
261
+ // Force fresh OAuth for projects that haven't been set up yet — no local
262
+ // ampli.json means we don't know which Amplitude org this project belongs to.
263
+ let forceFresh = false;
264
+ if (_options.installDir) {
265
+ const { ampliConfigExists } = await import('../lib/ampli-config.js');
266
+ forceFresh = !ampliConfigExists(_options.installDir);
267
+ if (forceFresh) {
268
+ (0, ui_1.getUI)().log.info(chalk_1.default.dim('No ampli.json found — starting fresh Amplitude authentication for this project.'));
269
+ }
270
+ }
271
+ const result = await (0, telemetry_1.traceStep)('login', () => askForWizardLogin({ forceFresh, installDir: _options.installDir }));
272
+ return {
273
+ accessToken: result.accessToken,
274
+ host: constants_1.DEFAULT_HOST_URL,
275
+ projectApiKey: result.projectApiKey,
276
+ projectId: result.projectId,
277
+ cloudRegion: result.cloudRegion,
278
+ };
279
+ }
280
+ async function askForWizardLogin(opts = {}) {
281
+ // ── 1. Authenticate via Amplitude OAuth (reuses ampli CLI session) ──
282
+ const auth = await (0, oauth_1.performAmplitudeAuth)({
283
+ zone: constants_2.DEFAULT_AMPLITUDE_ZONE,
284
+ forceFresh: opts.forceFresh,
285
+ });
286
+ // ── 2. Detect actual cloud region (EU users auth via US endpoint but
287
+ // their data lives on EU servers — detectRegionFromToken probes both) ──
288
+ let cloudRegion = 'us';
289
+ try {
290
+ cloudRegion = await (0, urls_1.detectRegionFromToken)(auth.accessToken);
291
+ }
292
+ catch {
293
+ // Fall back to 'us' if region detection fails
294
+ }
295
+ // ── 3. Fetch user info from Amplitude Data API ────────────────────
296
+ let userInfo;
297
+ try {
298
+ userInfo = await (0, api_1.fetchAmplitudeUser)(auth.idToken, cloudRegion);
299
+ }
300
+ catch {
301
+ // Could not fetch user info — warn and continue without it
302
+ (0, ui_1.getUI)().log.warn(chalk_1.default.yellow('Could not fetch user info from Amplitude. Continuing without it.'));
303
+ }
304
+ let selectedOrg;
305
+ if (userInfo) {
306
+ // Persist user details back to ~/.ampli.json (replaces the "pending" entry)
307
+ (0, ampli_settings_1.storeToken)({
308
+ id: userInfo.id,
309
+ firstName: userInfo.firstName,
310
+ lastName: userInfo.lastName,
311
+ email: userInfo.email,
312
+ zone: auth.zone,
313
+ }, {
314
+ accessToken: auth.accessToken,
315
+ idToken: auth.idToken,
316
+ refreshToken: auth.refreshToken,
317
+ expiresAt: new Date(Date.now() + 3600 * 1000).toISOString(),
318
+ });
319
+ // ── 4. Org resolution (flowchart: sign-in → determine destination org) ──
320
+ if (userInfo.orgs.length === 0) {
321
+ // New user who hasn't created an org yet — direct them to the browser
322
+ (0, ui_1.getUI)().log.error(`${chalk_1.default.red('No Amplitude organization found.')}\n\n` +
323
+ chalk_1.default.dim('Your account has no organizations. Please complete signup at ' +
324
+ chalk_1.default.cyan('https://app.amplitude.com') +
325
+ ' and create an organization, then re-run the wizard.'));
326
+ await abort();
327
+ }
328
+ else if (userInfo.orgs.length === 1) {
329
+ selectedOrg = userInfo.orgs[0];
330
+ }
331
+ else {
332
+ // Multiple orgs — prompt the user to pick one
333
+ const { select } = await import('@inquirer/prompts');
334
+ selectedOrg = await select({
335
+ message: 'Select an Amplitude organization:',
336
+ choices: userInfo.orgs.map((org) => ({ name: org.name, value: org })),
337
+ });
338
+ }
339
+ (0, ui_1.getUI)().log.success(`Logged in as ${chalk_1.default.bold(userInfo.email)}${selectedOrg ? ` (${selectedOrg.name})` : ''}`);
340
+ analytics_1.analytics.setDistinctId(userInfo.id);
341
+ analytics_1.analytics.setTag('opened-wizard-link', true);
342
+ }
343
+ let selectedWorkspace;
344
+ if (selectedOrg) {
345
+ if (selectedOrg.workspaces.length === 1) {
346
+ selectedWorkspace = selectedOrg.workspaces[0];
347
+ }
348
+ else if (selectedOrg.workspaces.length > 1) {
349
+ const { select } = await import('@inquirer/prompts');
350
+ selectedWorkspace = await select({
351
+ message: `Select a workspace in ${selectedOrg.name}:`,
352
+ choices: selectedOrg.workspaces.map((ws) => ({
353
+ name: ws.name,
354
+ value: ws,
355
+ })),
356
+ });
357
+ }
358
+ // Write ~/.ampli.json so future runs recognise this project
359
+ if (opts.installDir && selectedWorkspace) {
360
+ const { writeAmpliConfig } = await import('../lib/ampli-config.js');
361
+ writeAmpliConfig(opts.installDir, {
362
+ OrgId: selectedOrg.id,
363
+ WorkspaceId: selectedWorkspace.id,
364
+ Zone: cloudRegion,
365
+ });
366
+ }
367
+ }
368
+ // ── 5. Get the Amplitude project API key ─────────────────────────
369
+ // The Data API returns apiKey on the Environment → App type, so we
370
+ // can grab it directly from the workspace data we already fetched.
371
+ // Falls back to Thunder's agentic API, then manual prompt.
372
+ let projectApiKey;
373
+ if (selectedWorkspace) {
374
+ // Get environments that have an app with an API key, sorted by rank (lowest = primary)
375
+ const envsWithKey = (selectedWorkspace.environments ?? [])
376
+ .filter((env) => env.app?.apiKey)
377
+ .sort((a, b) => a.rank - b.rank);
378
+ if (envsWithKey.length === 1) {
379
+ projectApiKey = envsWithKey[0].app.apiKey;
380
+ (0, ui_1.getUI)().log.success(chalk_1.default.dim(`Retrieved API key for ${chalk_1.default.bold(envsWithKey[0].name)} environment`));
381
+ }
382
+ else if (envsWithKey.length > 1) {
383
+ const { select } = await import('@inquirer/prompts');
384
+ const selectedEnv = await select({
385
+ message: 'Select an environment:',
386
+ choices: envsWithKey.map((env) => ({
387
+ name: `${env.name} (${env.app.id})`,
388
+ value: env,
389
+ })),
390
+ });
391
+ projectApiKey = selectedEnv.app.apiKey;
392
+ (0, ui_1.getUI)().log.success(chalk_1.default.dim(`Retrieved API key for ${chalk_1.default.bold(selectedEnv.name)} environment`));
393
+ }
394
+ // Persist so future runs don't need to fetch again
395
+ if (projectApiKey && opts.installDir) {
396
+ const { persistApiKey } = await import('./api-key-store.js');
397
+ const source = persistApiKey(projectApiKey, opts.installDir);
398
+ (0, ui_1.getUI)().log.success(chalk_1.default.dim(source === 'keychain'
399
+ ? 'API key saved to system keychain'
400
+ : 'API key saved to .env.local (added to .gitignore)'));
401
+ }
402
+ }
403
+ // Fall back to manual prompt if auto-fetch didn't work
404
+ if (!projectApiKey) {
405
+ projectApiKey = await askForAmplitudeApiKey(opts.installDir);
406
+ }
407
+ return {
408
+ accessToken: auth.idToken,
409
+ projectApiKey,
410
+ host: constants_1.DEFAULT_HOST_URL,
411
+ distinctId: userInfo?.id ?? 'unknown',
412
+ projectId: 0,
413
+ cloudRegion,
414
+ };
415
+ }
416
+ async function askForAmplitudeApiKey(installDir) {
417
+ const { readApiKeyWithSource, persistApiKey } = await import('./api-key-store.js');
418
+ // Return saved key if available
419
+ if (installDir) {
420
+ const result = readApiKeyWithSource(installDir);
421
+ if (result) {
422
+ (0, ui_1.getUI)().log.success(chalk_1.default.dim(result.source === 'keychain'
423
+ ? 'Using saved Amplitude API key from system keychain'
424
+ : 'Using saved Amplitude API key from .env.local'));
425
+ return result.key;
426
+ }
427
+ }
428
+ const { input } = await import('@inquirer/prompts');
429
+ (0, ui_1.getUI)().log.info(`\nTo finish setup, enter your Amplitude project ${chalk_1.default.bold('API Key')}.\n` +
430
+ chalk_1.default.dim(`Find it at: Amplitude → Settings → Projects → [your project] → API Keys\n`));
431
+ const apiKey = await input({
432
+ message: 'Amplitude API Key:',
433
+ validate: (v) => v.trim().length > 0 || 'API key cannot be empty',
434
+ });
435
+ const trimmed = apiKey.trim();
436
+ // Persist so the user doesn't have to enter it again
437
+ if (installDir) {
438
+ const source = persistApiKey(trimmed, installDir);
439
+ (0, ui_1.getUI)().log.success(chalk_1.default.dim(source === 'keychain'
440
+ ? 'API key saved to system keychain'
441
+ : 'API key saved to .env.local (added to .gitignore)'));
442
+ }
443
+ return trimmed;
444
+ }
445
+ /**
446
+ * Creates a new config file with the given filepath and codeSnippet.
447
+ */
448
+ async function createNewConfigFile(filepath, codeSnippet, { installDir }, moreInformation) {
449
+ if (!(0, node_path_1.isAbsolute)(filepath)) {
450
+ (0, debug_1.debug)(`createNewConfigFile: filepath is not absolute: ${filepath}`);
451
+ return false;
452
+ }
453
+ const prettyFilename = chalk_1.default.cyan((0, node_path_1.relative)(installDir, filepath));
454
+ try {
455
+ await fs.promises.writeFile(filepath, codeSnippet);
456
+ (0, ui_1.getUI)().log.success(`Added new ${prettyFilename} file.`);
457
+ if (moreInformation) {
458
+ (0, ui_1.getUI)().log.info(chalk_1.default.gray(moreInformation));
459
+ }
460
+ return true;
461
+ }
462
+ catch (e) {
463
+ (0, debug_1.debug)(e);
464
+ (0, ui_1.getUI)().log.warn(`Could not create a new ${prettyFilename} file. Please create one manually and follow the instructions below.`);
465
+ }
466
+ return false;
467
+ }
@@ -0,0 +1,10 @@
1
+ type SupportedShell = 'zsh' | 'bash';
2
+ export declare function detectShell(): SupportedShell | null;
3
+ export declare const ZSH_COMPLETION_SCRIPT = "###-begin-amplitude-wizard-completions-###\n\n_amplitude_wizard() {\n local state\n local -a commands global_opts wizard_opts\n\n commands=(\n 'login:Log in to your Amplitude account'\n 'logout:Log out of your Amplitude account'\n 'whoami:Show the currently logged-in Amplitude account'\n 'slack:Set up Amplitude Slack integration'\n 'mcp:MCP server management commands'\n 'completion:Print shell completion script'\n )\n\n global_opts=(\n '--debug[Enable verbose logging]'\n '--verbose[Print diagnostic info to the run log]'\n '--signup[Create a new Amplitude account during setup]'\n '--ci[Enable non-interactive CI mode]'\n '--api-key[Amplitude project API key]:key:'\n '--project-id[Amplitude project ID]:id:'\n '--local-mcp[Use local MCP server at http://localhost:8787/mcp]'\n {-h,--help}'[Show help]'\n {-v,--version}'[Show version]'\n )\n\n wizard_opts=(\n '--force-install[Force package install even if peer checks fail]'\n '--install-dir[Directory to install Amplitude in]:dir:_files -/'\n '--integration[Framework integration to set up]:integration:(nextjs vue react-router django flask fastapi javascript_web javascript_node python)'\n '--menu[Show integration selection menu instead of auto-detecting]'\n '--benchmark[Run in benchmark mode with per-phase token tracking]'\n )\n\n _arguments -C \\\n '1: :->cmd' \\\n '*:: :->args'\n\n case $state in\n cmd)\n _describe 'command' commands\n _arguments $global_opts $wizard_opts\n ;;\n args)\n case ${words[1]} in\n mcp)\n local -a mcp_cmds\n mcp_cmds=('add:Install Amplitude MCP server' 'remove:Remove Amplitude MCP server')\n _arguments -C '1: :->sub' '*:: :->subargs'\n case $state in\n sub) _describe 'mcp command' mcp_cmds ;;\n subargs) _arguments '--local[Use local MCP server at http://localhost:8787]' ;;\n esac\n ;;\n login)\n _arguments '--zone[Amplitude data center zone]:zone:(us eu)'\n ;;\n *)\n _arguments $global_opts $wizard_opts\n ;;\n esac\n ;;\n esac\n}\n\n(( $+functions[compdef] )) || { autoload -Uz compinit; compinit; }\ncompdef _amplitude_wizard amplitude-wizard\n###-end-amplitude-wizard-completions-###";
4
+ export declare const BASH_COMPLETION_SCRIPT = "###-begin-amplitude-wizard-completions-###\n_amplitude_wizard_completions() {\n local cur prev\n cur=\"${COMP_WORDS[COMP_CWORD]}\"\n prev=\"${COMP_WORDS[COMP_CWORD-1]}\"\n\n local commands=\"login logout whoami slack mcp completion\"\n local global_flags=\"--debug --verbose --signup --ci --api-key --project-id --local-mcp --help --version\"\n local wizard_flags=\"--force-install --install-dir --integration --menu --benchmark\"\n local integrations=\"nextjs vue react-router django flask fastapi javascript_web javascript_node python\"\n\n if [[ ${COMP_CWORD} -eq 1 ]]; then\n COMPREPLY=($(compgen -W \"$commands $global_flags $wizard_flags\" -- \"$cur\"))\n return\n fi\n\n case \"${COMP_WORDS[1]}\" in\n mcp)\n if [[ ${COMP_CWORD} -eq 2 ]]; then\n COMPREPLY=($(compgen -W \"add remove\" -- \"$cur\"))\n else\n COMPREPLY=($(compgen -W \"--local\" -- \"$cur\"))\n fi\n ;;\n login)\n if [[ \"$prev\" == \"--zone\" ]]; then\n COMPREPLY=($(compgen -W \"us eu\" -- \"$cur\"))\n else\n COMPREPLY=($(compgen -W \"--zone\" -- \"$cur\"))\n fi\n ;;\n *)\n if [[ \"$prev\" == \"--integration\" ]]; then\n COMPREPLY=($(compgen -W \"$integrations\" -- \"$cur\"))\n elif [[ \"$prev\" == \"--install-dir\" ]]; then\n COMPREPLY=($(compgen -d -- \"$cur\"))\n else\n COMPREPLY=($(compgen -W \"$global_flags $wizard_flags\" -- \"$cur\"))\n fi\n ;;\n esac\n}\ncomplete -F _amplitude_wizard_completions amplitude-wizard\n###-end-amplitude-wizard-completions-###";
5
+ /**
6
+ * Silently appends `eval "$(amplitude-wizard completion)"` to the user's shell
7
+ * RC file if it isn't already there. Call fire-and-forget at startup.
8
+ */
9
+ export declare function installCompletions(): void;
10
+ export {};