cursor-usage-tracker 1.16.0 → 1.18.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/README.md +88 -49
  2. package/package.json +2 -1
package/README.md CHANGED
@@ -73,6 +73,7 @@ Developer uses Cursor → API collects data hourly → Engine detects anomaly
73
73
  | Someone's daily spend spikes | `Alice: daily spend spiked to $214 (4.2x her 7-day avg of $51)` → Slack alert |
74
74
  | A user's cycle spend is far above the team | `Bob: cycle spend $957 is 5.1x the team median ($188)` → Slack alert |
75
75
  | A user is statistically far from the team | `Bob: daily spend $214 is 3.2σ above team mean ($42)` → Slack alert |
76
+ | Someone switches to an expensive model | `Bob: cost/request spiked to $1.45 (4.2x his avg of $0.34) — using opus-max` → Slack alert |
76
77
  | A developer uses an expensive model when others don't | `Bob averaged $4.20/req on claude-opus-max (team median: $0.52 on sonnet)` → Model cost comparison table |
77
78
 
78
79
  Every alert includes who, what model, how much, and a link to their dashboard page so you can investigate immediately.
@@ -83,11 +84,12 @@ Every alert includes who, what model, how much, and a link to their dashboard pa
83
84
 
84
85
  ### Three-Layer Anomaly Detection
85
86
 
86
- | Layer | Method | What it catches |
87
- | -------------- | ------------- | ----------------------------------------------------------------------------- |
88
- | **Thresholds** | Static limits | Optional hard caps on spend, requests, or tokens (disabled by default) |
89
- | **Z-Score** | Statistical | User daily spend 2.5+ standard deviations above team mean (active users only) |
90
- | **Trends** | Spend-based | Daily spend spikes vs personal average, cycle spend outliers vs team median |
87
+ | Layer | Method | What it catches |
88
+ | ------------------- | ------------- | -------------------------------------------------------------------------------------- |
89
+ | **Thresholds** | Static limits | Optional hard caps on spend, requests, or tokens (disabled by default) |
90
+ | **Z-Score** | Statistical | User daily spend 2.5+ standard deviations above team mean (active users only) |
91
+ | **Trends** | Spend-based | Daily spend spikes vs personal average, cycle spend outliers vs team median |
92
+ | **Expensive Model** | Cost/request | User's $/request jumps vs their own history (catches model switches like max-thinking) |
91
93
 
92
94
  ### Incident Lifecycle (MTTD / MTTI / MTTR)
93
95
 
