faces-cli 1.6.0 → 1.6.2

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 (51) hide show
  1. package/README.md +50 -17
  2. package/dist/client.d.ts +4 -0
  3. package/dist/client.js +16 -0
  4. package/dist/commands/auth/register.d.ts +0 -1
  5. package/dist/commands/auth/register.js +1 -3
  6. package/dist/commands/billing/checkout.js +1 -1
  7. package/dist/commands/catalog/backup.js +84 -19
  8. package/dist/commands/catalog/doctor.js +10 -4
  9. package/dist/commands/catalog/restore.js +64 -11
  10. package/dist/commands/face/create.d.ts +1 -0
  11. package/dist/commands/face/create.js +14 -1
  12. package/dist/commands/face/list.d.ts +1 -0
  13. package/dist/commands/face/list.js +11 -1
  14. package/dist/commands/face/tag/add.d.ts +14 -0
  15. package/dist/commands/face/tag/add.js +29 -0
  16. package/dist/commands/face/tag/list.d.ts +13 -0
  17. package/dist/commands/face/tag/list.js +35 -0
  18. package/dist/commands/face/tag/remove.d.ts +14 -0
  19. package/dist/commands/face/tag/remove.js +29 -0
  20. package/dist/commands/face/tag/set.d.ts +14 -0
  21. package/dist/commands/face/tag/set.js +29 -0
  22. package/dist/commands/face/update.d.ts +1 -0
  23. package/dist/commands/face/update.js +17 -6
  24. package/dist/commands/team/add.d.ts +14 -0
  25. package/dist/commands/team/add.js +51 -0
  26. package/dist/commands/team/create.d.ts +15 -0
  27. package/dist/commands/team/create.js +53 -0
  28. package/dist/commands/team/delete.d.ts +15 -0
  29. package/dist/commands/team/delete.js +44 -0
  30. package/dist/commands/team/get.d.ts +13 -0
  31. package/dist/commands/team/get.js +28 -0
  32. package/dist/commands/team/list.d.ts +10 -0
  33. package/dist/commands/team/list.js +49 -0
  34. package/dist/commands/team/members.d.ts +13 -0
  35. package/dist/commands/team/members.js +28 -0
  36. package/dist/commands/team/remove.d.ts +14 -0
  37. package/dist/commands/team/remove.js +42 -0
  38. package/dist/commands/team/tag/add.d.ts +14 -0
  39. package/dist/commands/team/tag/add.js +29 -0
  40. package/dist/commands/team/tag/list.d.ts +13 -0
  41. package/dist/commands/team/tag/list.js +35 -0
  42. package/dist/commands/team/tag/remove.d.ts +14 -0
  43. package/dist/commands/team/tag/remove.js +29 -0
  44. package/dist/commands/team/tag/set.d.ts +14 -0
  45. package/dist/commands/team/tag/set.js +29 -0
  46. package/dist/commands/team/update.d.ts +17 -0
  47. package/dist/commands/team/update.js +48 -0
  48. package/dist/team-catalog.d.ts +16 -0
  49. package/dist/team-catalog.js +99 -0
  50. package/oclif.manifest.json +1693 -614
  51. package/package.json +1 -1
