cursor-usage 0.1.1 → 0.1.3

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 CHANGED
@@ -4,12 +4,12 @@ A CLI tool for analyzing Cursor API usage and membership information, inspired b
4
4
 
5
5
  ## Features
6
6
 
7
- - Extract Cursor credentials from local database
8
- - 🔗 Fetch usage data from Cursor API
9
- - 💳 Display membership and plan usage information
10
- - 📊 Show usage breakdown (included vs bonus)
11
- - 🎯 Track percentage of included usage consumed
12
- - 🎨 Colorful terminal output
7
+ - Extract Cursor credentials from local database
8
+ - Fetch usage data from Cursor API
9
+ - Display membership and plan usage information
10
+ - Show usage breakdown (included vs bonus)
11
+ - Track percentage of included usage consumed
12
+ - Colorful terminal output
13
13
 
14
14
  ## Installation
15
15
 
@@ -17,6 +17,26 @@ A CLI tool for analyzing Cursor API usage and membership information, inspired b
17
17
  npm install
18
18
  ```
19
19
 
20
+ ## Quick Test
21
+
22
+ You can test the package without installing it locally using npx or bunx:
23
+
24
+ ```bash
25
+ # Test with npx (Node.js)
26
+ npx cursor-usage@latest
27
+
28
+ # Test with bunx (Bun runtime)
29
+ bunx cursor-usage@latest
30
+
31
+ # Test specific commands
32
+ npx cursor-usage@latest daily
33
+ npx cursor-usage@latest monthly
34
+
35
+ # Test with flags
36
+ npx cursor-usage@latest daily --breakdown
37
+ npx cursor-usage@latest weekly --json
38
+ ```
39
+
20
40
  ## Usage
21
41
 
22
42
  ### Commands
@@ -44,8 +64,28 @@ npm run dev -- today
44
64
 
45
65
  # Show help
46
66
  npm run dev -- help
67
+
68
+ # Show usage with date range
69
+ npm run dev -- daily --since 2026-01-01 --until 2026-01-15
70
+
71
+ # Show usage with model breakdown
72
+ npm run dev -- daily --breakdown
73
+
74
+ # Show compact table format
75
+ npm run dev -- monthly --compact
76
+
77
+ # Output as JSON (detailed reports only)
78
+ npm run dev -- daily --json
47
79
  ```
48
80
 
81
+ ### Flags
82
+
83
+ - `--since DATE` - Start date (YYYY-MM-DD)
84
+ - `--until DATE` - End date (YYYY-MM-DD)
85
+ - `--breakdown` - Show per-model breakdown
86
+ - `--json` - Output as JSON (machine-readable format)
87
+ - `--compact` - Compact table format
88
+
49
89
  ### Development
50
90
 
51
91
  ```bash
@@ -59,11 +99,11 @@ npm run build # Compile TypeScript
59
99
  ### Summary View
60
100
 
61
101
  ```
62
- 📊 ACCOUNT INFORMATION:
102
+ ACCOUNT INFORMATION:
63
103
  Membership: pro
64
104
  Billing Cycle: <your-billing-cycle>
65
105
 
66
- 📊 PLAN USAGE:
106
+ PLAN USAGE:
67
107
  Used: 150 / 2000 (7.50%)
68
108
  Remaining: 1850
