@amplitude/wizard 1.0.0-beta.2 → 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +171 -74
- package/dist/bin.js +338 -222
- package/dist/src/lib/agent-interface.js +64 -9
- package/dist/src/lib/agent-runner.js +1 -10
- package/dist/src/lib/api.d.ts +22 -4
- package/dist/src/lib/api.js +114 -12
- package/dist/src/lib/commandments.js +14 -1
- package/dist/src/lib/constants.d.ts +6 -5
- package/dist/src/lib/constants.js +13 -13
- package/dist/src/lib/credential-resolution.d.ts +45 -0
- package/dist/src/lib/credential-resolution.js +311 -0
- package/dist/src/lib/exit-codes.d.ts +10 -0
- package/dist/src/lib/exit-codes.js +12 -0
- package/dist/src/lib/health-checks/statuspage.d.ts +1 -0
- package/dist/src/lib/health-checks/statuspage.js +5 -1
- package/dist/src/lib/mode-config.d.ts +14 -0
- package/dist/src/lib/mode-config.js +14 -0
- package/dist/src/lib/session-checkpoint.d.ts +27 -0
- package/dist/src/lib/session-checkpoint.js +134 -0
- package/dist/src/lib/wizard-session.d.ts +44 -1
- package/dist/src/lib/wizard-session.js +70 -14
- package/dist/src/lib/wizard-tools.js +19 -4
- package/dist/src/steps/add-mcp-server-to-clients/clients/claude.d.ts +3 -0
- package/dist/src/steps/add-mcp-server-to-clients/clients/claude.js +6 -0
- package/dist/src/steps/add-mcp-server-to-clients/clients/cursor.js +3 -1
- package/dist/src/ui/agent-ui.d.ts +91 -0
- package/dist/src/ui/agent-ui.js +277 -0
- package/dist/src/ui/logging-ui.js +1 -1
- package/dist/src/ui/tui/App.d.ts +12 -0
- package/dist/src/ui/tui/App.js +29 -18
- package/dist/src/ui/tui/components/AmplitudeLogo.js +16 -17
- package/dist/src/ui/tui/components/AmplitudeTextLogo.d.ts +0 -2
- package/dist/src/ui/tui/components/AmplitudeTextLogo.js +53 -18
- package/dist/src/ui/tui/components/BrailleSpinner.d.ts +8 -0
- package/dist/src/ui/tui/components/BrailleSpinner.js +15 -0
- package/dist/src/ui/tui/components/ConsoleView.d.ts +8 -11
- package/dist/src/ui/tui/components/ConsoleView.js +51 -34
- package/dist/src/ui/tui/components/HeaderBar.d.ts +12 -0
- package/dist/src/ui/tui/components/HeaderBar.js +17 -0
- package/dist/src/ui/tui/components/JourneyStepper.d.ts +16 -0
- package/dist/src/ui/tui/components/JourneyStepper.js +83 -0
- package/dist/src/ui/tui/components/KeyHintBar.d.ts +19 -0
- package/dist/src/ui/tui/components/KeyHintBar.js +20 -0
- package/dist/src/ui/tui/console-commands.d.ts +1 -2
- package/dist/src/ui/tui/console-commands.js +48 -7
- package/dist/src/ui/tui/flows.d.ts +1 -1
- package/dist/src/ui/tui/flows.js +1 -1
- package/dist/src/ui/tui/hooks/useAsyncEffect.d.ts +15 -0
- package/dist/src/ui/tui/hooks/useAsyncEffect.js +35 -0
- package/dist/src/ui/tui/hooks/useWizardStore.d.ts +9 -0
- package/dist/src/ui/tui/hooks/useWizardStore.js +11 -0
- package/dist/src/ui/tui/ink-ui.js +1 -1
- package/dist/src/ui/tui/primitives/DissolveTransition.js +4 -5
- package/dist/src/ui/tui/primitives/EventPlanViewer.d.ts +3 -1
- package/dist/src/ui/tui/primitives/EventPlanViewer.js +8 -3
- package/dist/src/ui/tui/primitives/ProgressList.js +1 -1
- package/dist/src/ui/tui/primitives/SlashCommandInput.js +19 -4
- package/dist/src/ui/tui/primitives/SplitView.d.ts +2 -1
- package/dist/src/ui/tui/primitives/SplitView.js +10 -2
- package/dist/src/ui/tui/primitives/TabContainer.js +10 -2
- package/dist/src/ui/tui/primitives/index.d.ts +0 -1
- package/dist/src/ui/tui/primitives/index.js +0 -1
- package/dist/src/ui/tui/router.js +1 -1
- package/dist/src/ui/tui/screen-registry.d.ts +0 -7
- package/dist/src/ui/tui/screen-registry.js +13 -4
- package/dist/src/ui/tui/screens/ActivationOptionsScreen.d.ts +2 -2
- package/dist/src/ui/tui/screens/ActivationOptionsScreen.js +8 -8
- package/dist/src/ui/tui/screens/AuthScreen.js +57 -27
- package/dist/src/ui/tui/screens/ChecklistScreen.d.ts +2 -12
- package/dist/src/ui/tui/screens/ChecklistScreen.js +22 -33
- package/dist/src/ui/tui/screens/DataIngestionCheckScreen.d.ts +3 -12
- package/dist/src/ui/tui/screens/DataIngestionCheckScreen.js +109 -39
- package/dist/src/ui/tui/screens/DataSetupScreen.d.ts +3 -3
- package/dist/src/ui/tui/screens/DataSetupScreen.js +17 -10
- package/dist/src/ui/tui/screens/IntroScreen.d.ts +5 -3
- package/dist/src/ui/tui/screens/IntroScreen.js +132 -41
- package/dist/src/ui/tui/screens/LoginScreen.d.ts +1 -1
- package/dist/src/ui/tui/screens/LoginScreen.js +4 -4
- package/dist/src/ui/tui/screens/LogoutScreen.d.ts +4 -2
- package/dist/src/ui/tui/screens/LogoutScreen.js +17 -5
- package/dist/src/ui/tui/screens/McpScreen.d.ts +4 -4
- package/dist/src/ui/tui/screens/McpScreen.js +25 -17
- package/dist/src/ui/tui/screens/OutageScreen.d.ts +1 -1
- package/dist/src/ui/tui/screens/OutageScreen.js +5 -5
- package/dist/src/ui/tui/screens/OutroScreen.d.ts +5 -0
- package/dist/src/ui/tui/screens/OutroScreen.js +21 -14
- package/dist/src/ui/tui/screens/RegionSelectScreen.js +15 -13
- package/dist/src/ui/tui/screens/RunScreen.d.ts +7 -5
- package/dist/src/ui/tui/screens/RunScreen.js +102 -157
- package/dist/src/ui/tui/screens/SettingsOverrideScreen.d.ts +1 -1
- package/dist/src/ui/tui/screens/SettingsOverrideScreen.js +6 -5
- package/dist/src/ui/tui/screens/SetupScreen.d.ts +1 -1
- package/dist/src/ui/tui/screens/SetupScreen.js +7 -7
- package/dist/src/ui/tui/screens/SlackScreen.d.ts +2 -2
- package/dist/src/ui/tui/screens/SlackScreen.js +60 -35
- package/dist/src/ui/tui/session-constants.d.ts +41 -0
- package/dist/src/ui/tui/session-constants.js +38 -0
- package/dist/src/ui/tui/start-tui.d.ts +3 -1
- package/dist/src/ui/tui/start-tui.js +14 -10
- package/dist/src/ui/tui/store.d.ts +2 -1
- package/dist/src/ui/tui/store.js +33 -7
- package/dist/src/ui/tui/styles.d.ts +75 -19
- package/dist/src/ui/tui/styles.js +101 -19
- package/dist/src/ui/tui/utils/classify-error.d.ts +14 -0
- package/dist/src/ui/tui/utils/classify-error.js +90 -0
- package/dist/src/ui/tui/utils/diagnostics.d.ts +21 -0
- package/dist/src/ui/tui/utils/diagnostics.js +72 -0
- package/dist/src/ui/tui/utils/with-retry.d.ts +12 -0
- package/dist/src/ui/tui/utils/with-retry.js +32 -0
- package/dist/src/ui/tui/utils/with-timeout.d.ts +10 -0
- package/dist/src/ui/tui/utils/with-timeout.js +24 -0
- package/dist/src/utils/ampli-settings.d.ts +1 -1
- package/dist/src/utils/ampli-settings.js +15 -5
- package/dist/src/utils/api-key-store.js +5 -5
- package/dist/src/utils/atomic-write.d.ts +15 -0
- package/dist/src/utils/atomic-write.js +34 -0
- package/dist/src/utils/setup-utils.js +2 -2
- package/dist/src/utils/token-refresh.d.ts +22 -0
- package/dist/src/utils/token-refresh.js +79 -0
- package/dist/src/utils/wizard-abort.js +6 -1
- package/package.json +6 -6
- package/skills/instrumentation/add-analytics-instrumentation/SKILL.md +142 -0
- package/skills/instrumentation/diff-intake/SKILL.md +128 -0
- package/skills/instrumentation/discover-analytics-patterns/SKILL.md +185 -0
- package/skills/instrumentation/discover-event-surfaces/SKILL.md +322 -0
- package/skills/instrumentation/discover-event-surfaces/references/best-practices.md +563 -0
- package/skills/instrumentation/instrument-events/SKILL.md +169 -0
- package/skills/instrumentation/instrument-events/references/best-practices.md +563 -0
- package/skills/integration/integration-android/SKILL.md +49 -0
- package/skills/integration/integration-android/references/EXAMPLE.md +1977 -0
- package/skills/integration/integration-android/references/amplitude-quickstart.md +1845 -0
- package/skills/integration/integration-android/references/analytics.md +1778 -0
- package/skills/integration/integration-android/references/basic-integration-1.0-begin.md +43 -0
- package/skills/integration/integration-android/references/basic-integration-1.1-edit.md +35 -0
- package/skills/integration/integration-android/references/basic-integration-1.2-revise.md +23 -0
- package/skills/integration/integration-android/references/basic-integration-1.3-conclude.md +57 -0
- package/skills/integration/integration-angular/SKILL.md +49 -0
- package/skills/integration/integration-angular/references/EXAMPLE.md +899 -0
- package/skills/integration/integration-angular/references/amplitude-quickstart.md +1845 -0
- package/skills/integration/integration-angular/references/basic-integration-1.0-begin.md +43 -0
- package/skills/integration/integration-angular/references/basic-integration-1.1-edit.md +35 -0
- package/skills/integration/integration-angular/references/basic-integration-1.2-revise.md +23 -0
- package/skills/integration/integration-angular/references/basic-integration-1.3-conclude.md +57 -0
- package/skills/integration/integration-angular/references/browser-sdk-2.md +4680 -0
- package/skills/integration/integration-astro-hybrid/SKILL.md +56 -0
- package/skills/integration/integration-astro-hybrid/references/EXAMPLE.md +1095 -0
- package/skills/integration/integration-astro-hybrid/references/amplitude-quickstart.md +1845 -0
- package/skills/integration/integration-astro-hybrid/references/basic-integration-1.0-begin.md +43 -0
- package/skills/integration/integration-astro-hybrid/references/basic-integration-1.1-edit.md +35 -0
- package/skills/integration/integration-astro-hybrid/references/basic-integration-1.2-revise.md +23 -0
- package/skills/integration/integration-astro-hybrid/references/basic-integration-1.3-conclude.md +57 -0
- package/skills/integration/integration-astro-hybrid/references/browser-sdk-2.md +4680 -0
- package/skills/integration/integration-astro-ssr/SKILL.md +52 -0
- package/skills/integration/integration-astro-ssr/references/EXAMPLE.md +1106 -0
- package/skills/integration/integration-astro-ssr/references/amplitude-quickstart.md +1845 -0
- package/skills/integration/integration-astro-ssr/references/basic-integration-1.0-begin.md +43 -0
- package/skills/integration/integration-astro-ssr/references/basic-integration-1.1-edit.md +35 -0
- package/skills/integration/integration-astro-ssr/references/basic-integration-1.2-revise.md +23 -0
- package/skills/integration/integration-astro-ssr/references/basic-integration-1.3-conclude.md +57 -0
- package/skills/integration/integration-astro-ssr/references/browser-sdk-2.md +4680 -0
- package/skills/integration/integration-astro-static/SKILL.md +49 -0
- package/skills/integration/integration-astro-static/references/EXAMPLE.md +910 -0
- package/skills/integration/integration-astro-static/references/amplitude-quickstart.md +1845 -0
- package/skills/integration/integration-astro-static/references/basic-integration-1.0-begin.md +43 -0
- package/skills/integration/integration-astro-static/references/basic-integration-1.1-edit.md +35 -0
- package/skills/integration/integration-astro-static/references/basic-integration-1.2-revise.md +23 -0
- package/skills/integration/integration-astro-static/references/basic-integration-1.3-conclude.md +57 -0
- package/skills/integration/integration-astro-static/references/browser-sdk-2.md +4680 -0
- package/skills/integration/integration-astro-view-transitions/SKILL.md +51 -0
- package/skills/integration/integration-astro-view-transitions/references/EXAMPLE.md +979 -0
- package/skills/integration/integration-astro-view-transitions/references/amplitude-quickstart.md +1845 -0
- package/skills/integration/integration-astro-view-transitions/references/basic-integration-1.0-begin.md +43 -0
- package/skills/integration/integration-astro-view-transitions/references/basic-integration-1.1-edit.md +35 -0
- package/skills/integration/integration-astro-view-transitions/references/basic-integration-1.2-revise.md +23 -0
- package/skills/integration/integration-astro-view-transitions/references/basic-integration-1.3-conclude.md +57 -0
- package/skills/integration/integration-astro-view-transitions/references/browser-sdk-2.md +4680 -0
- package/skills/integration/integration-django/SKILL.md +57 -0
- package/skills/integration/integration-django/references/EXAMPLE.md +1005 -0
- package/skills/integration/integration-django/references/amplitude-quickstart.md +1845 -0
- package/skills/integration/integration-django/references/basic-integration-1.0-begin.md +43 -0
- package/skills/integration/integration-django/references/basic-integration-1.1-edit.md +35 -0
- package/skills/integration/integration-django/references/basic-integration-1.2-revise.md +23 -0
- package/skills/integration/integration-django/references/basic-integration-1.3-conclude.md +57 -0
- package/skills/integration/integration-django/references/python.md +1424 -0
- package/skills/integration/integration-expo/SKILL.md +53 -0
- package/skills/integration/integration-expo/references/EXAMPLE.md +1291 -0
- package/skills/integration/integration-expo/references/amplitude-quickstart.md +1845 -0
- package/skills/integration/integration-expo/references/basic-integration-1.0-begin.md +43 -0
- package/skills/integration/integration-expo/references/basic-integration-1.1-edit.md +35 -0
- package/skills/integration/integration-expo/references/basic-integration-1.2-revise.md +23 -0
- package/skills/integration/integration-expo/references/basic-integration-1.3-conclude.md +57 -0
- package/skills/integration/integration-expo/references/react-native-sdk.md +2819 -0
- package/skills/integration/integration-fastapi/SKILL.md +57 -0
- package/skills/integration/integration-fastapi/references/EXAMPLE.md +1389 -0
- package/skills/integration/integration-fastapi/references/amplitude-quickstart.md +1845 -0
- package/skills/integration/integration-fastapi/references/basic-integration-1.0-begin.md +43 -0
- package/skills/integration/integration-fastapi/references/basic-integration-1.1-edit.md +35 -0
- package/skills/integration/integration-fastapi/references/basic-integration-1.2-revise.md +23 -0
- package/skills/integration/integration-fastapi/references/basic-integration-1.3-conclude.md +57 -0
- package/skills/integration/integration-fastapi/references/python.md +1424 -0
- package/skills/integration/integration-flask/SKILL.md +56 -0
- package/skills/integration/integration-flask/references/EXAMPLE.md +1130 -0
- package/skills/integration/integration-flask/references/amplitude-quickstart.md +1845 -0
- package/skills/integration/integration-flask/references/basic-integration-1.0-begin.md +43 -0
- package/skills/integration/integration-flask/references/basic-integration-1.1-edit.md +35 -0
- package/skills/integration/integration-flask/references/basic-integration-1.2-revise.md +23 -0
- package/skills/integration/integration-flask/references/basic-integration-1.3-conclude.md +57 -0
- package/skills/integration/integration-flask/references/python.md +1424 -0
- package/skills/integration/integration-javascript_node/SKILL.md +54 -0
- package/skills/integration/integration-javascript_node/references/EXAMPLE.md +365 -0
- package/skills/integration/integration-javascript_node/references/amplitude-quickstart.md +1845 -0
- package/skills/integration/integration-javascript_node/references/analytics.md +1778 -0
- package/skills/integration/integration-javascript_node/references/basic-integration-1.0-begin.md +43 -0
- package/skills/integration/integration-javascript_node/references/basic-integration-1.1-edit.md +35 -0
- package/skills/integration/integration-javascript_node/references/basic-integration-1.2-revise.md +23 -0
- package/skills/integration/integration-javascript_node/references/basic-integration-1.3-conclude.md +57 -0
- package/skills/integration/integration-javascript_web/SKILL.md +58 -0
- package/skills/integration/integration-javascript_web/references/EXAMPLE.md +451 -0
- package/skills/integration/integration-javascript_web/references/amplitude-quickstart.md +1845 -0
- package/skills/integration/integration-javascript_web/references/basic-integration-1.0-begin.md +43 -0
- package/skills/integration/integration-javascript_web/references/basic-integration-1.1-edit.md +35 -0
- package/skills/integration/integration-javascript_web/references/basic-integration-1.2-revise.md +23 -0
- package/skills/integration/integration-javascript_web/references/basic-integration-1.3-conclude.md +57 -0
- package/skills/integration/integration-javascript_web/references/browser-sdk-2.md +4680 -0
- package/skills/integration/integration-laravel/SKILL.md +52 -0
- package/skills/integration/integration-laravel/references/EXAMPLE.md +2039 -0
- package/skills/integration/integration-laravel/references/amplitude-quickstart.md +1845 -0
- package/skills/integration/integration-laravel/references/analytics.md +1778 -0
- package/skills/integration/integration-laravel/references/basic-integration-1.0-begin.md +43 -0
- package/skills/integration/integration-laravel/references/basic-integration-1.1-edit.md +35 -0
- package/skills/integration/integration-laravel/references/basic-integration-1.2-revise.md +23 -0
- package/skills/integration/integration-laravel/references/basic-integration-1.3-conclude.md +57 -0
- package/skills/integration/integration-nextjs-app-router/SKILL.md +54 -0
- package/skills/integration/integration-nextjs-app-router/references/EXAMPLE.md +673 -0
- package/skills/integration/integration-nextjs-app-router/references/amplitude-quickstart.md +1845 -0
- package/skills/integration/integration-nextjs-app-router/references/basic-integration-1.0-begin.md +43 -0
- package/skills/integration/integration-nextjs-app-router/references/basic-integration-1.1-edit.md +35 -0
- package/skills/integration/integration-nextjs-app-router/references/basic-integration-1.2-revise.md +23 -0
- package/skills/integration/integration-nextjs-app-router/references/basic-integration-1.3-conclude.md +57 -0
- package/skills/integration/integration-nextjs-app-router/references/browser-sdk-2.md +4680 -0
- package/skills/integration/integration-nextjs-pages-router/SKILL.md +54 -0
- package/skills/integration/integration-nextjs-pages-router/references/EXAMPLE.md +735 -0
- package/skills/integration/integration-nextjs-pages-router/references/amplitude-quickstart.md +1845 -0
- package/skills/integration/integration-nextjs-pages-router/references/basic-integration-1.0-begin.md +43 -0
- package/skills/integration/integration-nextjs-pages-router/references/basic-integration-1.1-edit.md +35 -0
- package/skills/integration/integration-nextjs-pages-router/references/basic-integration-1.2-revise.md +23 -0
- package/skills/integration/integration-nextjs-pages-router/references/basic-integration-1.3-conclude.md +57 -0
- package/skills/integration/integration-nextjs-pages-router/references/browser-sdk-2.md +4680 -0
- package/skills/integration/integration-nuxt-3.6/SKILL.md +46 -0
- package/skills/integration/integration-nuxt-3.6/references/EXAMPLE.md +8422 -0
- package/skills/integration/integration-nuxt-3.6/references/amplitude-quickstart.md +1845 -0
- package/skills/integration/integration-nuxt-3.6/references/basic-integration-1.0-begin.md +43 -0
- package/skills/integration/integration-nuxt-3.6/references/basic-integration-1.1-edit.md +35 -0
- package/skills/integration/integration-nuxt-3.6/references/basic-integration-1.2-revise.md +23 -0
- package/skills/integration/integration-nuxt-3.6/references/basic-integration-1.3-conclude.md +57 -0
- package/skills/integration/integration-nuxt-3.6/references/browser-sdk-2.md +4680 -0
- package/skills/integration/integration-nuxt-4/SKILL.md +46 -0
- package/skills/integration/integration-nuxt-4/references/EXAMPLE.md +8670 -0
- package/skills/integration/integration-nuxt-4/references/amplitude-quickstart.md +1845 -0
- package/skills/integration/integration-nuxt-4/references/basic-integration-1.0-begin.md +43 -0
- package/skills/integration/integration-nuxt-4/references/basic-integration-1.1-edit.md +35 -0
- package/skills/integration/integration-nuxt-4/references/basic-integration-1.2-revise.md +23 -0
- package/skills/integration/integration-nuxt-4/references/basic-integration-1.3-conclude.md +57 -0
- package/skills/integration/integration-nuxt-4/references/browser-sdk-2.md +4680 -0
- package/skills/integration/integration-python/SKILL.md +53 -0
- package/skills/integration/integration-python/references/EXAMPLE.md +445 -0
- package/skills/integration/integration-python/references/amplitude-quickstart.md +1845 -0
- package/skills/integration/integration-python/references/basic-integration-1.0-begin.md +43 -0
- package/skills/integration/integration-python/references/basic-integration-1.1-edit.md +35 -0
- package/skills/integration/integration-python/references/basic-integration-1.2-revise.md +23 -0
- package/skills/integration/integration-python/references/basic-integration-1.3-conclude.md +57 -0
- package/skills/integration/integration-python/references/python.md +1424 -0
- package/skills/integration/integration-react-native/SKILL.md +49 -0
- package/skills/integration/integration-react-native/references/EXAMPLE.md +2253 -0
- package/skills/integration/integration-react-native/references/amplitude-quickstart.md +1845 -0
- package/skills/integration/integration-react-native/references/basic-integration-1.0-begin.md +43 -0
- package/skills/integration/integration-react-native/references/basic-integration-1.1-edit.md +35 -0
- package/skills/integration/integration-react-native/references/basic-integration-1.2-revise.md +23 -0
- package/skills/integration/integration-react-native/references/basic-integration-1.3-conclude.md +57 -0
- package/skills/integration/integration-react-native/references/react-native-sdk.md +2819 -0
- package/skills/integration/integration-react-react-router-6/SKILL.md +53 -0
- package/skills/integration/integration-react-react-router-6/references/EXAMPLE.md +570 -0
- package/skills/integration/integration-react-react-router-6/references/amplitude-quickstart.md +1845 -0
- package/skills/integration/integration-react-react-router-6/references/basic-integration-1.0-begin.md +43 -0
- package/skills/integration/integration-react-react-router-6/references/basic-integration-1.1-edit.md +35 -0
- package/skills/integration/integration-react-react-router-6/references/basic-integration-1.2-revise.md +23 -0
- package/skills/integration/integration-react-react-router-6/references/basic-integration-1.3-conclude.md +57 -0
- package/skills/integration/integration-react-react-router-6/references/browser-sdk-2.md +4680 -0
- package/skills/integration/integration-react-react-router-7-data/SKILL.md +53 -0
- package/skills/integration/integration-react-react-router-7-data/references/EXAMPLE.md +830 -0
- package/skills/integration/integration-react-react-router-7-data/references/amplitude-quickstart.md +1845 -0
- package/skills/integration/integration-react-react-router-7-data/references/basic-integration-1.0-begin.md +43 -0
- package/skills/integration/integration-react-react-router-7-data/references/basic-integration-1.1-edit.md +35 -0
- package/skills/integration/integration-react-react-router-7-data/references/basic-integration-1.2-revise.md +23 -0
- package/skills/integration/integration-react-react-router-7-data/references/basic-integration-1.3-conclude.md +57 -0
- package/skills/integration/integration-react-react-router-7-data/references/browser-sdk-2.md +4680 -0
- package/skills/integration/integration-react-react-router-7-declarative/SKILL.md +53 -0
- package/skills/integration/integration-react-react-router-7-declarative/references/EXAMPLE.md +609 -0
- package/skills/integration/integration-react-react-router-7-declarative/references/amplitude-quickstart.md +1845 -0
- package/skills/integration/integration-react-react-router-7-declarative/references/basic-integration-1.0-begin.md +43 -0
- package/skills/integration/integration-react-react-router-7-declarative/references/basic-integration-1.1-edit.md +35 -0
- package/skills/integration/integration-react-react-router-7-declarative/references/basic-integration-1.2-revise.md +23 -0
- package/skills/integration/integration-react-react-router-7-declarative/references/basic-integration-1.3-conclude.md +57 -0
- package/skills/integration/integration-react-react-router-7-declarative/references/browser-sdk-2.md +4680 -0
- package/skills/integration/integration-react-react-router-7-framework/SKILL.md +53 -0
- package/skills/integration/integration-react-react-router-7-framework/references/EXAMPLE.md +1081 -0
- package/skills/integration/integration-react-react-router-7-framework/references/amplitude-quickstart.md +1845 -0
- package/skills/integration/integration-react-react-router-7-framework/references/basic-integration-1.0-begin.md +43 -0
- package/skills/integration/integration-react-react-router-7-framework/references/basic-integration-1.1-edit.md +35 -0
- package/skills/integration/integration-react-react-router-7-framework/references/basic-integration-1.2-revise.md +23 -0
- package/skills/integration/integration-react-react-router-7-framework/references/basic-integration-1.3-conclude.md +57 -0
- package/skills/integration/integration-react-react-router-7-framework/references/browser-sdk-2.md +4680 -0
- package/skills/integration/integration-react-tanstack-router-code-based/SKILL.md +57 -0
- package/skills/integration/integration-react-tanstack-router-code-based/references/EXAMPLE.md +659 -0
- package/skills/integration/integration-react-tanstack-router-code-based/references/amplitude-quickstart.md +1845 -0
- package/skills/integration/integration-react-tanstack-router-code-based/references/basic-integration-1.0-begin.md +43 -0
- package/skills/integration/integration-react-tanstack-router-code-based/references/basic-integration-1.1-edit.md +35 -0
- package/skills/integration/integration-react-tanstack-router-code-based/references/basic-integration-1.2-revise.md +23 -0
- package/skills/integration/integration-react-tanstack-router-code-based/references/basic-integration-1.3-conclude.md +57 -0
- package/skills/integration/integration-react-tanstack-router-code-based/references/browser-sdk-2.md +4680 -0
- package/skills/integration/integration-react-tanstack-router-file-based/SKILL.md +57 -0
- package/skills/integration/integration-react-tanstack-router-file-based/references/EXAMPLE.md +777 -0
- package/skills/integration/integration-react-tanstack-router-file-based/references/amplitude-quickstart.md +1845 -0
- package/skills/integration/integration-react-tanstack-router-file-based/references/basic-integration-1.0-begin.md +43 -0
- package/skills/integration/integration-react-tanstack-router-file-based/references/basic-integration-1.1-edit.md +35 -0
- package/skills/integration/integration-react-tanstack-router-file-based/references/basic-integration-1.2-revise.md +23 -0
- package/skills/integration/integration-react-tanstack-router-file-based/references/basic-integration-1.3-conclude.md +57 -0
- package/skills/integration/integration-react-tanstack-router-file-based/references/browser-sdk-2.md +4680 -0
- package/skills/integration/integration-react-vite/SKILL.md +53 -0
- package/skills/integration/integration-react-vite/references/EXAMPLE.md +542 -0
- package/skills/integration/integration-react-vite/references/amplitude-quickstart.md +1845 -0
- package/skills/integration/integration-react-vite/references/basic-integration-1.0-begin.md +43 -0
- package/skills/integration/integration-react-vite/references/basic-integration-1.1-edit.md +35 -0
- package/skills/integration/integration-react-vite/references/basic-integration-1.2-revise.md +23 -0
- package/skills/integration/integration-react-vite/references/basic-integration-1.3-conclude.md +57 -0
- package/skills/integration/integration-react-vite/references/browser-sdk-2.md +4680 -0
- package/skills/integration/integration-ruby/SKILL.md +50 -0
- package/skills/integration/integration-ruby/references/EXAMPLE.md +420 -0
- package/skills/integration/integration-ruby/references/amplitude-quickstart.md +1845 -0
- package/skills/integration/integration-ruby/references/analytics.md +1778 -0
- package/skills/integration/integration-ruby/references/basic-integration-1.0-begin.md +43 -0
- package/skills/integration/integration-ruby/references/basic-integration-1.1-edit.md +35 -0
- package/skills/integration/integration-ruby/references/basic-integration-1.2-revise.md +23 -0
- package/skills/integration/integration-ruby/references/basic-integration-1.3-conclude.md +57 -0
- package/skills/integration/integration-ruby-on-rails/SKILL.md +55 -0
- package/skills/integration/integration-ruby-on-rails/references/EXAMPLE.md +1013 -0
- package/skills/integration/integration-ruby-on-rails/references/amplitude-quickstart.md +1845 -0
- package/skills/integration/integration-ruby-on-rails/references/analytics.md +1778 -0
- package/skills/integration/integration-ruby-on-rails/references/basic-integration-1.0-begin.md +43 -0
- package/skills/integration/integration-ruby-on-rails/references/basic-integration-1.1-edit.md +35 -0
- package/skills/integration/integration-ruby-on-rails/references/basic-integration-1.2-revise.md +23 -0
- package/skills/integration/integration-ruby-on-rails/references/basic-integration-1.3-conclude.md +57 -0
- package/skills/integration/integration-sveltekit/SKILL.md +47 -0
- package/skills/integration/integration-sveltekit/references/EXAMPLE.md +14121 -0
- package/skills/integration/integration-sveltekit/references/amplitude-quickstart.md +1845 -0
- package/skills/integration/integration-sveltekit/references/basic-integration-1.0-begin.md +43 -0
- package/skills/integration/integration-sveltekit/references/basic-integration-1.1-edit.md +35 -0
- package/skills/integration/integration-sveltekit/references/basic-integration-1.2-revise.md +23 -0
- package/skills/integration/integration-sveltekit/references/basic-integration-1.3-conclude.md +57 -0
- package/skills/integration/integration-sveltekit/references/browser-sdk-2.md +4680 -0
- package/skills/integration/integration-swift/SKILL.md +49 -0
- package/skills/integration/integration-swift/references/EXAMPLE.md +660 -0
- package/skills/integration/integration-swift/references/amplitude-quickstart.md +1845 -0
- package/skills/integration/integration-swift/references/analytics.md +1778 -0
- package/skills/integration/integration-swift/references/basic-integration-1.0-begin.md +43 -0
- package/skills/integration/integration-swift/references/basic-integration-1.1-edit.md +35 -0
- package/skills/integration/integration-swift/references/basic-integration-1.2-revise.md +23 -0
- package/skills/integration/integration-swift/references/basic-integration-1.3-conclude.md +57 -0
- package/skills/integration/integration-tanstack-start/SKILL.md +58 -0
- package/skills/integration/integration-tanstack-start/references/EXAMPLE.md +998 -0
- package/skills/integration/integration-tanstack-start/references/amplitude-quickstart.md +1845 -0
- package/skills/integration/integration-tanstack-start/references/basic-integration-1.0-begin.md +43 -0
- package/skills/integration/integration-tanstack-start/references/basic-integration-1.1-edit.md +35 -0
- package/skills/integration/integration-tanstack-start/references/basic-integration-1.2-revise.md +23 -0
- package/skills/integration/integration-tanstack-start/references/basic-integration-1.3-conclude.md +57 -0
- package/skills/integration/integration-tanstack-start/references/browser-sdk-2.md +4680 -0
- package/skills/integration/integration-vue-3/SKILL.md +46 -0
- package/skills/integration/integration-vue-3/references/EXAMPLE.md +846 -0
- package/skills/integration/integration-vue-3/references/amplitude-quickstart.md +1845 -0
- package/skills/integration/integration-vue-3/references/basic-integration-1.0-begin.md +43 -0
- package/skills/integration/integration-vue-3/references/basic-integration-1.1-edit.md +35 -0
- package/skills/integration/integration-vue-3/references/basic-integration-1.2-revise.md +23 -0
- package/skills/integration/integration-vue-3/references/basic-integration-1.3-conclude.md +57 -0
- package/skills/integration/integration-vue-3/references/browser-sdk-2.md +4680 -0
- package/skills/taxonomy/amplitude-quickstart-taxonomy-agent/SKILL.md +228 -0
- package/dist/src/ui/tui/components/TitleBar.d.ts +0 -8
- package/dist/src/ui/tui/components/TitleBar.js +0 -27
- package/dist/src/ui/tui/primitives/KagiSmallWebViewer.d.ts +0 -7
- package/dist/src/ui/tui/primitives/KagiSmallWebViewer.js +0 -101
- package/dist/src/utils/anthropic-status.d.ts +0 -17
- package/dist/src/utils/anthropic-status.js +0 -51
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: integration-javascript_node
|
|
3
|
+
description: >-
|
|
4
|
+
Amplitude integration for server-side Node.js applications using
|
|
5
|
+
@amplitude/analytics-node
|
|
6
|
+
metadata:
|
|
7
|
+
author: Amplitude
|
|
8
|
+
version: dev
|
|
9
|
+
---
|
|
10
|
+
|
|
11
|
+
# Amplitude integration for JavaScript Node
|
|
12
|
+
|
|
13
|
+
This skill helps you add Amplitude analytics to JavaScript Node applications.
|
|
14
|
+
|
|
15
|
+
## Workflow
|
|
16
|
+
|
|
17
|
+
Follow these steps in order to complete the integration:
|
|
18
|
+
|
|
19
|
+
1. `basic-integration-1.0-begin.md` - Amplitude Setup - Begin ← **Start here**
|
|
20
|
+
2. `basic-integration-1.1-edit.md` - Amplitude Setup - Edit
|
|
21
|
+
3. `basic-integration-1.2-revise.md` - Amplitude Setup - Revise
|
|
22
|
+
4. `basic-integration-1.3-conclude.md` - Amplitude Setup - Conclusion
|
|
23
|
+
|
|
24
|
+
## Reference files
|
|
25
|
+
|
|
26
|
+
- `references/EXAMPLE.md` - JavaScript Node example project code
|
|
27
|
+
- `references/analytics.md` - Amplitude documentation for Analytics
|
|
28
|
+
- `references/amplitude-quickstart.md` - Amplitude documentation for Amplitude Quickstart
|
|
29
|
+
- `references/basic-integration-1.0-begin.md` - Amplitude setup - begin
|
|
30
|
+
- `references/basic-integration-1.1-edit.md` - Amplitude setup - edit
|
|
31
|
+
- `references/basic-integration-1.2-revise.md` - Amplitude setup - revise
|
|
32
|
+
- `references/basic-integration-1.3-conclude.md` - Amplitude setup - conclusion
|
|
33
|
+
|
|
34
|
+
The example project shows the target implementation pattern. Consult the documentation for API details.
|
|
35
|
+
|
|
36
|
+
## Key principles
|
|
37
|
+
|
|
38
|
+
- **Environment variables**: Always use environment variables for Amplitude keys. Never hardcode them.
|
|
39
|
+
- **Minimal changes**: Add Amplitude code alongside existing integrations. Don't replace or restructure existing code.
|
|
40
|
+
- **Match the example**: Your implementation should follow the example project's patterns as closely as possible.
|
|
41
|
+
|
|
42
|
+
## Framework guidelines
|
|
43
|
+
|
|
44
|
+
- @amplitude/analytics-node is the Node.js server-side SDK package name — do NOT use @amplitude/analytics-browser on the server
|
|
45
|
+
- Add amplitude.track() calls in route handlers for meaningful user actions — every route that creates, updates, or deletes data should track an event with contextual properties
|
|
46
|
+
- In long-running servers, the SDK batches events automatically — do NOT set flushQueueSize or flushIntervalMillis unless you have a specific reason to
|
|
47
|
+
- For short-lived processes (scripts, CLIs, serverless), call await amplitude.flush() before the process exits to ensure all events are sent
|
|
48
|
+
- Reverse proxy is NOT needed for server-side Node.js — only client-side JavaScript may benefit from a proxy to avoid ad blockers
|
|
49
|
+
- Remember that source code is available in the node_modules directory
|
|
50
|
+
- Check package.json for type checking or build scripts to validate changes
|
|
51
|
+
|
|
52
|
+
## Identifying users
|
|
53
|
+
|
|
54
|
+
Identify users during login and signup events. Refer to the example code and documentation for the correct identify pattern for this framework. Call `amplitude.setUserId(userId)` to associate events with a known user, and use `amplitude.identify()` with an `Identify` object to set user properties. If both frontend and backend code exist, pass a consistent user/device ID via custom request headers to maintain event correlation.
|
|
@@ -0,0 +1,365 @@
|
|
|
1
|
+
# Amplitude JavaScript Node Example Project
|
|
2
|
+
|
|
3
|
+
Repository: https://github.com/amplitude/context-hub
|
|
4
|
+
Path: basics/javascript-node
|
|
5
|
+
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
## README.md
|
|
9
|
+
|
|
10
|
+
# Amplitude Node.js Example - Todo API
|
|
11
|
+
|
|
12
|
+
A simple Express server demonstrating Amplitude Node.js integration for server-side applications (APIs, backends, workers, etc.).
|
|
13
|
+
|
|
14
|
+
## Purpose
|
|
15
|
+
|
|
16
|
+
This example serves as:
|
|
17
|
+
|
|
18
|
+
- **Verification** that the context-hub wizard works for plain Node.js projects
|
|
19
|
+
- **Reference implementation** of Amplitude best practices for server-side Node.js code
|
|
20
|
+
- **Working example** you can run and modify
|
|
21
|
+
|
|
22
|
+
## Features
|
|
23
|
+
|
|
24
|
+
- **Event capture** – tracks user actions with `amplitude.capture()` on each route
|
|
25
|
+
- **User identification** – calls `amplitude.identify()` on write actions to associate user traits
|
|
26
|
+
- **Feature flags** – gates the stats endpoint detail level with `amplitude.isFeatureEnabled()`
|
|
27
|
+
- **Error tracking** – captures exceptions with `amplitude.captureException()` and `enableExceptionAutocapture`
|
|
28
|
+
- **Graceful shutdown** – flushes pending events with `await amplitude.shutdown()` on SIGINT/SIGTERM
|
|
29
|
+
|
|
30
|
+
## Quick start
|
|
31
|
+
|
|
32
|
+
### 1. Install Dependencies
|
|
33
|
+
|
|
34
|
+
```bash
|
|
35
|
+
npm install
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
### 2. Configure Amplitude
|
|
39
|
+
|
|
40
|
+
```bash
|
|
41
|
+
# Copy environment template
|
|
42
|
+
cp .env.example .env
|
|
43
|
+
|
|
44
|
+
# Edit .env and add your Amplitude API key
|
|
45
|
+
# AMPLITUDE_API_KEY=your_amplitude_api_key
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
### 3. Run the server
|
|
49
|
+
|
|
50
|
+
```bash
|
|
51
|
+
npm start
|
|
52
|
+
# Todo API running at http://localhost:3000
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
### 4. Try it out
|
|
56
|
+
|
|
57
|
+
```bash
|
|
58
|
+
# Add a todo
|
|
59
|
+
curl -X POST http://localhost:3000/todos \
|
|
60
|
+
-H 'Content-Type: application/json' \
|
|
61
|
+
-d '{"text": "Buy groceries", "user_id": "user_123"}'
|
|
62
|
+
|
|
63
|
+
# List all todos
|
|
64
|
+
curl http://localhost:3000/todos
|
|
65
|
+
|
|
66
|
+
# Complete a todo
|
|
67
|
+
curl -X PATCH http://localhost:3000/todos/1/complete \
|
|
68
|
+
-H 'Content-Type: application/json' \
|
|
69
|
+
-d '{"user_id": "user_123"}'
|
|
70
|
+
|
|
71
|
+
# Delete a todo
|
|
72
|
+
curl -X DELETE http://localhost:3000/todos/1
|
|
73
|
+
|
|
74
|
+
# Show statistics
|
|
75
|
+
curl http://localhost:3000/stats
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
## What gets tracked
|
|
79
|
+
|
|
80
|
+
The app tracks these events in Amplitude:
|
|
81
|
+
|
|
82
|
+
| Event | Properties | Purpose |
|
|
83
|
+
|-------|-----------|---------|
|
|
84
|
+
| `Todo Added` | `todo_id`, `todo_length`, `total_todos` | When a todo is created |
|
|
85
|
+
| `Todos Viewed` | `total_todos`, `completed_todos` | When todos are listed |
|
|
86
|
+
| `Todo Completed` | `todo_id`, `time_to_complete_hours` | When a todo is completed |
|
|
87
|
+
| `Todo Deleted` | `todo_id`, `was_completed` | When a todo is deleted |
|
|
88
|
+
| `Stats Viewed` | `total_todos`, `completed_todos`, `pending_todos` | When stats are requested |
|
|
89
|
+
|
|
90
|
+
## Code structure
|
|
91
|
+
|
|
92
|
+
```
|
|
93
|
+
basics/javascript-node/
|
|
94
|
+
├── todo.js # Express server with Amplitude tracking
|
|
95
|
+
├── package.json # Node.js dependencies
|
|
96
|
+
├── .env.example # Environment variable template
|
|
97
|
+
├── .gitignore # Git ignore rules
|
|
98
|
+
└── README.md # This file
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
## Patterns
|
|
102
|
+
|
|
103
|
+
### 1. Initialization
|
|
104
|
+
|
|
105
|
+
```javascript
|
|
106
|
+
import { init, track, identify, Identify, flush } from '@amplitude/analytics-node';
|
|
107
|
+
|
|
108
|
+
init(apiKey);
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
### 2. Event tracking on routes
|
|
112
|
+
|
|
113
|
+
```javascript
|
|
114
|
+
app.post('/todos', (req, res) => {
|
|
115
|
+
// ... create todo ...
|
|
116
|
+
|
|
117
|
+
amplitude.capture({
|
|
118
|
+
distinctId: req.body.user_id,
|
|
119
|
+
event: 'Todo Added',
|
|
120
|
+
properties: { todo_id: todo.id },
|
|
121
|
+
});
|
|
122
|
+
|
|
123
|
+
res.status(201).json(todo);
|
|
124
|
+
});
|
|
125
|
+
```
|
|
126
|
+
|
|
127
|
+
### 3. Graceful shutdown
|
|
128
|
+
|
|
129
|
+
```javascript
|
|
130
|
+
async function shutdown() {
|
|
131
|
+
server.close();
|
|
132
|
+
await amplitude.shutdown(); // Flush pending events
|
|
133
|
+
process.exit(0);
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
process.on('SIGINT', shutdown);
|
|
137
|
+
process.on('SIGTERM', shutdown);
|
|
138
|
+
```
|
|
139
|
+
|
|
140
|
+
## Learn more
|
|
141
|
+
|
|
142
|
+
- [Amplitude Node.js SDK Documentation](https://amplitude.com/docs/libraries/node)
|
|
143
|
+
- [Amplitude Node.js SDK API Reference](https://amplitude.com/docs/references/@amplitude/analytics-node)
|
|
144
|
+
- [Amplitude Product Analytics](https://amplitude.com/docs/product-analytics)
|
|
145
|
+
|
|
146
|
+
---
|
|
147
|
+
|
|
148
|
+
## .env.example
|
|
149
|
+
|
|
150
|
+
```example
|
|
151
|
+
# Amplitude Configuration
|
|
152
|
+
AMPLITUDE_API_KEY=your_amplitude_api_key_here
|
|
153
|
+
|
|
154
|
+
```
|
|
155
|
+
|
|
156
|
+
---
|
|
157
|
+
|
|
158
|
+
## todo.js
|
|
159
|
+
|
|
160
|
+
```js
|
|
161
|
+
/**
|
|
162
|
+
* Simple Todo API with Amplitude Analytics
|
|
163
|
+
*
|
|
164
|
+
* A minimal Express server demonstrating Amplitude Node.js integration
|
|
165
|
+
* for server-side applications (APIs, backends, workers, etc.).
|
|
166
|
+
*/
|
|
167
|
+
|
|
168
|
+
import express from 'express';
|
|
169
|
+
import { init, track, identify, Identify, flush } from '@amplitude/analytics-node';
|
|
170
|
+
import dotenv from 'dotenv';
|
|
171
|
+
|
|
172
|
+
// Load environment variables
|
|
173
|
+
dotenv.config();
|
|
174
|
+
|
|
175
|
+
const app = express();
|
|
176
|
+
app.use(express.json());
|
|
177
|
+
|
|
178
|
+
// In-memory store, replaced with a database in production
|
|
179
|
+
const todos = [];
|
|
180
|
+
let nextId = 1;
|
|
181
|
+
|
|
182
|
+
// --- Amplitude Setup ---
|
|
183
|
+
|
|
184
|
+
function initializeAmplitude() {
|
|
185
|
+
const apiKey = process.env.AMPLITUDE_API_KEY;
|
|
186
|
+
|
|
187
|
+
if (!apiKey) {
|
|
188
|
+
console.log('WARNING: Amplitude not configured (AMPLITUDE_API_KEY not set)');
|
|
189
|
+
console.log(' App will work but analytics won\'t be tracked');
|
|
190
|
+
return false;
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
init(apiKey);
|
|
194
|
+
return true;
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
const amplitudeEnabled = initializeAmplitude();
|
|
198
|
+
|
|
199
|
+
function trackEvent(userId, event, properties = {}) {
|
|
200
|
+
if (!amplitudeEnabled) return;
|
|
201
|
+
|
|
202
|
+
track(event, properties, { user_id: userId });
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
function identifyUser(userId, properties = {}) {
|
|
206
|
+
if (!amplitudeEnabled) return;
|
|
207
|
+
|
|
208
|
+
const identifyEvent = new Identify();
|
|
209
|
+
Object.entries(properties).forEach(([key, value]) => identifyEvent.set(key, value));
|
|
210
|
+
identify(identifyEvent, { user_id: userId });
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
// --- Routes ---
|
|
214
|
+
|
|
215
|
+
// Add a todo
|
|
216
|
+
app.post('/todos', (req, res) => {
|
|
217
|
+
const { text, user_id } = req.body;
|
|
218
|
+
|
|
219
|
+
if (!text) {
|
|
220
|
+
return res.status(400).json({ error: 'text is required' });
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
const userId = user_id || 'anonymous';
|
|
224
|
+
|
|
225
|
+
const todo = {
|
|
226
|
+
id: nextId++,
|
|
227
|
+
text,
|
|
228
|
+
completed: false,
|
|
229
|
+
created_at: new Date().toISOString(),
|
|
230
|
+
};
|
|
231
|
+
|
|
232
|
+
todos.push(todo);
|
|
233
|
+
|
|
234
|
+
identifyUser(userId, {
|
|
235
|
+
last_active: new Date().toISOString(),
|
|
236
|
+
total_todos_created: todos.length,
|
|
237
|
+
});
|
|
238
|
+
|
|
239
|
+
trackEvent(userId, 'Todo Added', {
|
|
240
|
+
todo_id: todo.id,
|
|
241
|
+
todo_length: text.length,
|
|
242
|
+
total_todos: todos.length,
|
|
243
|
+
});
|
|
244
|
+
|
|
245
|
+
res.status(201).json(todo);
|
|
246
|
+
});
|
|
247
|
+
|
|
248
|
+
// List all todos
|
|
249
|
+
app.get('/todos', (req, res) => {
|
|
250
|
+
const userId = req.query.user_id || 'anonymous';
|
|
251
|
+
|
|
252
|
+
trackEvent(userId, 'Todos Viewed', {
|
|
253
|
+
total_todos: todos.length,
|
|
254
|
+
completed_todos: todos.filter((t) => t.completed).length,
|
|
255
|
+
});
|
|
256
|
+
|
|
257
|
+
res.json(todos);
|
|
258
|
+
});
|
|
259
|
+
|
|
260
|
+
// Complete a todo
|
|
261
|
+
app.patch('/todos/:id/complete', (req, res) => {
|
|
262
|
+
const todo = todos.find((t) => t.id === parseInt(req.params.id, 10));
|
|
263
|
+
|
|
264
|
+
if (!todo) {
|
|
265
|
+
return res.status(404).json({ error: 'Todo not found' });
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
if (todo.completed) {
|
|
269
|
+
return res.status(400).json({ error: 'Todo already completed' });
|
|
270
|
+
}
|
|
271
|
+
|
|
272
|
+
todo.completed = true;
|
|
273
|
+
todo.completed_at = new Date().toISOString();
|
|
274
|
+
|
|
275
|
+
const userId = req.body.user_id || 'anonymous';
|
|
276
|
+
|
|
277
|
+
trackEvent(userId, 'Todo Completed', {
|
|
278
|
+
todo_id: todo.id,
|
|
279
|
+
time_to_complete_hours:
|
|
280
|
+
(new Date(todo.completed_at) - new Date(todo.created_at)) / 3600000,
|
|
281
|
+
});
|
|
282
|
+
|
|
283
|
+
res.json(todo);
|
|
284
|
+
});
|
|
285
|
+
|
|
286
|
+
// Delete a todo
|
|
287
|
+
app.delete('/todos/:id', (req, res) => {
|
|
288
|
+
const index = todos.findIndex((t) => t.id === parseInt(req.params.id, 10));
|
|
289
|
+
|
|
290
|
+
if (index === -1) {
|
|
291
|
+
return res.status(404).json({ error: 'Todo not found' });
|
|
292
|
+
}
|
|
293
|
+
|
|
294
|
+
const todo = todos[index];
|
|
295
|
+
todos.splice(index, 1);
|
|
296
|
+
|
|
297
|
+
const userId = req.query.user_id || 'anonymous';
|
|
298
|
+
|
|
299
|
+
trackEvent(userId, 'Todo Deleted', {
|
|
300
|
+
todo_id: todo.id,
|
|
301
|
+
was_completed: todo.completed,
|
|
302
|
+
});
|
|
303
|
+
|
|
304
|
+
res.status(204).end();
|
|
305
|
+
});
|
|
306
|
+
|
|
307
|
+
// Stats
|
|
308
|
+
app.get('/stats', async (req, res) => {
|
|
309
|
+
const total = todos.length;
|
|
310
|
+
const completed = todos.filter((t) => t.completed).length;
|
|
311
|
+
const pending = total - completed;
|
|
312
|
+
|
|
313
|
+
const userId = req.query.user_id || 'anonymous';
|
|
314
|
+
|
|
315
|
+
const stats = {
|
|
316
|
+
total,
|
|
317
|
+
completed,
|
|
318
|
+
pending,
|
|
319
|
+
completion_rate: total > 0 ? ((completed / total) * 100).toFixed(1) : '0.0',
|
|
320
|
+
};
|
|
321
|
+
|
|
322
|
+
// TODO: Use Amplitude Experiment for feature flags
|
|
323
|
+
|
|
324
|
+
trackEvent(userId, 'Stats Viewed', {
|
|
325
|
+
total_todos: total,
|
|
326
|
+
completed_todos: completed,
|
|
327
|
+
pending_todos: pending,
|
|
328
|
+
});
|
|
329
|
+
|
|
330
|
+
res.json(stats);
|
|
331
|
+
});
|
|
332
|
+
|
|
333
|
+
// --- Error Handling ---
|
|
334
|
+
|
|
335
|
+
// Global error handler
|
|
336
|
+
app.use((err, req, res, _next) => {
|
|
337
|
+
console.error('Unhandled error:', err.message);
|
|
338
|
+
res.status(500).json({ error: 'Internal server error' });
|
|
339
|
+
});
|
|
340
|
+
|
|
341
|
+
// --- Server ---
|
|
342
|
+
|
|
343
|
+
const PORT = process.env.PORT || 3000;
|
|
344
|
+
|
|
345
|
+
const server = app.listen(PORT, () => {
|
|
346
|
+
console.log(`Todo API running at http://localhost:${PORT}`);
|
|
347
|
+
});
|
|
348
|
+
|
|
349
|
+
// Graceful shutdown, flush Amplitude events before exiting
|
|
350
|
+
async function shutdown() {
|
|
351
|
+
console.log('\nShutting down...');
|
|
352
|
+
server.close();
|
|
353
|
+
if (amplitudeEnabled) {
|
|
354
|
+
await flush();
|
|
355
|
+
}
|
|
356
|
+
process.exit(0);
|
|
357
|
+
}
|
|
358
|
+
|
|
359
|
+
process.on('SIGINT', shutdown);
|
|
360
|
+
process.on('SIGTERM', shutdown);
|
|
361
|
+
|
|
362
|
+
```
|
|
363
|
+
|
|
364
|
+
---
|
|
365
|
+
|