faces-cli 1.0.0

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.
Files changed (94) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +50 -0
  3. package/bin/dev.js +5 -0
  4. package/bin/run.js +5 -0
  5. package/dist/base.d.ts +16 -0
  6. package/dist/base.js +53 -0
  7. package/dist/client.d.ts +36 -0
  8. package/dist/client.js +191 -0
  9. package/dist/commands/account/state.d.ts +10 -0
  10. package/dist/commands/account/state.js +24 -0
  11. package/dist/commands/auth/login.d.ts +12 -0
  12. package/dist/commands/auth/login.js +40 -0
  13. package/dist/commands/auth/logout.d.ts +10 -0
  14. package/dist/commands/auth/logout.js +14 -0
  15. package/dist/commands/auth/refresh.d.ts +10 -0
  16. package/dist/commands/auth/refresh.js +30 -0
  17. package/dist/commands/auth/register.d.ts +15 -0
  18. package/dist/commands/auth/register.js +45 -0
  19. package/dist/commands/auth/whoami.d.ts +10 -0
  20. package/dist/commands/auth/whoami.js +24 -0
  21. package/dist/commands/billing/balance.d.ts +10 -0
  22. package/dist/commands/billing/balance.js +24 -0
  23. package/dist/commands/billing/card-setup.d.ts +10 -0
  24. package/dist/commands/billing/card-setup.js +24 -0
  25. package/dist/commands/billing/checkout.d.ts +11 -0
  26. package/dist/commands/billing/checkout.js +30 -0
  27. package/dist/commands/billing/llm-costs.d.ts +11 -0
  28. package/dist/commands/billing/llm-costs.js +29 -0
  29. package/dist/commands/billing/quota.d.ts +10 -0
  30. package/dist/commands/billing/quota.js +24 -0
  31. package/dist/commands/billing/subscription.d.ts +10 -0
  32. package/dist/commands/billing/subscription.js +24 -0
  33. package/dist/commands/billing/topup.d.ts +12 -0
  34. package/dist/commands/billing/topup.js +33 -0
  35. package/dist/commands/billing/usage.d.ts +13 -0
  36. package/dist/commands/billing/usage.js +38 -0
  37. package/dist/commands/chat/chat.d.ts +20 -0
  38. package/dist/commands/chat/chat.js +81 -0
  39. package/dist/commands/chat/messages.d.ts +17 -0
  40. package/dist/commands/chat/messages.js +68 -0
  41. package/dist/commands/chat/responses.d.ts +16 -0
  42. package/dist/commands/chat/responses.js +67 -0
  43. package/dist/commands/compile/doc/create.d.ts +16 -0
  44. package/dist/commands/compile/doc/create.js +43 -0
  45. package/dist/commands/compile/doc/delete.d.ts +13 -0
  46. package/dist/commands/compile/doc/delete.js +28 -0
  47. package/dist/commands/compile/doc/get.d.ts +13 -0
  48. package/dist/commands/compile/doc/get.js +28 -0
  49. package/dist/commands/compile/doc/list.d.ts +13 -0
  50. package/dist/commands/compile/doc/list.js +28 -0
  51. package/dist/commands/compile/doc/prepare.d.ts +13 -0
  52. package/dist/commands/compile/doc/prepare.js +28 -0
  53. package/dist/commands/compile/doc/sync.d.ts +15 -0
  54. package/dist/commands/compile/doc/sync.js +44 -0
  55. package/dist/commands/compile/thread/create.d.ts +14 -0
  56. package/dist/commands/compile/thread/create.js +32 -0
  57. package/dist/commands/compile/thread/list.d.ts +13 -0
  58. package/dist/commands/compile/thread/list.js +28 -0
  59. package/dist/commands/compile/thread/message.d.ts +14 -0
  60. package/dist/commands/compile/thread/message.js +31 -0
  61. package/dist/commands/compile/thread/sync.d.ts +13 -0
  62. package/dist/commands/compile/thread/sync.js +28 -0
  63. package/dist/commands/config/clear.d.ts +12 -0
  64. package/dist/commands/config/clear.js +31 -0
  65. package/dist/commands/config/set.d.ts +14 -0
  66. package/dist/commands/config/set.js +19 -0
  67. package/dist/commands/config/show.d.ts +10 -0
  68. package/dist/commands/config/show.js +19 -0
  69. package/dist/commands/face/create.d.ts +15 -0
  70. package/dist/commands/face/create.js +42 -0
  71. package/dist/commands/face/delete.d.ts +15 -0
  72. package/dist/commands/face/delete.js +44 -0
  73. package/dist/commands/face/get.d.ts +13 -0
  74. package/dist/commands/face/get.js +28 -0
  75. package/dist/commands/face/list.d.ts +10 -0
  76. package/dist/commands/face/list.js +24 -0
  77. package/dist/commands/face/stats.d.ts +10 -0
  78. package/dist/commands/face/stats.js +24 -0
  79. package/dist/commands/face/update.d.ts +16 -0
  80. package/dist/commands/face/update.js +48 -0
  81. package/dist/commands/face/upload.d.ts +15 -0
  82. package/dist/commands/face/upload.js +43 -0
  83. package/dist/commands/keys/create.d.ts +15 -0
  84. package/dist/commands/keys/create.js +39 -0
  85. package/dist/commands/keys/list.d.ts +10 -0
  86. package/dist/commands/keys/list.js +24 -0
  87. package/dist/commands/keys/revoke.d.ts +15 -0
  88. package/dist/commands/keys/revoke.js +44 -0
  89. package/dist/commands/keys/update.d.ts +16 -0
  90. package/dist/commands/keys/update.js +40 -0
  91. package/dist/config.d.ts +16 -0
  92. package/dist/config.js +65 -0
  93. package/oclif.manifest.json +2719 -0
  94. package/package.json +55 -0
