@agent-analytics/cli 0.1.7 → 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
@@ -8,35 +8,40 @@ Web analytics your AI agent can read. Drop a JS snippet on your site, query the
8
8
  # 1. Get your API key from https://api.agentanalytics.sh (sign in with GitHub)
9
9
 
10
10
  # 2. Save your key
11
- npx agent-analytics login --token aak_your_key
11
+ npx @agent-analytics/cli login --token aak_your_key
12
12
 
13
13
  # 3. Create a project
14
- npx agent-analytics create my-site --domain https://mysite.com
14
+ npx @agent-analytics/cli create my-site --domain https://mysite.com
15
15
 
16
16
  # 4. Check your stats
17
- npx agent-analytics stats my-site
17
+ npx @agent-analytics/cli stats my-site
18
18
  ```
19
19
 
20
20
  ## Commands
21
21
 
22
22
  ```bash
23
23
  # Auth
24
- npx agent-analytics login --token <key> # Save your API key
25
- npx agent-analytics whoami # Show current account
24
+ npx @agent-analytics/cli login --token <key> # Save your API key
25
+ npx @agent-analytics/cli whoami # Show current account
26
26
 
27
27
  # Projects
28
- npx agent-analytics create <name> --domain <url> # Create a project
29
- npx agent-analytics projects # List your projects
30
- npx agent-analytics delete <id> # Delete a project
28
+ npx @agent-analytics/cli create <name> --domain <url> # Create a project
29
+ npx @agent-analytics/cli projects # List your projects
30
+ npx @agent-analytics/cli delete <id> # Delete a project
31
31
 
32
32
  # Analytics
