agentlytics 0.0.1 → 0.0.2
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.
- package/README.md +68 -265
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1,301 +1,104 @@
|
|
|
1
|
-
|
|
1
|
+
<p align="center">
|
|
2
|
+
<img src="misc/logo.svg" width="120" alt="Agentlytics">
|
|
3
|
+
</p>
|
|
2
4
|
|
|
3
|
-
|
|
5
|
+
<h1 align="center">Agentlytics</h1>
|
|
4
6
|
|
|
5
|
-
|
|
7
|
+
<p align="center">
|
|
8
|
+
<strong>Unified analytics for your AI coding agents</strong><br>
|
|
9
|
+
<sub>Cursor · Windsurf · Claude Code · VS Code Copilot · Zed · Antigravity · OpenCode</sub>
|
|
10
|
+
</p>
|
|
6
11
|
|
|
7
|
-
|
|
12
|
+
<p align="center">
|
|
13
|
+
<a href="https://www.npmjs.com/package/agentlytics"><img src="https://img.shields.io/npm/v/agentlytics?color=6366f1&label=npm" alt="npm"></a>
|
|
14
|
+
<a href="#supported-editors"><img src="https://img.shields.io/badge/editors-9-818cf8" alt="editors"></a>
|
|
15
|
+
<a href="#license"><img src="https://img.shields.io/badge/license-MIT-green" alt="license"></a>
|
|
16
|
+
<a href="https://nodejs.org"><img src="https://img.shields.io/badge/node-%E2%89%A518-brightgreen" alt="node"></a>
|
|
17
|
+
</p>
|
|
8
18
|
|
|
9
|
-
<
|
|
19
|
+
<p align="center">
|
|
20
|
+
<img src="https://github.com/user-attachments/assets/fdb0acb2-db0f-4091-af23-949ca0fae9c8" alt="Agentlytics demo" width="100%">
|
|
21
|
+
</p>
|
|
10
22
|
|
|
11
23
|
---
|
|
12
24
|
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
- **Dashboard** — KPI cards (total sessions, daily avg, current month), activity heatmap, editor breakdown with click-to-filter, mode distribution, top projects
|
|
16
|
-
- **Sessions** — Paginated list of every chat session with editor/project/mode badges, search, and editor filter. Click any session to see the full conversation with syntax-highlighted markdown, expandable tool call details, and diff views
|
|
17
|
-
- **Projects** — Per-project analytics: sessions, messages, tokens, tool calls, models, and editor breakdown. Filterable by editor and searchable
|
|
18
|
-
- **Deep Analysis** — Aggregated tool call frequency, model distribution (doughnut chart), token breakdown (input/output/cache read/write). Click any tool bar to drill down into individual calls with full arguments
|
|
19
|
-
- **Compare** — Side-by-side editor comparison: totals, efficiency ratios (avg msgs/session, output/input ratio, cache hit rate), grouped bar charts, tool and model breakdowns
|
|
20
|
-
- **Refetch** — One-click cache rebuild with live SSE progress streaming
|
|
21
|
-
|
|
22
|
-
### Supported Editors
|
|
23
|
-
|
|
24
|
-
| Editor | Source ID | Data Location | Messages | Tool Args | Models | Tokens |
|
|
25
|
-
|--------|-----------|---------------|----------|-----------|--------|--------|
|
|
26
|
-
| **Cursor** | `cursor` | `~/.cursor/chats/` + `~/Library/Application Support/Cursor/` | ✅ | ✅ | ⚠️ provider only | ⚠️ partial |
|
|
27
|
-
| **Windsurf** | `windsurf` | ConnectRPC from running language server | ✅ | ✅ | ✅ | ✅ |
|
|
28
|
-
| **Windsurf Next** | `windsurf-next` | ConnectRPC from running language server | ✅ | ✅ | ✅ | ✅ |
|
|
29
|
-
| **Antigravity** | `antigravity` | ConnectRPC from running language server (HTTPS) | ✅ | ✅ | ✅ | ✅ |
|
|
30
|
-
| **Claude Code** | `claude-code` | `~/.claude/projects/` | ✅ | ✅ | ✅ | ✅ |
|
|
31
|
-
| **VS Code** | `vscode` | `~/Library/Application Support/Code/` | ✅ | ✅ | ✅ | ✅ |
|
|
32
|
-
| **VS Code Insiders** | `vscode-insiders` | `~/Library/Application Support/Code - Insiders/` | ✅ | ✅ | ✅ | ✅ |
|
|
33
|
-
| **Zed** | `zed` | `~/Library/Application Support/Zed/threads/threads.db` | ✅ | ✅ | ✅ | ❌ |
|
|
34
|
-
| **OpenCode** | `opencode` | `~/.local/share/opencode/opencode.db` | ✅ | ✅ | ✅ | ✅ |
|
|
35
|
-
|
|
36
|
-
> **Note:** Windsurf, Windsurf Next, and Antigravity require their app to be running during scan — they expose data via a local ConnectRPC API from the language server process.
|
|
37
|
-
|
|
38
|
-
---
|
|
25
|
+
Agentlytics reads local chat history from every major AI coding assistant and presents a unified analytics dashboard in your browser. **No data ever leaves your machine.**
|
|
39
26
|
|
|
40
27
|
## Quick Start
|
|
41
28
|
|
|
42
|
-
### Prerequisites
|
|
43
|
-
|
|
44
|
-
- **Node.js** ≥ 18
|
|
45
|
-
- **macOS** (currently the only supported platform — all editor paths are macOS-specific)
|
|
46
|
-
|
|
47
|
-
### Install & Run
|
|
48
|
-
|
|
49
29
|
```bash
|
|
50
|
-
|
|
51
|
-
cd agentlytics
|
|
52
|
-
|
|
53
|
-
# Install backend dependencies
|
|
54
|
-
npm install
|
|
55
|
-
|
|
56
|
-
# Build the frontend
|
|
57
|
-
cd ui && npm install && npm run build && cd ..
|
|
58
|
-
|
|
59
|
-
# Start the dashboard
|
|
60
|
-
npm start
|
|
30
|
+
npx agentlytics
|
|
61
31
|
```
|
|
62
32
|
|
|
63
|
-
|
|
33
|
+
Opens at **http://localhost:4637**. Requires Node.js ≥ 18, macOS.
|
|
64
34
|
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
### Options
|
|
68
|
-
|
|
69
|
-
```bash
|
|
70
|
-
npm start # normal start (uses cache)
|
|
71
|
-
npm start -- --no-cache # wipe cache and rescan everything
|
|
72
|
-
```
|
|
73
|
-
|
|
74
|
-
### Development
|
|
35
|
+
## Features
|
|
75
36
|
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
37
|
+
- **Dashboard** — KPIs, activity heatmap, editor breakdown, coding streaks, token economy, peak hours, top models & tools
|
|
38
|
+
- **Sessions** — Search, filter, full conversation viewer with syntax highlighting and diff views
|
|
39
|
+
- **Projects** — Per-project analytics: sessions, messages, tokens, models, editor breakdown
|
|
40
|
+
- **Deep Analysis** — Tool frequency, model distribution, token breakdown with drill-down
|
|
41
|
+
- **Compare** — Side-by-side editor comparison with efficiency ratios
|
|
42
|
+
- **Refetch** — One-click cache rebuild with live progress
|
|
79
43
|
|
|
80
|
-
|
|
81
|
-
npm start
|
|
82
|
-
```
|
|
44
|
+
## Supported Editors
|
|
83
45
|
|
|
84
|
-
|
|
46
|
+
| Editor | ID | Msgs | Tools | Models | Tokens |
|
|
47
|
+
|--------|----|:----:|:-----:|:------:|:------:|
|
|
48
|
+
| **Cursor** | `cursor` | ✅ | ✅ | ⚠️ | ⚠️ |
|
|
49
|
+
| **Windsurf** | `windsurf` | ✅ | ✅ | ✅ | ✅ |
|
|
50
|
+
| **Windsurf Next** | `windsurf-next` | ✅ | ✅ | ✅ | ✅ |
|
|
51
|
+
| **Antigravity** | `antigravity` | ✅ | ✅ | ✅ | ✅ |
|
|
52
|
+
| **Claude Code** | `claude-code` | ✅ | ✅ | ✅ | ✅ |
|
|
53
|
+
| **VS Code** | `vscode` | ✅ | ✅ | ✅ | ✅ |
|
|
54
|
+
| **VS Code Insiders** | `vscode-insiders` | ✅ | ✅ | ✅ | ✅ |
|
|
55
|
+
| **Zed** | `zed` | ✅ | ✅ | ✅ | ❌ |
|
|
56
|
+
| **OpenCode** | `opencode` | ✅ | ✅ | ✅ | ✅ |
|
|
85
57
|
|
|
86
|
-
|
|
58
|
+
> Windsurf, Windsurf Next, and Antigravity must be running during scan.
|
|
87
59
|
|
|
88
|
-
|
|
60
|
+
## How It Works
|
|
89
61
|
|
|
90
62
|
```
|
|
91
|
-
Editor
|
|
63
|
+
Editor files/APIs → editors/*.js → cache.js (SQLite) → server.js (REST) → React SPA
|
|
92
64
|
```
|
|
93
65
|
|
|
94
|
-
|
|
95
|
-
2. **Cache layer** normalizes everything into a single SQLite DB (`~/.agentlytics/cache.db`) with tables for `chats`, `messages`, `chat_stats`, and `tool_calls`
|
|
96
|
-
3. **Express server** exposes read-only REST endpoints against the cache
|
|
97
|
-
4. **React frontend** fetches data from the API and renders charts via Chart.js
|
|
98
|
-
|
|
99
|
-
---
|
|
100
|
-
|
|
101
|
-
## API Reference
|
|
102
|
-
|
|
103
|
-
All endpoints are `GET` and return JSON.
|
|
104
|
-
|
|
105
|
-
| Endpoint | Description | Query Params |
|
|
106
|
-
|----------|-------------|--------------|
|
|
107
|
-
| `/api/overview` | Dashboard overview: totals, editors, modes, monthly trend, top projects | `editor` |
|
|
108
|
-
| `/api/daily-activity` | Daily activity data for heatmap | `editor` |
|
|
109
|
-
| `/api/chats` | Paginated chat list | `editor`, `folder`, `named`, `limit`, `offset` |
|
|
110
|
-
| `/api/chats/:id` | Full chat detail with messages and stats | — |
|
|
111
|
-
| `/api/projects` | All projects with aggregated analytics | — |
|
|
112
|
-
| `/api/deep-analytics` | Aggregated tool/model/token analytics | `editor`, `folder`, `limit` |
|
|
113
|
-
| `/api/tool-calls` | Individual tool call instances | `name` (required), `folder`, `limit` |
|
|
114
|
-
| `/api/refetch` | SSE stream: wipe cache and rescan all editors | — |
|
|
115
|
-
|
|
116
|
-
---
|
|
117
|
-
|
|
118
|
-
## Cache Database Schema
|
|
119
|
-
|
|
120
|
-
Location: `~/.agentlytics/cache.db`
|
|
121
|
-
|
|
122
|
-
### `chats`
|
|
123
|
-
Stores one row per chat session, normalized across all editors.
|
|
124
|
-
|
|
125
|
-
| Column | Type | Description |
|
|
126
|
-
|--------|------|-------------|
|
|
127
|
-
| `id` | TEXT PK | Unique chat ID (composerId) |
|
|
128
|
-
| `source` | TEXT | Editor identifier (`cursor`, `windsurf`, `claude-code`, etc.) |
|
|
129
|
-
| `name` | TEXT | Chat title |
|
|
130
|
-
| `mode` | TEXT | Session mode (`agent`, `edit`, `chat`, `ask`, etc.) |
|
|
131
|
-
| `folder` | TEXT | Project working directory |
|
|
132
|
-
| `created_at` | INTEGER | Creation timestamp (ms) |
|
|
133
|
-
| `last_updated_at` | INTEGER | Last update timestamp (ms) |
|
|
134
|
-
| `bubble_count` | INTEGER | Number of messages/bubbles |
|
|
135
|
-
| `encrypted` | INTEGER | 1 if content is encrypted |
|
|
66
|
+
All data is normalized into a local SQLite cache at `~/.agentlytics/cache.db`. The Express server exposes read-only REST endpoints consumed by the React frontend.
|
|
136
67
|
|
|
137
|
-
|
|
138
|
-
Individual messages per chat, stored with truncation at 50K characters.
|
|
68
|
+
## API
|
|
139
69
|
|
|
140
|
-
|
|
|
141
|
-
|
|
142
|
-
| `
|
|
143
|
-
| `
|
|
144
|
-
| `
|
|
145
|
-
| `
|
|
146
|
-
| `
|
|
147
|
-
| `
|
|
148
|
-
| `
|
|
70
|
+
| Endpoint | Description |
|
|
71
|
+
|----------|-------------|
|
|
72
|
+
| `GET /api/overview` | Dashboard KPIs, editors, modes, trends |
|
|
73
|
+
| `GET /api/daily-activity` | Daily counts for heatmap |
|
|
74
|
+
| `GET /api/dashboard-stats` | Hourly, weekday, streaks, tokens, velocity |
|
|
75
|
+
| `GET /api/chats` | Paginated session list |
|
|
76
|
+
| `GET /api/chats/:id` | Full chat with messages |
|
|
77
|
+
| `GET /api/projects` | Project-level aggregations |
|
|
78
|
+
| `GET /api/deep-analytics` | Tool/model/token breakdowns |
|
|
79
|
+
| `GET /api/tool-calls` | Individual tool call instances |
|
|
80
|
+
| `GET /api/refetch` | SSE: wipe cache and rescan |
|
|
149
81
|
|
|
150
|
-
|
|
151
|
-
Pre-aggregated statistics per chat, computed during analysis.
|
|
82
|
+
All endpoints accept optional `editor` filter. See **[API.md](API.md)** for full request/response documentation.
|
|
152
83
|
|
|
153
|
-
|
|
154
|
-
|--------|------|-------------|
|
|
155
|
-
| `chat_id` | TEXT PK | References `chats.id` |
|
|
156
|
-
| `total_messages` | INTEGER | Total message count |
|
|
157
|
-
| `user_messages` | INTEGER | User message count |
|
|
158
|
-
| `assistant_messages` | INTEGER | Assistant message count |
|
|
159
|
-
| `tool_calls` | TEXT | JSON array of tool call names |
|
|
160
|
-
| `models` | TEXT | JSON array of model names |
|
|
161
|
-
| `total_input_tokens` | INTEGER | Sum of input tokens |
|
|
162
|
-
| `total_output_tokens` | INTEGER | Sum of output tokens |
|
|
163
|
-
| `total_cache_read` | INTEGER | Sum of cache read tokens |
|
|
164
|
-
| `total_cache_write` | INTEGER | Sum of cache write tokens |
|
|
84
|
+
## Roadmap
|
|
165
85
|
|
|
166
|
-
|
|
167
|
-
|
|
86
|
+
- [ ] **Offline Windsurf/Antigravity support** — Read cascade data from local file structure instead of requiring the app to be running (see below)
|
|
87
|
+
- [ ] **LLM-powered insights** — Use an LLM to analyze session patterns, generate summaries, detect coding habits, and surface actionable recommendations
|
|
88
|
+
- [ ] **Linux & Windows support** — Adapt editor paths for non-macOS platforms
|
|
89
|
+
- [ ] **Export & reports** — PDF/CSV export of analytics and session data
|
|
90
|
+
- [ ] **Cost tracking** — Estimate API costs per editor/model based on token usage
|
|
168
91
|
|
|
169
|
-
|
|
170
|
-
|--------|------|-------------|
|
|
171
|
-
| `chat_id` | TEXT FK | References `chats.id` |
|
|
172
|
-
| `tool_name` | TEXT | Tool function name |
|
|
173
|
-
| `args_json` | TEXT | Full arguments as JSON |
|
|
174
|
-
| `source` | TEXT | Editor source |
|
|
175
|
-
| `folder` | TEXT | Project directory |
|
|
176
|
-
| `timestamp` | INTEGER | Call timestamp (ms) |
|
|
92
|
+
## Contributions Needed
|
|
177
93
|
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
## Editor Adapters — Technical Details
|
|
181
|
-
|
|
182
|
-
### Cursor
|
|
183
|
-
|
|
184
|
-
Reads from **two separate data stores**:
|
|
185
|
-
|
|
186
|
-
1. **Agent Store** (`~/.cursor/chats/<workspace>/<chatId>/store.db`)
|
|
187
|
-
- SQLite with `meta` table (hex-encoded JSON) and `blobs` table (content-addressed SHA-256 tree)
|
|
188
|
-
- Meta contains: `agentId`, `latestRootBlobId`, `name`, `createdAt`
|
|
189
|
-
- Messages are retrieved by walking the blob tree: tree nodes contain message refs and child refs
|
|
190
|
-
- Tool calls extracted from OpenAI-format `tool_calls` array on assistant messages
|
|
191
|
-
|
|
192
|
-
2. **Workspace Composers** (`~/Library/Application Support/Cursor/User/`)
|
|
193
|
-
- `workspaceStorage/<hash>/state.vscdb` — `composer.composerData` key holds all composer headers
|
|
194
|
-
- `globalStorage/state.vscdb` — `cursorDiskKV` table with `bubbleId:<composerId>:<n>` keys
|
|
195
|
-
- Each bubble is a JSON object with `type` (1=user, 2=assistant), `text`, `toolFormerData`, `tokenCount`
|
|
196
|
-
- Tool args extracted from `toolFormerData.rawArgs` with fallback to `toolFormerData.params`
|
|
197
|
-
|
|
198
|
-
**Limitations:** Cursor does not persist model names per chat or per message. Provider name (e.g., "anthropic") is extracted from `providerOptions` when available.
|
|
199
|
-
|
|
200
|
-
### Windsurf / Windsurf Next / Antigravity
|
|
201
|
-
|
|
202
|
-
Connects to the **running language server** via ConnectRPC (buf Connect protocol):
|
|
203
|
-
|
|
204
|
-
1. Discovers process via `ps aux` — finds `language_server_macos_arm` with `--csrf_token`
|
|
205
|
-
2. Extracts CSRF token and PID, finds listening port via `lsof`
|
|
206
|
-
3. Calls `GetAllCascadeTrajectories` for session summaries
|
|
207
|
-
4. Calls `GetCascadeTrajectory` per session for full conversation data
|
|
208
|
-
|
|
209
|
-
**Requires the application to be running** — data is served from the language server process, not from files on disk.
|
|
210
|
-
|
|
211
|
-
### Claude Code
|
|
212
|
-
|
|
213
|
-
Reads from `~/.claude/projects/<encoded-path>/`:
|
|
214
|
-
- `sessions-index.json` — session index with titles and timestamps
|
|
215
|
-
- Individual `.jsonl` session files — each line is a JSON message with `type`, `role`, `content`, `model`, `usage`
|
|
216
|
-
- Tool calls extracted from `tool_use` content blocks and `tool_result` messages
|
|
217
|
-
|
|
218
|
-
### VS Code / VS Code Insiders
|
|
219
|
-
|
|
220
|
-
Reads from `~/Library/Application Support/{Code,Code - Insiders}/User/`:
|
|
221
|
-
- `workspaceStorage/<hash>/state.vscdb` — workspace-to-folder mapping
|
|
222
|
-
- Chat sessions stored as `.jsonl` files in the Copilot Chat extension directory
|
|
223
|
-
- JSONL reconstruction: `kind:0` = init state, `kind:1` = JSON patch at key path
|
|
224
|
-
- Messages, tool calls, and token usage extracted from reconstructed chat state
|
|
225
|
-
|
|
226
|
-
### Zed
|
|
227
|
-
|
|
228
|
-
Reads from `~/Library/Application Support/Zed/threads/threads.db`:
|
|
229
|
-
- SQLite database with `threads` table containing zstd-compressed JSON blobs
|
|
230
|
-
- Each thread decompressed via `zstd` CLI to extract messages, tool calls, and model info
|
|
231
|
-
- Messages in OpenAI format with `tool_calls` array on assistant messages
|
|
94
|
+
**Windsurf / Windsurf Next / Antigravity offline reading** — Currently these editors require their app to be running because data is fetched via ConnectRPC from the language server process. Unlike Cursor or Claude Code, there's no known local file structure to read cascade history from. If you know where Windsurf stores trajectory data on disk, or can help reverse-engineer the storage format, contributions are very welcome.
|
|
232
95
|
|
|
233
|
-
|
|
96
|
+
**LLM-based analytics** — We'd love to add intelligent analysis on top of the raw data — session summaries, coding pattern detection, productivity insights, and natural language queries over your agent history. If you have ideas or want to build this, open an issue or PR.
|
|
234
97
|
|
|
235
|
-
|
|
236
|
-
- SQLite database with `session`, `message`, and `project` tables
|
|
237
|
-
- Messages queried directly via SQL with full content, model, and token data
|
|
98
|
+
## Contributing
|
|
238
99
|
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
## Adding a New Editor
|
|
242
|
-
|
|
243
|
-
1. Create `editors/<name>.js` exporting:
|
|
244
|
-
|
|
245
|
-
```javascript
|
|
246
|
-
const name = 'my-editor';
|
|
247
|
-
|
|
248
|
-
function getChats() {
|
|
249
|
-
// Return array of chat objects:
|
|
250
|
-
return [{
|
|
251
|
-
source: name, // editor identifier
|
|
252
|
-
composerId: '...', // unique chat ID
|
|
253
|
-
name: '...', // chat title (nullable)
|
|
254
|
-
createdAt: 1234567, // timestamp in ms (nullable)
|
|
255
|
-
lastUpdatedAt: 1234567, // timestamp in ms (nullable)
|
|
256
|
-
mode: 'agent', // session mode (nullable)
|
|
257
|
-
folder: '/path/to/project', // working directory (nullable)
|
|
258
|
-
encrypted: false, // true if messages can't be read
|
|
259
|
-
bubbleCount: 10, // message count hint (nullable)
|
|
260
|
-
}];
|
|
261
|
-
}
|
|
262
|
-
|
|
263
|
-
function getMessages(chat) {
|
|
264
|
-
// Return array of message objects:
|
|
265
|
-
return [{
|
|
266
|
-
role: 'user', // 'user' | 'assistant' | 'system' | 'tool'
|
|
267
|
-
content: '...', // message text
|
|
268
|
-
_model: 'gpt-4', // model name (optional)
|
|
269
|
-
_inputTokens: 500, // input token count (optional)
|
|
270
|
-
_outputTokens: 200, // output token count (optional)
|
|
271
|
-
_cacheRead: 100, // cache read tokens (optional)
|
|
272
|
-
_cacheWrite: 50, // cache write tokens (optional)
|
|
273
|
-
_toolCalls: [{ // tool calls (optional)
|
|
274
|
-
name: 'read_file',
|
|
275
|
-
args: { path: '/foo.js' },
|
|
276
|
-
}],
|
|
277
|
-
}];
|
|
278
|
-
}
|
|
279
|
-
|
|
280
|
-
module.exports = { name, getChats, getMessages };
|
|
281
|
-
```
|
|
282
|
-
|
|
283
|
-
2. Register in `editors/index.js`:
|
|
284
|
-
|
|
285
|
-
```javascript
|
|
286
|
-
const myEditor = require('./my-editor');
|
|
287
|
-
const editors = [...existingEditors, myEditor];
|
|
288
|
-
```
|
|
289
|
-
|
|
290
|
-
3. Add color and label in `ui/src/lib/constants.js`:
|
|
291
|
-
|
|
292
|
-
```javascript
|
|
293
|
-
export const EDITOR_COLORS = { ..., 'my-editor': '#hex' };
|
|
294
|
-
export const EDITOR_LABELS = { ..., 'my-editor': 'My Editor' };
|
|
295
|
-
```
|
|
296
|
-
|
|
297
|
-
---
|
|
100
|
+
See **[CONTRIBUTING.md](CONTRIBUTING.md)** for development setup, editor adapter details, database schema, and how to add support for new editors.
|
|
298
101
|
|
|
299
102
|
## License
|
|
300
103
|
|
|
301
|
-
MIT
|
|
104
|
+
MIT — Built by [@f](https://github.com/f)
|
package/package.json
CHANGED