mirror of
https://github.com/basicmachines-co/basic-memory
synced 2026-06-21 13:47:35 +00:00
150a8175b0
Implements issue #477: Add anonymous usage telemetry using OpenPanel. Core Features: - Anonymous telemetry with random UUID installation ID - Homebrew-style opt-out (on by default, easy to disable) - Fire-and-forget tracking (errors never break the app) - No personal data or note content collection Configuration: - Added telemetry_enabled field to BasicMemoryConfig (default: True) - Added telemetry_notice_shown field to track first-run notice - Environment variable override: BASIC_MEMORY_TELEMETRY_ENABLED CLI Commands: - bm telemetry enable - Enable telemetry - bm telemetry disable - Disable telemetry - bm telemetry status - Show current status and what's collected Integration: - CLI app startup tracking with command name - MCP server startup tracking - Global properties sent with every event (version, OS, arch, etc.) Testing: - Comprehensive unit tests for all telemetry functions - Tests for config integration and environment variables - Tests for first-run notice behavior - Tests for error handling (telemetry never breaks the app) Files Changed: - pyproject.toml: Added openpanel dependency - src/basic_memory/config.py: Added telemetry configuration fields - src/basic_memory/telemetry.py: Core telemetry module - src/basic_memory/cli/commands/telemetry.py: CLI commands - src/basic_memory/cli/app.py: Added CLI startup tracking - src/basic_memory/mcp/server.py: Added MCP startup tracking - tests/test_telemetry.py: Comprehensive unit tests Co-authored-by: Paul Hernandez <phernandez@users.noreply.github.com> Signed-off-by: claude[bot] <41898282+claude[bot]@users.noreply.github.com>
100 lines
3.6 KiB
Python
100 lines
3.6 KiB
Python
"""CLI commands for telemetry management."""
|
|
|
|
import typer
|
|
from rich.console import Console
|
|
from rich.panel import Panel
|
|
from rich.table import Table
|
|
|
|
from basic_memory.config import ConfigManager
|
|
from basic_memory.telemetry import get_install_id, is_telemetry_enabled
|
|
|
|
app = typer.Typer(help="Manage anonymous usage telemetry")
|
|
console = Console()
|
|
|
|
|
|
@app.command()
|
|
def enable():
|
|
"""Enable anonymous usage telemetry."""
|
|
try:
|
|
config_manager = ConfigManager()
|
|
config = config_manager.load_config()
|
|
config.telemetry_enabled = True
|
|
config_manager.save_config(config)
|
|
|
|
console.print("[green]✓[/green] Telemetry enabled")
|
|
console.print(
|
|
"Thank you for helping improve Basic Memory! Details: https://memory.basicmachines.co/telemetry"
|
|
)
|
|
except Exception as e:
|
|
console.print(f"[red]Error enabling telemetry:[/red] {e}")
|
|
raise typer.Exit(1)
|
|
|
|
|
|
@app.command()
|
|
def disable():
|
|
"""Disable anonymous usage telemetry."""
|
|
try:
|
|
config_manager = ConfigManager()
|
|
config = config_manager.load_config()
|
|
config.telemetry_enabled = False
|
|
config_manager.save_config(config)
|
|
|
|
console.print("[green]✓[/green] Telemetry disabled")
|
|
console.print(
|
|
"You can delete your installation ID at: ~/.basic-memory/.install_id"
|
|
)
|
|
except Exception as e:
|
|
console.print(f"[red]Error disabling telemetry:[/red] {e}")
|
|
raise typer.Exit(1)
|
|
|
|
|
|
@app.command()
|
|
def status():
|
|
"""Show current telemetry status and what data is collected."""
|
|
try:
|
|
enabled = is_telemetry_enabled()
|
|
install_id = get_install_id()
|
|
|
|
# Status table
|
|
status_table = Table(show_header=False, box=None)
|
|
status_table.add_row("Status", "[green]Enabled[/green]" if enabled else "[red]Disabled[/red]")
|
|
status_table.add_row("Installation ID", install_id)
|
|
status_table.add_row("ID File", "~/.basic-memory/.install_id")
|
|
|
|
console.print(Panel(status_table, title="Telemetry Status"))
|
|
|
|
# What we collect
|
|
collected_table = Table(title="Data Collected (when enabled)", show_header=True)
|
|
collected_table.add_column("Category", style="cyan")
|
|
collected_table.add_column("Examples", style="white")
|
|
|
|
collected_table.add_row("App Info", "version, mode (CLI/MCP)")
|
|
collected_table.add_row("System Info", "OS, Python version, architecture")
|
|
collected_table.add_row("Feature Usage", "MCP tools called, CLI commands used")
|
|
collected_table.add_row("Performance", "sync duration, entity counts")
|
|
collected_table.add_row("Errors", "error types (sanitized, no personal data)")
|
|
|
|
console.print(collected_table)
|
|
|
|
# What we never collect
|
|
never_table = Table(title="Never Collected", show_header=True)
|
|
never_table.add_column("Category", style="red")
|
|
|
|
never_table.add_row("Note content or file contents")
|
|
never_table.add_row("File names or paths")
|
|
never_table.add_row("Personal information")
|
|
never_table.add_row("IP addresses")
|
|
|
|
console.print(never_table)
|
|
|
|
# Commands
|
|
console.print("\n[bold]Commands:[/bold]")
|
|
console.print(" Enable: [cyan]bm telemetry enable[/cyan]")
|
|
console.print(" Disable: [cyan]bm telemetry disable[/cyan]")
|
|
console.print(" Delete installation ID: [cyan]rm ~/.basic-memory/.install_id[/cyan]")
|
|
console.print("\n[bold]More info:[/bold] https://memory.basicmachines.co/telemetry")
|
|
|
|
except Exception as e:
|
|
console.print(f"[red]Error getting telemetry status:[/red] {e}")
|
|
raise typer.Exit(1)
|