@kaitranntt/ccs 5.11.0 → 5.12.0-dev.1

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 (59) hide show
  1. package/README.md +2 -1
  2. package/VERSION +1 -1
  3. package/dist/cliproxy/model-catalog.d.ts.map +1 -1
  4. package/dist/cliproxy/model-catalog.js +11 -15
  5. package/dist/cliproxy/model-catalog.js.map +1 -1
  6. package/dist/commands/update-command.d.ts.map +1 -1
  7. package/dist/commands/update-command.js +7 -8
  8. package/dist/commands/update-command.js.map +1 -1
  9. package/dist/commands/version-command.d.ts.map +1 -1
  10. package/dist/commands/version-command.js +2 -3
  11. package/dist/commands/version-command.js.map +1 -1
  12. package/dist/ui/assets/accounts-B9xp2MbI.js +1 -0
  13. package/dist/ui/assets/analytics-BfjSH3d-.js +64 -0
  14. package/dist/ui/assets/api-DYr0Tx6Z.js +1 -0
  15. package/dist/ui/assets/cliproxy-BuB-MuAt.js +1 -0
  16. package/dist/ui/assets/dropdown-menu-iwA6PgQW.js +1 -0
  17. package/dist/ui/assets/{form-utils-Bjfa1DVH.js → form-utils-CSa50xnO.js} +1 -1
  18. package/dist/ui/assets/health-ChYme1jV.js +1 -0
  19. package/dist/ui/assets/icons-ByUiVGTN.js +1 -0
  20. package/dist/ui/assets/index-ChihF1Y9.css +1 -0
  21. package/dist/ui/assets/index-P2CKOdyd.js +10 -0
  22. package/dist/ui/assets/{radix-ui-Ba6LUgyw.js → radix-ui-DAH8Vq_G.js} +2 -2
  23. package/dist/ui/assets/react-vendor-CjrBBxxX.js +3 -0
  24. package/dist/ui/assets/settings-B2OdR7RO.js +1 -0
  25. package/dist/ui/assets/shared-ZSfv4HA6.js +1 -0
  26. package/dist/ui/assets/table-OTpVLgy9.js +1 -0
  27. package/dist/ui/assets/{tanstack-MD0629v8.js → tanstack-DAI1tKxf.js} +2 -2
  28. package/dist/ui/index.html +15 -7
  29. package/dist/utils/version.d.ts +8 -0
  30. package/dist/utils/version.d.ts.map +1 -0
  31. package/dist/utils/version.js +51 -0
  32. package/dist/utils/version.js.map +1 -0
  33. package/dist/web-server/health-service.d.ts +14 -3
  34. package/dist/web-server/health-service.d.ts.map +1 -1
  35. package/dist/web-server/health-service.js +545 -66
  36. package/dist/web-server/health-service.js.map +1 -1
  37. package/dist/web-server/index.d.ts.map +1 -1
  38. package/dist/web-server/index.js +5 -0
  39. package/dist/web-server/index.js.map +1 -1
  40. package/dist/web-server/overview-routes.d.ts.map +1 -1
  41. package/dist/web-server/overview-routes.js +18 -4
  42. package/dist/web-server/overview-routes.js.map +1 -1
  43. package/dist/web-server/routes.js +11 -4
  44. package/dist/web-server/routes.js.map +1 -1
  45. package/dist/web-server/shared-routes.js +3 -2
  46. package/dist/web-server/shared-routes.js.map +1 -1
  47. package/dist/web-server/usage-disk-cache.d.ts +46 -0
  48. package/dist/web-server/usage-disk-cache.d.ts.map +1 -0
  49. package/dist/web-server/usage-disk-cache.js +158 -0
  50. package/dist/web-server/usage-disk-cache.js.map +1 -0
  51. package/dist/web-server/usage-routes.d.ts +35 -0
  52. package/dist/web-server/usage-routes.d.ts.map +1 -0
  53. package/dist/web-server/usage-routes.js +570 -0
  54. package/dist/web-server/usage-routes.js.map +1 -0
  55. package/package.json +2 -1
  56. package/dist/ui/assets/icons-D-Y22K9Z.js +0 -1
  57. package/dist/ui/assets/index-M5ru6OPu.js +0 -9
  58. package/dist/ui/assets/index-ZXu5MvSE.css +0 -1
  59. package/dist/ui/assets/react-vendor-CW-MU7-e.js +0 -3