@@ -0,0 +1,13 @@
1
+ import { BaseCommand } from '../../../base.js';
2
+ export default class FaceTagList 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
+ static args: {
10
+ alias: import("@oclif/core/interfaces").Arg<string, Record<string, unknown>>;
11
+ };
12
+ run(): Promise<unknown>;
13
+ }
@@ -0,0 +1,35 @@
1
+ import { Args } from '@oclif/core';
2
+ import { BaseCommand } from '../../../base.js';
3
+ import { FacesAPIError } from '../../../client.js';
4
+ export default class FaceTagList extends BaseCommand {
5
+ static description = 'List tags on a face';
6
+ static flags = {
7
+ ...BaseCommand.baseFlags,
8
+ };
9
+ static args = {
10
+ alias: Args.string({ description: 'Face alias', required: true }),
11
+ };
12
+ async run() {
13
+ const { args, flags } = await this.parse(FaceTagList);
14
+ const client = this.makeClient(flags);
15
+ let data;
16
+ try {
17
+ data = await client.get(`/v1/iam/${args.alias}/tags`);
18
+ }
19
+ catch (err) {
20
+ if (err instanceof FacesAPIError)
21
+ this.error(`Error (${err.statusCode}): ${err.message}`);
22
+ throw err;
23
+ }
24
+ if (!this.jsonEnabled()) {
25
+ const tags = data.tags ?? [];
26
+ if (tags.length === 0) {
27
+ this.log('(no tags)');
28
+ }
29
+ else {
30
+ this.log(tags.join(', '));
31
+ }
32
+ }
33
+ return data;
34
+ }
35
+ }
@@ -0,0 +1,14 @@
1
+ import { BaseCommand } from '../../../base.js';
2
+ export default class FaceTagRemove 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
+ static args: {
10
+ alias: import("@oclif/core/interfaces").Arg<string, Record<string, unknown>>;
11
+ tag: import("@oclif/core/interfaces").Arg<string, Record<string, unknown>>;
12
+ };
13
+ run(): Promise<unknown>;
14
+ }
@@ -0,0 +1,29 @@
1
+ import { Args } from '@oclif/core';
2
+ import { BaseCommand } from '../../../base.js';
3
+ import { FacesAPIError } from '../../../client.js';
4
+ export default class FaceTagRemove extends BaseCommand {
5
+ static description = 'Remove a tag from a face';
6
+ static flags = {
7
+ ...BaseCommand.baseFlags,
8
+ };
9
+ static args = {
10
+ alias: Args.string({ description: 'Face alias', required: true }),
11
+ tag: Args.string({ description: 'Tag to remove', required: true }),
12
+ };
13
+ async run() {
14
+ const { args, flags } = await this.parse(FaceTagRemove);
15
+ const client = this.makeClient(flags);
16
+ let data;
17
+ try {
18
+ data = await client.delete(`/v1/iam/${args.alias}/tags/${encodeURIComponent(args.tag)}`);
19
+ }
20
+ catch (err) {
21
+ if (err instanceof FacesAPIError)
22
+ this.error(`Error (${err.statusCode}): ${err.message}`);
23
+ throw err;
24
+ }
25
+ if (!this.jsonEnabled())
26
+ this.log(`Removed tag '${args.tag}' from ${args.alias}`);
27
+ return data;
28
+ }
29
+ }
@@ -0,0 +1,14 @@
1
+ import { BaseCommand } from '../../../base.js';
2
+ export default class FaceTagSet extends BaseCommand {
3
+ static description: string;
4
+ static flags: {
5
+ tag: 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
+ static args: {
11
+ alias: import("@oclif/core/interfaces").Arg<string, Record<string, unknown>>;
12
+ };
13
+ run(): Promise<unknown>;
14
+ }
@@ -0,0 +1,29 @@
1
+ import { Args, Flags } from '@oclif/core';
2
+ import { BaseCommand } from '../../../base.js';
3
+ import { FacesAPIError } from '../../../client.js';
4
+ export default class FaceTagSet extends BaseCommand {
5
+ static description = 'Replace all tags on a face';
6
+ static flags = {
7
+ ...BaseCommand.baseFlags,
8
+ tag: Flags.string({ description: 'Tag to set (repeatable, replaces all)', multiple: true, required: true }),
9
+ };
10
+ static args = {
11
+ alias: Args.string({ description: 'Face alias', required: true }),
12
+ };
13
+ async run() {
14
+ const { args, flags } = await this.parse(FaceTagSet);
15
+ const client = this.makeClient(flags);
16
+ let data;
17
+ try {
18
+ data = await client.put(`/v1/iam/${args.alias}/tags`, { body: { tags: flags.tag } });
19
+ }
20
+ catch (err) {
21
+ if (err instanceof FacesAPIError)
22
+ this.error(`Error (${err.statusCode}): ${err.message}`);
23
+ throw err;
24
+ }
25
+ if (!this.jsonEnabled())
26
+ this.printHuman(data);
27
+ return data;
28
+ }
29
+ }
@@ -4,6 +4,7 @@ export default class FaceUpdate extends BaseCommand {
4
4
  static flags: {
5
5
  name: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
6
6
  description: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
7
+ tag: import("@oclif/core/interfaces").OptionFlag<string[] | undefined, import("@oclif/core/interfaces").CustomOptions>;
7
8
  'default-model': import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
8
9
  formula: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
9
10
  attr: import("@oclif/core/interfaces").OptionFlag<string[] | undefined, import("@oclif/core/interfaces").CustomOptions>;
@@ -8,7 +8,8 @@ export default class FaceUpdate extends BaseCommand {
8
8
  static flags = {
9
9
  ...BaseCommand.baseFlags,
10
10
  name: Flags.string({ description: 'New display name' }),
11
- description: Flags.string({ description: 'Description for local catalog' }),
11
+ description: Flags.string({ description: 'Plain-text description / bio (max 1500 chars)' }),
12
+ tag: Flags.string({ description: 'Replace all tags (repeatable, lowercase)', multiple: true }),
12
13
  'default-model': Flags.string({ description: 'Default LLM for chat (e.g. gpt-4o-mini, claude-sonnet-4-6)' }),
13
14
  formula: Flags.string({ description: 'New boolean formula (synthetic faces only)' }),
14
15
  attr: Flags.string({ description: 'Update attribute KEY=VALUE (repeatable)', multiple: true }),
@@ -39,12 +40,13 @@ export default class FaceUpdate extends BaseCommand {
39
40
  payload.default_tools = flags.tool;
40
41
  if (flags['default-model'])
41
42
  payload.default_model = flags['default-model'];
42
- const hasApiFields = Object.keys(payload).length > 0;
43
- const hasDescription = Boolean(flags.description);
44
- if (!hasApiFields && !hasDescription)
43
+ if (flags.description !== undefined)
44
+ payload.description = flags.description;
45
+ const hasTags = flags.tag && flags.tag.length > 0;
46
+ if (Object.keys(payload).length === 0 && !hasTags)
45
47
  this.error('Provide at least one field to update.');
46
48
  let data;
47
- if (hasApiFields) {
49
+ if (Object.keys(payload).length > 0) {
48
50
  try {
49
51
  data = await client.patch(`/v1/faces/${args.face_id}`, { body: payload });
50
52
  }
@@ -55,7 +57,6 @@ export default class FaceUpdate extends BaseCommand {
55
57
  }
56
58
  }
57
59
  else {
58
- // description-only update: fetch current face data for catalog
59
60
  try {
60
61
  data = await client.get(`/v1/faces/${args.face_id}`);
61
62
  }
@@ -65,6 +66,16 @@ export default class FaceUpdate extends BaseCommand {
65
66
  throw err;
66
67
  }
67
68
  }
69
+ // Replace tags if provided
70
+ if (hasTags) {
71
+ try {
72
+ await client.put(`/v1/iam/${args.face_id}/tags`, { body: { tags: flags.tag } });
73
+ }
74
+ catch (err) {
75
+ if (err instanceof FacesAPIError)
76
+ this.warn(`Tags failed (${err.statusCode}): ${err.message}`);
77
+ }
78
+ }
68
79
  const face = data;
69
80
  if (Array.isArray(face.warnings) && face.warnings.length > 0) {
70
81
  for (const w of face.warnings)
@@ -0,0 +1,14 @@
1
+ import { BaseCommand } from '../../base.js';
2
+ export default class TeamAdd extends BaseCommand {
3
+ static description: string;
4
+ static flags: {
5
+ face: 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
+ static args: {
11
+ team_id: import("@oclif/core/interfaces").Arg<string, Record<string, unknown>>;
12
+ };
13
+ run(): Promise<unknown>;
14
+ }
@@ -0,0 +1,51 @@
1
+ import { Args, Flags } from '@oclif/core';
2
+ import { BaseCommand } from '../../base.js';
3
+ import { FacesAPIError } from '../../client.js';
4
+ export default class TeamAdd extends BaseCommand {
5
+ static description = 'Add face(s) to a team';
6
+ static flags = {
7
+ ...BaseCommand.baseFlags,
8
+ face: Flags.string({ description: 'Face alias to add (repeatable)', multiple: true, required: true }),
9
+ };
10
+ static args = {
11
+ team_id: Args.string({ description: 'Team ID', required: true }),
12
+ };
13
+ async run() {
14
+ const { args, flags } = await this.parse(TeamAdd);
15
+ const client = this.makeClient(flags);
16
+ // Resolve aliases to iam_ids
17
+ const iamIds = [];
18
+ for (const alias of flags.face) {
19
+ try {
20
+ const face = await client.get(`/v1/faces/${alias}`);
21
+ const id = (face.uid ?? face.id ?? face.iam_id);
22
+ if (!id)
23
+ this.error(`Could not resolve iam_id for face '${alias}'`);
24
+ iamIds.push(id);
25
+ }
26
+ catch (err) {
27
+ if (err instanceof FacesAPIError)
28
+ this.error(`Error resolving '${alias}' (${err.statusCode}): ${err.message}`);
29
+ throw err;
30
+ }
31
+ }
32
+ let data;
33
+ try {
34
+ if (iamIds.length === 1) {
35
+ data = await client.post(`/v1/teams/${args.team_id}/members`, { body: { iam_id: iamIds[0] } });
36
+ }
37
+ else {
38
+ data = await client.post(`/v1/teams/${args.team_id}/members`, { body: { iam_ids: iamIds } });
39
+ }
40
+ }
41
+ catch (err) {
42
+ if (err instanceof FacesAPIError)
43
+ this.error(`Error (${err.statusCode}): ${err.message}`);
44
+ throw err;
45
+ }
46
+ if (!this.jsonEnabled()) {
47
+ this.log(`Added ${flags.face.join(', ')} to team.`);
48
+ }
49
+ return data;
50
+ }
51
+ }
@@ -0,0 +1,15 @@
1
+ import { BaseCommand } from '../../base.js';
2
+ export default class TeamCreate extends BaseCommand {
3
+ static description: string;
4
+ static flags: {
5
+ name: import("@oclif/core/interfaces").OptionFlag<string, import("@oclif/core/interfaces").CustomOptions>;
6
+ description: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
7
+ protocol: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
8
+ 'protocol-file': import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
9
+ tag: import("@oclif/core/interfaces").OptionFlag<string[] | undefined, import("@oclif/core/interfaces").CustomOptions>;
10
+ 'base-url': import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
11
+ token: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
12
+ 'api-key': import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
13
+ };
14
+ run(): Promise<unknown>;
15
+ }
@@ -0,0 +1,53 @@
1
+ import { 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 TeamCreate extends BaseCommand {
6
+ static description = 'Create a new team';
7
+ static flags = {
8
+ ...BaseCommand.baseFlags,
9
+ name: Flags.string({ description: 'Team name', required: true }),
10
+ description: Flags.string({ description: 'Plain-text team description (max 1500 chars)' }),
11
+ protocol: Flags.string({ description: 'Protocol content (mermaid diagram or markdown, max 1000 words)' }),
12
+ 'protocol-file': Flags.string({ description: 'Read protocol from file' }),
13
+ tag: Flags.string({ description: 'Tag label (repeatable, lowercase)', multiple: true }),
14
+ };
15
+ async run() {
16
+ const { flags } = await this.parse(TeamCreate);
17
+ const client = this.makeClient(flags);
18
+ let protocol = flags.protocol;
19
+ if (flags['protocol-file']) {
20
+ if (!fs.existsSync(flags['protocol-file']))
21
+ this.error(`File not found: ${flags['protocol-file']}`);
22
+ protocol = fs.readFileSync(flags['protocol-file'], 'utf8');
23
+ }
24
+ const payload = { name: flags.name };
25
+ if (flags.description)
26
+ payload.description = flags.description;
27
+ if (protocol)
28
+ payload.protocol = protocol;
29
+ let data;
30
+ try {
31
+ data = await client.post('/v1/teams', { body: payload });
32
+ }
33
+ catch (err) {
34
+ if (err instanceof FacesAPIError)
35
+ this.error(`Error (${err.statusCode}): ${err.message}`);
36
+ throw err;
37
+ }
38
+ const team = data;
39
+ // Post tags if provided
40
+ if (flags.tag && flags.tag.length > 0) {
41
+ try {
42
+ await client.post(`/v1/teams/${team.id}/tags`, { body: { tags: flags.tag } });
43
+ }
44
+ catch (err) {
45
+ if (err instanceof FacesAPIError)
46
+ this.warn(`Tags failed (${err.statusCode}): ${err.message}`);
47
+ }
48
+ }
49
+ if (!this.jsonEnabled())
50
+ this.printHuman(data);
51
+ return data;
52
+ }
53
+ }
@@ -0,0 +1,15 @@
1
+ import { BaseCommand } from '../../base.js';
2
+ export default class TeamDelete 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
+ static args: {
11
+ team_id: import("@oclif/core/interfaces").Arg<string, Record<string, unknown>>;
12
+ };
13
+ run(): Promise<unknown>;
14
+ private confirm;
15
+ }
@@ -0,0 +1,44 @@
1
+ import { Args, 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 TeamDelete extends BaseCommand {
6
+ static description = 'Delete a team';
7
+ static flags = {
8
+ ...BaseCommand.baseFlags,
9
+ yes: Flags.boolean({ description: 'Skip confirmation', default: false }),
10
+ };
11
+ static args = {
12
+ team_id: Args.string({ description: 'Team ID', required: true }),
13
+ };
14
+ async run() {
15
+ const { args, flags } = await this.parse(TeamDelete);
16
+ const client = this.makeClient(flags);
17
+ if (!flags.yes) {
18
+ const confirmed = await this.confirm(`Delete team '${args.team_id}'?`);
19
+ if (!confirmed)
20
+ this.error('Aborted.');
21
+ }
22
+ let data;
23
+ try {
24
+ data = await client.delete(`/v1/teams/${args.team_id}`);
25
+ }
26
+ catch (err) {
27
+ if (err instanceof FacesAPIError)
28
+ this.error(`Error (${err.statusCode}): ${err.message}`);
29
+ throw err;
30
+ }
31
+ if (!this.jsonEnabled())
32
+ this.printHuman(data);
33
+ return data;
34
+ }
35
+ confirm(message) {
36
+ return new Promise((resolve) => {
37
+ const rl = createInterface({ input: process.stdin, output: process.stdout });
38
+ rl.question(`${message} [y/N] `, (answer) => {
39
+ rl.close();
40
+ resolve(answer.toLowerCase() === 'y');
41
+ });
42
+ });
43
+ }
44
+ }
@@ -0,0 +1,13 @@
1
+ import { BaseCommand } from '../../base.js';
2
+ export default class TeamGet 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
+ static args: {
10
+ team_id: import("@oclif/core/interfaces").Arg<string, Record<string, unknown>>;
11
+ };
12
+ run(): Promise<unknown>;
13
+ }
@@ -0,0 +1,28 @@
1
+ import { Args } from '@oclif/core';
2
+ import { BaseCommand } from '../../base.js';
3
+ import { FacesAPIError } from '../../client.js';
4
+ export default class TeamGet extends BaseCommand {
5
+ static description = 'Get a team by ID';
6
+ static flags = {
7
+ ...BaseCommand.baseFlags,
8
+ };
9
+ static args = {
10
+ team_id: Args.string({ description: 'Team ID', required: true }),
11
+ };
12
+ async run() {
13
+ const { args, flags } = await this.parse(TeamGet);
14
+ const client = this.makeClient(flags);
15
+ let data;
16
+ try {
17
+ data = await client.get(`/v1/teams/${args.team_id}`);
18
+ }
19
+ catch (err) {
20
+ if (err instanceof FacesAPIError)
21
+ this.error(`Error (${err.statusCode}): ${err.message}`);
22
+ throw err;
23
+ }
24
+ if (!this.jsonEnabled())
25
+ this.printHuman(data);
26
+ return data;
27
+ }
28
+ }
@@ -0,0 +1,10 @@
1
+ import { BaseCommand } from '../../base.js';
2
+ export default class TeamList 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,49 @@
1
+ import { BaseCommand } from '../../base.js';
2
+ import { FacesAPIError } from '../../client.js';
3
+ export default class TeamList extends BaseCommand {
4
+ static description = 'List your teams';
5
+ static flags = {
6
+ ...BaseCommand.baseFlags,
7
+ };
8
+ async run() {
9
+ const { flags } = await this.parse(TeamList);
10
+ const client = this.makeClient(flags);
11
+ // Get current username to filter out personal Guild
12
+ let username;
13
+ try {
14
+ const resp = await client.get('/auth/me');
15
+ const whoami = (resp.data ?? resp);
16
+ username = whoami.username ?? undefined;
17
+ }
18
+ catch { /* proceed without filtering */ }
19
+ let data;
20
+ try {
21
+ data = await client.get('/v1/me/teams');
22
+ }
23
+ catch (err) {
24
+ if (err instanceof FacesAPIError)
25
+ this.error(`Error (${err.statusCode}): ${err.message}`);
26
+ throw err;
27
+ }
28
+ const resp = data;
29
+ let teams = resp.data ?? data;
30
+ // Filter out personal Guild
31
+ if (username) {
32
+ teams = teams.filter(t => t.name !== username);
33
+ }
34
+ if (this.jsonEnabled())
35
+ return teams;
36
+ if (teams.length === 0) {
37
+ this.log('(no teams)');
38
+ }
39
+ else {
40
+ const nameWidth = Math.max(...teams.map(t => String(t.name ?? '').length));
41
+ for (const t of teams) {
42
+ const name = String(t.name ?? '').padEnd(nameWidth);
43
+ const desc = t.description ? ` ${String(t.description).slice(0, 60)}` : '';
44
+ this.log(`${t.id} ${name}${desc}`);
45
+ }
46
+ }
47
+ return teams;
48
+ }
49
+ }
@@ -0,0 +1,13 @@
1
+ import { BaseCommand } from '../../base.js';
2
+ export default class TeamMembers 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
+ static args: {
10
+ team_id: import("@oclif/core/interfaces").Arg<string, Record<string, unknown>>;
11
+ };
12
+ run(): Promise<unknown>;
13
+ }
@@ -0,0 +1,28 @@
1
+ import { Args } from '@oclif/core';
2
+ import { BaseCommand } from '../../base.js';
3
+ import { FacesAPIError } from '../../client.js';
4
+ export default class TeamMembers extends BaseCommand {
5
+ static description = 'List members of a team';
6
+ static flags = {
7
+ ...BaseCommand.baseFlags,
8
+ };
9
+ static args = {
10
+ team_id: Args.string({ description: 'Team ID', required: true }),
11
+ };
12
+ async run() {
13
+ const { args, flags } = await this.parse(TeamMembers);
14
+ const client = this.makeClient(flags);
15
+ let data;
16
+ try {
17
+ data = await client.get(`/v1/teams/${args.team_id}/members`);
18
+ }
19
+ catch (err) {
20
+ if (err instanceof FacesAPIError)
21
+ this.error(`Error (${err.statusCode}): ${err.message}`);
22
+ throw err;
23
+ }
24
+ if (!this.jsonEnabled())
25
+ this.printHuman(data);
26
+ return data;
27
+ }
28
+ }
@@ -0,0 +1,14 @@
1
+ import { BaseCommand } from '../../base.js';
2
+ export default class TeamRemove 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
+ static args: {
10
+ team_id: import("@oclif/core/interfaces").Arg<string, Record<string, unknown>>;
11
+ alias: import("@oclif/core/interfaces").Arg<string, Record<string, unknown>>;
12
+ };
13
+ run(): Promise<unknown>;
14
+ }
@@ -0,0 +1,42 @@
1
+ import { Args } from '@oclif/core';
2
+ import { BaseCommand } from '../../base.js';
3
+ import { FacesAPIError } from '../../client.js';
4
+ export default class TeamRemove extends BaseCommand {
5
+ static description = 'Remove a face from a team';
6
+ static flags = {
7
+ ...BaseCommand.baseFlags,
8
+ };
9
+ static args = {
10
+ team_id: Args.string({ description: 'Team ID', required: true }),
11
+ alias: Args.string({ description: 'Face alias to remove', required: true }),
12
+ };
13
+ async run() {
14
+ const { args, flags } = await this.parse(TeamRemove);
15
+ const client = this.makeClient(flags);
16
+ // Resolve alias to iam_id
17
+ let iamId;
18
+ try {
19
+ const face = await client.get(`/v1/faces/${args.alias}`);
20
+ iamId = (face.uid ?? face.id ?? face.iam_id);
21
+ if (!iamId)
22
+ this.error(`Could not resolve iam_id for face '${args.alias}'`);
23
+ }
24
+ catch (err) {
25
+ if (err instanceof FacesAPIError)
26
+ this.error(`Error resolving '${args.alias}' (${err.statusCode}): ${err.message}`);
27
+ throw err;
28
+ }
29
+ let data;
30
+ try {
31
+ data = await client.delete(`/v1/teams/${args.team_id}/members/${iamId}`);
32
+ }
33
+ catch (err) {
34
+ if (err instanceof FacesAPIError)
35
+ this.error(`Error (${err.statusCode}): ${err.message}`);
36
+ throw err;
37
+ }
38
+ if (!this.jsonEnabled())
39
+ this.log(`Removed ${args.alias} from team.`);
40
+ return data;
41
+ }
42
+ }
@@ -0,0 +1,14 @@
1
+ import { BaseCommand } from '../../../base.js';
2
+ export default class TeamTagAdd extends BaseCommand {
3
+ static description: string;
4
+ static flags: {
5
+ tag: 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
+ static args: {
11
+ team_id: import("@oclif/core/interfaces").Arg<string, Record<string, unknown>>;
12
+ };
13
+ run(): Promise<unknown>;
14
+ }