@@ -127,7 +129,7 @@ Also supports **email alerts** via [Resend](https://resend.com) (one API key, no
127
129
  | **Insights** | DAU chart, model adoption trends, model efficiency rankings (cost/precision), MCP tool usage, file extensions, client versions |
128
130
  | **User Drilldown** | Per-user token timeline, model breakdown, feature usage, activity profile, anomaly history |
129
131
  | **Anomalies** | Open incidents, MTTD/MTTI/MTTR metrics, full anomaly timeline |
130
- | **Settings** | Detection thresholds, **billing group management** (rename, assign, create), **HiBob CSV import** with change preview |
132
+ | **Settings** | Detection thresholds, expensive model alerts, billing group management, HiBob CSV import, group export/import |
131
133
 
132
134
  > For a detailed breakdown of every section, metric, badge, and chart, see [FEATURES.md](FEATURES.md).
133
135
 
@@ -193,7 +195,6 @@ DASHBOARD_URL=http://localhost:3000
193
195
 
194
196
  # Optional
195
197
  CRON_SECRET=your_secret_here # protects the cron endpoint
196
- DASHBOARD_PASSWORD=your_password # optional basic auth for the dashboard
197
198
 
198
199
  # Email alerts via Resend (optional)
199
200
  RESEND_API_KEY=re_xxxxxxxxxxxx
@@ -296,7 +297,7 @@ Any platform that supports Docker + persistent volumes works:
296
297
  - **[Render](https://render.com)** — use the deploy button above, or `render.yaml` in this repo
297
298
  - **[Railway](https://railway.app)** — create a project from this repo, attach a volume at `/app/data`
298
299
 
299
- > **Note:** Vercel is not supportedSQLite requires a persistent filesystem that Vercel's serverless functions don't provide.
300
+ > **Serverless platforms** (Vercel, AWS Lambda, etc.) require replacing SQLite with an external database. The data layer is abstracted behind `src/lib/data/` swap the implementation to use Postgres, Supabase, PlanetScale, or any other database. See [Architecture](#architecture) for details.
300
301
 
301
302
  ---
302
303
 
@@ -306,7 +307,7 @@ Any platform that supports Docker + persistent volumes works:
306
307
  flowchart TB
307
308
  APIs["Cursor Enterprise APIs\n/teams/members · /teams/spend · /teams/daily-usage-data\n/teams/filtered-usage-events · /teams/groups · /analytics/team/*"]
308
309
  C["Collector (hourly)"]
309
- DB[("SQLite (local)")]
310
+ DB[("Database\n(SQLite default, swappable)")]
310
311
  D["Detection Engine, 3 layers"]
311
312
  AL["Alerts: Slack / Email"]
312
313
  DA["Dashboard: Next.js"]
@@ -316,7 +317,7 @@ flowchart TB
316
317
  D --> AL
317
318
  ```
318
319
 
319
- **Zero external dependencies.** SQLite stores everything locally. No Postgres, no Redis, no cloud database. Clone, configure, run.
320
+ The data layer is abstracted behind `src/lib/data/` — SQLite is the default (zero-config), but you can swap the implementation for Postgres, Supabase, or any database that fits your infrastructure.
320
321
 
321
322
  ---
322
323
 
@@ -324,55 +325,93 @@ flowchart TB
324
325
 
325
326
  All detection thresholds are configurable via the Settings page or the API:
326
327
 
327
- | Setting | Default | What it does |
328
- | ------------------------ | ------- | -------------------------------------------------------------- |
329
- | Max spend per cycle | 0 (off) | Alert when a user exceeds this in a billing cycle |
330
- | Max requests per day | 0 (off) | Alert on excessive daily request count |
331
- | Max tokens per day | 0 (off) | Alert on excessive daily token consumption |
332
- | Z-score multiplier | 2.5 | How many standard deviations above mean to flag (spend + reqs) |
333
- | Z-score window | 7 days | Historical window for statistical comparison |
334
- | Spend spike multiplier | 5.0x | Alert when today's spend > N× user's personal daily average |
335
- | Spend spike lookback | 7 days | How many days of history to compare against |
336
- | Cycle outlier multiplier | 10.0x | Alert when cycle spend > N× team median (active users only) |
328
+ | Setting | Default | What it does |
329
+ | ------------------------- | ------- | -------------------------------------------------------------- |
330
+ | Max spend per cycle | 0 (off) | Alert when a user exceeds this in a billing cycle |
331
+ | Max requests per day | 0 (off) | Alert on excessive daily request count |
332
+ | Max tokens per day | 0 (off) | Alert on excessive daily token consumption |
333
+ | Z-score multiplier | 2.5 | How many standard deviations above mean to flag (spend + reqs) |
334
+ | Z-score window | 7 days | Historical window for statistical comparison |
335
+ | Spend spike multiplier | 5.0x | Alert when today's spend > N× user's personal daily average |
336
+ | Spend spike lookback | 7 days | How many days of history to compare against |
337
+ | Cycle outlier multiplier | 10.0x | Alert when cycle spend > N× team median (active users only) |
338
+ | Cost/req spike multiplier | 3.0x | Alert when today's $/request > N× user's historical average |
339
+ | Cost/req min daily spend | $20 | Skip cost/req alerts for users below this daily spend |
337
340
 
338
341
  ---
339
342
 
340
- <details>
341
- <summary><strong>Billing Groups: organize teams by department, group, or custom structure</strong></summary>
343
+ ## Settings
344
+
345
+ The Settings page (`/settings`) is where you configure detection behavior and manage your team structure. Everything is persisted locally and takes effect on the next detection run.
342
346
 
343
- Billing groups let you organize team members by department, team, or any structure that fits your org.
347
+ ### Detection Thresholds
344
348
 
345
- **Dashboard Filtering**
349
+ All anomaly detection parameters listed in [Configuration](#configuration) above are editable from the Settings page — static thresholds, z-score sensitivity, spend spike multipliers, and the expensive model detector. Set any value to 0 to disable that specific check.
346
350
 
347
- The Team Overview page includes a group filter dropdown next to the search bar. Select a group to instantly filter all stats, charts, and the members table to that subset. Groups are displayed in a hierarchical `Parent > Team` format.
351
+ ### Billing Groups
348
352
 
349
- **Settings Page**
353
+ Billing groups let you organize team members by department, team, or any structure that fits your org. The Team Overview page includes a group filter dropdown — select a group to instantly scope all stats, charts, and the members table to that subset.
350
354
 
351
355
  From the Settings page you can:
352
356
 
353
357
  - **View** all groups with member counts and per-group spend
354
- - **Rename** groups to match your org structure
355
- - **Reassign** members between groups
358
+ - **Rename** groups to match your org structure (displayed as `Parent > Team`)
359
+ - **Reassign** individual members between groups
356
360
  - **Create** new groups manually
357
- - **Search** across all members to find who's in which group
358
-
359
- </details>
361
+ - **Search** across all members to find and reassign anyone
362
+ - **Export** your current group mapping as a CSV backup
363
+ - **Import** a previously exported CSV to restore or transfer mappings between environments
360
364
 
361
- <details>
362
- <summary><strong>HiBob Import: sync your org structure from HiBob's People Directory</strong></summary>
365
+ ### HiBob Import
363
366
 
364
- For teams using [HiBob](https://www.hibob.com/) as their HR platform, the Settings page includes an **Import from HiBob** feature:
367
+ For teams using [HiBob](https://www.hibob.com/) as their HR platform, the Settings page includes a dedicated **Import from HiBob** flow:
365
368
 
366
- 1. Download a CSV export from HiBob's People Directory
367
- 2. Upload it to the import modal in Settings
368
- 3. Review the preview: see which members will be moved, which groups will be created, and which members weren't matched
369
+ 1. Export a CSV from HiBob's People Directory (include Email, Department, Group, and Team columns)
370
+ 2. Upload it to the import modal
371
+ 3. Review the preview see which members will be moved, which groups will be created, and who wasn't matched
369
372
  4. Selectively approve or reject individual changes before applying
370
373
 
371
- The import uses HiBob's `Group` and `Team` columns (falling back to `Department`) to build a `Group > Team` hierarchy. Small teams (fewer than 3 members) are automatically consolidated into broader groups to avoid excessive granularity.
374
+ The import builds a `Group > Team` hierarchy automatically. Small teams (fewer than 3 members) are merged into their parent group. Members not found in the CSV keep their current assignment.
372
375
 
373
376
  > The HiBob import updates your local billing groups only. It does not push changes back to HiBob or to Cursor's billing API.
374
377
 
375
- </details>
378
+ ---
379
+
380
+ ## Authentication
381
+
382
+ Authentication is **fully optional**. When no auth environment variables are set, the dashboard is open (the default behavior). Setting `AUTH_SECRET` enables Google OAuth sign-in.
383
+
384
+ ### Setup
385
+
386
+ 1. Create a [Google OAuth app](https://console.cloud.google.com/apis/credentials) with redirect URI:
387
+ - Local: `http://localhost:3000/api/auth/callback/google`
388
+ - Production: `https://your-domain.com/api/auth/callback/google`
389
+
390
+ 2. Add to your `.env`:
391
+
392
+ ```bash
393
+ AUTH_SECRET=$(openssl rand -base64 32) # encryption key for sessions
394
+ AUTH_GOOGLE_ID=your-client-id.apps.google... # Google OAuth client ID
395
+ AUTH_GOOGLE_SECRET=GOCSPX-... # Google OAuth client secret
396
+ AUTH_TRUST_HOST=true # required behind a reverse proxy
397
+ AUTH_URL=https://your-domain.com # public URL (auto-detected locally)
398
+ ```
399
+
400
+ 3. Optionally restrict access by domain or specific emails:
401
+
402
+ ```bash
403
+ AUTH_ALLOWED_DOMAIN=yourcompany.com # only @yourcompany.com emails
404
+ AUTH_ALLOWED_EMAILS=admin@example.com,cto@example.com # or specific emails
405
+ ```
406
+
407
+ When both are set, either match grants access. When neither is set, any Google account can sign in.
408
+
409
+ ### How It Works
410
+
411
+ - Sessions use encrypted JWT cookies — no database tables needed
412
+ - The `/api/cron` endpoint is excluded from auth (it uses its own `CRON_SECRET`)
413
+ - Sign-in page appears automatically when auth is enabled
414
+ - User avatar and sign-out menu appear in the nav bar
376
415
 
377
416
  ---
378
417
 
@@ -397,15 +436,15 @@ The import uses HiBob's `Group` and `Team` columns (falling back to `Department`
397
436
 
398
437
  ## Tech Stack
399
438
 
400
- | Component | Technology |
401
- | ---------- | ------------------------------------ |
402
- | Framework | Next.js (App Router) |
403
- | Language | TypeScript (strict mode) |
404
- | Database | SQLite (better-sqlite3), zero config |
405
- | Charts | Recharts |
406
- | Styling | Tailwind CSS |
407
- | Testing | Vitest |
408
- | Deployment | Docker (multi-stage) |
439
+ | Component | Technology |
440
+ | ---------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------- |
441
+ | Framework | [![Next.js](https://img.shields.io/badge/Next.js-000?logo=nextdotjs&logoColor=white)](https://github.com/vercel/next.js) App Router |
442
+ | Language | [![TypeScript](https://img.shields.io/badge/TypeScript-3178C6?logo=typescript&logoColor=white)](https://github.com/microsoft/TypeScript) strict mode |
443
+ | Database | [![SQLite](https://img.shields.io/badge/SQLite-003B57?logo=sqlite&logoColor=white)](https://github.com/WiseLibs/better-sqlite3) via better-sqlite3 (swappable) |
444
+ | Charts | [![Recharts](https://img.shields.io/badge/Recharts-22B5BF?logo=recharts&logoColor=white)](https://github.com/recharts/recharts) |
445
+ | Styling | [![Tailwind CSS](https://img.shields.io/badge/Tailwind_CSS-06B6D4?logo=tailwindcss&logoColor=white)](https://github.com/tailwindlabs/tailwindcss) |
446
+ | Testing | [![Vitest](https://img.shields.io/badge/Vitest-6E9F18?logo=vitest&logoColor=white)](https://github.com/vitest-dev/vitest) |
447
+ | Deployment | [![Docker](https://img.shields.io/badge/Docker-2496ED?logo=docker&logoColor=white)](https://github.com/docker) multi-stage build |
409
448
 
410
449
  ---
411
450
 
@@ -447,7 +486,7 @@ This project handles sensitive usage and spending data, so security matters here
447
486
  - **Automated scanning**: Every push and PR goes through [CodeQL](https://codeql.github.com/) (SQL injection, XSS, CSRF, etc.) and [Dependabot](https://docs.github.com/en/code-security/dependabot) for dependency vulnerabilities.
448
487
  - **OpenSSF Scorecard**: Continuously evaluated against [OpenSSF Scorecard](https://scorecard.dev/viewer/?uri=github.com/ofershap/cursor-usage-tracker) security benchmarks.
449
488
  - **OpenSSF Best Practices**: [Passing badge](https://www.bestpractices.dev/projects/11968) earned.
450
- - **Data stays local**: Everything is stored in a local SQLite file. Nothing leaves your infrastructure. No external databases, no cloud services, no telemetry.
489
+ - **Data stays yours**: Everything is stored in your own infrastructure. No external services, no telemetry, no data leaving your network.
451
490
  - **Small dependency tree**: Fewer dependencies = smaller attack surface.
452
491
  - **Signed releases**: Automated via semantic-release with GitHub-verified provenance.
453
492
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "cursor-usage-tracker",
3
- "version": "1.16.0",
3
+ "version": "1.18.0",
4
4
  "description": "Open-source Cursor IDE usage monitoring, anomaly detection, and alerting for enterprise teams",
5
5
  "homepage": "https://github.com/ofershap/cursor-usage-tracker#readme",
6
6
  "type": "module",
@@ -73,6 +73,7 @@
73
73
  "@tailwindcss/postcss": "^4.1.18",
74
74
  "better-sqlite3": "^12.6.2",
75
75
  "next": "^16.1.6",
76
+ "next-auth": "^5.0.0-beta.30",
76
77
  "react": "^19.2.4",
77
78
  "react-dom": "^19.2.4",
78
79
  "recharts": "^3.7.0",