@@ -0,0 +1,570 @@
1
+ "use strict";
2
+ /**
3
+ * Usage Analytics API Routes
4
+ *
5
+ * Provides REST endpoints for Claude Code usage analytics using better-ccusage library.
6
+ * Supports daily, monthly, and session-based usage data aggregation.
7
+ *
8
+ * Performance optimizations:
9
+ * - Persistent disk cache to avoid re-parsing JSONL files on startup
10
+ * - TTL-based in-memory caching for fast repeated requests
11
+ * - Request coalescing to prevent duplicate concurrent requests
12
+ * - Non-blocking prewarm with instant stale data serving
13
+ */
14
+ Object.defineProperty(exports, "__esModule", { value: true });
15
+ exports.prewarmUsageCache = exports.clearUsageCache = exports.getLastFetchTimestamp = exports.usageRoutes = void 0;
16
+ const express_1 = require("express");
17
+ const data_loader_1 = require("better-ccusage/data-loader");
18
+ const usage_disk_cache_1 = require("./usage-disk-cache");
19
+ exports.usageRoutes = (0, express_1.Router)();
20
+ // Constants for validation
21
+ const MAX_LIMIT = 1000;
22
+ const DEFAULT_LIMIT = 50;
23
+ const DATE_REGEX = /^\d{8}$/; // YYYYMMDD format
24
+ // Cache TTLs (milliseconds)
25
+ const CACHE_TTL = {
26
+ daily: 60 * 1000, // 1 minute - changes frequently
27
+ monthly: 5 * 60 * 1000, // 5 minutes - aggregated data
28
+ session: 60 * 1000, // 1 minute - user may refresh
29
+ };
30
+ /// Stale-while-revalidate: max age for stale data (7 days)
31
+ // We always show cached data to avoid blocking UI, refresh happens in background
32
+ const STALE_TTL = 7 * 24 * 60 * 60 * 1000;
33
+ // Track when data was last fetched (for UI indicator)
34
+ let lastFetchTimestamp = null;
35
+ /** Get timestamp of last successful data fetch */
36
+ function getLastFetchTimestamp() {
37
+ return lastFetchTimestamp;
38
+ }
39
+ exports.getLastFetchTimestamp = getLastFetchTimestamp;
40
+ // In-memory cache
41
+ const cache = new Map();
42
+ // Pending requests for coalescing (prevents duplicate concurrent calls)
43
+ const pendingRequests = new Map();
44
+ // Track if disk cache has been loaded into memory
45
+ let diskCacheInitialized = false;
46
+ /**
47
+ * Persist cache to disk when we have enough data to be useful.
48
+ * Writes immediately with whatever data is available (empty arrays for missing).
49
+ * This ensures disk cache is created after first Analytics page visit.
50
+ */
51
+ function persistCacheIfComplete() {
52
+ const daily = cache.get('daily');
53
+ const monthly = cache.get('monthly');
54
+ const session = cache.get('session');
55
+ // Write if we have at least daily data (the most essential)
56
+ if (daily) {
57
+ (0, usage_disk_cache_1.writeDiskCache)(daily.data, monthly?.data ?? [], session?.data ?? []);
58
+ }
59
+ }
60
+ /**
61
+ * Get cached data or fetch from loader with TTL
62
+ * Also coalesces concurrent requests to prevent duplicate library calls
63
+ * Implements stale-while-revalidate pattern for instant responses
64
+ */
65
+ async function getCachedData(key, ttl, loader) {
66
+ // Ensure disk cache is loaded on first request
67
+ ensureDiskCacheLoaded();
68
+ const cached = cache.get(key);
69
+ const now = Date.now();
70
+ // Fresh cache - return immediately
71
+ if (cached && now - cached.timestamp < ttl) {
72
+ return cached.data;
73
+ }
74
+ // Stale cache - return immediately, refresh in background (SWR pattern)
75
+ if (cached && now - cached.timestamp < STALE_TTL) {
76
+ // Fire and forget background refresh if not already pending
77
+ if (!pendingRequests.has(key)) {
78
+ const promise = loader()
79
+ .then((data) => {
80
+ cache.set(key, { data, timestamp: Date.now() });
81
+ lastFetchTimestamp = Date.now();
82
+ // Persist to disk if all data types are cached
83
+ persistCacheIfComplete();
84
+ })
85
+ .catch((err) => {
86
+ console.error(`[!] Background refresh failed for ${key}:`, err);
87
+ })
88
+ .finally(() => {
89
+ pendingRequests.delete(key);
90
+ });
91
+ pendingRequests.set(key, promise);
92
+ }
93
+ return cached.data;
94
+ }
95
+ // No usable cache - check if request is already pending (coalesce)
96
+ const pending = pendingRequests.get(key);
97
+ if (pending) {
98
+ return pending;
99
+ }
100
+ // Create new request
101
+ const promise = loader()
102
+ .then((data) => {
103
+ cache.set(key, { data, timestamp: Date.now() });
104
+ lastFetchTimestamp = Date.now();
105
+ // Persist to disk if all data types are cached
106
+ persistCacheIfComplete();
107
+ return data;
108
+ })
109
+ .finally(() => {
110
+ pendingRequests.delete(key);
111
+ });
112
+ pendingRequests.set(key, promise);
113
+ return promise;
114
+ }
115
+ /** Cached loader for daily usage data */
116
+ async function getCachedDailyData() {
117
+ return getCachedData('daily', CACHE_TTL.daily, async () => {
118
+ return (await (0, data_loader_1.loadDailyUsageData)());
119
+ });
120
+ }
121
+ /** Cached loader for monthly usage data */
122
+ async function getCachedMonthlyData() {
123
+ return getCachedData('monthly', CACHE_TTL.monthly, async () => {
124
+ return (await (0, data_loader_1.loadMonthlyUsageData)());
125
+ });
126
+ }
127
+ /** Cached loader for session data */
128
+ async function getCachedSessionData() {
129
+ return getCachedData('session', CACHE_TTL.session, async () => {
130
+ return (await (0, data_loader_1.loadSessionData)());
131
+ });
132
+ }
133
+ /**
134
+ * Clear all cached data (useful for manual refresh)
135
+ */
136
+ function clearUsageCache() {
137
+ cache.clear();
138
+ (0, usage_disk_cache_1.clearDiskCache)();
139
+ // Reset so next API call will try to reload from disk/source
140
+ diskCacheInitialized = false;
141
+ }
142
+ exports.clearUsageCache = clearUsageCache;
143
+ // Track if background refresh is in progress
144
+ let isRefreshing = false;
145
+ /**
146
+ * Load fresh data from better-ccusage and update both memory and disk caches
147
+ */
148
+ async function refreshFromSource() {
149
+ const [daily, monthly, session] = await Promise.all([
150
+ (0, data_loader_1.loadDailyUsageData)(),
151
+ (0, data_loader_1.loadMonthlyUsageData)(),
152
+ (0, data_loader_1.loadSessionData)(),
153
+ ]);
154
+ // Update in-memory cache
155
+ const now = Date.now();
156
+ cache.set('daily', { data: daily, timestamp: now });
157
+ cache.set('monthly', { data: monthly, timestamp: now });
158
+ cache.set('session', { data: session, timestamp: now });
159
+ lastFetchTimestamp = now;
160
+ // Persist to disk
161
+ (0, usage_disk_cache_1.writeDiskCache)(daily, monthly, session);
162
+ return { daily, monthly, session };
163
+ }
164
+ // ============================================================================
165
+ // Module Initialization - Load disk cache immediately for instant API responses
166
+ // ============================================================================
167
+ /**
168
+ * Initialize in-memory cache from disk cache (lazy - called on first API request).
169
+ * This ensures first API request gets instant data without calling better-ccusage.
170
+ * Background refresh is NOT triggered here - it happens via SWR pattern in getCachedData().
171
+ */
172
+ function ensureDiskCacheLoaded() {
173
+ if (diskCacheInitialized)
174
+ return;
175
+ diskCacheInitialized = true;
176
+ const diskCache = (0, usage_disk_cache_1.readDiskCache)();
177
+ if (!diskCache)
178
+ return;
179
+ // Load disk cache into memory (regardless of freshness)
180
+ // SWR pattern in getCachedData() will handle background refresh
181
+ cache.set('daily', { data: diskCache.daily, timestamp: diskCache.timestamp });
182
+ cache.set('monthly', { data: diskCache.monthly, timestamp: diskCache.timestamp });
183
+ cache.set('session', { data: diskCache.session, timestamp: diskCache.timestamp });
184
+ lastFetchTimestamp = diskCache.timestamp;
185
+ }
186
+ /**
187
+ * Pre-warm usage caches on server startup
188
+ *
189
+ * Strategy:
190
+ * 1. Check disk cache - if fresh, use it (instant startup)
191
+ * 2. If stale, use it immediately but trigger background refresh
192
+ * 3. If no cache, return immediately and let first request trigger load
193
+ *
194
+ * This ensures dashboard opens in <1s regardless of cache state
195
+ */
196
+ async function prewarmUsageCache() {
197
+ const start = Date.now();
198
+ console.log('[i] Pre-warming usage cache...');
199
+ try {
200
+ const diskCache = (0, usage_disk_cache_1.readDiskCache)();
201
+ // Fresh disk cache - use it directly
202
+ if (diskCache && (0, usage_disk_cache_1.isDiskCacheFresh)(diskCache)) {
203
+ const now = Date.now();
204
+ cache.set('daily', { data: diskCache.daily, timestamp: diskCache.timestamp });
205
+ cache.set('monthly', { data: diskCache.monthly, timestamp: diskCache.timestamp });
206
+ cache.set('session', { data: diskCache.session, timestamp: diskCache.timestamp });
207
+ lastFetchTimestamp = diskCache.timestamp;
208
+ const elapsed = Date.now() - start;
209
+ console.log(`[OK] Usage cache ready from disk (${elapsed}ms, cached ${(0, usage_disk_cache_1.getCacheAge)(diskCache)})`);
210
+ return { timestamp: now, elapsed, source: 'disk-fresh' };
211
+ }
212
+ // Stale disk cache - use it immediately, refresh in background
213
+ if (diskCache && (0, usage_disk_cache_1.isDiskCacheStale)(diskCache)) {
214
+ const now = Date.now();
215
+ cache.set('daily', { data: diskCache.daily, timestamp: diskCache.timestamp });
216
+ cache.set('monthly', { data: diskCache.monthly, timestamp: diskCache.timestamp });
217
+ cache.set('session', { data: diskCache.session, timestamp: diskCache.timestamp });
218
+ lastFetchTimestamp = diskCache.timestamp;
219
+ const elapsed = Date.now() - start;
220
+ console.log(`[OK] Usage cache ready from disk (${elapsed}ms, stale ${(0, usage_disk_cache_1.getCacheAge)(diskCache)}, refreshing...)`);
221
+ // Background refresh
222
+ if (!isRefreshing) {
223
+ isRefreshing = true;
224
+ refreshFromSource()
225
+ .then(() => console.log('[OK] Background refresh complete'))
226
+ .catch((err) => console.error('[!] Background refresh failed:', err))
227
+ .finally(() => {
228
+ isRefreshing = false;
229
+ });
230
+ }
231
+ return { timestamp: now, elapsed, source: 'disk-stale' };
232
+ }
233
+ // No usable disk cache - refresh from source (blocking for first startup only)
234
+ console.log('[i] No disk cache, loading from source...');
235
+ await refreshFromSource();
236
+ const elapsed = Date.now() - start;
237
+ console.log(`[OK] Usage cache ready (${elapsed}ms)`);
238
+ return { timestamp: Date.now(), elapsed, source: 'fresh' };
239
+ }
240
+ catch (err) {
241
+ console.error('[!] Failed to prewarm usage cache:', err);
242
+ throw err;
243
+ }
244
+ }
245
+ exports.prewarmUsageCache = prewarmUsageCache;
246
+ // ============================================================================
247
+ // Validation Helpers
248
+ // ============================================================================
249
+ /**
250
+ * Validate date string in YYYYMMDD format
251
+ */
252
+ function validateDate(dateString) {
253
+ if (!dateString)
254
+ return undefined;
255
+ if (!DATE_REGEX.test(dateString)) {
256
+ throw new Error('Invalid date format. Use YYYYMMDD');
257
+ }
258
+ // Basic range check
259
+ const year = parseInt(dateString.substring(0, 4), 10);
260
+ const month = parseInt(dateString.substring(4, 6), 10);
261
+ const day = parseInt(dateString.substring(6, 8), 10);
262
+ if (year < 2024 || year > 2100)
263
+ throw new Error('Year out of valid range');
264
+ if (month < 1 || month > 12)
265
+ throw new Error('Month out of valid range');
266
+ if (day < 1 || day > 31)
267
+ throw new Error('Day out of valid range');
268
+ return dateString;
269
+ }
270
+ /**
271
+ * Validate and parse limit parameter
272
+ */
273
+ function validateLimit(limit) {
274
+ if (!limit)
275
+ return DEFAULT_LIMIT;
276
+ const num = parseInt(limit, 10);
277
+ if (isNaN(num) || num < 1 || num > MAX_LIMIT) {
278
+ throw new Error(`Limit must be between 1 and ${MAX_LIMIT}`);
279
+ }
280
+ return num;
281
+ }
282
+ /**
283
+ * Validate and parse offset parameter
284
+ */
285
+ function validateOffset(offset) {
286
+ if (!offset)
287
+ return 0;
288
+ const num = parseInt(offset, 10);
289
+ if (isNaN(num) || num < 0) {
290
+ throw new Error('Offset must be a non-negative number');
291
+ }
292
+ return num;
293
+ }
294
+ /**
295
+ * Filter data by date range
296
+ */
297
+ function filterByDateRange(data, since, until) {
298
+ if (!since && !until)
299
+ return data;
300
+ return data.filter((item) => {
301
+ // Get the date field (prioritize date, then month, then lastActivity)
302
+ const itemDate = item.date || item.month?.replace('-', '') || item.lastActivity?.replace(/-/g, '');
303
+ if (!itemDate)
304
+ return true;
305
+ // Normalize to YYYYMMDD for comparison
306
+ const normalizedDate = itemDate.replace(/-/g, '').substring(0, 8);
307
+ if (since && normalizedDate < since)
308
+ return false;
309
+ if (until && normalizedDate > until)
310
+ return false;
311
+ return true;
312
+ });
313
+ }
314
+ /**
315
+ * Create standard error response
316
+ */
317
+ function errorResponse(res, error, defaultMessage) {
318
+ console.error(defaultMessage + ':', error);
319
+ const errorMessage = error instanceof Error ? error.message : 'Unknown error';
320
+ const isValidationError = errorMessage.includes('Invalid') ||
321
+ errorMessage.includes('format') ||
322
+ errorMessage.includes('range') ||
323
+ errorMessage.includes('must be');
324
+ const statusCode = isValidationError ? 400 : 500;
325
+ res.status(statusCode).json({
326
+ success: false,
327
+ error: isValidationError ? errorMessage : defaultMessage,
328
+ });
329
+ }
330
+ /**
331
+ * GET /api/usage/summary
332
+ *
333
+ * Returns usage summary data for quick dashboard display.
334
+ * Query: ?since=YYYYMMDD&until=YYYYMMDD
335
+ */
336
+ exports.usageRoutes.get('/summary', async (req, res) => {
337
+ try {
338
+ const since = validateDate(req.query.since);
339
+ const until = validateDate(req.query.until);
340
+ const dailyData = await getCachedDailyData();
341
+ const filtered = filterByDateRange(dailyData, since, until);
342
+ // Calculate totals
343
+ let totalInputTokens = 0;
344
+ let totalOutputTokens = 0;
345
+ let totalCacheTokens = 0;
346
+ let totalCost = 0;
347
+ for (const day of filtered) {
348
+ totalInputTokens += day.inputTokens;
349
+ totalOutputTokens += day.outputTokens;
350
+ totalCacheTokens += day.cacheCreationTokens + day.cacheReadTokens;
351
+ totalCost += day.totalCost;
352
+ }
353
+ const totalTokens = totalInputTokens + totalOutputTokens;
354
+ res.json({
355
+ success: true,
356
+ data: {
357
+ totalTokens,
358
+ totalInputTokens,
359
+ totalOutputTokens,
360
+ totalCacheTokens,
361
+ totalCost: Math.round(totalCost * 100) / 100,
362
+ totalDays: filtered.length,
363
+ averageTokensPerDay: filtered.length > 0 ? Math.round(totalTokens / filtered.length) : 0,
364
+ averageCostPerDay: filtered.length > 0 ? Math.round((totalCost / filtered.length) * 100) / 100 : 0,
365
+ },
366
+ });
367
+ }
368
+ catch (error) {
369
+ errorResponse(res, error, 'Failed to fetch usage summary');
370
+ }
371
+ });
372
+ /**
373
+ * GET /api/usage/daily
374
+ *
375
+ * Returns daily usage trends for chart visualization.
376
+ * Query: ?since=YYYYMMDD&until=YYYYMMDD
377
+ */
378
+ exports.usageRoutes.get('/daily', async (req, res) => {
379
+ try {
380
+ const since = validateDate(req.query.since);
381
+ const until = validateDate(req.query.until);
382
+ const dailyData = await getCachedDailyData();
383
+ const filtered = filterByDateRange(dailyData, since, until);
384
+ // Transform for chart consumption
385
+ const trends = filtered.map((day) => ({
386
+ date: day.date,
387
+ tokens: day.inputTokens + day.outputTokens,
388
+ inputTokens: day.inputTokens,
389
+ outputTokens: day.outputTokens,
390
+ cacheTokens: day.cacheCreationTokens + day.cacheReadTokens,
391
+ cost: Math.round(day.totalCost * 100) / 100,
392
+ modelsUsed: day.modelsUsed.length,
393
+ }));
394
+ res.json({
395
+ success: true,
396
+ data: trends,
397
+ });
398
+ }
399
+ catch (error) {
400
+ errorResponse(res, error, 'Failed to fetch daily usage');
401
+ }
402
+ });
403
+ /**
404
+ * GET /api/usage/models
405
+ *
406
+ * Returns usage breakdown by model for pie/bar charts.
407
+ * Query: ?since=YYYYMMDD&until=YYYYMMDD
408
+ */
409
+ exports.usageRoutes.get('/models', async (req, res) => {
410
+ try {
411
+ const since = validateDate(req.query.since);
412
+ const until = validateDate(req.query.until);
413
+ const dailyData = await getCachedDailyData();
414
+ const filtered = filterByDateRange(dailyData, since, until);
415
+ // Aggregate model usage across all days
416
+ const modelMap = new Map();
417
+ for (const day of filtered) {
418
+ for (const breakdown of day.modelBreakdowns) {
419
+ const existing = modelMap.get(breakdown.modelName) || {
420
+ model: breakdown.modelName,
421
+ inputTokens: 0,
422
+ outputTokens: 0,
423
+ cacheTokens: 0,
424
+ cost: 0,
425
+ };
426
+ existing.inputTokens += breakdown.inputTokens;
427
+ existing.outputTokens += breakdown.outputTokens;
428
+ existing.cacheTokens += breakdown.cacheCreationTokens + breakdown.cacheReadTokens;
429
+ existing.cost += breakdown.cost;
430
+ modelMap.set(breakdown.modelName, existing);
431
+ }
432
+ }
433
+ // Calculate totals for percentage
434
+ const models = Array.from(modelMap.values());
435
+ const totalTokens = models.reduce((sum, m) => sum + m.inputTokens + m.outputTokens, 0);
436
+ // Add percentage and sort by tokens
437
+ const result = models
438
+ .map((m) => ({
439
+ ...m,
440
+ tokens: m.inputTokens + m.outputTokens,
441
+ cost: Math.round(m.cost * 100) / 100,
442
+ percentage: totalTokens > 0
443
+ ? Math.round(((m.inputTokens + m.outputTokens) / totalTokens) * 1000) / 10
444
+ : 0,
445
+ }))
446
+ .sort((a, b) => b.tokens - a.tokens);
447
+ res.json({
448
+ success: true,
449
+ data: result,
450
+ });
451
+ }
452
+ catch (error) {
453
+ errorResponse(res, error, 'Failed to fetch model usage');
454
+ }
455
+ });
456
+ /**
457
+ * GET /api/usage/sessions
458
+ *
459
+ * Returns paginated list of sessions.
460
+ * Query: ?since=YYYYMMDD&until=YYYYMMDD&limit=50&offset=0
461
+ */
462
+ exports.usageRoutes.get('/sessions', async (req, res) => {
463
+ try {
464
+ const since = validateDate(req.query.since);
465
+ const until = validateDate(req.query.until);
466
+ const limit = validateLimit(req.query.limit);
467
+ const offset = validateOffset(req.query.offset);
468
+ const sessionData = await getCachedSessionData();
469
+ // Filter by date range using lastActivity
470
+ const filtered = filterByDateRange(sessionData, since, until);
471
+ // Sort by lastActivity descending
472
+ const sorted = [...filtered].sort((a, b) => new Date(b.lastActivity).getTime() - new Date(a.lastActivity).getTime());
473
+ // Paginate
474
+ const paginated = sorted.slice(offset, offset + limit);
475
+ // Transform for frontend
476
+ const sessions = paginated.map((s) => ({
477
+ sessionId: s.sessionId,
478
+ projectPath: s.projectPath,
479
+ tokens: s.inputTokens + s.outputTokens,
480
+ inputTokens: s.inputTokens,
481
+ outputTokens: s.outputTokens,
482
+ cost: Math.round(s.totalCost * 100) / 100,
483
+ lastActivity: s.lastActivity,
484
+ modelsUsed: s.modelsUsed,
485
+ }));
486
+ res.json({
487
+ success: true,
488
+ data: {
489
+ sessions,
490
+ total: filtered.length,
491
+ limit,
492
+ offset,
493
+ hasMore: offset + limit < filtered.length,
494
+ },
495
+ });
496
+ }
497
+ catch (error) {
498
+ errorResponse(res, error, 'Failed to fetch sessions');
499
+ }
500
+ });
501
+ /**
502
+ * GET /api/usage/monthly
503
+ *
504
+ * Returns monthly usage summary for charts.
505
+ * Query: ?since=YYYYMMDD&until=YYYYMMDD
506
+ */
507
+ exports.usageRoutes.get('/monthly', async (req, res) => {
508
+ try {
509
+ const since = validateDate(req.query.since);
510
+ const until = validateDate(req.query.until);
511
+ const monthlyData = await getCachedMonthlyData();
512
+ // Filter by date range (convert month YYYY-MM to YYYYMM01 for comparison)
513
+ const filtered = since || until
514
+ ? monthlyData.filter((m) => {
515
+ const monthDate = m.month.replace('-', '') + '01';
516
+ if (since && monthDate < since)
517
+ return false;
518
+ if (until && monthDate > until)
519
+ return false;
520
+ return true;
521
+ })
522
+ : monthlyData;
523
+ // Transform for charts
524
+ const result = filtered.map((m) => ({
525
+ month: m.month,
526
+ tokens: m.inputTokens + m.outputTokens,
527
+ inputTokens: m.inputTokens,
528
+ outputTokens: m.outputTokens,
529
+ cacheTokens: m.cacheCreationTokens + m.cacheReadTokens,
530
+ cost: Math.round(m.totalCost * 100) / 100,
531
+ modelsUsed: m.modelsUsed.length,
532
+ }));
533
+ res.json({
534
+ success: true,
535
+ data: result.sort((a, b) => a.month.localeCompare(b.month)),
536
+ });
537
+ }
538
+ catch (error) {
539
+ errorResponse(res, error, 'Failed to fetch monthly usage');
540
+ }
541
+ });
542
+ /**
543
+ * POST /api/usage/refresh
544
+ *
545
+ * Clears the usage cache to force fresh data fetch.
546
+ * Useful when user wants to see latest data immediately.
547
+ */
548
+ exports.usageRoutes.post('/refresh', (_req, res) => {
549
+ clearUsageCache();
550
+ res.json({
551
+ success: true,
552
+ message: 'Usage cache cleared',
553
+ });
554
+ });
555
+ /**
556
+ * GET /api/usage/status
557
+ *
558
+ * Returns cache status including last fetch timestamp.
559
+ * Used by UI to show "Last updated: X ago" indicator.
560
+ */
561
+ exports.usageRoutes.get('/status', (_req, res) => {
562
+ res.json({
563
+ success: true,
564
+ data: {
565
+ lastFetch: lastFetchTimestamp,
566
+ cacheSize: cache.size,
567
+ },
568
+ });
569
+ });
570
+ //# sourceMappingURL=usage-routes.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"usage-routes.js","sourceRoot":"","sources":["../../src/web-server/usage-routes.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@kaitranntt/ccs",
3
- "version": "5.11.0",
3
+ "version": "5.12.0-dev.1",
4
4
  "description": "Claude Code Switch - Instant profile switching between Claude Sonnet 4.5 and GLM 4.6",
