Skip to content

Commit d6ff9c7

Browse files
committed
feat: snap coordinates to city centers for privacy (152k+ cities from GeoNames)
Replace deterministic coordinate rounding (~11km) with city center snapping using the GeoNames cities1000 database (152,914 cities across 246 countries). All developers in the same city now share identical coordinates, preventing cross-session tracking. - Add city-centers.json (GeoNames cities1000, pop > 1000) to all 3 extensions - Snap IP geolocation coordinates to canonical city center via normalized name lookup - Fallback for unmatched cities: random placement within 20km radius - Anonymous mode now picks from all 152k+ cities instead of only 50 per country - Remove anonymous-cities.json (replaced by city-centers.json)
1 parent 0b955db commit d6ff9c7

24 files changed

Lines changed: 488 additions & 150 deletions

README.md

Lines changed: 140 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
<p align="center">
99
<a href="#-vs-code">VS Code</a> &nbsp;·&nbsp;
1010
<a href="#-jetbrains">JetBrains</a> &nbsp;·&nbsp;
11+
<a href="#-claude-code">Claude Code</a> &nbsp;·&nbsp;
1112
<a href="#-privacy--security">Privacy</a> &nbsp;·&nbsp;
1213
<a href="#-how-it-works-technically">Technical</a>
1314
</p>
@@ -61,8 +62,8 @@ On [devglobe.xyz](https://devglobe.xyz), you'll find:
6162

6263
1. **Sign in** on [devglobe.xyz](https://devglobe.xyz) with GitHub
6364
2. **Copy your API key** from the site settings
64-
3. **Install the extension** in VS Code or your JetBrains IDE
65-
4. **Paste the key** in the extension sidebar
65+
3. **Install the extension** in VS Code, your JetBrains IDE, or Claude Code
66+
4. **Paste the key** in the extension sidebar (or config file for Claude Code)
6667
5. **You're online** — your marker appears on the globe
6768

6869
The extension sends a **heartbeat every 30 seconds** as long as you're actively coding. If you stop typing for more than 1 minute, heartbeats pause automatically. **After 10 minutes of inactivity, you disappear from the globe** and are considered inactive.
@@ -83,7 +84,8 @@ The extension sends a **heartbeat every 30 seconds** as long as you're actively
8384
|---------|-------------|
8485
| **Live heartbeat** | Sends your activity every 30s. Auto-pauses after 1 min of inactivity. |
8586
| **Language detection** | Detects 48+ languages from your active editor tab. |
86-
| **Git integration** | Detects your repo from the git remote. Counts insertions/deletions over 24h on each new commit. |
87+
| **Git integration** | Detects your repo from the git remote. Commit stats (insertions/deletions) are verified server-side via the GitHub API — never sent by the extension. |
88+
| **Anonymous mode** | Hide your exact location — your marker is placed on a random city in your country (from a database of 152,000+ cities worldwide). |
8789
| **Status message** | Write what you're working on — visible on your globe profile. |
8890
| **Repo sharing** | **You decide.** Your repo name is never shown unless you explicitly enable this toggle (disabled by default). |
8991
| **Offline recovery** | Detects connection loss and automatically resumes when the network is back. |
@@ -126,7 +128,8 @@ Same features as the VS Code extension, adapted for the JetBrains platform:
126128
|---------|-------------|
127129
| **Live heartbeat** | 30s interval, pauses after 1 min of inactivity. |
128130
| **Language detection** | Uses JetBrains' native FileType system — supports all languages in your IDE without configuration. |
129-
| **Git integration** | Same repo detection + commit stats. |
131+
| **Git integration** | Same repo detection. Commit stats verified server-side via GitHub API. |
132+
| **Anonymous mode** | Same privacy toggle as VS Code — a random city in your country (from a database of 152,000+ cities worldwide). |
130133
| **Status message** | Editable from the side panel, persists in IDE settings. |
131134
| **Repo sharing** | Same toggle as VS Code — your repo stays invisible unless explicitly enabled. |
132135
| **Offline recovery** | Automatic detection + resume when the network is back. |
@@ -140,6 +143,99 @@ Same features as the VS Code extension, adapted for the JetBrains platform:
140143

141144
---
142145

146+
## Claude Code
147+
148+
### Installation
149+
150+
```bash
151+
git clone https://github.com/Nako0/devglobe-extension
152+
```
153+
154+
Open Claude Code **from the same folder**, then run these two slash commands:
155+
156+
```bash
157+
/plugin marketplace add ./devglobe-extension/claude-code-plugin
158+
/plugin install devglobe@devglobe
159+
```
160+
161+
### Setup
162+
163+
Save your API key using one of these methods:
164+
165+
**Option A** — Environment variable (add to `~/.zshrc` or `~/.bashrc`):
166+
```bash
167+
export DEVGLOBE_API_KEY="your-api-key-here"
168+
```
169+
170+
**Option B** — Config file:
171+
```bash
172+
mkdir -p ~/.devglobe
173+
echo "your-api-key-here" > ~/.devglobe/api_key
174+
```
175+
176+
### Features
177+
178+
| Feature | Description |
179+
|---------|-------------|
180+
| **Live heartbeat** | Hooks into Claude Code events. Sends a heartbeat at most once per minute. |
181+
| **Language detection** | Detects the language from file extensions being edited. |
182+
| **Git integration** | Detects your repo from the git remote. |
183+
| **Anonymous mode** | Hide your exact location — placed on a random city in your country (from a database of 152,000+ cities worldwide). Set `"anonymousMode": true` in `~/.devglobe/config.json`. |
184+
| **Repo sharing** | Set `"shareRepo": true` in `~/.devglobe/config.json` to display your repo on the globe. |
185+
186+
### Configuration
187+
188+
Create `~/.devglobe/config.json`:
189+
190+
```json
191+
{
192+
"shareRepo": true,
193+
"anonymousMode": false
194+
}
195+
```
196+
197+
---
198+
199+
## GitHub App — Verified commit stats
200+
201+
DevGlobe uses a [GitHub App](https://github.com/apps/devglobeapp) to display **verified** commit statistics (insertions & deletions per week) on featured projects. This replaces the old client-side stats collection, which could be falsified.
202+
203+
### How it works
204+
205+
1. On your DevGlobe profile, click **"Connect repo"** in the Projects section
206+
2. You're redirected to GitHub to install the [DevGlobe App](https://github.com/apps/devglobeapp) on the repos you choose
207+
3. A server-side job syncs commit stats from the GitHub API **every 15 minutes**
208+
4. Stats are displayed on your featured projects in the carousel and on your profile
209+
210+
### What the GitHub App can access
211+
212+
The app requests **Metadata: Read-only** — the most minimal GitHub permission available. It uses the `GET /repos/{owner/repo}/stats/contributors` endpoint to retrieve aggregated contribution statistics (weekly insertions and deletions per contributor).
213+
214+
| Data | Access |
215+
|------|--------|
216+
| Aggregated commit statistics (insertions/deletions per week) | **Read** |
217+
| Repo metadata (name, description, stars, forks) | **Read** |
218+
| Your source code | **No access** |
219+
| Your file contents or file names | **No access** |
220+
| Your commit messages | **No access** |
221+
| Your issues and pull requests | **No access** |
222+
| Your repo settings | **No access** |
223+
| Your actions/workflows | **No access** |
224+
| Your collaborators list | **No access** |
225+
226+
### What happens if you don't install it
227+
228+
- You can still use DevGlobe normally (heartbeats, coding time, leaderboard)
229+
- You can still add projects to your profile
230+
- You just **can't feature a project** in the carousel without connecting its repo
231+
- No commit stats will be displayed on your profile
232+
233+
### How to uninstall
234+
235+
Go to [github.com/settings/installations](https://github.com/settings/installations), find "DevGlobe", and click **Uninstall**. Your coding time and profile data on DevGlobe remain intact.
236+
237+
---
238+
143239
## Privacy & Security
144240

145241
We know that when you install an extension, you trust the developer. We take that seriously. Here's exactly what the extension does — no gray area.
@@ -149,9 +245,10 @@ We know that when you install an extension, you trust the developer. We take tha
149245
| Data | Sent | Detail |
150246
|------|------|--------|
151247
| Programming language | Yes | The language name of your active tab (e.g. "TypeScript"). Nothing else. |
152-
| Approximate location | Yes | City + coordinates **rounded to ~11 km**. You appear as an area on the globe, not an address. |
153-
| Repo name | **You decide** | `owner/repo` format only. **Sharing is disabled by default.** Nobody sees your repo unless you explicitly enable the "Share repo" toggle. |
154-
| Commit stats | Yes | Number of insertions and deletions over 24h. Sent only once per new detected commit. |
248+
| Approximate location | Yes | City + coordinates **snapped to your city center** (from a database of 152,000+ cities). You appear as an area on the globe, not an address. |
249+
| Repo name | Always sent | `owner/repo` is always sent to the server (used for featured project score calculation), but **displayed on the globe only if you enable the "Share repo" toggle** (disabled by default). |
250+
| Commit stats | **Never by the extension** | Insertions/deletions are fetched **server-side** from the GitHub API via the GitHub App. The extension never reads or sends commit data. |
251+
| Anonymous mode | **You decide** | When enabled, your real coordinates are replaced with a random city in your country (from a database of 152,000+ cities worldwide). Your actual location is never sent to DevGlobe. |
155252
| Coding time | Yes | Accumulated per day, per language. |
156253
| Status message | Yes | Only what you write yourself. |
157254

@@ -191,6 +288,7 @@ Your DevGlobe API key is **never stored in plain text**.
191288
|-----|----------------|
192289
| VS Code | **SecretStorage** — your OS system keychain (macOS Keychain, Windows Credential Manager, Linux libsecret) |
193290
| JetBrains | **PasswordSafe** — the IDE's native credential manager, backed by the OS keychain |
291+
| Claude Code | **Environment variable** (`DEVGLOBE_API_KEY`) or **config file** (`~/.devglobe/api_key`) |
194292

195293
The VS Code extension automatically migrates old keys that were stored in plain text in `settings.json` to the secure keychain.
196294

@@ -203,7 +301,7 @@ The VS Code extension automatically migrates old keys that were stored in plain
203301

204302
### Open source
205303

206-
Both extensions are open source. You can read every line of code that runs on your machine. That's the purpose of this repository.
304+
All extensions are open source. You can read every line of code that runs on your machine. That's the purpose of this repository.
207305

208306
---
209307

@@ -216,13 +314,13 @@ Every 30 seconds, if you've typed code in the last minute, the extension sends a
216314
```
217315
{
218316
api_key, // your identifier (stored in the OS keychain)
219-
hour, // 0-23
220-
latitude, longitude, // rounded to 1 decimal (~11 km)
317+
latitude, longitude, // snapped to city center (152k+ cities)
221318
city, // "Paris, France"
222319
language, // "TypeScript"
223-
repo, // "owner/repo" (sent to the backend but display on the globe depends on your preferences, sending to the backend is used for featured project score calculation)
224-
share_repo, // true/false
225-
insertions, deletions // git stats 24h (on new commit only)
320+
editor, // "vscode", "intellij", "claude-code", etc.
321+
repo, // "owner/repo" (always sent for score calculation, but only visible on the globe if share_repo is true)
322+
share_repo, // true/false — controls whether the repo name is displayed on your profile
323+
anonymous, // true/false — when true, coordinates are a random city
226324
}
227325
```
228326

@@ -232,12 +330,19 @@ The server responds with today's total coding time. The extension updates the di
232330

233331
- **VS Code**: reads the `languageId` of the active editor, then translates it via a table of 48+ languages (JavaScript, TypeScript, Python, Rust, Go, Kotlin, etc.)
234332
- **JetBrains**: uses the IDE's native `FileType` system — no manual table, automatically supports all languages your IDE supports
333+
- **Claude Code**: detects the language from the file extension of edited files
235334

236335
### Git integration
237336

238337
The extension runs `git remote get-url origin` in your active file's directory and extracts the `owner/repo` identifier from the URL (SSH or HTTPS). The result is cached for 5 minutes.
239338

240-
When a new commit is detected (via `git rev-parse HEAD`), the extension counts insertions and deletions over the last 24h via `git log --shortstat`. **No code content, commit message or file name is read.**
339+
**The extension never reads commits, diffs, or file contents.** Commit statistics (insertions/deletions) are fetched entirely server-side via the GitHub API using the token granted by the [GitHub App](#-github-app--verified-commit-stats). This prevents falsification — the stats displayed on DevGlobe always match the real data on GitHub.
340+
341+
### Anonymous mode
342+
343+
When anonymous mode is enabled, the extension replaces your real coordinates with a **random city in your country**, chosen from a database of 152,000+ cities worldwide (GeoNames). Your actual location is never transmitted to DevGlobe. The random city is selected once per session and stays consistent until you restart your IDE or toggle the mode.
344+
345+
On the globe, your profile displays an "anonymous mode" badge instead of your city name.
241346

242347
### Offline detection
243348

@@ -253,7 +358,7 @@ vscode-extension/
253358
│ ├── heartbeat.ts # HTTP calls to the database
254359
│ ├── sidebar.ts # Side panel (webview HTML/CSS/JS)
255360
│ ├── geo.ts # IP geolocation (dual provider + fallback)
256-
│ ├── git.ts # Repo detection + commit stats
361+
│ ├── git.ts # Repo detection (owner/repo from remote)
257362
│ ├── language.ts # languageId → display name translation
258363
│ ├── logger.ts # Debug/info/warn/error logs
259364
│ └── constants.ts # URLs, timeouts, intervals
@@ -265,7 +370,7 @@ jetbrains-plugin/
265370
│ │ ├── DevGlobeTracker.kt # Singleton tracker, heartbeat scheduler
266371
│ │ ├── HeartbeatService.kt # HTTP client
267372
│ │ ├── GeoService.kt # IP geolocation (same logic)
268-
│ │ ├── GitService.kt # Repo detection + commit stats
373+
│ │ ├── GitService.kt # Repo detection (owner/repo from remote)
269374
│ │ ├── LanguageService.kt # Language detection via native FileType
270375
│ │ ├── TrackerState.kt # Immutable state
271376
│ │ └── Constants.kt # URLs, timeouts, intervals
@@ -281,6 +386,16 @@ jetbrains-plugin/
281386
├── src/main/resources/META-INF/
282387
│ └── plugin.xml
283388
└── build.gradle.kts
389+
390+
claude-code-plugin/
391+
├── plugins/devglobe/
392+
│ ├── src/
393+
│ │ ├── index.ts # Hook handlers (PostToolUse, UserPromptSubmit, Stop)
394+
│ │ ├── geo.ts # IP geolocation + anonymous mode
395+
│ │ ├── git.ts # Repo detection from remote
396+
│ │ └── lang.ts # File extension → language mapping
397+
│ └── package.json
398+
└── manifest.json
284399
```
285400

286401
---
@@ -310,6 +425,15 @@ The `.zip` will be in `build/distributions/`.
310425

311426
Test: `./gradlew runIde` or **Run → Run Plugin** in IntelliJ.
312427

428+
### Claude Code
429+
430+
```bash
431+
cd claude-code-plugin
432+
npm install
433+
```
434+
435+
Install locally: `/plugin install /path/to/claude-code-plugin`
436+
313437
---
314438

315439
## Contributing

claude-code-plugin/README.md

Lines changed: 36 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -10,10 +10,16 @@ Track your Claude Code activity on the [DevGlobe](https://devglobe.xyz) world ma
1010

1111
## Install
1212

13-
Add the marketplace and install the plugin:
13+
Clone the extension repository, then install the plugin from the local folder:
1414

1515
```bash
16-
/plugin marketplace add Nako0/devglobe-extension
16+
git clone https://github.com/Nako0/devglobe-extension
17+
```
18+
19+
Open Claude Code **from the same folder**, then run these two slash commands:
20+
21+
```bash
22+
/plugin marketplace add ./devglobe-extension/claude-code-plugin
1723
/plugin install devglobe@devglobe
1824
```
1925

@@ -35,22 +41,46 @@ Add the marketplace and install the plugin:
3541

3642
3. Restart Claude Code — you're done! Your activity will appear on the globe.
3743

38-
### Optional: share your repository
44+
### Configuration
3945

40-
To display your current repo on your DevGlobe profile, create `~/.devglobe/config.json`:
46+
Create `~/.devglobe/config.json` to customize behavior:
4147

4248
```json
4349
{
44-
"shareRepo": true
50+
"shareRepo": true,
51+
"anonymousMode": false
4552
}
4653
```
4754

55+
| Option | Default | Description |
56+
|--------|---------|-------------|
57+
| `shareRepo` | `false` | Display your current repo on your DevGlobe profile |
58+
| `anonymousMode` | `false` | Hide your exact location — your marker is placed on a random city in your country (from a database of 152,000+ cities worldwide) |
59+
4860
## How it works
4961

5062
The plugin hooks into Claude Code events (`PostToolUse`, `UserPromptSubmit`, `Stop`) and sends a heartbeat to DevGlobe at most once per minute. It automatically detects:
5163

5264
- The programming language from the files you interact with
53-
- Your git repository
65+
- Your git repository (from `git remote get-url origin`)
5466
- Your approximate location (via IP geolocation, cached for 1 hour)
5567

5668
Your coding session then appears live on the [DevGlobe map](https://devglobe.xyz) with the editor shown as `claude-code`.
69+
70+
## GitHub App — Verified commit stats
71+
72+
Commit statistics displayed on DevGlobe (insertions/deletions per week) are **never collected by this plugin**. They are fetched server-side via a [GitHub App](https://github.com/apps/devglobeapp) that requests only **Metadata: Read-only** — the most minimal permission available. No access to source code, file contents, commit messages, issues, or pull requests.
73+
74+
See the [main extensions README](../README.md#-github-app--verified-commit-stats) for details.
75+
76+
## Privacy
77+
78+
| Data | Sent | Detail |
79+
|------|------|--------|
80+
| Programming language | Yes | Detected from file extensions. Nothing else. |
81+
| Approximate location | Yes | Coordinates **snapped to your city center** (from a database of 152,000+ cities). |
82+
| Repo name | Always sent | `owner/repo` is always sent to the server (used for featured project score), but **displayed on the globe only if `shareRepo` is enabled** (disabled by default). |
83+
| Anonymous mode | **You decide** | When enabled, real coordinates are replaced with a random city in your country (from a database of 152,000+ cities worldwide). Your actual location is never transmitted. |
84+
| Coding time | Yes | Accumulated per day, per language. |
85+
86+
The plugin **never** reads your source code, file contents, file names, keystrokes, commit messages, environment variables, or credentials.

claude-code-plugin/plugins/devglobe/dist/index.js

Lines changed: 59 additions & 26 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

claude-code-plugin/plugins/devglobe/src/data/anonymous-cities.json

Lines changed: 0 additions & 1 deletion
This file was deleted.

claude-code-plugin/plugins/devglobe/src/data/city-centers.json

Lines changed: 1 addition & 0 deletions
Large diffs are not rendered by default.

0 commit comments

Comments
 (0)