fix: Add telemetry opt-out via installer prompt and env var
Sentry error reporting can now be disabled by: 1. Declining during the interactive installer (sets CODEGRAPH_TELEMETRY=off in the MCP server config env) 2. Setting CODEGRAPH_TELEMETRY=off in your shell environment README updated with a Telemetry section documenting what is collected and how to opt out. Closes #68 Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 4.6
parent
c401a96d17
commit
5a185eb736
@@ -165,6 +165,7 @@ The interactive installer will:
|
|||||||
- Prompt to install `codegraph` globally (needed for hooks & MCP server to work)
|
- Prompt to install `codegraph` globally (needed for hooks & MCP server to work)
|
||||||
- Configure the MCP server in `~/.claude.json`
|
- Configure the MCP server in `~/.claude.json`
|
||||||
- Set up auto-allow permissions for CodeGraph tools
|
- Set up auto-allow permissions for CodeGraph tools
|
||||||
|
- Ask about [anonymous error reporting](#-telemetry) (opt-out available)
|
||||||
- Add global instructions to `~/.claude/CLAUDE.md` (teaches Claude how to use CodeGraph)
|
- Add global instructions to `~/.claude/CLAUDE.md` (teaches Claude how to use CodeGraph)
|
||||||
- Install Claude Code hooks for automatic index syncing
|
- Install Claude Code hooks for automatic index syncing
|
||||||
- Optionally initialize your current project
|
- Optionally initialize your current project
|
||||||
@@ -309,11 +310,12 @@ npx @colbymchenry/codegraph # Run via npx (no global install needed)
|
|||||||
The installer will:
|
The installer will:
|
||||||
1. Prompt to install `codegraph` globally (needed for hooks & MCP server)
|
1. Prompt to install `codegraph` globally (needed for hooks & MCP server)
|
||||||
2. Ask for installation location (global `~/.claude` or local `./.claude`)
|
2. Ask for installation location (global `~/.claude` or local `./.claude`)
|
||||||
3. Configure the MCP server in `claude.json`
|
3. Optionally set up auto-allow permissions
|
||||||
4. Optionally set up auto-allow permissions
|
4. Ask about [anonymous error reporting](#-telemetry) (opt-out available)
|
||||||
5. Add global instructions to `~/.claude/CLAUDE.md` (teaches Claude how to use CodeGraph)
|
5. Configure the MCP server in `claude.json`
|
||||||
6. Install Claude Code hooks for automatic index syncing
|
6. Add global instructions to `~/.claude/CLAUDE.md` (teaches Claude how to use CodeGraph)
|
||||||
7. For local installs: initialize and index the current project
|
7. Install Claude Code hooks for automatic index syncing
|
||||||
|
8. For local installs: initialize and index the current project
|
||||||
|
|
||||||
### `codegraph init [path]`
|
### `codegraph init [path]`
|
||||||
|
|
||||||
@@ -709,6 +711,25 @@ Run `codegraph init` in your project directory first.
|
|||||||
- Check if the file's language is supported
|
- Check if the file's language is supported
|
||||||
- Verify the file isn't excluded by config patterns
|
- Verify the file isn't excluded by config patterns
|
||||||
|
|
||||||
|
## 📡 Telemetry
|
||||||
|
|
||||||
|
CodeGraph collects anonymous error reports via [Sentry](https://sentry.io) to help diagnose and fix bugs. This is **enabled by default** in production environments (disabled in development/test).
|
||||||
|
|
||||||
|
**What is collected:**
|
||||||
|
- Error type, message, and stack trace (includes local file paths in the trace)
|
||||||
|
- CodeGraph version and process name (CLI or MCP server)
|
||||||
|
|
||||||
|
**What is NOT collected:**
|
||||||
|
- Source code contents
|
||||||
|
- File contents or repository data
|
||||||
|
- Personal information or environment variables
|
||||||
|
|
||||||
|
**To opt out**, set the environment variable before running CodeGraph:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
export CODEGRAPH_TELEMETRY=off
|
||||||
|
```
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## 📄 License
|
## 📄 License
|
||||||
|
|||||||
@@ -100,18 +100,22 @@ function writeJsonFile(filePath: string, data: Record<string, any>): void {
|
|||||||
/**
|
/**
|
||||||
* Get the MCP server configuration
|
* Get the MCP server configuration
|
||||||
*/
|
*/
|
||||||
function getMcpServerConfig(): Record<string, any> {
|
function getMcpServerConfig(options?: { telemetry?: boolean }): Record<string, any> {
|
||||||
return {
|
const config: Record<string, any> = {
|
||||||
type: 'stdio',
|
type: 'stdio',
|
||||||
command: 'codegraph',
|
command: 'codegraph',
|
||||||
args: ['serve', '--mcp'],
|
args: ['serve', '--mcp'],
|
||||||
};
|
};
|
||||||
|
if (options?.telemetry === false) {
|
||||||
|
config.env = { CODEGRAPH_TELEMETRY: 'off' };
|
||||||
|
}
|
||||||
|
return config;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Write the MCP server configuration to claude.json
|
* Write the MCP server configuration to claude.json
|
||||||
*/
|
*/
|
||||||
export function writeMcpConfig(location: InstallLocation): void {
|
export function writeMcpConfig(location: InstallLocation, options?: { telemetry?: boolean }): void {
|
||||||
const claudeJsonPath = getClaudeJsonPath(location);
|
const claudeJsonPath = getClaudeJsonPath(location);
|
||||||
const config = readJsonFile(claudeJsonPath);
|
const config = readJsonFile(claudeJsonPath);
|
||||||
|
|
||||||
@@ -121,7 +125,7 @@ export function writeMcpConfig(location: InstallLocation): void {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Add or update codegraph server
|
// Add or update codegraph server
|
||||||
config.mcpServers.codegraph = getMcpServerConfig();
|
config.mcpServers.codegraph = getMcpServerConfig(options);
|
||||||
|
|
||||||
writeJsonFile(claudeJsonPath, config);
|
writeJsonFile(claudeJsonPath, config);
|
||||||
}
|
}
|
||||||
|
|||||||
+20
-8
@@ -51,9 +51,25 @@ export async function runInstaller(): Promise<void> {
|
|||||||
const location = await promptInstallLocation();
|
const location = await promptInstallLocation();
|
||||||
console.log();
|
console.log();
|
||||||
|
|
||||||
// Step 3: Write MCP configuration (always uses npx for reliability)
|
// Step 3: Ask about auto-allow permissions
|
||||||
|
const autoAllow = await promptAutoAllow();
|
||||||
|
console.log();
|
||||||
|
|
||||||
|
// Step 4: Ask about anonymous error reporting
|
||||||
|
console.log(chalk.bold(' Send anonymous error reports?') + chalk.dim(' (Helps fix bugs — no source code collected)'));
|
||||||
|
console.log();
|
||||||
|
const enableTelemetry = await promptConfirm('Enable anonymous error reporting', true);
|
||||||
|
|
||||||
|
if (!enableTelemetry) {
|
||||||
|
info('Telemetry disabled');
|
||||||
|
} else {
|
||||||
|
success('Anonymous error reporting enabled');
|
||||||
|
}
|
||||||
|
console.log();
|
||||||
|
|
||||||
|
// Step 5: Write MCP configuration (includes telemetry env if opted out)
|
||||||
const alreadyHasMcp = hasMcpConfig(location);
|
const alreadyHasMcp = hasMcpConfig(location);
|
||||||
writeMcpConfig(location);
|
writeMcpConfig(location, { telemetry: enableTelemetry });
|
||||||
|
|
||||||
if (alreadyHasMcp) {
|
if (alreadyHasMcp) {
|
||||||
success(`Updated MCP server in ${location === 'global' ? '~/.claude.json' : './.claude.json'}`);
|
success(`Updated MCP server in ${location === 'global' ? '~/.claude.json' : './.claude.json'}`);
|
||||||
@@ -61,10 +77,6 @@ export async function runInstaller(): Promise<void> {
|
|||||||
success(`Added MCP server to ${location === 'global' ? '~/.claude.json' : './.claude.json'}`);
|
success(`Added MCP server to ${location === 'global' ? '~/.claude.json' : './.claude.json'}`);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Step 4: Ask about auto-allow permissions
|
|
||||||
const autoAllow = await promptAutoAllow();
|
|
||||||
console.log();
|
|
||||||
|
|
||||||
if (autoAllow) {
|
if (autoAllow) {
|
||||||
const alreadyHasPerms = hasPermissions(location);
|
const alreadyHasPerms = hasPermissions(location);
|
||||||
writePermissions(location);
|
writePermissions(location);
|
||||||
@@ -76,7 +88,7 @@ export async function runInstaller(): Promise<void> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Step 5: Write auto-sync hooks
|
// Step 6: Write auto-sync hooks
|
||||||
const alreadyHasHooks = hasHooks(location);
|
const alreadyHasHooks = hasHooks(location);
|
||||||
writeHooks(location);
|
writeHooks(location);
|
||||||
|
|
||||||
@@ -86,7 +98,7 @@ export async function runInstaller(): Promise<void> {
|
|||||||
success(`Added auto-sync hooks to ${location === 'global' ? '~/.claude/settings.json' : './.claude/settings.json'}`);
|
success(`Added auto-sync hooks to ${location === 'global' ? '~/.claude/settings.json' : './.claude/settings.json'}`);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Step 6: Write CLAUDE.md instructions
|
// Step 7: Write CLAUDE.md instructions
|
||||||
const claudeMdResult = writeClaudeMd(location);
|
const claudeMdResult = writeClaudeMd(location);
|
||||||
const claudeMdPath = location === 'global' ? '~/.claude/CLAUDE.md' : './.claude/CLAUDE.md';
|
const claudeMdPath = location === 'global' ? '~/.claude/CLAUDE.md' : './.claude/CLAUDE.md';
|
||||||
|
|
||||||
|
|||||||
@@ -19,12 +19,19 @@ let _tags: Record<string, string> = {};
|
|||||||
/**
|
/**
|
||||||
* Initialize Sentry error reporting.
|
* Initialize Sentry error reporting.
|
||||||
* Safe to call multiple times — subsequent calls update tags/release.
|
* Safe to call multiple times — subsequent calls update tags/release.
|
||||||
|
*
|
||||||
|
* Opt out by setting the environment variable CODEGRAPH_TELEMETRY=off
|
||||||
*/
|
*/
|
||||||
export function initSentry({ processName, version }: { processName: string; version?: string }) {
|
export function initSentry({ processName, version }: { processName: string; version?: string }) {
|
||||||
// Skip in development/test environments
|
// Skip in development/test environments
|
||||||
if (process.env.NODE_ENV === 'development' || process.env.NODE_ENV === 'test' || process.env.VITEST) {
|
if (process.env.NODE_ENV === 'development' || process.env.NODE_ENV === 'test' || process.env.VITEST) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
// Respect user opt-out
|
||||||
|
const telemetry = process.env.CODEGRAPH_TELEMETRY?.toLowerCase();
|
||||||
|
if (telemetry === 'off' || telemetry === '0' || telemetry === 'false') {
|
||||||
|
return;
|
||||||
|
}
|
||||||
_enabled = true;
|
_enabled = true;
|
||||||
_release = `codegraph@${version ?? process.env.npm_package_version ?? 'unknown'}`;
|
_release = `codegraph@${version ?? process.env.npm_package_version ?? 'unknown'}`;
|
||||||
_tags = { processName };
|
_tags = { processName };
|
||||||
|
|||||||
Reference in New Issue
Block a user