feat(telemetry): opt-out phone-home telemetry for the CLI and cli.deepgram.com#59
Merged
lukeocodes merged 2 commits intomainfrom May 7, 2026
Merged
feat(telemetry): opt-out phone-home telemetry for the CLI and cli.deepgram.com#59lukeocodes merged 2 commits intomainfrom
lukeocodes merged 2 commits intomainfrom
Conversation
Adds packages/deepctl-telemetry, a workspace-required Sentry client that ships with every install of deepctl. Errors phone home to the dx-cli Sentry project by default; users can opt out anywhere with: dg config set telemetry.enabled false (or DEEPCTL_TELEMETRY_DISABLED=1 for one-shot CI runs). Wired into src/deepctl/main.py before plugin loads, with a Click monkey-patch that appends a dim one-line notice to every --help output (group, subcommand, plugin command — anywhere Click formats help). The init/notice failure path is wrapped in try/except so a broken telemetry dep cannot crash the CLI. Hard-dep enforced via the root pyproject.toml dependencies list (same pattern as deepctl-core, deepctl-shared-utils, and every command package). Release-please config and test workflow updated. Default Sentry DSN points at the existing dx-cli project; override via DEEPCTL_TELEMETRY_DSN for forks or self-hosted Sentry.
Adds @sentry/astro to the marketing site, pointed at the same dx-cli Sentry project as the CLI itself. Sentry init runs from web/sentry.client.config.ts and skips if localStorage.dg_telemetry === 'off'. Footer toggle next to the copyright line lets visitors flip the flag and reload. State is rendered on every page load so the displayed value stays in sync with what's actually about to happen on the next visit.
There was a problem hiding this comment.
Pull request overview
Adds opt-out (default-on) Sentry-backed “phone-home” telemetry to both the Deepgram CLI and cli.deepgram.com, including a per-user toggle for the website and a --help footer notice for the CLI.
Changes:
- Introduces new
packages/deepctl-telemetrypackage to gate/init Sentry and append a telemetry notice to all Click help output. - Wires CLI startup to initialize telemetry early and extends
deepctl_coreconfig withtelemetry.enabled(defaulttrue). - Adds
@sentry/astroclient initialization for the website plus a localStorage-backed “Telemetry: on/off” toggle in the footer.
Reviewed changes
Copilot reviewed 18 out of 21 changed files in this pull request and generated 4 comments.
Show a summary per file
| File | Description |
|---|---|
| web/src/pages/index.astro | Adds footer UI + client-side localStorage toggle to opt out of web telemetry. |
| web/sentry.client.config.ts | Initializes Sentry on the client only when not opted out via localStorage. |
| web/package.json | Adds @sentry/astro dependency. |
| web/package-lock.json | Locks Sentry (and transitive) dependencies. |
| web/astro.config.mjs | Registers Sentry Astro integration + source map upload configuration. |
| src/deepctl/main.py | Initializes CLI telemetry and installs Click help footer early in startup. |
| README.md | Documents new deepctl-telemetry workspace package. |
| pyproject.toml | Adds deepctl-telemetry as a root dependency + workspace source. |
| packages/deepctl-telemetry/tests/unit/test_telemetry.py | Unit tests for enablement logic and notice rendering. |
| packages/deepctl-telemetry/tests/unit/init.py | Test package marker. |
| packages/deepctl-telemetry/tests/init.py | Test package marker. |
| packages/deepctl-telemetry/src/deepctl_telemetry/notice.py | Implements Click get_help monkey-patch and notice rendering. |
| packages/deepctl-telemetry/src/deepctl_telemetry/client.py | Implements Sentry init + opt-out + event scrubbing. |
| packages/deepctl-telemetry/src/deepctl_telemetry/init.py | Public exports + version for telemetry package. |
| packages/deepctl-telemetry/README.md | Package-level documentation and usage notes. |
| packages/deepctl-telemetry/pyproject.toml | New package metadata and dependencies. |
| packages/deepctl-telemetry/CHANGELOG.md | Initializes changelog for release-please. |
| packages/deepctl-core/src/deepctl_core/config.py | Adds TelemetryConfig and DeepgramConfig.telemetry field. |
| .github/workflows/test.yml | Includes telemetry package tests in CI pytest invocation. |
| .github/release-please-config.json | Adds release-please configuration for telemetry package. |
| .github/.release-please-manifest.json | Adds telemetry package to release-please manifest. |
Files not reviewed (1)
- web/package-lock.json: Language not supported
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Comment on lines
+244
to
+246
| telemetry_config = Config() | ||
| init_telemetry(telemetry_config) | ||
| install_help_notice(telemetry_config) |
Comment on lines
+37
to
+45
| def init_telemetry(config: Config) -> bool: | ||
| """Initialize the Sentry SDK if telemetry is enabled. | ||
|
|
||
| Idempotent — safe to call multiple times. Returns whether init ran. | ||
| """ | ||
| global _initialized | ||
| if _initialized: | ||
| return True | ||
| if not is_enabled(config): |
Comment on lines
+1115
to
+1122
| const render = () => { | ||
| const off = localStorage.getItem(STORAGE_KEY) === 'off'; | ||
| stateEl.textContent = off ? 'off' : 'on'; | ||
| }; | ||
| toggleEl.addEventListener('click', () => { | ||
| const off = localStorage.getItem(STORAGE_KEY) === 'off'; | ||
| if (off) localStorage.removeItem(STORAGE_KEY); | ||
| else localStorage.setItem(STORAGE_KEY, 'off'); |
Comment on lines
+4
to
+7
| const optedOut = | ||
| typeof window !== 'undefined' && | ||
| window.localStorage?.getItem(STORAGE_KEY) === 'off'; | ||
|
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Phone-home telemetry for both the CLI and
cli.deepgram.com, both reporting into the existingdx-cliSentry project. Opt-out by default-on, configurable per user, can be killed entirely with one env var for CI runs.Sits alongside the new (disabled-pending-budget) Sentry uptime detector for
cli.deepgram.comso both sides of the project produce signal once budget lands.What changed
CLI (
packages/deepctl-telemetry)deepctl-telemetrywith three exports:init_telemetry(config)— lazysentry_sdk.initif telemetry is on, otherwise a no-op. Idempotent.is_enabled(config)— env override (DEEPCTL_TELEMETRY_DISABLED=1) wins, thenconfig.telemetry.enabled(defaultTrue)install_help_notice(config)— monkey-patchesclick.Command.get_helponce at startup so every--helpoutput (group, subcommand, plugin command, anywhere) ends with a dim one-line footerdx-cli. Override viaDEEPCTL_TELEMETRY_DSNfor forks/self-hosted Sentrybefore_sendhook scrubs request bodies, headers, cookies, email/IP/username fromuser, plussend_default_pii=False. Defense-in-depth — Sentry SDK does most of this but breadcrumbs/exception messages can still leak project IDs and file pathstraces_sample_rate=0andprofiles_sample_rate=0so we ship errors and breadcrumbs only, no perf dataCLI wiring
deepctl_core.config.DeepgramConfiggets atelemetry: TelemetryConfigfield withenabled: bool = Truesrc/deepctl/main.pycallsinit_telemetry()andinstall_help_notice()at the very top ofmain(), wrapped in a baretry/exceptso a broken telemetry dep can never crash the CLI itselfpyproject.tomland[tool.uv.sources]workspace member entry, same as every other shippable package.pip install deepctlpulls it in; you can't remove it without uninstalling the CLIWeb (
web/)@sentry/astrointegration inastro.config.mjs, init code inweb/sentry.client.config.tslocalStorage.dg_telemetry. If'off', Sentry never initializes that page loadTelemetry: on/offwith a toggle button that flips the flag and reloadstracesSampleRate/replaysSessionSampleRate/replaysOnErrorSampleRateall 0. Errors onlyNotice copy
When opted out:
Rendered with
click.style(..., dim=True)so it sits quietly under the help.Test plan
make check— ruff format/lint + mypy strict, all 115 source files cleanuv run pytest packages/deepctl-telemetry/tests— 5 passuv run dg --help— footer shows on telemetry onDEEPCTL_TELEMETRY_DISABLED=1 uv run dg --help— footer shows "off"uv run dg api --help— footer also shows on subcommand help (monkey-patch propagation)npm run buildinweb/— builds clean, source maps upload to Sentry whenSENTRY_AUTH_TOKENis set in CIPre-existing failures
5 tests in
packages/deepctl-core/tests/unit/test_base.py::TestBaseCommand::test_output_result_*fail on this branch and on baremain. Not introduced here.Related
telemetry.dx.deepgram.comcli.deepgram.comalready created (id 7211778), sits disabled until on-demand seat budget is approved