faces-cli 1.5.8 → 1.5.10

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,100 @@
1
1
  import { BaseCommand } from '../../base.js';
2
- import { FacesAPIError } from '../../client.js';
2
+ import { FacesClient, FacesAPIError } from '../../client.js';
3
+ import { resolveBaseUrl, resolveToken, resolveApiKey } from '../../config.js';
3
4
  export default class AuthWhoami extends BaseCommand {
4
- static description = 'Print current user profile';
5
+ static description = 'Print current user profile and auth diagnostic';
5
6
  static flags = {
6
7
  ...BaseCommand.baseFlags,
7
8
  };
8
9
  async run() {
9
10
  const { flags } = await this.parse(AuthWhoami);
10
- const client = this.makeClient(flags);
11
- let data;
12
- try {
13
- data = await client.get('/auth/me');
11
+ const baseUrl = resolveBaseUrl(flags['base-url']);
12
+ const token = resolveToken(flags.token);
13
+ const apiKey = resolveApiKey(flags['api-key']);
14
+ const json = this.jsonEnabled();
15
+ const diag = {
16
+ base_url: baseUrl,
17
+ jwt_configured: Boolean(token),
18
+ api_key_configured: Boolean(apiKey),
19
+ api_key_prefix: apiKey ? apiKey.slice(0, 12) + '...' : null,
20
+ };
21
+ if (!apiKey && !token) {
22
+ diag.authenticated = false;
23
+ diag.error = 'No credentials configured (no API key, no JWT)';
24
+ if (!json) {
25
+ process.stderr.write('Auth diagnostic:\n');
26
+ process.stderr.write(` base_url: ${baseUrl}\n`);
27
+ process.stderr.write(` jwt: not configured\n`);
28
+ process.stderr.write(` api_key: not configured\n`);
29
+ process.stderr.write(` status: not authenticated\n`);
30
+ }
31
+ return diag;
14
32
  }
15
- catch (err) {
16
- if (err instanceof FacesAPIError)
17
- this.error(`Error (${err.statusCode}): ${err.message}`);
18
- throw err;
33
+ // Try API key first (priority), then JWT. Always try both and report.
34
+ let apiKeyResult = null;
35
+ let jwtResult = null;
36
+ if (apiKey) {
37
+ const client = new FacesClient(baseUrl, undefined, apiKey);
38
+ try {
39
+ const data = await client.get('/auth/me');
40
+ apiKeyResult = { ok: true, data: (data.data ?? data) };
41
+ }
42
+ catch (err) {
43
+ const msg = err instanceof FacesAPIError ? `${err.statusCode}: ${err.message}` : String(err);
44
+ apiKeyResult = { ok: false, error: msg };
45
+ }
19
46
  }
20
- if (!this.jsonEnabled())
21
- this.printHuman(data);
22
- return data;
47
+ if (token) {
48
+ // Only try JWT if API key failed or wasn't configured
49
+ if (!apiKeyResult?.ok) {
50
+ const client = new FacesClient(baseUrl, token, undefined);
51
+ try {
52
+ const data = await client.get('/auth/me');
53
+ jwtResult = { ok: true, data: (data.data ?? data) };
54
+ }
55
+ catch (err) {
56
+ const msg = err instanceof FacesAPIError ? `${err.statusCode}: ${err.message}` : String(err);
57
+ jwtResult = { ok: false, error: msg };
58
+ }
59
+ }
60
+ else {
61
+ jwtResult = { ok: false, error: 'not tried (API key succeeded)' };
62
+ }
63
+ }
64
+ // Determine the winning result
65
+ const winner = apiKeyResult?.ok ? apiKeyResult : jwtResult?.ok ? jwtResult : null;
66
+ const winnerMethod = apiKeyResult?.ok ? 'api_key' : jwtResult?.ok ? 'jwt' : null;
67
+ diag.authenticated = Boolean(winner);
68
+ diag.auth_method = winnerMethod;
69
+ if (apiKeyResult)
70
+ diag.api_key_status = apiKeyResult.ok ? 'valid' : apiKeyResult.error;
71
+ if (jwtResult)
72
+ diag.jwt_status = jwtResult.ok ? 'valid' : jwtResult.error;
73
+ if (winner?.data) {
74
+ diag.user_id = winner.data.user_id;
75
+ diag.username = winner.data.username;
76
+ diag.email = winner.data.email;
77
+ diag.name = winner.data.name;
78
+ diag.is_admin = winner.data.is_admin;
79
+ }
80
+ else {
81
+ diag.error = 'All credentials failed';
82
+ }
83
+ if (!json) {
84
+ process.stderr.write('Auth diagnostic:\n');
85
+ process.stderr.write(` base_url: ${baseUrl}\n`);
86
+ process.stderr.write(` jwt: ${token ? (jwtResult?.ok ? 'valid' : `failed (${jwtResult?.error})`) : 'not configured'}\n`);
87
+ process.stderr.write(` api_key: ${apiKey ? (apiKeyResult?.ok ? `valid (${diag.api_key_prefix})` : `failed (${apiKeyResult?.error})`) : 'not configured'}\n`);
88
+ process.stderr.write(` auth_method: ${winnerMethod ?? 'none'}\n`);
89
+ process.stderr.write(` status: ${winner ? 'authenticated' : 'failed'}\n`);
90
+ if (winner?.data) {
91
+ process.stderr.write('\n');
92
+ process.stderr.write(` user_id: ${winner.data.user_id}\n`);
93
+ process.stderr.write(` username: ${winner.data.username}\n`);
94
+ process.stderr.write(` email: ${winner.data.email}\n`);
95
+ process.stderr.write(` name: ${winner.data.name}\n`);
96
+ }
97
+ }
98
+ return diag;
23
99
  }
24
100
  }
@@ -12,6 +12,10 @@ export default class ConfigSet extends BaseCommand {
12
12
  };
13
13
  async run() {
14
14
  const { args } = await this.parse(ConfigSet);
15
+ // Validate api_key prefix
16
+ if (args.key === 'api_key' && args.value && !args.value.startsWith('sk-faces-')) {
17
+ this.error('Faces API keys start with sk-faces-. This does not look like a Faces API key.');
18
+ }
15
19
  setConfigKey(args.key, args.value);
16
20
  this.log(`Set ${args.key}.`);
17
21
  return { key: args.key, status: 'set' };
package/dist/config.js CHANGED
@@ -50,16 +50,20 @@ export function resolveBaseUrl(override) {
50
50
  return 'https://api.faces.sh';
51
51
  }
52
52
  export function resolveToken(override) {
53
- if (override)
54
- return override;
55
- if (process.env.FACES_TOKEN)
56
- return process.env.FACES_TOKEN;
57
- return loadConfig().token;
53
+ // Empty string override means "no token" — don't fall back to config/env
54
+ if (override !== undefined)
55
+ return override || undefined;
56
+ const env = process.env.FACES_TOKEN;
57
+ if (env)
58
+ return env;
59
+ return loadConfig().token || undefined;
58
60
  }
59
61
  export function resolveApiKey(override) {
60
- if (override)
61
- return override;
62
- if (process.env.FACES_API_KEY)
63
- return process.env.FACES_API_KEY;
64
- return loadConfig().api_key;
62
+ // Empty string override means "no API key" — don't fall back to config/env
63
+ if (override !== undefined)
64
+ return override || undefined;
65
+ const env = process.env.FACES_API_KEY;
66
+ if (env)
67
+ return env;
68
+ return loadConfig().api_key || undefined;
65
69
  }
@@ -528,7 +528,7 @@
528
528
  "auth:whoami": {
529
529
  "aliases": [],
530
530
  "args": {},
531
- "description": "Print current user profile",
531
+ "description": "Print current user profile and auth diagnostic",
532
532
  "flags": {
533
533
  "json": {
534
534
  "description": "Format output as json.",
@@ -578,10 +578,10 @@
578
578
  "whoami.js"
579
579
  ]
580
580
  },
581
- "catalog:doctor": {
581
+ "billing:balance": {
582
582
  "aliases": [],
583
583
  "args": {},
584
- "description": "Diagnose and repair the local face catalog",
584
+ "description": "Show credit balance and payment method status",
585
585
  "flags": {
586
586
  "json": {
587
587
  "description": "Format output as json.",
@@ -613,23 +613,11 @@
613
613
  "hasDynamicHelp": false,
614
614
  "multiple": false,
615
615
  "type": "option"
616
- },
617
- "fix": {
618
- "description": "Rebuild missing or stale catalog entries from API",
619
- "name": "fix",
620
- "allowNo": false,
621
- "type": "boolean"
622
- },
623
- "generate": {
624
- "description": "Fix + generate missing descriptions via LLM",
625
- "name": "generate",
626
- "allowNo": false,
627
- "type": "boolean"
628
616
  }
629
617
  },
630
618
  "hasDynamicHelp": false,
631
619
  "hiddenAliases": [],
632
- "id": "catalog:doctor",
620
+ "id": "billing:balance",
633
621
  "pluginAlias": "faces-cli",
634
622
  "pluginName": "faces-cli",
635
623
  "pluginType": "core",
@@ -639,14 +627,14 @@
639
627
  "relativePath": [
640
628
  "dist",
641
629
  "commands",
642
- "catalog",
643
- "doctor.js"
630
+ "billing",
631
+ "balance.js"
644
632
  ]
645
633
  },
646
- "catalog:list": {
634
+ "billing:card-setup": {
647
635
  "aliases": [],
648
636
  "args": {},
649
- "description": "List all faces in the local catalog",
637
+ "description": "Get a Stripe card setup URL to save a payment method",
650
638
  "flags": {
651
639
  "json": {
652
640
  "description": "Format output as json.",
@@ -682,7 +670,7 @@
682
670
  },
683
671
  "hasDynamicHelp": false,
684
672
  "hiddenAliases": [],
685
- "id": "catalog:list",
673
+ "id": "billing:card-setup",
686
674
  "pluginAlias": "faces-cli",
687
675
  "pluginName": "faces-cli",
688
676
  "pluginType": "core",
@@ -692,14 +680,14 @@
692
680
  "relativePath": [
693
681
  "dist",
694
682
  "commands",
695
- "catalog",
696
- "list.js"
683
+ "billing",
684
+ "card-setup.js"
697
685
  ]
698
686
  },
699
- "catalog:manyfaced": {
687
+ "billing:checkout": {
700
688
  "aliases": [],
701
689
  "args": {},
702
- "description": "Browse and install community manyfaced skills from github.com/facessh/manyfaced",
690
+ "description": "Get a Stripe checkout URL to upgrade your subscription plan",
703
691
  "flags": {
704
692
  "json": {
705
693
  "description": "Format output as json.",
@@ -732,37 +720,21 @@
732
720
  "multiple": false,
733
721
  "type": "option"
734
722
  },
735
- "skill": {
736
- "description": "Show details for a specific skill",
737
- "name": "skill",
738
- "hasDynamicHelp": false,
739
- "multiple": false,
740
- "type": "option"
741
- },
742
- "install": {
743
- "description": "Install a skill by name",
744
- "name": "install",
745
- "hasDynamicHelp": false,
746
- "multiple": false,
747
- "type": "option"
748
- },
749
- "skills-dir": {
750
- "description": "Directory to install skills into (required for --install)",
751
- "name": "skills-dir",
723
+ "plan": {
724
+ "description": "Plan to subscribe to",
725
+ "name": "plan",
726
+ "default": "connect",
752
727
  "hasDynamicHelp": false,
753
728
  "multiple": false,
729
+ "options": [
730
+ "connect"
731
+ ],
754
732
  "type": "option"
755
- },
756
- "refresh": {
757
- "description": "Force refresh the skill index (ignore cache)",
758
- "name": "refresh",
759
- "allowNo": false,
760
- "type": "boolean"
761
733
  }
762
734
  },
763
735
  "hasDynamicHelp": false,
764
736
  "hiddenAliases": [],
765
- "id": "catalog:manyfaced",
737
+ "id": "billing:checkout",
766
738
  "pluginAlias": "faces-cli",
767
739
  "pluginName": "faces-cli",
768
740
  "pluginType": "core",
@@ -772,14 +744,14 @@
772
744
  "relativePath": [
773
745
  "dist",
774
746
  "commands",
775
- "catalog",
776
- "manyfaced.js"
747
+ "billing",
748
+ "checkout.js"
777
749
  ]
778
750
  },
779
- "billing:balance": {
751
+ "billing:llm-costs": {
780
752
  "aliases": [],
781
753
  "args": {},
782
- "description": "Show credit balance and payment method status",
754
+ "description": "List available LLMs and their per-token costs",
783
755
  "flags": {
784
756
  "json": {
785
757
  "description": "Format output as json.",
@@ -811,11 +783,18 @@
811
783
  "hasDynamicHelp": false,
812
784
  "multiple": false,
813
785
  "type": "option"
786
+ },
787
+ "provider": {
788
+ "description": "Filter by provider (e.g. openai, anthropic)",
789
+ "name": "provider",
790
+ "hasDynamicHelp": false,
791
+ "multiple": false,
792
+ "type": "option"
814
793
  }
815
794
  },
816
795
  "hasDynamicHelp": false,
817
796
  "hiddenAliases": [],
818
- "id": "billing:balance",
797
+ "id": "billing:llm-costs",
819
798
  "pluginAlias": "faces-cli",
820
799
  "pluginName": "faces-cli",
821
800
  "pluginType": "core",
@@ -826,13 +805,13 @@
826
805
  "dist",
827
806
  "commands",
828
807
  "billing",
829
- "balance.js"
808
+ "llm-costs.js"
830
809
  ]
831
810
  },
832
- "billing:card-setup": {
811
+ "billing:quota": {
833
812
  "aliases": [],
834
813
  "args": {},
835
- "description": "Get a Stripe card setup URL to save a payment method",
814
+ "description": "Show compile token quota and per-face stats",
836
815
  "flags": {
837
816
  "json": {
838
817
  "description": "Format output as json.",
@@ -868,7 +847,7 @@
868
847
  },
869
848
  "hasDynamicHelp": false,
870
849
  "hiddenAliases": [],
871
- "id": "billing:card-setup",
850
+ "id": "billing:quota",
872
851
  "pluginAlias": "faces-cli",
873
852
  "pluginName": "faces-cli",
874
853
  "pluginType": "core",
@@ -879,13 +858,13 @@
879
858
  "dist",
880
859
  "commands",
881
860
  "billing",
882
- "card-setup.js"
861
+ "quota.js"
883
862
  ]
884
863
  },
885
- "billing:checkout": {
864
+ "billing:subscription": {
886
865
  "aliases": [],
887
866
  "args": {},
888
- "description": "Get a Stripe checkout URL to upgrade your subscription plan",
867
+ "description": "Show current plan, face count, and renewal date",
889
868
  "flags": {
890
869
  "json": {
891
870
  "description": "Format output as json.",
@@ -917,22 +896,11 @@
917
896
  "hasDynamicHelp": false,
918
897
  "multiple": false,
919
898
  "type": "option"
920
- },
921
- "plan": {
922
- "description": "Plan to subscribe to",
923
- "name": "plan",
924
- "default": "connect",
925
- "hasDynamicHelp": false,
926
- "multiple": false,
927
- "options": [
928
- "connect"
929
- ],
930
- "type": "option"
931
899
  }
932
900
  },
933
901
  "hasDynamicHelp": false,
934
902
  "hiddenAliases": [],
935
- "id": "billing:checkout",
903
+ "id": "billing:subscription",
936
904
  "pluginAlias": "faces-cli",
937
905
  "pluginName": "faces-cli",
938
906
  "pluginType": "core",
@@ -943,13 +911,13 @@
943
911
  "dist",
944
912
  "commands",
945
913
  "billing",
946
- "checkout.js"
914
+ "subscription.js"
947
915
  ]
948
916
  },
949
- "billing:llm-costs": {
917
+ "billing:topup": {
950
918
  "aliases": [],
951
919
  "args": {},
952
- "description": "List available LLMs and their per-token costs",
920
+ "description": "Top up credit balance using saved payment method",
953
921
  "flags": {
954
922
  "json": {
955
923
  "description": "Format output as json.",
@@ -982,9 +950,17 @@
982
950
  "multiple": false,
983
951
  "type": "option"
984
952
  },
985
- "provider": {
986
- "description": "Filter by provider (e.g. openai, anthropic)",
987
- "name": "provider",
953
+ "amount": {
954
+ "description": "Top-up amount in USD (min $1)",
955
+ "name": "amount",
956
+ "required": true,
957
+ "hasDynamicHelp": false,
958
+ "multiple": false,
959
+ "type": "option"
960
+ },
961
+ "payment-ref": {
962
+ "description": "Payment reference (admin/test path)",
963
+ "name": "payment-ref",
988
964
  "hasDynamicHelp": false,
989
965
  "multiple": false,
990
966
  "type": "option"
@@ -992,7 +968,7 @@
992
968
  },
993
969
  "hasDynamicHelp": false,
994
970
  "hiddenAliases": [],
995
- "id": "billing:llm-costs",
971
+ "id": "billing:topup",
996
972
  "pluginAlias": "faces-cli",
997
973
  "pluginName": "faces-cli",
998
974
  "pluginType": "core",
@@ -1003,13 +979,13 @@
1003
979
  "dist",
1004
980
  "commands",
1005
981
  "billing",
1006
- "llm-costs.js"
982
+ "topup.js"
1007
983
  ]
1008
984
  },
1009
- "billing:quota": {
985
+ "billing:usage": {
1010
986
  "aliases": [],
1011
987
  "args": {},
1012
- "description": "Show compile token quota and per-face stats",
988
+ "description": "Aggregated usage analytics",
1013
989
  "flags": {
1014
990
  "json": {
1015
991
  "description": "Format output as json.",
@@ -1041,11 +1017,38 @@
1041
1017
  "hasDynamicHelp": false,
1042
1018
  "multiple": false,
1043
1019
  "type": "option"
1020
+ },
1021
+ "group-by": {
1022
+ "description": "Group results",
1023
+ "name": "group-by",
1024
+ "hasDynamicHelp": false,
1025
+ "multiple": false,
1026
+ "options": [
1027
+ "api_key",
1028
+ "model",
1029
+ "llm",
1030
+ "date"
1031
+ ],
1032
+ "type": "option"
1033
+ },
1034
+ "from": {
1035
+ "description": "Start date (YYYY-MM-DD)",
1036
+ "name": "from",
1037
+ "hasDynamicHelp": false,
1038
+ "multiple": false,
1039
+ "type": "option"
1040
+ },
1041
+ "to": {
1042
+ "description": "End date (YYYY-MM-DD)",
1043
+ "name": "to",
1044
+ "hasDynamicHelp": false,
1045
+ "multiple": false,
1046
+ "type": "option"
1044
1047
  }
1045
1048
  },
1046
1049
  "hasDynamicHelp": false,
1047
1050
  "hiddenAliases": [],
1048
- "id": "billing:quota",
1051
+ "id": "billing:usage",
1049
1052
  "pluginAlias": "faces-cli",
1050
1053
  "pluginName": "faces-cli",
1051
1054
  "pluginType": "core",
@@ -1056,13 +1059,13 @@
1056
1059
  "dist",
1057
1060
  "commands",
1058
1061
  "billing",
1059
- "quota.js"
1062
+ "usage.js"
1060
1063
  ]
1061
1064
  },
1062
- "billing:subscription": {
1065
+ "catalog:doctor": {
1063
1066
  "aliases": [],
1064
1067
  "args": {},
1065
- "description": "Show current plan, face count, and renewal date",
1068
+ "description": "Diagnose and repair the local face catalog",
1066
1069
  "flags": {
1067
1070
  "json": {
1068
1071
  "description": "Format output as json.",
@@ -1094,11 +1097,23 @@
1094
1097
  "hasDynamicHelp": false,
1095
1098
  "multiple": false,
1096
1099
  "type": "option"
1100
+ },
1101
+ "fix": {
1102
+ "description": "Rebuild missing or stale catalog entries from API",
1103
+ "name": "fix",
1104
+ "allowNo": false,
1105
+ "type": "boolean"
1106
+ },
1107
+ "generate": {
1108
+ "description": "Fix + generate missing descriptions via LLM",
1109
+ "name": "generate",
1110
+ "allowNo": false,
1111
+ "type": "boolean"
1097
1112
  }
1098
1113
  },
1099
1114
  "hasDynamicHelp": false,
1100
1115
  "hiddenAliases": [],
1101
- "id": "billing:subscription",
1116
+ "id": "catalog:doctor",
1102
1117
  "pluginAlias": "faces-cli",
1103
1118
  "pluginName": "faces-cli",
1104
1119
  "pluginType": "core",
@@ -1108,14 +1123,14 @@
1108
1123
  "relativePath": [
1109
1124
  "dist",
1110
1125
  "commands",
1111
- "billing",
1112
- "subscription.js"
1126
+ "catalog",
1127
+ "doctor.js"
1113
1128
  ]
1114
1129
  },
1115
- "billing:topup": {
1130
+ "catalog:list": {
1116
1131
  "aliases": [],
1117
1132
  "args": {},
1118
- "description": "Top up credit balance using saved payment method",
1133
+ "description": "List all faces in the local catalog",
1119
1134
  "flags": {
1120
1135
  "json": {
1121
1136
  "description": "Format output as json.",
@@ -1147,26 +1162,11 @@
1147
1162
  "hasDynamicHelp": false,
1148
1163
  "multiple": false,
1149
1164
  "type": "option"
1150
- },
1151
- "amount": {
1152
- "description": "Top-up amount in USD (min $1)",
1153
- "name": "amount",
1154
- "required": true,
1155
- "hasDynamicHelp": false,
1156
- "multiple": false,
1157
- "type": "option"
1158
- },
1159
- "payment-ref": {
1160
- "description": "Payment reference (admin/test path)",
1161
- "name": "payment-ref",
1162
- "hasDynamicHelp": false,
1163
- "multiple": false,
1164
- "type": "option"
1165
1165
  }
1166
1166
  },
1167
1167
  "hasDynamicHelp": false,
1168
1168
  "hiddenAliases": [],
1169
- "id": "billing:topup",
1169
+ "id": "catalog:list",
1170
1170
  "pluginAlias": "faces-cli",
1171
1171
  "pluginName": "faces-cli",
1172
1172
  "pluginType": "core",
@@ -1176,14 +1176,14 @@
1176
1176
  "relativePath": [
1177
1177
  "dist",
1178
1178
  "commands",
1179
- "billing",
1180
- "topup.js"
1179
+ "catalog",
1180
+ "list.js"
1181
1181
  ]
1182
1182
  },
1183
- "billing:usage": {
1183
+ "catalog:manyfaced": {
1184
1184
  "aliases": [],
1185
1185
  "args": {},
1186
- "description": "Aggregated usage analytics",
1186
+ "description": "Browse and install community manyfaced skills from github.com/facessh/manyfaced",
1187
1187
  "flags": {
1188
1188
  "json": {
1189
1189
  "description": "Format output as json.",
@@ -1216,37 +1216,37 @@
1216
1216
  "multiple": false,
1217
1217
  "type": "option"
1218
1218
  },
1219
- "group-by": {
1220
- "description": "Group results",
1221
- "name": "group-by",
1219
+ "skill": {
1220
+ "description": "Show details for a specific skill",
1221
+ "name": "skill",
1222
1222
  "hasDynamicHelp": false,
1223
1223
  "multiple": false,
1224
- "options": [
1225
- "api_key",
1226
- "model",
1227
- "llm",
1228
- "date"
1229
- ],
1230
1224
  "type": "option"
1231
1225
  },
1232
- "from": {
1233
- "description": "Start date (YYYY-MM-DD)",
1234
- "name": "from",
1226
+ "install": {
1227
+ "description": "Install a skill by name",
1228
+ "name": "install",
1235
1229
  "hasDynamicHelp": false,
1236
1230
  "multiple": false,
1237
1231
  "type": "option"
1238
1232
  },
1239
- "to": {
1240
- "description": "End date (YYYY-MM-DD)",
1241
- "name": "to",
1233
+ "skills-dir": {
1234
+ "description": "Directory to install skills into (required for --install)",
1235
+ "name": "skills-dir",
1242
1236
  "hasDynamicHelp": false,
1243
1237
  "multiple": false,
1244
1238
  "type": "option"
1239
+ },
1240
+ "refresh": {
1241
+ "description": "Force refresh the skill index (ignore cache)",
1242
+ "name": "refresh",
1243
+ "allowNo": false,
1244
+ "type": "boolean"
1245
1245
  }
1246
1246
  },
1247
1247
  "hasDynamicHelp": false,
1248
1248
  "hiddenAliases": [],
1249
- "id": "billing:usage",
1249
+ "id": "catalog:manyfaced",
1250
1250
  "pluginAlias": "faces-cli",
1251
1251
  "pluginName": "faces-cli",
1252
1252
  "pluginType": "core",
@@ -1256,8 +1256,8 @@
1256
1256
  "relativePath": [
1257
1257
  "dist",
1258
1258
  "commands",
1259
- "billing",
1260
- "usage.js"
1259
+ "catalog",
1260
+ "manyfaced.js"
1261
1261
  ]
1262
1262
  },
1263
1263
  "chat:chat": {
@@ -1545,10 +1545,16 @@
1545
1545
  "responses.js"
1546
1546
  ]
1547
1547
  },
1548
- "config:clear": {
1548
+ "compile:import": {
1549
1549
  "aliases": [],
1550
- "args": {},
1551
- "description": "Delete all saved credentials and config",
1550
+ "args": {
1551
+ "face_id": {
1552
+ "description": "Face alias",
1553
+ "name": "face_id",
1554
+ "required": true
1555
+ }
1556
+ },
1557
+ "description": "Import a YouTube video into a face via server-side download and transcription",
1552
1558
  "flags": {
1553
1559
  "json": {
1554
1560
  "description": "Format output as json.",
@@ -1581,16 +1587,55 @@
1581
1587
  "multiple": false,
1582
1588
  "type": "option"
1583
1589
  },
1584
- "yes": {
1585
- "description": "Skip confirmation",
1586
- "name": "yes",
1590
+ "url": {
1591
+ "description": "YouTube URL (youtube.com/watch?v=... or youtu.be/...)",
1592
+ "name": "url",
1593
+ "required": true,
1594
+ "hasDynamicHelp": false,
1595
+ "multiple": false,
1596
+ "type": "option"
1597
+ },
1598
+ "type": {
1599
+ "description": "\"document\" for solo talks, lectures, monologues; \"thread\" for interviews or multi-speaker conversations",
1600
+ "name": "type",
1601
+ "default": "document",
1602
+ "hasDynamicHelp": false,
1603
+ "multiple": false,
1604
+ "options": [
1605
+ "document",
1606
+ "thread"
1607
+ ],
1608
+ "type": "option"
1609
+ },
1610
+ "perspective": {
1611
+ "description": "\"first-person\" if the face is the speaker; \"third-person\" if the video is about the face",
1612
+ "name": "perspective",
1613
+ "default": "third-person",
1614
+ "hasDynamicHelp": false,
1615
+ "multiple": false,
1616
+ "options": [
1617
+ "first-person",
1618
+ "third-person"
1619
+ ],
1620
+ "type": "option"
1621
+ },
1622
+ "face-speaker": {
1623
+ "description": "For --type thread: AssemblyAI speaker label (e.g. \"A\") that corresponds to the face. Defaults to first detected speaker.",
1624
+ "name": "face-speaker",
1625
+ "hasDynamicHelp": false,
1626
+ "multiple": false,
1627
+ "type": "option"
1628
+ },
1629
+ "no-wait": {
1630
+ "description": "Return immediately after import starts (do not poll for transcription). Prints the ID for manual polling.",
1631
+ "name": "no-wait",
1587
1632
  "allowNo": false,
1588
1633
  "type": "boolean"
1589
1634
  }
1590
1635
  },
1591
1636
  "hasDynamicHelp": false,
1592
1637
  "hiddenAliases": [],
1593
- "id": "config:clear",
1638
+ "id": "compile:import",
1594
1639
  "pluginAlias": "faces-cli",
1595
1640
  "pluginName": "faces-cli",
1596
1641
  "pluginType": "core",
@@ -1600,25 +1645,20 @@
1600
1645
  "relativePath": [
1601
1646
  "dist",
1602
1647
  "commands",
1603
- "config",
1604
- "clear.js"
1648
+ "compile",
1649
+ "import.js"
1605
1650
  ]
1606
1651
  },
1607
- "config:set": {
1652
+ "compile:upload": {
1608
1653
  "aliases": [],
1609
1654
  "args": {
1610
- "key": {
1611
- "description": "Config key",
1612
- "name": "key",
1613
- "required": true
1614
- },
1615
- "value": {
1616
- "description": "Config value",
1617
- "name": "value",
1655
+ "alias": {
1656
+ "description": "Face alias",
1657
+ "name": "alias",
1618
1658
  "required": true
1619
1659
  }
1620
1660
  },
1621
- "description": "Set a config value (e.g. base_url, api_key, token)",
1661
+ "description": "Upload a file (text/PDF/audio/video) to compile into a face",
1622
1662
  "flags": {
1623
1663
  "json": {
1624
1664
  "description": "Format output as json.",
@@ -1650,11 +1690,56 @@
1650
1690
  "hasDynamicHelp": false,
1651
1691
  "multiple": false,
1652
1692
  "type": "option"
1693
+ },
1694
+ "file": {
1695
+ "description": "File to upload",
1696
+ "name": "file",
1697
+ "required": true,
1698
+ "hasDynamicHelp": false,
1699
+ "multiple": false,
1700
+ "type": "option"
1701
+ },
1702
+ "kind": {
1703
+ "description": "Upload kind: document or thread",
1704
+ "name": "kind",
1705
+ "default": "document",
1706
+ "hasDynamicHelp": false,
1707
+ "multiple": false,
1708
+ "options": [
1709
+ "document",
1710
+ "thread"
1711
+ ],
1712
+ "type": "option"
1713
+ },
1714
+ "perspective": {
1715
+ "description": "Perspective (document only)",
1716
+ "name": "perspective",
1717
+ "default": "third-person",
1718
+ "hasDynamicHelp": false,
1719
+ "multiple": false,
1720
+ "options": [
1721
+ "first-person",
1722
+ "third-person"
1723
+ ],
1724
+ "type": "option"
1725
+ },
1726
+ "face-speaker": {
1727
+ "description": "Speaker name to map to the face (thread only). If omitted, auto-detected from face name.",
1728
+ "name": "face-speaker",
1729
+ "hasDynamicHelp": false,
1730
+ "multiple": false,
1731
+ "type": "option"
1732
+ },
1733
+ "no-wait": {
1734
+ "description": "Return immediately after upload (do not poll for transcription). Prints the ID for manual polling.",
1735
+ "name": "no-wait",
1736
+ "allowNo": false,
1737
+ "type": "boolean"
1653
1738
  }
1654
1739
  },
1655
1740
  "hasDynamicHelp": false,
1656
1741
  "hiddenAliases": [],
1657
- "id": "config:set",
1742
+ "id": "compile:upload",
1658
1743
  "pluginAlias": "faces-cli",
1659
1744
  "pluginName": "faces-cli",
1660
1745
  "pluginType": "core",
@@ -1664,14 +1749,14 @@
1664
1749
  "relativePath": [
1665
1750
  "dist",
1666
1751
  "commands",
1667
- "config",
1668
- "set.js"
1752
+ "compile",
1753
+ "upload.js"
1669
1754
  ]
1670
1755
  },
1671
- "config:show": {
1756
+ "config:clear": {
1672
1757
  "aliases": [],
1673
1758
  "args": {},
1674
- "description": "Print current config (credentials are masked)",
1759
+ "description": "Delete all saved credentials and config",
1675
1760
  "flags": {
1676
1761
  "json": {
1677
1762
  "description": "Format output as json.",
@@ -1703,11 +1788,17 @@
1703
1788
  "hasDynamicHelp": false,
1704
1789
  "multiple": false,
1705
1790
  "type": "option"
1791
+ },
1792
+ "yes": {
1793
+ "description": "Skip confirmation",
1794
+ "name": "yes",
1795
+ "allowNo": false,
1796
+ "type": "boolean"
1706
1797
  }
1707
1798
  },
1708
1799
  "hasDynamicHelp": false,
1709
1800
  "hiddenAliases": [],
1710
- "id": "config:show",
1801
+ "id": "config:clear",
1711
1802
  "pluginAlias": "faces-cli",
1712
1803
  "pluginName": "faces-cli",
1713
1804
  "pluginType": "core",
@@ -1718,19 +1809,24 @@
1718
1809
  "dist",
1719
1810
  "commands",
1720
1811
  "config",
1721
- "show.js"
1812
+ "clear.js"
1722
1813
  ]
1723
1814
  },
1724
- "compile:import": {
1815
+ "config:set": {
1725
1816
  "aliases": [],
1726
1817
  "args": {
1727
- "face_id": {
1728
- "description": "Face alias",
1729
- "name": "face_id",
1818
+ "key": {
1819
+ "description": "Config key",
1820
+ "name": "key",
1821
+ "required": true
1822
+ },
1823
+ "value": {
1824
+ "description": "Config value",
1825
+ "name": "value",
1730
1826
  "required": true
1731
1827
  }
1732
1828
  },
1733
- "description": "Import a YouTube video into a face via server-side download and transcription",
1829
+ "description": "Set a config value (e.g. base_url, api_key, token)",
1734
1830
  "flags": {
1735
1831
  "json": {
1736
1832
  "description": "Format output as json.",
@@ -1762,56 +1858,11 @@
1762
1858
  "hasDynamicHelp": false,
1763
1859
  "multiple": false,
1764
1860
  "type": "option"
1765
- },
1766
- "url": {
1767
- "description": "YouTube URL (youtube.com/watch?v=... or youtu.be/...)",
1768
- "name": "url",
1769
- "required": true,
1770
- "hasDynamicHelp": false,
1771
- "multiple": false,
1772
- "type": "option"
1773
- },
1774
- "type": {
1775
- "description": "\"document\" for solo talks, lectures, monologues; \"thread\" for interviews or multi-speaker conversations",
1776
- "name": "type",
1777
- "default": "document",
1778
- "hasDynamicHelp": false,
1779
- "multiple": false,
1780
- "options": [
1781
- "document",
1782
- "thread"
1783
- ],
1784
- "type": "option"
1785
- },
1786
- "perspective": {
1787
- "description": "\"first-person\" if the face is the speaker; \"third-person\" if the video is about the face",
1788
- "name": "perspective",
1789
- "default": "third-person",
1790
- "hasDynamicHelp": false,
1791
- "multiple": false,
1792
- "options": [
1793
- "first-person",
1794
- "third-person"
1795
- ],
1796
- "type": "option"
1797
- },
1798
- "face-speaker": {
1799
- "description": "For --type thread: AssemblyAI speaker label (e.g. \"A\") that corresponds to the face. Defaults to first detected speaker.",
1800
- "name": "face-speaker",
1801
- "hasDynamicHelp": false,
1802
- "multiple": false,
1803
- "type": "option"
1804
- },
1805
- "no-wait": {
1806
- "description": "Return immediately after import starts (do not poll for transcription). Prints the ID for manual polling.",
1807
- "name": "no-wait",
1808
- "allowNo": false,
1809
- "type": "boolean"
1810
1861
  }
1811
1862
  },
1812
1863
  "hasDynamicHelp": false,
1813
1864
  "hiddenAliases": [],
1814
- "id": "compile:import",
1865
+ "id": "config:set",
1815
1866
  "pluginAlias": "faces-cli",
1816
1867
  "pluginName": "faces-cli",
1817
1868
  "pluginType": "core",
@@ -1821,20 +1872,14 @@
1821
1872
  "relativePath": [
1822
1873
  "dist",
1823
1874
  "commands",
1824
- "compile",
1825
- "import.js"
1875
+ "config",
1876
+ "set.js"
1826
1877
  ]
1827
1878
  },
1828
- "compile:upload": {
1879
+ "config:show": {
1829
1880
  "aliases": [],
1830
- "args": {
1831
- "alias": {
1832
- "description": "Face alias",
1833
- "name": "alias",
1834
- "required": true
1835
- }
1836
- },
1837
- "description": "Upload a file (text/PDF/audio/video) to compile into a face",
1881
+ "args": {},
1882
+ "description": "Print current config (credentials are masked)",
1838
1883
  "flags": {
1839
1884
  "json": {
1840
1885
  "description": "Format output as json.",
@@ -1866,56 +1911,11 @@
1866
1911
  "hasDynamicHelp": false,
1867
1912
  "multiple": false,
1868
1913
  "type": "option"
1869
- },
1870
- "file": {
1871
- "description": "File to upload",
1872
- "name": "file",
1873
- "required": true,
1874
- "hasDynamicHelp": false,
1875
- "multiple": false,
1876
- "type": "option"
1877
- },
1878
- "kind": {
1879
- "description": "Upload kind: document or thread",
1880
- "name": "kind",
1881
- "default": "document",
1882
- "hasDynamicHelp": false,
1883
- "multiple": false,
1884
- "options": [
1885
- "document",
1886
- "thread"
1887
- ],
1888
- "type": "option"
1889
- },
1890
- "perspective": {
1891
- "description": "Perspective (document only)",
1892
- "name": "perspective",
1893
- "default": "third-person",
1894
- "hasDynamicHelp": false,
1895
- "multiple": false,
1896
- "options": [
1897
- "first-person",
1898
- "third-person"
1899
- ],
1900
- "type": "option"
1901
- },
1902
- "face-speaker": {
1903
- "description": "Speaker name to map to the face (thread only). If omitted, auto-detected from face name.",
1904
- "name": "face-speaker",
1905
- "hasDynamicHelp": false,
1906
- "multiple": false,
1907
- "type": "option"
1908
- },
1909
- "no-wait": {
1910
- "description": "Return immediately after upload (do not poll for transcription). Prints the ID for manual polling.",
1911
- "name": "no-wait",
1912
- "allowNo": false,
1913
- "type": "boolean"
1914
1914
  }
1915
1915
  },
1916
1916
  "hasDynamicHelp": false,
1917
1917
  "hiddenAliases": [],
1918
- "id": "compile:upload",
1918
+ "id": "config:show",
1919
1919
  "pluginAlias": "faces-cli",
1920
1920
  "pluginName": "faces-cli",
1921
1921
  "pluginType": "core",
@@ -1925,8 +1925,8 @@
1925
1925
  "relativePath": [
1926
1926
  "dist",
1927
1927
  "commands",
1928
- "compile",
1929
- "upload.js"
1928
+ "config",
1929
+ "show.js"
1930
1930
  ]
1931
1931
  },
1932
1932
  "face:create": {
@@ -4231,5 +4231,5 @@
4231
4231
  ]
4232
4232
  }
4233
4233
  },
4234
- "version": "1.5.8"
4234
+ "version": "1.5.10"
4235
4235
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "faces-cli",
3
- "version": "1.5.8",
3
+ "version": "1.5.10",
4
4
  "description": "CLI for the Faces AI platform",
5
5
  "type": "module",
6
6
  "author": "sybileak <sybileak@proton.me>",