faces-cli 1.8.0 → 1.8.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.
@@ -120,23 +120,10 @@
120
120
  "state.js"
121
121
  ]
122
122
  },
123
- "auth:connect": {
123
+ "billing:balance": {
124
124
  "aliases": [],
125
- "args": {
126
- "provider": {
127
- "description": "OAuth provider to connect",
128
- "name": "provider",
129
- "options": [
130
- "openai"
131
- ],
132
- "required": true
133
- }
134
- },
135
- "description": "Connect your ChatGPT account to Faces via device-code authorization (Subscription Connect plan)",
136
- "examples": [
137
- "<%= config.bin %> auth connect openai",
138
- "<%= config.bin %> auth connect openai --json"
139
- ],
125
+ "args": {},
126
+ "description": "Show credit balance and payment method status",
140
127
  "flags": {
141
128
  "json": {
142
129
  "description": "Format output as json.",
@@ -172,7 +159,7 @@
172
159
  },
173
160
  "hasDynamicHelp": false,
174
161
  "hiddenAliases": [],
175
- "id": "auth:connect",
162
+ "id": "billing:balance",
176
163
  "pluginAlias": "faces-cli",
177
164
  "pluginName": "faces-cli",
178
165
  "pluginType": "core",
@@ -182,18 +169,14 @@
182
169
  "relativePath": [
183
170
  "dist",
184
171
  "commands",
185
- "auth",
186
- "connect.js"
172
+ "billing",
173
+ "balance.js"
187
174
  ]
188
175
  },
189
- "auth:connections": {
176
+ "billing:card-setup": {
190
177
  "aliases": [],
191
178
  "args": {},
192
- "description": "List connected OAuth provider accounts",
193
- "examples": [
194
- "<%= config.bin %> auth connections",
195
- "<%= config.bin %> auth connections --json"
196
- ],
179
+ "description": "Get a Stripe card setup URL to save a payment method",
197
180
  "flags": {
198
181
  "json": {
199
182
  "description": "Format output as json.",
@@ -229,7 +212,7 @@
229
212
  },
230
213
  "hasDynamicHelp": false,
231
214
  "hiddenAliases": [],
232
- "id": "auth:connections",
215
+ "id": "billing:card-setup",
233
216
  "pluginAlias": "faces-cli",
234
217
  "pluginName": "faces-cli",
235
218
  "pluginType": "core",
@@ -239,26 +222,14 @@
239
222
  "relativePath": [
240
223
  "dist",
241
224
  "commands",
242
- "auth",
243
- "connections.js"
225
+ "billing",
226
+ "card-setup.js"
244
227
  ]
245
228
  },
246
- "auth:disconnect": {
229
+ "billing:llm-costs": {
247
230
  "aliases": [],
248
- "args": {
249
- "provider": {
250
- "description": "OAuth provider to disconnect",
251
- "name": "provider",
252
- "options": [
253
- "openai"
254
- ],
255
- "required": true
256
- }
257
- },
258
- "description": "Disconnect a linked OAuth provider account",
259
- "examples": [
260
- "<%= config.bin %> auth disconnect openai"
261
- ],
231
+ "args": {},
232
+ "description": "List available LLMs and their per-token costs",
262
233
  "flags": {
263
234
  "json": {
264
235
  "description": "Format output as json.",
@@ -290,11 +261,18 @@
290
261
  "hasDynamicHelp": false,
291
262
  "multiple": false,
292
263
  "type": "option"
264
+ },
265
+ "provider": {
266
+ "description": "Filter by provider (e.g. openai, anthropic)",
267
+ "name": "provider",
268
+ "hasDynamicHelp": false,
269
+ "multiple": false,
270
+ "type": "option"
293
271
  }
294
272
  },
295
273
  "hasDynamicHelp": false,
296
274
  "hiddenAliases": [],
297
- "id": "auth:disconnect",
275
+ "id": "billing:llm-costs",
298
276
  "pluginAlias": "faces-cli",
299
277
  "pluginName": "faces-cli",
300
278
  "pluginType": "core",
@@ -304,14 +282,14 @@
304
282
  "relativePath": [
305
283
  "dist",
306
284
  "commands",
307
- "auth",
308
- "disconnect.js"
285
+ "billing",
286
+ "llm-costs.js"
309
287
  ]
310
288
  },
311
- "auth:login": {
289
+ "billing:topup": {
312
290
  "aliases": [],
313
291
  "args": {},
314
- "description": "Login and save JWT credentials",
292
+ "description": "Top up credit balance using saved payment method",
315
293
  "flags": {
316
294
  "json": {
317
295
  "description": "Format output as json.",
@@ -344,18 +322,17 @@
344
322
  "multiple": false,
345
323
  "type": "option"
346
324
  },
347
- "email": {
348
- "description": "Account email",
349
- "name": "email",
325
+ "amount": {
326
+ "description": "Top-up amount in USD (min $1)",
327
+ "name": "amount",
350
328
  "required": true,
351
329
  "hasDynamicHelp": false,
352
330
  "multiple": false,
353
331
  "type": "option"
354
332
  },
355
- "password": {
356
- "description": "Account password",
357
- "name": "password",
358
- "required": true,
333
+ "payment-ref": {
334
+ "description": "Payment reference (admin/test path)",
335
+ "name": "payment-ref",
359
336
  "hasDynamicHelp": false,
360
337
  "multiple": false,
361
338
  "type": "option"
@@ -363,7 +340,7 @@
363
340
  },
364
341
  "hasDynamicHelp": false,
365
342
  "hiddenAliases": [],
366
- "id": "auth:login",
343
+ "id": "billing:topup",
367
344
  "pluginAlias": "faces-cli",
368
345
  "pluginName": "faces-cli",
369
346
  "pluginType": "core",
@@ -373,14 +350,14 @@
373
350
  "relativePath": [
374
351
  "dist",
375
352
  "commands",
376
- "auth",
377
- "login.js"
353
+ "billing",
354
+ "topup.js"
378
355
  ]
379
356
  },
380
- "auth:logout": {
357
+ "billing:usage": {
381
358
  "aliases": [],
382
359
  "args": {},
383
- "description": "Clear saved credentials",
360
+ "description": "Aggregated usage analytics",
384
361
  "flags": {
385
362
  "json": {
386
363
  "description": "Format output as json.",
@@ -412,11 +389,38 @@
412
389
  "hasDynamicHelp": false,
413
390
  "multiple": false,
414
391
  "type": "option"
392
+ },
393
+ "group-by": {
394
+ "description": "Group results",
395
+ "name": "group-by",
396
+ "hasDynamicHelp": false,
397
+ "multiple": false,
398
+ "options": [
399
+ "api_key",
400
+ "model",
401
+ "llm",
402
+ "date"
403
+ ],
404
+ "type": "option"
405
+ },
406
+ "from": {
407
+ "description": "Start date (YYYY-MM-DD)",
408
+ "name": "from",
409
+ "hasDynamicHelp": false,
410
+ "multiple": false,
411
+ "type": "option"
412
+ },
413
+ "to": {
414
+ "description": "End date (YYYY-MM-DD)",
415
+ "name": "to",
416
+ "hasDynamicHelp": false,
417
+ "multiple": false,
418
+ "type": "option"
415
419
  }
416
420
  },
417
421
  "hasDynamicHelp": false,
418
422
  "hiddenAliases": [],
419
- "id": "auth:logout",
423
+ "id": "billing:usage",
420
424
  "pluginAlias": "faces-cli",
421
425
  "pluginName": "faces-cli",
422
426
  "pluginType": "core",
@@ -426,14 +430,27 @@
426
430
  "relativePath": [
427
431
  "dist",
428
432
  "commands",
429
- "auth",
430
- "logout.js"
433
+ "billing",
434
+ "usage.js"
431
435
  ]
432
436
  },
433
- "auth:refresh": {
437
+ "auth:connect": {
434
438
  "aliases": [],
435
- "args": {},
436
- "description": "Exchange current JWT for a fresh one",
439
+ "args": {
440
+ "provider": {
441
+ "description": "OAuth provider to connect",
442
+ "name": "provider",
443
+ "options": [
444
+ "openai"
445
+ ],
446
+ "required": true
447
+ }
448
+ },
449
+ "description": "Connect your ChatGPT account to Faces via device-code authorization (Subscription Connect plan)",
450
+ "examples": [
451
+ "<%= config.bin %> auth connect openai",
452
+ "<%= config.bin %> auth connect openai --json"
453
+ ],
437
454
  "flags": {
438
455
  "json": {
439
456
  "description": "Format output as json.",
@@ -469,7 +486,7 @@
469
486
  },
470
487
  "hasDynamicHelp": false,
471
488
  "hiddenAliases": [],
472
- "id": "auth:refresh",
489
+ "id": "auth:connect",
473
490
  "pluginAlias": "faces-cli",
474
491
  "pluginName": "faces-cli",
475
492
  "pluginType": "core",
@@ -480,13 +497,17 @@
480
497
  "dist",
481
498
  "commands",
482
499
  "auth",
483
- "refresh.js"
500
+ "connect.js"
484
501
  ]
485
502
  },
486
- "auth:register": {
503
+ "auth:connections": {
487
504
  "aliases": [],
488
505
  "args": {},
489
- "description": "Create a new Faces account",
506
+ "description": "List connected OAuth provider accounts",
507
+ "examples": [
508
+ "<%= config.bin %> auth connections",
509
+ "<%= config.bin %> auth connections --json"
510
+ ],
490
511
  "flags": {
491
512
  "json": {
492
513
  "description": "Format output as json.",
@@ -518,54 +539,11 @@
518
539
  "hasDynamicHelp": false,
519
540
  "multiple": false,
520
541
  "type": "option"
521
- },
522
- "email": {
523
- "description": "Email address",
524
- "name": "email",
525
- "required": true,
526
- "hasDynamicHelp": false,
527
- "multiple": false,
528
- "type": "option"
529
- },
530
- "password": {
531
- "description": "Password",
532
- "name": "password",
533
- "required": true,
534
- "hasDynamicHelp": false,
535
- "multiple": false,
536
- "type": "option"
537
- },
538
- "username": {
539
- "description": "Username (lowercase, dashes, numbers)",
540
- "name": "username",
541
- "required": true,
542
- "hasDynamicHelp": false,
543
- "multiple": false,
544
- "type": "option"
545
- },
546
- "invite-key": {
547
- "description": "Invite key (if required)",
548
- "name": "invite-key",
549
- "hasDynamicHelp": false,
550
- "multiple": false,
551
- "type": "option"
552
- },
553
- "plan": {
554
- "description": "Plan to subscribe to: \"free\" ($5 activation) or \"connect\" ($17/mo, no activation fee)",
555
- "name": "plan",
556
- "default": "free",
557
- "hasDynamicHelp": false,
558
- "multiple": false,
559
- "options": [
560
- "free",
561
- "connect"
562
- ],
563
- "type": "option"
564
542
  }
565
543
  },
566
544
  "hasDynamicHelp": false,
567
545
  "hiddenAliases": [],
568
- "id": "auth:register",
546
+ "id": "auth:connections",
569
547
  "pluginAlias": "faces-cli",
570
548
  "pluginName": "faces-cli",
571
549
  "pluginType": "core",
@@ -576,13 +554,25 @@
576
554
  "dist",
577
555
  "commands",
578
556
  "auth",
579
- "register.js"
557
+ "connections.js"
580
558
  ]
581
559
  },
582
- "auth:whoami": {
560
+ "auth:disconnect": {
583
561
  "aliases": [],
584
- "args": {},
585
- "description": "Print current user profile and auth diagnostic",
562
+ "args": {
563
+ "provider": {
564
+ "description": "OAuth provider to disconnect",
565
+ "name": "provider",
566
+ "options": [
567
+ "openai"
568
+ ],
569
+ "required": true
570
+ }
571
+ },
572
+ "description": "Disconnect a linked OAuth provider account",
573
+ "examples": [
574
+ "<%= config.bin %> auth disconnect openai"
575
+ ],
586
576
  "flags": {
587
577
  "json": {
588
578
  "description": "Format output as json.",
@@ -618,7 +608,7 @@
618
608
  },
619
609
  "hasDynamicHelp": false,
620
610
  "hiddenAliases": [],
621
- "id": "auth:whoami",
611
+ "id": "auth:disconnect",
622
612
  "pluginAlias": "faces-cli",
623
613
  "pluginName": "faces-cli",
624
614
  "pluginType": "core",
@@ -629,13 +619,13 @@
629
619
  "dist",
630
620
  "commands",
631
621
  "auth",
632
- "whoami.js"
622
+ "disconnect.js"
633
623
  ]
634
624
  },
635
- "billing:balance": {
625
+ "auth:login": {
636
626
  "aliases": [],
637
627
  "args": {},
638
- "description": "Show credit balance and payment method status",
628
+ "description": "Login and save JWT credentials",
639
629
  "flags": {
640
630
  "json": {
641
631
  "description": "Format output as json.",
@@ -667,11 +657,27 @@
667
657
  "hasDynamicHelp": false,
668
658
  "multiple": false,
669
659
  "type": "option"
660
+ },
661
+ "email": {
662
+ "description": "Account email",
663
+ "name": "email",
664
+ "required": true,
665
+ "hasDynamicHelp": false,
666
+ "multiple": false,
667
+ "type": "option"
668
+ },
669
+ "password": {
670
+ "description": "Account password",
671
+ "name": "password",
672
+ "required": true,
673
+ "hasDynamicHelp": false,
674
+ "multiple": false,
675
+ "type": "option"
670
676
  }
671
677
  },
672
678
  "hasDynamicHelp": false,
673
679
  "hiddenAliases": [],
674
- "id": "billing:balance",
680
+ "id": "auth:login",
675
681
  "pluginAlias": "faces-cli",
676
682
  "pluginName": "faces-cli",
677
683
  "pluginType": "core",
@@ -681,14 +687,14 @@
681
687
  "relativePath": [
682
688
  "dist",
683
689
  "commands",
684
- "billing",
685
- "balance.js"
690
+ "auth",
691
+ "login.js"
686
692
  ]
687
693
  },
688
- "billing:card-setup": {
694
+ "auth:logout": {
689
695
  "aliases": [],
690
696
  "args": {},
691
- "description": "Get a Stripe card setup URL to save a payment method",
697
+ "description": "Clear saved credentials",
692
698
  "flags": {
693
699
  "json": {
694
700
  "description": "Format output as json.",
@@ -724,7 +730,7 @@
724
730
  },
725
731
  "hasDynamicHelp": false,
726
732
  "hiddenAliases": [],
727
- "id": "billing:card-setup",
733
+ "id": "auth:logout",
728
734
  "pluginAlias": "faces-cli",
729
735
  "pluginName": "faces-cli",
730
736
  "pluginType": "core",
@@ -734,14 +740,14 @@
734
740
  "relativePath": [
735
741
  "dist",
736
742
  "commands",
737
- "billing",
738
- "card-setup.js"
743
+ "auth",
744
+ "logout.js"
739
745
  ]
740
746
  },
741
- "billing:llm-costs": {
747
+ "auth:refresh": {
742
748
  "aliases": [],
743
749
  "args": {},
744
- "description": "List available LLMs and their per-token costs",
750
+ "description": "Exchange current JWT for a fresh one",
745
751
  "flags": {
746
752
  "json": {
747
753
  "description": "Format output as json.",
@@ -773,18 +779,11 @@
773
779
  "hasDynamicHelp": false,
774
780
  "multiple": false,
775
781
  "type": "option"
776
- },
777
- "provider": {
778
- "description": "Filter by provider (e.g. openai, anthropic)",
779
- "name": "provider",
780
- "hasDynamicHelp": false,
781
- "multiple": false,
782
- "type": "option"
783
782
  }
784
783
  },
785
784
  "hasDynamicHelp": false,
786
785
  "hiddenAliases": [],
787
- "id": "billing:llm-costs",
786
+ "id": "auth:refresh",
788
787
  "pluginAlias": "faces-cli",
789
788
  "pluginName": "faces-cli",
790
789
  "pluginType": "core",
@@ -794,14 +793,14 @@
794
793
  "relativePath": [
795
794
  "dist",
796
795
  "commands",
797
- "billing",
798
- "llm-costs.js"
796
+ "auth",
797
+ "refresh.js"
799
798
  ]
800
799
  },
801
- "billing:topup": {
800
+ "auth:register": {
802
801
  "aliases": [],
803
802
  "args": {},
804
- "description": "Top up credit balance using saved payment method",
803
+ "description": "Create a new Faces account",
805
804
  "flags": {
806
805
  "json": {
807
806
  "description": "Format output as json.",
@@ -834,25 +833,53 @@
834
833
  "multiple": false,
835
834
  "type": "option"
836
835
  },
837
- "amount": {
838
- "description": "Top-up amount in USD (min $1)",
839
- "name": "amount",
836
+ "email": {
837
+ "description": "Email address",
838
+ "name": "email",
840
839
  "required": true,
841
840
  "hasDynamicHelp": false,
842
841
  "multiple": false,
843
842
  "type": "option"
844
843
  },
845
- "payment-ref": {
846
- "description": "Payment reference (admin/test path)",
847
- "name": "payment-ref",
844
+ "password": {
845
+ "description": "Password",
846
+ "name": "password",
847
+ "required": true,
848
+ "hasDynamicHelp": false,
849
+ "multiple": false,
850
+ "type": "option"
851
+ },
852
+ "username": {
853
+ "description": "Username (lowercase, dashes, numbers)",
854
+ "name": "username",
855
+ "required": true,
856
+ "hasDynamicHelp": false,
857
+ "multiple": false,
858
+ "type": "option"
859
+ },
860
+ "invite-key": {
861
+ "description": "Invite key (if required)",
862
+ "name": "invite-key",
863
+ "hasDynamicHelp": false,
864
+ "multiple": false,
865
+ "type": "option"
866
+ },
867
+ "plan": {
868
+ "description": "Plan to subscribe to: \"free\" ($5 activation) or \"connect\" ($17/mo, no activation fee)",
869
+ "name": "plan",
870
+ "default": "free",
848
871
  "hasDynamicHelp": false,
849
872
  "multiple": false,
873
+ "options": [
874
+ "free",
875
+ "connect"
876
+ ],
850
877
  "type": "option"
851
878
  }
852
879
  },
853
880
  "hasDynamicHelp": false,
854
881
  "hiddenAliases": [],
855
- "id": "billing:topup",
882
+ "id": "auth:register",
856
883
  "pluginAlias": "faces-cli",
857
884
  "pluginName": "faces-cli",
858
885
  "pluginType": "core",
@@ -862,14 +889,14 @@
862
889
  "relativePath": [
863
890
  "dist",
864
891
  "commands",
865
- "billing",
866
- "topup.js"
892
+ "auth",
893
+ "register.js"
867
894
  ]
868
895
  },
869
- "billing:usage": {
896
+ "auth:whoami": {
870
897
  "aliases": [],
871
898
  "args": {},
872
- "description": "Aggregated usage analytics",
899
+ "description": "Print current user profile and auth diagnostic",
873
900
  "flags": {
874
901
  "json": {
875
902
  "description": "Format output as json.",
@@ -901,38 +928,11 @@
901
928
  "hasDynamicHelp": false,
902
929
  "multiple": false,
903
930
  "type": "option"
904
- },
905
- "group-by": {
906
- "description": "Group results",
907
- "name": "group-by",
908
- "hasDynamicHelp": false,
909
- "multiple": false,
910
- "options": [
911
- "api_key",
912
- "model",
913
- "llm",
914
- "date"
915
- ],
916
- "type": "option"
917
- },
918
- "from": {
919
- "description": "Start date (YYYY-MM-DD)",
920
- "name": "from",
921
- "hasDynamicHelp": false,
922
- "multiple": false,
923
- "type": "option"
924
- },
925
- "to": {
926
- "description": "End date (YYYY-MM-DD)",
927
- "name": "to",
928
- "hasDynamicHelp": false,
929
- "multiple": false,
930
- "type": "option"
931
931
  }
932
932
  },
933
933
  "hasDynamicHelp": false,
934
934
  "hiddenAliases": [],
935
- "id": "billing:usage",
935
+ "id": "auth:whoami",
936
936
  "pluginAlias": "faces-cli",
937
937
  "pluginName": "faces-cli",
938
938
  "pluginType": "core",
@@ -942,8 +942,8 @@
942
942
  "relativePath": [
943
943
  "dist",
944
944
  "commands",
945
- "billing",
946
- "usage.js"
945
+ "auth",
946
+ "whoami.js"
947
947
  ]
948
948
  },
949
949
  "catalog:backup": {
@@ -1372,7 +1372,7 @@
1372
1372
  "type": "boolean"
1373
1373
  },
1374
1374
  "medium": {
1375
- "description": "What sort of writing this is — e.g. email, text message, social post, essay, academic paper, blog post, legal document, thread reply, conversation (covers speech: transcripts, interviews, calls). Common synonyms fold automatically. Omit it if you do not know: a wrong declaration is worse than none, because a declaration is trusted and an absence is not.",
1375
+ "description": "What sort of writing this is — e.g. email, text message, social post, essay, academic paper, blog post, legal document, thread reply, conversation (dialogue: transcripts, interviews, calls), lecture (sustained speech nobody interrupts: talks, sermons, keynotes). Common synonyms fold automatically. Omit it if you do not know: a wrong declaration is worse than none, because a declaration is trusted and an absence is not.",
1376
1376
  "name": "medium",
1377
1377
  "hasDynamicHelp": false,
1378
1378
  "multiple": false,
@@ -1474,7 +1474,7 @@
1474
1474
  "type": "option"
1475
1475
  },
1476
1476
  "medium": {
1477
- "description": "What sort of writing this is — e.g. email, text message, social post, essay, academic paper, blog post, legal document, thread reply, conversation (covers speech: transcripts, interviews, calls). Common synonyms fold automatically. Omit it if you do not know: a wrong declaration is worse than none, because a declaration is trusted and an absence is not.",
1477
+ "description": "What sort of writing this is — e.g. email, text message, social post, essay, academic paper, blog post, legal document, thread reply, conversation (dialogue: transcripts, interviews, calls), lecture (sustained speech nobody interrupts: talks, sermons, keynotes). Common synonyms fold automatically. Omit it if you do not know: a wrong declaration is worse than none, because a declaration is trusted and an absence is not.",
1478
1478
  "name": "medium",
1479
1479
  "hasDynamicHelp": false,
1480
1480
  "multiple": false,
@@ -1568,7 +1568,7 @@
1568
1568
  "type": "boolean"
1569
1569
  },
1570
1570
  "medium": {
1571
- "description": "What sort of writing this is — e.g. email, text message, social post, essay, academic paper, blog post, legal document, thread reply, conversation (covers speech: transcripts, interviews, calls). Common synonyms fold automatically. Omit it if you do not know: a wrong declaration is worse than none, because a declaration is trusted and an absence is not.",
1571
+ "description": "What sort of writing this is — e.g. email, text message, social post, essay, academic paper, blog post, legal document, thread reply, conversation (dialogue: transcripts, interviews, calls), lecture (sustained speech nobody interrupts: talks, sermons, keynotes). Common synonyms fold automatically. Omit it if you do not know: a wrong declaration is worse than none, because a declaration is trusted and an absence is not.",
1572
1572
  "name": "medium",
1573
1573
  "hasDynamicHelp": false,
1574
1574
  "multiple": false,
@@ -1703,7 +1703,7 @@
1703
1703
  "type": "boolean"
1704
1704
  },
1705
1705
  "medium": {
1706
- "description": "What sort of writing this is — e.g. email, text message, social post, essay, academic paper, blog post, legal document, thread reply, conversation (covers speech: transcripts, interviews, calls). Common synonyms fold automatically. Omit it if you do not know: a wrong declaration is worse than none, because a declaration is trusted and an absence is not.",
1706
+ "description": "What sort of writing this is — e.g. email, text message, social post, essay, academic paper, blog post, legal document, thread reply, conversation (dialogue: transcripts, interviews, calls), lecture (sustained speech nobody interrupts: talks, sermons, keynotes). Common synonyms fold automatically. Omit it if you do not know: a wrong declaration is worse than none, because a declaration is trusted and an absence is not.",
1707
1707
  "name": "medium",
1708
1708
  "hasDynamicHelp": false,
1709
1709
  "multiple": false,
@@ -2043,7 +2043,7 @@
2043
2043
  "type": "option"
2044
2044
  },
2045
2045
  "medium": {
2046
- "description": "What sort of writing this is — e.g. email, text message, social post, essay, academic paper, blog post, legal document, thread reply, conversation (covers speech: transcripts, interviews, calls). Common synonyms fold automatically. Omit it if you do not know: a wrong declaration is worse than none, because a declaration is trusted and an absence is not. Only valid with --kind document.",
2046
+ "description": "What sort of writing this is — e.g. email, text message, social post, essay, academic paper, blog post, legal document, thread reply, conversation (dialogue: transcripts, interviews, calls), lecture (sustained speech nobody interrupts: talks, sermons, keynotes). Common synonyms fold automatically. Omit it if you do not know: a wrong declaration is worse than none, because a declaration is trusted and an absence is not. Only valid with --kind document.",
2047
2047
  "name": "medium",
2048
2048
  "hasDynamicHelp": false,
2049
2049
  "multiple": false,
@@ -2255,63 +2255,10 @@
2255
2255
  "show.js"
2256
2256
  ]
2257
2257
  },
2258
- "face:attributes": {
2259
- "aliases": [],
2260
- "args": {},
2261
- "description": "List all supported attribute keys",
2262
- "flags": {
2263
- "json": {
2264
- "description": "Format output as json.",
2265
- "helpGroup": "GLOBAL",
2266
- "name": "json",
2267
- "allowNo": false,
2268
- "type": "boolean"
2269
- },
2270
- "base-url": {
2271
- "description": "API base URL",
2272
- "env": "FACES_BASE_URL",
2273
- "name": "base-url",
2274
- "hasDynamicHelp": false,
2275
- "multiple": false,
2276
- "type": "option"
2277
- },
2278
- "token": {
2279
- "description": "JWT bearer token",
2280
- "env": "FACES_TOKEN",
2281
- "name": "token",
2282
- "hasDynamicHelp": false,
2283
- "multiple": false,
2284
- "type": "option"
2285
- },
2286
- "api-key": {
2287
- "description": "API key",
2288
- "env": "FACES_API_KEY",
2289
- "name": "api-key",
2290
- "hasDynamicHelp": false,
2291
- "multiple": false,
2292
- "type": "option"
2293
- }
2294
- },
2295
- "hasDynamicHelp": false,
2296
- "hiddenAliases": [],
2297
- "id": "face:attributes",
2298
- "pluginAlias": "faces-cli",
2299
- "pluginName": "faces-cli",
2300
- "pluginType": "core",
2301
- "strict": true,
2302
- "enableJsonFlag": true,
2303
- "isESM": true,
2304
- "relativePath": [
2305
- "dist",
2306
- "commands",
2307
- "face",
2308
- "attributes.js"
2309
- ]
2310
- },
2311
- "face:create": {
2258
+ "keys:create": {
2312
2259
  "aliases": [],
2313
2260
  "args": {},
2314
- "description": "Create a new face",
2261
+ "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.",
2315
2262
  "flags": {
2316
2263
  "json": {
2317
2264
  "description": "Format output as json.",
@@ -2345,84 +2292,51 @@
2345
2292
  "type": "option"
2346
2293
  },
2347
2294
  "name": {
2348
- "description": "Display name",
2295
+ "description": "Key name/label",
2349
2296
  "name": "name",
2350
2297
  "required": true,
2351
2298
  "hasDynamicHelp": false,
2352
2299
  "multiple": false,
2353
2300
  "type": "option"
2354
2301
  },
2355
- "alias": {
2356
- "description": "Unique alias slug",
2357
- "name": "alias",
2358
- "required": true,
2359
- "hasDynamicHelp": false,
2360
- "multiple": false,
2361
- "type": "option"
2362
- },
2363
- "description": {
2364
- "description": "Plain-text description / bio (max 1500 chars)",
2365
- "name": "description",
2366
- "hasDynamicHelp": false,
2367
- "multiple": false,
2368
- "type": "option"
2369
- },
2370
- "tag": {
2371
- "description": "Tag label (repeatable, lowercase)",
2372
- "name": "tag",
2373
- "hasDynamicHelp": false,
2374
- "multiple": true,
2375
- "type": "option"
2376
- },
2377
- "default-model": {
2378
- "description": "Default LLM for chat (e.g. gpt-4o-mini, claude-sonnet-4-6)",
2379
- "name": "default-model",
2302
+ "expires-days": {
2303
+ "description": "Expiry in days (omit for no expiry)",
2304
+ "name": "expires-days",
2380
2305
  "hasDynamicHelp": false,
2381
2306
  "multiple": false,
2382
2307
  "type": "option"
2383
2308
  },
2384
- "formula": {
2385
- "description": "Boolean formula over owned concrete face aliases (e.g. \"a | b\", \"(a | b) - c\"). Creates a composite face.",
2386
- "name": "formula",
2309
+ "budget": {
2310
+ "description": "Spend budget in USD",
2311
+ "name": "budget",
2387
2312
  "hasDynamicHelp": false,
2388
2313
  "multiple": false,
2389
2314
  "type": "option"
2390
2315
  },
2391
- "attr": {
2392
- "description": "Attribute KEY=VALUE (repeatable)",
2393
- "name": "attr",
2316
+ "face": {
2317
+ "description": "Allowed face alias (repeatable)",
2318
+ "name": "face",
2394
2319
  "hasDynamicHelp": false,
2395
2320
  "multiple": true,
2396
2321
  "type": "option"
2397
2322
  },
2398
- "tool": {
2399
- "description": "Tool name to enable (repeatable)",
2400
- "name": "tool",
2323
+ "model": {
2324
+ "description": "Allowed model name (repeatable)",
2325
+ "name": "model",
2401
2326
  "hasDynamicHelp": false,
2402
2327
  "multiple": true,
2403
2328
  "type": "option"
2404
2329
  },
2405
- "profile-addendum": {
2406
- "description": "Per-face system prompt, injected after the persona profile and before any per-request system prompt (max 100,000 chars).",
2407
- "name": "profile-addendum",
2408
- "hasDynamicHelp": false,
2409
- "multiple": false,
2410
- "type": "option"
2411
- },
2412
- "profile-addendum-file": {
2413
- "description": "Read the per-face system prompt from a file (alternative to --profile-addendum).",
2414
- "exclusive": [
2415
- "profile-addendum"
2416
- ],
2417
- "name": "profile-addendum-file",
2418
- "hasDynamicHelp": false,
2419
- "multiple": false,
2420
- "type": "option"
2330
+ "save": {
2331
+ "description": "Save the new key to ~/.faces/config.json as api_key (default: true; use --no-save to skip)",
2332
+ "name": "save",
2333
+ "allowNo": true,
2334
+ "type": "boolean"
2421
2335
  }
2422
2336
  },
2423
2337
  "hasDynamicHelp": false,
2424
2338
  "hiddenAliases": [],
2425
- "id": "face:create",
2339
+ "id": "keys:create",
2426
2340
  "pluginAlias": "faces-cli",
2427
2341
  "pluginName": "faces-cli",
2428
2342
  "pluginType": "core",
@@ -2432,20 +2346,14 @@
2432
2346
  "relativePath": [
2433
2347
  "dist",
2434
2348
  "commands",
2435
- "face",
2349
+ "keys",
2436
2350
  "create.js"
2437
2351
  ]
2438
2352
  },
2439
- "face:delete": {
2353
+ "keys:list": {
2440
2354
  "aliases": [],
2441
- "args": {
2442
- "face_id": {
2443
- "description": "Face alias",
2444
- "name": "face_id",
2445
- "required": true
2446
- }
2447
- },
2448
- "description": "Delete a face permanently",
2355
+ "args": {},
2356
+ "description": "List all API keys (JWT required)",
2449
2357
  "flags": {
2450
2358
  "json": {
2451
2359
  "description": "Format output as json.",
@@ -2477,17 +2385,11 @@
2477
2385
  "hasDynamicHelp": false,
2478
2386
  "multiple": false,
2479
2387
  "type": "option"
2480
- },
2481
- "yes": {
2482
- "description": "Skip confirmation",
2483
- "name": "yes",
2484
- "allowNo": false,
2485
- "type": "boolean"
2486
2388
  }
2487
2389
  },
2488
2390
  "hasDynamicHelp": false,
2489
2391
  "hiddenAliases": [],
2490
- "id": "face:delete",
2392
+ "id": "keys:list",
2491
2393
  "pluginAlias": "faces-cli",
2492
2394
  "pluginName": "faces-cli",
2493
2395
  "pluginType": "core",
@@ -2497,14 +2399,20 @@
2497
2399
  "relativePath": [
2498
2400
  "dist",
2499
2401
  "commands",
2500
- "face",
2501
- "delete.js"
2402
+ "keys",
2403
+ "list.js"
2502
2404
  ]
2503
2405
  },
2504
- "face:diff": {
2406
+ "keys:revoke": {
2505
2407
  "aliases": [],
2506
- "args": {},
2507
- "description": "Compare owned faces pairwise across all centroid components",
2408
+ "args": {
2409
+ "key_id": {
2410
+ "description": "Key ID",
2411
+ "name": "key_id",
2412
+ "required": true
2413
+ }
2414
+ },
2415
+ "description": "Revoke an API key (JWT required)",
2508
2416
  "flags": {
2509
2417
  "json": {
2510
2418
  "description": "Format output as json.",
@@ -2537,18 +2445,16 @@
2537
2445
  "multiple": false,
2538
2446
  "type": "option"
2539
2447
  },
2540
- "face": {
2541
- "description": "Face alias to include (repeatable, min 2)",
2542
- "name": "face",
2543
- "required": true,
2544
- "hasDynamicHelp": false,
2545
- "multiple": true,
2546
- "type": "option"
2448
+ "yes": {
2449
+ "description": "Skip confirmation",
2450
+ "name": "yes",
2451
+ "allowNo": false,
2452
+ "type": "boolean"
2547
2453
  }
2548
2454
  },
2549
2455
  "hasDynamicHelp": false,
2550
2456
  "hiddenAliases": [],
2551
- "id": "face:diff",
2457
+ "id": "keys:revoke",
2552
2458
  "pluginAlias": "faces-cli",
2553
2459
  "pluginName": "faces-cli",
2554
2460
  "pluginType": "core",
@@ -2558,20 +2464,20 @@
2558
2464
  "relativePath": [
2559
2465
  "dist",
2560
2466
  "commands",
2561
- "face",
2562
- "diff.js"
2467
+ "keys",
2468
+ "revoke.js"
2563
2469
  ]
2564
2470
  },
2565
- "face:edit": {
2471
+ "keys:update": {
2566
2472
  "aliases": [],
2567
2473
  "args": {
2568
- "face_id": {
2569
- "description": "Face alias",
2570
- "name": "face_id",
2474
+ "key_id": {
2475
+ "description": "Key ID",
2476
+ "name": "key_id",
2571
2477
  "required": true
2572
2478
  }
2573
2479
  },
2574
- "description": "Edit a face's metadata",
2480
+ "description": "Update API key metadata (JWT required)",
2575
2481
  "flags": {
2576
2482
  "json": {
2577
2483
  "description": "Format output as json.",
@@ -2605,85 +2511,29 @@
2605
2511
  "type": "option"
2606
2512
  },
2607
2513
  "name": {
2608
- "description": "New display name",
2514
+ "description": "New key name",
2609
2515
  "name": "name",
2610
2516
  "hasDynamicHelp": false,
2611
2517
  "multiple": false,
2612
2518
  "type": "option"
2613
2519
  },
2614
- "description": {
2615
- "description": "Plain-text description / bio (max 1500 chars)",
2616
- "name": "description",
2617
- "hasDynamicHelp": false,
2618
- "multiple": false,
2619
- "type": "option"
2620
- },
2621
- "tag": {
2622
- "description": "Replace all tags (repeatable, lowercase)",
2623
- "name": "tag",
2624
- "hasDynamicHelp": false,
2625
- "multiple": true,
2626
- "type": "option"
2627
- },
2628
- "default-model": {
2629
- "description": "Default LLM for chat (e.g. gpt-4o-mini, claude-sonnet-4-6)",
2630
- "name": "default-model",
2631
- "hasDynamicHelp": false,
2632
- "multiple": false,
2633
- "type": "option"
2634
- },
2635
- "formula": {
2636
- "description": "New boolean formula (synthetic faces only)",
2637
- "name": "formula",
2638
- "hasDynamicHelp": false,
2639
- "multiple": false,
2640
- "type": "option"
2641
- },
2642
- "attr": {
2643
- "description": "Update attribute KEY=VALUE (repeatable)",
2644
- "name": "attr",
2645
- "hasDynamicHelp": false,
2646
- "multiple": true,
2647
- "type": "option"
2648
- },
2649
- "tool": {
2650
- "description": "Tool names to set (replaces list, repeatable)",
2651
- "name": "tool",
2652
- "hasDynamicHelp": false,
2653
- "multiple": true,
2654
- "type": "option"
2655
- },
2656
- "profile-addendum": {
2657
- "description": "Replace the per-face system prompt (max 100,000 chars).",
2658
- "name": "profile-addendum",
2659
- "hasDynamicHelp": false,
2660
- "multiple": false,
2661
- "type": "option"
2662
- },
2663
- "profile-addendum-file": {
2664
- "description": "Replace the per-face system prompt from a file.",
2665
- "exclusive": [
2666
- "profile-addendum"
2667
- ],
2668
- "name": "profile-addendum-file",
2520
+ "budget": {
2521
+ "description": "New spend budget in USD",
2522
+ "name": "budget",
2669
2523
  "hasDynamicHelp": false,
2670
2524
  "multiple": false,
2671
2525
  "type": "option"
2672
2526
  },
2673
- "clear-profile-addendum": {
2674
- "description": "Remove the per-face system prompt.",
2675
- "exclusive": [
2676
- "profile-addendum",
2677
- "profile-addendum-file"
2678
- ],
2679
- "name": "clear-profile-addendum",
2527
+ "reset-spent": {
2528
+ "description": "Reset spent amount to zero",
2529
+ "name": "reset-spent",
2680
2530
  "allowNo": false,
2681
2531
  "type": "boolean"
2682
2532
  }
2683
2533
  },
2684
2534
  "hasDynamicHelp": false,
2685
2535
  "hiddenAliases": [],
2686
- "id": "face:edit",
2536
+ "id": "keys:update",
2687
2537
  "pluginAlias": "faces-cli",
2688
2538
  "pluginName": "faces-cli",
2689
2539
  "pluginType": "core",
@@ -2693,20 +2543,24 @@
2693
2543
  "relativePath": [
2694
2544
  "dist",
2695
2545
  "commands",
2696
- "face",
2697
- "edit.js"
2546
+ "keys",
2547
+ "update.js"
2698
2548
  ]
2699
2549
  },
2700
- "face:get": {
2550
+ "style:delete": {
2701
2551
  "aliases": [],
2702
2552
  "args": {
2703
- "face_id": {
2553
+ "alias": {
2704
2554
  "description": "Face alias",
2705
- "name": "face_id",
2555
+ "name": "alias",
2706
2556
  "required": true
2707
2557
  }
2708
2558
  },
2709
- "description": "Get details for a face by alias",
2559
+ "description": "Delete a face's captured style. The material it was learned from is kept, so the style can be captured again without re-uploading. This never deletes documents or threads: remove those with compile:doc:delete or compile:thread:delete.",
2560
+ "examples": [
2561
+ "<%= config.bin %> <%= command.id %> alice",
2562
+ "<%= config.bin %> <%= command.id %> alice --yes"
2563
+ ],
2710
2564
  "flags": {
2711
2565
  "json": {
2712
2566
  "description": "Format output as json.",
@@ -2739,23 +2593,16 @@
2739
2593
  "multiple": false,
2740
2594
  "type": "option"
2741
2595
  },
2742
- "include": {
2743
- "description": "Include extra fields: tags, teams (comma-separated)",
2744
- "name": "include",
2745
- "hasDynamicHelp": false,
2746
- "multiple": false,
2747
- "type": "option"
2748
- },
2749
- "full": {
2750
- "description": "Print the full profile_addendum instead of a truncated preview",
2751
- "name": "full",
2596
+ "yes": {
2597
+ "description": "Skip confirmation",
2598
+ "name": "yes",
2752
2599
  "allowNo": false,
2753
2600
  "type": "boolean"
2754
2601
  }
2755
2602
  },
2756
2603
  "hasDynamicHelp": false,
2757
2604
  "hiddenAliases": [],
2758
- "id": "face:get",
2605
+ "id": "style:delete",
2759
2606
  "pluginAlias": "faces-cli",
2760
2607
  "pluginName": "faces-cli",
2761
2608
  "pluginType": "core",
@@ -2765,14 +2612,26 @@
2765
2612
  "relativePath": [
2766
2613
  "dist",
2767
2614
  "commands",
2768
- "face",
2769
- "get.js"
2615
+ "style",
2616
+ "delete.js"
2770
2617
  ]
2771
2618
  },
2772
- "face:list": {
2619
+ "style:make": {
2773
2620
  "aliases": [],
2774
- "args": {},
2775
- "description": "List faces. By default lists owned faces; use --public to include published faces from other accounts.",
2621
+ "args": {
2622
+ "alias": {
2623
+ "description": "Face alias",
2624
+ "name": "alias",
2625
+ "required": true
2626
+ }
2627
+ },
2628
+ "description": "Capture how a face writes, from its own material, and install it. This is style, not knowledge: compile teaches a face what it knows, style teaches it how it sounds. Name the sources to learn from with --source, or take everything ready with --all.",
2629
+ "examples": [
2630
+ "<%= config.bin %> <%= command.id %> alice --all",
2631
+ "<%= config.bin %> <%= command.id %> alice --source 1a2b3c4d --source 5e6f7a8b",
2632
+ "<%= config.bin %> <%= command.id %> alice --source 1a2b3c4d:essay",
2633
+ "<%= config.bin %> <%= command.id %> alice --all --medium essay --no-wait"
2634
+ ],
2776
2635
  "flags": {
2777
2636
  "json": {
2778
2637
  "description": "Format output as json.",
@@ -2805,63 +2664,70 @@
2805
2664
  "multiple": false,
2806
2665
  "type": "option"
2807
2666
  },
2808
- "tag": {
2809
- "description": "Filter by tag (repeatable, AND logic)",
2810
- "name": "tag",
2667
+ "source": {
2668
+ "description": "A document or thread to learn from, by id (repeatable). Append :<medium> to declare what it is, e.g. --source 1a2b3c4d:essay, when the source does not already say.",
2669
+ "name": "source",
2811
2670
  "hasDynamicHelp": false,
2812
2671
  "multiple": true,
2813
2672
  "type": "option"
2814
2673
  },
2815
- "team": {
2816
- "description": "Filter by team ID (repeatable, OR logic)",
2817
- "name": "team",
2674
+ "all": {
2675
+ "description": "Use every source on the face that is ready. Anything skipped is listed.",
2676
+ "name": "all",
2677
+ "allowNo": false,
2678
+ "type": "boolean"
2679
+ },
2680
+ "medium": {
2681
+ "description": "Medium for selected sources that do not already declare one. It does not override a source that does. Each medium is analysed on its own, so an essay never teaches a rule about email.",
2682
+ "name": "medium",
2818
2683
  "hasDynamicHelp": false,
2819
- "multiple": true,
2684
+ "multiple": false,
2820
2685
  "type": "option"
2821
2686
  },
2822
- "include": {
2823
- "description": "Include extra fields: tags, teams (comma-separated)",
2824
- "name": "include",
2687
+ "model": {
2688
+ "description": "Analyst model (default: gpt-5.6-terra)",
2689
+ "name": "model",
2825
2690
  "hasDynamicHelp": false,
2826
2691
  "multiple": false,
2827
2692
  "type": "option"
2828
2693
  },
2829
- "public": {
2830
- "description": "Include published faces from other accounts (open to everybody)",
2831
- "name": "public",
2832
- "allowNo": false,
2833
- "type": "boolean"
2834
- },
2835
- "shared": {
2836
- "description": "Include faces other accounts have shared with YOU in particular",
2837
- "name": "shared",
2694
+ "allow-paid": {
2695
+ "description": "Permit a build that bills. Without this a build is free or it does not run. Needed for any model outside the free tier, and to allow the paid route when a free quota is exhausted.",
2696
+ "name": "allow-paid",
2838
2697
  "allowNo": false,
2839
2698
  "type": "boolean"
2840
2699
  },
2841
- "system": {
2842
- "description": "Show only the curated system faces (published faces owned by 'head')",
2843
- "name": "system",
2844
- "allowNo": false,
2700
+ "compile": {
2701
+ "description": "Compile any named source that is not compiled yet, before capturing style. On by default. --no-compile captures style from what is already compiled and never bills for compilation.",
2702
+ "name": "compile",
2703
+ "allowNo": true,
2845
2704
  "type": "boolean"
2846
2705
  },
2847
- "from-users": {
2848
- "description": "Only published faces from these owners (repeatable/comma-separated)",
2849
- "name": "from-users",
2706
+ "best-of": {
2707
+ "description": "Generate N candidates and keep the best (1-5, default 1)",
2708
+ "name": "best-of",
2850
2709
  "hasDynamicHelp": false,
2851
- "multiple": true,
2710
+ "multiple": false,
2852
2711
  "type": "option"
2853
2712
  },
2854
- "not-from-users": {
2855
- "description": "Exclude published faces from these owners (repeatable/comma-separated)",
2856
- "name": "not-from-users",
2713
+ "no-wait": {
2714
+ "description": "Start the build and return the job id without polling.",
2715
+ "name": "no-wait",
2716
+ "allowNo": false,
2717
+ "type": "boolean"
2718
+ },
2719
+ "timeout": {
2720
+ "description": "How long to wait, in seconds (default: 3600)",
2721
+ "name": "timeout",
2722
+ "default": 3600,
2857
2723
  "hasDynamicHelp": false,
2858
- "multiple": true,
2724
+ "multiple": false,
2859
2725
  "type": "option"
2860
2726
  }
2861
2727
  },
2862
2728
  "hasDynamicHelp": false,
2863
2729
  "hiddenAliases": [],
2864
- "id": "face:list",
2730
+ "id": "style:make",
2865
2731
  "pluginAlias": "faces-cli",
2866
2732
  "pluginName": "faces-cli",
2867
2733
  "pluginType": "core",
@@ -2871,22 +2737,23 @@
2871
2737
  "relativePath": [
2872
2738
  "dist",
2873
2739
  "commands",
2874
- "face",
2875
- "list.js"
2740
+ "style",
2741
+ "make.js"
2876
2742
  ]
2877
2743
  },
2878
- "face:lock": {
2744
+ "style:revert": {
2879
2745
  "aliases": [],
2880
2746
  "args": {
2881
- "face_id": {
2747
+ "alias": {
2882
2748
  "description": "Face alias",
2883
- "name": "face_id",
2749
+ "name": "alias",
2884
2750
  "required": true
2885
2751
  }
2886
2752
  },
2887
- "description": "Lock a face (read-only). A locked face still reads and chats normally, but it and everything it owns (documents, threads, voiceprint) cannot be changed until unlocked.",
2753
+ "description": "Go back to the style a face had before the last style:make. A face holds one style per medium, so name which one with --medium when it has more than one. Two versions are kept per medium, so this goes back exactly one step. It changes how the face writes immediately, so it asks first.",
2888
2754
  "examples": [
2889
- "<%= config.bin %> <%= command.id %> socrates"
2755
+ "<%= config.bin %> <%= command.id %> alice --yes",
2756
+ "<%= config.bin %> <%= command.id %> alice --medium email --yes"
2890
2757
  ],
2891
2758
  "flags": {
2892
2759
  "json": {
@@ -2919,11 +2786,24 @@
2919
2786
  "hasDynamicHelp": false,
2920
2787
  "multiple": false,
2921
2788
  "type": "option"
2789
+ },
2790
+ "medium": {
2791
+ "description": "Which style to step back, when the face has more than one. See faces style:versions <alias>.",
2792
+ "name": "medium",
2793
+ "hasDynamicHelp": false,
2794
+ "multiple": false,
2795
+ "type": "option"
2796
+ },
2797
+ "yes": {
2798
+ "description": "Skip confirmation",
2799
+ "name": "yes",
2800
+ "allowNo": false,
2801
+ "type": "boolean"
2922
2802
  }
2923
2803
  },
2924
2804
  "hasDynamicHelp": false,
2925
2805
  "hiddenAliases": [],
2926
- "id": "face:lock",
2806
+ "id": "style:revert",
2927
2807
  "pluginAlias": "faces-cli",
2928
2808
  "pluginName": "faces-cli",
2929
2809
  "pluginType": "core",
@@ -2933,20 +2813,25 @@
2933
2813
  "relativePath": [
2934
2814
  "dist",
2935
2815
  "commands",
2936
- "face",
2937
- "lock.js"
2816
+ "style",
2817
+ "revert.js"
2938
2818
  ]
2939
2819
  },
2940
- "face:neighbors": {
2820
+ "style:status": {
2941
2821
  "aliases": [],
2942
2822
  "args": {
2943
- "face_id": {
2944
- "description": "Face alias",
2945
- "name": "face_id",
2946
- "required": true
2823
+ "job_id": {
2824
+ "description": "Build job id",
2825
+ "name": "job_id",
2826
+ "required": false
2947
2827
  }
2948
2828
  },
2949
- "description": "Find the most similar or dissimilar owned faces to a given face",
2829
+ "description": "Read a style build. Give a job id for one build, or --face to list a face's recent builds. Listing is how you find a job id you no longer have.",
2830
+ "examples": [
2831
+ "<%= config.bin %> <%= command.id %> 7a8b9c0d",
2832
+ "<%= config.bin %> <%= command.id %> --face alice",
2833
+ "<%= config.bin %> <%= command.id %> 7a8b9c0d --wait"
2834
+ ],
2950
2835
  "flags": {
2951
2836
  "json": {
2952
2837
  "description": "Format output as json.",
@@ -2979,38 +2864,39 @@
2979
2864
  "multiple": false,
2980
2865
  "type": "option"
2981
2866
  },
2982
- "k": {
2983
- "description": "Number of results (1–20)",
2984
- "name": "k",
2985
- "default": 5,
2867
+ "face": {
2868
+ "description": "List recent builds for this face instead of reading one job",
2869
+ "name": "face",
2986
2870
  "hasDynamicHelp": false,
2987
2871
  "multiple": false,
2988
2872
  "type": "option"
2989
2873
  },
2990
- "component": {
2991
- "description": "What to rank on: `face` for overall similarity, or a component position such as 1. Which positions are comparable varies; the API names them if you pick a wrong one.",
2992
- "name": "component",
2993
- "default": "face",
2874
+ "limit": {
2875
+ "description": "How many builds to list with --face (default: 10)",
2876
+ "name": "limit",
2877
+ "default": 10,
2994
2878
  "hasDynamicHelp": false,
2995
2879
  "multiple": false,
2996
2880
  "type": "option"
2997
2881
  },
2998
- "direction": {
2999
- "description": "nearest (most similar) or furthest (most dissimilar)",
3000
- "name": "direction",
3001
- "default": "nearest",
2882
+ "wait": {
2883
+ "description": "Block until the job finishes",
2884
+ "name": "wait",
2885
+ "allowNo": false,
2886
+ "type": "boolean"
2887
+ },
2888
+ "timeout": {
2889
+ "description": "How long to wait with --wait, in seconds (default: 3600)",
2890
+ "name": "timeout",
2891
+ "default": 3600,
3002
2892
  "hasDynamicHelp": false,
3003
2893
  "multiple": false,
3004
- "options": [
3005
- "nearest",
3006
- "furthest"
3007
- ],
3008
2894
  "type": "option"
3009
2895
  }
3010
2896
  },
3011
2897
  "hasDynamicHelp": false,
3012
2898
  "hiddenAliases": [],
3013
- "id": "face:neighbors",
2899
+ "id": "style:status",
3014
2900
  "pluginAlias": "faces-cli",
3015
2901
  "pluginName": "faces-cli",
3016
2902
  "pluginType": "core",
@@ -3020,22 +2906,29 @@
3020
2906
  "relativePath": [
3021
2907
  "dist",
3022
2908
  "commands",
3023
- "face",
3024
- "neighbors.js"
2909
+ "style",
2910
+ "status.js"
3025
2911
  ]
3026
2912
  },
3027
- "face:publish": {
2913
+ "style:upload": {
3028
2914
  "aliases": [],
3029
2915
  "args": {
3030
2916
  "alias": {
3031
2917
  "description": "Face alias",
3032
2918
  "name": "alias",
3033
2919
  "required": true
2920
+ },
2921
+ "file": {
2922
+ "description": "Corpus file",
2923
+ "name": "file",
2924
+ "required": true
3034
2925
  }
3035
2926
  },
3036
- "description": "Publish a face so EVERY account can chat with it. This is a global override: while it is on, everyone can reach the face regardless of who it is shared with. You still pay only to compile it; whoever chats pays for their own inference.",
2927
+ "description": "Load a corpus of a person's own writing (a mail export, a message archive) as source material for style capture. This only stores the material: nothing is compiled and nothing is billed. Capture the style afterwards with style:make.",
3037
2928
  "examples": [
3038
- "<%= config.bin %> <%= command.id %> alice --yes"
2929
+ "<%= config.bin %> <%= command.id %> alice ./mail.jsonl",
2930
+ "<%= config.bin %> <%= command.id %> alice ./thread.json --type thread_json",
2931
+ "<%= config.bin %> <%= command.id %> alice ./mail.jsonl --messages-per-room 100 --strict"
3039
2932
  ],
3040
2933
  "flags": {
3041
2934
  "json": {
@@ -3069,16 +2962,36 @@
3069
2962
  "multiple": false,
3070
2963
  "type": "option"
3071
2964
  },
3072
- "yes": {
3073
- "description": "Skip confirmation",
3074
- "name": "yes",
2965
+ "type": {
2966
+ "description": "email_jsonl: one message per line, split across several rooms. thread_json: a JSON array that becomes a single room.",
2967
+ "name": "type",
2968
+ "default": "email_jsonl",
2969
+ "hasDynamicHelp": false,
2970
+ "multiple": false,
2971
+ "options": [
2972
+ "email_jsonl",
2973
+ "thread_json"
2974
+ ],
2975
+ "type": "option"
2976
+ },
2977
+ "messages-per-room": {
2978
+ "description": "How many messages per room when the type is email_jsonl (1-1000, default: 50)",
2979
+ "name": "messages-per-room",
2980
+ "default": 50,
2981
+ "hasDynamicHelp": false,
2982
+ "multiple": false,
2983
+ "type": "option"
2984
+ },
2985
+ "strict": {
2986
+ "description": "Reject the whole upload if any message is invalid. By default invalid messages are skipped and reported, because a corpus is statistical and a few bad lines are not worth losing the rest.",
2987
+ "name": "strict",
3075
2988
  "allowNo": false,
3076
2989
  "type": "boolean"
3077
2990
  }
3078
2991
  },
3079
2992
  "hasDynamicHelp": false,
3080
2993
  "hiddenAliases": [],
3081
- "id": "face:publish",
2994
+ "id": "style:upload",
3082
2995
  "pluginAlias": "faces-cli",
3083
2996
  "pluginName": "faces-cli",
3084
2997
  "pluginType": "core",
@@ -3088,11 +3001,11 @@
3088
3001
  "relativePath": [
3089
3002
  "dist",
3090
3003
  "commands",
3091
- "face",
3092
- "publish.js"
3004
+ "style",
3005
+ "upload.js"
3093
3006
  ]
3094
3007
  },
3095
- "face:share": {
3008
+ "style:versions": {
3096
3009
  "aliases": [],
3097
3010
  "args": {
3098
3011
  "alias": {
@@ -3101,12 +3014,10 @@
3101
3014
  "required": true
3102
3015
  }
3103
3016
  },
3104
- "description": "Share a face so named accounts can chat with it. Sharing grants chat and nothing else: no reading its documents, no compiling, no re-sharing, and never its profile addendum. --add keeps the current list; --with replaces it.",
3017
+ "description": "List the styles captured for a face, and which one it writes in now. A face holds one style per medium, so more than one can be in use at once: an email style and an essay style are separate and do not replace each other. Two versions are kept per medium, which is what style:revert has to go back to.",
3105
3018
  "examples": [
3106
- "<%= config.bin %> <%= command.id %> alice --list",
3107
- "<%= config.bin %> <%= command.id %> alice --add dana",
3108
- "<%= config.bin %> <%= command.id %> alice --with dana --with sam@example.com",
3109
- "<%= config.bin %> <%= command.id %> alice --none --yes"
3019
+ "<%= config.bin %> <%= command.id %> alice",
3020
+ "<%= config.bin %> <%= command.id %> alice --json"
3110
3021
  ],
3111
3022
  "flags": {
3112
3023
  "json": {
@@ -3139,55 +3050,11 @@
3139
3050
  "hasDynamicHelp": false,
3140
3051
  "multiple": false,
3141
3052
  "type": "option"
3142
- },
3143
- "list": {
3144
- "description": "Show who the face is shared with, and change nothing",
3145
- "name": "list",
3146
- "allowNo": false,
3147
- "type": "boolean"
3148
- },
3149
- "add": {
3150
- "description": "Add an account, keeping everyone already on the list — username or email (repeatable)",
3151
- "exclusive": [
3152
- "with",
3153
- "none"
3154
- ],
3155
- "name": "add",
3156
- "hasDynamicHelp": false,
3157
- "multiple": true,
3158
- "type": "option"
3159
- },
3160
- "with": {
3161
- "description": "Set the list to exactly these accounts, dropping anyone else (repeatable)",
3162
- "exclusive": [
3163
- "add",
3164
- "none"
3165
- ],
3166
- "name": "with",
3167
- "hasDynamicHelp": false,
3168
- "multiple": true,
3169
- "type": "option"
3170
- },
3171
- "none": {
3172
- "description": "Revoke everyone",
3173
- "exclusive": [
3174
- "add",
3175
- "with"
3176
- ],
3177
- "name": "none",
3178
- "allowNo": false,
3179
- "type": "boolean"
3180
- },
3181
- "yes": {
3182
- "description": "Skip the confirmation shown when someone would lose access",
3183
- "name": "yes",
3184
- "allowNo": false,
3185
- "type": "boolean"
3186
3053
  }
3187
3054
  },
3188
3055
  "hasDynamicHelp": false,
3189
3056
  "hiddenAliases": [],
3190
- "id": "face:share",
3057
+ "id": "style:versions",
3191
3058
  "pluginAlias": "faces-cli",
3192
3059
  "pluginName": "faces-cli",
3193
3060
  "pluginType": "core",
@@ -3197,25 +3064,20 @@
3197
3064
  "relativePath": [
3198
3065
  "dist",
3199
3066
  "commands",
3200
- "face",
3201
- "share.js"
3067
+ "style",
3068
+ "versions.js"
3202
3069
  ]
3203
3070
  },
3204
- "face:sources": {
3071
+ "team:add": {
3205
3072
  "aliases": [],
3206
3073
  "args": {
3207
- "alias": {
3208
- "description": "Face alias",
3209
- "name": "alias",
3074
+ "team_id": {
3075
+ "description": "Team ID",
3076
+ "name": "team_id",
3210
3077
  "required": true
3211
3078
  }
3212
3079
  },
3213
- "description": "List every source compiled into a face: documents and threads together, one row each. Exits 4 if the face does not exist, which is a different answer from a face that has no sources. Content is never printed; read a single source with compile:doc:get or compile:thread:get.",
3214
- "examples": [
3215
- "<%= config.bin %> <%= command.id %> alice",
3216
- "<%= config.bin %> <%= command.id %> alice --type thread",
3217
- "<%= config.bin %> <%= command.id %> alice --json"
3218
- ],
3080
+ "description": "Add face(s) to a team. A team may only contain faces this account owns: a published or shared face can be chatted with but cannot be a member.",
3219
3081
  "flags": {
3220
3082
  "json": {
3221
3083
  "description": "Format output as json.",
@@ -3248,21 +3110,18 @@
3248
3110
  "multiple": false,
3249
3111
  "type": "option"
3250
3112
  },
3251
- "type": {
3252
- "description": "Show only one kind of source",
3253
- "name": "type",
3113
+ "face": {
3114
+ "description": "Face alias to add (repeatable)",
3115
+ "name": "face",
3116
+ "required": true,
3254
3117
  "hasDynamicHelp": false,
3255
- "multiple": false,
3256
- "options": [
3257
- "doc",
3258
- "thread"
3259
- ],
3118
+ "multiple": true,
3260
3119
  "type": "option"
3261
3120
  }
3262
3121
  },
3263
3122
  "hasDynamicHelp": false,
3264
3123
  "hiddenAliases": [],
3265
- "id": "face:sources",
3124
+ "id": "team:add",
3266
3125
  "pluginAlias": "faces-cli",
3267
3126
  "pluginName": "faces-cli",
3268
3127
  "pluginType": "core",
@@ -3272,14 +3131,14 @@
3272
3131
  "relativePath": [
3273
3132
  "dist",
3274
3133
  "commands",
3275
- "face",
3276
- "sources.js"
3134
+ "team",
3135
+ "add.js"
3277
3136
  ]
3278
3137
  },
3279
- "face:stats": {
3138
+ "team:create": {
3280
3139
  "aliases": [],
3281
3140
  "args": {},
3282
- "description": "Compile and chat stats for all owned faces",
3141
+ "description": "Create a new team",
3283
3142
  "flags": {
3284
3143
  "json": {
3285
3144
  "description": "Format output as json.",
@@ -3311,11 +3170,47 @@
3311
3170
  "hasDynamicHelp": false,
3312
3171
  "multiple": false,
3313
3172
  "type": "option"
3173
+ },
3174
+ "name": {
3175
+ "description": "Team name",
3176
+ "name": "name",
3177
+ "required": true,
3178
+ "hasDynamicHelp": false,
3179
+ "multiple": false,
3180
+ "type": "option"
3181
+ },
3182
+ "description": {
3183
+ "description": "Plain-text team description (max 1500 chars)",
3184
+ "name": "description",
3185
+ "hasDynamicHelp": false,
3186
+ "multiple": false,
3187
+ "type": "option"
3188
+ },
3189
+ "protocol": {
3190
+ "description": "Protocol content (mermaid diagram or markdown, max 1000 words)",
3191
+ "name": "protocol",
3192
+ "hasDynamicHelp": false,
3193
+ "multiple": false,
3194
+ "type": "option"
3195
+ },
3196
+ "protocol-file": {
3197
+ "description": "Read protocol from file",
3198
+ "name": "protocol-file",
3199
+ "hasDynamicHelp": false,
3200
+ "multiple": false,
3201
+ "type": "option"
3202
+ },
3203
+ "tag": {
3204
+ "description": "Tag label (repeatable, lowercase)",
3205
+ "name": "tag",
3206
+ "hasDynamicHelp": false,
3207
+ "multiple": true,
3208
+ "type": "option"
3314
3209
  }
3315
3210
  },
3316
3211
  "hasDynamicHelp": false,
3317
3212
  "hiddenAliases": [],
3318
- "id": "face:stats",
3213
+ "id": "team:create",
3319
3214
  "pluginAlias": "faces-cli",
3320
3215
  "pluginName": "faces-cli",
3321
3216
  "pluginType": "core",
@@ -3325,20 +3220,20 @@
3325
3220
  "relativePath": [
3326
3221
  "dist",
3327
3222
  "commands",
3328
- "face",
3329
- "stats.js"
3223
+ "team",
3224
+ "create.js"
3330
3225
  ]
3331
3226
  },
3332
- "face:teams": {
3227
+ "team:delete": {
3333
3228
  "aliases": [],
3334
3229
  "args": {
3335
- "alias": {
3336
- "description": "Face alias",
3337
- "name": "alias",
3230
+ "team_id": {
3231
+ "description": "Team ID",
3232
+ "name": "team_id",
3338
3233
  "required": true
3339
3234
  }
3340
3235
  },
3341
- "description": "Set a face's team memberships (replaces all)",
3236
+ "description": "Delete a team",
3342
3237
  "flags": {
3343
3238
  "json": {
3344
3239
  "description": "Format output as json.",
@@ -3371,18 +3266,16 @@
3371
3266
  "multiple": false,
3372
3267
  "type": "option"
3373
3268
  },
3374
- "team": {
3375
- "description": "Team ID (repeatable, replaces all memberships)",
3376
- "name": "team",
3377
- "required": true,
3378
- "hasDynamicHelp": false,
3379
- "multiple": true,
3380
- "type": "option"
3269
+ "yes": {
3270
+ "description": "Skip confirmation",
3271
+ "name": "yes",
3272
+ "allowNo": false,
3273
+ "type": "boolean"
3381
3274
  }
3382
3275
  },
3383
3276
  "hasDynamicHelp": false,
3384
3277
  "hiddenAliases": [],
3385
- "id": "face:teams",
3278
+ "id": "team:delete",
3386
3279
  "pluginAlias": "faces-cli",
3387
3280
  "pluginName": "faces-cli",
3388
3281
  "pluginType": "core",
@@ -3392,23 +3285,20 @@
3392
3285
  "relativePath": [
3393
3286
  "dist",
3394
3287
  "commands",
3395
- "face",
3396
- "teams.js"
3288
+ "team",
3289
+ "delete.js"
3397
3290
  ]
3398
3291
  },
3399
- "face:unlock": {
3292
+ "team:edit": {
3400
3293
  "aliases": [],
3401
3294
  "args": {
3402
- "face_id": {
3403
- "description": "Face alias",
3404
- "name": "face_id",
3295
+ "team_id": {
3296
+ "description": "Team ID",
3297
+ "name": "team_id",
3405
3298
  "required": true
3406
3299
  }
3407
3300
  },
3408
- "description": "Unlock a face (make it writable again). Thaws the face and everything it owns (documents, threads, voiceprint).",
3409
- "examples": [
3410
- "<%= config.bin %> <%= command.id %> socrates"
3411
- ],
3301
+ "description": "Edit a team",
3412
3302
  "flags": {
3413
3303
  "json": {
3414
3304
  "description": "Format output as json.",
@@ -3440,11 +3330,39 @@
3440
3330
  "hasDynamicHelp": false,
3441
3331
  "multiple": false,
3442
3332
  "type": "option"
3333
+ },
3334
+ "name": {
3335
+ "description": "New team name",
3336
+ "name": "name",
3337
+ "hasDynamicHelp": false,
3338
+ "multiple": false,
3339
+ "type": "option"
3340
+ },
3341
+ "description": {
3342
+ "description": "New description (max 1500 chars)",
3343
+ "name": "description",
3344
+ "hasDynamicHelp": false,
3345
+ "multiple": false,
3346
+ "type": "option"
3347
+ },
3348
+ "protocol": {
3349
+ "description": "New protocol content",
3350
+ "name": "protocol",
3351
+ "hasDynamicHelp": false,
3352
+ "multiple": false,
3353
+ "type": "option"
3354
+ },
3355
+ "protocol-file": {
3356
+ "description": "Read protocol from file",
3357
+ "name": "protocol-file",
3358
+ "hasDynamicHelp": false,
3359
+ "multiple": false,
3360
+ "type": "option"
3443
3361
  }
3444
3362
  },
3445
3363
  "hasDynamicHelp": false,
3446
3364
  "hiddenAliases": [],
3447
- "id": "face:unlock",
3365
+ "id": "team:edit",
3448
3366
  "pluginAlias": "faces-cli",
3449
3367
  "pluginName": "faces-cli",
3450
3368
  "pluginType": "core",
@@ -3454,20 +3372,20 @@
3454
3372
  "relativePath": [
3455
3373
  "dist",
3456
3374
  "commands",
3457
- "face",
3458
- "unlock.js"
3375
+ "team",
3376
+ "edit.js"
3459
3377
  ]
3460
3378
  },
3461
- "face:unpublish": {
3379
+ "team:get": {
3462
3380
  "aliases": [],
3463
3381
  "args": {
3464
- "alias": {
3465
- "description": "Face alias",
3466
- "name": "alias",
3382
+ "team_id": {
3383
+ "description": "Team ID",
3384
+ "name": "team_id",
3467
3385
  "required": true
3468
3386
  }
3469
3387
  },
3470
- "description": "Stop publishing a face. Anyone it is individually shared with keeps their access — publishing is an override on top of sharing, not a replacement for it.",
3388
+ "description": "Get a team by ID",
3471
3389
  "flags": {
3472
3390
  "json": {
3473
3391
  "description": "Format output as json.",
@@ -3503,7 +3421,7 @@
3503
3421
  },
3504
3422
  "hasDynamicHelp": false,
3505
3423
  "hiddenAliases": [],
3506
- "id": "face:unpublish",
3424
+ "id": "team:get",
3507
3425
  "pluginAlias": "faces-cli",
3508
3426
  "pluginName": "faces-cli",
3509
3427
  "pluginType": "core",
@@ -3513,24 +3431,14 @@
3513
3431
  "relativePath": [
3514
3432
  "dist",
3515
3433
  "commands",
3516
- "face",
3517
- "unpublish.js"
3434
+ "team",
3435
+ "get.js"
3518
3436
  ]
3519
3437
  },
3520
- "face:unshare": {
3438
+ "team:list": {
3521
3439
  "aliases": [],
3522
- "args": {
3523
- "alias": {
3524
- "description": "Face alias",
3525
- "name": "alias",
3526
- "required": true
3527
- }
3528
- },
3529
- "description": "Revoke access to a shared face. Takes effect immediately — there is no grace period.",
3530
- "examples": [
3531
- "<%= config.bin %> <%= command.id %> alice --from dana --yes",
3532
- "<%= config.bin %> <%= command.id %> alice --all --yes"
3533
- ],
3440
+ "args": {},
3441
+ "description": "List your teams",
3534
3442
  "flags": {
3535
3443
  "json": {
3536
3444
  "description": "Format output as json.",
@@ -3562,36 +3470,11 @@
3562
3470
  "hasDynamicHelp": false,
3563
3471
  "multiple": false,
3564
3472
  "type": "option"
3565
- },
3566
- "from": {
3567
- "description": "Account to revoke (repeatable)",
3568
- "exclusive": [
3569
- "all"
3570
- ],
3571
- "name": "from",
3572
- "hasDynamicHelp": false,
3573
- "multiple": true,
3574
- "type": "option"
3575
- },
3576
- "all": {
3577
- "description": "Revoke everyone",
3578
- "exclusive": [
3579
- "from"
3580
- ],
3581
- "name": "all",
3582
- "allowNo": false,
3583
- "type": "boolean"
3584
- },
3585
- "yes": {
3586
- "description": "Skip confirmation",
3587
- "name": "yes",
3588
- "allowNo": false,
3589
- "type": "boolean"
3590
3473
  }
3591
3474
  },
3592
3475
  "hasDynamicHelp": false,
3593
3476
  "hiddenAliases": [],
3594
- "id": "face:unshare",
3477
+ "id": "team:list",
3595
3478
  "pluginAlias": "faces-cli",
3596
3479
  "pluginName": "faces-cli",
3597
3480
  "pluginType": "core",
@@ -3601,14 +3484,20 @@
3601
3484
  "relativePath": [
3602
3485
  "dist",
3603
3486
  "commands",
3604
- "face",
3605
- "unshare.js"
3487
+ "team",
3488
+ "list.js"
3606
3489
  ]
3607
3490
  },
3608
- "keys:create": {
3491
+ "team:members": {
3609
3492
  "aliases": [],
3610
- "args": {},
3611
- "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.",
3493
+ "args": {
3494
+ "team_id": {
3495
+ "description": "Team ID",
3496
+ "name": "team_id",
3497
+ "required": true
3498
+ }
3499
+ },
3500
+ "description": "List members of a team",
3612
3501
  "flags": {
3613
3502
  "json": {
3614
3503
  "description": "Format output as json.",
@@ -3640,53 +3529,11 @@
3640
3529
  "hasDynamicHelp": false,
3641
3530
  "multiple": false,
3642
3531
  "type": "option"
3643
- },
3644
- "name": {
3645
- "description": "Key name/label",
3646
- "name": "name",
3647
- "required": true,
3648
- "hasDynamicHelp": false,
3649
- "multiple": false,
3650
- "type": "option"
3651
- },
3652
- "expires-days": {
3653
- "description": "Expiry in days (omit for no expiry)",
3654
- "name": "expires-days",
3655
- "hasDynamicHelp": false,
3656
- "multiple": false,
3657
- "type": "option"
3658
- },
3659
- "budget": {
3660
- "description": "Spend budget in USD",
3661
- "name": "budget",
3662
- "hasDynamicHelp": false,
3663
- "multiple": false,
3664
- "type": "option"
3665
- },
3666
- "face": {
3667
- "description": "Allowed face alias (repeatable)",
3668
- "name": "face",
3669
- "hasDynamicHelp": false,
3670
- "multiple": true,
3671
- "type": "option"
3672
- },
3673
- "model": {
3674
- "description": "Allowed model name (repeatable)",
3675
- "name": "model",
3676
- "hasDynamicHelp": false,
3677
- "multiple": true,
3678
- "type": "option"
3679
- },
3680
- "save": {
3681
- "description": "Save the new key to ~/.faces/config.json as api_key (default: true; use --no-save to skip)",
3682
- "name": "save",
3683
- "allowNo": true,
3684
- "type": "boolean"
3685
3532
  }
3686
3533
  },
3687
3534
  "hasDynamicHelp": false,
3688
3535
  "hiddenAliases": [],
3689
- "id": "keys:create",
3536
+ "id": "team:members",
3690
3537
  "pluginAlias": "faces-cli",
3691
3538
  "pluginName": "faces-cli",
3692
3539
  "pluginType": "core",
@@ -3696,14 +3543,25 @@
3696
3543
  "relativePath": [
3697
3544
  "dist",
3698
3545
  "commands",
3699
- "keys",
3700
- "create.js"
3546
+ "team",
3547
+ "members.js"
3701
3548
  ]
3702
3549
  },
3703
- "keys:list": {
3550
+ "team:remove": {
3704
3551
  "aliases": [],
3705
- "args": {},
3706
- "description": "List all API keys (JWT required)",
3552
+ "args": {
3553
+ "team_id": {
3554
+ "description": "Team ID",
3555
+ "name": "team_id",
3556
+ "required": true
3557
+ },
3558
+ "alias": {
3559
+ "description": "Face alias to remove",
3560
+ "name": "alias",
3561
+ "required": true
3562
+ }
3563
+ },
3564
+ "description": "Remove a face from a team",
3707
3565
  "flags": {
3708
3566
  "json": {
3709
3567
  "description": "Format output as json.",
@@ -3739,7 +3597,7 @@
3739
3597
  },
3740
3598
  "hasDynamicHelp": false,
3741
3599
  "hiddenAliases": [],
3742
- "id": "keys:list",
3600
+ "id": "team:remove",
3743
3601
  "pluginAlias": "faces-cli",
3744
3602
  "pluginName": "faces-cli",
3745
3603
  "pluginType": "core",
@@ -3749,20 +3607,14 @@
3749
3607
  "relativePath": [
3750
3608
  "dist",
3751
3609
  "commands",
3752
- "keys",
3753
- "list.js"
3610
+ "team",
3611
+ "remove.js"
3754
3612
  ]
3755
3613
  },
3756
- "keys:revoke": {
3614
+ "face:attributes": {
3757
3615
  "aliases": [],
3758
- "args": {
3759
- "key_id": {
3760
- "description": "Key ID",
3761
- "name": "key_id",
3762
- "required": true
3763
- }
3764
- },
3765
- "description": "Revoke an API key (JWT required)",
3616
+ "args": {},
3617
+ "description": "List all supported attribute keys",
3766
3618
  "flags": {
3767
3619
  "json": {
3768
3620
  "description": "Format output as json.",
@@ -3794,17 +3646,11 @@
3794
3646
  "hasDynamicHelp": false,
3795
3647
  "multiple": false,
3796
3648
  "type": "option"
3797
- },
3798
- "yes": {
3799
- "description": "Skip confirmation",
3800
- "name": "yes",
3801
- "allowNo": false,
3802
- "type": "boolean"
3803
3649
  }
3804
3650
  },
3805
3651
  "hasDynamicHelp": false,
3806
3652
  "hiddenAliases": [],
3807
- "id": "keys:revoke",
3653
+ "id": "face:attributes",
3808
3654
  "pluginAlias": "faces-cli",
3809
3655
  "pluginName": "faces-cli",
3810
3656
  "pluginType": "core",
@@ -3814,20 +3660,14 @@
3814
3660
  "relativePath": [
3815
3661
  "dist",
3816
3662
  "commands",
3817
- "keys",
3818
- "revoke.js"
3663
+ "face",
3664
+ "attributes.js"
3819
3665
  ]
3820
3666
  },
3821
- "keys:update": {
3667
+ "face:create": {
3822
3668
  "aliases": [],
3823
- "args": {
3824
- "key_id": {
3825
- "description": "Key ID",
3826
- "name": "key_id",
3827
- "required": true
3828
- }
3829
- },
3830
- "description": "Update API key metadata (JWT required)",
3669
+ "args": {},
3670
+ "description": "Create a new face",
3831
3671
  "flags": {
3832
3672
  "json": {
3833
3673
  "description": "Format output as json.",
@@ -3861,29 +3701,84 @@
3861
3701
  "type": "option"
3862
3702
  },
3863
3703
  "name": {
3864
- "description": "New key name",
3704
+ "description": "Display name",
3865
3705
  "name": "name",
3706
+ "required": true,
3866
3707
  "hasDynamicHelp": false,
3867
3708
  "multiple": false,
3868
3709
  "type": "option"
3869
3710
  },
3870
- "budget": {
3871
- "description": "New spend budget in USD",
3872
- "name": "budget",
3711
+ "alias": {
3712
+ "description": "Unique alias slug",
3713
+ "name": "alias",
3714
+ "required": true,
3873
3715
  "hasDynamicHelp": false,
3874
3716
  "multiple": false,
3875
3717
  "type": "option"
3876
3718
  },
3877
- "reset-spent": {
3878
- "description": "Reset spent amount to zero",
3879
- "name": "reset-spent",
3880
- "allowNo": false,
3881
- "type": "boolean"
3719
+ "description": {
3720
+ "description": "Plain-text description / bio (max 1500 chars)",
3721
+ "name": "description",
3722
+ "hasDynamicHelp": false,
3723
+ "multiple": false,
3724
+ "type": "option"
3725
+ },
3726
+ "tag": {
3727
+ "description": "Tag label (repeatable, lowercase)",
3728
+ "name": "tag",
3729
+ "hasDynamicHelp": false,
3730
+ "multiple": true,
3731
+ "type": "option"
3732
+ },
3733
+ "default-model": {
3734
+ "description": "Default LLM for chat (e.g. gpt-4o-mini, claude-sonnet-4-6)",
3735
+ "name": "default-model",
3736
+ "hasDynamicHelp": false,
3737
+ "multiple": false,
3738
+ "type": "option"
3739
+ },
3740
+ "formula": {
3741
+ "description": "Boolean formula over owned concrete face aliases (e.g. \"a | b\", \"(a | b) - c\"). Creates a composite face.",
3742
+ "name": "formula",
3743
+ "hasDynamicHelp": false,
3744
+ "multiple": false,
3745
+ "type": "option"
3746
+ },
3747
+ "attr": {
3748
+ "description": "Attribute KEY=VALUE (repeatable)",
3749
+ "name": "attr",
3750
+ "hasDynamicHelp": false,
3751
+ "multiple": true,
3752
+ "type": "option"
3753
+ },
3754
+ "tool": {
3755
+ "description": "Tool name to enable (repeatable)",
3756
+ "name": "tool",
3757
+ "hasDynamicHelp": false,
3758
+ "multiple": true,
3759
+ "type": "option"
3760
+ },
3761
+ "profile-addendum": {
3762
+ "description": "Per-face system prompt, injected after the persona profile and before any per-request system prompt (max 100,000 chars).",
3763
+ "name": "profile-addendum",
3764
+ "hasDynamicHelp": false,
3765
+ "multiple": false,
3766
+ "type": "option"
3767
+ },
3768
+ "profile-addendum-file": {
3769
+ "description": "Read the per-face system prompt from a file (alternative to --profile-addendum).",
3770
+ "exclusive": [
3771
+ "profile-addendum"
3772
+ ],
3773
+ "name": "profile-addendum-file",
3774
+ "hasDynamicHelp": false,
3775
+ "multiple": false,
3776
+ "type": "option"
3882
3777
  }
3883
3778
  },
3884
3779
  "hasDynamicHelp": false,
3885
3780
  "hiddenAliases": [],
3886
- "id": "keys:update",
3781
+ "id": "face:create",
3887
3782
  "pluginAlias": "faces-cli",
3888
3783
  "pluginName": "faces-cli",
3889
3784
  "pluginType": "core",
@@ -3893,24 +3788,20 @@
3893
3788
  "relativePath": [
3894
3789
  "dist",
3895
3790
  "commands",
3896
- "keys",
3897
- "update.js"
3791
+ "face",
3792
+ "create.js"
3898
3793
  ]
3899
3794
  },
3900
- "style:delete": {
3795
+ "face:delete": {
3901
3796
  "aliases": [],
3902
3797
  "args": {
3903
- "alias": {
3798
+ "face_id": {
3904
3799
  "description": "Face alias",
3905
- "name": "alias",
3800
+ "name": "face_id",
3906
3801
  "required": true
3907
3802
  }
3908
3803
  },
3909
- "description": "Delete a face's captured style. --scope map forgets the style and keeps the material it came from. --scope all deletes the uploaded material too, permanently. There is no default because the two differ by whether your material survives.",
3910
- "examples": [
3911
- "<%= config.bin %> <%= command.id %> alice --scope map",
3912
- "<%= config.bin %> <%= command.id %> alice --scope all --yes"
3913
- ],
3804
+ "description": "Delete a face permanently",
3914
3805
  "flags": {
3915
3806
  "json": {
3916
3807
  "description": "Format output as json.",
@@ -3943,18 +3834,6 @@
3943
3834
  "multiple": false,
3944
3835
  "type": "option"
3945
3836
  },
3946
- "scope": {
3947
- "description": "map: forget the style, keep the material. all: delete the material with it, permanently.",
3948
- "name": "scope",
3949
- "required": true,
3950
- "hasDynamicHelp": false,
3951
- "multiple": false,
3952
- "options": [
3953
- "map",
3954
- "all"
3955
- ],
3956
- "type": "option"
3957
- },
3958
3837
  "yes": {
3959
3838
  "description": "Skip confirmation",
3960
3839
  "name": "yes",
@@ -3964,7 +3843,7 @@
3964
3843
  },
3965
3844
  "hasDynamicHelp": false,
3966
3845
  "hiddenAliases": [],
3967
- "id": "style:delete",
3846
+ "id": "face:delete",
3968
3847
  "pluginAlias": "faces-cli",
3969
3848
  "pluginName": "faces-cli",
3970
3849
  "pluginType": "core",
@@ -3974,26 +3853,81 @@
3974
3853
  "relativePath": [
3975
3854
  "dist",
3976
3855
  "commands",
3977
- "style",
3856
+ "face",
3978
3857
  "delete.js"
3979
3858
  ]
3980
3859
  },
3981
- "style:make": {
3860
+ "face:diff": {
3861
+ "aliases": [],
3862
+ "args": {},
3863
+ "description": "Compare owned faces pairwise across all centroid components",
3864
+ "flags": {
3865
+ "json": {
3866
+ "description": "Format output as json.",
3867
+ "helpGroup": "GLOBAL",
3868
+ "name": "json",
3869
+ "allowNo": false,
3870
+ "type": "boolean"
3871
+ },
3872
+ "base-url": {
3873
+ "description": "API base URL",
3874
+ "env": "FACES_BASE_URL",
3875
+ "name": "base-url",
3876
+ "hasDynamicHelp": false,
3877
+ "multiple": false,
3878
+ "type": "option"
3879
+ },
3880
+ "token": {
3881
+ "description": "JWT bearer token",
3882
+ "env": "FACES_TOKEN",
3883
+ "name": "token",
3884
+ "hasDynamicHelp": false,
3885
+ "multiple": false,
3886
+ "type": "option"
3887
+ },
3888
+ "api-key": {
3889
+ "description": "API key",
3890
+ "env": "FACES_API_KEY",
3891
+ "name": "api-key",
3892
+ "hasDynamicHelp": false,
3893
+ "multiple": false,
3894
+ "type": "option"
3895
+ },
3896
+ "face": {
3897
+ "description": "Face alias to include (repeatable, min 2)",
3898
+ "name": "face",
3899
+ "required": true,
3900
+ "hasDynamicHelp": false,
3901
+ "multiple": true,
3902
+ "type": "option"
3903
+ }
3904
+ },
3905
+ "hasDynamicHelp": false,
3906
+ "hiddenAliases": [],
3907
+ "id": "face:diff",
3908
+ "pluginAlias": "faces-cli",
3909
+ "pluginName": "faces-cli",
3910
+ "pluginType": "core",
3911
+ "strict": true,
3912
+ "enableJsonFlag": true,
3913
+ "isESM": true,
3914
+ "relativePath": [
3915
+ "dist",
3916
+ "commands",
3917
+ "face",
3918
+ "diff.js"
3919
+ ]
3920
+ },
3921
+ "face:edit": {
3982
3922
  "aliases": [],
3983
3923
  "args": {
3984
- "alias": {
3924
+ "face_id": {
3985
3925
  "description": "Face alias",
3986
- "name": "alias",
3926
+ "name": "face_id",
3987
3927
  "required": true
3988
3928
  }
3989
3929
  },
3990
- "description": "Capture how a face writes, from its own material, and install it. This is style, not knowledge: compile teaches a face what it knows, style teaches it how it sounds. Name the sources to learn from with --source, or take everything ready with --all.",
3991
- "examples": [
3992
- "<%= config.bin %> <%= command.id %> alice --all",
3993
- "<%= config.bin %> <%= command.id %> alice --source 1a2b3c4d --source 5e6f7a8b",
3994
- "<%= config.bin %> <%= command.id %> alice --source 1a2b3c4d:essay",
3995
- "<%= config.bin %> <%= command.id %> alice --all --medium essay --no-wait"
3996
- ],
3930
+ "description": "Edit a face's metadata",
3997
3931
  "flags": {
3998
3932
  "json": {
3999
3933
  "description": "Format output as json.",
@@ -4026,70 +3960,86 @@
4026
3960
  "multiple": false,
4027
3961
  "type": "option"
4028
3962
  },
4029
- "source": {
4030
- "description": "A document or thread to learn from, by id (repeatable). Append :<medium> to declare what it is, e.g. --source 1a2b3c4d:essay, when the source does not already say.",
4031
- "name": "source",
3963
+ "name": {
3964
+ "description": "New display name",
3965
+ "name": "name",
4032
3966
  "hasDynamicHelp": false,
4033
- "multiple": true,
3967
+ "multiple": false,
4034
3968
  "type": "option"
4035
3969
  },
4036
- "all": {
4037
- "description": "Use every source on the face that is ready. Anything skipped is listed.",
4038
- "name": "all",
4039
- "allowNo": false,
4040
- "type": "boolean"
3970
+ "description": {
3971
+ "description": "Plain-text description / bio (max 1500 chars)",
3972
+ "name": "description",
3973
+ "hasDynamicHelp": false,
3974
+ "multiple": false,
3975
+ "type": "option"
4041
3976
  },
4042
- "medium": {
4043
- "description": "Medium for any selected source that does not declare one. Each medium is analysed on its own, so an essay never teaches a rule about email.",
4044
- "name": "medium",
3977
+ "tag": {
3978
+ "description": "Replace all tags (repeatable, lowercase)",
3979
+ "name": "tag",
3980
+ "hasDynamicHelp": false,
3981
+ "multiple": true,
3982
+ "type": "option"
3983
+ },
3984
+ "default-model": {
3985
+ "description": "Default LLM for chat (e.g. gpt-4o-mini, claude-sonnet-4-6)",
3986
+ "name": "default-model",
4045
3987
  "hasDynamicHelp": false,
4046
3988
  "multiple": false,
4047
3989
  "type": "option"
4048
3990
  },
4049
- "model": {
4050
- "description": "Analyst model (default: gpt-5.6-terra)",
4051
- "name": "model",
3991
+ "formula": {
3992
+ "description": "New boolean formula (synthetic faces only)",
3993
+ "name": "formula",
4052
3994
  "hasDynamicHelp": false,
4053
3995
  "multiple": false,
4054
3996
  "type": "option"
4055
3997
  },
4056
- "allow-paid": {
4057
- "description": "Permit a build that bills. Without this a build is free or it does not run. Needed for any model outside the free tier, and to allow the paid route when a free quota is exhausted.",
4058
- "name": "allow-paid",
4059
- "allowNo": false,
4060
- "type": "boolean"
3998
+ "attr": {
3999
+ "description": "Update attribute KEY=VALUE (repeatable)",
4000
+ "name": "attr",
4001
+ "hasDynamicHelp": false,
4002
+ "multiple": true,
4003
+ "type": "option"
4061
4004
  },
4062
- "compile": {
4063
- "description": "Compile any named source that is not compiled yet, before capturing style. On by default. --no-compile captures style from what is already compiled and never bills for compilation.",
4064
- "name": "compile",
4065
- "allowNo": true,
4066
- "type": "boolean"
4005
+ "tool": {
4006
+ "description": "Tool names to set (replaces list, repeatable)",
4007
+ "name": "tool",
4008
+ "hasDynamicHelp": false,
4009
+ "multiple": true,
4010
+ "type": "option"
4067
4011
  },
4068
- "best-of": {
4069
- "description": "Generate N candidates and keep the best (1-5, default 1)",
4070
- "name": "best-of",
4012
+ "profile-addendum": {
4013
+ "description": "Replace the per-face system prompt (max 100,000 chars).",
4014
+ "name": "profile-addendum",
4071
4015
  "hasDynamicHelp": false,
4072
4016
  "multiple": false,
4073
4017
  "type": "option"
4074
4018
  },
4075
- "no-wait": {
4076
- "description": "Start the build and return the job id without polling.",
4077
- "name": "no-wait",
4078
- "allowNo": false,
4079
- "type": "boolean"
4080
- },
4081
- "timeout": {
4082
- "description": "How long to wait, in seconds (default: 3600)",
4083
- "name": "timeout",
4084
- "default": 3600,
4019
+ "profile-addendum-file": {
4020
+ "description": "Replace the per-face system prompt from a file.",
4021
+ "exclusive": [
4022
+ "profile-addendum"
4023
+ ],
4024
+ "name": "profile-addendum-file",
4085
4025
  "hasDynamicHelp": false,
4086
4026
  "multiple": false,
4087
4027
  "type": "option"
4028
+ },
4029
+ "clear-profile-addendum": {
4030
+ "description": "Remove the per-face system prompt.",
4031
+ "exclusive": [
4032
+ "profile-addendum",
4033
+ "profile-addendum-file"
4034
+ ],
4035
+ "name": "clear-profile-addendum",
4036
+ "allowNo": false,
4037
+ "type": "boolean"
4088
4038
  }
4089
4039
  },
4090
4040
  "hasDynamicHelp": false,
4091
4041
  "hiddenAliases": [],
4092
- "id": "style:make",
4042
+ "id": "face:edit",
4093
4043
  "pluginAlias": "faces-cli",
4094
4044
  "pluginName": "faces-cli",
4095
4045
  "pluginType": "core",
@@ -4099,23 +4049,20 @@
4099
4049
  "relativePath": [
4100
4050
  "dist",
4101
4051
  "commands",
4102
- "style",
4103
- "make.js"
4052
+ "face",
4053
+ "edit.js"
4104
4054
  ]
4105
4055
  },
4106
- "style:revert": {
4056
+ "face:get": {
4107
4057
  "aliases": [],
4108
4058
  "args": {
4109
- "alias": {
4059
+ "face_id": {
4110
4060
  "description": "Face alias",
4111
- "name": "alias",
4061
+ "name": "face_id",
4112
4062
  "required": true
4113
4063
  }
4114
4064
  },
4115
- "description": "Go back to the style a face had before the last style:make. It steps backwards through the kept versions and there is no step forward, so the way to undo a revert is to capture the style again. It changes how the face writes immediately, so it asks first.",
4116
- "examples": [
4117
- "<%= config.bin %> <%= command.id %> alice --yes"
4118
- ],
4065
+ "description": "Get details for a face, by alias or owner:alias. A published or shared face is reachable under the same owner:alias address chat uses; it is shown with a note that you do not own it.",
4119
4066
  "flags": {
4120
4067
  "json": {
4121
4068
  "description": "Format output as json.",
@@ -4148,16 +4095,23 @@
4148
4095
  "multiple": false,
4149
4096
  "type": "option"
4150
4097
  },
4151
- "yes": {
4152
- "description": "Skip confirmation",
4153
- "name": "yes",
4098
+ "include": {
4099
+ "description": "Include extra fields: tags, teams (comma-separated)",
4100
+ "name": "include",
4101
+ "hasDynamicHelp": false,
4102
+ "multiple": false,
4103
+ "type": "option"
4104
+ },
4105
+ "full": {
4106
+ "description": "Print the full profile_addendum instead of a truncated preview",
4107
+ "name": "full",
4154
4108
  "allowNo": false,
4155
4109
  "type": "boolean"
4156
4110
  }
4157
4111
  },
4158
4112
  "hasDynamicHelp": false,
4159
4113
  "hiddenAliases": [],
4160
- "id": "style:revert",
4114
+ "id": "face:get",
4161
4115
  "pluginAlias": "faces-cli",
4162
4116
  "pluginName": "faces-cli",
4163
4117
  "pluginType": "core",
@@ -4167,25 +4121,14 @@
4167
4121
  "relativePath": [
4168
4122
  "dist",
4169
4123
  "commands",
4170
- "style",
4171
- "revert.js"
4124
+ "face",
4125
+ "get.js"
4172
4126
  ]
4173
4127
  },
4174
- "style:status": {
4128
+ "face:list": {
4175
4129
  "aliases": [],
4176
- "args": {
4177
- "job_id": {
4178
- "description": "Build job id",
4179
- "name": "job_id",
4180
- "required": false
4181
- }
4182
- },
4183
- "description": "Read a style build. Give a job id for one build, or --face to list a face's recent builds. Listing is how you find a job id you no longer have.",
4184
- "examples": [
4185
- "<%= config.bin %> <%= command.id %> 7a8b9c0d",
4186
- "<%= config.bin %> <%= command.id %> --face alice",
4187
- "<%= config.bin %> <%= command.id %> 7a8b9c0d --wait"
4188
- ],
4130
+ "args": {},
4131
+ "description": "List faces. By default lists owned faces; use --public to include published faces from other accounts.",
4189
4132
  "flags": {
4190
4133
  "json": {
4191
4134
  "description": "Format output as json.",
@@ -4215,42 +4158,66 @@
4215
4158
  "env": "FACES_API_KEY",
4216
4159
  "name": "api-key",
4217
4160
  "hasDynamicHelp": false,
4218
- "multiple": false,
4161
+ "multiple": false,
4162
+ "type": "option"
4163
+ },
4164
+ "tag": {
4165
+ "description": "Filter by tag (repeatable, AND logic)",
4166
+ "name": "tag",
4167
+ "hasDynamicHelp": false,
4168
+ "multiple": true,
4219
4169
  "type": "option"
4220
4170
  },
4221
- "face": {
4222
- "description": "List recent builds for this face instead of reading one job",
4223
- "name": "face",
4171
+ "team": {
4172
+ "description": "Filter by team ID (repeatable, OR logic)",
4173
+ "name": "team",
4224
4174
  "hasDynamicHelp": false,
4225
- "multiple": false,
4175
+ "multiple": true,
4226
4176
  "type": "option"
4227
4177
  },
4228
- "limit": {
4229
- "description": "How many builds to list with --face (default: 10)",
4230
- "name": "limit",
4231
- "default": 10,
4178
+ "include": {
4179
+ "description": "Include extra fields: tags, teams (comma-separated)",
4180
+ "name": "include",
4232
4181
  "hasDynamicHelp": false,
4233
4182
  "multiple": false,
4234
4183
  "type": "option"
4235
4184
  },
4236
- "wait": {
4237
- "description": "Block until the job finishes",
4238
- "name": "wait",
4185
+ "public": {
4186
+ "description": "Include published faces from other accounts (open to everybody)",
4187
+ "name": "public",
4239
4188
  "allowNo": false,
4240
4189
  "type": "boolean"
4241
4190
  },
4242
- "timeout": {
4243
- "description": "How long to wait with --wait, in seconds (default: 3600)",
4244
- "name": "timeout",
4245
- "default": 3600,
4191
+ "shared": {
4192
+ "description": "Include faces other accounts have shared with YOU in particular",
4193
+ "name": "shared",
4194
+ "allowNo": false,
4195
+ "type": "boolean"
4196
+ },
4197
+ "system": {
4198
+ "description": "Show only the curated system faces (published faces owned by 'head')",
4199
+ "name": "system",
4200
+ "allowNo": false,
4201
+ "type": "boolean"
4202
+ },
4203
+ "from-users": {
4204
+ "description": "Only published faces from these owners (repeatable/comma-separated)",
4205
+ "name": "from-users",
4246
4206
  "hasDynamicHelp": false,
4247
- "multiple": false,
4207
+ "multiple": true,
4208
+ "type": "option"
4209
+ },
4210
+ "not-from-users": {
4211
+ "description": "Exclude published faces from these owners (repeatable/comma-separated)",
4212
+ "name": "not-from-users",
4213
+ "hasDynamicHelp": false,
4214
+ "multiple": true,
4248
4215
  "type": "option"
4249
4216
  }
4250
4217
  },
4251
4218
  "hasDynamicHelp": false,
4252
4219
  "hiddenAliases": [],
4253
- "id": "style:status",
4220
+ "id": "face:list",
4254
4221
  "pluginAlias": "faces-cli",
4255
4222
  "pluginName": "faces-cli",
4256
4223
  "pluginType": "core",
@@ -4260,29 +4227,22 @@
4260
4227
  "relativePath": [
4261
4228
  "dist",
4262
4229
  "commands",
4263
- "style",
4264
- "status.js"
4230
+ "face",
4231
+ "list.js"
4265
4232
  ]
4266
4233
  },
4267
- "style:upload": {
4234
+ "face:lock": {
4268
4235
  "aliases": [],
4269
4236
  "args": {
4270
- "alias": {
4237
+ "face_id": {
4271
4238
  "description": "Face alias",
4272
- "name": "alias",
4273
- "required": true
4274
- },
4275
- "file": {
4276
- "description": "Corpus file",
4277
- "name": "file",
4239
+ "name": "face_id",
4278
4240
  "required": true
4279
4241
  }
4280
4242
  },
4281
- "description": "Load a corpus of a person's own writing (a mail export, a message archive) as source material for style capture. This only stores the material: nothing is compiled and nothing is billed. Capture the style afterwards with style:make.",
4243
+ "description": "Lock a face (read-only). A locked face still reads and chats normally, but it and everything it owns (documents, threads, voiceprint) cannot be changed until unlocked.",
4282
4244
  "examples": [
4283
- "<%= config.bin %> <%= command.id %> alice ./mail.jsonl",
4284
- "<%= config.bin %> <%= command.id %> alice ./thread.json --type thread_json",
4285
- "<%= config.bin %> <%= command.id %> alice ./mail.jsonl --messages-per-room 100 --strict"
4245
+ "<%= config.bin %> <%= command.id %> socrates"
4286
4246
  ],
4287
4247
  "flags": {
4288
4248
  "json": {
@@ -4315,37 +4275,11 @@
4315
4275
  "hasDynamicHelp": false,
4316
4276
  "multiple": false,
4317
4277
  "type": "option"
4318
- },
4319
- "type": {
4320
- "description": "email_jsonl: one message per line, split across several rooms. thread_json: a JSON array that becomes a single room.",
4321
- "name": "type",
4322
- "default": "email_jsonl",
4323
- "hasDynamicHelp": false,
4324
- "multiple": false,
4325
- "options": [
4326
- "email_jsonl",
4327
- "thread_json"
4328
- ],
4329
- "type": "option"
4330
- },
4331
- "messages-per-room": {
4332
- "description": "How many messages per room when the type is email_jsonl (1-1000, default: 50)",
4333
- "name": "messages-per-room",
4334
- "default": 50,
4335
- "hasDynamicHelp": false,
4336
- "multiple": false,
4337
- "type": "option"
4338
- },
4339
- "strict": {
4340
- "description": "Reject the whole upload if any message is invalid. By default invalid messages are skipped and reported, because a corpus is statistical and a few bad lines are not worth losing the rest.",
4341
- "name": "strict",
4342
- "allowNo": false,
4343
- "type": "boolean"
4344
4278
  }
4345
4279
  },
4346
4280
  "hasDynamicHelp": false,
4347
4281
  "hiddenAliases": [],
4348
- "id": "style:upload",
4282
+ "id": "face:lock",
4349
4283
  "pluginAlias": "faces-cli",
4350
4284
  "pluginName": "faces-cli",
4351
4285
  "pluginType": "core",
@@ -4355,24 +4289,20 @@
4355
4289
  "relativePath": [
4356
4290
  "dist",
4357
4291
  "commands",
4358
- "style",
4359
- "upload.js"
4292
+ "face",
4293
+ "lock.js"
4360
4294
  ]
4361
4295
  },
4362
- "style:versions": {
4296
+ "face:neighbors": {
4363
4297
  "aliases": [],
4364
4298
  "args": {
4365
- "alias": {
4299
+ "face_id": {
4366
4300
  "description": "Face alias",
4367
- "name": "alias",
4301
+ "name": "face_id",
4368
4302
  "required": true
4369
4303
  }
4370
4304
  },
4371
- "description": "List the styles captured for a face, and which one it is writing in now. Each style:make keeps the previous one, so this is what style:revert has to go back to.",
4372
- "examples": [
4373
- "<%= config.bin %> <%= command.id %> alice",
4374
- "<%= config.bin %> <%= command.id %> alice --json"
4375
- ],
4305
+ "description": "Find the most similar or dissimilar owned faces to a given face",
4376
4306
  "flags": {
4377
4307
  "json": {
4378
4308
  "description": "Format output as json.",
@@ -4404,11 +4334,39 @@
4404
4334
  "hasDynamicHelp": false,
4405
4335
  "multiple": false,
4406
4336
  "type": "option"
4337
+ },
4338
+ "k": {
4339
+ "description": "Number of results (1–20)",
4340
+ "name": "k",
4341
+ "default": 5,
4342
+ "hasDynamicHelp": false,
4343
+ "multiple": false,
4344
+ "type": "option"
4345
+ },
4346
+ "component": {
4347
+ "description": "What to rank on: `face` for overall similarity, or a component position such as 1. Which positions are comparable varies; the API names them if you pick a wrong one.",
4348
+ "name": "component",
4349
+ "default": "face",
4350
+ "hasDynamicHelp": false,
4351
+ "multiple": false,
4352
+ "type": "option"
4353
+ },
4354
+ "direction": {
4355
+ "description": "nearest (most similar) or furthest (most dissimilar)",
4356
+ "name": "direction",
4357
+ "default": "nearest",
4358
+ "hasDynamicHelp": false,
4359
+ "multiple": false,
4360
+ "options": [
4361
+ "nearest",
4362
+ "furthest"
4363
+ ],
4364
+ "type": "option"
4407
4365
  }
4408
4366
  },
4409
4367
  "hasDynamicHelp": false,
4410
4368
  "hiddenAliases": [],
4411
- "id": "style:versions",
4369
+ "id": "face:neighbors",
4412
4370
  "pluginAlias": "faces-cli",
4413
4371
  "pluginName": "faces-cli",
4414
4372
  "pluginType": "core",
@@ -4418,20 +4376,23 @@
4418
4376
  "relativePath": [
4419
4377
  "dist",
4420
4378
  "commands",
4421
- "style",
4422
- "versions.js"
4379
+ "face",
4380
+ "neighbors.js"
4423
4381
  ]
4424
4382
  },
4425
- "team:add": {
4383
+ "face:publish": {
4426
4384
  "aliases": [],
4427
4385
  "args": {
4428
- "team_id": {
4429
- "description": "Team ID",
4430
- "name": "team_id",
4386
+ "alias": {
4387
+ "description": "Face alias",
4388
+ "name": "alias",
4431
4389
  "required": true
4432
4390
  }
4433
4391
  },
4434
- "description": "Add face(s) to a team",
4392
+ "description": "Publish a face so EVERY account can chat with it. This is a global override: while it is on, everyone can reach the face regardless of who it is shared with. You still pay only to compile it; whoever chats pays for their own inference.",
4393
+ "examples": [
4394
+ "<%= config.bin %> <%= command.id %> alice --yes"
4395
+ ],
4435
4396
  "flags": {
4436
4397
  "json": {
4437
4398
  "description": "Format output as json.",
@@ -4464,18 +4425,16 @@
4464
4425
  "multiple": false,
4465
4426
  "type": "option"
4466
4427
  },
4467
- "face": {
4468
- "description": "Face alias to add (repeatable)",
4469
- "name": "face",
4470
- "required": true,
4471
- "hasDynamicHelp": false,
4472
- "multiple": true,
4473
- "type": "option"
4428
+ "yes": {
4429
+ "description": "Skip confirmation",
4430
+ "name": "yes",
4431
+ "allowNo": false,
4432
+ "type": "boolean"
4474
4433
  }
4475
4434
  },
4476
4435
  "hasDynamicHelp": false,
4477
4436
  "hiddenAliases": [],
4478
- "id": "team:add",
4437
+ "id": "face:publish",
4479
4438
  "pluginAlias": "faces-cli",
4480
4439
  "pluginName": "faces-cli",
4481
4440
  "pluginType": "core",
@@ -4485,14 +4444,26 @@
4485
4444
  "relativePath": [
4486
4445
  "dist",
4487
4446
  "commands",
4488
- "team",
4489
- "add.js"
4447
+ "face",
4448
+ "publish.js"
4490
4449
  ]
4491
4450
  },
4492
- "team:create": {
4451
+ "face:share": {
4493
4452
  "aliases": [],
4494
- "args": {},
4495
- "description": "Create a new team",
4453
+ "args": {
4454
+ "alias": {
4455
+ "description": "Face alias",
4456
+ "name": "alias",
4457
+ "required": true
4458
+ }
4459
+ },
4460
+ "description": "Share a face so named accounts can chat with it. Sharing grants chat and nothing else: no reading its documents, no compiling, no re-sharing, and never its profile addendum. --add keeps the current list; --with replaces it.",
4461
+ "examples": [
4462
+ "<%= config.bin %> <%= command.id %> alice --list",
4463
+ "<%= config.bin %> <%= command.id %> alice --add dana",
4464
+ "<%= config.bin %> <%= command.id %> alice --with dana --with sam@example.com",
4465
+ "<%= config.bin %> <%= command.id %> alice --none --yes"
4466
+ ],
4496
4467
  "flags": {
4497
4468
  "json": {
4498
4469
  "description": "Format output as json.",
@@ -4525,46 +4496,54 @@
4525
4496
  "multiple": false,
4526
4497
  "type": "option"
4527
4498
  },
4528
- "name": {
4529
- "description": "Team name",
4530
- "name": "name",
4531
- "required": true,
4532
- "hasDynamicHelp": false,
4533
- "multiple": false,
4534
- "type": "option"
4499
+ "list": {
4500
+ "description": "Show who the face is shared with, and change nothing",
4501
+ "name": "list",
4502
+ "allowNo": false,
4503
+ "type": "boolean"
4535
4504
  },
4536
- "description": {
4537
- "description": "Plain-text team description (max 1500 chars)",
4538
- "name": "description",
4505
+ "add": {
4506
+ "description": "Add an account, keeping everyone already on the list — username or email (repeatable)",
4507
+ "exclusive": [
4508
+ "with",
4509
+ "none"
4510
+ ],
4511
+ "name": "add",
4539
4512
  "hasDynamicHelp": false,
4540
- "multiple": false,
4513
+ "multiple": true,
4541
4514
  "type": "option"
4542
4515
  },
4543
- "protocol": {
4544
- "description": "Protocol content (mermaid diagram or markdown, max 1000 words)",
4545
- "name": "protocol",
4516
+ "with": {
4517
+ "description": "Set the list to exactly these accounts, dropping anyone else (repeatable)",
4518
+ "exclusive": [
4519
+ "add",
4520
+ "none"
4521
+ ],
4522
+ "name": "with",
4546
4523
  "hasDynamicHelp": false,
4547
- "multiple": false,
4524
+ "multiple": true,
4548
4525
  "type": "option"
4549
4526
  },
4550
- "protocol-file": {
4551
- "description": "Read protocol from file",
4552
- "name": "protocol-file",
4553
- "hasDynamicHelp": false,
4554
- "multiple": false,
4555
- "type": "option"
4527
+ "none": {
4528
+ "description": "Revoke everyone",
4529
+ "exclusive": [
4530
+ "add",
4531
+ "with"
4532
+ ],
4533
+ "name": "none",
4534
+ "allowNo": false,
4535
+ "type": "boolean"
4556
4536
  },
4557
- "tag": {
4558
- "description": "Tag label (repeatable, lowercase)",
4559
- "name": "tag",
4560
- "hasDynamicHelp": false,
4561
- "multiple": true,
4562
- "type": "option"
4537
+ "yes": {
4538
+ "description": "Skip the confirmation shown when someone would lose access",
4539
+ "name": "yes",
4540
+ "allowNo": false,
4541
+ "type": "boolean"
4563
4542
  }
4564
4543
  },
4565
4544
  "hasDynamicHelp": false,
4566
4545
  "hiddenAliases": [],
4567
- "id": "team:create",
4546
+ "id": "face:share",
4568
4547
  "pluginAlias": "faces-cli",
4569
4548
  "pluginName": "faces-cli",
4570
4549
  "pluginType": "core",
@@ -4574,20 +4553,25 @@
4574
4553
  "relativePath": [
4575
4554
  "dist",
4576
4555
  "commands",
4577
- "team",
4578
- "create.js"
4556
+ "face",
4557
+ "share.js"
4579
4558
  ]
4580
4559
  },
4581
- "team:delete": {
4560
+ "face:sources": {
4582
4561
  "aliases": [],
4583
4562
  "args": {
4584
- "team_id": {
4585
- "description": "Team ID",
4586
- "name": "team_id",
4563
+ "alias": {
4564
+ "description": "Face alias",
4565
+ "name": "alias",
4587
4566
  "required": true
4588
4567
  }
4589
4568
  },
4590
- "description": "Delete a team",
4569
+ "description": "List every source compiled into a face: documents and threads together, one row each. Exits 4 if the face does not exist, which is a different answer from a face that has no sources. Content is never printed; read a single source with compile:doc:get or compile:thread:get.",
4570
+ "examples": [
4571
+ "<%= config.bin %> <%= command.id %> alice",
4572
+ "<%= config.bin %> <%= command.id %> alice --type thread",
4573
+ "<%= config.bin %> <%= command.id %> alice --json"
4574
+ ],
4591
4575
  "flags": {
4592
4576
  "json": {
4593
4577
  "description": "Format output as json.",
@@ -4620,16 +4604,21 @@
4620
4604
  "multiple": false,
4621
4605
  "type": "option"
4622
4606
  },
4623
- "yes": {
4624
- "description": "Skip confirmation",
4625
- "name": "yes",
4626
- "allowNo": false,
4627
- "type": "boolean"
4607
+ "type": {
4608
+ "description": "Show only one kind of source",
4609
+ "name": "type",
4610
+ "hasDynamicHelp": false,
4611
+ "multiple": false,
4612
+ "options": [
4613
+ "doc",
4614
+ "thread"
4615
+ ],
4616
+ "type": "option"
4628
4617
  }
4629
4618
  },
4630
4619
  "hasDynamicHelp": false,
4631
4620
  "hiddenAliases": [],
4632
- "id": "team:delete",
4621
+ "id": "face:sources",
4633
4622
  "pluginAlias": "faces-cli",
4634
4623
  "pluginName": "faces-cli",
4635
4624
  "pluginType": "core",
@@ -4639,20 +4628,14 @@
4639
4628
  "relativePath": [
4640
4629
  "dist",
4641
4630
  "commands",
4642
- "team",
4643
- "delete.js"
4631
+ "face",
4632
+ "sources.js"
4644
4633
  ]
4645
4634
  },
4646
- "team:edit": {
4635
+ "face:stats": {
4647
4636
  "aliases": [],
4648
- "args": {
4649
- "team_id": {
4650
- "description": "Team ID",
4651
- "name": "team_id",
4652
- "required": true
4653
- }
4654
- },
4655
- "description": "Edit a team",
4637
+ "args": {},
4638
+ "description": "Compile and chat stats for all owned faces",
4656
4639
  "flags": {
4657
4640
  "json": {
4658
4641
  "description": "Format output as json.",
@@ -4684,39 +4667,11 @@
4684
4667
  "hasDynamicHelp": false,
4685
4668
  "multiple": false,
4686
4669
  "type": "option"
4687
- },
4688
- "name": {
4689
- "description": "New team name",
4690
- "name": "name",
4691
- "hasDynamicHelp": false,
4692
- "multiple": false,
4693
- "type": "option"
4694
- },
4695
- "description": {
4696
- "description": "New description (max 1500 chars)",
4697
- "name": "description",
4698
- "hasDynamicHelp": false,
4699
- "multiple": false,
4700
- "type": "option"
4701
- },
4702
- "protocol": {
4703
- "description": "New protocol content",
4704
- "name": "protocol",
4705
- "hasDynamicHelp": false,
4706
- "multiple": false,
4707
- "type": "option"
4708
- },
4709
- "protocol-file": {
4710
- "description": "Read protocol from file",
4711
- "name": "protocol-file",
4712
- "hasDynamicHelp": false,
4713
- "multiple": false,
4714
- "type": "option"
4715
4670
  }
4716
4671
  },
4717
4672
  "hasDynamicHelp": false,
4718
4673
  "hiddenAliases": [],
4719
- "id": "team:edit",
4674
+ "id": "face:stats",
4720
4675
  "pluginAlias": "faces-cli",
4721
4676
  "pluginName": "faces-cli",
4722
4677
  "pluginType": "core",
@@ -4726,20 +4681,20 @@
4726
4681
  "relativePath": [
4727
4682
  "dist",
4728
4683
  "commands",
4729
- "team",
4730
- "edit.js"
4684
+ "face",
4685
+ "stats.js"
4731
4686
  ]
4732
4687
  },
4733
- "team:get": {
4688
+ "face:teams": {
4734
4689
  "aliases": [],
4735
4690
  "args": {
4736
- "team_id": {
4737
- "description": "Team ID",
4738
- "name": "team_id",
4691
+ "alias": {
4692
+ "description": "Face alias",
4693
+ "name": "alias",
4739
4694
  "required": true
4740
4695
  }
4741
4696
  },
4742
- "description": "Get a team by ID",
4697
+ "description": "Set a face's team memberships (replaces all)",
4743
4698
  "flags": {
4744
4699
  "json": {
4745
4700
  "description": "Format output as json.",
@@ -4771,11 +4726,19 @@
4771
4726
  "hasDynamicHelp": false,
4772
4727
  "multiple": false,
4773
4728
  "type": "option"
4729
+ },
4730
+ "team": {
4731
+ "description": "Team ID (repeatable, replaces all memberships)",
4732
+ "name": "team",
4733
+ "required": true,
4734
+ "hasDynamicHelp": false,
4735
+ "multiple": true,
4736
+ "type": "option"
4774
4737
  }
4775
4738
  },
4776
4739
  "hasDynamicHelp": false,
4777
4740
  "hiddenAliases": [],
4778
- "id": "team:get",
4741
+ "id": "face:teams",
4779
4742
  "pluginAlias": "faces-cli",
4780
4743
  "pluginName": "faces-cli",
4781
4744
  "pluginType": "core",
@@ -4785,14 +4748,23 @@
4785
4748
  "relativePath": [
4786
4749
  "dist",
4787
4750
  "commands",
4788
- "team",
4789
- "get.js"
4751
+ "face",
4752
+ "teams.js"
4790
4753
  ]
4791
4754
  },
4792
- "team:list": {
4755
+ "face:unlock": {
4793
4756
  "aliases": [],
4794
- "args": {},
4795
- "description": "List your teams",
4757
+ "args": {
4758
+ "face_id": {
4759
+ "description": "Face alias",
4760
+ "name": "face_id",
4761
+ "required": true
4762
+ }
4763
+ },
4764
+ "description": "Unlock a face (make it writable again). Thaws the face and everything it owns (documents, threads, voiceprint).",
4765
+ "examples": [
4766
+ "<%= config.bin %> <%= command.id %> socrates"
4767
+ ],
4796
4768
  "flags": {
4797
4769
  "json": {
4798
4770
  "description": "Format output as json.",
@@ -4828,7 +4800,7 @@
4828
4800
  },
4829
4801
  "hasDynamicHelp": false,
4830
4802
  "hiddenAliases": [],
4831
- "id": "team:list",
4803
+ "id": "face:unlock",
4832
4804
  "pluginAlias": "faces-cli",
4833
4805
  "pluginName": "faces-cli",
4834
4806
  "pluginType": "core",
@@ -4838,20 +4810,20 @@
4838
4810
  "relativePath": [
4839
4811
  "dist",
4840
4812
  "commands",
4841
- "team",
4842
- "list.js"
4813
+ "face",
4814
+ "unlock.js"
4843
4815
  ]
4844
4816
  },
4845
- "team:members": {
4817
+ "face:unpublish": {
4846
4818
  "aliases": [],
4847
4819
  "args": {
4848
- "team_id": {
4849
- "description": "Team ID",
4850
- "name": "team_id",
4820
+ "alias": {
4821
+ "description": "Face alias",
4822
+ "name": "alias",
4851
4823
  "required": true
4852
4824
  }
4853
4825
  },
4854
- "description": "List members of a team",
4826
+ "description": "Stop publishing a face. Anyone it is individually shared with keeps their access — publishing is an override on top of sharing, not a replacement for it.",
4855
4827
  "flags": {
4856
4828
  "json": {
4857
4829
  "description": "Format output as json.",
@@ -4887,7 +4859,7 @@
4887
4859
  },
4888
4860
  "hasDynamicHelp": false,
4889
4861
  "hiddenAliases": [],
4890
- "id": "team:members",
4862
+ "id": "face:unpublish",
4891
4863
  "pluginAlias": "faces-cli",
4892
4864
  "pluginName": "faces-cli",
4893
4865
  "pluginType": "core",
@@ -4897,25 +4869,24 @@
4897
4869
  "relativePath": [
4898
4870
  "dist",
4899
4871
  "commands",
4900
- "team",
4901
- "members.js"
4872
+ "face",
4873
+ "unpublish.js"
4902
4874
  ]
4903
4875
  },
4904
- "team:remove": {
4876
+ "face:unshare": {
4905
4877
  "aliases": [],
4906
4878
  "args": {
4907
- "team_id": {
4908
- "description": "Team ID",
4909
- "name": "team_id",
4910
- "required": true
4911
- },
4912
4879
  "alias": {
4913
- "description": "Face alias to remove",
4880
+ "description": "Face alias",
4914
4881
  "name": "alias",
4915
4882
  "required": true
4916
4883
  }
4917
4884
  },
4918
- "description": "Remove a face from a team",
4885
+ "description": "Revoke access to a shared face. Takes effect immediately — there is no grace period.",
4886
+ "examples": [
4887
+ "<%= config.bin %> <%= command.id %> alice --from dana --yes",
4888
+ "<%= config.bin %> <%= command.id %> alice --all --yes"
4889
+ ],
4919
4890
  "flags": {
4920
4891
  "json": {
4921
4892
  "description": "Format output as json.",
@@ -4947,11 +4918,36 @@
4947
4918
  "hasDynamicHelp": false,
4948
4919
  "multiple": false,
4949
4920
  "type": "option"
4921
+ },
4922
+ "from": {
4923
+ "description": "Account to revoke (repeatable)",
4924
+ "exclusive": [
4925
+ "all"
4926
+ ],
4927
+ "name": "from",
4928
+ "hasDynamicHelp": false,
4929
+ "multiple": true,
4930
+ "type": "option"
4931
+ },
4932
+ "all": {
4933
+ "description": "Revoke everyone",
4934
+ "exclusive": [
4935
+ "from"
4936
+ ],
4937
+ "name": "all",
4938
+ "allowNo": false,
4939
+ "type": "boolean"
4940
+ },
4941
+ "yes": {
4942
+ "description": "Skip confirmation",
4943
+ "name": "yes",
4944
+ "allowNo": false,
4945
+ "type": "boolean"
4950
4946
  }
4951
4947
  },
4952
4948
  "hasDynamicHelp": false,
4953
4949
  "hiddenAliases": [],
4954
- "id": "team:remove",
4950
+ "id": "face:unshare",
4955
4951
  "pluginAlias": "faces-cli",
4956
4952
  "pluginName": "faces-cli",
4957
4953
  "pluginType": "core",
@@ -4961,8 +4957,8 @@
4961
4957
  "relativePath": [
4962
4958
  "dist",
4963
4959
  "commands",
4964
- "team",
4965
- "remove.js"
4960
+ "face",
4961
+ "unshare.js"
4966
4962
  ]
4967
4963
  },
4968
4964
  "billing:subscription:activate": {
@@ -5208,7 +5204,7 @@
5208
5204
  "type": "option"
5209
5205
  },
5210
5206
  "medium": {
5211
- "description": "What sort of writing this is — e.g. email, text message, social post, essay, academic paper, blog post, legal document, thread reply, conversation (covers speech: transcripts, interviews, calls). Common synonyms fold automatically. Omit it if you do not know: a wrong declaration is worse than none, because a declaration is trusted and an absence is not.",
5207
+ "description": "What sort of writing this is — e.g. email, text message, social post, essay, academic paper, blog post, legal document, thread reply, conversation (dialogue: transcripts, interviews, calls), lecture (sustained speech nobody interrupts: talks, sermons, keynotes). Common synonyms fold automatically. Omit it if you do not know: a wrong declaration is worse than none, because a declaration is trusted and an absence is not.",
5212
5208
  "name": "medium",
5213
5209
  "hasDynamicHelp": false,
5214
5210
  "multiple": false,
@@ -5368,7 +5364,7 @@
5368
5364
  "type": "option"
5369
5365
  },
5370
5366
  "medium": {
5371
- "description": "What sort of writing this is — e.g. email, text message, social post, essay, academic paper, blog post, legal document, thread reply, conversation (covers speech: transcripts, interviews, calls). Common synonyms fold automatically. Omit it if you do not know: a wrong declaration is worse than none, because a declaration is trusted and an absence is not.",
5367
+ "description": "What sort of writing this is — e.g. email, text message, social post, essay, academic paper, blog post, legal document, thread reply, conversation (dialogue: transcripts, interviews, calls), lecture (sustained speech nobody interrupts: talks, sermons, keynotes). Common synonyms fold automatically. Omit it if you do not know: a wrong declaration is worse than none, because a declaration is trusted and an absence is not.",
5372
5368
  "name": "medium",
5373
5369
  "hasDynamicHelp": false,
5374
5370
  "multiple": false,
@@ -5534,7 +5530,7 @@
5534
5530
  "type": "option"
5535
5531
  },
5536
5532
  "medium": {
5537
- "description": "What sort of writing this is — e.g. email, text message, social post, essay, academic paper, blog post, legal document, thread reply, conversation (covers speech: transcripts, interviews, calls). Common synonyms fold automatically. Omit it if you do not know: a wrong declaration is worse than none, because a declaration is trusted and an absence is not.",
5533
+ "description": "What sort of writing this is — e.g. email, text message, social post, essay, academic paper, blog post, legal document, thread reply, conversation (dialogue: transcripts, interviews, calls), lecture (sustained speech nobody interrupts: talks, sermons, keynotes). Common synonyms fold automatically. Omit it if you do not know: a wrong declaration is worse than none, because a declaration is trusted and an absence is not.",
5538
5534
  "name": "medium",
5539
5535
  "hasDynamicHelp": false,
5540
5536
  "multiple": false,
@@ -5864,16 +5860,16 @@
5864
5860
  "reset.js"
5865
5861
  ]
5866
5862
  },
5867
- "face:tag:add": {
5863
+ "compile:thread:create": {
5868
5864
  "aliases": [],
5869
5865
  "args": {
5870
- "alias": {
5866
+ "face_id": {
5871
5867
  "description": "Face alias",
5872
- "name": "alias",
5868
+ "name": "face_id",
5873
5869
  "required": true
5874
5870
  }
5875
5871
  },
5876
- "description": "Add tags to a face (appends, idempotent)",
5872
+ "description": "Start a new thread for a face",
5877
5873
  "flags": {
5878
5874
  "json": {
5879
5875
  "description": "Format output as json.",
@@ -5906,18 +5902,23 @@
5906
5902
  "multiple": false,
5907
5903
  "type": "option"
5908
5904
  },
5909
- "tag": {
5910
- "description": "Tag to add (repeatable)",
5911
- "name": "tag",
5912
- "required": true,
5905
+ "label": {
5906
+ "description": "Thread label",
5907
+ "name": "label",
5913
5908
  "hasDynamicHelp": false,
5914
- "multiple": true,
5909
+ "multiple": false,
5915
5910
  "type": "option"
5911
+ },
5912
+ "oauth-only": {
5913
+ "description": "Prevent fallback to paid system key (use OAuth only)",
5914
+ "name": "oauth-only",
5915
+ "allowNo": false,
5916
+ "type": "boolean"
5916
5917
  }
5917
5918
  },
5918
5919
  "hasDynamicHelp": false,
5919
5920
  "hiddenAliases": [],
5920
- "id": "face:tag:add",
5921
+ "id": "compile:thread:create",
5921
5922
  "pluginAlias": "faces-cli",
5922
5923
  "pluginName": "faces-cli",
5923
5924
  "pluginType": "core",
@@ -5927,15 +5928,21 @@
5927
5928
  "relativePath": [
5928
5929
  "dist",
5929
5930
  "commands",
5930
- "face",
5931
- "tag",
5932
- "add.js"
5931
+ "compile",
5932
+ "thread",
5933
+ "create.js"
5933
5934
  ]
5934
5935
  },
5935
- "face:tag:all": {
5936
+ "compile:thread:delete": {
5936
5937
  "aliases": [],
5937
- "args": {},
5938
- "description": "List all tags across all your faces",
5938
+ "args": {
5939
+ "thread_id": {
5940
+ "description": "Thread ID",
5941
+ "name": "thread_id",
5942
+ "required": true
5943
+ }
5944
+ },
5945
+ "description": "Delete a thread",
5939
5946
  "flags": {
5940
5947
  "json": {
5941
5948
  "description": "Format output as json.",
@@ -5967,11 +5974,17 @@
5967
5974
  "hasDynamicHelp": false,
5968
5975
  "multiple": false,
5969
5976
  "type": "option"
5977
+ },
5978
+ "yes": {
5979
+ "description": "Skip confirmation",
5980
+ "name": "yes",
5981
+ "allowNo": false,
5982
+ "type": "boolean"
5970
5983
  }
5971
5984
  },
5972
5985
  "hasDynamicHelp": false,
5973
5986
  "hiddenAliases": [],
5974
- "id": "face:tag:all",
5987
+ "id": "compile:thread:delete",
5975
5988
  "pluginAlias": "faces-cli",
5976
5989
  "pluginName": "faces-cli",
5977
5990
  "pluginType": "core",
@@ -5981,21 +5994,21 @@
5981
5994
  "relativePath": [
5982
5995
  "dist",
5983
5996
  "commands",
5984
- "face",
5985
- "tag",
5986
- "all.js"
5997
+ "compile",
5998
+ "thread",
5999
+ "delete.js"
5987
6000
  ]
5988
6001
  },
5989
- "face:tag:list": {
6002
+ "compile:thread:edit": {
5990
6003
  "aliases": [],
5991
6004
  "args": {
5992
- "alias": {
5993
- "description": "Face alias",
5994
- "name": "alias",
6005
+ "thread_id": {
6006
+ "description": "Thread ID",
6007
+ "name": "thread_id",
5995
6008
  "required": true
5996
6009
  }
5997
6010
  },
5998
- "description": "List tags on a face",
6011
+ "description": "Edit a thread (label and/or reassign face speaker)",
5999
6012
  "flags": {
6000
6013
  "json": {
6001
6014
  "description": "Format output as json.",
@@ -6027,11 +6040,25 @@
6027
6040
  "hasDynamicHelp": false,
6028
6041
  "multiple": false,
6029
6042
  "type": "option"
6043
+ },
6044
+ "label": {
6045
+ "description": "New thread label",
6046
+ "name": "label",
6047
+ "hasDynamicHelp": false,
6048
+ "multiple": false,
6049
+ "type": "option"
6050
+ },
6051
+ "face-speaker": {
6052
+ "description": "Reassign face speaker: set this speaker to role=user, all others to role=assistant",
6053
+ "name": "face-speaker",
6054
+ "hasDynamicHelp": false,
6055
+ "multiple": false,
6056
+ "type": "option"
6030
6057
  }
6031
6058
  },
6032
6059
  "hasDynamicHelp": false,
6033
6060
  "hiddenAliases": [],
6034
- "id": "face:tag:list",
6061
+ "id": "compile:thread:edit",
6035
6062
  "pluginAlias": "faces-cli",
6036
6063
  "pluginName": "faces-cli",
6037
6064
  "pluginType": "core",
@@ -6041,26 +6068,21 @@
6041
6068
  "relativePath": [
6042
6069
  "dist",
6043
6070
  "commands",
6044
- "face",
6045
- "tag",
6046
- "list.js"
6071
+ "compile",
6072
+ "thread",
6073
+ "edit.js"
6047
6074
  ]
6048
6075
  },
6049
- "face:tag:remove": {
6076
+ "compile:thread:get": {
6050
6077
  "aliases": [],
6051
6078
  "args": {
6052
- "alias": {
6053
- "description": "Face alias",
6054
- "name": "alias",
6055
- "required": true
6056
- },
6057
- "tag": {
6058
- "description": "Tag to remove",
6059
- "name": "tag",
6079
+ "thread_id": {
6080
+ "description": "Thread ID",
6081
+ "name": "thread_id",
6060
6082
  "required": true
6061
6083
  }
6062
6084
  },
6063
- "description": "Remove a tag from a face",
6085
+ "description": "Get a thread by ID",
6064
6086
  "flags": {
6065
6087
  "json": {
6066
6088
  "description": "Format output as json.",
@@ -6096,7 +6118,7 @@
6096
6118
  },
6097
6119
  "hasDynamicHelp": false,
6098
6120
  "hiddenAliases": [],
6099
- "id": "face:tag:remove",
6121
+ "id": "compile:thread:get",
6100
6122
  "pluginAlias": "faces-cli",
6101
6123
  "pluginName": "faces-cli",
6102
6124
  "pluginType": "core",
@@ -6106,21 +6128,21 @@
6106
6128
  "relativePath": [
6107
6129
  "dist",
6108
6130
  "commands",
6109
- "face",
6110
- "tag",
6111
- "remove.js"
6131
+ "compile",
6132
+ "thread",
6133
+ "get.js"
6112
6134
  ]
6113
6135
  },
6114
- "face:tag:set": {
6136
+ "compile:thread:list": {
6115
6137
  "aliases": [],
6116
6138
  "args": {
6117
- "alias": {
6139
+ "face_id": {
6118
6140
  "description": "Face alias",
6119
- "name": "alias",
6141
+ "name": "face_id",
6120
6142
  "required": true
6121
6143
  }
6122
6144
  },
6123
- "description": "Replace all tags on a face",
6145
+ "description": "List threads for a face",
6124
6146
  "flags": {
6125
6147
  "json": {
6126
6148
  "description": "Format output as json.",
@@ -6152,19 +6174,11 @@
6152
6174
  "hasDynamicHelp": false,
6153
6175
  "multiple": false,
6154
6176
  "type": "option"
6155
- },
6156
- "tag": {
6157
- "description": "Tag to set (repeatable, replaces all)",
6158
- "name": "tag",
6159
- "required": true,
6160
- "hasDynamicHelp": false,
6161
- "multiple": true,
6162
- "type": "option"
6163
6177
  }
6164
6178
  },
6165
6179
  "hasDynamicHelp": false,
6166
6180
  "hiddenAliases": [],
6167
- "id": "face:tag:set",
6181
+ "id": "compile:thread:list",
6168
6182
  "pluginAlias": "faces-cli",
6169
6183
  "pluginName": "faces-cli",
6170
6184
  "pluginType": "core",
@@ -6174,21 +6188,21 @@
6174
6188
  "relativePath": [
6175
6189
  "dist",
6176
6190
  "commands",
6177
- "face",
6178
- "tag",
6179
- "set.js"
6191
+ "compile",
6192
+ "thread",
6193
+ "list.js"
6180
6194
  ]
6181
6195
  },
6182
- "team:tag:add": {
6196
+ "compile:thread:make": {
6183
6197
  "aliases": [],
6184
6198
  "args": {
6185
- "team_id": {
6186
- "description": "Team ID",
6187
- "name": "team_id",
6199
+ "thread_id": {
6200
+ "description": "Thread ID",
6201
+ "name": "thread_id",
6188
6202
  "required": true
6189
6203
  }
6190
6204
  },
6191
- "description": "Add tags to a team (appends, idempotent)",
6205
+ "description": "Compile an existing thread (prepare + sync in one step)",
6192
6206
  "flags": {
6193
6207
  "json": {
6194
6208
  "description": "Format output as json.",
@@ -6221,18 +6235,24 @@
6221
6235
  "multiple": false,
6222
6236
  "type": "option"
6223
6237
  },
6224
- "tag": {
6225
- "description": "Tag to add (repeatable)",
6226
- "name": "tag",
6227
- "required": true,
6238
+ "timeout": {
6239
+ "description": "Compile timeout in seconds (default: 600)",
6240
+ "name": "timeout",
6241
+ "default": 600,
6228
6242
  "hasDynamicHelp": false,
6229
- "multiple": true,
6243
+ "multiple": false,
6230
6244
  "type": "option"
6245
+ },
6246
+ "no-wait": {
6247
+ "description": "Return immediately after triggering compilation. Prints the thread ID for manual polling.",
6248
+ "name": "no-wait",
6249
+ "allowNo": false,
6250
+ "type": "boolean"
6231
6251
  }
6232
6252
  },
6233
6253
  "hasDynamicHelp": false,
6234
6254
  "hiddenAliases": [],
6235
- "id": "team:tag:add",
6255
+ "id": "compile:thread:make",
6236
6256
  "pluginAlias": "faces-cli",
6237
6257
  "pluginName": "faces-cli",
6238
6258
  "pluginType": "core",
@@ -6242,21 +6262,21 @@
6242
6262
  "relativePath": [
6243
6263
  "dist",
6244
6264
  "commands",
6245
- "team",
6246
- "tag",
6247
- "add.js"
6265
+ "compile",
6266
+ "thread",
6267
+ "make.js"
6248
6268
  ]
6249
6269
  },
6250
- "team:tag:list": {
6270
+ "compile:thread:message": {
6251
6271
  "aliases": [],
6252
6272
  "args": {
6253
- "team_id": {
6254
- "description": "Team ID",
6255
- "name": "team_id",
6273
+ "thread_id": {
6274
+ "description": "Thread ID",
6275
+ "name": "thread_id",
6256
6276
  "required": true
6257
6277
  }
6258
6278
  },
6259
- "description": "List tags on a team",
6279
+ "description": "Send a user message to a thread",
6260
6280
  "flags": {
6261
6281
  "json": {
6262
6282
  "description": "Format output as json.",
@@ -6288,11 +6308,26 @@
6288
6308
  "hasDynamicHelp": false,
6289
6309
  "multiple": false,
6290
6310
  "type": "option"
6311
+ },
6312
+ "message": {
6313
+ "char": "m",
6314
+ "description": "User message to append",
6315
+ "name": "message",
6316
+ "required": true,
6317
+ "hasDynamicHelp": false,
6318
+ "multiple": false,
6319
+ "type": "option"
6320
+ },
6321
+ "oauth-only": {
6322
+ "description": "Prevent fallback to paid system key (use OAuth only)",
6323
+ "name": "oauth-only",
6324
+ "allowNo": false,
6325
+ "type": "boolean"
6291
6326
  }
6292
6327
  },
6293
6328
  "hasDynamicHelp": false,
6294
6329
  "hiddenAliases": [],
6295
- "id": "team:tag:list",
6330
+ "id": "compile:thread:message",
6296
6331
  "pluginAlias": "faces-cli",
6297
6332
  "pluginName": "faces-cli",
6298
6333
  "pluginType": "core",
@@ -6302,26 +6337,21 @@
6302
6337
  "relativePath": [
6303
6338
  "dist",
6304
6339
  "commands",
6305
- "team",
6306
- "tag",
6307
- "list.js"
6340
+ "compile",
6341
+ "thread",
6342
+ "message.js"
6308
6343
  ]
6309
6344
  },
6310
- "team:tag:remove": {
6345
+ "compile:thread:pause": {
6311
6346
  "aliases": [],
6312
6347
  "args": {
6313
- "team_id": {
6314
- "description": "Team ID",
6315
- "name": "team_id",
6316
- "required": true
6317
- },
6318
- "tag": {
6319
- "description": "Tag to remove",
6320
- "name": "tag",
6348
+ "thread_id": {
6349
+ "description": "Thread ID",
6350
+ "name": "thread_id",
6321
6351
  "required": true
6322
6352
  }
6323
6353
  },
6324
- "description": "Remove a tag from a team",
6354
+ "description": "Ask a running thread compilation to stop (preserves progress, resume with make). The compile stops at the next chunk boundary; this waits for it unless --no-wait.",
6325
6355
  "flags": {
6326
6356
  "json": {
6327
6357
  "description": "Format output as json.",
@@ -6353,11 +6383,25 @@
6353
6383
  "hasDynamicHelp": false,
6354
6384
  "multiple": false,
6355
6385
  "type": "option"
6386
+ },
6387
+ "no-wait": {
6388
+ "description": "Return as soon as the pause is accepted, without waiting for the compile to stop.",
6389
+ "name": "no-wait",
6390
+ "allowNo": false,
6391
+ "type": "boolean"
6392
+ },
6393
+ "timeout": {
6394
+ "description": "Seconds to wait for the compile to stop (default: 60)",
6395
+ "name": "timeout",
6396
+ "default": 60,
6397
+ "hasDynamicHelp": false,
6398
+ "multiple": false,
6399
+ "type": "option"
6356
6400
  }
6357
6401
  },
6358
6402
  "hasDynamicHelp": false,
6359
6403
  "hiddenAliases": [],
6360
- "id": "team:tag:remove",
6404
+ "id": "compile:thread:pause",
6361
6405
  "pluginAlias": "faces-cli",
6362
6406
  "pluginName": "faces-cli",
6363
6407
  "pluginType": "core",
@@ -6367,21 +6411,21 @@
6367
6411
  "relativePath": [
6368
6412
  "dist",
6369
6413
  "commands",
6370
- "team",
6371
- "tag",
6372
- "remove.js"
6414
+ "compile",
6415
+ "thread",
6416
+ "pause.js"
6373
6417
  ]
6374
6418
  },
6375
- "team:tag:set": {
6419
+ "compile:thread:reset": {
6376
6420
  "aliases": [],
6377
6421
  "args": {
6378
- "team_id": {
6379
- "description": "Team ID",
6380
- "name": "team_id",
6422
+ "thread_id": {
6423
+ "description": "Thread ID",
6424
+ "name": "thread_id",
6381
6425
  "required": true
6382
6426
  }
6383
6427
  },
6384
- "description": "Replace all tags on a team",
6428
+ "description": "Reset thread compilation progress (wipe extraction, keep source messages)",
6385
6429
  "flags": {
6386
6430
  "json": {
6387
6431
  "description": "Format output as json.",
@@ -6414,18 +6458,16 @@
6414
6458
  "multiple": false,
6415
6459
  "type": "option"
6416
6460
  },
6417
- "tag": {
6418
- "description": "Tag to set (repeatable, replaces all)",
6419
- "name": "tag",
6420
- "required": true,
6421
- "hasDynamicHelp": false,
6422
- "multiple": true,
6423
- "type": "option"
6461
+ "yes": {
6462
+ "description": "Skip confirmation",
6463
+ "name": "yes",
6464
+ "allowNo": false,
6465
+ "type": "boolean"
6424
6466
  }
6425
6467
  },
6426
6468
  "hasDynamicHelp": false,
6427
6469
  "hiddenAliases": [],
6428
- "id": "team:tag:set",
6470
+ "id": "compile:thread:reset",
6429
6471
  "pluginAlias": "faces-cli",
6430
6472
  "pluginName": "faces-cli",
6431
6473
  "pluginType": "core",
@@ -6435,21 +6477,21 @@
6435
6477
  "relativePath": [
6436
6478
  "dist",
6437
6479
  "commands",
6438
- "team",
6439
- "tag",
6440
- "set.js"
6480
+ "compile",
6481
+ "thread",
6482
+ "reset.js"
6441
6483
  ]
6442
6484
  },
6443
- "compile:thread:create": {
6485
+ "compile:thread:sync": {
6444
6486
  "aliases": [],
6445
6487
  "args": {
6446
- "face_id": {
6447
- "description": "Face alias",
6448
- "name": "face_id",
6488
+ "thread_id": {
6489
+ "description": "Thread ID",
6490
+ "name": "thread_id",
6449
6491
  "required": true
6450
6492
  }
6451
6493
  },
6452
- "description": "Start a new thread for a face",
6494
+ "description": "Archive and sync a thread into a face",
6453
6495
  "flags": {
6454
6496
  "json": {
6455
6497
  "description": "Format output as json.",
@@ -6481,24 +6523,11 @@
6481
6523
  "hasDynamicHelp": false,
6482
6524
  "multiple": false,
6483
6525
  "type": "option"
6484
- },
6485
- "label": {
6486
- "description": "Thread label",
6487
- "name": "label",
6488
- "hasDynamicHelp": false,
6489
- "multiple": false,
6490
- "type": "option"
6491
- },
6492
- "oauth-only": {
6493
- "description": "Prevent fallback to paid system key (use OAuth only)",
6494
- "name": "oauth-only",
6495
- "allowNo": false,
6496
- "type": "boolean"
6497
6526
  }
6498
6527
  },
6499
6528
  "hasDynamicHelp": false,
6500
6529
  "hiddenAliases": [],
6501
- "id": "compile:thread:create",
6530
+ "id": "compile:thread:sync",
6502
6531
  "pluginAlias": "faces-cli",
6503
6532
  "pluginName": "faces-cli",
6504
6533
  "pluginType": "core",
@@ -6510,19 +6539,19 @@
6510
6539
  "commands",
6511
6540
  "compile",
6512
6541
  "thread",
6513
- "create.js"
6542
+ "sync.js"
6514
6543
  ]
6515
6544
  },
6516
- "compile:thread:delete": {
6545
+ "team:tag:add": {
6517
6546
  "aliases": [],
6518
6547
  "args": {
6519
- "thread_id": {
6520
- "description": "Thread ID",
6521
- "name": "thread_id",
6548
+ "team_id": {
6549
+ "description": "Team ID",
6550
+ "name": "team_id",
6522
6551
  "required": true
6523
6552
  }
6524
6553
  },
6525
- "description": "Delete a thread",
6554
+ "description": "Add tags to a team (appends, idempotent)",
6526
6555
  "flags": {
6527
6556
  "json": {
6528
6557
  "description": "Format output as json.",
@@ -6552,19 +6581,21 @@
6552
6581
  "env": "FACES_API_KEY",
6553
6582
  "name": "api-key",
6554
6583
  "hasDynamicHelp": false,
6555
- "multiple": false,
6584
+ "multiple": false,
6585
+ "type": "option"
6586
+ },
6587
+ "tag": {
6588
+ "description": "Tag to add (repeatable)",
6589
+ "name": "tag",
6590
+ "required": true,
6591
+ "hasDynamicHelp": false,
6592
+ "multiple": true,
6556
6593
  "type": "option"
6557
- },
6558
- "yes": {
6559
- "description": "Skip confirmation",
6560
- "name": "yes",
6561
- "allowNo": false,
6562
- "type": "boolean"
6563
6594
  }
6564
6595
  },
6565
6596
  "hasDynamicHelp": false,
6566
6597
  "hiddenAliases": [],
6567
- "id": "compile:thread:delete",
6598
+ "id": "team:tag:add",
6568
6599
  "pluginAlias": "faces-cli",
6569
6600
  "pluginName": "faces-cli",
6570
6601
  "pluginType": "core",
@@ -6574,21 +6605,21 @@
6574
6605
  "relativePath": [
6575
6606
  "dist",
6576
6607
  "commands",
6577
- "compile",
6578
- "thread",
6579
- "delete.js"
6608
+ "team",
6609
+ "tag",
6610
+ "add.js"
6580
6611
  ]
6581
6612
  },
6582
- "compile:thread:edit": {
6613
+ "team:tag:list": {
6583
6614
  "aliases": [],
6584
6615
  "args": {
6585
- "thread_id": {
6586
- "description": "Thread ID",
6587
- "name": "thread_id",
6616
+ "team_id": {
6617
+ "description": "Team ID",
6618
+ "name": "team_id",
6588
6619
  "required": true
6589
6620
  }
6590
6621
  },
6591
- "description": "Edit a thread (label and/or reassign face speaker)",
6622
+ "description": "List tags on a team",
6592
6623
  "flags": {
6593
6624
  "json": {
6594
6625
  "description": "Format output as json.",
@@ -6620,25 +6651,11 @@
6620
6651
  "hasDynamicHelp": false,
6621
6652
  "multiple": false,
6622
6653
  "type": "option"
6623
- },
6624
- "label": {
6625
- "description": "New thread label",
6626
- "name": "label",
6627
- "hasDynamicHelp": false,
6628
- "multiple": false,
6629
- "type": "option"
6630
- },
6631
- "face-speaker": {
6632
- "description": "Reassign face speaker: set this speaker to role=user, all others to role=assistant",
6633
- "name": "face-speaker",
6634
- "hasDynamicHelp": false,
6635
- "multiple": false,
6636
- "type": "option"
6637
6654
  }
6638
6655
  },
6639
6656
  "hasDynamicHelp": false,
6640
6657
  "hiddenAliases": [],
6641
- "id": "compile:thread:edit",
6658
+ "id": "team:tag:list",
6642
6659
  "pluginAlias": "faces-cli",
6643
6660
  "pluginName": "faces-cli",
6644
6661
  "pluginType": "core",
@@ -6648,21 +6665,26 @@
6648
6665
  "relativePath": [
6649
6666
  "dist",
6650
6667
  "commands",
6651
- "compile",
6652
- "thread",
6653
- "edit.js"
6668
+ "team",
6669
+ "tag",
6670
+ "list.js"
6654
6671
  ]
6655
6672
  },
6656
- "compile:thread:get": {
6673
+ "team:tag:remove": {
6657
6674
  "aliases": [],
6658
6675
  "args": {
6659
- "thread_id": {
6660
- "description": "Thread ID",
6661
- "name": "thread_id",
6676
+ "team_id": {
6677
+ "description": "Team ID",
6678
+ "name": "team_id",
6679
+ "required": true
6680
+ },
6681
+ "tag": {
6682
+ "description": "Tag to remove",
6683
+ "name": "tag",
6662
6684
  "required": true
6663
6685
  }
6664
6686
  },
6665
- "description": "Get a thread by ID",
6687
+ "description": "Remove a tag from a team",
6666
6688
  "flags": {
6667
6689
  "json": {
6668
6690
  "description": "Format output as json.",
@@ -6698,7 +6720,7 @@
6698
6720
  },
6699
6721
  "hasDynamicHelp": false,
6700
6722
  "hiddenAliases": [],
6701
- "id": "compile:thread:get",
6723
+ "id": "team:tag:remove",
6702
6724
  "pluginAlias": "faces-cli",
6703
6725
  "pluginName": "faces-cli",
6704
6726
  "pluginType": "core",
@@ -6708,21 +6730,21 @@
6708
6730
  "relativePath": [
6709
6731
  "dist",
6710
6732
  "commands",
6711
- "compile",
6712
- "thread",
6713
- "get.js"
6733
+ "team",
6734
+ "tag",
6735
+ "remove.js"
6714
6736
  ]
6715
6737
  },
6716
- "compile:thread:list": {
6738
+ "team:tag:set": {
6717
6739
  "aliases": [],
6718
6740
  "args": {
6719
- "face_id": {
6720
- "description": "Face alias",
6721
- "name": "face_id",
6741
+ "team_id": {
6742
+ "description": "Team ID",
6743
+ "name": "team_id",
6722
6744
  "required": true
6723
6745
  }
6724
6746
  },
6725
- "description": "List threads for a face",
6747
+ "description": "Replace all tags on a team",
6726
6748
  "flags": {
6727
6749
  "json": {
6728
6750
  "description": "Format output as json.",
@@ -6754,11 +6776,19 @@
6754
6776
  "hasDynamicHelp": false,
6755
6777
  "multiple": false,
6756
6778
  "type": "option"
6779
+ },
6780
+ "tag": {
6781
+ "description": "Tag to set (repeatable, replaces all)",
6782
+ "name": "tag",
6783
+ "required": true,
6784
+ "hasDynamicHelp": false,
6785
+ "multiple": true,
6786
+ "type": "option"
6757
6787
  }
6758
6788
  },
6759
6789
  "hasDynamicHelp": false,
6760
6790
  "hiddenAliases": [],
6761
- "id": "compile:thread:list",
6791
+ "id": "team:tag:set",
6762
6792
  "pluginAlias": "faces-cli",
6763
6793
  "pluginName": "faces-cli",
6764
6794
  "pluginType": "core",
@@ -6768,21 +6798,21 @@
6768
6798
  "relativePath": [
6769
6799
  "dist",
6770
6800
  "commands",
6771
- "compile",
6772
- "thread",
6773
- "list.js"
6801
+ "team",
6802
+ "tag",
6803
+ "set.js"
6774
6804
  ]
6775
6805
  },
6776
- "compile:thread:make": {
6806
+ "face:tag:add": {
6777
6807
  "aliases": [],
6778
6808
  "args": {
6779
- "thread_id": {
6780
- "description": "Thread ID",
6781
- "name": "thread_id",
6809
+ "alias": {
6810
+ "description": "Face alias",
6811
+ "name": "alias",
6782
6812
  "required": true
6783
6813
  }
6784
6814
  },
6785
- "description": "Compile an existing thread (prepare + sync in one step)",
6815
+ "description": "Add tags to a face (appends, idempotent)",
6786
6816
  "flags": {
6787
6817
  "json": {
6788
6818
  "description": "Format output as json.",
@@ -6815,24 +6845,18 @@
6815
6845
  "multiple": false,
6816
6846
  "type": "option"
6817
6847
  },
6818
- "timeout": {
6819
- "description": "Compile timeout in seconds (default: 600)",
6820
- "name": "timeout",
6821
- "default": 600,
6848
+ "tag": {
6849
+ "description": "Tag to add (repeatable)",
6850
+ "name": "tag",
6851
+ "required": true,
6822
6852
  "hasDynamicHelp": false,
6823
- "multiple": false,
6853
+ "multiple": true,
6824
6854
  "type": "option"
6825
- },
6826
- "no-wait": {
6827
- "description": "Return immediately after triggering compilation. Prints the thread ID for manual polling.",
6828
- "name": "no-wait",
6829
- "allowNo": false,
6830
- "type": "boolean"
6831
6855
  }
6832
6856
  },
6833
6857
  "hasDynamicHelp": false,
6834
6858
  "hiddenAliases": [],
6835
- "id": "compile:thread:make",
6859
+ "id": "face:tag:add",
6836
6860
  "pluginAlias": "faces-cli",
6837
6861
  "pluginName": "faces-cli",
6838
6862
  "pluginType": "core",
@@ -6842,21 +6866,15 @@
6842
6866
  "relativePath": [
6843
6867
  "dist",
6844
6868
  "commands",
6845
- "compile",
6846
- "thread",
6847
- "make.js"
6869
+ "face",
6870
+ "tag",
6871
+ "add.js"
6848
6872
  ]
6849
6873
  },
6850
- "compile:thread:message": {
6874
+ "face:tag:all": {
6851
6875
  "aliases": [],
6852
- "args": {
6853
- "thread_id": {
6854
- "description": "Thread ID",
6855
- "name": "thread_id",
6856
- "required": true
6857
- }
6858
- },
6859
- "description": "Send a user message to a thread",
6876
+ "args": {},
6877
+ "description": "List all tags across all your faces",
6860
6878
  "flags": {
6861
6879
  "json": {
6862
6880
  "description": "Format output as json.",
@@ -6888,26 +6906,11 @@
6888
6906
  "hasDynamicHelp": false,
6889
6907
  "multiple": false,
6890
6908
  "type": "option"
6891
- },
6892
- "message": {
6893
- "char": "m",
6894
- "description": "User message to append",
6895
- "name": "message",
6896
- "required": true,
6897
- "hasDynamicHelp": false,
6898
- "multiple": false,
6899
- "type": "option"
6900
- },
6901
- "oauth-only": {
6902
- "description": "Prevent fallback to paid system key (use OAuth only)",
6903
- "name": "oauth-only",
6904
- "allowNo": false,
6905
- "type": "boolean"
6906
6909
  }
6907
6910
  },
6908
6911
  "hasDynamicHelp": false,
6909
6912
  "hiddenAliases": [],
6910
- "id": "compile:thread:message",
6913
+ "id": "face:tag:all",
6911
6914
  "pluginAlias": "faces-cli",
6912
6915
  "pluginName": "faces-cli",
6913
6916
  "pluginType": "core",
@@ -6917,21 +6920,21 @@
6917
6920
  "relativePath": [
6918
6921
  "dist",
6919
6922
  "commands",
6920
- "compile",
6921
- "thread",
6922
- "message.js"
6923
+ "face",
6924
+ "tag",
6925
+ "all.js"
6923
6926
  ]
6924
6927
  },
6925
- "compile:thread:pause": {
6928
+ "face:tag:list": {
6926
6929
  "aliases": [],
6927
6930
  "args": {
6928
- "thread_id": {
6929
- "description": "Thread ID",
6930
- "name": "thread_id",
6931
+ "alias": {
6932
+ "description": "Face alias",
6933
+ "name": "alias",
6931
6934
  "required": true
6932
6935
  }
6933
6936
  },
6934
- "description": "Ask a running thread compilation to stop (preserves progress, resume with make). The compile stops at the next chunk boundary; this waits for it unless --no-wait.",
6937
+ "description": "List tags on a face",
6935
6938
  "flags": {
6936
6939
  "json": {
6937
6940
  "description": "Format output as json.",
@@ -6963,25 +6966,11 @@
6963
6966
  "hasDynamicHelp": false,
6964
6967
  "multiple": false,
6965
6968
  "type": "option"
6966
- },
6967
- "no-wait": {
6968
- "description": "Return as soon as the pause is accepted, without waiting for the compile to stop.",
6969
- "name": "no-wait",
6970
- "allowNo": false,
6971
- "type": "boolean"
6972
- },
6973
- "timeout": {
6974
- "description": "Seconds to wait for the compile to stop (default: 60)",
6975
- "name": "timeout",
6976
- "default": 60,
6977
- "hasDynamicHelp": false,
6978
- "multiple": false,
6979
- "type": "option"
6980
6969
  }
6981
6970
  },
6982
6971
  "hasDynamicHelp": false,
6983
6972
  "hiddenAliases": [],
6984
- "id": "compile:thread:pause",
6973
+ "id": "face:tag:list",
6985
6974
  "pluginAlias": "faces-cli",
6986
6975
  "pluginName": "faces-cli",
6987
6976
  "pluginType": "core",
@@ -6991,21 +6980,26 @@
6991
6980
  "relativePath": [
6992
6981
  "dist",
6993
6982
  "commands",
6994
- "compile",
6995
- "thread",
6996
- "pause.js"
6983
+ "face",
6984
+ "tag",
6985
+ "list.js"
6997
6986
  ]
6998
6987
  },
6999
- "compile:thread:reset": {
6988
+ "face:tag:remove": {
7000
6989
  "aliases": [],
7001
6990
  "args": {
7002
- "thread_id": {
7003
- "description": "Thread ID",
7004
- "name": "thread_id",
6991
+ "alias": {
6992
+ "description": "Face alias",
6993
+ "name": "alias",
6994
+ "required": true
6995
+ },
6996
+ "tag": {
6997
+ "description": "Tag to remove",
6998
+ "name": "tag",
7005
6999
  "required": true
7006
7000
  }
7007
7001
  },
7008
- "description": "Reset thread compilation progress (wipe extraction, keep source messages)",
7002
+ "description": "Remove a tag from a face",
7009
7003
  "flags": {
7010
7004
  "json": {
7011
7005
  "description": "Format output as json.",
@@ -7037,17 +7031,11 @@
7037
7031
  "hasDynamicHelp": false,
7038
7032
  "multiple": false,
7039
7033
  "type": "option"
7040
- },
7041
- "yes": {
7042
- "description": "Skip confirmation",
7043
- "name": "yes",
7044
- "allowNo": false,
7045
- "type": "boolean"
7046
7034
  }
7047
7035
  },
7048
7036
  "hasDynamicHelp": false,
7049
7037
  "hiddenAliases": [],
7050
- "id": "compile:thread:reset",
7038
+ "id": "face:tag:remove",
7051
7039
  "pluginAlias": "faces-cli",
7052
7040
  "pluginName": "faces-cli",
7053
7041
  "pluginType": "core",
@@ -7057,21 +7045,21 @@
7057
7045
  "relativePath": [
7058
7046
  "dist",
7059
7047
  "commands",
7060
- "compile",
7061
- "thread",
7062
- "reset.js"
7048
+ "face",
7049
+ "tag",
7050
+ "remove.js"
7063
7051
  ]
7064
7052
  },
7065
- "compile:thread:sync": {
7053
+ "face:tag:set": {
7066
7054
  "aliases": [],
7067
7055
  "args": {
7068
- "thread_id": {
7069
- "description": "Thread ID",
7070
- "name": "thread_id",
7056
+ "alias": {
7057
+ "description": "Face alias",
7058
+ "name": "alias",
7071
7059
  "required": true
7072
7060
  }
7073
7061
  },
7074
- "description": "Archive and sync a thread into a face",
7062
+ "description": "Replace all tags on a face",
7075
7063
  "flags": {
7076
7064
  "json": {
7077
7065
  "description": "Format output as json.",
@@ -7103,11 +7091,19 @@
7103
7091
  "hasDynamicHelp": false,
7104
7092
  "multiple": false,
7105
7093
  "type": "option"
7094
+ },
7095
+ "tag": {
7096
+ "description": "Tag to set (repeatable, replaces all)",
7097
+ "name": "tag",
7098
+ "required": true,
7099
+ "hasDynamicHelp": false,
7100
+ "multiple": true,
7101
+ "type": "option"
7106
7102
  }
7107
7103
  },
7108
7104
  "hasDynamicHelp": false,
7109
7105
  "hiddenAliases": [],
7110
- "id": "compile:thread:sync",
7106
+ "id": "face:tag:set",
7111
7107
  "pluginAlias": "faces-cli",
7112
7108
  "pluginName": "faces-cli",
7113
7109
  "pluginType": "core",
@@ -7117,11 +7113,11 @@
7117
7113
  "relativePath": [
7118
7114
  "dist",
7119
7115
  "commands",
7120
- "compile",
7121
- "thread",
7122
- "sync.js"
7116
+ "face",
7117
+ "tag",
7118
+ "set.js"
7123
7119
  ]
7124
7120
  }
7125
7121
  },
7126
- "version": "1.8.0"
7122
+ "version": "1.8.2"
7127
7123
  }