Skip to content

Commit 8b5622d

Browse files
committed
Remove Sentry telemetry system from CodeGraph
Eliminates anonymous error reporting functionality that was collecting stack traces and error context via Sentry. Removes all telemetry-related code, configuration options, and documentation references.
1 parent 9bb8e96 commit 8b5622d

14 files changed

Lines changed: 11 additions & 286 deletions

File tree

CLAUDE.md

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,6 @@ src/
7878
│ ├── index.ts # MCPServer class
7979
│ ├── tools.ts # MCP tool definitions
8080
│ └── transport.ts # Stdio transport
81-
├── sentry.ts # Error tracking/reporting
8281
└── bin/codegraph.ts # CLI entry point
8382
```
8483

README.md

Lines changed: 4 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -165,7 +165,6 @@ The interactive installer will:
165165
- Prompt to install `codegraph` globally (needed for hooks & MCP server to work)
166166
- Configure the MCP server in `~/.claude.json`
167167
- Set up auto-allow permissions for CodeGraph tools
168-
- Ask about [anonymous error reporting](#-telemetry) (opt-out available)
169168
- Add global instructions to `~/.claude/CLAUDE.md` (teaches Claude how to use CodeGraph)
170169
- Install Claude Code hooks for automatic index syncing
171170
- Optionally initialize your current project
@@ -311,11 +310,10 @@ The installer will:
311310
1. Prompt to install `codegraph` globally (needed for hooks & MCP server)
312311
2. Ask for installation location (global `~/.claude` or local `./.claude`)
313312
3. Optionally set up auto-allow permissions
314-
4. Ask about [anonymous error reporting](#-telemetry) (opt-out available)
315-
5. Configure the MCP server in `claude.json`
316-
6. Add global instructions to `~/.claude/CLAUDE.md` (teaches Claude how to use CodeGraph)
317-
7. Install Claude Code hooks for automatic index syncing
318-
8. For local installs: initialize and index the current project
313+
4. Configure the MCP server in `claude.json`
314+
5. Add global instructions to `~/.claude/CLAUDE.md` (teaches Claude how to use CodeGraph)
315+
6. Install Claude Code hooks for automatic index syncing
316+
7. For local installs: initialize and index the current project
319317

320318
### `codegraph init [path]`
321319

@@ -711,27 +709,6 @@ Run `codegraph init` in your project directory first.
711709
- Check if the file's language is supported
712710
- Verify the file isn't excluded by config patterns
713711

714-
## 📡 Telemetry
715-
716-
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).
717-
718-
**What is collected:**
719-
- Error type, message, and stack trace (includes local file paths in the trace)
720-
- CodeGraph version and process name (CLI or MCP server)
721-
722-
**What is NOT collected:**
723-
- Source code contents
724-
- File contents or repository data
725-
- Personal information or environment variables
726-
727-
**To opt out**, set the environment variable before running CodeGraph:
728-
729-
```bash
730-
export CODEGRAPH_TELEMETRY=off
731-
```
732-
733-
---
734-
735712
## 📄 License
736713

737714
MIT

src/bin/codegraph.ts

Lines changed: 0 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,6 @@ import * as path from 'path';
2828
import * as fs from 'fs';
2929
import { spawn } from 'child_process';
3030
import { getCodeGraphDir, findNearestCodeGraphRoot, isInitialized } from '../directory';
31-
import { initSentry, captureException } from '../sentry';
3231

3332
// Lazy-load heavy modules (CodeGraph, runInstaller) to keep CLI startup fast.
3433
async function loadCodeGraph(): Promise<typeof import('../index')> {
@@ -47,19 +46,10 @@ async function loadCodeGraph(): Promise<typeof import('../index')> {
4746
type IndexProgress = import('../index').IndexProgress;
4847

4948
// Check if running with no arguments - run installer
50-
// Read version for Sentry release tag
51-
const pkgVersion = (() => {
52-
try {
53-
return JSON.parse(fs.readFileSync(path.join(__dirname, '..', '..', 'package.json'), 'utf-8')).version;
54-
} catch { return undefined; }
55-
})();
56-
initSentry({ processName: 'codegraph-cli', version: pkgVersion });
57-
5849
if (process.argv.length === 2) {
5950
import('../installer').then(({ runInstaller }) =>
6051
runInstaller()
6152
).catch((err) => {
62-
captureException(err);
6353
console.error('Installation failed:', err instanceof Error ? err.message : String(err));
6454
process.exit(1);
6555
});
@@ -69,12 +59,10 @@ if (process.argv.length === 2) {
6959
}
7060

7161
process.on('uncaughtException', (error) => {
72-
captureException(error);
7362
console.error('[CodeGraph] Uncaught exception:', error);
7463
});
7564

7665
process.on('unhandledRejection', (reason) => {
77-
captureException(reason);
7866
console.error('[CodeGraph] Unhandled rejection:', reason);
7967
});
8068

@@ -296,7 +284,6 @@ program
296284

297285
cg.destroy();
298286
} catch (err) {
299-
captureException(err);
300287
error(`Failed to initialize: ${err instanceof Error ? err.message : String(err)}`);
301288
process.exit(1);
302289
}
@@ -342,7 +329,6 @@ program
342329

343330
success(`Removed CodeGraph from ${projectPath}`);
344331
} catch (err) {
345-
captureException(err);
346332
error(`Failed to uninitialize: ${err instanceof Error ? err.message : String(err)}`);
347333
process.exit(1);
348334
}
@@ -411,7 +397,6 @@ program
411397

412398
cg.destroy();
413399
} catch (err) {
414-
captureException(err);
415400
error(`Failed to index: ${err instanceof Error ? err.message : String(err)}`);
416401
process.exit(1);
417402
}
@@ -469,7 +454,6 @@ program
469454

470455
cg.destroy();
471456
} catch (err) {
472-
captureException(err);
473457
if (!options.quiet) {
474458
error(`Failed to sync: ${err instanceof Error ? err.message : String(err)}`);
475459
}
@@ -581,7 +565,6 @@ program
581565

582566
cg.destroy();
583567
} catch (err) {
584-
captureException(err);
585568
error(`Failed to get status: ${err instanceof Error ? err.message : String(err)}`);
586569
process.exit(1);
587570
}
@@ -644,7 +627,6 @@ program
644627

645628
cg.destroy();
646629
} catch (err) {
647-
captureException(err);
648630
error(`Search failed: ${err instanceof Error ? err.message : String(err)}`);
649631
process.exit(1);
650632
}
@@ -770,7 +752,6 @@ program
770752
console.log();
771753
cg.destroy();
772754
} catch (err) {
773-
captureException(err);
774755
error(`Failed to list files: ${err instanceof Error ? err.message : String(err)}`);
775756
process.exit(1);
776757
}
@@ -898,7 +879,6 @@ program
898879

899880
cg.destroy();
900881
} catch (err) {
901-
captureException(err);
902882
error(`Failed to build context: ${err instanceof Error ? err.message : String(err)}`);
903883
process.exit(1);
904884
}
@@ -949,7 +929,6 @@ program
949929
console.error(chalk.cyan(' codegraph_status') + ' - Get index status');
950930
}
951931
} catch (err) {
952-
captureException(err);
953932
error(`Failed to start server: ${err instanceof Error ? err.message : String(err)}`);
954933
process.exit(1);
955934
}
@@ -1013,7 +992,6 @@ program
1013992
process.on('SIGINT', shutdown);
1014993
process.on('SIGTERM', shutdown);
1015994
} catch (err) {
1016-
captureException(err);
1017995
error(`Failed to start visualizer: ${err instanceof Error ? err.message : String(err)}`);
1018996
process.exit(1);
1019997
}
@@ -1126,7 +1104,6 @@ program
11261104
fs.unlinkSync(lockPath);
11271105
success('Removed lock file. You can now run indexing again.');
11281106
} catch (err) {
1129-
captureException(err);
11301107
error(`Failed to remove lock: ${err instanceof Error ? err.message : String(err)}`);
11311108
process.exit(1);
11321109
}
@@ -1265,7 +1242,6 @@ program
12651242

12661243
cg.destroy();
12671244
} catch (err) {
1268-
captureException(err);
12691245
error(`Affected analysis failed: ${err instanceof Error ? err.message : String(err)}`);
12701246
process.exit(1);
12711247
}

src/db/queries.ts

Lines changed: 0 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -240,16 +240,6 @@ export class QueryBuilder {
240240
updatedAt: node.updatedAt ?? Date.now(),
241241
});
242242
} catch (error) {
243-
const { captureException } = require('../sentry');
244-
captureException(error, {
245-
operation: 'insertNode',
246-
nodeId: node.id,
247-
nodeKind: node.kind,
248-
nodeName: node.name,
249-
filePath: node.filePath,
250-
language: node.language,
251-
startLine: node.startLine,
252-
});
253243
throw error;
254244
}
255245
}

src/errors.ts

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -233,13 +233,8 @@ export function logWarn(message: string, context?: Record<string, unknown>): voi
233233
}
234234

235235
/**
236-
* Log an error message (also sends to Sentry if initialized)
236+
* Log an error message
237237
*/
238238
export function logError(message: string, context?: Record<string, unknown>): void {
239239
currentLogger.error(message, context);
240-
// Lazy import to avoid circular deps
241-
try {
242-
const { captureMessage } = require('./sentry');
243-
captureMessage(message, context);
244-
} catch {}
245240
}

src/extraction/index.ts

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,6 @@ import { QueryBuilder } from '../db/queries';
2020
import { extractFromSource } from './tree-sitter';
2121
import { detectLanguage, isLanguageSupported, initGrammars, loadGrammarsForLanguages } from './grammars';
2222
import { logDebug, logWarn } from '../errors';
23-
import { captureException } from '../sentry';
2423
import { validatePathWithinRoot, normalizePath } from '../utils';
2524
import picomatch from 'picomatch';
2625

@@ -257,7 +256,6 @@ function scanDirectoryWalk(
257256
try {
258257
entries = fs.readdirSync(dir, { withFileTypes: true });
259258
} catch (error) {
260-
captureException(error, { operation: 'walk-directory', dir });
261259
logDebug('Skipping unreadable directory', { dir, error: String(error) });
262260
return;
263261
}
@@ -548,7 +546,6 @@ export class ExtractionOrchestrator {
548546
stats = await fsp.stat(fullPath);
549547
content = await fsp.readFile(fullPath, 'utf-8');
550548
} catch (error) {
551-
captureException(error, { operation: 'extract-file', filePath: fullPath });
552549
return {
553550
nodes: [],
554551
edges: [],
@@ -744,7 +741,6 @@ export class ExtractionOrchestrator {
744741
try {
745742
content = fs.readFileSync(fullPath, 'utf-8');
746743
} catch (error) {
747-
captureException(error, { operation: 'sync-read-file', filePath });
748744
logDebug('Skipping unreadable file during sync', { filePath, error: String(error) });
749745
continue;
750746
}
@@ -796,7 +792,6 @@ export class ExtractionOrchestrator {
796792
try {
797793
content = fs.readFileSync(fullPath, 'utf-8');
798794
} catch (error) {
799-
captureException(error, { operation: 'sync-read-file', filePath });
800795
logDebug('Skipping unreadable file during sync', { filePath, error: String(error) });
801796
continue;
802797
}
@@ -876,7 +871,6 @@ export class ExtractionOrchestrator {
876871
try {
877872
content = fs.readFileSync(fullPath, 'utf-8');
878873
} catch (error) {
879-
captureException(error, { operation: 'detect-changes-read-file', filePath });
880874
logDebug('Skipping unreadable file while detecting changes', { filePath, error: String(error) });
881875
continue;
882876
}
@@ -927,7 +921,6 @@ export class ExtractionOrchestrator {
927921
try {
928922
content = fs.readFileSync(fullPath, 'utf-8');
929923
} catch (error) {
930-
captureException(error, { operation: 'detect-changes-read-file', filePath });
931924
logDebug('Skipping unreadable file while detecting changes', { filePath, error: String(error) });
932925
continue;
933926
}

src/extraction/tree-sitter.ts

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,6 @@ import {
1717
UnresolvedReference,
1818
} from '../types';
1919
import { getParser, detectLanguage, isLanguageSupported } from './grammars';
20-
import { captureException } from '../sentry';
2120

2221
/**
2322
* Generate a unique node ID
@@ -961,7 +960,6 @@ export class TreeSitterExtractor {
961960
this.visitNode(this.tree.rootNode);
962961
this.nodeStack.pop();
963962
} catch (error) {
964-
captureException(error, { operation: 'tree-sitter-parse', filePath: this.filePath, language: this.language });
965963
this.errors.push({
966964
message: `Parse error: ${error instanceof Error ? error.message : String(error)}`,
967965
severity: 'error',
@@ -2514,7 +2512,6 @@ export class LiquidExtractor {
25142512
// Extract assign statements as variables
25152513
this.extractAssignments(fileNode.id);
25162514
} catch (error) {
2517-
captureException(error, { operation: 'liquid-extraction', filePath: this.filePath });
25182515
this.errors.push({
25192516
message: `Liquid extraction error: ${error instanceof Error ? error.message : String(error)}`,
25202517
severity: 'error',
@@ -2856,7 +2853,6 @@ export class SvelteExtractor {
28562853
this.processScriptBlock(block, componentNode.id);
28572854
}
28582855
} catch (error) {
2859-
captureException(error, { operation: 'svelte-extraction', filePath: this.filePath });
28602856
this.errors.push({
28612857
message: `Svelte extraction error: ${error instanceof Error ? error.message : String(error)}`,
28622858
severity: 'error',
@@ -3047,7 +3043,6 @@ export class DfmExtractor {
30473043
const fileNode = this.createFileNode();
30483044
this.parseComponents(fileNode.id);
30493045
} catch (error) {
3050-
captureException(error, { operation: 'dfm-extraction', filePath: this.filePath });
30513046
this.errors.push({
30523047
message: `DFM extraction error: ${error instanceof Error ? error.message : String(error)}`,
30533048
severity: 'error',

src/installer/config-writer.ts

Lines changed: 4 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -100,22 +100,18 @@ function writeJsonFile(filePath: string, data: Record<string, any>): void {
100100
/**
101101
* Get the MCP server configuration
102102
*/
103-
function getMcpServerConfig(options?: { telemetry?: boolean }): Record<string, any> {
104-
const config: Record<string, any> = {
103+
function getMcpServerConfig(): Record<string, any> {
104+
return {
105105
type: 'stdio',
106106
command: 'codegraph',
107107
args: ['serve', '--mcp'],
108108
};
109-
if (options?.telemetry === false) {
110-
config.env = { CODEGRAPH_TELEMETRY: 'off' };
111-
}
112-
return config;
113109
}
114110

115111
/**
116112
* Write the MCP server configuration to claude.json
117113
*/
118-
export function writeMcpConfig(location: InstallLocation, options?: { telemetry?: boolean }): void {
114+
export function writeMcpConfig(location: InstallLocation): void {
119115
const claudeJsonPath = getClaudeJsonPath(location);
120116
const config = readJsonFile(claudeJsonPath);
121117

@@ -125,7 +121,7 @@ export function writeMcpConfig(location: InstallLocation, options?: { telemetry?
125121
}
126122

127123
// Add or update codegraph server
128-
config.mcpServers.codegraph = getMcpServerConfig(options);
124+
config.mcpServers.codegraph = getMcpServerConfig();
129125

130126
writeJsonFile(claudeJsonPath, config);
131127
}

src/installer/index.ts

Lines changed: 2 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -55,21 +55,9 @@ export async function runInstaller(): Promise<void> {
5555
const autoAllow = await promptAutoAllow();
5656
console.log();
5757

58-
// Step 4: Ask about anonymous error reporting
59-
console.log(chalk.bold(' Send anonymous error reports?') + chalk.dim(' (Helps fix bugs — no source code collected)'));
60-
console.log();
61-
const enableTelemetry = await promptConfirm('Enable anonymous error reporting', true);
62-
63-
if (!enableTelemetry) {
64-
info('Telemetry disabled');
65-
} else {
66-
success('Anonymous error reporting enabled');
67-
}
68-
console.log();
69-
70-
// Step 5: Write MCP configuration (includes telemetry env if opted out)
58+
// Step 4: Write MCP configuration
7159
const alreadyHasMcp = hasMcpConfig(location);
72-
writeMcpConfig(location, { telemetry: enableTelemetry });
60+
writeMcpConfig(location);
7361

7462
if (alreadyHasMcp) {
7563
success(`Updated MCP server in ${location === 'global' ? '~/.claude.json' : './.claude.json'}`);

0 commit comments

Comments
 (0)