faces-cli 1.6.5 → 1.6.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.
@@ -1,24 +1,12 @@
1
1
  import { BaseCommand } from '../../base.js';
2
- import { FacesAPIError } from '../../client.js';
3
2
  export default class BillingQuota extends BaseCommand {
4
- static description = 'Show compile token quota and per-face stats';
3
+ static description = 'Show compilation stats per face (deprecated — use compile:stats)';
5
4
  static flags = {
6
5
  ...BaseCommand.baseFlags,
7
6
  };
8
7
  async run() {
9
- const { flags } = await this.parse(BillingQuota);
10
- const client = this.makeClient(flags);
11
- let data;
12
- try {
13
- data = await client.get('/v1/billing/compile-quota');
14
- }
15
- catch (err) {
16
- if (err instanceof FacesAPIError)
17
- this.error(`Error (${err.statusCode}): ${err.message}`);
18
- throw err;
19
- }
20
- if (!this.jsonEnabled())
21
- this.printHuman(data);
22
- return data;
8
+ process.stderr.write('Note: billing:quota is deprecated. Use compile:stats instead.\n');
9
+ await this.config.runCommand('compile:stats', this.argv);
10
+ return {};
23
11
  }
24
12
  }
@@ -1,5 +1,5 @@
1
- import { BaseCommand } from '../../base.js';
2
- export default class BillingCheckout extends BaseCommand {
1
+ import { BaseCommand } from '../../../base.js';
2
+ export default class BillingSubscriptionActivate extends BaseCommand {
3
3
  static description: string;
4
4
  static flags: {
5
5
  plan: import("@oclif/core/interfaces").OptionFlag<string, import("@oclif/core/interfaces").CustomOptions>;
@@ -0,0 +1,75 @@
1
+ import { Flags } from '@oclif/core';
2
+ import { BaseCommand } from '../../../base.js';
3
+ import { FacesAPIError } from '../../../client.js';
4
+ export default class BillingSubscriptionActivate extends BaseCommand {
5
+ static description = 'Activate or reactivate a subscription plan';
6
+ static flags = {
7
+ ...BaseCommand.baseFlags,
8
+ plan: Flags.string({
9
+ description: 'Plan to activate',
10
+ options: ['connect'],
11
+ default: 'connect',
12
+ }),
13
+ };
14
+ async run() {
15
+ const { flags } = await this.parse(BillingSubscriptionActivate);
16
+ const client = this.makeClient(flags);
17
+ const json = this.jsonEnabled();
18
+ // Fetch current state
19
+ let sub;
20
+ try {
21
+ sub = await client.get('/v1/billing/subscription');
22
+ }
23
+ catch (err) {
24
+ if (err instanceof FacesAPIError)
25
+ this.error(`Error (${err.statusCode}): ${err.message}`);
26
+ throw err;
27
+ }
28
+ const plan = sub.plan;
29
+ const cancelAtPeriodEnd = sub.cancel_at_period_end;
30
+ // Already active Connect, not pending cancel
31
+ if (plan === 'connect' && !cancelAtPeriodEnd) {
32
+ if (!json)
33
+ this.log('Already on the Connect plan.');
34
+ return { status: 'already_active', plan: 'connect' };
35
+ }
36
+ // Pending cancel — reactivate instead of creating a new checkout
37
+ if (plan === 'connect' && cancelAtPeriodEnd) {
38
+ let data;
39
+ try {
40
+ data = await client.post('/v1/billing/subscription/reactivate');
41
+ }
42
+ catch (err) {
43
+ if (err instanceof FacesAPIError)
44
+ this.error(`Error (${err.statusCode}): ${err.message}`);
45
+ throw err;
46
+ }
47
+ const result = data;
48
+ if (!json) {
49
+ this.log(`Reactivated. Connect plan continues — next renewal: ${result.current_period_end ?? 'unknown'}.`);
50
+ }
51
+ return { status: 'reactivated', ...result };
52
+ }
53
+ // Free plan — create checkout
54
+ let data;
55
+ try {
56
+ data = await client.post(`/v1/billing/checkout?plan=${flags.plan}&source=cli`);
57
+ }
58
+ catch (err) {
59
+ if (err instanceof FacesAPIError)
60
+ this.error(`Error (${err.statusCode}): ${err.message}`);
61
+ throw err;
62
+ }
63
+ const result = data;
64
+ const url = result.checkout_url;
65
+ if (!json) {
66
+ this.log('Subscription Connect — $17/month');
67
+ this.log('');
68
+ this.log('Complete payment at this link:');
69
+ this.log(` ${url}`);
70
+ this.log('');
71
+ this.log('After payment, verify with: faces billing:subscription');
72
+ }
73
+ return { status: 'checkout_created', checkout_url: url };
74
+ }
75
+ }
@@ -0,0 +1,12 @@
1
+ import { BaseCommand } from '../../../base.js';
2
+ export default class BillingSubscriptionCancel extends BaseCommand {
3
+ static description: string;
4
+ static flags: {
5
+ yes: import("@oclif/core/interfaces").BooleanFlag<boolean>;
6
+ 'base-url': import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
7
+ token: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
8
+ 'api-key': import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
9
+ };
10
+ run(): Promise<unknown>;
11
+ private confirm;
12
+ }
@@ -0,0 +1,68 @@
1
+ import { Flags } from '@oclif/core';
2
+ import { createInterface } from 'node:readline';
3
+ import { BaseCommand } from '../../../base.js';
4
+ import { FacesAPIError } from '../../../client.js';
5
+ export default class BillingSubscriptionCancel extends BaseCommand {
6
+ static description = 'Cancel your subscription (keeps access until period end)';
7
+ static flags = {
8
+ ...BaseCommand.baseFlags,
9
+ yes: Flags.boolean({ description: 'Skip confirmation', default: false }),
10
+ };
11
+ async run() {
12
+ const { flags } = await this.parse(BillingSubscriptionCancel);
13
+ const client = this.makeClient(flags);
14
+ const json = this.jsonEnabled();
15
+ // Fetch current state
16
+ let sub;
17
+ try {
18
+ sub = await client.get('/v1/billing/subscription');
19
+ }
20
+ catch (err) {
21
+ if (err instanceof FacesAPIError)
22
+ this.error(`Error (${err.statusCode}): ${err.message}`);
23
+ throw err;
24
+ }
25
+ const plan = sub.plan;
26
+ if (plan === 'free') {
27
+ if (!json)
28
+ this.log('No active subscription to cancel (currently on pay-per-token plan).');
29
+ return { status: 'no_subscription' };
30
+ }
31
+ if (sub.cancel_at_period_end) {
32
+ if (!json)
33
+ this.log(`Already canceled. Connect access ends ${sub.current_period_end ?? 'at period end'}.`);
34
+ return { status: 'already_canceled', current_period_end: sub.current_period_end };
35
+ }
36
+ // Confirm
37
+ if (!flags.yes) {
38
+ const periodEnd = sub.current_period_end ?? 'period end';
39
+ const confirmed = await this.confirm(`Cancel Connect plan? You'll keep access until ${periodEnd}.`);
40
+ if (!confirmed)
41
+ this.error('Aborted.');
42
+ }
43
+ let data;
44
+ try {
45
+ data = await client.post('/v1/billing/subscription/cancel');
46
+ }
47
+ catch (err) {
48
+ if (err instanceof FacesAPIError)
49
+ this.error(`Error (${err.statusCode}): ${err.message}`);
50
+ throw err;
51
+ }
52
+ const result = data;
53
+ if (!json) {
54
+ this.log(`Canceled. Connect access continues until ${result.current_period_end ?? 'period end'}.`);
55
+ this.log('To reactivate before then: faces billing:subscription:activate');
56
+ }
57
+ return { status: 'canceled', ...result };
58
+ }
59
+ confirm(message) {
60
+ return new Promise((resolve) => {
61
+ const rl = createInterface({ input: process.stdin, output: process.stdout });
62
+ rl.question(`${message} [y/N] `, (answer) => {
63
+ rl.close();
64
+ resolve(answer.toLowerCase() === 'y');
65
+ });
66
+ });
67
+ }
68
+ }
@@ -0,0 +1,10 @@
1
+ import { BaseCommand } from '../../../base.js';
2
+ export default class BillingSubscription extends BaseCommand {
3
+ static description: string;
4
+ static flags: {
5
+ 'base-url': import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
6
+ token: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
7
+ 'api-key': import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
8
+ };
9
+ run(): Promise<unknown>;
10
+ }
@@ -0,0 +1,24 @@
1
+ import { BaseCommand } from '../../../base.js';
2
+ import { FacesAPIError } from '../../../client.js';
3
+ export default class BillingSubscription extends BaseCommand {
4
+ static description = 'Show current plan, face count, and renewal date';
5
+ static flags = {
6
+ ...BaseCommand.baseFlags,
7
+ };
8
+ async run() {
9
+ const { flags } = await this.parse(BillingSubscription);
10
+ const client = this.makeClient(flags);
11
+ let data;
12
+ try {
13
+ data = await client.get('/v1/billing/subscription');
14
+ }
15
+ catch (err) {
16
+ if (err instanceof FacesAPIError)
17
+ this.error(`Error (${err.statusCode}): ${err.message}`);
18
+ throw err;
19
+ }
20
+ if (!this.jsonEnabled())
21
+ this.printHuman(data);
22
+ return data;
23
+ }
24
+ }
@@ -0,0 +1,10 @@
1
+ import { BaseCommand } from '../../base.js';
2
+ export default class CompileStats extends BaseCommand {
3
+ static description: string;
4
+ static flags: {
5
+ 'base-url': import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
6
+ token: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
7
+ 'api-key': import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
8
+ };
9
+ run(): Promise<unknown>;
10
+ }
@@ -0,0 +1,34 @@
1
+ import { BaseCommand } from '../../base.js';
2
+ import { FacesAPIError } from '../../client.js';
3
+ export default class CompileStats extends BaseCommand {
4
+ static description = 'Show compilation stats per face';
5
+ static flags = {
6
+ ...BaseCommand.baseFlags,
7
+ };
8
+ async run() {
9
+ const { flags } = await this.parse(CompileStats);
10
+ const client = this.makeClient(flags);
11
+ let data;
12
+ try {
13
+ data = await client.get('/v1/billing/compile-quota');
14
+ }
15
+ catch (err) {
16
+ if (err instanceof FacesAPIError)
17
+ this.error(`Error (${err.statusCode}): ${err.message}`);
18
+ throw err;
19
+ }
20
+ // Rename face_id → alias in the faces array
21
+ const resp = data;
22
+ if (Array.isArray(resp.faces)) {
23
+ for (const f of resp.faces) {
24
+ if (f.face_id !== undefined) {
25
+ f.alias = f.face_id;
26
+ delete f.face_id;
27
+ }
28
+ }
29
+ }
30
+ if (!this.jsonEnabled())
31
+ this.printHuman(data);
32
+ return data;
33
+ }
34
+ }
@@ -120,23 +120,10 @@
120
120
  "state.js"
121
121
  ]
122
122
  },
123
- "auth:connect": {
123
+ "billing:balance": {
124
124
  "aliases": [],
125
- "args": {
126
- "provider": {
127
- "description": "OAuth provider to connect",
128
- "name": "provider",
129
- "options": [
130
- "openai"
131
- ],
132
- "required": true
133
- }
134
- },
135
- "description": "Connect an OAuth provider account to Faces (e.g. ChatGPT Plus/Pro)",
136
- "examples": [
137
- "<%= config.bin %> auth connect openai",
138
- "<%= config.bin %> auth connect openai --manual"
139
- ],
125
+ "args": {},
126
+ "description": "Show credit balance and payment method status",
140
127
  "flags": {
141
128
  "json": {
142
129
  "description": "Format output as json.",
@@ -168,17 +155,11 @@
168
155
  "hasDynamicHelp": false,
169
156
  "multiple": false,
170
157
  "type": "option"
171
- },
172
- "manual": {
173
- "description": "Manual mode for headless environments: prints the authorize URL and prompts you to paste the callback URL after approving in any browser.",
174
- "name": "manual",
175
- "allowNo": false,
176
- "type": "boolean"
177
158
  }
178
159
  },
179
160
  "hasDynamicHelp": false,
180
161
  "hiddenAliases": [],
181
- "id": "auth:connect",
162
+ "id": "billing:balance",
182
163
  "pluginAlias": "faces-cli",
183
164
  "pluginName": "faces-cli",
184
165
  "pluginType": "core",
@@ -188,18 +169,14 @@
188
169
  "relativePath": [
189
170
  "dist",
190
171
  "commands",
191
- "auth",
192
- "connect.js"
172
+ "billing",
173
+ "balance.js"
193
174
  ]
194
175
  },
195
- "auth:connections": {
176
+ "billing:card-setup": {
196
177
  "aliases": [],
197
178
  "args": {},
198
- "description": "List connected OAuth provider accounts",
199
- "examples": [
200
- "<%= config.bin %> auth connections",
201
- "<%= config.bin %> auth connections --json"
202
- ],
179
+ "description": "Get a Stripe card setup URL to save a payment method",
203
180
  "flags": {
204
181
  "json": {
205
182
  "description": "Format output as json.",
@@ -235,7 +212,7 @@
235
212
  },
236
213
  "hasDynamicHelp": false,
237
214
  "hiddenAliases": [],
238
- "id": "auth:connections",
215
+ "id": "billing:card-setup",
239
216
  "pluginAlias": "faces-cli",
240
217
  "pluginName": "faces-cli",
241
218
  "pluginType": "core",
@@ -245,26 +222,14 @@
245
222
  "relativePath": [
246
223
  "dist",
247
224
  "commands",
248
- "auth",
249
- "connections.js"
225
+ "billing",
226
+ "card-setup.js"
250
227
  ]
251
228
  },
252
- "auth:disconnect": {
229
+ "billing:llm-costs": {
253
230
  "aliases": [],
254
- "args": {
255
- "provider": {
256
- "description": "OAuth provider to disconnect",
257
- "name": "provider",
258
- "options": [
259
- "openai"
260
- ],
261
- "required": true
262
- }
263
- },
264
- "description": "Disconnect a linked OAuth provider account",
265
- "examples": [
266
- "<%= config.bin %> auth disconnect openai"
267
- ],
231
+ "args": {},
232
+ "description": "List available LLMs and their per-token costs",
268
233
  "flags": {
269
234
  "json": {
270
235
  "description": "Format output as json.",
@@ -296,11 +261,18 @@
296
261
  "hasDynamicHelp": false,
297
262
  "multiple": false,
298
263
  "type": "option"
264
+ },
265
+ "provider": {
266
+ "description": "Filter by provider (e.g. openai, anthropic)",
267
+ "name": "provider",
268
+ "hasDynamicHelp": false,
269
+ "multiple": false,
270
+ "type": "option"
299
271
  }
300
272
  },
301
273
  "hasDynamicHelp": false,
302
274
  "hiddenAliases": [],
303
- "id": "auth:disconnect",
275
+ "id": "billing:llm-costs",
304
276
  "pluginAlias": "faces-cli",
305
277
  "pluginName": "faces-cli",
306
278
  "pluginType": "core",
@@ -310,14 +282,14 @@
310
282
  "relativePath": [
311
283
  "dist",
312
284
  "commands",
313
- "auth",
314
- "disconnect.js"
285
+ "billing",
286
+ "llm-costs.js"
315
287
  ]
316
288
  },
317
- "auth:login": {
289
+ "billing:quota": {
318
290
  "aliases": [],
319
291
  "args": {},
320
- "description": "Login and save JWT credentials",
292
+ "description": "Show compilation stats per face (deprecated — use compile:stats)",
321
293
  "flags": {
322
294
  "json": {
323
295
  "description": "Format output as json.",
@@ -349,27 +321,11 @@
349
321
  "hasDynamicHelp": false,
350
322
  "multiple": false,
351
323
  "type": "option"
352
- },
353
- "email": {
354
- "description": "Account email",
355
- "name": "email",
356
- "required": true,
357
- "hasDynamicHelp": false,
358
- "multiple": false,
359
- "type": "option"
360
- },
361
- "password": {
362
- "description": "Account password",
363
- "name": "password",
364
- "required": true,
365
- "hasDynamicHelp": false,
366
- "multiple": false,
367
- "type": "option"
368
324
  }
369
325
  },
370
326
  "hasDynamicHelp": false,
371
327
  "hiddenAliases": [],
372
- "id": "auth:login",
328
+ "id": "billing:quota",
373
329
  "pluginAlias": "faces-cli",
374
330
  "pluginName": "faces-cli",
375
331
  "pluginType": "core",
@@ -379,14 +335,14 @@
379
335
  "relativePath": [
380
336
  "dist",
381
337
  "commands",
382
- "auth",
383
- "login.js"
338
+ "billing",
339
+ "quota.js"
384
340
  ]
385
341
  },
386
- "auth:logout": {
342
+ "billing:subscription": {
387
343
  "aliases": [],
388
344
  "args": {},
389
- "description": "Clear saved credentials",
345
+ "description": "Show current plan, face count, and renewal date",
390
346
  "flags": {
391
347
  "json": {
392
348
  "description": "Format output as json.",
@@ -422,7 +378,7 @@
422
378
  },
423
379
  "hasDynamicHelp": false,
424
380
  "hiddenAliases": [],
425
- "id": "auth:logout",
381
+ "id": "billing:subscription",
426
382
  "pluginAlias": "faces-cli",
427
383
  "pluginName": "faces-cli",
428
384
  "pluginType": "core",
@@ -432,14 +388,14 @@
432
388
  "relativePath": [
433
389
  "dist",
434
390
  "commands",
435
- "auth",
436
- "logout.js"
391
+ "billing",
392
+ "subscription.js"
437
393
  ]
438
394
  },
439
- "auth:refresh": {
395
+ "billing:topup": {
440
396
  "aliases": [],
441
397
  "args": {},
442
- "description": "Exchange current JWT for a fresh one",
398
+ "description": "Top up credit balance using saved payment method",
443
399
  "flags": {
444
400
  "json": {
445
401
  "description": "Format output as json.",
@@ -471,11 +427,26 @@
471
427
  "hasDynamicHelp": false,
472
428
  "multiple": false,
473
429
  "type": "option"
430
+ },
431
+ "amount": {
432
+ "description": "Top-up amount in USD (min $1)",
433
+ "name": "amount",
434
+ "required": true,
435
+ "hasDynamicHelp": false,
436
+ "multiple": false,
437
+ "type": "option"
438
+ },
439
+ "payment-ref": {
440
+ "description": "Payment reference (admin/test path)",
441
+ "name": "payment-ref",
442
+ "hasDynamicHelp": false,
443
+ "multiple": false,
444
+ "type": "option"
474
445
  }
475
446
  },
476
447
  "hasDynamicHelp": false,
477
448
  "hiddenAliases": [],
478
- "id": "auth:refresh",
449
+ "id": "billing:topup",
479
450
  "pluginAlias": "faces-cli",
480
451
  "pluginName": "faces-cli",
481
452
  "pluginType": "core",
@@ -485,14 +456,14 @@
485
456
  "relativePath": [
486
457
  "dist",
487
458
  "commands",
488
- "auth",
489
- "refresh.js"
459
+ "billing",
460
+ "topup.js"
490
461
  ]
491
462
  },
492
- "auth:register": {
463
+ "billing:usage": {
493
464
  "aliases": [],
494
465
  "args": {},
495
- "description": "Create a new Faces account",
466
+ "description": "Aggregated usage analytics",
496
467
  "flags": {
497
468
  "json": {
498
469
  "description": "Format output as json.",
@@ -525,53 +496,37 @@
525
496
  "multiple": false,
526
497
  "type": "option"
527
498
  },
528
- "email": {
529
- "description": "Email address",
530
- "name": "email",
531
- "required": true,
532
- "hasDynamicHelp": false,
533
- "multiple": false,
534
- "type": "option"
535
- },
536
- "password": {
537
- "description": "Password",
538
- "name": "password",
539
- "required": true,
540
- "hasDynamicHelp": false,
541
- "multiple": false,
542
- "type": "option"
543
- },
544
- "username": {
545
- "description": "Username (lowercase, dashes, numbers)",
546
- "name": "username",
547
- "required": true,
499
+ "group-by": {
500
+ "description": "Group results",
501
+ "name": "group-by",
548
502
  "hasDynamicHelp": false,
549
503
  "multiple": false,
504
+ "options": [
505
+ "api_key",
506
+ "model",
507
+ "llm",
508
+ "date"
509
+ ],
550
510
  "type": "option"
551
511
  },
552
- "invite-key": {
553
- "description": "Invite key (if required)",
554
- "name": "invite-key",
512
+ "from": {
513
+ "description": "Start date (YYYY-MM-DD)",
514
+ "name": "from",
555
515
  "hasDynamicHelp": false,
556
516
  "multiple": false,
557
517
  "type": "option"
558
518
  },
559
- "plan": {
560
- "description": "Plan to subscribe to: \"free\" ($5 activation) or \"connect\" ($17/mo, no activation fee)",
561
- "name": "plan",
562
- "default": "free",
519
+ "to": {
520
+ "description": "End date (YYYY-MM-DD)",
521
+ "name": "to",
563
522
  "hasDynamicHelp": false,
564
523
  "multiple": false,
565
- "options": [
566
- "free",
567
- "connect"
568
- ],
569
524
  "type": "option"
570
525
  }
571
526
  },
572
527
  "hasDynamicHelp": false,
573
528
  "hiddenAliases": [],
574
- "id": "auth:register",
529
+ "id": "billing:usage",
575
530
  "pluginAlias": "faces-cli",
576
531
  "pluginName": "faces-cli",
577
532
  "pluginType": "core",
@@ -581,14 +536,27 @@
581
536
  "relativePath": [
582
537
  "dist",
583
538
  "commands",
584
- "auth",
585
- "register.js"
539
+ "billing",
540
+ "usage.js"
586
541
  ]
587
542
  },
588
- "auth:whoami": {
543
+ "auth:connect": {
589
544
  "aliases": [],
590
- "args": {},
591
- "description": "Print current user profile and auth diagnostic",
545
+ "args": {
546
+ "provider": {
547
+ "description": "OAuth provider to connect",
548
+ "name": "provider",
549
+ "options": [
550
+ "openai"
551
+ ],
552
+ "required": true
553
+ }
554
+ },
555
+ "description": "Connect an OAuth provider account to Faces (e.g. ChatGPT Plus/Pro)",
556
+ "examples": [
557
+ "<%= config.bin %> auth connect openai",
558
+ "<%= config.bin %> auth connect openai --manual"
559
+ ],
592
560
  "flags": {
593
561
  "json": {
594
562
  "description": "Format output as json.",
@@ -620,11 +588,17 @@
620
588
  "hasDynamicHelp": false,
621
589
  "multiple": false,
622
590
  "type": "option"
591
+ },
592
+ "manual": {
593
+ "description": "Manual mode for headless environments: prints the authorize URL and prompts you to paste the callback URL after approving in any browser.",
594
+ "name": "manual",
595
+ "allowNo": false,
596
+ "type": "boolean"
623
597
  }
624
598
  },
625
599
  "hasDynamicHelp": false,
626
600
  "hiddenAliases": [],
627
- "id": "auth:whoami",
601
+ "id": "auth:connect",
628
602
  "pluginAlias": "faces-cli",
629
603
  "pluginName": "faces-cli",
630
604
  "pluginType": "core",
@@ -635,13 +609,17 @@
635
609
  "dist",
636
610
  "commands",
637
611
  "auth",
638
- "whoami.js"
612
+ "connect.js"
639
613
  ]
640
614
  },
641
- "billing:balance": {
615
+ "auth:connections": {
642
616
  "aliases": [],
643
617
  "args": {},
644
- "description": "Show credit balance and payment method status",
618
+ "description": "List connected OAuth provider accounts",
619
+ "examples": [
620
+ "<%= config.bin %> auth connections",
621
+ "<%= config.bin %> auth connections --json"
622
+ ],
645
623
  "flags": {
646
624
  "json": {
647
625
  "description": "Format output as json.",
@@ -677,7 +655,7 @@
677
655
  },
678
656
  "hasDynamicHelp": false,
679
657
  "hiddenAliases": [],
680
- "id": "billing:balance",
658
+ "id": "auth:connections",
681
659
  "pluginAlias": "faces-cli",
682
660
  "pluginName": "faces-cli",
683
661
  "pluginType": "core",
@@ -687,14 +665,26 @@
687
665
  "relativePath": [
688
666
  "dist",
689
667
  "commands",
690
- "billing",
691
- "balance.js"
668
+ "auth",
669
+ "connections.js"
692
670
  ]
693
671
  },
694
- "billing:card-setup": {
672
+ "auth:disconnect": {
695
673
  "aliases": [],
696
- "args": {},
697
- "description": "Get a Stripe card setup URL to save a payment method",
674
+ "args": {
675
+ "provider": {
676
+ "description": "OAuth provider to disconnect",
677
+ "name": "provider",
678
+ "options": [
679
+ "openai"
680
+ ],
681
+ "required": true
682
+ }
683
+ },
684
+ "description": "Disconnect a linked OAuth provider account",
685
+ "examples": [
686
+ "<%= config.bin %> auth disconnect openai"
687
+ ],
698
688
  "flags": {
699
689
  "json": {
700
690
  "description": "Format output as json.",
@@ -730,7 +720,7 @@
730
720
  },
731
721
  "hasDynamicHelp": false,
732
722
  "hiddenAliases": [],
733
- "id": "billing:card-setup",
723
+ "id": "auth:disconnect",
734
724
  "pluginAlias": "faces-cli",
735
725
  "pluginName": "faces-cli",
736
726
  "pluginType": "core",
@@ -740,14 +730,14 @@
740
730
  "relativePath": [
741
731
  "dist",
742
732
  "commands",
743
- "billing",
744
- "card-setup.js"
733
+ "auth",
734
+ "disconnect.js"
745
735
  ]
746
736
  },
747
- "billing:checkout": {
737
+ "auth:login": {
748
738
  "aliases": [],
749
739
  "args": {},
750
- "description": "Get a Stripe checkout URL to upgrade your subscription plan",
740
+ "description": "Login and save JWT credentials",
751
741
  "flags": {
752
742
  "json": {
753
743
  "description": "Format output as json.",
@@ -780,73 +770,18 @@
780
770
  "multiple": false,
781
771
  "type": "option"
782
772
  },
783
- "plan": {
784
- "description": "Plan to subscribe to",
785
- "name": "plan",
786
- "default": "connect",
787
- "hasDynamicHelp": false,
788
- "multiple": false,
789
- "options": [
790
- "connect"
791
- ],
792
- "type": "option"
793
- }
794
- },
795
- "hasDynamicHelp": false,
796
- "hiddenAliases": [],
797
- "id": "billing:checkout",
798
- "pluginAlias": "faces-cli",
799
- "pluginName": "faces-cli",
800
- "pluginType": "core",
801
- "strict": true,
802
- "enableJsonFlag": true,
803
- "isESM": true,
804
- "relativePath": [
805
- "dist",
806
- "commands",
807
- "billing",
808
- "checkout.js"
809
- ]
810
- },
811
- "billing:llm-costs": {
812
- "aliases": [],
813
- "args": {},
814
- "description": "List available LLMs and their per-token costs",
815
- "flags": {
816
- "json": {
817
- "description": "Format output as json.",
818
- "helpGroup": "GLOBAL",
819
- "name": "json",
820
- "allowNo": false,
821
- "type": "boolean"
822
- },
823
- "base-url": {
824
- "description": "API base URL",
825
- "env": "FACES_BASE_URL",
826
- "name": "base-url",
827
- "hasDynamicHelp": false,
828
- "multiple": false,
829
- "type": "option"
830
- },
831
- "token": {
832
- "description": "JWT bearer token",
833
- "env": "FACES_TOKEN",
834
- "name": "token",
835
- "hasDynamicHelp": false,
836
- "multiple": false,
837
- "type": "option"
838
- },
839
- "api-key": {
840
- "description": "API key",
841
- "env": "FACES_API_KEY",
842
- "name": "api-key",
773
+ "email": {
774
+ "description": "Account email",
775
+ "name": "email",
776
+ "required": true,
843
777
  "hasDynamicHelp": false,
844
778
  "multiple": false,
845
779
  "type": "option"
846
780
  },
847
- "provider": {
848
- "description": "Filter by provider (e.g. openai, anthropic)",
849
- "name": "provider",
781
+ "password": {
782
+ "description": "Account password",
783
+ "name": "password",
784
+ "required": true,
850
785
  "hasDynamicHelp": false,
851
786
  "multiple": false,
852
787
  "type": "option"
@@ -854,7 +789,7 @@
854
789
  },
855
790
  "hasDynamicHelp": false,
856
791
  "hiddenAliases": [],
857
- "id": "billing:llm-costs",
792
+ "id": "auth:login",
858
793
  "pluginAlias": "faces-cli",
859
794
  "pluginName": "faces-cli",
860
795
  "pluginType": "core",
@@ -864,14 +799,14 @@
864
799
  "relativePath": [
865
800
  "dist",
866
801
  "commands",
867
- "billing",
868
- "llm-costs.js"
802
+ "auth",
803
+ "login.js"
869
804
  ]
870
805
  },
871
- "billing:quota": {
806
+ "auth:logout": {
872
807
  "aliases": [],
873
808
  "args": {},
874
- "description": "Show compile token quota and per-face stats",
809
+ "description": "Clear saved credentials",
875
810
  "flags": {
876
811
  "json": {
877
812
  "description": "Format output as json.",
@@ -907,7 +842,7 @@
907
842
  },
908
843
  "hasDynamicHelp": false,
909
844
  "hiddenAliases": [],
910
- "id": "billing:quota",
845
+ "id": "auth:logout",
911
846
  "pluginAlias": "faces-cli",
912
847
  "pluginName": "faces-cli",
913
848
  "pluginType": "core",
@@ -917,14 +852,14 @@
917
852
  "relativePath": [
918
853
  "dist",
919
854
  "commands",
920
- "billing",
921
- "quota.js"
855
+ "auth",
856
+ "logout.js"
922
857
  ]
923
858
  },
924
- "billing:subscription": {
859
+ "auth:refresh": {
925
860
  "aliases": [],
926
861
  "args": {},
927
- "description": "Show current plan, face count, and renewal date",
862
+ "description": "Exchange current JWT for a fresh one",
928
863
  "flags": {
929
864
  "json": {
930
865
  "description": "Format output as json.",
@@ -960,7 +895,7 @@
960
895
  },
961
896
  "hasDynamicHelp": false,
962
897
  "hiddenAliases": [],
963
- "id": "billing:subscription",
898
+ "id": "auth:refresh",
964
899
  "pluginAlias": "faces-cli",
965
900
  "pluginName": "faces-cli",
966
901
  "pluginType": "core",
@@ -970,14 +905,14 @@
970
905
  "relativePath": [
971
906
  "dist",
972
907
  "commands",
973
- "billing",
974
- "subscription.js"
908
+ "auth",
909
+ "refresh.js"
975
910
  ]
976
911
  },
977
- "billing:topup": {
912
+ "auth:register": {
978
913
  "aliases": [],
979
914
  "args": {},
980
- "description": "Top up credit balance using saved payment method",
915
+ "description": "Create a new Faces account",
981
916
  "flags": {
982
917
  "json": {
983
918
  "description": "Format output as json.",
@@ -1010,25 +945,53 @@
1010
945
  "multiple": false,
1011
946
  "type": "option"
1012
947
  },
1013
- "amount": {
1014
- "description": "Top-up amount in USD (min $1)",
1015
- "name": "amount",
948
+ "email": {
949
+ "description": "Email address",
950
+ "name": "email",
1016
951
  "required": true,
1017
952
  "hasDynamicHelp": false,
1018
953
  "multiple": false,
1019
954
  "type": "option"
1020
955
  },
1021
- "payment-ref": {
1022
- "description": "Payment reference (admin/test path)",
1023
- "name": "payment-ref",
956
+ "password": {
957
+ "description": "Password",
958
+ "name": "password",
959
+ "required": true,
960
+ "hasDynamicHelp": false,
961
+ "multiple": false,
962
+ "type": "option"
963
+ },
964
+ "username": {
965
+ "description": "Username (lowercase, dashes, numbers)",
966
+ "name": "username",
967
+ "required": true,
968
+ "hasDynamicHelp": false,
969
+ "multiple": false,
970
+ "type": "option"
971
+ },
972
+ "invite-key": {
973
+ "description": "Invite key (if required)",
974
+ "name": "invite-key",
975
+ "hasDynamicHelp": false,
976
+ "multiple": false,
977
+ "type": "option"
978
+ },
979
+ "plan": {
980
+ "description": "Plan to subscribe to: \"free\" ($5 activation) or \"connect\" ($17/mo, no activation fee)",
981
+ "name": "plan",
982
+ "default": "free",
1024
983
  "hasDynamicHelp": false,
1025
984
  "multiple": false,
985
+ "options": [
986
+ "free",
987
+ "connect"
988
+ ],
1026
989
  "type": "option"
1027
990
  }
1028
991
  },
1029
992
  "hasDynamicHelp": false,
1030
993
  "hiddenAliases": [],
1031
- "id": "billing:topup",
994
+ "id": "auth:register",
1032
995
  "pluginAlias": "faces-cli",
1033
996
  "pluginName": "faces-cli",
1034
997
  "pluginType": "core",
@@ -1038,14 +1001,14 @@
1038
1001
  "relativePath": [
1039
1002
  "dist",
1040
1003
  "commands",
1041
- "billing",
1042
- "topup.js"
1004
+ "auth",
1005
+ "register.js"
1043
1006
  ]
1044
1007
  },
1045
- "billing:usage": {
1008
+ "auth:whoami": {
1046
1009
  "aliases": [],
1047
1010
  "args": {},
1048
- "description": "Aggregated usage analytics",
1011
+ "description": "Print current user profile and auth diagnostic",
1049
1012
  "flags": {
1050
1013
  "json": {
1051
1014
  "description": "Format output as json.",
@@ -1077,38 +1040,11 @@
1077
1040
  "hasDynamicHelp": false,
1078
1041
  "multiple": false,
1079
1042
  "type": "option"
1080
- },
1081
- "group-by": {
1082
- "description": "Group results",
1083
- "name": "group-by",
1084
- "hasDynamicHelp": false,
1085
- "multiple": false,
1086
- "options": [
1087
- "api_key",
1088
- "model",
1089
- "llm",
1090
- "date"
1091
- ],
1092
- "type": "option"
1093
- },
1094
- "from": {
1095
- "description": "Start date (YYYY-MM-DD)",
1096
- "name": "from",
1097
- "hasDynamicHelp": false,
1098
- "multiple": false,
1099
- "type": "option"
1100
- },
1101
- "to": {
1102
- "description": "End date (YYYY-MM-DD)",
1103
- "name": "to",
1104
- "hasDynamicHelp": false,
1105
- "multiple": false,
1106
- "type": "option"
1107
1043
  }
1108
1044
  },
1109
1045
  "hasDynamicHelp": false,
1110
1046
  "hiddenAliases": [],
1111
- "id": "billing:usage",
1047
+ "id": "auth:whoami",
1112
1048
  "pluginAlias": "faces-cli",
1113
1049
  "pluginName": "faces-cli",
1114
1050
  "pluginType": "core",
@@ -1118,8 +1054,8 @@
1118
1054
  "relativePath": [
1119
1055
  "dist",
1120
1056
  "commands",
1121
- "billing",
1122
- "usage.js"
1057
+ "auth",
1058
+ "whoami.js"
1123
1059
  ]
1124
1060
  },
1125
1061
  "catalog:backup": {
@@ -1905,6 +1841,59 @@
1905
1841
  "import.js"
1906
1842
  ]
1907
1843
  },
1844
+ "compile:stats": {
1845
+ "aliases": [],
1846
+ "args": {},
1847
+ "description": "Show compilation stats per face",
1848
+ "flags": {
1849
+ "json": {
1850
+ "description": "Format output as json.",
1851
+ "helpGroup": "GLOBAL",
1852
+ "name": "json",
1853
+ "allowNo": false,
1854
+ "type": "boolean"
1855
+ },
1856
+ "base-url": {
1857
+ "description": "API base URL",
1858
+ "env": "FACES_BASE_URL",
1859
+ "name": "base-url",
1860
+ "hasDynamicHelp": false,
1861
+ "multiple": false,
1862
+ "type": "option"
1863
+ },
1864
+ "token": {
1865
+ "description": "JWT bearer token",
1866
+ "env": "FACES_TOKEN",
1867
+ "name": "token",
1868
+ "hasDynamicHelp": false,
1869
+ "multiple": false,
1870
+ "type": "option"
1871
+ },
1872
+ "api-key": {
1873
+ "description": "API key",
1874
+ "env": "FACES_API_KEY",
1875
+ "name": "api-key",
1876
+ "hasDynamicHelp": false,
1877
+ "multiple": false,
1878
+ "type": "option"
1879
+ }
1880
+ },
1881
+ "hasDynamicHelp": false,
1882
+ "hiddenAliases": [],
1883
+ "id": "compile:stats",
1884
+ "pluginAlias": "faces-cli",
1885
+ "pluginName": "faces-cli",
1886
+ "pluginType": "core",
1887
+ "strict": true,
1888
+ "enableJsonFlag": true,
1889
+ "isESM": true,
1890
+ "relativePath": [
1891
+ "dist",
1892
+ "commands",
1893
+ "compile",
1894
+ "stats.js"
1895
+ ]
1896
+ },
1908
1897
  "compile:upload": {
1909
1898
  "aliases": [],
1910
1899
  "args": {
@@ -3863,6 +3852,131 @@
3863
3852
  "update.js"
3864
3853
  ]
3865
3854
  },
3855
+ "billing:subscription:activate": {
3856
+ "aliases": [],
3857
+ "args": {},
3858
+ "description": "Activate or reactivate a subscription plan",
3859
+ "flags": {
3860
+ "json": {
3861
+ "description": "Format output as json.",
3862
+ "helpGroup": "GLOBAL",
3863
+ "name": "json",
3864
+ "allowNo": false,
3865
+ "type": "boolean"
3866
+ },
3867
+ "base-url": {
3868
+ "description": "API base URL",
3869
+ "env": "FACES_BASE_URL",
3870
+ "name": "base-url",
3871
+ "hasDynamicHelp": false,
3872
+ "multiple": false,
3873
+ "type": "option"
3874
+ },
3875
+ "token": {
3876
+ "description": "JWT bearer token",
3877
+ "env": "FACES_TOKEN",
3878
+ "name": "token",
3879
+ "hasDynamicHelp": false,
3880
+ "multiple": false,
3881
+ "type": "option"
3882
+ },
3883
+ "api-key": {
3884
+ "description": "API key",
3885
+ "env": "FACES_API_KEY",
3886
+ "name": "api-key",
3887
+ "hasDynamicHelp": false,
3888
+ "multiple": false,
3889
+ "type": "option"
3890
+ },
3891
+ "plan": {
3892
+ "description": "Plan to activate",
3893
+ "name": "plan",
3894
+ "default": "connect",
3895
+ "hasDynamicHelp": false,
3896
+ "multiple": false,
3897
+ "options": [
3898
+ "connect"
3899
+ ],
3900
+ "type": "option"
3901
+ }
3902
+ },
3903
+ "hasDynamicHelp": false,
3904
+ "hiddenAliases": [],
3905
+ "id": "billing:subscription:activate",
3906
+ "pluginAlias": "faces-cli",
3907
+ "pluginName": "faces-cli",
3908
+ "pluginType": "core",
3909
+ "strict": true,
3910
+ "enableJsonFlag": true,
3911
+ "isESM": true,
3912
+ "relativePath": [
3913
+ "dist",
3914
+ "commands",
3915
+ "billing",
3916
+ "subscription",
3917
+ "activate.js"
3918
+ ]
3919
+ },
3920
+ "billing:subscription:cancel": {
3921
+ "aliases": [],
3922
+ "args": {},
3923
+ "description": "Cancel your subscription (keeps access until period end)",
3924
+ "flags": {
3925
+ "json": {
3926
+ "description": "Format output as json.",
3927
+ "helpGroup": "GLOBAL",
3928
+ "name": "json",
3929
+ "allowNo": false,
3930
+ "type": "boolean"
3931
+ },
3932
+ "base-url": {
3933
+ "description": "API base URL",
3934
+ "env": "FACES_BASE_URL",
3935
+ "name": "base-url",
3936
+ "hasDynamicHelp": false,
3937
+ "multiple": false,
3938
+ "type": "option"
3939
+ },
3940
+ "token": {
3941
+ "description": "JWT bearer token",
3942
+ "env": "FACES_TOKEN",
3943
+ "name": "token",
3944
+ "hasDynamicHelp": false,
3945
+ "multiple": false,
3946
+ "type": "option"
3947
+ },
3948
+ "api-key": {
3949
+ "description": "API key",
3950
+ "env": "FACES_API_KEY",
3951
+ "name": "api-key",
3952
+ "hasDynamicHelp": false,
3953
+ "multiple": false,
3954
+ "type": "option"
3955
+ },
3956
+ "yes": {
3957
+ "description": "Skip confirmation",
3958
+ "name": "yes",
3959
+ "allowNo": false,
3960
+ "type": "boolean"
3961
+ }
3962
+ },
3963
+ "hasDynamicHelp": false,
3964
+ "hiddenAliases": [],
3965
+ "id": "billing:subscription:cancel",
3966
+ "pluginAlias": "faces-cli",
3967
+ "pluginName": "faces-cli",
3968
+ "pluginType": "core",
3969
+ "strict": true,
3970
+ "enableJsonFlag": true,
3971
+ "isESM": true,
3972
+ "relativePath": [
3973
+ "dist",
3974
+ "commands",
3975
+ "billing",
3976
+ "subscription",
3977
+ "cancel.js"
3978
+ ]
3979
+ },
3866
3980
  "compile:doc:create": {
3867
3981
  "aliases": [],
3868
3982
  "args": {
@@ -5780,5 +5894,5 @@
5780
5894
  ]
5781
5895
  }
5782
5896
  },
5783
- "version": "1.6.5"
5897
+ "version": "1.6.7"
5784
5898
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "faces-cli",
3
- "version": "1.6.5",
3
+ "version": "1.6.7",
4
4
  "description": "CLI for the Faces AI platform",
5
5
  "type": "module",
6
6
  "author": "sybileak <sybileak@proton.me>",
@@ -1,30 +0,0 @@
1
- import { Flags } from '@oclif/core';
2
- import { BaseCommand } from '../../base.js';
3
- import { FacesAPIError } from '../../client.js';
4
- export default class BillingCheckout extends BaseCommand {
5
- static description = 'Get a Stripe checkout URL to upgrade your subscription plan';
6
- static flags = {
7
- ...BaseCommand.baseFlags,
8
- plan: Flags.string({
9
- description: 'Plan to subscribe to',
10
- options: ['connect'],
11
- default: 'connect',
12
- }),
13
- };
14
- async run() {
15
- const { flags } = await this.parse(BillingCheckout);
16
- const client = this.makeClient(flags);
17
- let data;
18
- try {
19
- data = await client.post(`/v1/billing/checkout?plan=${flags.plan}&source=cli`);
20
- }
21
- catch (err) {
22
- if (err instanceof FacesAPIError)
23
- this.error(`Error (${err.statusCode}): ${err.message}`);
24
- throw err;
25
- }
26
- if (!this.jsonEnabled())
27
- this.printHuman(data);
28
- return data;
29
- }
30
- }