faces-cli 1.6.16 → 1.6.17

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.
@@ -7,6 +7,7 @@ export default class KeysCreate extends BaseCommand {
7
7
  budget: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
8
8
  face: import("@oclif/core/interfaces").OptionFlag<string[] | undefined, import("@oclif/core/interfaces").CustomOptions>;
9
9
  model: import("@oclif/core/interfaces").OptionFlag<string[] | undefined, import("@oclif/core/interfaces").CustomOptions>;
10
+ save: import("@oclif/core/interfaces").BooleanFlag<boolean>;
10
11
  'base-url': import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
11
12
  token: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
12
13
  'api-key': import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
@@ -1,8 +1,9 @@
1
1
  import { Flags } from '@oclif/core';
2
2
  import { BaseCommand } from '../../base.js';
3
3
  import { FacesAPIError } from '../../client.js';
4
+ import { saveConfig } from '../../config.js';
4
5
  export default class KeysCreate extends BaseCommand {
5
- static description = 'Create a new API key (JWT required)';
6
+ static description = 'Create a new API key (JWT required). The new key is saved to ~/.faces/config.json as api_key by default; pass --no-save to skip.';
6
7
  static flags = {
7
8
  ...BaseCommand.baseFlags,
8
9
  name: Flags.string({ description: 'Key name/label', required: true }),
@@ -10,6 +11,11 @@ export default class KeysCreate extends BaseCommand {
10
11
  budget: Flags.string({ description: 'Spend budget in USD' }),
11
12
  face: Flags.string({ description: 'Allowed face alias (repeatable)', multiple: true }),
12
13
  model: Flags.string({ description: 'Allowed model name (repeatable)', multiple: true }),
14
+ save: Flags.boolean({
15
+ description: 'Save the new key to ~/.faces/config.json as api_key (default: true; use --no-save to skip)',
16
+ default: true,
17
+ allowNo: true,
18
+ }),
13
19
  };
14
20
  async run() {
15
21
  const { flags } = await this.parse(KeysCreate);
@@ -25,15 +31,40 @@ export default class KeysCreate extends BaseCommand {
25
31
  payload.allowed_models = flags.model;
26
32
  let data;
27
33
  try {
28
- data = await client.post('/v1/auth/api-keys', { requireJwt: true, body: payload });
34
+ data = (await client.post('/v1/auth/api-keys', {
35
+ requireJwt: true,
36
+ body: payload,
37
+ }));
29
38
  }
30
39
  catch (err) {
31
40
  if (err instanceof FacesAPIError)
32
41
  this.error(`Error (${err.statusCode}): ${err.message}`);
33
42
  throw err;
34
43
  }
35
- if (!this.jsonEnabled())
36
- this.printHuman(data);
44
+ // The plaintext secret is returned exactly once — here. keys:list only ever
45
+ // returns it truncated, so it must be saved or copied now.
46
+ const apiKey = (data.key ?? data.api_key ?? data.secret);
47
+ let saved = false;
48
+ if (flags.save && apiKey) {
49
+ saveConfig({ api_key: apiKey });
50
+ saved = true;
51
+ }
52
+ if (this.jsonEnabled()) {
53
+ data._saved_to_config = saved;
54
+ return data;
55
+ }
56
+ this.printHuman(data);
57
+ this.log('');
58
+ this.log('⚠ The full key is shown only once — `faces keys:list` returns it truncated by design.');
59
+ if (saved) {
60
+ this.log('✓ Saved to ~/.faces/config.json as api_key — faces commands will use it automatically.');
61
+ }
62
+ else if (!flags.save) {
63
+ this.log(' Not saved (--no-save). Copy the key above now.');
64
+ }
65
+ else {
66
+ this.warn('Could not find the key in the response — nothing was saved. Copy it manually.');
67
+ }
37
68
  return data;
38
69
  }
39
70
  }