@agent-analytics/cli 0.1.8 → 0.1.9

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
@@ -34,6 +34,11 @@ npx @agent-analytics/cli stats <name> # Stats (last 7 days)
34
34
  npx @agent-analytics/cli stats <name> --days 30 # Stats (last 30 days)
35
35
  npx @agent-analytics/cli events <name> # Recent events
36
36
  npx @agent-analytics/cli properties-received <name> # Property keys per event
37
+ npx @agent-analytics/cli insights <name> # Period-over-period comparison (--period 7d)
38
+ npx @agent-analytics/cli breakdown <name> --property path # Top values for a property
39
+ npx @agent-analytics/cli pages <name> # Landing page performance (--type entry|exit|both)
40
+ npx @agent-analytics/cli sessions-dist <name> # Session duration histogram
41
+ npx @agent-analytics/cli heatmap <name> # Peak hours & busiest days
37
42
 
38
43
  # Security
39
44
  npx @agent-analytics/cli revoke-key # Revoke and regenerate API key
package/bin/cli.mjs CHANGED
@@ -10,6 +10,11 @@
10
10
  * npx @agent-analytics/cli stats <name> — Get stats for a project
11
11
  * npx @agent-analytics/cli events <name> — Get recent events
12
12
  * npx @agent-analytics/cli properties-received <name> — Show property keys per event
13
+ * npx @agent-analytics/cli insights <name> — Period-over-period comparison
14
+ * npx @agent-analytics/cli breakdown <name> — Property value distribution
15
+ * npx @agent-analytics/cli pages <name> — Entry/exit page stats
16
+ * npx @agent-analytics/cli sessions-dist <name> — Session duration distribution
17
+ * npx @agent-analytics/cli heatmap <name> — Peak hours & busiest days
13
18
  * npx @agent-analytics/cli init <name> — Alias for create
14
19
  * npx @agent-analytics/cli delete <id> — Delete a project
15
20
  * npx @agent-analytics/cli revoke-key — Revoke and regenerate API key
@@ -257,6 +262,151 @@ async function cmdPropertiesReceived(project, opts = {}) {
257
262
  }
258
263
  }
259
264
 
