@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.
- package/LICENSE +47 -0
- package/README.md +119 -0
- package/dist/bin.d.ts +2 -0
- package/dist/bin.js +763 -0
- package/dist/package.json +144 -0
- package/dist/src/frameworks/android/android-wizard-agent.d.ts +6 -0
- package/dist/src/frameworks/android/android-wizard-agent.js +72 -0
- package/dist/src/frameworks/android/utils.d.ts +11 -0
- package/dist/src/frameworks/android/utils.js +32 -0
- package/dist/src/frameworks/django/django-wizard-agent.d.ts +8 -0
- package/dist/src/frameworks/django/django-wizard-agent.js +171 -0
- package/dist/src/frameworks/django/utils.d.ts +31 -0
- package/dist/src/frameworks/django/utils.js +305 -0
- package/dist/src/frameworks/fastapi/fastapi-wizard-agent.d.ts +11 -0
- package/dist/src/frameworks/fastapi/fastapi-wizard-agent.js +189 -0
- package/dist/src/frameworks/fastapi/utils.d.ts +26 -0
- package/dist/src/frameworks/fastapi/utils.js +257 -0
- package/dist/src/frameworks/flask/flask-wizard-agent.d.ts +8 -0
- package/dist/src/frameworks/flask/flask-wizard-agent.js +177 -0
- package/dist/src/frameworks/flask/utils.d.ts +28 -0
- package/dist/src/frameworks/flask/utils.js +343 -0
- package/dist/src/frameworks/flutter/flutter-wizard-agent.d.ts +4 -0
- package/dist/src/frameworks/flutter/flutter-wizard-agent.js +57 -0
- package/dist/src/frameworks/flutter/utils.d.ts +7 -0
- package/dist/src/frameworks/flutter/utils.js +64 -0
- package/dist/src/frameworks/generic/generic-wizard-agent.d.ts +2 -0
- package/dist/src/frameworks/generic/generic-wizard-agent.js +176 -0
- package/dist/src/frameworks/go/go-wizard-agent.d.ts +4 -0
- package/dist/src/frameworks/go/go-wizard-agent.js +57 -0
- package/dist/src/frameworks/go/utils.d.ts +5 -0
- package/dist/src/frameworks/go/utils.js +44 -0
- package/dist/src/frameworks/java/java-wizard-agent.d.ts +7 -0
- package/dist/src/frameworks/java/java-wizard-agent.js +73 -0
- package/dist/src/frameworks/java/utils.d.ts +15 -0
- package/dist/src/frameworks/java/utils.js +64 -0
- package/dist/src/frameworks/javascript-node/javascript-node-wizard-agent.d.ts +4 -0
- package/dist/src/frameworks/javascript-node/javascript-node-wizard-agent.js +57 -0
- package/dist/src/frameworks/javascript-web/javascript-web-wizard-agent.d.ts +3 -0
- package/dist/src/frameworks/javascript-web/javascript-web-wizard-agent.js +151 -0
- package/dist/src/frameworks/javascript-web/utils.d.ts +28 -0
- package/dist/src/frameworks/javascript-web/utils.js +153 -0
- package/dist/src/frameworks/nextjs/nextjs-wizard-agent.d.ts +7 -0
- package/dist/src/frameworks/nextjs/nextjs-wizard-agent.js +98 -0
- package/dist/src/frameworks/nextjs/utils.d.ts +12 -0
- package/dist/src/frameworks/nextjs/utils.js +51 -0
- package/dist/src/frameworks/python/python-wizard-agent.d.ts +7 -0
- package/dist/src/frameworks/python/python-wizard-agent.js +193 -0
- package/dist/src/frameworks/python/utils.d.ts +28 -0
- package/dist/src/frameworks/python/utils.js +146 -0
- package/dist/src/frameworks/react-native/react-native-wizard-agent.d.ts +6 -0
- package/dist/src/frameworks/react-native/react-native-wizard-agent.js +84 -0
- package/dist/src/frameworks/react-native/utils.d.ts +21 -0
- package/dist/src/frameworks/react-native/utils.js +82 -0
- package/dist/src/frameworks/react-router/react-router-wizard-agent.d.ts +7 -0
- package/dist/src/frameworks/react-router/react-router-wizard-agent.js +98 -0
- package/dist/src/frameworks/react-router/utils.d.ts +13 -0
- package/dist/src/frameworks/react-router/utils.js +160 -0
- package/dist/src/frameworks/swift/swift-wizard-agent.d.ts +7 -0
- package/dist/src/frameworks/swift/swift-wizard-agent.js +72 -0
- package/dist/src/frameworks/swift/utils.d.ts +12 -0
- package/dist/src/frameworks/swift/utils.js +82 -0
- package/dist/src/frameworks/unity/unity-wizard-agent.d.ts +6 -0
- package/dist/src/frameworks/unity/unity-wizard-agent.js +79 -0
- package/dist/src/frameworks/unity/utils.d.ts +12 -0
- package/dist/src/frameworks/unity/utils.js +66 -0
- package/dist/src/frameworks/unreal/unreal-wizard-agent.d.ts +6 -0
- package/dist/src/frameworks/unreal/unreal-wizard-agent.js +77 -0
- package/dist/src/frameworks/unreal/utils.d.ts +10 -0
- package/dist/src/frameworks/unreal/utils.js +29 -0
- package/dist/src/frameworks/vue/vue-wizard-agent.d.ts +4 -0
- package/dist/src/frameworks/vue/vue-wizard-agent.js +64 -0
- package/dist/src/lib/agent-hooks.d.ts +26 -0
- package/dist/src/lib/agent-hooks.js +118 -0
- package/dist/src/lib/agent-interface.d.ts +175 -0
- package/dist/src/lib/agent-interface.js +1217 -0
- package/dist/src/lib/agent-runner.d.ts +9 -0
- package/dist/src/lib/agent-runner.js +415 -0
- package/dist/src/lib/ampli-config.d.ts +105 -0
- package/dist/src/lib/ampli-config.js +178 -0
- package/dist/src/lib/api.d.ts +107 -0
- package/dist/src/lib/api.js +442 -0
- package/dist/src/lib/commandments.d.ts +1 -0
- package/dist/src/lib/commandments.js +24 -0
- package/dist/src/lib/console-query.d.ts +27 -0
- package/dist/src/lib/console-query.js +121 -0
- package/dist/src/lib/constants.d.ts +124 -0
- package/dist/src/lib/constants.js +170 -0
- package/dist/src/lib/detect-amplitude.d.ts +31 -0
- package/dist/src/lib/detect-amplitude.js +407 -0
- package/dist/src/lib/framework-config.d.ts +188 -0
- package/dist/src/lib/framework-config.js +21 -0
- package/dist/src/lib/health-checks/endpoints.d.ts +3 -0
- package/dist/src/lib/health-checks/endpoints.js +45 -0
- package/dist/src/lib/health-checks/index.d.ts +4 -0
- package/dist/src/lib/health-checks/index.js +22 -0
- package/dist/src/lib/health-checks/readiness.d.ts +24 -0
- package/dist/src/lib/health-checks/readiness.js +118 -0
- package/dist/src/lib/health-checks/statuspage.d.ts +9 -0
- package/dist/src/lib/health-checks/statuspage.js +104 -0
- package/dist/src/lib/health-checks/types.d.ts +31 -0
- package/dist/src/lib/health-checks/types.js +9 -0
- package/dist/src/lib/helper-functions.d.ts +1 -0
- package/dist/src/lib/helper-functions.js +5 -0
- package/dist/src/lib/middleware/benchmark.d.ts +54 -0
- package/dist/src/lib/middleware/benchmark.js +48 -0
- package/dist/src/lib/middleware/benchmarks/cache-tracker.d.ts +44 -0
- package/dist/src/lib/middleware/benchmarks/cache-tracker.js +80 -0
- package/dist/src/lib/middleware/benchmarks/compaction-tracker.d.ts +29 -0
- package/dist/src/lib/middleware/benchmarks/compaction-tracker.js +59 -0
- package/dist/src/lib/middleware/benchmarks/context-size-tracker.d.ts +26 -0
- package/dist/src/lib/middleware/benchmarks/context-size-tracker.js +55 -0
- package/dist/src/lib/middleware/benchmarks/cost-tracker.d.ts +16 -0
- package/dist/src/lib/middleware/benchmarks/cost-tracker.js +75 -0
- package/dist/src/lib/middleware/benchmarks/duration-tracker.d.ts +20 -0
- package/dist/src/lib/middleware/benchmarks/duration-tracker.js +39 -0
- package/dist/src/lib/middleware/benchmarks/index.d.ts +9 -0
- package/dist/src/lib/middleware/benchmarks/index.js +67 -0
- package/dist/src/lib/middleware/benchmarks/json-writer.d.ts +15 -0
- package/dist/src/lib/middleware/benchmarks/json-writer.js +144 -0
- package/dist/src/lib/middleware/benchmarks/summary.d.ts +9 -0
- package/dist/src/lib/middleware/benchmarks/summary.js +105 -0
- package/dist/src/lib/middleware/benchmarks/token-tracker.d.ts +40 -0
- package/dist/src/lib/middleware/benchmarks/token-tracker.js +76 -0
- package/dist/src/lib/middleware/benchmarks/turn-counter.d.ts +34 -0
- package/dist/src/lib/middleware/benchmarks/turn-counter.js +58 -0
- package/dist/src/lib/middleware/config.d.ts +24 -0
- package/dist/src/lib/middleware/config.js +96 -0
- package/dist/src/lib/middleware/index.d.ts +11 -0
- package/dist/src/lib/middleware/index.js +17 -0
- package/dist/src/lib/middleware/phase-detector.d.ts +8 -0
- package/dist/src/lib/middleware/phase-detector.js +63 -0
- package/dist/src/lib/middleware/pipeline.d.ts +29 -0
- package/dist/src/lib/middleware/pipeline.js +81 -0
- package/dist/src/lib/middleware/schemas.d.ts +27 -0
- package/dist/src/lib/middleware/schemas.js +84 -0
- package/dist/src/lib/middleware/types.d.ts +94 -0
- package/dist/src/lib/middleware/types.js +8 -0
- package/dist/src/lib/package-manager-detection.d.ts +42 -0
- package/dist/src/lib/package-manager-detection.js +292 -0
- package/dist/src/lib/registry.d.ts +3 -0
- package/dist/src/lib/registry.js +42 -0
- package/dist/src/lib/safe-tools.d.ts +2 -0
- package/dist/src/lib/safe-tools.js +214 -0
- package/dist/src/lib/wizard-session.d.ts +220 -0
- package/dist/src/lib/wizard-session.js +127 -0
- package/dist/src/lib/wizard-tools.d.ts +82 -0
- package/dist/src/lib/wizard-tools.js +499 -0
- package/dist/src/run.d.ts +19 -0
- package/dist/src/run.js +151 -0
- package/dist/src/steps/add-mcp-server-to-clients/MCPClient.d.ts +30 -0
- package/dist/src/steps/add-mcp-server-to-clients/MCPClient.js +141 -0
- package/dist/src/steps/add-mcp-server-to-clients/clients/claude-code.d.ts +29 -0
- package/dist/src/steps/add-mcp-server-to-clients/clients/claude-code.js +180 -0
- package/dist/src/steps/add-mcp-server-to-clients/clients/claude.d.ts +20 -0
- package/dist/src/steps/add-mcp-server-to-clients/clients/claude.js +63 -0
- package/dist/src/steps/add-mcp-server-to-clients/clients/codex.d.ts +28 -0
- package/dist/src/steps/add-mcp-server-to-clients/clients/codex.js +77 -0
- package/dist/src/steps/add-mcp-server-to-clients/clients/cursor.d.ts +24 -0
- package/dist/src/steps/add-mcp-server-to-clients/clients/cursor.js +60 -0
- package/dist/src/steps/add-mcp-server-to-clients/clients/visual-studio-code.d.ts +27 -0
- package/dist/src/steps/add-mcp-server-to-clients/clients/visual-studio-code.js +101 -0
- package/dist/src/steps/add-mcp-server-to-clients/clients/zed.d.ts +26 -0
- package/dist/src/steps/add-mcp-server-to-clients/clients/zed.js +102 -0
- package/dist/src/steps/add-mcp-server-to-clients/defaults.d.ts +44 -0
- package/dist/src/steps/add-mcp-server-to-clients/defaults.js +123 -0
- package/dist/src/steps/add-mcp-server-to-clients/index.d.ts +19 -0
- package/dist/src/steps/add-mcp-server-to-clients/index.js +110 -0
- package/dist/src/steps/add-or-update-environment-variables.d.ts +10 -0
- package/dist/src/steps/add-or-update-environment-variables.js +188 -0
- package/dist/src/steps/index.d.ts +4 -0
- package/dist/src/steps/index.js +20 -0
- package/dist/src/steps/run-prettier.d.ts +5 -0
- package/dist/src/steps/run-prettier.js +90 -0
- package/dist/src/steps/upload-environment-variables/EnvironmentProvider.d.ts +11 -0
- package/dist/src/steps/upload-environment-variables/EnvironmentProvider.js +11 -0
- package/dist/src/steps/upload-environment-variables/index.d.ts +6 -0
- package/dist/src/steps/upload-environment-variables/index.js +37 -0
- package/dist/src/steps/upload-environment-variables/providers/vercel.d.ts +15 -0
- package/dist/src/steps/upload-environment-variables/providers/vercel.js +145 -0
- package/dist/src/telemetry.d.ts +2 -0
- package/dist/src/telemetry.js +12 -0
- package/dist/src/ui/index.d.ts +8 -0
- package/dist/src/ui/index.js +16 -0
- package/dist/src/ui/logging-ui.d.ts +56 -0
- package/dist/src/ui/logging-ui.js +157 -0
- package/dist/src/ui/tui/App.d.ts +6 -0
- package/dist/src/ui/tui/App.js +34 -0
- package/dist/src/ui/tui/components/AmplitudeLogo.d.ts +5 -0
- package/dist/src/ui/tui/components/AmplitudeLogo.js +81 -0
- package/dist/src/ui/tui/components/AmplitudeTextLogo.d.ts +3 -0
- package/dist/src/ui/tui/components/AmplitudeTextLogo.js +31 -0
- package/dist/src/ui/tui/components/ConsoleView.d.ts +23 -0
- package/dist/src/ui/tui/components/ConsoleView.js +220 -0
- package/dist/src/ui/tui/components/TitleBar.d.ts +6 -0
- package/dist/src/ui/tui/components/TitleBar.js +16 -0
- package/dist/src/ui/tui/console-commands.d.ts +16 -0
- package/dist/src/ui/tui/console-commands.js +31 -0
- package/dist/src/ui/tui/context/CommandModeContext.d.ts +2 -0
- package/dist/src/ui/tui/context/CommandModeContext.js +3 -0
- package/dist/src/ui/tui/flows.d.ts +48 -0
- package/dist/src/ui/tui/flows.js +154 -0
- package/dist/src/ui/tui/hooks/useScreenInput.d.ts +13 -0
- package/dist/src/ui/tui/hooks/useScreenInput.js +18 -0
- package/dist/src/ui/tui/hooks/useStdoutDimensions.d.ts +9 -0
- package/dist/src/ui/tui/hooks/useStdoutDimensions.js +29 -0
- package/dist/src/ui/tui/ink-ui.d.ts +62 -0
- package/dist/src/ui/tui/ink-ui.js +142 -0
- package/dist/src/ui/tui/primitives/CardLayout.d.ts +12 -0
- package/dist/src/ui/tui/primitives/CardLayout.js +9 -0
- package/dist/src/ui/tui/primitives/ConfirmationInput.d.ts +13 -0
- package/dist/src/ui/tui/primitives/ConfirmationInput.js +35 -0
- package/dist/src/ui/tui/primitives/DissolveTransition.d.ts +21 -0
- package/dist/src/ui/tui/primitives/DissolveTransition.js +143 -0
- package/dist/src/ui/tui/primitives/EventPlanViewer.d.ts +9 -0
- package/dist/src/ui/tui/primitives/EventPlanViewer.js +9 -0
- package/dist/src/ui/tui/primitives/KagiSmallWebViewer.d.ts +7 -0
- package/dist/src/ui/tui/primitives/KagiSmallWebViewer.js +101 -0
- package/dist/src/ui/tui/primitives/LoadingBox.d.ts +8 -0
- package/dist/src/ui/tui/primitives/LoadingBox.js +9 -0
- package/dist/src/ui/tui/primitives/LogViewer.d.ts +11 -0
- package/dist/src/ui/tui/primitives/LogViewer.js +55 -0
- package/dist/src/ui/tui/primitives/PickerMenu.d.ts +20 -0
- package/dist/src/ui/tui/primitives/PickerMenu.js +212 -0
- package/dist/src/ui/tui/primitives/ProgressList.d.ts +15 -0
- package/dist/src/ui/tui/primitives/ProgressList.js +29 -0
- package/dist/src/ui/tui/primitives/PromptLabel.d.ts +11 -0
- package/dist/src/ui/tui/primitives/PromptLabel.js +12 -0
- package/dist/src/ui/tui/primitives/ReportViewer.d.ts +12 -0
- package/dist/src/ui/tui/primitives/ReportViewer.js +99 -0
- package/dist/src/ui/tui/primitives/ScreenErrorBoundary.d.ts +26 -0
- package/dist/src/ui/tui/primitives/ScreenErrorBoundary.js +29 -0
- package/dist/src/ui/tui/primitives/SlashCommandInput.d.ts +21 -0
- package/dist/src/ui/tui/primitives/SlashCommandInput.js +85 -0
- package/dist/src/ui/tui/primitives/SnakeGame.d.ts +1 -0
- package/dist/src/ui/tui/primitives/SnakeGame.js +1 -0
- package/dist/src/ui/tui/primitives/SplitView.d.ts +11 -0
- package/dist/src/ui/tui/primitives/SplitView.js +8 -0
- package/dist/src/ui/tui/primitives/TabContainer.d.ts +18 -0
- package/dist/src/ui/tui/primitives/TabContainer.js +30 -0
- package/dist/src/ui/tui/primitives/index.d.ts +23 -0
- package/dist/src/ui/tui/primitives/index.js +19 -0
- package/dist/src/ui/tui/router.d.ts +61 -0
- package/dist/src/ui/tui/router.js +104 -0
- package/dist/src/ui/tui/screen-registry.d.ts +19 -0
- package/dist/src/ui/tui/screen-registry.js +56 -0
- package/dist/src/ui/tui/screens/ActivationOptionsScreen.d.ts +12 -0
- package/dist/src/ui/tui/screens/ActivationOptionsScreen.js +57 -0
- package/dist/src/ui/tui/screens/AuthScreen.d.ts +18 -0
- package/dist/src/ui/tui/screens/AuthScreen.js +107 -0
- package/dist/src/ui/tui/screens/ChecklistScreen.d.ts +22 -0
- package/dist/src/ui/tui/screens/ChecklistScreen.js +122 -0
- package/dist/src/ui/tui/screens/DataIngestionCheckScreen.d.ts +24 -0
- package/dist/src/ui/tui/screens/DataIngestionCheckScreen.js +113 -0
- package/dist/src/ui/tui/screens/DataSetupScreen.d.ts +17 -0
- package/dist/src/ui/tui/screens/DataSetupScreen.js +73 -0
- package/dist/src/ui/tui/screens/IntroScreen.d.ts +16 -0
- package/dist/src/ui/tui/screens/IntroScreen.js +86 -0
- package/dist/src/ui/tui/screens/LoginScreen.d.ts +15 -0
- package/dist/src/ui/tui/screens/LoginScreen.js +65 -0
- package/dist/src/ui/tui/screens/LogoutScreen.d.ts +12 -0
- package/dist/src/ui/tui/screens/LogoutScreen.js +28 -0
- package/dist/src/ui/tui/screens/McpScreen.d.ts +26 -0
- package/dist/src/ui/tui/screens/McpScreen.js +148 -0
- package/dist/src/ui/tui/screens/OutageScreen.d.ts +10 -0
- package/dist/src/ui/tui/screens/OutageScreen.js +17 -0
- package/dist/src/ui/tui/screens/OutroScreen.d.ts +11 -0
- package/dist/src/ui/tui/screens/OutroScreen.js +69 -0
- package/dist/src/ui/tui/screens/RegionSelectScreen.d.ts +17 -0
- package/dist/src/ui/tui/screens/RegionSelectScreen.js +40 -0
- package/dist/src/ui/tui/screens/RunScreen.d.ts +16 -0
- package/dist/src/ui/tui/screens/RunScreen.js +212 -0
- package/dist/src/ui/tui/screens/SettingsOverrideScreen.d.ts +10 -0
- package/dist/src/ui/tui/screens/SettingsOverrideScreen.js +23 -0
- package/dist/src/ui/tui/screens/SetupScreen.d.ts +13 -0
- package/dist/src/ui/tui/screens/SetupScreen.js +73 -0
- package/dist/src/ui/tui/screens/SlackScreen.d.ts +25 -0
- package/dist/src/ui/tui/screens/SlackScreen.js +97 -0
- package/dist/src/ui/tui/services/mcp-installer.d.ts +25 -0
- package/dist/src/ui/tui/services/mcp-installer.js +82 -0
- package/dist/src/ui/tui/start-tui.d.ts +10 -0
- package/dist/src/ui/tui/start-tui.js +50 -0
- package/dist/src/ui/tui/store.d.ts +231 -0
- package/dist/src/ui/tui/store.js +568 -0
- package/dist/src/ui/tui/styles.d.ts +31 -0
- package/dist/src/ui/tui/styles.js +33 -0
- package/dist/src/ui/wizard-ui.d.ts +110 -0
- package/dist/src/ui/wizard-ui.js +18 -0
- package/dist/src/utils/ampli-settings.d.ts +37 -0
- package/dist/src/utils/ampli-settings.js +182 -0
- package/dist/src/utils/analytics.d.ts +35 -0
- package/dist/src/utils/analytics.js +133 -0
- package/dist/src/utils/anthropic-status.d.ts +17 -0
- package/dist/src/utils/anthropic-status.js +51 -0
- package/dist/src/utils/api-key-store.d.ts +35 -0
- package/dist/src/utils/api-key-store.js +176 -0
- package/dist/src/utils/bash.d.ts +2 -0
- package/dist/src/utils/bash.js +53 -0
- package/dist/src/utils/custom-headers.d.ts +9 -0
- package/dist/src/utils/custom-headers.js +23 -0
- package/dist/src/utils/debug.d.ts +23 -0
- package/dist/src/utils/debug.js +86 -0
- package/dist/src/utils/environment.d.ts +4 -0
- package/dist/src/utils/environment.js +76 -0
- package/dist/src/utils/file-utils.d.ts +2 -0
- package/dist/src/utils/file-utils.js +16 -0
- package/dist/src/utils/get-api-key.d.ts +17 -0
- package/dist/src/utils/get-api-key.js +50 -0
- package/dist/src/utils/logging.d.ts +9 -0
- package/dist/src/utils/logging.js +48 -0
- package/dist/src/utils/oauth.d.ts +53 -0
- package/dist/src/utils/oauth.js +354 -0
- package/dist/src/utils/package-json.d.ts +25 -0
- package/dist/src/utils/package-json.js +26 -0
- package/dist/src/utils/package-manager.d.ts +21 -0
- package/dist/src/utils/package-manager.js +208 -0
- package/dist/src/utils/semver.d.ts +21 -0
- package/dist/src/utils/semver.js +61 -0
- package/dist/src/utils/setup-utils.d.ts +82 -0
- package/dist/src/utils/setup-utils.js +467 -0
- package/dist/src/utils/shell-completions.d.ts +10 -0
- package/dist/src/utils/shell-completions.js +199 -0
- package/dist/src/utils/string.d.ts +1 -0
- package/dist/src/utils/string.js +8 -0
- package/dist/src/utils/types.d.ts +72 -0
- package/dist/src/utils/types.js +2 -0
- package/dist/src/utils/urls.d.ts +14 -0
- package/dist/src/utils/urls.js +69 -0
- package/dist/src/utils/vendor/is-unicorn-supported.d.ts +1 -0
- package/dist/src/utils/vendor/is-unicorn-supported.js +23 -0
- package/dist/src/utils/wizard-abort.d.ts +13 -0
- package/dist/src/utils/wizard-abort.js +56 -0
- package/man/amplitude-wizard.1 +170 -0
- 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 {};
|