69
109
  ```
@@ -136,21 +176,91 @@ USAGE EVENTS FOR Today
136
176
  Total Events: 3
137
177
  Total Tokens: 3,150
138
178
  Total Cost: $0.14
139
- ========================================================================================================================
179
+ ==================================================================================================================
180
+ ```
181
+
182
+ ### Model Breakdown View (`--breakdown`)
183
+
184
+ When using `--breakdown`, reports include a detailed per-model breakdown:
185
+
186
+ ```
187
+ ==================================================================================================================
188
+ PER-MODEL BREAKDOWN
189
+ ==================================================================================================================
190
+
191
+ +---------------+--------+--------------+-------+-------+-------+---------+------------+------------+
192
+ | Model | Events | Total Tokens | Input | Output| Cost | Token % | Cost % |
193
+ +---------------+--------+--------------+-------+-------+-------+---------+------------+
194
+ | claude-opus | 15 | 2,500,000 | 20000 | 15000 | $2.00 | 50.00% | 40.00% |
195
+ | claude-sonnet | 10 | 2,000,000 | 15000 | 12000 | $1.60 | 40.00% | 32.00% |
196
+ | claude-haiku | 5 | 500,000 | 5000 | 3000 | $0.40 | 10.00% | 8.00% |
197
+ +---------------+--------+--------------+-------+-------+-------+---------+------------+
198
+ ```
199
+
200
+ ### JSON Output (`--json`)
201
+
202
+ JSON output provides clean, structured data for programmatic use (no table formatting):
203
+
204
+ ```json
205
+ {
206
+ "command": "daily",
207
+ "generatedAt": "2026-01-11T10:30:00.000Z",
208
+ "period": "last 7 days",
209
+ "summary": {
210
+ "totalEvents": 45,
211
+ "totalTokens": 539301,
212
+ "totalCost": 0.82
213
+ },
214
+ "data": [
215
+ {
216
+ "date": "2026-01-11",
217
+ "eventCount": 3,
218
+ "totalTokens": 539301,
219
+ "inputTokens": 381,
220
+ "outputTokens": 7081,
221
+ "totalCost": 0.82,
222
+ "models": {
223
+ "claude-4.5-opus-high-thinking": 3
224
+ }
225
+ }
226
+ ],
227
+ "breakdown": [
228
+ {
229
+ "model": "claude-opus",
230
+ "count": 15,
231
+ "totalTokens": 250000,
232
+ "inputTokens": 20000,
233
+ "outputTokens": 15000,
234
+ "totalCost": 2.0,
235
+ "tokenPercent": 50.0,
236
+ "costPercent": 40.0
237
+ }
238
+ ]
239
+ }
140
240
  ```
141
241
 
142
- ## How It Works
242
+ ### Compact Table Format (`--compact`)
143
243
 
144
- 1. **Extracts credentials** from `~/Library/Application Support/Cursor/User/globalStorage/state.vscdb`
145
- - User ID from `workbench.experiments.statsigBootstrap`
146
- - Access Token from `cursorAuth/accessToken`
147
- - Email and membership (optional)
244
+ The `--compact` flag provides a more condensed table layout:
148
245
 
149
- 2. **Authenticates** with Cursor API using `WorkosCursorSessionToken` cookie
246
+ ```
247
+ ==================================================================================================================
248
+ DAILY USAGE REPORT (Last 7 days)
249
+ ==================================================================================================================
150
250
 
151
- 3. **Fetches usage data** from `https://cursor.com/api/usage-summary`
251
+ Date Events Tokens Cost Models
252
+ 2026-01-11 3 539,301 $0.82 claude-4.5-opus-high-thinking(3)
253
+ 2026-01-10 5 1,200,450 $1.45 claude-sonnet(4), claude-opus(1)
254
+ 2026-01-09 2 89,320 $0.12 claude-haiku(2)
152
255
 
153
- 4. **Parses and displays** membership, plan usage, and billing information
256
+ ==================================================================================================================
257
+ SUMMARY
258
+ ==================================================================================================================
259
+ Total Events: 10
260
+ Total Tokens: 1,829,071
261
+ Total Cost: $2.39
262
+ ==================================================================================================================
263
+ ```
154
264
 
155
265
  ## Environment Variables
156
266
 
@@ -168,15 +278,6 @@ src/
168
278
  └── _consts.ts # Constants & configuration
169
279
  ```
170
280
 