265
+ async function cmdInsights(project, period = '7d') {
266
+ if (!project) error('Usage: npx @agent-analytics/cli insights <project-name> [--period 7d]');
267
+
268
+ const api = requireKey();
269
+
270
+ try {
271
+ const data = await api.getInsights(project, { period });
272
+
273
+ heading(`Insights: ${project} (${period} vs previous)`);
274
+ log('');
275
+
276
+ const m = data.metrics;
277
+ for (const [key, metric] of Object.entries(m)) {
278
+ const label = key.replace(/_/g, ' ');
279
+ const arrow = metric.change > 0 ? `${GREEN}↑` : metric.change < 0 ? `${RED}↓` : `${DIM}—`;
280
+ const pct = metric.change_pct !== null ? ` (${metric.change_pct > 0 ? '+' : ''}${metric.change_pct}%)` : '';
281
+ log(` ${BOLD}${label}:${RESET} ${metric.current} ${arrow}${pct}${RESET} ${DIM}was ${metric.previous}${RESET}`);
282
+ }
283
+
284
+ log('');
285
+ log(` ${BOLD}Trend:${RESET} ${data.trend}`);
286
+ log('');
287
+ } catch (err) {
288
+ error(`Failed to get insights: ${err.message}`);
289
+ }
290
+ }
291
+
292
+ async function cmdBreakdown(project, property, opts = {}) {
293
+ if (!project || !property) error('Usage: npx @agent-analytics/cli breakdown <project-name> --property <key> [--event page_view] [--limit 20]');
294
+
295
+ const api = requireKey();
296
+
297
+ try {
298
+ const data = await api.getBreakdown(project, { property, ...opts });
299
+
300
+ heading(`Breakdown: ${project} — ${property}${data.event ? ` (${data.event})` : ''}`);
301
+ log('');
302
+
303
+ if (!data.values || data.values.length === 0) {
304
+ log(' No data found.');
305
+ return;
306
+ }
307
+
308
+ for (const v of data.values) {
309
+ log(` ${BOLD}${v.value}${RESET} ${v.count} events ${DIM}(${v.unique_users} users)${RESET}`);
310
+ }
311
+ log(`\n${DIM}${data.total_with_property} of ${data.total_events} events have this property${RESET}`);
312
+ log('');
313
+ } catch (err) {
314
+ error(`Failed to get breakdown: ${err.message}`);
315
+ }
316
+ }
317
+
318
+ async function cmdPages(project, type = 'entry', opts = {}) {
319
+ if (!project) error('Usage: npx @agent-analytics/cli pages <project-name> [--type entry|exit|both] [--limit 20]');
320
+
321
+ const api = requireKey();
322
+
323
+ try {
324
+ const data = await api.getPages(project, { type, ...opts });
325
+
326
+ heading(`Pages: ${project} (${type})`);
327
+ log('');
328
+
329
+ const pages = data.entry_pages || data.exit_pages || [];
330
+ if (pages.length === 0) {
331
+ log(' No page data found.');
332
+ return;
333
+ }
334
+
335
+ for (const p of pages) {
336
+ const bounceStr = `${Math.round(p.bounce_rate * 100)}% bounce`;
337
+ const durStr = `${Math.round(p.avg_duration / 1000)}s avg`;
338
+ log(` ${BOLD}${p.page}${RESET} ${p.sessions} sessions ${DIM}${bounceStr} ${durStr} ${p.avg_events} events/session${RESET}`);
339
+ }
340
+
341
+ if (data.exit_pages && data.entry_pages) {
342
+ log('');
343
+ heading('Exit pages:');
344
+ for (const p of data.exit_pages) {
345
+ log(` ${BOLD}${p.page}${RESET} ${p.sessions} sessions`);
346
+ }
347
+ }
348
+ log('');
349
+ } catch (err) {
350
+ error(`Failed to get pages: ${err.message}`);
351
+ }
352
+ }
353
+
354
+ async function cmdSessionsDist(project) {
355
+ if (!project) error('Usage: npx @agent-analytics/cli sessions-dist <project-name>');
356
+
357
+ const api = requireKey();
358
+
359
+ try {
360
+ const data = await api.getSessionDistribution(project);
361
+
362
+ heading(`Session Distribution: ${project}`);
363
+ log('');
364
+
365
+ if (!data.distribution || data.distribution.length === 0) {
366
+ log(' No session data found.');
367
+ return;
368
+ }
369
+
370
+ for (const b of data.distribution) {
371
+ const bar = '█'.repeat(Math.min(Math.ceil(b.pct / 2), 40));
372
+ log(` ${b.bucket.padEnd(7)} ${GREEN}${bar}${RESET} ${b.sessions} (${b.pct}%)`);
373
+ }
374
+
375
+ log('');
376
+ log(` ${BOLD}Median:${RESET} ${data.median_bucket} ${BOLD}Engaged:${RESET} ${data.engaged_pct}% (sessions ≥30s)`);
377
+ log('');
378
+ } catch (err) {
379
+ error(`Failed to get session distribution: ${err.message}`);
380
+ }
381
+ }
382
+
383
+ async function cmdHeatmap(project) {
384
+ if (!project) error('Usage: npx @agent-analytics/cli heatmap <project-name>');
385
+
386
+ const api = requireKey();
387
+
388
+ try {
389
+ const data = await api.getHeatmap(project);
390
+
391
+ heading(`Heatmap: ${project}`);
392
+ log('');
393
+
394
+ if (!data.heatmap || data.heatmap.length === 0) {
395
+ log(' No heatmap data found.');
396
+ return;
397
+ }
398
+
399
+ if (data.peak) {
400
+ log(` ${BOLD}Peak:${RESET} ${data.peak.day_name} at ${data.peak.hour}:00 (${data.peak.events} events, ${data.peak.users} users)`);
401
+ }
402
+ log(` ${BOLD}Busiest day:${RESET} ${data.busiest_day}`);
403
+ log(` ${BOLD}Busiest hour:${RESET} ${data.busiest_hour}:00`);
404
+ log('');
405
+ } catch (err) {
406
+ error(`Failed to get heatmap: ${err.message}`);
407
+ }
408
+ }
409
+
260
410
  async function cmdDelete(id) {
261
411
  if (!id) error('Usage: npx @agent-analytics/cli delete <project-id>');
262
412
 
@@ -331,16 +481,25 @@ ${BOLD}COMMANDS${RESET}
331
481
  ${CYAN}stats${RESET} <name> Get stats for a project
332
482
  ${CYAN}events${RESET} <name> Get recent events
333
483
  ${CYAN}properties-received${RESET} <name> Show property keys per event
484
+ ${CYAN}insights${RESET} <name> Period-over-period comparison
485
+ ${CYAN}breakdown${RESET} <name> Property value distribution
486
+ ${CYAN}pages${RESET} <name> Entry/exit page performance
487
+ ${CYAN}sessions-dist${RESET} <name> Session duration distribution
488
+ ${CYAN}heatmap${RESET} <name> Peak hours & busiest days
334
489
  ${CYAN}whoami${RESET} Show current account
335
490
  ${CYAN}revoke-key${RESET} Revoke and regenerate API key
336
491
  ${CYAN}delete-account${RESET} Delete your account (opens dashboard)
337
492
 
338
493
  ${BOLD}OPTIONS${RESET}
339
494
  --days <N> Days of data (default: 7)
340
- --limit <N> Max events to return (default: 100)
495
+ --limit <N> Max events/rows to return (default: 100)
341
496
  --domain <url> Your site domain (required for create)
342
497
  --since <date> ISO date for properties-received (default: 7 days)
343
498
  --sample <N> Max events to sample (default: 5000)
499
+ --period <P> Period for insights: 1d, 7d, 14d, 30d, 90d (default: 7d)
500
+ --property <key> Property key for breakdown (required)
501
+ --event <name> Filter by event name (breakdown only)
502
+ --type <T> Page type: entry, exit, both (default: entry)
344
503
 
345
504
  ${BOLD}ENVIRONMENT${RESET}
346
505
  AGENT_ANALYTICS_API_KEY API key (overrides config file)
@@ -388,20 +547,40 @@ try {
388
547
  await cmdProjects();
389
548
  break;
390
549
  case 'stats':
391
- await cmdStats(args[1], parseInt(getArg('--days') || '7'));
550
+ await cmdStats(args[1], parseInt(getArg('--days') || '7', 10));
392
551
  break;
393
552
  case 'events':
394
553
  await cmdEvents(args[1], {
395
- days: parseInt(getArg('--days') || '7'),
396
- limit: parseInt(getArg('--limit') || '100'),
554
+ days: parseInt(getArg('--days') || '7', 10),
555
+ limit: parseInt(getArg('--limit') || '100', 10),
397
556
  });
398
557
  break;
399
558
  case 'properties-received':
400
559
  await cmdPropertiesReceived(args[1], {
401
560
  since: getArg('--since'),
402
- sample: getArg('--sample') ? parseInt(getArg('--sample')) : undefined,
561
+ sample: getArg('--sample') ? parseInt(getArg('--sample'), 10) : undefined,
403
562
  });
404
563
  break;
564
+ case 'insights':
565
+ await cmdInsights(args[1], getArg('--period') || '7d');
566
+ break;
567
+ case 'breakdown':
568
+ await cmdBreakdown(args[1], getArg('--property'), {
569
+ event: getArg('--event'),
570
+ limit: getArg('--limit') ? parseInt(getArg('--limit'), 10) : undefined,
571
+ });
572
+ break;
573
+ case 'pages':
574
+ await cmdPages(args[1], getArg('--type') || 'entry', {
575
+ limit: getArg('--limit') ? parseInt(getArg('--limit'), 10) : undefined,
576
+ });
577
+ break;
578
+ case 'sessions-dist':
579
+ await cmdSessionsDist(args[1]);
580
+ break;
581
+ case 'heatmap':
582
+ await cmdHeatmap(args[1]);
583
+ break;
405
584
  case 'delete':
406
585
  await cmdDelete(args[1]);
407
586
  break;
package/lib/api.mjs CHANGED
@@ -87,4 +87,36 @@ export class AgentAnalyticsAPI {
87
87
  if (sample) qs += `&sample=${sample}`;
88
88
  return this.request('GET', `/properties/received?${qs}`);
89
89
  }
90
+
91
+ // Analytics
92
+ async getBreakdown(project, { property, event, since, limit = 20 } = {}) {
93
+ let qs = `project=${encodeURIComponent(project)}&property=${encodeURIComponent(property)}`;
94
+ if (event) qs += `&event=${encodeURIComponent(event)}`;
95
+ if (since) qs += `&since=${encodeURIComponent(since)}`;
96
+ if (limit) qs += `&limit=${limit}`;
97
+ return this.request('GET', `/breakdown?${qs}`);
98
+ }
99
+
100
+ async getInsights(project, { period = '7d' } = {}) {
101
+ return this.request('GET', `/insights?project=${encodeURIComponent(project)}&period=${period}`);
102
+ }
103
+
104
+ async getPages(project, { type = 'entry', since, limit = 20 } = {}) {
105
+ let qs = `project=${encodeURIComponent(project)}&type=${type}`;
106
+ if (since) qs += `&since=${encodeURIComponent(since)}`;
107
+ if (limit) qs += `&limit=${limit}`;
108
+ return this.request('GET', `/pages?${qs}`);
109
+ }
110
+
111
+ async getSessionDistribution(project, { since } = {}) {
112
+ let qs = `project=${encodeURIComponent(project)}`;
113
+ if (since) qs += `&since=${encodeURIComponent(since)}`;
114
+ return this.request('GET', `/sessions/distribution?${qs}`);
115
+ }
116
+
117
+ async getHeatmap(project, { since } = {}) {
118
+ let qs = `project=${encodeURIComponent(project)}`;
119
+ if (since) qs += `&since=${encodeURIComponent(since)}`;
120
+ return this.request('GET', `/heatmap?${qs}`);
121
+ }
90
122
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@agent-analytics/cli",
3
- "version": "0.1.8",
3
+ "version": "0.1.9",
4
4
  "description": "Web analytics your AI agent can read. CLI for managing projects and querying stats.",
5
5
  "bin": {
6
6
  "agent-analytics": "./bin/cli.mjs"