@@ -0,0 +1,24 @@
1
+ import { BaseCommand } from '../../base.js';
2
+ import { FacesAPIError } from '../../client.js';
3
+ export default class BillingBalance extends BaseCommand {
4
+ static description = 'Show credit balance and payment method status';
5
+ static flags = {
6
+ ...BaseCommand.baseFlags,
7
+ };
8
+ async run() {
9
+ const { flags } = await this.parse(BillingBalance);
10
+ const client = this.makeClient(flags);
11
+ let data;
12
+ try {
13
+ data = await client.get('/v1/billing/balance');
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 BillingCardSetup 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 BillingCardSetup extends BaseCommand {
4
+ static description = 'Get a Stripe card setup URL to save a payment method';
5
+ static flags = {
6
+ ...BaseCommand.baseFlags,
7
+ };
8
+ async run() {
9
+ const { flags } = await this.parse(BillingCardSetup);
10
+ const client = this.makeClient(flags);
11
+ let data;
12
+ try {
13
+ data = await client.post('/v1/billing/card-setup');
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,11 @@
1
+ import { BaseCommand } from '../../base.js';
2
+ export default class BillingCheckout extends BaseCommand {
3
+ static description: string;
4
+ static flags: {
5
+ plan: import("@oclif/core/interfaces").OptionFlag<string, import("@oclif/core/interfaces").CustomOptions>;
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
+ }
@@ -0,0 +1,30 @@
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 upgrade to',
10
+ options: ['standard', 'pro'],
11
+ required: true,
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}`);
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
+ }
@@ -0,0 +1,11 @@
1
+ import { BaseCommand } from '../../base.js';
2
+ export default class BillingLlmCosts extends BaseCommand {
3
+ static description: string;
4
+ static flags: {
5
+ provider: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
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
+ }
@@ -0,0 +1,29 @@
1
+ import { Flags } from '@oclif/core';
2
+ import { BaseCommand } from '../../base.js';
3
+ import { FacesAPIError } from '../../client.js';
4
+ export default class BillingLlmCosts extends BaseCommand {
5
+ static description = 'List available LLMs and their per-token costs';
6
+ static flags = {
7
+ ...BaseCommand.baseFlags,
8
+ provider: Flags.string({ description: 'Filter by provider (e.g. openai, anthropic)' }),
9
+ };
10
+ async run() {
11
+ const { flags } = await this.parse(BillingLlmCosts);
12
+ const client = this.makeClient(flags);
13
+ let data;
14
+ try {
15
+ data = await client.get('/v1/billing/llm-costs');
16
+ }
17
+ catch (err) {
18
+ if (err instanceof FacesAPIError)
19
+ this.error(`Error (${err.statusCode}): ${err.message}`);
20
+ throw err;
21
+ }
22
+ if (flags.provider && Array.isArray(data)) {
23
+ data = data.filter((row) => String(row.provider ?? '').toLowerCase() === flags.provider.toLowerCase());
24
+ }
25
+ if (!this.jsonEnabled())
26
+ this.printHuman(data);
27
+ return data;
28
+ }
29
+ }
@@ -0,0 +1,10 @@
1
+ import { BaseCommand } from '../../base.js';
2
+ export default class BillingQuota 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 BillingQuota extends BaseCommand {
4
+ static description = 'Show compile token quota and per-face stats';
5
+ static flags = {
6
+ ...BaseCommand.baseFlags,
7
+ };
8
+ 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;
23
+ }
24
+ }
@@ -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,12 @@
1
+ import { BaseCommand } from '../../base.js';
2
+ export default class BillingTopup extends BaseCommand {
3
+ static description: string;
4
+ static flags: {
5
+ amount: import("@oclif/core/interfaces").OptionFlag<string, import("@oclif/core/interfaces").CustomOptions>;
6
+ 'payment-ref': import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
7
+ 'base-url': import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
8
+ token: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
9
+ 'api-key': import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
10
+ };
11
+ run(): Promise<unknown>;
12
+ }
@@ -0,0 +1,33 @@
1
+ import { Flags } from '@oclif/core';
2
+ import { BaseCommand } from '../../base.js';
3
+ import { FacesAPIError } from '../../client.js';
4
+ export default class BillingTopup extends BaseCommand {
5
+ static description = 'Top up credit balance using saved payment method';
6
+ static flags = {
7
+ ...BaseCommand.baseFlags,
8
+ amount: Flags.string({ description: 'Top-up amount in USD (min $1)', required: true }),
9
+ 'payment-ref': Flags.string({ description: 'Payment reference (admin/test path)' }),
10
+ };
11
+ async run() {
12
+ const { flags } = await this.parse(BillingTopup);
13
+ const client = this.makeClient(flags);
14
+ const amount = Number.parseFloat(flags.amount);
15
+ if (Number.isNaN(amount) || amount < 1.0)
16
+ this.error('Minimum topup is $1.00 (--amount)');
17
+ const payload = { amount };
18
+ if (flags['payment-ref'])
19
+ payload.payment_ref = flags['payment-ref'];
20
+ let data;
21
+ try {
22
+ data = await client.post('/v1/billing/topup', { body: payload });
23
+ }
24
+ catch (err) {
25
+ if (err instanceof FacesAPIError)
26
+ this.error(`Error (${err.statusCode}): ${err.message}`);
27
+ throw err;
28
+ }
29
+ if (!this.jsonEnabled())
30
+ this.printHuman(data);
31
+ return data;
32
+ }
33
+ }
@@ -0,0 +1,13 @@
1
+ import { BaseCommand } from '../../base.js';
2
+ export default class BillingUsage extends BaseCommand {
3
+ static description: string;
4
+ static flags: {
5
+ 'group-by': import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
6
+ from: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
7
+ to: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
8
+ 'base-url': import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
9
+ token: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
10
+ 'api-key': import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
11
+ };
12
+ run(): Promise<unknown>;
13
+ }
@@ -0,0 +1,38 @@
1
+ import { Flags } from '@oclif/core';
2
+ import { BaseCommand } from '../../base.js';
3
+ import { FacesAPIError } from '../../client.js';
4
+ export default class BillingUsage extends BaseCommand {
5
+ static description = 'Aggregated usage analytics';
6
+ static flags = {
7
+ ...BaseCommand.baseFlags,
8
+ 'group-by': Flags.string({
9
+ description: 'Group results',
10
+ options: ['api_key', 'model', 'llm', 'date'],
11
+ }),
12
+ from: Flags.string({ description: 'Start date (YYYY-MM-DD)' }),
13
+ to: Flags.string({ description: 'End date (YYYY-MM-DD)' }),
14
+ };
15
+ async run() {
16
+ const { flags } = await this.parse(BillingUsage);
17
+ const client = this.makeClient(flags);
18
+ const params = {};
19
+ if (flags['group-by'])
20
+ params.group_by = flags['group-by'];
21
+ if (flags.from)
22
+ params.from = flags.from;
23
+ if (flags.to)
24
+ params.to = flags.to;
25
+ let data;
26
+ try {
27
+ data = await client.get('/v1/billing/usage', { params });
28
+ }
29
+ catch (err) {
30
+ if (err instanceof FacesAPIError)
31
+ this.error(`Error (${err.statusCode}): ${err.message}`);
32
+ throw err;
33
+ }
34
+ if (!this.jsonEnabled())
35
+ this.printHuman(data);
36
+ return data;
37
+ }
38
+ }
@@ -0,0 +1,20 @@
1
+ import { BaseCommand } from '../../base.js';
2
+ export default class ChatChat extends BaseCommand {
3
+ static description: string;
4
+ static flags: {
5
+ message: import("@oclif/core/interfaces").OptionFlag<string[] | undefined, import("@oclif/core/interfaces").CustomOptions>;
6
+ llm: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
7
+ system: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
8
+ stream: import("@oclif/core/interfaces").BooleanFlag<boolean>;
9
+ 'max-tokens': import("@oclif/core/interfaces").OptionFlag<number | undefined, import("@oclif/core/interfaces").CustomOptions>;
10
+ temperature: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
11
+ file: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
12
+ 'base-url': import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
13
+ token: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
14
+ 'api-key': import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
15
+ };
16
+ static args: {
17
+ face_username: import("@oclif/core/interfaces").Arg<string, Record<string, unknown>>;
18
+ };
19
+ run(): Promise<unknown>;
20
+ }
@@ -0,0 +1,81 @@
1
+ import { Args, Flags } from '@oclif/core';
2
+ import fs from 'node:fs';
3
+ import { BaseCommand } from '../../base.js';
4
+ import { FacesAPIError } from '../../client.js';
5
+ export default class ChatChat extends BaseCommand {
6
+ static description = 'OpenAI-compatible chat completion via a face';
7
+ static flags = {
8
+ ...BaseCommand.baseFlags,
9
+ message: Flags.string({ char: 'm', description: 'User message (repeatable)', multiple: true, required: false }),
10
+ llm: Flags.string({ description: 'LLM override (e.g. claude-sonnet-4-6)' }),
11
+ system: Flags.string({ description: 'System prompt override' }),
12
+ stream: Flags.boolean({ description: 'Stream the response', default: false }),
13
+ 'max-tokens': Flags.integer({ description: 'Max tokens' }),
14
+ temperature: Flags.string({ description: 'Temperature (0.0-2.0)' }),
15
+ file: Flags.string({ description: 'Read message from file' }),
16
+ };
17
+ static args = {
18
+ face_username: Args.string({ description: 'Face username', required: true }),
19
+ };
20
+ async run() {
21
+ const { args, flags } = await this.parse(ChatChat);
22
+ const client = this.makeClient(flags);
23
+ const messages = [];
24
+ if (flags.system)
25
+ messages.push({ role: 'system', content: flags.system });
26
+ if (flags.file) {
27
+ if (!fs.existsSync(flags.file))
28
+ this.error(`File not found: ${flags.file}`);
29
+ messages.push({ role: 'user', content: fs.readFileSync(flags.file, 'utf8') });
30
+ }
31
+ else if (flags.message && flags.message.length > 0) {
32
+ for (const m of flags.message)
33
+ messages.push({ role: 'user', content: m });
34
+ }
35
+ else {
36
+ this.error('Provide at least one --message/-m or --file');
37
+ }
38
+ const model = flags.llm ? `${args.face_username}@${flags.llm}` : args.face_username;
39
+ const payload = { model, messages, stream: flags.stream };
40
+ if (flags['max-tokens'])
41
+ payload.max_tokens = flags['max-tokens'];
42
+ if (flags.temperature !== undefined)
43
+ payload.temperature = Number.parseFloat(flags.temperature);
44
+ try {
45
+ if (flags.stream) {
46
+ for await (const line of client.stream('/v1/chat/completions', payload)) {
47
+ if (!line.startsWith('data: '))
48
+ continue;
49
+ const chunk = line.slice(6);
50
+ if (chunk.trim() === '[DONE]')
51
+ break;
52
+ try {
53
+ const parsed = JSON.parse(chunk);
54
+ const choices = parsed?.choices;
55
+ const delta = choices?.[0]?.delta?.content ?? '';
56
+ if (delta)
57
+ process.stdout.write(String(delta));
58
+ }
59
+ catch {
60
+ // ignore parse errors
61
+ }
62
+ }
63
+ process.stdout.write('\n');
64
+ return {};
65
+ }
66
+ const data = (await client.post('/v1/chat/completions', { body: payload }));
67
+ if (this.jsonEnabled())
68
+ return data;
69
+ const choices = data.choices;
70
+ const message = choices?.[0]?.message;
71
+ const content = message?.content ?? '';
72
+ this.log(String(content));
73
+ return data;
74
+ }
75
+ catch (err) {
76
+ if (err instanceof FacesAPIError)
77
+ this.error(`Error (${err.statusCode}): ${err.message}`);
78
+ throw err;
79
+ }
80
+ }
81
+ }
@@ -0,0 +1,17 @@
1
+ import { BaseCommand } from '../../base.js';
2
+ export default class ChatMessages extends BaseCommand {
3
+ static description: string;
4
+ static flags: {
5
+ message: import("@oclif/core/interfaces").OptionFlag<string[], import("@oclif/core/interfaces").CustomOptions>;
6
+ system: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
7
+ stream: import("@oclif/core/interfaces").BooleanFlag<boolean>;
8
+ 'max-tokens': import("@oclif/core/interfaces").OptionFlag<number, import("@oclif/core/interfaces").CustomOptions>;
9
+ 'base-url': import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
10
+ token: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
11
+ 'api-key': import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
12
+ };
13
+ static args: {
14
+ face_model: import("@oclif/core/interfaces").Arg<string, Record<string, unknown>>;
15
+ };
16
+ run(): Promise<unknown>;
17
+ }
@@ -0,0 +1,68 @@
1
+ import { Args, Flags } from '@oclif/core';
2
+ import { BaseCommand } from '../../base.js';
3
+ import { FacesAPIError } from '../../client.js';
4
+ export default class ChatMessages extends BaseCommand {
5
+ static description = 'Anthropic Messages API proxy via a face (e.g. face@claude-sonnet-4-6)';
6
+ static flags = {
7
+ ...BaseCommand.baseFlags,
8
+ message: Flags.string({ char: 'm', description: 'User message (repeatable)', multiple: true, required: true }),
9
+ system: Flags.string({ description: 'System prompt' }),
10
+ stream: Flags.boolean({ description: 'Stream the response', default: false }),
11
+ 'max-tokens': Flags.integer({ description: 'Max tokens', default: 1024 }),
12
+ };
13
+ static args = {
14
+ face_model: Args.string({ description: 'Face model (e.g. myface or myface@claude-sonnet-4-6)', required: true }),
15
+ };
16
+ async run() {
17
+ const { args, flags } = await this.parse(ChatMessages);
18
+ const client = this.makeClient(flags);
19
+ const msgs = flags.message.map((m) => ({ role: 'user', content: m }));
20
+ const payload = {
21
+ model: args.face_model,
22
+ messages: msgs,
23
+ max_tokens: flags['max-tokens'],
24
+ stream: flags.stream,
25
+ };
26
+ if (flags.system)
27
+ payload.system = flags.system;
28
+ try {
29
+ if (flags.stream) {
30
+ for await (const line of client.stream('/v1/messages', payload)) {
31
+ if (!line.startsWith('data: '))
32
+ continue;
33
+ const chunk = line.slice(6);
34
+ if (chunk.trim() === '[DONE]' || chunk.trim() === '')
35
+ continue;
36
+ try {
37
+ const obj = JSON.parse(chunk);
38
+ if (obj.type === 'content_block_delta') {
39
+ const delta = obj.delta?.text ?? '';
40
+ if (delta)
41
+ process.stdout.write(String(delta));
42
+ }
43
+ }
44
+ catch {
45
+ // ignore
46
+ }
47
+ }
48
+ process.stdout.write('\n');
49
+ return {};
50
+ }
51
+ const data = (await client.post('/v1/messages', { body: payload }));
52
+ if (this.jsonEnabled())
53
+ return data;
54
+ let content = '';
55
+ for (const block of data.content ?? []) {
56
+ if (block.type === 'text')
57
+ content += String(block.text ?? '');
58
+ }
59
+ this.log(content);
60
+ return data;
61
+ }
62
+ catch (err) {
63
+ if (err instanceof FacesAPIError)
64
+ this.error(`Error (${err.statusCode}): ${err.message}`);
65
+ throw err;
66
+ }
67
+ }
68
+ }
@@ -0,0 +1,16 @@
1
+ import { BaseCommand } from '../../base.js';
2
+ export default class ChatResponses extends BaseCommand {
3
+ static description: string;
4
+ static flags: {
5
+ message: import("@oclif/core/interfaces").OptionFlag<string, import("@oclif/core/interfaces").CustomOptions>;
6
+ instructions: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
7
+ stream: import("@oclif/core/interfaces").BooleanFlag<boolean>;
8
+ 'base-url': import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
9
+ token: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
10
+ 'api-key': import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
11
+ };
12
+ static args: {
13
+ face_model: import("@oclif/core/interfaces").Arg<string, Record<string, unknown>>;
14
+ };
15
+ run(): Promise<unknown>;
16
+ }
@@ -0,0 +1,67 @@
1
+ import { Args, Flags } from '@oclif/core';
2
+ import { BaseCommand } from '../../base.js';
3
+ import { FacesAPIError } from '../../client.js';
4
+ export default class ChatResponses extends BaseCommand {
5
+ static description = 'OpenAI Responses API proxy via a face';
6
+ static flags = {
7
+ ...BaseCommand.baseFlags,
8
+ message: Flags.string({ char: 'm', description: 'User input message', required: true }),
9
+ instructions: Flags.string({ description: 'System instructions' }),
10
+ stream: Flags.boolean({ description: 'Stream the response', default: false }),
11
+ };
12
+ static args = {
13
+ face_model: Args.string({ description: 'Face model (e.g. myface or myface@gpt-4o)', required: true }),
14
+ };
15
+ async run() {
16
+ const { args, flags } = await this.parse(ChatResponses);
17
+ const client = this.makeClient(flags);
18
+ const payload = {
19
+ model: args.face_model,
20
+ input: flags.message,
21
+ stream: flags.stream,
22
+ };
23
+ if (flags.instructions)
24
+ payload.instructions = flags.instructions;
25
+ try {
26
+ if (flags.stream) {
27
+ for await (const line of client.stream('/v1/responses', payload)) {
28
+ if (!line.startsWith('data: '))
29
+ continue;
30
+ const chunk = line.slice(6);
31
+ if (chunk.trim() === '[DONE]' || chunk.trim() === '')
32
+ continue;
33
+ try {
34
+ const obj = JSON.parse(chunk);
35
+ if (obj.type === 'response.output_text.delta') {
36
+ const delta = obj.delta ?? '';
37
+ if (delta)
38
+ process.stdout.write(String(delta));
39
+ }
40
+ }
41
+ catch {
42
+ // ignore
43
+ }
44
+ }
45
+ process.stdout.write('\n');
46
+ return {};
47
+ }
48
+ const data = (await client.post('/v1/responses', { body: payload }));
49
+ if (this.jsonEnabled())
50
+ return data;
51
+ let outputText = '';
52
+ for (const item of data.output ?? []) {
53
+ for (const block of item.content ?? []) {
54
+ if (block.type === 'output_text')
55
+ outputText += String(block.text ?? '');
56
+ }
57
+ }
58
+ this.log(outputText);
59
+ return data;
60
+ }
61
+ catch (err) {
62
+ if (err instanceof FacesAPIError)
63
+ this.error(`Error (${err.statusCode}): ${err.message}`);
64
+ throw err;
65
+ }
66
+ }
67
+ }
@@ -0,0 +1,16 @@
1
+ import { BaseCommand } from '../../../base.js';
2
+ export default class CompileDocCreate extends BaseCommand {
3
+ static description: string;
4
+ static flags: {
5
+ label: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
6
+ content: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
7
+ file: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
8
+ 'base-url': import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
9
+ token: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
10
+ 'api-key': import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
11
+ };
12
+ static args: {
13
+ face_id: import("@oclif/core/interfaces").Arg<string, Record<string, unknown>>;
14
+ };
15
+ run(): Promise<unknown>;
16
+ }