Cursor AI Activity Stats
Count every Cursor agent hook fire and track live AI turn time — locally, across windows and multi-root workspaces. No chat scraping, no DOM hacks, no prompts or file contents leave your machine.

v0.5.0 — Install profiles (timer / tool counts / both) · compact ledger · no HTTP server.
Why this extension?
| Problem |
What we do |
| Port fights when two Cursor windows run agents |
Hooks only append to a shared local ledger under extension storage — no shared port |
| Only one workspace folder got hooks |
Install covers every multi-root folder with a stable workspace id |
| Lifetime blob, no history |
Day-partitioned events-YYYY-MM-DD.jsonl + range filters |
| Privacy anxiety |
Observational hooks only; ledger lines never include paths, prompts, or tool output |
| Hook spawn cost |
Install profiles: timer-only · tool counts · or both |
Features
- Hook counters (this chat + selected period) for thoughts, shell, MCP, file reads/edits, tools, subagents, tab edits, compaction, …
- Project filter: All projects · This project · pick another
- Time period: Today · Last 7 days · Last 30 days · All time (within retention)
- Live status bar timer while an AI turn is running (from the same ledger ticks)
- Merges into
.cursor/hooks.json without replacing other hooks
- Interval log for completed timer sessions (separate from clearing count data)

Privacy
Installed hooks are observational only (not workspaceOpen). The shim:
- Reads only the first ~24KB of stdin (hook name + session near the start — never loads multi-MB tool payloads)
- Appends one compact tick:
+\t{ws}\t{hook}\t{session}\t{epochMs} (ledger path baked into the shim at install)
- Exits immediately — no HTTP. Uses Bun when on PATH, otherwise Node.
- Installs a profiled hook set: timer-only · tool counts · or both (default)
Absolute folder paths live only in local workspaces.json. Nothing is sent to the network.
Install profiles
| Profile |
Hooks (summary) |
Best for |
| Timer only |
sessionStart, beforeSubmitPrompt, stop, subagentStart, subagentStop |
Fastest; live status-bar time |
| Tool counts |
thoughts, tools, shell, MCP, reads, edits, tab edits, compact, responses |
KPI tiles without timer hooks |
| Both |
Union of the two |
Full dashboard |
Switching profile rewrites owned hook entries (drops the other set). Unrelated workspace hooks stay.
Quick start
- Open AI Activity in the Activity Bar.
- Under Hook setup, pick a profile:
- Timer only — live turn time (few lightweight hooks)
- Tool counts — KPI counters (tools, shell, reads…; heavier)
- Both — timer + counters
- Click Install / refresh.
- Use Cursor AI. Data updates from the local ledger (watch + short poll).
- Pick a project and time period in the sidebar for historical totals.
Multi-window / multi-root
- Two windows on different projects share the same extension global storage ledger.
- Multi-root: hooks install on every folder; each gets its own
workspaceId.
- After upgrading: open the workspace once (auto-refresh) or click Install / refresh hooks.
Hook KPI map
| Tile |
Hook |
| Thoughts |
afterAgentThought |
| Shell |
afterShellExecution |
| MCP |
afterMCPExecution |
| File reads |
beforeReadFile |
| File edits |
afterFileEdit |
| Tool (after) |
postToolUse |
| Tool failures |
postToolUseFailure |
| Responses |
afterAgentResponse |
| Prompts |
beforeSubmitPrompt |
| Subagent start |
subagentStart |
| Tab edits |
afterTabFileEdit |
| Compactions |
preCompact |
Clear count data removes all saved hook counts (every day, every project). This cannot be undone. Clearing the interval log is separate.
Legacy hook-stats.json migrates once into synthetic lines under workspace id legacy (“Pre-ledger (migrated)”).
Timer rules
Derived by the extension from lifecycle ticks in the ledger:
beforeSubmitPrompt starts an interval
stop ends it after all subagents stop
subagentStart / subagentStop keep the interval open while subagents run
- Duplicate stops do not double-count
- Only new ticks after extension activate advance the live timer (history is not replayed into the status bar)
Commands
| Command |
AI Activity: Focus Dashboard |
AI Activity: Install Cursor Hooks |
AI Activity: Uninstall Cursor Hooks |
AI Activity: Show Interval Log |
AI Activity: Clear Interval Log |
AI Activity: Clear Count Data |
Configuration
| Setting |
Default |
Description |
cursorAiActivityTimer.hookInstallProfile |
both |
Default install profile: timer / counts / both |
cursorAiActivityTimer.autoInstallHooks |
false |
Auto-install hooks on activate |
cursorAiActivityTimer.showElapsedTime |
true |
Status bar elapsed time |
cursorAiActivityTimer.logRetentionDays |
30 |
Interval log retention |
cursorAiActivityTimer.eventRetentionDays |
90 |
JSONL day-file retention |
cursorAiActivityTimer.statsRangeDefault |
today |
Default period: today / 7d / 30d / all time |
Troubleshooting
| Symptom |
Try |
| Counters or timer stuck |
Install/refresh hooks; config must have ledgerPath + workspaceId |
| After upgrade |
Reopen workspace or Install / refresh hooks so the compact shim is rewritten |
| Multi-root missing counts |
Install on every folder (command covers all roots) |
Development
npm install
npm run compile
npm test
npm run package
Press F5 in Cursor/VS Code for the Extension Development Host.
Maintainer docs (architecture, PDR, standards, deploy):
Links