171
- ## API Response Structure
172
-
173
- The tool fetches data from Cursor's `/api/usage-summary` endpoint which returns:
174
- - Billing cycle information
175
- - Membership type (pro, hobby, etc.)
176
- - Plan usage (used/limit/remaining)
177
- - On-demand usage status
178
- - Display messages about usage percentage
179
-
180
281
  ## Features Implemented
181
282
 
182
283
  - ✅ Daily usage reports with table formatting
@@ -187,17 +288,6 @@ The tool fetches data from Cursor's `/api/usage-summary` endpoint which returns:
187
288
  - ✅ Flexible date range querying
188
289
  - ✅ Colorized CLI output
189
290
 
190
- ## Future Enhancements
191
-
192
- - [ ] JSON output format (`--json`)
193
- - [ ] Date range queries (`--from 2026-01-01 --to 2026-01-31`)
194
- - [ ] Weekly/monthly aggregations
195
- - [ ] Historical data caching
196
- - [ ] Cost projections
197
- - [ ] Team usage analysis
198
- - [ ] Export to CSV/JSON
199
- - [ ] Web dashboard
200
- - [ ] Webhook notifications
201
291
 
202
292
  ## License
203
293
 
package/dist/cli.js CHANGED
@@ -81,17 +81,22 @@ function displayResults(data) {
81
81
  const plan = data.individualUsage?.plan;
82
82
  if (plan) {
83
83
  logger.log('\n📊 PLAN USAGE:');
84
- logger.log(` Used: ${plan.used} / ${plan.limit} (${(plan.totalPercentUsed * 100).toFixed(2)}%)`);
85
- logger.log(` Remaining: ${plan.remaining}`);
84
+ logger.log(` Used: ${plan.used} / ${plan.limit} (${plan.limit > 0 ? ((plan.used / plan.limit) * 100).toFixed(2) : '0.00'}%)`);
85
+ logger.log(` Remaining: ${plan.limit - plan.used}`);
86
86
  logger.log(` Breakdown:`);
87
87
  logger.log(` - Included: ${plan.breakdown?.included || 0}`);
88
88
  logger.log(` - Bonus: ${plan.breakdown?.bonus || 0}`);
89
+ logger.log(` - Total: ${plan.breakdown?.total || 0}`);
89
90
  }
90
91
  // On-demand usage
91
92
  const onDemand = data.individualUsage?.onDemand;
92
93
  if (onDemand && onDemand.enabled) {
93
94
  logger.log('\n💰 ON-DEMAND USAGE:');
94
95
  logger.log(` Used: ${onDemand.used}`);
96
+ if (onDemand.limit !== null) {
97
+ logger.log(` Limit: ${onDemand.limit}`);
98
+ logger.log(` Remaining: ${onDemand.remaining !== null ? onDemand.remaining : (onDemand.limit - onDemand.used)}`);
99
+ }
95
100
  logger.log(` Status: Enabled`);
96
101
  }
97
102
  // Display messages
package/dist/commands.js CHANGED
@@ -71,50 +71,53 @@ export async function showDailyReport(credentials, days = 7, options = {}, outpu
71
71
  logger.warn('No usage events found for this period');
72
72
  return;
73
73
  }
74
- logger.log('');
75
74
  // Group and calculate stats
76
75
  const grouped = groupByDay(events);
77
76
  const stats = calculateDailyStats(grouped);
78
- // Display table
79
- logger.log('\n' + '='.repeat(100));
80
- logger.log(`DAILY USAGE REPORT (Last ${days} days)`);
81
- logger.log('='.repeat(100) + '\n');
82
- const tableData = stats.map((day) => {
83
- const modelList = Array.from(day.models.entries())
84
- .map(([model, count]) => `${model}(${count})`)
85
- .join(', ');
86
- return [
87
- day.date,
88
- day.eventCount.toString(),
89
- day.totalTokens.toLocaleString(),
90
- day.inputTokens.toLocaleString(),
91
- day.outputTokens.toLocaleString(),
92
- `$${day.totalCost.toFixed(2)}`,
93
- modelList || 'N/A',
94
- ];
95
- });
96
- const table = createTable(['Date', 'Events', 'Total Tokens', 'Input', 'Output', 'Cost', 'Models'], tableData);
97
- logger.log(table);
98
- // Summary
99
- const totalEvents = stats.reduce((sum, day) => sum + day.eventCount, 0);
100
- const totalTokens = stats.reduce((sum, day) => sum + day.totalTokens, 0);
101
- const totalCost = stats.reduce((sum, day) => sum + day.totalCost, 0);
102
- logger.log('\n' + '='.repeat(100));
103
- logger.log('SUMMARY');
104
- logger.log('='.repeat(100));
105
- logger.log(`Total Events: ${totalEvents}`);
106
- logger.log(`Total Tokens: ${totalTokens.toLocaleString()}`);
107
- logger.log(`Total Cost: $${totalCost.toFixed(2)}`);
108
- logger.log('='.repeat(100) + '\n');
109
- // Show breakdown if requested
110
- if (options.breakdown) {
111
- displayBreakdown(events, 'PER-MODEL BREAKDOWN');
112
- }
113
- // Output JSON if requested
114
77
  if (outputJson) {
78
+ // Output JSON only - no table display
115
79
  const jsonOutput = statsToJSON('daily', stats, events, { breakdown: options.breakdown, period: `last ${days} days` });
116
80
  console.log(jsonOutput);
117
81
  }
82
+ else {
83
+ // Display table and summary
84
+ logger.log('');
85
+ // Display table
86
+ logger.log('\n' + '='.repeat(100));
87
+ logger.log(`DAILY USAGE REPORT (Last ${days} days)`);
88
+ logger.log('='.repeat(100) + '\n');
89
+ const tableData = stats.map((day) => {
90
+ const modelList = Array.from(day.models.entries())
91
+ .map(([model, count]) => `${model}(${count})`)
92
+ .join(', ');
93
+ return [
94
+ day.date,
95
+ day.eventCount.toString(),
96
+ day.totalTokens.toLocaleString(),
97
+ day.inputTokens.toLocaleString(),
98
+ day.outputTokens.toLocaleString(),
99
+ `$${day.totalCost.toFixed(2)}`,
100
+ modelList || 'N/A',
101
+ ];
102
+ });
103
+ const table = createTable(['Date', 'Events', 'Total Tokens', 'Input', 'Output', 'Cost', 'Models'], tableData);
104
+ logger.log(table);
105
+ // Summary
106
+ const totalEvents = stats.reduce((sum, day) => sum + day.eventCount, 0);
107
+ const totalTokens = stats.reduce((sum, day) => sum + day.totalTokens, 0);
108
+ const totalCost = stats.reduce((sum, day) => sum + day.totalCost, 0);
109
+ logger.log('\n' + '='.repeat(100));
110
+ logger.log('SUMMARY');
111
+ logger.log('='.repeat(100));
112
+ logger.log(`Total Events: ${totalEvents}`);
113
+ logger.log(`Total Tokens: ${totalTokens.toLocaleString()}`);
114
+ logger.log(`Total Cost: $${totalCost.toFixed(2)}`);
115
+ logger.log('='.repeat(100) + '\n');
116
+ // Show breakdown if requested
117
+ if (options.breakdown) {
118
+ displayBreakdown(events, 'PER-MODEL BREAKDOWN');
119
+ }
120
+ }
118
121
  }