5
5
  "keywords": [
6
6
  "cli",
@@ -79,6 +79,7 @@
79
79
  "postinstall": "node scripts/postinstall.js"
80
80
  },
81
81
  "dependencies": {
82
+ "better-ccusage": "^1.2.6",
82
83
  "boxen": "^8.0.1",
83
84
  "chalk": "^5.6.2",
84
85
  "chokidar": "^5.0.0",
@@ -1 +0,0 @@
1
- import{r as n}from"./react-vendor-CW-MU7-e.js";const M=t=>t.replace(/([a-z0-9])([A-Z])/g,"$1-$2").toLowerCase(),_=t=>t.replace(/^([A-Z])|[\s-_]+(\w)/g,(a,o,c)=>c?c.toUpperCase():o.toLowerCase()),r=t=>{const a=_(t);return a.charAt(0).toUpperCase()+a.slice(1)},y=(...t)=>t.filter((a,o,c)=>!!a&&a.trim()!==""&&c.indexOf(a)===o).join(" ").trim(),v=t=>{for(const a in t)if(a.startsWith("aria-")||a==="role"||a==="title")return!0};var f={xmlns:"http://www.w3.org/2000/svg",width:24,height:24,viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:2,strokeLinecap:"round",strokeLinejoin:"round"};const m=n.forwardRef(({color:t="currentColor",size:a=24,strokeWidth:o=2,absoluteStrokeWidth:c,className:h="",children:s,iconNode:k,...d},p)=>n.createElement("svg",{ref:p,...f,width:a,height:a,stroke:t,strokeWidth:c?Number(o)*24/Number(a):o,className:y("lucide",h),...!s&&!v(d)&&{"aria-hidden":"true"},...d},[...k.map(([i,l])=>n.createElement(i,l)),...Array.isArray(s)?s:[s]]));const e=(t,a)=>{const o=n.forwardRef(({className:c,...h},s)=>n.createElement(m,{ref:s,iconNode:a,className:y(`lucide-${M(r(t))}`,`lucide-${t}`,c),...h}));return o.displayName=r(t),o};const u=[["path",{d:"M22 12h-2.48a2 2 0 0 0-1.93 1.46l-2.35 8.36a.25.25 0 0 1-.48 0L9.24 2.18a.25.25 0 0 0-.48 0l-2.35 8.36A2 2 0 0 1 4.49 12H2",key:"169zse"}]],n1=e("activity",u);const w=[["path",{d:"M5 12h14",key:"1ays0h"}],["path",{d:"m12 5 7 7-7 7",key:"xquz4c"}]],h1=e("arrow-right",w);const $=[["path",{d:"M12 7v14",key:"1akyts"}],["path",{d:"M3 18a1 1 0 0 1-1-1V4a1 1 0 0 1 1-1h5a4 4 0 0 1 4 4 4 4 0 0 1 4-4h5a1 1 0 0 1 1 1v13a1 1 0 0 1-1 1h-6a3 3 0 0 0-3 3 3 3 0 0 0-3-3z",key:"ruj8y"}]],d1=e("book-open",$);const x=[["path",{d:"M12 8V4H8",key:"hb8ula"}],["rect",{width:"16",height:"12",x:"4",y:"8",rx:"2",key:"enze0r"}],["path",{d:"M2 14h2",key:"vft8re"}],["path",{d:"M20 14h2",key:"4cs60a"}],["path",{d:"M15 13v2",key:"1xurst"}],["path",{d:"M9 13v2",key:"rq6x2g"}]],r1=e("bot",x);const N=[["path",{d:"M20 6 9 17l-5-5",key:"1gmf2c"}]],y1=e("check",N);const g=[["path",{d:"m6 9 6 6 6-6",key:"qrunsl"}]],k1=e("chevron-down",g);const z=[["path",{d:"m9 18 6-6-6-6",key:"mthhwq"}]],p1=e("chevron-right",z);const b=[["path",{d:"M21.801 10A10 10 0 1 1 17 3.335",key:"yps3ct"}],["path",{d:"m9 11 3 3L22 4",key:"1pflzl"}]],i1=e("circle-check-big",b);const C=[["circle",{cx:"12",cy:"12",r:"10",key:"1mglay"}],["path",{d:"m15 9-6 6",key:"1uzhvr"}],["path",{d:"m9 9 6 6",key:"z0biqf"}]],l1=e("circle-x",C);const j=[["rect",{x:"2",y:"6",width:"20",height:"8",rx:"1",key:"1estib"}],["path",{d:"M17 14v7",key:"7m2elx"}],["path",{d:"M7 14v7",key:"1cm7wv"}],["path",{d:"M17 3v3",key:"1v4jwn"}],["path",{d:"M7 3v3",key:"7o6guu"}],["path",{d:"M10 14 2.3 6.3",key:"1023jk"}],["path",{d:"m14 6 7.7 7.7",key:"1s8pl2"}],["path",{d:"m8 6 8 8",key:"hl96qh"}]],M1=e("construction",j);const A=[["circle",{cx:"12",cy:"12",r:"1",key:"41hilf"}],["circle",{cx:"19",cy:"12",r:"1",key:"1wjl8i"}],["circle",{cx:"5",cy:"12",r:"1",key:"1pcz8c"}]],_1=e("ellipsis",A);const q=[["path",{d:"M10.733 5.076a10.744 10.744 0 0 1 11.205 6.575 1 1 0 0 1 0 .696 10.747 10.747 0 0 1-1.444 2.49",key:"ct8e1f"}],["path",{d:"M14.084 14.158a3 3 0 0 1-4.242-4.242",key:"151rxh"}],["path",{d:"M17.479 17.499a10.75 10.75 0 0 1-15.417-5.151 1 1 0 0 1 0-.696 10.75 10.75 0 0 1 4.446-5.143",key:"13bj9a"}],["path",{d:"m2 2 20 20",key:"1ooewy"}]],v1=e("eye-off",q);const H=[["path",{d:"M2.062 12.348a1 1 0 0 1 0-.696 10.75 10.75 0 0 1 19.876 0 1 1 0 0 1 0 .696 10.75 10.75 0 0 1-19.876 0",key:"1nclc0"}],["circle",{cx:"12",cy:"12",r:"3",key:"1v7zrd"}]],f1=e("eye",H);const L=[["path",{d:"M6 22a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h8a2.4 2.4 0 0 1 1.704.706l3.588 3.588A2.4 2.4 0 0 1 20 8v12a2 2 0 0 1-2 2z",key:"1oefj6"}],["path",{d:"M14 2v5a1 1 0 0 0 1 1h5",key:"wfsgrz"}],["path",{d:"M10 9H8",key:"b1mrlr"}],["path",{d:"M16 13H8",key:"t4e002"}],["path",{d:"M16 17H8",key:"z1uh3a"}]],m1=e("file-text",L);const V=[["path",{d:"m6 14 1.5-2.9A2 2 0 0 1 9.24 10H20a2 2 0 0 1 1.94 2.5l-1.54 6a2 2 0 0 1-1.95 1.5H4a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h3.9a2 2 0 0 1 1.69.9l.81 1.2a2 2 0 0 0 1.67.9H18a2 2 0 0 1 2 2v2",key:"usdka0"}]],u1=e("folder-open",V);const S=[["path",{d:"M15 21v-8a1 1 0 0 0-1-1h-4a1 1 0 0 0-1 1v8",key:"5wwlr5"}],["path",{d:"M3 10a2 2 0 0 1 .709-1.528l7-6a2 2 0 0 1 2.582 0l7 6A2 2 0 0 1 21 10v9a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2z",key:"r6nss1"}]],w1=e("house",S);const E=[["path",{d:"m15.5 7.5 2.3 2.3a1 1 0 0 0 1.4 0l2.1-2.1a1 1 0 0 0 0-1.4L19 4",key:"g0fldk"}],["path",{d:"m21 2-9.6 9.6",key:"1j0ho8"}],["circle",{cx:"7.5",cy:"15.5",r:"5.5",key:"yqb3hr"}]],$1=e("key",E);const B=[["path",{d:"M21 12a9 9 0 1 1-6.219-8.56",key:"13zald"}]],x1=e("loader-circle",B);const P=[["path",{d:"M20.985 12.486a9 9 0 1 1-9.473-9.472c.405-.022.617.46.402.803a6 6 0 0 0 8.268 8.268c.344-.215.825-.004.803.401",key:"kfwtm"}]],N1=e("moon",P);const R=[["rect",{width:"18",height:"18",x:"3",y:"3",rx:"2",key:"afitv7"}],["path",{d:"M9 3v18",key:"fh3hqa"}]],g1=e("panel-left",R);const W=[["path",{d:"M5 12h14",key:"1ays0h"}],["path",{d:"M12 5v14",key:"s699le"}]],z1=e("plus",W);const O=[["path",{d:"M3 12a9 9 0 0 1 9-9 9.75 9.75 0 0 1 6.74 2.74L21 8",key:"v9h5vc"}],["path",{d:"M21 3v5h-5",key:"1q7to0"}],["path",{d:"M21 12a9 9 0 0 1-9 9 9.75 9.75 0 0 1-6.74-2.74L3 16",key:"3uifl3"}],["path",{d:"M8 16H3v5",key:"1cv678"}]],b1=e("refresh-cw",O);const U=[["path",{d:"M15.2 3a2 2 0 0 1 1.4.6l3.8 3.8a2 2 0 0 1 .6 1.4V19a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2z",key:"1c8476"}],["path",{d:"M17 21v-7a1 1 0 0 0-1-1H8a1 1 0 0 0-1 1v7",key:"1ydtos"}],["path",{d:"M7 3v4a1 1 0 0 0 1 1h7",key:"t51u73"}]],C1=e("save",U);const T=[["path",{d:"M9.671 4.136a2.34 2.34 0 0 1 4.659 0 2.34 2.34 0 0 0 3.319 1.915 2.34 2.34 0 0 1 2.33 4.033 2.34 2.34 0 0 0 0 3.831 2.34 2.34 0 0 1-2.33 4.033 2.34 2.34 0 0 0-3.319 1.915 2.34 2.34 0 0 1-4.659 0 2.34 2.34 0 0 0-3.32-1.915 2.34 2.34 0 0 1-2.33-4.033 2.34 2.34 0 0 0 0-3.831A2.34 2.34 0 0 1 6.35 6.051a2.34 2.34 0 0 0 3.319-1.915",key:"1i5ecw"}],["circle",{cx:"12",cy:"12",r:"3",key:"1v7zrd"}]],j1=e("settings",T);const Z=[["path",{d:"M20 13c0 5-3.5 7.5-7.66 8.95a1 1 0 0 1-.67-.01C7.5 20.5 4 18 4 13V6a1 1 0 0 1 1-1c2 0 4.5-1.2 6.24-2.72a1.17 1.17 0 0 1 1.52 0C14.51 3.81 17 5 19 5a1 1 0 0 1 1 1z",key:"oel41y"}]],A1=e("shield",Z);const F=[["path",{d:"M11.017 2.814a1 1 0 0 1 1.966 0l1.051 5.558a2 2 0 0 0 1.594 1.594l5.558 1.051a1 1 0 0 1 0 1.966l-5.558 1.051a2 2 0 0 0-1.594 1.594l-1.051 5.558a1 1 0 0 1-1.966 0l-1.051-5.558a2 2 0 0 0-1.594-1.594l-5.558-1.051a1 1 0 0 1 0-1.966l5.558-1.051a2 2 0 0 0 1.594-1.594z",key:"1s2grr"}],["path",{d:"M20 2v4",key:"1rf3ol"}],["path",{d:"M22 4h-4",key:"gwowj6"}],["circle",{cx:"4",cy:"20",r:"2",key:"6kqj1y"}]],q1=e("sparkles",F);const K=[["path",{d:"M12 3H5a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h14a2 2 0 0 0 2-2v-7",key:"1m0v6g"}],["path",{d:"M18.375 2.625a1 1 0 0 1 3 3l-9.013 9.014a2 2 0 0 1-.853.505l-2.873.84a.5.5 0 0 1-.62-.62l.84-2.873a2 2 0 0 1 .506-.852z",key:"ohrbg2"}]],H1=e("square-pen",K);const I=[["path",{d:"M11.525 2.295a.53.53 0 0 1 .95 0l2.31 4.679a2.123 2.123 0 0 0 1.595 1.16l5.166.756a.53.53 0 0 1 .294.904l-3.736 3.638a2.123 2.123 0 0 0-.611 1.878l.882 5.14a.53.53 0 0 1-.771.56l-4.618-2.428a2.122 2.122 0 0 0-1.973 0L6.396 21.01a.53.53 0 0 1-.77-.56l.881-5.139a2.122 2.122 0 0 0-.611-1.879L2.16 9.795a.53.53 0 0 1 .294-.906l5.165-.755a2.122 2.122 0 0 0 1.597-1.16z",key:"r04s7s"}]],L1=e("star",I);const X=[["path",{d:"M11 2v2",key:"1539x4"}],["path",{d:"M5 2v2",key:"1yf1q8"}],["path",{d:"M5 3H4a2 2 0 0 0-2 2v4a6 6 0 0 0 12 0V5a2 2 0 0 0-2-2h-1",key:"rb5t3r"}],["path",{d:"M8 15a6 6 0 0 0 12 0v-3",key:"x18d4x"}],["circle",{cx:"20",cy:"10",r:"2",key:"ts1r5v"}]],V1=e("stethoscope",X);const D=[["circle",{cx:"12",cy:"12",r:"4",key:"4exip2"}],["path",{d:"M12 2v2",key:"tus03m"}],["path",{d:"M12 20v2",key:"1lh1kg"}],["path",{d:"m4.93 4.93 1.41 1.41",key:"149t6j"}],["path",{d:"m17.66 17.66 1.41 1.41",key:"ptbguv"}],["path",{d:"M2 12h2",key:"1t8f8n"}],["path",{d:"M20 12h2",key:"1q8mjw"}],["path",{d:"m6.34 17.66-1.41 1.41",key:"1m8zz5"}],["path",{d:"m19.07 4.93-1.41 1.41",key:"1shlcs"}]],S1=e("sun",D);const G=[["path",{d:"M10 11v6",key:"nco0om"}],["path",{d:"M14 11v6",key:"outv1u"}],["path",{d:"M19 6v14a2 2 0 0 1-2 2H7a2 2 0 0 1-2-2V6",key:"miytrc"}],["path",{d:"M3 6h18",key:"d0wm0j"}],["path",{d:"M8 6V4a2 2 0 0 1 2-2h4a2 2 0 0 1 2 2v2",key:"e791ji"}]],E1=e("trash-2",G);const J=[["path",{d:"m21.73 18-8-14a2 2 0 0 0-3.48 0l-8 14A2 2 0 0 0 4 21h16a2 2 0 0 0 1.73-3",key:"wmoenq"}],["path",{d:"M12 9v4",key:"juzpu7"}],["path",{d:"M12 17h.01",key:"p32p05"}]],B1=e("triangle-alert",J);const Q=[["path",{d:"M19 21v-2a4 4 0 0 0-4-4H9a4 4 0 0 0-4 4v2",key:"975kel"}],["circle",{cx:"12",cy:"7",r:"4",key:"17ys0d"}]],P1=e("user",Q);const Y=[["path",{d:"M16 21v-2a4 4 0 0 0-4-4H6a4 4 0 0 0-4 4v2",key:"1yyitq"}],["path",{d:"M16 3.128a4 4 0 0 1 0 7.744",key:"16gr8j"}],["path",{d:"M22 21v-2a4 4 0 0 0-3-3.87",key:"kshegd"}],["circle",{cx:"9",cy:"7",r:"4",key:"nufk8"}]],R1=e("users",Y);const e1=[["path",{d:"M12 20h.01",key:"zekei9"}],["path",{d:"M8.5 16.429a5 5 0 0 1 7 0",key:"1bycff"}],["path",{d:"M5 12.859a10 10 0 0 1 5.17-2.69",key:"1dl1wf"}],["path",{d:"M19 12.859a10 10 0 0 0-2.007-1.523",key:"4k23kn"}],["path",{d:"M2 8.82a15 15 0 0 1 4.177-2.643",key:"1grhjp"}],["path",{d:"M22 8.82a15 15 0 0 0-11.288-3.764",key:"z3jwby"}],["path",{d:"m2 2 20 20",key:"1ooewy"}]],W1=e("wifi-off",e1);const a1=[["path",{d:"M12 20h.01",key:"zekei9"}],["path",{d:"M2 8.82a15 15 0 0 1 20 0",key:"dnpr2z"}],["path",{d:"M5 12.859a10 10 0 0 1 14 0",key:"1x1e6c"}],["path",{d:"M8.5 16.429a5 5 0 0 1 7 0",key:"1bycff"}]],O1=e("wifi",a1);const t1=[["path",{d:"M14.7 6.3a1 1 0 0 0 0 1.4l1.6 1.6a1 1 0 0 0 1.4 0l3.106-3.105c.32-.322.863-.22.983.218a6 6 0 0 1-8.259 7.057l-7.91 7.91a1 1 0 0 1-2.999-3l7.91-7.91a6 6 0 0 1 7.057-8.259c.438.12.54.662.219.984z",key:"1ngwbx"}]],U1=e("wrench",t1);const o1=[["path",{d:"M18 6 6 18",key:"1bl5f8"}],["path",{d:"m6 6 12 12",key:"d8bk6v"}]],T1=e("x",o1);const c1=[["path",{d:"M4 14a1 1 0 0 1-.78-1.63l9.9-10.2a.5.5 0 0 1 .86.46l-1.92 6.02A1 1 0 0 0 13 10h7a1 1 0 0 1 .78 1.63l-9.9 10.2a.5.5 0 0 1-.86-.46l1.92-6.02A1 1 0 0 0 11 14z",key:"1xq2db"}]],Z1=e("zap",c1);export{n1 as A,d1 as B,p1 as C,_1 as E,u1 as F,w1 as H,$1 as K,x1 as L,N1 as M,g1 as P,b1 as R,j1 as S,B1 as T,R1 as U,W1 as W,T1 as X,Z1 as Z,S1 as a,O1 as b,A1 as c,z1 as d,V1 as e,H1 as f,E1 as g,v1 as h,f1 as i,C1 as j,P1 as k,y1 as l,L1 as m,k1 as n,M1 as o,h1 as p,l1 as q,i1 as r,U1 as s,m1 as t,q1 as u,r1 as v};