@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,499 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Unified in-process MCP server for the Amplitude wizard.
|
|
4
|
+
*
|
|
5
|
+
* Provides tools that run locally (secret values never leave the machine):
|
|
6
|
+
* - check_env_keys: Check which env var keys exist in a .env file
|
|
7
|
+
* - set_env_values: Create/update env vars in a .env file
|
|
8
|
+
* - detect_package_manager: Detect the project's package manager(s)
|
|
9
|
+
*/
|
|
10
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
11
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
12
|
+
};
|
|
13
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
14
|
+
exports.WIZARD_TOOL_NAMES = void 0;
|
|
15
|
+
exports.fetchSkillMenu = fetchSkillMenu;
|
|
16
|
+
exports.downloadSkill = downloadSkill;
|
|
17
|
+
exports.loadBundledSkillMenu = loadBundledSkillMenu;
|
|
18
|
+
exports.installBundledSkill = installBundledSkill;
|
|
19
|
+
exports.resolveEnvPath = resolveEnvPath;
|
|
20
|
+
exports.ensureGitignoreCoverage = ensureGitignoreCoverage;
|
|
21
|
+
exports.parseEnvKeys = parseEnvKeys;
|
|
22
|
+
exports.mergeEnvValues = mergeEnvValues;
|
|
23
|
+
exports.createWizardToolsServer = createWizardToolsServer;
|
|
24
|
+
const path_1 = __importDefault(require("path"));
|
|
25
|
+
const fs_1 = __importDefault(require("fs"));
|
|
26
|
+
const zod_1 = require("zod");
|
|
27
|
+
const debug_1 = require("../utils/debug");
|
|
28
|
+
const ui_1 = require("../ui");
|
|
29
|
+
// ---------------------------------------------------------------------------
|
|
30
|
+
// Remote skill helpers — for future use with amplitude/context-hub releases.
|
|
31
|
+
// Currently unused; skills are bundled locally. Enable by setting SKILLS_URL
|
|
32
|
+
// env var (e.g. https://github.com/amplitude/context-hub/releases/latest/download).
|
|
33
|
+
// ---------------------------------------------------------------------------
|
|
34
|
+
/**
|
|
35
|
+
* Fetch the skill menu from a remote skills server (GitHub Releases).
|
|
36
|
+
* Returns parsed data on success, `null` on failure.
|
|
37
|
+
*/
|
|
38
|
+
async function fetchSkillMenu(skillsBaseUrl) {
|
|
39
|
+
try {
|
|
40
|
+
const menuUrl = `${skillsBaseUrl}/skill-menu.json`;
|
|
41
|
+
(0, debug_1.logToFile)(`fetchSkillMenu: fetching from ${menuUrl}`);
|
|
42
|
+
const resp = await fetch(menuUrl);
|
|
43
|
+
if (resp.ok) {
|
|
44
|
+
const data = (await resp.json());
|
|
45
|
+
(0, debug_1.logToFile)(`fetchSkillMenu: loaded (${Object.keys(data.categories).length} categories)`);
|
|
46
|
+
return data;
|
|
47
|
+
}
|
|
48
|
+
(0, debug_1.logToFile)(`fetchSkillMenu: failed with HTTP ${resp.status}`);
|
|
49
|
+
return null;
|
|
50
|
+
}
|
|
51
|
+
catch (err) {
|
|
52
|
+
(0, debug_1.logToFile)(`fetchSkillMenu: error: ${err instanceof Error ? err.message : String(err)}`);
|
|
53
|
+
return null;
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
/**
|
|
57
|
+
* Download and extract a skill from a remote URL.
|
|
58
|
+
* Installs to `<installDir>/.claude/skills/<id>/`.
|
|
59
|
+
*/
|
|
60
|
+
function downloadSkill(skillEntry, installDir) {
|
|
61
|
+
const { execFileSync } = require('child_process');
|
|
62
|
+
const skillDir = path_1.default.join(installDir, '.claude', 'skills', skillEntry.id);
|
|
63
|
+
const tmpFile = `/tmp/amplitude-skill-${skillEntry.id}.zip`;
|
|
64
|
+
try {
|
|
65
|
+
fs_1.default.mkdirSync(skillDir, { recursive: true });
|
|
66
|
+
execFileSync('curl', ['-sL', skillEntry.downloadUrl, '-o', tmpFile], {
|
|
67
|
+
timeout: 30000,
|
|
68
|
+
});
|
|
69
|
+
execFileSync('unzip', ['-o', tmpFile, '-d', skillDir], {
|
|
70
|
+
timeout: 30000,
|
|
71
|
+
});
|
|
72
|
+
try {
|
|
73
|
+
fs_1.default.unlinkSync(tmpFile);
|
|
74
|
+
}
|
|
75
|
+
catch {
|
|
76
|
+
/* ignore cleanup errors */
|
|
77
|
+
}
|
|
78
|
+
(0, debug_1.logToFile)(`downloadSkill: installed ${skillEntry.id} from ${skillEntry.downloadUrl}`);
|
|
79
|
+
return { success: true };
|
|
80
|
+
}
|
|
81
|
+
catch (err) {
|
|
82
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
83
|
+
(0, debug_1.logToFile)(`downloadSkill: error: ${msg}`);
|
|
84
|
+
return { success: false, error: msg };
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
// ---------------------------------------------------------------------------
|
|
88
|
+
// Bundled skill helpers — reads skills from wizard/skills/integration/
|
|
89
|
+
// ---------------------------------------------------------------------------
|
|
90
|
+
/**
|
|
91
|
+
* Resolve the bundled skills root directory.
|
|
92
|
+
* Skills are shipped in `<wizardRoot>/skills/<category>/` subdirectories.
|
|
93
|
+
*/
|
|
94
|
+
function getSkillsRootDir() {
|
|
95
|
+
// Walk up from this file to find the wizard repo root (where skills/ lives)
|
|
96
|
+
let dir = __dirname;
|
|
97
|
+
for (let i = 0; i < 5; i++) {
|
|
98
|
+
if (fs_1.default.existsSync(path_1.default.join(dir, 'skills'))) {
|
|
99
|
+
return path_1.default.join(dir, 'skills');
|
|
100
|
+
}
|
|
101
|
+
dir = path_1.default.dirname(dir);
|
|
102
|
+
}
|
|
103
|
+
// Fallback: relative to cwd
|
|
104
|
+
return path_1.default.join(process.cwd(), 'skills');
|
|
105
|
+
}
|
|
106
|
+
/**
|
|
107
|
+
* Build skill menu from bundled skill directories.
|
|
108
|
+
* Scans skills/<category>/ subdirectories for folders containing SKILL.md.
|
|
109
|
+
* Each subdirectory of skills/ becomes a category (e.g. integration, instrumentation).
|
|
110
|
+
*/
|
|
111
|
+
function loadBundledSkillMenu() {
|
|
112
|
+
const skillsRoot = getSkillsRootDir();
|
|
113
|
+
(0, debug_1.logToFile)(`loadBundledSkillMenu: scanning ${skillsRoot}`);
|
|
114
|
+
const categories = {};
|
|
115
|
+
try {
|
|
116
|
+
for (const category of fs_1.default.readdirSync(skillsRoot)) {
|
|
117
|
+
const categoryPath = path_1.default.join(skillsRoot, category);
|
|
118
|
+
if (!fs_1.default.statSync(categoryPath).isDirectory())
|
|
119
|
+
continue;
|
|
120
|
+
const entries = [];
|
|
121
|
+
for (const name of fs_1.default.readdirSync(categoryPath)) {
|
|
122
|
+
const skillPath = path_1.default.join(categoryPath, name);
|
|
123
|
+
const skillMd = path_1.default.join(skillPath, 'SKILL.md');
|
|
124
|
+
if (fs_1.default.statSync(skillPath).isDirectory() && fs_1.default.existsSync(skillMd)) {
|
|
125
|
+
// Extract display name from SKILL.md frontmatter
|
|
126
|
+
const content = fs_1.default.readFileSync(skillMd, 'utf8');
|
|
127
|
+
const descMatch = content.match(/^description:\s*>-?\s*\n\s+(.+)/m);
|
|
128
|
+
const fallbackName = name
|
|
129
|
+
.replace(new RegExp(`^${category}-`), '')
|
|
130
|
+
.replace(/-/g, ' ');
|
|
131
|
+
const displayName = descMatch ? descMatch[1].trim() : fallbackName;
|
|
132
|
+
entries.push({ id: name, name: displayName, downloadUrl: '' });
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
if (entries.length > 0) {
|
|
136
|
+
categories[category] = entries;
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
catch (err) {
|
|
141
|
+
(0, debug_1.logToFile)(`loadBundledSkillMenu: error scanning: ${err instanceof Error ? err.message : String(err)}`);
|
|
142
|
+
}
|
|
143
|
+
const total = Object.values(categories).reduce((sum, entries) => sum + entries.length, 0);
|
|
144
|
+
(0, debug_1.logToFile)(`loadBundledSkillMenu: found ${total} skills across ${Object.keys(categories).length} categories`);
|
|
145
|
+
return { categories };
|
|
146
|
+
}
|
|
147
|
+
/**
|
|
148
|
+
* Install a bundled skill by copying it to the project's .claude/skills/ dir.
|
|
149
|
+
* Searches across all category subdirectories under skills/.
|
|
150
|
+
*/
|
|
151
|
+
function installBundledSkill(skillId, installDir) {
|
|
152
|
+
const skillsRoot = getSkillsRootDir();
|
|
153
|
+
const dest = path_1.default.join(installDir, '.claude', 'skills', skillId);
|
|
154
|
+
try {
|
|
155
|
+
for (const category of fs_1.default.readdirSync(skillsRoot)) {
|
|
156
|
+
const src = path_1.default.join(skillsRoot, category, skillId);
|
|
157
|
+
if (fs_1.default.existsSync(src) && fs_1.default.statSync(src).isDirectory()) {
|
|
158
|
+
fs_1.default.cpSync(src, dest, { recursive: true });
|
|
159
|
+
(0, debug_1.logToFile)(`installBundledSkill: copied ${skillId} from ${src} to ${dest}`);
|
|
160
|
+
return { success: true };
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
catch (err) {
|
|
165
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
166
|
+
(0, debug_1.logToFile)(`installBundledSkill: error: ${msg}`);
|
|
167
|
+
return { success: false, error: msg };
|
|
168
|
+
}
|
|
169
|
+
return { success: false, error: `Bundled skill "${skillId}" not found` };
|
|
170
|
+
}
|
|
171
|
+
let _sdkModule = null;
|
|
172
|
+
async function getSDKModule() {
|
|
173
|
+
if (!_sdkModule) {
|
|
174
|
+
_sdkModule = (await import('@anthropic-ai/claude-agent-sdk'));
|
|
175
|
+
}
|
|
176
|
+
return _sdkModule;
|
|
177
|
+
}
|
|
178
|
+
// ---------------------------------------------------------------------------
|
|
179
|
+
// Env file helpers
|
|
180
|
+
// ---------------------------------------------------------------------------
|
|
181
|
+
/**
|
|
182
|
+
* Resolve filePath relative to workingDirectory, rejecting path traversal.
|
|
183
|
+
*/
|
|
184
|
+
function resolveEnvPath(workingDirectory, filePath) {
|
|
185
|
+
const resolved = path_1.default.resolve(workingDirectory, filePath);
|
|
186
|
+
if (!resolved.startsWith(workingDirectory + path_1.default.sep) &&
|
|
187
|
+
resolved !== workingDirectory) {
|
|
188
|
+
throw new Error(`Path traversal rejected: "${filePath}" resolves outside working directory`);
|
|
189
|
+
}
|
|
190
|
+
return resolved;
|
|
191
|
+
}
|
|
192
|
+
/**
|
|
193
|
+
* Ensure the given env file basename is covered by .gitignore in the working directory.
|
|
194
|
+
* Creates .gitignore if it doesn't exist; appends the entry if missing.
|
|
195
|
+
*/
|
|
196
|
+
function ensureGitignoreCoverage(workingDirectory, envFileName) {
|
|
197
|
+
const gitignorePath = path_1.default.join(workingDirectory, '.gitignore');
|
|
198
|
+
if (fs_1.default.existsSync(gitignorePath)) {
|
|
199
|
+
const content = fs_1.default.readFileSync(gitignorePath, 'utf8');
|
|
200
|
+
// Check if the file (or a glob covering it) is already listed
|
|
201
|
+
if (content.split('\n').some((line) => line.trim() === envFileName)) {
|
|
202
|
+
return;
|
|
203
|
+
}
|
|
204
|
+
const newContent = content.endsWith('\n')
|
|
205
|
+
? `${content}${envFileName}\n`
|
|
206
|
+
: `${content}\n${envFileName}\n`;
|
|
207
|
+
fs_1.default.writeFileSync(gitignorePath, newContent, 'utf8');
|
|
208
|
+
}
|
|
209
|
+
else {
|
|
210
|
+
fs_1.default.writeFileSync(gitignorePath, `${envFileName}\n`, 'utf8');
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
/**
|
|
214
|
+
* Parse a .env file's content and return the set of defined key names.
|
|
215
|
+
*/
|
|
216
|
+
function parseEnvKeys(content) {
|
|
217
|
+
const keys = new Set();
|
|
218
|
+
for (const line of content.split('\n')) {
|
|
219
|
+
const match = line.match(/^\s*([A-Za-z_][A-Za-z0-9_]*)\s*=/);
|
|
220
|
+
if (match) {
|
|
221
|
+
keys.add(match[1]);
|
|
222
|
+
}
|
|
223
|
+
}
|
|
224
|
+
return keys;
|
|
225
|
+
}
|
|
226
|
+
/**
|
|
227
|
+
* Merge key-value pairs into existing .env content.
|
|
228
|
+
* Updates existing keys in-place, appends new keys at the end.
|
|
229
|
+
*/
|
|
230
|
+
function mergeEnvValues(content, values) {
|
|
231
|
+
let result = content;
|
|
232
|
+
const updatedKeys = new Set();
|
|
233
|
+
for (const [key, value] of Object.entries(values)) {
|
|
234
|
+
const regex = new RegExp(`^(\\s*${key}\\s*=).*$`, 'm');
|
|
235
|
+
if (regex.test(result)) {
|
|
236
|
+
result = result.replace(regex, `$1${value}`);
|
|
237
|
+
updatedKeys.add(key);
|
|
238
|
+
}
|
|
239
|
+
}
|
|
240
|
+
const newKeys = Object.entries(values).filter(([key]) => !updatedKeys.has(key));
|
|
241
|
+
if (newKeys.length > 0) {
|
|
242
|
+
if (result.length > 0 && !result.endsWith('\n')) {
|
|
243
|
+
result += '\n';
|
|
244
|
+
}
|
|
245
|
+
for (const [key, value] of newKeys) {
|
|
246
|
+
result += `${key}=${value}\n`;
|
|
247
|
+
}
|
|
248
|
+
}
|
|
249
|
+
return result;
|
|
250
|
+
}
|
|
251
|
+
// ---------------------------------------------------------------------------
|
|
252
|
+
// Server factory
|
|
253
|
+
// ---------------------------------------------------------------------------
|
|
254
|
+
const SERVER_NAME = 'wizard-tools';
|
|
255
|
+
/**
|
|
256
|
+
* Create the unified in-process MCP server with all wizard tools.
|
|
257
|
+
* Must be called asynchronously because the SDK is an ESM module loaded via dynamic import.
|
|
258
|
+
*/
|
|
259
|
+
async function createWizardToolsServer(options) {
|
|
260
|
+
const { workingDirectory, detectPackageManager, skillsBaseUrl } = options;
|
|
261
|
+
const { tool, createSdkMcpServer } = await getSDKModule();
|
|
262
|
+
// Load skill menu: try remote first, fall back to bundled
|
|
263
|
+
const menu = skillsBaseUrl
|
|
264
|
+
? (await fetchSkillMenu(skillsBaseUrl)) ?? loadBundledSkillMenu()
|
|
265
|
+
: loadBundledSkillMenu();
|
|
266
|
+
const cachedSkillMenu = menu?.categories ?? {};
|
|
267
|
+
const keys = Object.keys(cachedSkillMenu);
|
|
268
|
+
const categoryNames = keys.length > 0 ? keys : ['integration'];
|
|
269
|
+
// -- check_env_keys -------------------------------------------------------
|
|
270
|
+
const checkEnvKeys = tool('check_env_keys', 'Check which environment variable keys are present or missing in a .env file. Never reveals values.', {
|
|
271
|
+
filePath: zod_1.z
|
|
272
|
+
.string()
|
|
273
|
+
.describe('Path to the .env file, relative to the project root'),
|
|
274
|
+
keys: zod_1.z
|
|
275
|
+
.array(zod_1.z.string())
|
|
276
|
+
.describe('Environment variable key names to check'),
|
|
277
|
+
}, (args) => {
|
|
278
|
+
const resolved = resolveEnvPath(workingDirectory, args.filePath);
|
|
279
|
+
(0, debug_1.logToFile)(`check_env_keys: ${resolved}, keys: ${args.keys.join(', ')}`);
|
|
280
|
+
const existingKeys = fs_1.default.existsSync(resolved)
|
|
281
|
+
? parseEnvKeys(fs_1.default.readFileSync(resolved, 'utf8'))
|
|
282
|
+
: new Set();
|
|
283
|
+
const results = {};
|
|
284
|
+
for (const key of args.keys) {
|
|
285
|
+
results[key] = existingKeys.has(key) ? 'present' : 'missing';
|
|
286
|
+
}
|
|
287
|
+
return {
|
|
288
|
+
content: [
|
|
289
|
+
{ type: 'text', text: JSON.stringify(results, null, 2) },
|
|
290
|
+
],
|
|
291
|
+
};
|
|
292
|
+
});
|
|
293
|
+
// -- set_env_values -------------------------------------------------------
|
|
294
|
+
const setEnvValues = tool('set_env_values', 'Create or update environment variable keys in a .env file. Creates the file if it does not exist. Ensures .gitignore coverage.', {
|
|
295
|
+
filePath: zod_1.z
|
|
296
|
+
.string()
|
|
297
|
+
.describe('Path to the .env file, relative to the project root'),
|
|
298
|
+
values: zod_1.z
|
|
299
|
+
.record(zod_1.z.string(), zod_1.z.string())
|
|
300
|
+
.describe('Key-value pairs to set'),
|
|
301
|
+
}, (args) => {
|
|
302
|
+
const resolved = resolveEnvPath(workingDirectory, args.filePath);
|
|
303
|
+
(0, debug_1.logToFile)(`set_env_values: ${resolved}, keys: ${Object.keys(args.values).join(', ')}`);
|
|
304
|
+
const existing = fs_1.default.existsSync(resolved)
|
|
305
|
+
? fs_1.default.readFileSync(resolved, 'utf8')
|
|
306
|
+
: '';
|
|
307
|
+
const content = mergeEnvValues(existing, args.values);
|
|
308
|
+
// Ensure parent directory exists
|
|
309
|
+
const dir = path_1.default.dirname(resolved);
|
|
310
|
+
if (!fs_1.default.existsSync(dir)) {
|
|
311
|
+
fs_1.default.mkdirSync(dir, { recursive: true });
|
|
312
|
+
}
|
|
313
|
+
fs_1.default.writeFileSync(resolved, content, 'utf8');
|
|
314
|
+
// Ensure .gitignore coverage for this env file
|
|
315
|
+
const envFileName = path_1.default.basename(resolved);
|
|
316
|
+
ensureGitignoreCoverage(workingDirectory, envFileName);
|
|
317
|
+
return {
|
|
318
|
+
content: [
|
|
319
|
+
{
|
|
320
|
+
type: 'text',
|
|
321
|
+
text: `Updated ${Object.keys(args.values).length} key(s) in ${args.filePath}`,
|
|
322
|
+
},
|
|
323
|
+
],
|
|
324
|
+
};
|
|
325
|
+
});
|
|
326
|
+
// -- detect_package_manager -----------------------------------------------
|
|
327
|
+
const detectPM = tool('detect_package_manager', 'Detect which package manager(s) the project uses. Returns the name, install command, and run command for each detected package manager. Call this before running any install commands.', {}, async () => {
|
|
328
|
+
(0, debug_1.logToFile)(`detect_package_manager: scanning ${workingDirectory}`);
|
|
329
|
+
const result = await detectPackageManager(workingDirectory);
|
|
330
|
+
(0, debug_1.logToFile)(`detect_package_manager: detected ${result.detected.length} package manager(s)`);
|
|
331
|
+
return {
|
|
332
|
+
content: [
|
|
333
|
+
{
|
|
334
|
+
type: 'text',
|
|
335
|
+
text: JSON.stringify(result, null, 2),
|
|
336
|
+
},
|
|
337
|
+
],
|
|
338
|
+
};
|
|
339
|
+
});
|
|
340
|
+
// -- load_skill_menu ------------------------------------------------------
|
|
341
|
+
const loadSkillMenu = tool('load_skill_menu', 'Load available Amplitude skills for a category. Returns skill IDs and names. Call this first, then use install_skill with the chosen ID.', {
|
|
342
|
+
category: zod_1.z.enum(categoryNames).describe('Skill category'),
|
|
343
|
+
}, (args) => {
|
|
344
|
+
const skills = cachedSkillMenu[args.category];
|
|
345
|
+
if (!skills || skills.length === 0) {
|
|
346
|
+
return {
|
|
347
|
+
content: [
|
|
348
|
+
{
|
|
349
|
+
type: 'text',
|
|
350
|
+
text: `No skills found for category "${args.category}".`,
|
|
351
|
+
},
|
|
352
|
+
],
|
|
353
|
+
isError: true,
|
|
354
|
+
};
|
|
355
|
+
}
|
|
356
|
+
const menuText = skills.map((s) => `- ${s.id}: ${s.name}`).join('\n');
|
|
357
|
+
(0, debug_1.logToFile)(`load_skill_menu: returning ${skills.length} skills for "${args.category}"`);
|
|
358
|
+
return {
|
|
359
|
+
content: [{ type: 'text', text: menuText }],
|
|
360
|
+
};
|
|
361
|
+
});
|
|
362
|
+
// -- install_skill --------------------------------------------------------
|
|
363
|
+
const installSkill = tool('install_skill', 'Download and install an Amplitude skill by ID. Call load_skill_menu first to see available skills. Extracts the skill to .claude/skills/<skillId>/.', {
|
|
364
|
+
skillId: zod_1.z
|
|
365
|
+
.string()
|
|
366
|
+
.describe('Skill ID from the skill menu (e.g., "integration-nextjs-app-router")'),
|
|
367
|
+
}, (args) => {
|
|
368
|
+
if (!/^[a-z0-9][a-z0-9_-]*$/.test(args.skillId)) {
|
|
369
|
+
return {
|
|
370
|
+
content: [
|
|
371
|
+
{
|
|
372
|
+
type: 'text',
|
|
373
|
+
text: 'Error: skillId must be lowercase alphanumeric with hyphens.',
|
|
374
|
+
},
|
|
375
|
+
],
|
|
376
|
+
isError: true,
|
|
377
|
+
};
|
|
378
|
+
}
|
|
379
|
+
// Look up download URL from cached menu
|
|
380
|
+
const allSkills = Object.values(cachedSkillMenu).flat();
|
|
381
|
+
const skill = allSkills.find((s) => s.id === args.skillId);
|
|
382
|
+
if (!skill) {
|
|
383
|
+
return {
|
|
384
|
+
content: [
|
|
385
|
+
{
|
|
386
|
+
type: 'text',
|
|
387
|
+
text: `Error: skill "${args.skillId}" not found. Use load_skill_menu to see available skills.`,
|
|
388
|
+
},
|
|
389
|
+
],
|
|
390
|
+
isError: true,
|
|
391
|
+
};
|
|
392
|
+
}
|
|
393
|
+
// Try remote download if URL available, otherwise use bundled copy
|
|
394
|
+
const result = skill.downloadUrl
|
|
395
|
+
? downloadSkill(skill, workingDirectory)
|
|
396
|
+
: installBundledSkill(args.skillId, workingDirectory);
|
|
397
|
+
if (result.success) {
|
|
398
|
+
return {
|
|
399
|
+
content: [
|
|
400
|
+
{
|
|
401
|
+
type: 'text',
|
|
402
|
+
text: `Skill installed to .claude/skills/${args.skillId}/`,
|
|
403
|
+
},
|
|
404
|
+
],
|
|
405
|
+
};
|
|
406
|
+
}
|
|
407
|
+
else {
|
|
408
|
+
return {
|
|
409
|
+
content: [
|
|
410
|
+
{
|
|
411
|
+
type: 'text',
|
|
412
|
+
text: `Error installing skill: ${result.error}`,
|
|
413
|
+
},
|
|
414
|
+
],
|
|
415
|
+
isError: true,
|
|
416
|
+
};
|
|
417
|
+
}
|
|
418
|
+
});
|
|
419
|
+
// -- confirm --------------------------------------------------------------
|
|
420
|
+
const confirm = tool('confirm', 'Ask the user a yes/no question and wait for their answer. Returns true if confirmed, false if declined or skipped.', {
|
|
421
|
+
message: zod_1.z
|
|
422
|
+
.string()
|
|
423
|
+
.describe('The confirmation question to show the user'),
|
|
424
|
+
}, async (args) => {
|
|
425
|
+
(0, debug_1.logToFile)(`confirm: ${args.message}`);
|
|
426
|
+
const answer = await (0, ui_1.getUI)().promptConfirm(args.message);
|
|
427
|
+
return {
|
|
428
|
+
content: [{ type: 'text', text: answer ? 'true' : 'false' }],
|
|
429
|
+
};
|
|
430
|
+
});
|
|
431
|
+
// -- choose ---------------------------------------------------------------
|
|
432
|
+
const choose = tool('choose', 'Present the user with a list of options and wait for their selection. Returns the chosen option, or an empty string if skipped.', {
|
|
433
|
+
message: zod_1.z.string().describe('The prompt to show above the options'),
|
|
434
|
+
options: zod_1.z
|
|
435
|
+
.array(zod_1.z.string())
|
|
436
|
+
.min(2)
|
|
437
|
+
.describe('The list of choices to present'),
|
|
438
|
+
}, async (args) => {
|
|
439
|
+
(0, debug_1.logToFile)(`choose: ${args.message}, options: ${args.options.join(', ')}`);
|
|
440
|
+
const answer = await (0, ui_1.getUI)().promptChoice(args.message, args.options);
|
|
441
|
+
return {
|
|
442
|
+
content: [{ type: 'text', text: answer }],
|
|
443
|
+
};
|
|
444
|
+
});
|
|
445
|
+
// -- confirm_event_plan ---------------------------------------------------
|
|
446
|
+
const confirmEventPlan = tool('confirm_event_plan', `Present the proposed instrumentation plan to the user for review BEFORE instrumenting any events.
|
|
447
|
+
Call this tool AFTER installing the SDK and adding initialization code, but BEFORE writing any track() calls.
|
|
448
|
+
The user can approve the plan, skip the review, or give feedback.
|
|
449
|
+
If the user gives feedback, revise your plan and call this tool again — loop until approved or skipped.
|
|
450
|
+
Returns: "approved", "skipped", or "feedback: <user message>"`, {
|
|
451
|
+
events: zod_1.z
|
|
452
|
+
.array(zod_1.z.object({
|
|
453
|
+
name: zod_1.z.string().describe('Event name, e.g. "Button Clicked"'),
|
|
454
|
+
description: zod_1.z
|
|
455
|
+
.string()
|
|
456
|
+
.describe('When this event fires and what it tracks'),
|
|
457
|
+
}))
|
|
458
|
+
.min(1)
|
|
459
|
+
.describe('The list of events you plan to instrument'),
|
|
460
|
+
}, async (args) => {
|
|
461
|
+
(0, debug_1.logToFile)(`confirm_event_plan: ${args.events.length} events`);
|
|
462
|
+
const decision = await (0, ui_1.getUI)().promptEventPlan(args.events);
|
|
463
|
+
let text;
|
|
464
|
+
if (decision.decision === 'revised') {
|
|
465
|
+
text = `feedback: ${decision.feedback}`;
|
|
466
|
+
}
|
|
467
|
+
else {
|
|
468
|
+
text = decision.decision; // 'approved' or 'skipped'
|
|
469
|
+
}
|
|
470
|
+
(0, debug_1.logToFile)(`confirm_event_plan result: ${text}`);
|
|
471
|
+
return { content: [{ type: 'text', text }] };
|
|
472
|
+
});
|
|
473
|
+
// -- Assemble server ------------------------------------------------------
|
|
474
|
+
return createSdkMcpServer({
|
|
475
|
+
name: SERVER_NAME,
|
|
476
|
+
version: '1.0.0',
|
|
477
|
+
tools: [
|
|
478
|
+
checkEnvKeys,
|
|
479
|
+
setEnvValues,
|
|
480
|
+
detectPM,
|
|
481
|
+
loadSkillMenu,
|
|
482
|
+
installSkill,
|
|
483
|
+
confirm,
|
|
484
|
+
choose,
|
|
485
|
+
confirmEventPlan,
|
|
486
|
+
],
|
|
487
|
+
});
|
|
488
|
+
}
|
|
489
|
+
/** Tool names exposed by the wizard-tools server, for use in allowedTools */
|
|
490
|
+
exports.WIZARD_TOOL_NAMES = [
|
|
491
|
+
`${SERVER_NAME}:check_env_keys`,
|
|
492
|
+
`${SERVER_NAME}:set_env_values`,
|
|
493
|
+
`${SERVER_NAME}:detect_package_manager`,
|
|
494
|
+
`${SERVER_NAME}:load_skill_menu`,
|
|
495
|
+
`${SERVER_NAME}:install_skill`,
|
|
496
|
+
`${SERVER_NAME}:confirm`,
|
|
497
|
+
`${SERVER_NAME}:choose`,
|
|
498
|
+
`${SERVER_NAME}:confirm_event_plan`,
|
|
499
|
+
];
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { type WizardSession } from './lib/wizard-session';
|
|
2
|
+
import { Integration } from './lib/constants';
|
|
3
|
+
type Args = {
|
|
4
|
+
integration?: Integration;
|
|
5
|
+
debug?: boolean;
|
|
6
|
+
forceInstall?: boolean;
|
|
7
|
+
installDir?: string;
|
|
8
|
+
default?: boolean;
|
|
9
|
+
signup?: boolean;
|
|
10
|
+
localMcp?: boolean;
|
|
11
|
+
ci?: boolean;
|
|
12
|
+
apiKey?: string;
|
|
13
|
+
projectId?: string;
|
|
14
|
+
menu?: boolean;
|
|
15
|
+
benchmark?: boolean;
|
|
16
|
+
};
|
|
17
|
+
export declare function runWizard(argv: Args, session?: WizardSession): Promise<void>;
|
|
18
|
+
export declare function detectIntegration(installDir: string): Promise<Integration | undefined>;
|
|
19
|
+
export {};
|
package/dist/src/run.js
ADDED
|
@@ -0,0 +1,151 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.runWizard = runWizard;
|
|
7
|
+
exports.detectIntegration = detectIntegration;
|
|
8
|
+
const wizard_session_1 = require("./lib/wizard-session");
|
|
9
|
+
const constants_1 = require("./lib/constants");
|
|
10
|
+
const environment_1 = require("./utils/environment");
|
|
11
|
+
const ui_1 = require("./ui");
|
|
12
|
+
const path_1 = __importDefault(require("path"));
|
|
13
|
+
const registry_1 = require("./lib/registry");
|
|
14
|
+
const analytics_1 = require("./utils/analytics");
|
|
15
|
+
const agent_runner_1 = require("./lib/agent-runner");
|
|
16
|
+
const events_1 = require("events");
|
|
17
|
+
const chalk_1 = __importDefault(require("chalk"));
|
|
18
|
+
const debug_1 = require("./utils/debug");
|
|
19
|
+
const wizard_abort_1 = require("./utils/wizard-abort");
|
|
20
|
+
events_1.EventEmitter.defaultMaxListeners = 50;
|
|
21
|
+
async function runWizard(argv, session) {
|
|
22
|
+
const finalArgs = {
|
|
23
|
+
...argv,
|
|
24
|
+
...(0, environment_1.readEnvironment)(),
|
|
25
|
+
};
|
|
26
|
+
let resolvedInstallDir;
|
|
27
|
+
if (finalArgs.installDir) {
|
|
28
|
+
if (path_1.default.isAbsolute(finalArgs.installDir)) {
|
|
29
|
+
resolvedInstallDir = finalArgs.installDir;
|
|
30
|
+
}
|
|
31
|
+
else {
|
|
32
|
+
resolvedInstallDir = path_1.default.join(process.cwd(), finalArgs.installDir);
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
else {
|
|
36
|
+
resolvedInstallDir = process.cwd();
|
|
37
|
+
}
|
|
38
|
+
// Build session if not provided (CI mode passes one pre-built)
|
|
39
|
+
if (!session) {
|
|
40
|
+
session = (0, wizard_session_1.buildSession)({
|
|
41
|
+
debug: finalArgs.debug,
|
|
42
|
+
forceInstall: finalArgs.forceInstall,
|
|
43
|
+
installDir: resolvedInstallDir,
|
|
44
|
+
ci: finalArgs.ci,
|
|
45
|
+
signup: finalArgs.signup,
|
|
46
|
+
localMcp: finalArgs.localMcp,
|
|
47
|
+
apiKey: finalArgs.apiKey,
|
|
48
|
+
menu: finalArgs.menu,
|
|
49
|
+
integration: finalArgs.integration,
|
|
50
|
+
benchmark: finalArgs.benchmark,
|
|
51
|
+
projectId: finalArgs.projectId,
|
|
52
|
+
});
|
|
53
|
+
}
|
|
54
|
+
session.installDir = resolvedInstallDir;
|
|
55
|
+
(0, ui_1.getUI)().intro(`Welcome to the Amplitude setup wizard`);
|
|
56
|
+
if (session.ci) {
|
|
57
|
+
(0, ui_1.getUI)().log.info(chalk_1.default.dim('Running in CI mode'));
|
|
58
|
+
}
|
|
59
|
+
const integration = session.integration ?? (await detectAndResolveIntegration(session));
|
|
60
|
+
session.integration = integration;
|
|
61
|
+
analytics_1.analytics.setTag('integration', integration);
|
|
62
|
+
analytics_1.analytics.wizardCapture('session started', {
|
|
63
|
+
integration,
|
|
64
|
+
ci: session.ci ?? false,
|
|
65
|
+
});
|
|
66
|
+
const config = registry_1.FRAMEWORK_REGISTRY[integration];
|
|
67
|
+
session.frameworkConfig = config;
|
|
68
|
+
// Run gatherContext if the framework has it and it hasn't already run
|
|
69
|
+
// (bin.ts runs it early so IntroScreen can show the friendly label)
|
|
70
|
+
const contextAlreadyGathered = Object.keys(session.frameworkContext).length > 0;
|
|
71
|
+
if (config.metadata.gatherContext && !contextAlreadyGathered) {
|
|
72
|
+
try {
|
|
73
|
+
const context = await config.metadata.gatherContext({
|
|
74
|
+
installDir: session.installDir,
|
|
75
|
+
debug: session.debug,
|
|
76
|
+
forceInstall: session.forceInstall,
|
|
77
|
+
default: false,
|
|
78
|
+
signup: session.signup,
|
|
79
|
+
localMcp: session.localMcp,
|
|
80
|
+
ci: session.ci,
|
|
81
|
+
menu: session.menu,
|
|
82
|
+
benchmark: session.benchmark,
|
|
83
|
+
});
|
|
84
|
+
for (const [key, value] of Object.entries(context)) {
|
|
85
|
+
if (!(key in session.frameworkContext)) {
|
|
86
|
+
session.frameworkContext[key] = value;
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
catch {
|
|
91
|
+
// Detection failed — SetupScreen or agent will handle it
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
let retry = true;
|
|
95
|
+
while (retry) {
|
|
96
|
+
try {
|
|
97
|
+
await (0, agent_runner_1.runAgentWizard)(config, session);
|
|
98
|
+
retry = false;
|
|
99
|
+
}
|
|
100
|
+
catch (error) {
|
|
101
|
+
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
102
|
+
const errorStack = error instanceof Error && error.stack ? error.stack : undefined;
|
|
103
|
+
(0, debug_1.logToFile)(`[Wizard run.ts] ERROR MESSAGE: ${errorMessage} `);
|
|
104
|
+
if (errorStack) {
|
|
105
|
+
(0, debug_1.logToFile)(`[Wizard run.ts] ERROR STACK: ${errorStack}`);
|
|
106
|
+
}
|
|
107
|
+
const debugInfo = session.debug && errorStack ? `\n\n${errorStack}` : '';
|
|
108
|
+
retry = await (0, ui_1.getUI)().setRunError(error);
|
|
109
|
+
if (!retry) {
|
|
110
|
+
await (0, wizard_abort_1.wizardAbort)({
|
|
111
|
+
message: `Something went wrong: ${errorMessage}\n\nYou can read the documentation at ${config.metadata.docsUrl} to set up Amplitude manually.${debugInfo}`,
|
|
112
|
+
error: error,
|
|
113
|
+
});
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
async function detectIntegration(installDir) {
|
|
119
|
+
for (const integration of Object.values(constants_1.Integration)) {
|
|
120
|
+
const config = registry_1.FRAMEWORK_REGISTRY[integration];
|
|
121
|
+
try {
|
|
122
|
+
const detected = await Promise.race([
|
|
123
|
+
config.detection.detect({ installDir }),
|
|
124
|
+
new Promise((resolve) => setTimeout(() => resolve(false), constants_1.DETECTION_TIMEOUT_MS)),
|
|
125
|
+
]);
|
|
126
|
+
if (detected) {
|
|
127
|
+
return integration;
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
catch {
|
|
131
|
+
// Skip frameworks whose detection throws
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
async function detectAndResolveIntegration(session) {
|
|
136
|
+
if (!session.menu) {
|
|
137
|
+
const detectedIntegration = await detectIntegration(session.installDir);
|
|
138
|
+
if (detectedIntegration) {
|
|
139
|
+
(0, ui_1.getUI)().setDetectedFramework(registry_1.FRAMEWORK_REGISTRY[detectedIntegration].metadata.name);
|
|
140
|
+
return detectedIntegration;
|
|
141
|
+
}
|
|
142
|
+
// Framework not detected — fall back to generic Amplitude quickstart.
|
|
143
|
+
(0, ui_1.getUI)().log.warn("Couldn't detect your framework. Falling back to the Amplitude quickstart guide.");
|
|
144
|
+
return constants_1.Integration.generic;
|
|
145
|
+
}
|
|
146
|
+
// Fallback: in TUI mode the IntroScreen would handle this,
|
|
147
|
+
// but for CI mode or when detection fails, abort with guidance.
|
|
148
|
+
return (0, wizard_abort_1.wizardAbort)({
|
|
149
|
+
message: 'Could not auto-detect your framework. Please specify --integration on the command line.',
|
|
150
|
+
});
|
|
151
|
+
}
|