@agent-analytics/cli 0.1.7

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/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Agent Analytics
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,80 @@
1
+ # agent-analytics
2
+
3
+ Web analytics your AI agent can read. Drop a JS snippet on your site, query the data via API.
4
+
5
+ ## Quick Start
6
+
7
+ ```bash
8
+ # 1. Get your API key from https://api.agentanalytics.sh (sign in with GitHub)
9
+
10
+ # 2. Save your key
11
+ npx agent-analytics login --token aak_your_key
12
+
13
+ # 3. Create a project
14
+ npx agent-analytics create my-site --domain https://mysite.com
15
+
16
+ # 4. Check your stats
17
+ npx agent-analytics stats my-site
18
+ ```
19
+
20
+ ## Commands
21
+
22
+ ```bash
23
+ # Auth
24
+ npx agent-analytics login --token <key> # Save your API key
25
+ npx agent-analytics whoami # Show current account
26
+
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
31
+
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
37
+
38
+ # Security
39
+ npx agent-analytics revoke-key # Revoke and regenerate API key
40
+ ```
41
+
42
+ ## For AI Agents
43
+
44
+ Set the env var and call the API directly — no CLI needed:
45
+
46
+ ```bash
47
+ export AGENT_ANALYTICS_API_KEY=aak_your_key
48
+
49
+ # Query stats
50
+ curl "https://api.agentanalytics.sh/stats?project=my-site&days=7" \
51
+ -H "X-API-Key: $AGENT_ANALYTICS_API_KEY"
52
+
53
+ # Create a project
54
+ curl -X POST "https://api.agentanalytics.sh/projects" \
55
+ -H "X-API-Key: $AGENT_ANALYTICS_API_KEY" \
56
+ -H "Content-Type: application/json" \
57
+ -d '{"name": "new-site", "allowed_origins": "https://mysite.com"}'
58
+ ```
59
+
60
+ ## Environment Variables
61
+
62
+ | Variable | Description |
63
+ |----------|-------------|
64
+ | `AGENT_ANALYTICS_API_KEY` | API key (overrides config file) |
65
+ | `AGENT_ANALYTICS_URL` | Custom API URL (for self-hosted) |
66
+
67
+ ## Config
68
+
69
+ Stored at `~/.config/agent-analytics/config.json` (file permissions: 600).
70
+
71
+ ## Links
72
+
73
+ - **Dashboard:** https://api.agentanalytics.sh
74
+ - **Website:** https://agentanalytics.sh
75
+ - **GitHub:** https://github.com/Agent-Analytics
76
+ - **Self-host:** https://github.com/Agent-Analytics/agent-analytics
77
+
78
+ ## License
79
+
80
+ MIT
package/bin/cli.mjs ADDED
@@ -0,0 +1,428 @@
1
+ #!/usr/bin/env node
2
+
3
+ /**
4
+ * agent-analytics CLI
5
+ *
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
18
+ */
19
+
20
+ import { AgentAnalyticsAPI } from '../lib/api.mjs';
21
+ import { getApiKey, setApiKey, getBaseUrl, getConfig, saveConfig } from '../lib/config.mjs';
22
+
23
+ const BOLD = '\x1b[1m';
24
+ const DIM = '\x1b[2m';
25
+ const GREEN = '\x1b[32m';
26
+ const YELLOW = '\x1b[33m';
27
+ const CYAN = '\x1b[36m';
28
+ const RED = '\x1b[31m';
29
+ const RESET = '\x1b[0m';
30
+
31
+ function log(msg = '') { console.log(msg); }
32
+ function success(msg) { log(`${GREEN}✓${RESET} ${msg}`); }
33
+ function warn(msg) { log(`${YELLOW}⚠${RESET} ${msg}`); }
34
+ function error(msg) { log(`${RED}✗${RESET} ${msg}`); process.exit(1); }
35
+ function heading(msg) { log(`\n${BOLD}${msg}${RESET}`); }
36
+
37
+ function requireKey() {
38
+ const key = getApiKey();
39
+ if (!key) {
40
+ error('Not logged in. Run: npx agent-analytics login');
41
+ }
42
+ return new AgentAnalyticsAPI(key, getBaseUrl());
43
+ }
44
+
45
+ // ==================== COMMANDS ====================
46
+
47
+ async function cmdLogin(token) {
48
+ if (!token) {
49
+ heading('Agent Analytics — Login');
50
+ log('');
51
+ log('Pass your API key from the dashboard:');
52
+ log(` ${CYAN}npx agent-analytics login --token aak_your_key_here${RESET}`);
53
+ log('');
54
+ log('Or set it as an environment variable:');
55
+ log(` ${CYAN}export AGENT_ANALYTICS_API_KEY=aak_your_key_here${RESET}`);
56
+ log('');
57
+ log(`Get your API key at: ${CYAN}https://app.agentanalytics.sh${RESET}`);
58
+ log(`${DIM}Sign in with GitHub → your API key is shown once on first signup.${RESET}`);
59
+ return;
60
+ }
61
+
62
+ // Validate the token works
63
+ const api = new AgentAnalyticsAPI(token, getBaseUrl());
64
+ try {
65
+ const account = await api.getAccount();
66
+ setApiKey(token);
67
+ const config = getConfig();
68
+ config.email = account.email;
69
+ config.github_login = account.github_login;
70
+ saveConfig(config);
71
+
72
+ success(`Logged in as ${BOLD}${account.github_login || account.email}${RESET}`);
73
+ log(`${DIM}API key saved to ~/.config/agent-analytics/config.json${RESET}`);
74
+ log(`\nNext: ${CYAN}npx agent-analytics create my-site${RESET}`);
75
+ } catch (err) {
76
+ error(`Invalid API key: ${err.message}`);
77
+ }
78
+ }
79
+
80
+ 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.');
83
+
84
+ const api = requireKey();
85
+
86
+ heading(`Creating project: ${name}`);
87
+
88
+ try {
89
+ const data = await api.createProject(name, domain);
90
+
91
+ success(data.existing
92
+ ? `Found existing project for ${BOLD}${domain}${RESET}!\n`
93
+ : `Project created for ${BOLD}${domain}${RESET}!\n`);
94
+
95
+ heading('1. Add this snippet to your site:');
96
+ log(`${CYAN}${data.snippet}${RESET}\n`);
97
+
98
+ heading('2. Your agent queries stats with:');
99
+ log(`${CYAN}${data.api_example}${RESET}\n`);
100
+
101
+ heading('Project token (for the snippet):');
102
+ log(`${YELLOW}${data.project_token}${RESET}\n`);
103
+
104
+ } catch (err) {
105
+ error(`Failed to create project: ${err.message}`);
106
+ }
107
+ }
108
+
109
+ async function cmdProjects() {
110
+ const api = requireKey();
111
+
112
+ try {
113
+ const data = await api.listProjects();
114
+ const projects = data.projects;
115
+
116
+ if (!projects || projects.length === 0) {
117
+ log('No projects yet. Create one:');
118
+ log(` ${CYAN}npx agent-analytics create my-site${RESET}`);
119
+ return;
120
+ }
121
+
122
+ heading(`Your Projects (${projects.length})`);
123
+ log('');
124
+
125
+ for (const p of projects) {
126
+ const created = new Date(p.created_at).toLocaleDateString();
127
+ log(` ${BOLD}${p.name}${RESET} ${DIM}created ${created}${RESET}`);
128
+ log(` ${DIM}token:${RESET} ${p.project_token}`);
129
+ log(` ${DIM}origins:${RESET} ${p.allowed_origins || '*'}`);
130
+ log('');
131
+ }
132
+ } catch (err) {
133
+ error(`Failed to list projects: ${err.message}`);
134
+ }
135
+ }
136
+
137
+ async function cmdStats(project, days = 7) {
138
+ if (!project) error('Usage: npx agent-analytics stats <project-name> [--days N]');
139
+
140
+ const api = requireKey();
141
+
142
+ try {
143
+ const result = await api.getStats(project, days, { returnHeaders: true });
144
+ const data = result.data;
145
+ const headers = result.headers;
146
+
147
+ heading(`Stats: ${project} (last ${days} days)`);
148
+ log('');
149
+
150
+ if (data.totals) {
151
+ log(` ${BOLD}Total events:${RESET} ${data.totals.total_events || 0}`);
152
+ log(` ${BOLD}Unique users:${RESET} ${data.totals.unique_users || 0}`);
153
+ }
154
+
155
+ if (data.events && data.events.length > 0) {
156
+ log('');
157
+ heading('Events:');
158
+ for (const e of data.events) {
159
+ log(` ${e.event} ${DIM}→${RESET} ${BOLD}${e.count}${RESET} ${DIM}(${e.unique_users} users)${RESET}`);
160
+ }
161
+ }
162
+
163
+ if (data.daily && data.daily.length > 0) {
164
+ log('');
165
+ heading('Daily:');
166
+ for (const d of data.daily) {
167
+ const bar = '█'.repeat(Math.min(Math.ceil(d.total_events / 5), 40));
168
+ log(` ${d.date} ${GREEN}${bar}${RESET} ${d.total_events} events`);
169
+ }
170
+ }
171
+
172
+ // Monthly usage summary from response headers
173
+ const monthlyUsage = headers['x-monthly-usage'];
174
+ if (monthlyUsage) {
175
+ const events = parseInt(monthlyUsage, 10);
176
+ const bill = (events / 1000) * 2;
177
+ const monthlyLimit = headers['x-monthly-limit'];
178
+ const pct = headers['x-monthly-usage-percent'];
179
+ log('');
180
+ if (monthlyLimit && pct) {
181
+ const capDollars = (parseInt(monthlyLimit, 10) / 1000) * 2;
182
+ log(` ${DIM}Monthly usage:${RESET} ${events.toLocaleString()} events ($${bill.toFixed(2)}) — ${pct}% of $${capDollars.toFixed(2)} cap`);
183
+ } else {
184
+ log(` ${DIM}Monthly usage:${RESET} ${events.toLocaleString()} events ($${bill.toFixed(2)})`);
185
+ }
186
+ }
187
+
188
+ log('');
189
+ } catch (err) {
190
+ error(`Failed to get stats: ${err.message}`);
191
+ }
192
+ }
193
+
194
+ async function cmdEvents(project, opts = {}) {
195
+ if (!project) error('Usage: npx agent-analytics events <project-name> [--days N] [--limit N]');
196
+
197
+ const api = requireKey();
198
+
199
+ try {
200
+ const data = await api.getEvents(project, opts);
201
+
202
+ heading(`Events: ${project}`);
203
+ log('');
204
+
205
+ if (!data.events || data.events.length === 0) {
206
+ log(' No events yet.');
207
+ return;
208
+ }
209
+
210
+ for (const e of data.events) {
211
+ const time = new Date(e.timestamp).toLocaleString();
212
+ log(` ${DIM}${time}${RESET} ${BOLD}${e.event}${RESET} ${DIM}${e.user_id || ''}${RESET}`);
213
+ if (e.properties) {
214
+ log(` ${DIM}${JSON.stringify(e.properties)}${RESET}`);
215
+ }
216
+ }
217
+ log('');
218
+ } catch (err) {
219
+ error(`Failed to get events: ${err.message}`);
220
+ }
221
+ }
222
+
223
+ async function cmdPropertiesReceived(project, opts = {}) {
224
+ if (!project) error('Usage: npx agent-analytics properties-received <project-name> [--since DATE] [--sample N]');
225
+
226
+ const api = requireKey();
227
+
228
+ try {
229
+ const data = await api.getPropertiesReceived(project, opts);
230
+
231
+ heading(`Received Properties: ${project}`);
232
+ log('');
233
+
234
+ if (!data.properties || data.properties.length === 0) {
235
+ log(' No properties found.');
236
+ return;
237
+ }
238
+
239
+ // Group by event for display
240
+ const byEvent = {};
241
+ for (const p of data.properties) {
242
+ if (!byEvent[p.event]) byEvent[p.event] = [];
243
+ byEvent[p.event].push(p.key);
244
+ }
245
+
246
+ for (const [event, keys] of Object.entries(byEvent)) {
247
+ log(` ${BOLD}${event}${RESET}`);
248
+ for (const key of keys) {
249
+ log(` ${CYAN}${key}${RESET}`);
250
+ }
251
+ }
252
+
253
+ log(`\n${DIM}Sampled from last ${data.sample_size} events${RESET}`);
254
+ log('');
255
+ } catch (err) {
256
+ error(`Failed to get properties: ${err.message}`);
257
+ }
258
+ }
259
+
260
+ async function cmdDelete(id) {
261
+ if (!id) error('Usage: npx agent-analytics delete <project-id>');
262
+
263
+ const api = requireKey();
264
+
265
+ try {
266
+ await api.deleteProject(id);
267
+ success(`Project ${id} deleted`);
268
+ } catch (err) {
269
+ error(`Failed to delete project: ${err.message}`);
270
+ }
271
+ }
272
+
273
+ function cmdDeleteAccount() {
274
+ heading('Delete Account');
275
+ log('');
276
+ log('For security, account deletion must be done from the dashboard.');
277
+ log(`Visit: ${CYAN}https://app.agentanalytics.sh/settings${RESET}`);
278
+ log('');
279
+ }
280
+
281
+ async function cmdRevokeKey() {
282
+ const api = requireKey();
283
+
284
+ try {
285
+ const data = await api.revokeKey();
286
+ setApiKey(data.api_key);
287
+
288
+ warn('Old API key revoked');
289
+ success('New API key generated and saved\n');
290
+ heading('New API key:');
291
+ log(`${YELLOW}${data.api_key}${RESET}`);
292
+ log(`${DIM}Saved to ~/.config/agent-analytics/config.json${RESET}\n`);
293
+ warn('Update your agent with this new key!');
294
+ } catch (err) {
295
+ error(`Failed to revoke key: ${err.message}`);
296
+ }
297
+ }
298
+
299
+ async function cmdWhoami() {
300
+ const api = requireKey();
301
+
302
+ try {
303
+ const data = await api.getAccount();
304
+ heading('Account');
305
+ log(` ${BOLD}Email:${RESET} ${data.email}`);
306
+ log(` ${BOLD}GitHub:${RESET} ${data.github_login || 'N/A'}`);
307
+ log(` ${BOLD}Tier:${RESET} ${data.tier}`);
308
+ log(` ${BOLD}Projects:${RESET} ${data.projects_count}/${data.projects_limit}`);
309
+ if (data.tier === 'pro' && data.monthly_spend_cap_dollars != null) {
310
+ log(` ${BOLD}Spend cap:${RESET} $${data.monthly_spend_cap_dollars.toFixed(2)}/month`);
311
+ }
312
+ log('');
313
+ } catch (err) {
314
+ error(`Failed to get account: ${err.message}`);
315
+ }
316
+ }
317
+
318
+ function showHelp() {
319
+ log(`
320
+ ${BOLD}agent-analytics${RESET} — Web analytics your AI agent can read
321
+
322
+ ${BOLD}USAGE${RESET}
323
+ npx agent-analytics <command> [options]
324
+
325
+ ${BOLD}COMMANDS${RESET}
326
+ ${CYAN}login${RESET} --token <key> Save your API key
327
+ ${CYAN}create${RESET} <name> Create a project and get your snippet
328
+ ${CYAN}projects${RESET} List your projects
329
+ ${CYAN}init${RESET} <name> Alias for create
330
+ ${CYAN}delete${RESET} <id> Delete a project
331
+ ${CYAN}stats${RESET} <name> Get stats for a project
332
+ ${CYAN}events${RESET} <name> Get recent events
333
+ ${CYAN}properties-received${RESET} <name> Show property keys per event
334
+ ${CYAN}whoami${RESET} Show current account
335
+ ${CYAN}revoke-key${RESET} Revoke and regenerate API key
336
+ ${CYAN}delete-account${RESET} Delete your account (opens dashboard)
337
+
338
+ ${BOLD}OPTIONS${RESET}
339
+ --days <N> Days of data (default: 7)
340
+ --limit <N> Max events to return (default: 100)
341
+ --domain <url> Your site domain (required for create)
342
+ --since <date> ISO date for properties-received (default: 7 days)
343
+ --sample <N> Max events to sample (default: 5000)
344
+
345
+ ${BOLD}ENVIRONMENT${RESET}
346
+ AGENT_ANALYTICS_API_KEY API key (overrides config file)
347
+ AGENT_ANALYTICS_URL Custom API URL
348
+
349
+ ${BOLD}EXAMPLES${RESET}
350
+ ${DIM}# First time: save your API key (from app.agentanalytics.sh)${RESET}
351
+ npx agent-analytics login --token aak_your_key
352
+
353
+ ${DIM}# Create a project${RESET}
354
+ npx agent-analytics create my-site --domain https://mysite.com
355
+
356
+ ${DIM}# Check how your site is doing${RESET}
357
+ npx agent-analytics stats my-site --days 30
358
+
359
+ ${DIM}# Your agent can also use the API directly${RESET}
360
+ curl "https://api.agentanalytics.sh/stats?project=my-site&days=7" \\
361
+ -H "X-API-Key: \$AGENT_ANALYTICS_API_KEY"
362
+
363
+ ${DIM}https://agentanalytics.sh${RESET}
364
+ `);
365
+ }
366
+
367
+ // ==================== MAIN ====================
368
+
369
+ const args = process.argv.slice(2);
370
+ const command = args[0];
371
+
372
+ function getArg(flag) {
373
+ const idx = args.indexOf(flag);
374
+ return idx > -1 && args[idx + 1] ? args[idx + 1] : null;
375
+ }
376
+
377
+ try {
378
+ switch (command) {
379
+ case 'login':
380
+ await cmdLogin(getArg('--token'));
381
+ break;
382
+ case 'create':
383
+ case 'init':
384
+ await cmdCreate(args[1], getArg('--domain'));
385
+ break;
386
+ case 'projects':
387
+ case 'list':
388
+ await cmdProjects();
389
+ break;
390
+ case 'stats':
391
+ await cmdStats(args[1], parseInt(getArg('--days') || '7'));
392
+ break;
393
+ case 'events':
394
+ await cmdEvents(args[1], {
395
+ days: parseInt(getArg('--days') || '7'),
396
+ limit: parseInt(getArg('--limit') || '100'),
397
+ });
398
+ break;
399
+ case 'properties-received':
400
+ await cmdPropertiesReceived(args[1], {
401
+ since: getArg('--since'),
402
+ sample: getArg('--sample') ? parseInt(getArg('--sample')) : undefined,
403
+ });
404
+ break;
405
+ case 'delete':
406
+ await cmdDelete(args[1]);
407
+ break;
408
+ case 'revoke-key':
409
+ await cmdRevokeKey();
410
+ break;
411
+ case 'delete-account':
412
+ cmdDeleteAccount();
413
+ break;
414
+ case 'whoami':
415
+ await cmdWhoami();
416
+ break;
417
+ case 'help':
418
+ case '--help':
419
+ case '-h':
420
+ case undefined:
421
+ showHelp();
422
+ break;
423
+ default:
424
+ error(`Unknown command: ${command}. Run: npx agent-analytics help`);
425
+ }
426
+ } catch (err) {
427
+ error(err.message);
428
+ }
package/lib/api.mjs ADDED
@@ -0,0 +1,90 @@
1
+ /**
2
+ * Agent Analytics API client.
3
+ * Zero dependencies — uses native fetch.
4
+ */
5
+
6
+ const BASE_URL = 'https://api.agentanalytics.sh';
7
+
8
+ export class AgentAnalyticsAPI {
9
+ constructor(apiKey, baseUrl = BASE_URL) {
10
+ this.apiKey = apiKey;
11
+ this.baseUrl = baseUrl;
12
+ }
13
+
14
+ async request(method, path, body, { returnHeaders = false } = {}) {
15
+ const opts = {
16
+ method,
17
+ headers: { 'Content-Type': 'application/json' },
18
+ };
19
+
20
+ if (this.apiKey) {
21
+ opts.headers['X-API-Key'] = this.apiKey;
22
+ }
23
+
24
+ if (body) {
25
+ opts.body = JSON.stringify(body);
26
+ }
27
+
28
+ const res = await fetch(`${this.baseUrl}${path}`, opts);
29
+ const data = await res.json();
30
+
31
+ if (!res.ok) {
32
+ throw new Error(data.error || `HTTP ${res.status}`);
33
+ }
34
+
35
+ if (returnHeaders) {
36
+ const headers = {};
37
+ res.headers.forEach((v, k) => { headers[k] = v; });
38
+ return { data, headers };
39
+ }
40
+
41
+ return data;
42
+ }
43
+
44
+ // Account
45
+ async getAccount() {
46
+ return this.request('GET', '/account');
47
+ }
48
+
49
+ async revokeKey() {
50
+ return this.request('POST', '/account/revoke-key');
51
+ }
52
+
53
+ // Projects
54
+ async createProject(name, allowedOrigins = '*') {
55
+ return this.request('POST', '/projects', {
56
+ name,
57
+ allowed_origins: allowedOrigins,
58
+ });
59
+ }
60
+
61
+ async listProjects() {
62
+ return this.request('GET', '/projects');
63
+ }
64
+
65
+ async deleteProject(id) {
66
+ return this.request('DELETE', `/projects/${id}`);
67
+ }
68
+
69
+ // Stats
70
+ async getStats(project, days = 7, { returnHeaders = false } = {}) {
71
+ return this.request('GET', `/stats?project=${encodeURIComponent(project)}&days=${days}`, undefined, { returnHeaders });
72
+ }
73
+
74
+ async getEvents(project, { event, days = 7, limit = 100 } = {}) {
75
+ let qs = `project=${encodeURIComponent(project)}&days=${days}&limit=${limit}`;
76
+ if (event) qs += `&event=${encodeURIComponent(event)}`;
77
+ return this.request('GET', `/events?${qs}`);
78
+ }
79
+
80
+ async getProperties(project, days = 30) {
81
+ return this.request('GET', `/properties?project=${encodeURIComponent(project)}&days=${days}`);
82
+ }
83
+
84
+ async getPropertiesReceived(project, { since, sample } = {}) {
85
+ let qs = `project=${encodeURIComponent(project)}`;
86
+ if (since) qs += `&since=${encodeURIComponent(since)}`;
87
+ if (sample) qs += `&sample=${sample}`;
88
+ return this.request('GET', `/properties/received?${qs}`);
89
+ }
90
+ }
package/lib/config.mjs ADDED
@@ -0,0 +1,40 @@
1
+ /**
2
+ * Config management — stores API key locally.
3
+ * ~/.config/agent-analytics/config.json
4
+ */
5
+
6
+ import { readFileSync, writeFileSync, mkdirSync } from 'node:fs';
7
+ import { join } from 'node:path';
8
+ import { homedir } from 'node:os';
9
+
10
+ const CONFIG_DIR = join(homedir(), '.config', 'agent-analytics');
11
+ const CONFIG_FILE = join(CONFIG_DIR, 'config.json');
12
+
13
+ export function getConfig() {
14
+ try {
15
+ return JSON.parse(readFileSync(CONFIG_FILE, 'utf8'));
16
+ } catch {
17
+ return {};
18
+ }
19
+ }
20
+
21
+ export function saveConfig(config) {
22
+ mkdirSync(CONFIG_DIR, { recursive: true });
23
+ writeFileSync(CONFIG_FILE, JSON.stringify(config, null, 2) + '\n', { mode: 0o600 });
24
+ }
25
+
26
+ export function getApiKey() {
27
+ const config = getConfig();
28
+ return process.env.AGENT_ANALYTICS_API_KEY || config.api_key || null;
29
+ }
30
+
31
+ export function setApiKey(key) {
32
+ const config = getConfig();
33
+ config.api_key = key;
34
+ saveConfig(config);
35
+ }
36
+
37
+ export function getBaseUrl() {
38
+ const config = getConfig();
39
+ return process.env.AGENT_ANALYTICS_URL || config.base_url || 'https://api.agentanalytics.sh';
40
+ }
package/package.json ADDED
@@ -0,0 +1,35 @@
1
+ {
2
+ "name": "@agent-analytics/cli",
3
+ "version": "0.1.7",
4
+ "description": "Web analytics your AI agent can read. CLI for managing projects and querying stats.",
5
+ "bin": {
6
+ "agent-analytics": "./bin/cli.mjs"
7
+ },
8
+ "type": "module",
9
+ "keywords": [
10
+ "analytics",
11
+ "ai",
12
+ "agent",
13
+ "cli",
14
+ "web-analytics"
15
+ ],
16
+ "author": "Agent Analytics <danny@animaapp.com>",
17
+ "license": "MIT",
18
+ "repository": {
19
+ "type": "git",
20
+ "url": "https://github.com/Agent-Analytics/agent-analytics-cli"
21
+ },
22
+ "homepage": "https://agentanalytics.sh",
23
+ "engines": {
24
+ "node": ">=18"
25
+ },
26
+ "files": [
27
+ "bin/",
28
+ "lib/",
29
+ "README.md",
30
+ "LICENSE"
31
+ ],
32
+ "scripts": {
33
+ "test": "node --test test/*.test.mjs"
34
+ }
35
+ }