119
122
  /**
120
123
  * Show monthly usage report
@@ -136,38 +139,41 @@ export async function showMonthlyReport(credentials, months = 3, options = {}, o
136
139
  logger.warn('No usage events found for this period');
137
140
  return;
138
141
  }
139
- logger.log('');
140
142
  // Group and calculate stats
141
143
  const grouped = groupByMonth(events);
142
144
  const stats = calculateMonthlyStats(grouped);
143
- // Display table
144
- logger.log('\n' + '='.repeat(100));
145
- logger.log(`MONTHLY USAGE REPORT (Last ${months} months)`);
146
- logger.log('='.repeat(100) + '\n');
147
- const tableData = formatMonthlyStatsTable(stats);
148
- const table = createTable(['Month', 'Events', 'Total Tokens', 'Input', 'Output', 'Cost', 'Models'], tableData);
149
- logger.log(table);
150
- // Summary
151
- const totalEvents = stats.reduce((sum, month) => sum + month.eventCount, 0);
152
- const totalTokens = stats.reduce((sum, month) => sum + month.totalTokens, 0);
153
- const totalCost = stats.reduce((sum, month) => sum + month.totalCost, 0);
154
- logger.log('\n' + '='.repeat(100));
155
- logger.log('SUMMARY');
156
- logger.log('='.repeat(100));
157
- logger.log(`Total Events: ${totalEvents}`);
158
- logger.log(`Total Tokens: ${totalTokens.toLocaleString()}`);
159
- logger.log(`Total Cost: $${totalCost.toFixed(2)}`);
160
- logger.log(`Average per month: ${(totalTokens / Math.max(1, stats.length)).toLocaleString()} tokens, $${(totalCost / Math.max(1, stats.length)).toFixed(2)}`);
161
- logger.log('='.repeat(100) + '\n');
162
- // Show breakdown if requested
163
- if (options.breakdown) {
164
- displayBreakdown(events, 'PER-MODEL BREAKDOWN');
165
- }
166
- // Output JSON if requested
167
145
  if (outputJson) {
146
+ // Output JSON only - no table display
168
147
  const jsonOutput = statsToJSON('monthly', stats, events, { breakdown: options.breakdown, period: `last ${months} months` });
169
148
  console.log(jsonOutput);
170
149
  }
150
+ else {
151
+ // Display table and summary
152
+ logger.log('');
153
+ // Display table
154
+ logger.log('\n' + '='.repeat(100));
155
+ logger.log(`MONTHLY USAGE REPORT (Last ${months} months)`);
156
+ logger.log('='.repeat(100) + '\n');
157
+ const tableData = formatMonthlyStatsTable(stats);
158
+ const table = createTable(['Month', 'Events', 'Total Tokens', 'Input', 'Output', 'Cost', 'Models'], tableData);
159
+ logger.log(table);
160
+ // Summary
161
+ const totalEvents = stats.reduce((sum, month) => sum + month.eventCount, 0);
162
+ const totalTokens = stats.reduce((sum, month) => sum + month.totalTokens, 0);
163
+ const totalCost = stats.reduce((sum, month) => sum + month.totalCost, 0);
164
+ logger.log('\n' + '='.repeat(100));
165
+ logger.log('SUMMARY');
166
+ logger.log('='.repeat(100));
167
+ logger.log(`Total Events: ${totalEvents}`);
168
+ logger.log(`Total Tokens: ${totalTokens.toLocaleString()}`);
169
+ logger.log(`Total Cost: $${totalCost.toFixed(2)}`);
170
+ logger.log(`Average per month: ${(totalTokens / Math.max(1, stats.length)).toLocaleString()} tokens, $${(totalCost / Math.max(1, stats.length)).toFixed(2)}`);
171
+ logger.log('='.repeat(100) + '\n');
172
+ // Show breakdown if requested
173
+ if (options.breakdown) {
174
+ displayBreakdown(events, 'PER-MODEL BREAKDOWN');
175
+ }
176
+ }
171
177
  }
172
178
  /**
173
179
  * Show weekly usage report
@@ -188,38 +194,41 @@ export async function showWeeklyReport(credentials, weeks = 4, options = {}, out
188
194
  logger.warn('No usage events found for this period');
189
195
  return;
190
196
  }
191
- logger.log('');
192
197
  // Group and calculate stats
193
198
  const grouped = groupByWeek(events);
194
199
  const stats = calculateWeeklyStats(grouped);
195
- // Display table
196
- logger.log('\n' + '='.repeat(120));
197
- logger.log(`WEEKLY USAGE REPORT (Last ${weeks} weeks)`);
198
- logger.log('='.repeat(120) + '\n');
199
- const tableData = formatWeeklyStatsTable(stats);
200
- const table = createTable(['Week', 'Events', 'Total Tokens', 'Input', 'Output', 'Cost', 'Models'], tableData);
201
- logger.log(table);
202
- // Summary
203
- const totalEvents = stats.reduce((sum, week) => sum + week.eventCount, 0);
204
- const totalTokens = stats.reduce((sum, week) => sum + week.totalTokens, 0);
205
- const totalCost = stats.reduce((sum, week) => sum + week.totalCost, 0);
206
- logger.log('\n' + '='.repeat(120));
207
- logger.log('SUMMARY');
208
- logger.log('='.repeat(120));
209
- logger.log(`Total Events: ${totalEvents}`);
210
- logger.log(`Total Tokens: ${totalTokens.toLocaleString()}`);
211
- logger.log(`Total Cost: $${totalCost.toFixed(2)}`);
212
- logger.log(`Average per week: ${(totalTokens / Math.max(1, stats.length)).toLocaleString()} tokens, $${(totalCost / Math.max(1, stats.length)).toFixed(2)}`);
213
- logger.log('='.repeat(120) + '\n');
214
- // Show breakdown if requested
215
- if (options.breakdown) {
216
- displayBreakdown(events, 'PER-MODEL BREAKDOWN');
217
- }
218
- // Output JSON if requested
219
200
  if (outputJson) {
201
+ // Output JSON only - no table display
220
202
  const jsonOutput = statsToJSON('weekly', stats, events, { breakdown: options.breakdown, period: `last ${weeks} weeks` });
221
203
  console.log(jsonOutput);
222
204
  }
205
+ else {
206
+ // Display table and summary
207
+ logger.log('');
208
+ // Display table
209
+ logger.log('\n' + '='.repeat(120));
210
+ logger.log(`WEEKLY USAGE REPORT (Last ${weeks} weeks)`);
211
+ logger.log('='.repeat(120) + '\n');
212
+ const tableData = formatWeeklyStatsTable(stats);
213
+ const table = createTable(['Week', 'Events', 'Total Tokens', 'Input', 'Output', 'Cost', 'Models'], tableData);
214
+ logger.log(table);
215
+ // Summary
216
+ const totalEvents = stats.reduce((sum, week) => sum + week.eventCount, 0);
217
+ const totalTokens = stats.reduce((sum, week) => sum + week.totalTokens, 0);
218
+ const totalCost = stats.reduce((sum, week) => sum + week.totalCost, 0);
219
+ logger.log('\n' + '='.repeat(120));
220
+ logger.log('SUMMARY');
221
+ logger.log('='.repeat(120));
222
+ logger.log(`Total Events: ${totalEvents}`);
223
+ logger.log(`Total Tokens: ${totalTokens.toLocaleString()}`);
224
+ logger.log(`Total Cost: $${totalCost.toFixed(2)}`);
225
+ logger.log(`Average per week: ${(totalTokens / Math.max(1, stats.length)).toLocaleString()} tokens, $${(totalCost / Math.max(1, stats.length)).toFixed(2)}`);
226
+ logger.log('='.repeat(120) + '\n');
227
+ // Show breakdown if requested
228
+ if (options.breakdown) {
229
+ displayBreakdown(events, 'PER-MODEL BREAKDOWN');
230
+ }
231
+ }
223
232
  }
224
233
  /**
225
234
  * Show usage for a specific date
@@ -234,40 +243,43 @@ export async function showDateReport(credentials, date, options = {}, outputJson
234
243
  logger.warn('No usage events found for this date');
235
244
  return;
236
245
  }
237
- logger.log('');
238
- // Display detailed events
239
- logger.log('\n' + '='.repeat(120));
240
- logger.log(`USAGE EVENTS FOR ${date.toDateString()}`);
241
- logger.log('='.repeat(120) + '\n');
242
- const tableData = events.map((event) => {
243
- const timestamp = new Date(event.timestamp).toLocaleTimeString();
244
- return [
245
- timestamp,
246
- event.model,
247
- event.type,
248
- event.inputTokens.toLocaleString(),
249
- event.outputTokens.toLocaleString(),
250
- event.tokens.toLocaleString(),
251
- `$${event.cost?.toFixed(4) || '0.0000'}`,
252
- ];
253
- });
254
- const table = createTable(['Time', 'Model', 'Type', 'Input Tokens', 'Output Tokens', 'Total Tokens', 'Cost'], tableData);
255
- logger.log(table);
256
- // Summary
257
- const totalTokens = events.reduce((sum, e) => sum + e.tokens, 0);
258
- const totalCost = events.reduce((sum, e) => sum + (e.cost || 0), 0);
259
- logger.log('\n' + '='.repeat(120));
260
- logger.log(`Total Events: ${events.length}`);
261
- logger.log(`Total Tokens: ${totalTokens.toLocaleString()}`);
262
- logger.log(`Total Cost: $${totalCost.toFixed(2)}`);
263
- logger.log('='.repeat(120) + '\n');
264
- // Show breakdown if requested
265
- if (options.breakdown) {
266
- displayBreakdown(events, 'PER-MODEL BREAKDOWN');
267
- }
268
- // Output JSON if requested
269
246
  if (outputJson) {
247
+ // Output JSON only - no table display
270
248
  const jsonOutput = statsToJSON('today', events.map((e, i) => ({ ...e, eventIndex: i })), events, { breakdown: options.breakdown, period: 'today' });
271
249
  console.log(jsonOutput);
272
250
  }
251
+ else {
252
+ // Display table and summary
253
+ logger.log('');
254
+ // Display detailed events
255
+ logger.log('\n' + '='.repeat(120));
256
+ logger.log(`USAGE EVENTS FOR ${date.toDateString()}`);
257
+ logger.log('='.repeat(120) + '\n');
258
+ const tableData = events.map((event) => {
259
+ const timestamp = new Date(event.timestamp).toLocaleTimeString();
260
+ return [
261
+ timestamp,
262
+ event.model,
263
+ event.type,
264
+ event.inputTokens.toLocaleString(),
265
+ event.outputTokens.toLocaleString(),
266
+ event.tokens.toLocaleString(),
267
+ `$${event.cost?.toFixed(4) || '0.0000'}`,
268
+ ];
269
+ });
270
+ const table = createTable(['Time', 'Model', 'Type', 'Input Tokens', 'Output Tokens', 'Total Tokens', 'Cost'], tableData);
271
+ logger.log(table);
272
+ // Summary
273
+ const totalTokens = events.reduce((sum, e) => sum + e.tokens, 0);
274
+ const totalCost = events.reduce((sum, e) => sum + (e.cost || 0), 0);
275
+ logger.log('\n' + '='.repeat(120));
276
+ logger.log(`Total Events: ${events.length}`);
277
+ logger.log(`Total Tokens: ${totalTokens.toLocaleString()}`);
278
+ logger.log(`Total Cost: $${totalCost.toFixed(2)}`);
279
+ logger.log('='.repeat(120) + '\n');
280
+ // Show breakdown if requested
281
+ if (options.breakdown) {
282
+ displayBreakdown(events, 'PER-MODEL BREAKDOWN');
283
+ }
284
+ }
273
285
  }
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "cursor-usage",
3
3
  "type": "module",
4
- "version": "0.1.1",
4
+ "version": "0.1.3",
5
5
  "description": "CLI tool for analyzing Cursor usage and token consumption",
6
6
  "author": "yifen <anthonyeef@gmail.com>",
7
7
  "license": "MIT",