osai-agent 4.2.28 → 4.2.30

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "osai-agent",
3
- "version": "4.2.28",
3
+ "version": "4.2.30",
4
4
  "type": "module",
5
5
  "description": "OS AI Agent - YOUR AI AGENT",
6
6
  "main": "src/index.js",
@@ -43,6 +43,7 @@ const adminFetch = async (serverArg, path, method = 'GET', body = null, pathPref
43
43
  return data;
44
44
  };
45
45
 
46
+ export { adminFetch };
46
47
  export const listUsers = async ({ server }) => {
47
48
  const data = await adminFetch(server, '/admin/users');
48
49
  const users = data.users || [];
@@ -31,6 +31,19 @@ export const run = async ({ server: serverOverride, noConfirm = false, osOverrid
31
31
  }
32
32
  }
33
33
 
34
+ if (!effectiveLocal && token && server) {
35
+ try {
36
+ const res = await fetch(`${server}/auth/check-status`, {
37
+ headers: { 'Authorization': `Bearer ${token}` }
38
+ });
39
+ const data = await res.json();
40
+ if (data.status === 'disabled') {
41
+ console.log(chalk.red(`\n ${data.error}\n`));
42
+ process.exit(1);
43
+ }
44
+ } catch {}
45
+ }
46
+
34
47
  const resumedMode = Object.values(MODES).includes(fromSession?.mode) ? fromSession.mode : null;
35
48
  const resumedOS = fromSession?.os;
36
49
  const userOS = osOverride || resumedOS || config.get('os') || detectDefaultOS();
@@ -0,0 +1,75 @@
1
+ import chalk from 'chalk';
2
+ import { adminFetch } from './admin.js';
3
+
4
+ export const usageStats = async ({ server, days, json }) => {
5
+ const daysVal = Math.min(Math.max(parseInt(days || '7', 10) || 7, 1), 365);
6
+ const qs = daysVal !== 7 ? `?days=${daysVal}` : '';
7
+ const data = await adminFetch(server, `/admin/usage-stats${qs}`, 'GET', null, '/auth');
8
+ const { summary, users } = data;
9
+
10
+ if (json) {
11
+ console.log(JSON.stringify(data, null, 2));
12
+ return;
13
+ }
14
+
15
+ console.log(chalk.hex('#4a9eff').bold(`\n Admin — Usage Stats (last ${summary.period_days} days)\n`));
16
+ console.log(` ${chalk.white('━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━')}`);
17
+
18
+ const activePct = summary.total_users > 0 ? Math.round(summary.active / summary.total_users * 100) : 0;
19
+ const proPct = summary.total_users > 0 ? Math.round(summary.pro / summary.total_users * 100) : 0;
20
+
21
+ console.log(
22
+ ` Users: ${chalk.white(summary.total_users)}` +
23
+ ` (${chalk.green(`${summary.active} active`)} ` +
24
+ `· ${chalk.red(`${summary.disabled} disabled`)})`
25
+ );
26
+ console.log(
27
+ ` Plans: ${chalk.white(summary.free)} free` +
28
+ ` · ${chalk.hex('#ff9e64')(`${summary.pro} pro`)}` +
29
+ ` (${chalk.gray(`${proPct}%`)} pro, ${chalk.gray(`+${summary.new_users} new`)})`
30
+ );
31
+ console.log(
32
+ ` Sessions: ${chalk.white(summary.total_sessions)}` +
33
+ ` | Commands: ${chalk.white(summary.total_commands.toLocaleString())}` +
34
+ ` | Pro keys claimed: ${chalk.white(summary.claimed_pro_keys)}`
35
+ );
36
+
37
+ console.log(` ${chalk.white('━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━')}\n`);
38
+
39
+ if (users.length === 0) {
40
+ console.log(chalk.yellow(' No users found.\n'));
41
+ return;
42
+ }
43
+
44
+ const header = ` ${chalk.dim('Email'.padEnd(36))}${chalk.dim('Plan'.padEnd(6))}${chalk.dim('Status'.padEnd(9))}${chalk.dim('Logs'.padEnd(6))}${chalk.dim('Cmd'.padEnd(8))}${chalk.dim('Last active')}`;
45
+ console.log(header);
46
+
47
+ for (const u of users) {
48
+ const planBadge = u.plan === 'pro' ? chalk.hex('#ff9e64')('pro') : chalk.gray('free');
49
+ const statusBadge = u.status === 'disabled' ? chalk.red('disabled') : chalk.green('active');
50
+ const lastActive = u.last_active
51
+ ? (() => {
52
+ const d = new Date(u.last_active);
53
+ const now = Date.now();
54
+ const diff = now - d.getTime();
55
+ if (diff < 60000) return 'just now';
56
+ if (diff < 3600000) return `${Math.floor(diff / 60000)}m ago`;
57
+ if (diff < 86400000) return `${Math.floor(diff / 3600000)}h ago`;
58
+ return d.toLocaleDateString();
59
+ })()
60
+ : chalk.gray('never');
61
+
62
+ const logsStr = u.total_logs > 0 ? chalk.white(u.total_logs) : chalk.gray('0');
63
+ const cmdStr = u.total_commands > 0 ? chalk.white(u.total_commands) : chalk.gray('0');
64
+
65
+ console.log(
66
+ ` ${chalk.white(u.email.padEnd(36))}` +
67
+ `${planBadge.padEnd(6)}` +
68
+ `${statusBadge.padEnd(9)}` +
69
+ `${logsStr.padEnd(6)}` +
70
+ `${cmdStr.padEnd(8)}` +
71
+ `${lastActive}`
72
+ );
73
+ }
74
+ console.log();
75
+ };
package/src/index.js CHANGED
@@ -27,6 +27,7 @@ import { stopSubagent } from './commands/stop-subagent.js';
27
27
  import { claimProKey } from './commands/pro.js';
28
28
  import { deleteAccount } from './commands/account.js';
29
29
  import { listUsers, disableUser, enableUser, generateProKeys } from './commands/admin.js';
30
+ import { usageStats } from './commands/usage.js';
30
31
  import minimist from 'minimist';
31
32
  import updateNotifier from 'update-notifier';
32
33
  import { createRequire } from 'module';
@@ -144,6 +145,15 @@ switch (cmd) {
144
145
  }
145
146
  break;
146
147
 
148
+ case 'usage':
149
+ if (args._[1] === 'stats') {
150
+ await usageStats({ server: args.server, days: args.days, json: args.json });
151
+ } else {
152
+ console.log('Usage: osai-agent usage stats [--days 7] [--json]');
153
+ process.exit(1);
154
+ }
155
+ break;
156
+
147
157
  case 'admin':
148
158
  if (args._[1] === 'users') {
149
159
  await listUsers({ server: args.server });
@@ -193,9 +203,10 @@ switch (cmd) {
193
203
  console.log(' skills Manage skills');
194
204
  console.log(' mcp Manage MCP servers');
195
205
  console.log(' stop-subagent Stop a running subagent');
196
- console.log(' pro Activate a pro access code');
197
- console.log(' account delete Permanently delete your account and all data');
198
- console.log();
206
+ console.log(' pro Activate a pro access code');
207
+ console.log(' usage stats Show admin usage statistics (--days 7, --json)');
208
+ console.log(' account delete Permanently delete your account and all data');
209
+ console.log();
199
210
  process.exit(cmd ? 1 : 0);
200
211
  }
201
212