33
- npx agent-analytics stats <name> # Stats (last 7 days)
34
- npx agent-analytics stats <name> --days 30 # Stats (last 30 days)
35
- npx agent-analytics events <name> # Recent events
36
- npx agent-analytics properties-received <name> # Property keys per event
33
+ npx @agent-analytics/cli stats <name> # Stats (last 7 days)
34
+ npx @agent-analytics/cli stats <name> --days 30 # Stats (last 30 days)
35
+ npx @agent-analytics/cli events <name> # Recent events
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
- npx agent-analytics revoke-key # Revoke and regenerate API key
44
+ npx @agent-analytics/cli revoke-key # Revoke and regenerate API key
40
45
  ```
41
46
 
42
47
  ## For AI Agents
package/bin/cli.mjs CHANGED
@@ -4,17 +4,22 @@
4
4
  * agent-analytics CLI
5
5
  *
6
6
  * Usage:
7
- * npx agent-analytics login --token <key> — Save your API key
8
- * npx agent-analytics create <name> — Create a project and get your snippet
9
- * npx agent-analytics projects — List your projects
10
- * npx agent-analytics stats <name> — Get stats for a project
11
- * npx agent-analytics events <name> — Get recent events
12
- * npx agent-analytics properties-received <name> — Show property keys per event
13
- * npx agent-analytics init <name> Alias for create
14
- * npx agent-analytics delete <id> Delete a project
15
- * npx agent-analytics revoke-key Revoke and regenerate API key
16
- * npx agent-analytics delete-account — Delete your account (opens dashboard)
17
- * npx agent-analytics whoami Show current account
7
+ * npx @agent-analytics/cli login --token <key> — Save your API key
8
+ * npx @agent-analytics/cli create <name> — Create a project and get your snippet
9
+ * npx @agent-analytics/cli projects — List your projects
10
+ * npx @agent-analytics/cli stats <name> — Get stats for a project
11
+ * npx @agent-analytics/cli events <name> — Get recent events
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
18
+ * npx @agent-analytics/cli init <name> — Alias for create
19
+ * npx @agent-analytics/cli delete <id> — Delete a project
20
+ * npx @agent-analytics/cli revoke-key — Revoke and regenerate API key
21
+ * npx @agent-analytics/cli delete-account — Delete your account (opens dashboard)
22
+ * npx @agent-analytics/cli whoami — Show current account
18
23
  */
19
24
 
20
25
  import { AgentAnalyticsAPI } from '../lib/api.mjs';
@@ -37,7 +42,7 @@ function heading(msg) { log(`\n${BOLD}${msg}${RESET}`); }
37
42
  function requireKey() {
38
43
  const key = getApiKey();
39
44
  if (!key) {
40
- error('Not logged in. Run: npx agent-analytics login');
45
+ error('Not logged in. Run: npx @agent-analytics/cli login');
41
46
  }
42
47
  return new AgentAnalyticsAPI(key, getBaseUrl());
43
48
  }
@@ -49,7 +54,7 @@ async function cmdLogin(token) {
49
54
  heading('Agent Analytics — Login');
50
55
  log('');
51
56
  log('Pass your API key from the dashboard:');
52
- log(` ${CYAN}npx agent-analytics login --token aak_your_key_here${RESET}`);
57
+ log(` ${CYAN}npx @agent-analytics/cli login --token aak_your_key_here${RESET}`);
53
58
  log('');
54
59
  log('Or set it as an environment variable:');
55
60
  log(` ${CYAN}export AGENT_ANALYTICS_API_KEY=aak_your_key_here${RESET}`);
@@ -71,15 +76,15 @@ async function cmdLogin(token) {
71
76
 
72
77
  success(`Logged in as ${BOLD}${account.github_login || account.email}${RESET}`);
73
78
  log(`${DIM}API key saved to ~/.config/agent-analytics/config.json${RESET}`);
74
- log(`\nNext: ${CYAN}npx agent-analytics create my-site${RESET}`);
79
+ log(`\nNext: ${CYAN}npx @agent-analytics/cli create my-site${RESET}`);
75
80
  } catch (err) {
76
81
  error(`Invalid API key: ${err.message}`);
77
82
  }
78
83
  }
79
84
 
80
85
  async function cmdCreate(name, domain) {
81
- if (!name) error('Usage: npx agent-analytics create <project-name> --domain https://mysite.com');
82
- if (!domain) error('Usage: npx agent-analytics create <project-name> --domain https://mysite.com\n\nThe domain is required so we can restrict tracking to your site.');
86
+ if (!name) error('Usage: npx @agent-analytics/cli create <project-name> --domain https://mysite.com');
87
+ if (!domain) error('Usage: npx @agent-analytics/cli create <project-name> --domain https://mysite.com\n\nThe domain is required so we can restrict tracking to your site.');
83
88
 
84
89
  const api = requireKey();
85
90
 
@@ -115,7 +120,7 @@ async function cmdProjects() {
115
120
 
116
121
  if (!projects || projects.length === 0) {
117
122
  log('No projects yet. Create one:');
118
- log(` ${CYAN}npx agent-analytics create my-site${RESET}`);
123
+ log(` ${CYAN}npx @agent-analytics/cli create my-site${RESET}`);
119
124
  return;
120
125
  }
121
126
 
@@ -135,7 +140,7 @@ async function cmdProjects() {
135
140
  }
136
141
 
137
142
  async function cmdStats(project, days = 7) {
138
- if (!project) error('Usage: npx agent-analytics stats <project-name> [--days N]');
143
+ if (!project) error('Usage: npx @agent-analytics/cli stats <project-name> [--days N]');
139
144
 
140
145
  const api = requireKey();
141
146
 
@@ -192,7 +197,7 @@ async function cmdStats(project, days = 7) {
192
197
  }
193
198
 
194
199
  async function cmdEvents(project, opts = {}) {
195
- if (!project) error('Usage: npx agent-analytics events <project-name> [--days N] [--limit N]');
200
+ if (!project) error('Usage: npx @agent-analytics/cli events <project-name> [--days N] [--limit N]');
196
201
 
197
202
  const api = requireKey();
198
203
 
@@ -221,7 +226,7 @@ async function cmdEvents(project, opts = {}) {
221
226
  }
222
227
 
223
228
  async function cmdPropertiesReceived(project, opts = {}) {
224
- if (!project) error('Usage: npx agent-analytics properties-received <project-name> [--since DATE] [--sample N]');
229
+ if (!project) error('Usage: npx @agent-analytics/cli properties-received <project-name> [--since DATE] [--sample N]');
225
230
 
226
231
  const api = requireKey();
227
232
 
@@ -257,8 +262,153 @@ 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
- if (!id) error('Usage: npx agent-analytics delete <project-id>');
411
+ if (!id) error('Usage: npx @agent-analytics/cli delete <project-id>');
262
412
 
263
413
  const api = requireKey();
264
414
 
@@ -320,7 +470,7 @@ function showHelp() {
320
470
  ${BOLD}agent-analytics${RESET} — Web analytics your AI agent can read
321
471
 
322
472
  ${BOLD}USAGE${RESET}
323
- npx agent-analytics <command> [options]
473
+ npx @agent-analytics/cli <command> [options]
324
474
 
325
475
  ${BOLD}COMMANDS${RESET}
326
476
  ${CYAN}login${RESET} --token <key> Save your API key
@@ -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)
@@ -348,13 +507,13 @@ ${BOLD}ENVIRONMENT${RESET}
348
507
 
349
508
  ${BOLD}EXAMPLES${RESET}
350
509
  ${DIM}# First time: save your API key (from app.agentanalytics.sh)${RESET}
351
- npx agent-analytics login --token aak_your_key
510
+ npx @agent-analytics/cli login --token aak_your_key
352
511
 
353
512
  ${DIM}# Create a project${RESET}
354
- npx agent-analytics create my-site --domain https://mysite.com
513
+ npx @agent-analytics/cli create my-site --domain https://mysite.com
355
514
 
356
515
  ${DIM}# Check how your site is doing${RESET}
357
- npx agent-analytics stats my-site --days 30
516
+ npx @agent-analytics/cli stats my-site --days 30
358
517
 
359
518
  ${DIM}# Your agent can also use the API directly${RESET}
360
519
  curl "https://api.agentanalytics.sh/stats?project=my-site&days=7" \\
@@ -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;
@@ -421,7 +600,7 @@ try {
421
600
  showHelp();
422
601
  break;
423
602
  default:
424
- error(`Unknown command: ${command}. Run: npx agent-analytics help`);
603
+ error(`Unknown command: ${command}. Run: npx @agent-analytics/cli help`);
425
604
  }
426
605
  } catch (err) {
427
606
  error(err.message);
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.7",
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"