faces-cli 1.8.4 → 1.8.5

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.
@@ -1261,10 +1261,21 @@
1261
1261
  "restore.js"
1262
1262
  ]
1263
1263
  },
1264
- "compile:all": {
1264
+ "chat:chat": {
1265
1265
  "aliases": [],
1266
- "args": {},
1267
- "description": "Compile all uncompiled documents and threads across all faces",
1266
+ "args": {
1267
+ "face_username": {
1268
+ "description": "Face alias (alias@model, owner:alias@model for a published face, or a composite formula like \"(a | b)@model\"). Omit when using --formula.",
1269
+ "name": "face_username",
1270
+ "required": false
1271
+ }
1272
+ },
1273
+ "description": "Chat via a face. Auto-routes to the correct API endpoint based on the model catalog.",
1274
+ "examples": [
1275
+ "<%= config.bin %> <%= command.id %> socrates -m \"What is virtue?\"",
1276
+ "<%= config.bin %> <%= command.id %> \"(socrates | nietzsche)@claude-sonnet-4-6\" -m \"What is virtue?\"",
1277
+ "<%= config.bin %> <%= command.id %> --formula \"socrates | nietzsche\" --llm claude-sonnet-4-6 -m \"What is virtue?\""
1278
+ ],
1268
1279
  "flags": {
1269
1280
  "json": {
1270
1281
  "description": "Format output as json.",
@@ -1297,18 +1308,86 @@
1297
1308
  "multiple": false,
1298
1309
  "type": "option"
1299
1310
  },
1300
- "timeout": {
1301
- "description": "Per-item compile timeout in seconds (default: 600)",
1302
- "name": "timeout",
1303
- "default": 600,
1311
+ "message": {
1312
+ "char": "m",
1313
+ "description": "User message (repeatable)",
1314
+ "name": "message",
1315
+ "required": false,
1316
+ "hasDynamicHelp": false,
1317
+ "multiple": true,
1318
+ "type": "option"
1319
+ },
1320
+ "llm": {
1321
+ "description": "LLM override (e.g. gpt-4o-mini, claude-sonnet-4-6)",
1322
+ "name": "llm",
1323
+ "hasDynamicHelp": false,
1324
+ "multiple": false,
1325
+ "type": "option"
1326
+ },
1327
+ "formula": {
1328
+ "description": "Compose a run-time composite from your own faces, e.g. \"socrates | nietzsche\" (operators: | & ^ -). Requires --llm. The composite takes the name of its first operand; use face:create --formula for a named, persisted composite.",
1329
+ "name": "formula",
1330
+ "hasDynamicHelp": false,
1331
+ "multiple": false,
1332
+ "type": "option"
1333
+ },
1334
+ "system": {
1335
+ "description": "System prompt / instructions",
1336
+ "name": "system",
1337
+ "hasDynamicHelp": false,
1338
+ "multiple": false,
1339
+ "type": "option"
1340
+ },
1341
+ "stream": {
1342
+ "description": "Stream the response",
1343
+ "name": "stream",
1344
+ "allowNo": false,
1345
+ "type": "boolean"
1346
+ },
1347
+ "max-tokens": {
1348
+ "description": "Max tokens",
1349
+ "name": "max-tokens",
1350
+ "hasDynamicHelp": false,
1351
+ "multiple": false,
1352
+ "type": "option"
1353
+ },
1354
+ "temperature": {
1355
+ "description": "Temperature (0.0-2.0)",
1356
+ "name": "temperature",
1357
+ "hasDynamicHelp": false,
1358
+ "multiple": false,
1359
+ "type": "option"
1360
+ },
1361
+ "file": {
1362
+ "description": "Read message from file",
1363
+ "name": "file",
1364
+ "hasDynamicHelp": false,
1365
+ "multiple": false,
1366
+ "type": "option"
1367
+ },
1368
+ "responses": {
1369
+ "description": "Force the OpenAI Responses API endpoint (escape hatch; routing is automatic otherwise)",
1370
+ "name": "responses",
1371
+ "allowNo": false,
1372
+ "type": "boolean"
1373
+ },
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 (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
+ "name": "medium",
1304
1377
  "hasDynamicHelp": false,
1305
1378
  "multiple": false,
1306
1379
  "type": "option"
1380
+ },
1381
+ "oauth-only": {
1382
+ "description": "Prevent fallback to paid system key (use OAuth only)",
1383
+ "name": "oauth-only",
1384
+ "allowNo": false,
1385
+ "type": "boolean"
1307
1386
  }
1308
1387
  },
1309
1388
  "hasDynamicHelp": false,
1310
1389
  "hiddenAliases": [],
1311
- "id": "compile:all",
1390
+ "id": "chat:chat",
1312
1391
  "pluginAlias": "faces-cli",
1313
1392
  "pluginName": "faces-cli",
1314
1393
  "pluginType": "core",
@@ -1318,20 +1397,20 @@
1318
1397
  "relativePath": [
1319
1398
  "dist",
1320
1399
  "commands",
1321
- "compile",
1322
- "all.js"
1400
+ "chat",
1401
+ "chat.js"
1323
1402
  ]
1324
1403
  },
1325
- "compile:import": {
1404
+ "chat:messages": {
1326
1405
  "aliases": [],
1327
1406
  "args": {
1328
- "face_id": {
1329
- "description": "Face alias",
1330
- "name": "face_id",
1407
+ "face_model": {
1408
+ "description": "Face model (e.g. myface, myface@claude-sonnet-4-6, or head:socrates@claude-sonnet-4-6)",
1409
+ "name": "face_model",
1331
1410
  "required": true
1332
1411
  }
1333
1412
  },
1334
- "description": "Import a YouTube video into a face via server-side download and transcription",
1413
+ "description": "Anthropic Messages API proxy via a face (alias: chat:chat auto-routes Anthropic models here)",
1335
1414
  "flags": {
1336
1415
  "json": {
1337
1416
  "description": "Format output as json.",
@@ -1364,55 +1443,53 @@
1364
1443
  "multiple": false,
1365
1444
  "type": "option"
1366
1445
  },
1367
- "url": {
1368
- "description": "YouTube URL (youtube.com/watch?v=... or youtu.be/...)",
1369
- "name": "url",
1446
+ "message": {
1447
+ "char": "m",
1448
+ "description": "User message (repeatable)",
1449
+ "name": "message",
1370
1450
  "required": true,
1371
1451
  "hasDynamicHelp": false,
1372
- "multiple": false,
1452
+ "multiple": true,
1373
1453
  "type": "option"
1374
1454
  },
1375
- "type": {
1376
- "description": "\"document\" for solo talks, lectures, monologues; \"thread\" for interviews or multi-speaker conversations",
1377
- "name": "type",
1378
- "default": "document",
1455
+ "system": {
1456
+ "description": "System prompt",
1457
+ "name": "system",
1379
1458
  "hasDynamicHelp": false,
1380
1459
  "multiple": false,
1381
- "options": [
1382
- "document",
1383
- "thread"
1384
- ],
1385
1460
  "type": "option"
1386
1461
  },
1387
- "perspective": {
1388
- "description": "\"first-person\" if the face is the speaker; \"third-person\" if the video is about the face",
1389
- "name": "perspective",
1390
- "default": "third-person",
1462
+ "stream": {
1463
+ "description": "Stream the response",
1464
+ "name": "stream",
1465
+ "allowNo": false,
1466
+ "type": "boolean"
1467
+ },
1468
+ "max-tokens": {
1469
+ "description": "Max tokens",
1470
+ "name": "max-tokens",
1471
+ "default": 1024,
1391
1472
  "hasDynamicHelp": false,
1392
1473
  "multiple": false,
1393
- "options": [
1394
- "first-person",
1395
- "third-person"
1396
- ],
1397
1474
  "type": "option"
1398
1475
  },
1399
- "face-speaker": {
1400
- "description": "For --type thread: AssemblyAI speaker label (e.g. \"A\") that corresponds to the face. Defaults to first detected speaker.",
1401
- "name": "face-speaker",
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 (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
+ "name": "medium",
1402
1479
  "hasDynamicHelp": false,
1403
1480
  "multiple": false,
1404
1481
  "type": "option"
1405
1482
  },
1406
- "no-wait": {
1407
- "description": "Return immediately after import starts (do not poll for transcription). Prints the ID for manual polling.",
1408
- "name": "no-wait",
1483
+ "oauth-only": {
1484
+ "description": "Prevent fallback to paid system key (use OAuth only)",
1485
+ "name": "oauth-only",
1409
1486
  "allowNo": false,
1410
1487
  "type": "boolean"
1411
1488
  }
1412
1489
  },
1413
1490
  "hasDynamicHelp": false,
1414
1491
  "hiddenAliases": [],
1415
- "id": "compile:import",
1492
+ "id": "chat:messages",
1416
1493
  "pluginAlias": "faces-cli",
1417
1494
  "pluginName": "faces-cli",
1418
1495
  "pluginType": "core",
@@ -1422,14 +1499,20 @@
1422
1499
  "relativePath": [
1423
1500
  "dist",
1424
1501
  "commands",
1425
- "compile",
1426
- "import.js"
1502
+ "chat",
1503
+ "messages.js"
1427
1504
  ]
1428
1505
  },
1429
- "compile:stats": {
1506
+ "chat:responses": {
1430
1507
  "aliases": [],
1431
- "args": {},
1432
- "description": "Show compilation stats per face",
1508
+ "args": {
1509
+ "face_model": {
1510
+ "description": "Face model (e.g. myface, myface@gpt-4o, or head:socrates@gpt-5.4)",
1511
+ "name": "face_model",
1512
+ "required": true
1513
+ }
1514
+ },
1515
+ "description": "OpenAI Responses API proxy via a face (alias: chat:chat --responses)",
1433
1516
  "flags": {
1434
1517
  "json": {
1435
1518
  "description": "Format output as json.",
@@ -1461,11 +1544,46 @@
1461
1544
  "hasDynamicHelp": false,
1462
1545
  "multiple": false,
1463
1546
  "type": "option"
1547
+ },
1548
+ "message": {
1549
+ "char": "m",
1550
+ "description": "User input message",
1551
+ "name": "message",
1552
+ "required": true,
1553
+ "hasDynamicHelp": false,
1554
+ "multiple": false,
1555
+ "type": "option"
1556
+ },
1557
+ "instructions": {
1558
+ "description": "System instructions",
1559
+ "name": "instructions",
1560
+ "hasDynamicHelp": false,
1561
+ "multiple": false,
1562
+ "type": "option"
1563
+ },
1564
+ "stream": {
1565
+ "description": "Stream the response",
1566
+ "name": "stream",
1567
+ "allowNo": false,
1568
+ "type": "boolean"
1569
+ },
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 (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
+ "name": "medium",
1573
+ "hasDynamicHelp": false,
1574
+ "multiple": false,
1575
+ "type": "option"
1576
+ },
1577
+ "oauth-only": {
1578
+ "description": "Prevent fallback to paid system key (use OAuth only)",
1579
+ "name": "oauth-only",
1580
+ "allowNo": false,
1581
+ "type": "boolean"
1464
1582
  }
1465
1583
  },
1466
1584
  "hasDynamicHelp": false,
1467
1585
  "hiddenAliases": [],
1468
- "id": "compile:stats",
1586
+ "id": "chat:responses",
1469
1587
  "pluginAlias": "faces-cli",
1470
1588
  "pluginName": "faces-cli",
1471
1589
  "pluginType": "core",
@@ -1475,20 +1593,27 @@
1475
1593
  "relativePath": [
1476
1594
  "dist",
1477
1595
  "commands",
1478
- "compile",
1479
- "stats.js"
1596
+ "chat",
1597
+ "responses.js"
1480
1598
  ]
1481
1599
  },
1482
- "compile:upload": {
1600
+ "chat:thread": {
1483
1601
  "aliases": [],
1484
1602
  "args": {
1485
- "alias": {
1486
- "description": "Face alias",
1487
- "name": "alias",
1488
- "required": true
1603
+ "face_username": {
1604
+ "description": "Face alias (alias@model, or owner:alias@model for a published face) — required when starting a new thread",
1605
+ "name": "face_username",
1606
+ "required": false
1489
1607
  }
1490
1608
  },
1491
- "description": "Upload a file (text/PDF/Word .docx/audio/video) to compile into a face",
1609
+ "description": "Multi-turn chat thread. Conversation history is stored under ~/.faces/threads/<id>.json resume any thread later with --id.",
1610
+ "examples": [
1611
+ "<%= config.bin %> <%= command.id %> socrates -m \"What is justice?\"",
1612
+ "<%= config.bin %> <%= command.id %> --id t_abc123 -m \"Say more about that\"",
1613
+ "<%= config.bin %> <%= command.id %> --list",
1614
+ "<%= config.bin %> <%= command.id %> --id t_abc123 --show",
1615
+ "<%= config.bin %> <%= command.id %> --id t_abc123 --delete"
1616
+ ],
1492
1617
  "flags": {
1493
1618
  "json": {
1494
1619
  "description": "Format output as json.",
@@ -1521,62 +1646,97 @@
1521
1646
  "multiple": false,
1522
1647
  "type": "option"
1523
1648
  },
1524
- "file": {
1525
- "description": "File to upload",
1526
- "name": "file",
1527
- "required": true,
1649
+ "id": {
1650
+ "description": "Resume an existing thread by id",
1651
+ "name": "id",
1528
1652
  "hasDynamicHelp": false,
1529
1653
  "multiple": false,
1530
1654
  "type": "option"
1531
1655
  },
1532
- "kind": {
1533
- "description": "Upload kind: document or thread",
1534
- "name": "kind",
1535
- "default": "document",
1656
+ "message": {
1657
+ "char": "m",
1658
+ "description": "User message",
1659
+ "name": "message",
1536
1660
  "hasDynamicHelp": false,
1537
1661
  "multiple": false,
1538
- "options": [
1539
- "document",
1540
- "thread"
1541
- ],
1542
1662
  "type": "option"
1543
1663
  },
1544
- "perspective": {
1545
- "description": "Perspective (document only)",
1546
- "name": "perspective",
1547
- "default": "third-person",
1664
+ "file": {
1665
+ "description": "Read message from file",
1666
+ "name": "file",
1548
1667
  "hasDynamicHelp": false,
1549
1668
  "multiple": false,
1550
- "options": [
1551
- "first-person",
1552
- "third-person"
1553
- ],
1554
1669
  "type": "option"
1555
1670
  },
1556
- "medium": {
1557
- "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.",
1558
- "name": "medium",
1671
+ "llm": {
1672
+ "description": "LLM override (only honored when starting a new thread)",
1673
+ "name": "llm",
1559
1674
  "hasDynamicHelp": false,
1560
1675
  "multiple": false,
1561
1676
  "type": "option"
1562
1677
  },
1563
- "face-speaker": {
1564
- "description": "Speaker name to map to the face (thread only). If omitted, auto-detected from face name.",
1565
- "name": "face-speaker",
1678
+ "system": {
1679
+ "description": "System prompt (only honored when starting a new thread)",
1680
+ "name": "system",
1566
1681
  "hasDynamicHelp": false,
1567
1682
  "multiple": false,
1568
1683
  "type": "option"
1569
1684
  },
1570
- "no-wait": {
1571
- "description": "Return immediately after upload (do not poll for transcription). Prints the ID for manual polling.",
1572
- "name": "no-wait",
1685
+ "max-tokens": {
1686
+ "description": "Max tokens",
1687
+ "name": "max-tokens",
1688
+ "hasDynamicHelp": false,
1689
+ "multiple": false,
1690
+ "type": "option"
1691
+ },
1692
+ "temperature": {
1693
+ "description": "Temperature (0.0-2.0, OpenAI/Chat Completions only)",
1694
+ "name": "temperature",
1695
+ "hasDynamicHelp": false,
1696
+ "multiple": false,
1697
+ "type": "option"
1698
+ },
1699
+ "stream": {
1700
+ "description": "Stream the response",
1701
+ "name": "stream",
1702
+ "allowNo": false,
1703
+ "type": "boolean"
1704
+ },
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 (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
+ "name": "medium",
1708
+ "hasDynamicHelp": false,
1709
+ "multiple": false,
1710
+ "type": "option"
1711
+ },
1712
+ "oauth-only": {
1713
+ "description": "Prevent fallback to paid system key",
1714
+ "name": "oauth-only",
1715
+ "allowNo": false,
1716
+ "type": "boolean"
1717
+ },
1718
+ "list": {
1719
+ "description": "List saved threads",
1720
+ "name": "list",
1721
+ "allowNo": false,
1722
+ "type": "boolean"
1723
+ },
1724
+ "show": {
1725
+ "description": "Show the thread transcript (requires --id)",
1726
+ "name": "show",
1727
+ "allowNo": false,
1728
+ "type": "boolean"
1729
+ },
1730
+ "delete": {
1731
+ "description": "Delete the thread (requires --id)",
1732
+ "name": "delete",
1573
1733
  "allowNo": false,
1574
1734
  "type": "boolean"
1575
1735
  }
1576
1736
  },
1577
1737
  "hasDynamicHelp": false,
1578
1738
  "hiddenAliases": [],
1579
- "id": "compile:upload",
1739
+ "id": "chat:thread",
1580
1740
  "pluginAlias": "faces-cli",
1581
1741
  "pluginName": "faces-cli",
1582
1742
  "pluginType": "core",
@@ -1586,14 +1746,14 @@
1586
1746
  "relativePath": [
1587
1747
  "dist",
1588
1748
  "commands",
1589
- "compile",
1590
- "upload.js"
1749
+ "chat",
1750
+ "thread.js"
1591
1751
  ]
1592
1752
  },
1593
- "config:clear": {
1753
+ "compile:all": {
1594
1754
  "aliases": [],
1595
1755
  "args": {},
1596
- "description": "Delete all saved credentials and config",
1756
+ "description": "Compile all uncompiled documents and threads across all faces",
1597
1757
  "flags": {
1598
1758
  "json": {
1599
1759
  "description": "Format output as json.",
@@ -1626,16 +1786,18 @@
1626
1786
  "multiple": false,
1627
1787
  "type": "option"
1628
1788
  },
1629
- "yes": {
1630
- "description": "Skip confirmation",
1631
- "name": "yes",
1632
- "allowNo": false,
1633
- "type": "boolean"
1789
+ "timeout": {
1790
+ "description": "Per-item compile timeout in seconds (default: 600)",
1791
+ "name": "timeout",
1792
+ "default": 600,
1793
+ "hasDynamicHelp": false,
1794
+ "multiple": false,
1795
+ "type": "option"
1634
1796
  }
1635
1797
  },
1636
1798
  "hasDynamicHelp": false,
1637
1799
  "hiddenAliases": [],
1638
- "id": "config:clear",
1800
+ "id": "compile:all",
1639
1801
  "pluginAlias": "faces-cli",
1640
1802
  "pluginName": "faces-cli",
1641
1803
  "pluginType": "core",
@@ -1645,25 +1807,20 @@
1645
1807
  "relativePath": [
1646
1808
  "dist",
1647
1809
  "commands",
1648
- "config",
1649
- "clear.js"
1810
+ "compile",
1811
+ "all.js"
1650
1812
  ]
1651
1813
  },
1652
- "config:set": {
1814
+ "compile:import": {
1653
1815
  "aliases": [],
1654
1816
  "args": {
1655
- "key": {
1656
- "description": "Config key",
1657
- "name": "key",
1658
- "required": true
1659
- },
1660
- "value": {
1661
- "description": "Config value",
1662
- "name": "value",
1817
+ "face_id": {
1818
+ "description": "Face alias",
1819
+ "name": "face_id",
1663
1820
  "required": true
1664
1821
  }
1665
1822
  },
1666
- "description": "Set a config value (e.g. base_url, api_key, token)",
1823
+ "description": "Import a YouTube video into a face via server-side download and transcription",
1667
1824
  "flags": {
1668
1825
  "json": {
1669
1826
  "description": "Format output as json.",
@@ -1695,11 +1852,56 @@
1695
1852
  "hasDynamicHelp": false,
1696
1853
  "multiple": false,
1697
1854
  "type": "option"
1855
+ },
1856
+ "url": {
1857
+ "description": "YouTube URL (youtube.com/watch?v=... or youtu.be/...)",
1858
+ "name": "url",
1859
+ "required": true,
1860
+ "hasDynamicHelp": false,
1861
+ "multiple": false,
1862
+ "type": "option"
1863
+ },
1864
+ "type": {
1865
+ "description": "\"document\" for solo talks, lectures, monologues; \"thread\" for interviews or multi-speaker conversations",
1866
+ "name": "type",
1867
+ "default": "document",
1868
+ "hasDynamicHelp": false,
1869
+ "multiple": false,
1870
+ "options": [
1871
+ "document",
1872
+ "thread"
1873
+ ],
1874
+ "type": "option"
1875
+ },
1876
+ "perspective": {
1877
+ "description": "\"first-person\" if the face is the speaker; \"third-person\" if the video is about the face",
1878
+ "name": "perspective",
1879
+ "default": "third-person",
1880
+ "hasDynamicHelp": false,
1881
+ "multiple": false,
1882
+ "options": [
1883
+ "first-person",
1884
+ "third-person"
1885
+ ],
1886
+ "type": "option"
1887
+ },
1888
+ "face-speaker": {
1889
+ "description": "For --type thread: AssemblyAI speaker label (e.g. \"A\") that corresponds to the face. Defaults to first detected speaker.",
1890
+ "name": "face-speaker",
1891
+ "hasDynamicHelp": false,
1892
+ "multiple": false,
1893
+ "type": "option"
1894
+ },
1895
+ "no-wait": {
1896
+ "description": "Return immediately after import starts (do not poll for transcription). Prints the ID for manual polling.",
1897
+ "name": "no-wait",
1898
+ "allowNo": false,
1899
+ "type": "boolean"
1698
1900
  }
1699
1901
  },
1700
1902
  "hasDynamicHelp": false,
1701
1903
  "hiddenAliases": [],
1702
- "id": "config:set",
1904
+ "id": "compile:import",
1703
1905
  "pluginAlias": "faces-cli",
1704
1906
  "pluginName": "faces-cli",
1705
1907
  "pluginType": "core",
@@ -1709,14 +1911,14 @@
1709
1911
  "relativePath": [
1710
1912
  "dist",
1711
1913
  "commands",
1712
- "config",
1713
- "set.js"
1914
+ "compile",
1915
+ "import.js"
1714
1916
  ]
1715
1917
  },
1716
- "config:show": {
1918
+ "compile:stats": {
1717
1919
  "aliases": [],
1718
1920
  "args": {},
1719
- "description": "Print current config (credentials are masked)",
1921
+ "description": "Show compilation stats per face",
1720
1922
  "flags": {
1721
1923
  "json": {
1722
1924
  "description": "Format output as json.",
@@ -1752,7 +1954,7 @@
1752
1954
  },
1753
1955
  "hasDynamicHelp": false,
1754
1956
  "hiddenAliases": [],
1755
- "id": "config:show",
1957
+ "id": "compile:stats",
1756
1958
  "pluginAlias": "faces-cli",
1757
1959
  "pluginName": "faces-cli",
1758
1960
  "pluginType": "core",
@@ -1762,25 +1964,20 @@
1762
1964
  "relativePath": [
1763
1965
  "dist",
1764
1966
  "commands",
1765
- "config",
1766
- "show.js"
1967
+ "compile",
1968
+ "stats.js"
1767
1969
  ]
1768
1970
  },
1769
- "chat:chat": {
1971
+ "compile:upload": {
1770
1972
  "aliases": [],
1771
1973
  "args": {
1772
- "face_username": {
1773
- "description": "Face alias (alias@model, owner:alias@model for a published face, or a composite formula like \"(a | b)@model\"). Omit when using --formula.",
1774
- "name": "face_username",
1775
- "required": false
1974
+ "alias": {
1975
+ "description": "Face alias",
1976
+ "name": "alias",
1977
+ "required": true
1776
1978
  }
1777
1979
  },
1778
- "description": "Chat via a face. Auto-routes to the correct API endpoint based on the model catalog.",
1779
- "examples": [
1780
- "<%= config.bin %> <%= command.id %> socrates -m \"What is virtue?\"",
1781
- "<%= config.bin %> <%= command.id %> \"(socrates | nietzsche)@claude-sonnet-4-6\" -m \"What is virtue?\"",
1782
- "<%= config.bin %> <%= command.id %> --formula \"socrates | nietzsche\" --llm claude-sonnet-4-6 -m \"What is virtue?\""
1783
- ],
1980
+ "description": "Upload a file (text/PDF/Word .docx/audio/video) to compile into a face",
1784
1981
  "flags": {
1785
1982
  "json": {
1786
1983
  "description": "Format output as json.",
@@ -1813,86 +2010,62 @@
1813
2010
  "multiple": false,
1814
2011
  "type": "option"
1815
2012
  },
1816
- "message": {
1817
- "char": "m",
1818
- "description": "User message (repeatable)",
1819
- "name": "message",
1820
- "required": false,
1821
- "hasDynamicHelp": false,
1822
- "multiple": true,
1823
- "type": "option"
1824
- },
1825
- "llm": {
1826
- "description": "LLM override (e.g. gpt-4o-mini, claude-sonnet-4-6)",
1827
- "name": "llm",
1828
- "hasDynamicHelp": false,
1829
- "multiple": false,
1830
- "type": "option"
1831
- },
1832
- "formula": {
1833
- "description": "Compose a run-time composite from your own faces, e.g. \"socrates | nietzsche\" (operators: | & ^ -). Requires --llm. The composite takes the name of its first operand; use face:create --formula for a named, persisted composite.",
1834
- "name": "formula",
1835
- "hasDynamicHelp": false,
1836
- "multiple": false,
1837
- "type": "option"
1838
- },
1839
- "system": {
1840
- "description": "System prompt / instructions",
1841
- "name": "system",
2013
+ "file": {
2014
+ "description": "File to upload",
2015
+ "name": "file",
2016
+ "required": true,
1842
2017
  "hasDynamicHelp": false,
1843
2018
  "multiple": false,
1844
2019
  "type": "option"
1845
2020
  },
1846
- "stream": {
1847
- "description": "Stream the response",
1848
- "name": "stream",
1849
- "allowNo": false,
1850
- "type": "boolean"
1851
- },
1852
- "max-tokens": {
1853
- "description": "Max tokens",
1854
- "name": "max-tokens",
2021
+ "kind": {
2022
+ "description": "Upload kind: document or thread",
2023
+ "name": "kind",
2024
+ "default": "document",
1855
2025
  "hasDynamicHelp": false,
1856
2026
  "multiple": false,
2027
+ "options": [
2028
+ "document",
2029
+ "thread"
2030
+ ],
1857
2031
  "type": "option"
1858
2032
  },
1859
- "temperature": {
1860
- "description": "Temperature (0.0-2.0)",
1861
- "name": "temperature",
2033
+ "perspective": {
2034
+ "description": "Perspective (document only)",
2035
+ "name": "perspective",
2036
+ "default": "third-person",
1862
2037
  "hasDynamicHelp": false,
1863
2038
  "multiple": false,
2039
+ "options": [
2040
+ "first-person",
2041
+ "third-person"
2042
+ ],
1864
2043
  "type": "option"
1865
2044
  },
1866
- "file": {
1867
- "description": "Read message from file",
1868
- "name": "file",
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 (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
+ "name": "medium",
1869
2048
  "hasDynamicHelp": false,
1870
2049
  "multiple": false,
1871
2050
  "type": "option"
1872
2051
  },
1873
- "responses": {
1874
- "description": "Force the OpenAI Responses API endpoint (escape hatch; routing is automatic otherwise)",
1875
- "name": "responses",
1876
- "allowNo": false,
1877
- "type": "boolean"
1878
- },
1879
- "medium": {
1880
- "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.",
1881
- "name": "medium",
2052
+ "face-speaker": {
2053
+ "description": "Speaker name to map to the face (thread only). If omitted, auto-detected from face name.",
2054
+ "name": "face-speaker",
1882
2055
  "hasDynamicHelp": false,
1883
2056
  "multiple": false,
1884
2057
  "type": "option"
1885
2058
  },
1886
- "oauth-only": {
1887
- "description": "Prevent fallback to paid system key (use OAuth only)",
1888
- "name": "oauth-only",
2059
+ "no-wait": {
2060
+ "description": "Return immediately after upload (do not poll for transcription). Prints the ID for manual polling.",
2061
+ "name": "no-wait",
1889
2062
  "allowNo": false,
1890
2063
  "type": "boolean"
1891
2064
  }
1892
2065
  },
1893
2066
  "hasDynamicHelp": false,
1894
2067
  "hiddenAliases": [],
1895
- "id": "chat:chat",
2068
+ "id": "compile:upload",
1896
2069
  "pluginAlias": "faces-cli",
1897
2070
  "pluginName": "faces-cli",
1898
2071
  "pluginType": "core",
@@ -1902,20 +2075,14 @@
1902
2075
  "relativePath": [
1903
2076
  "dist",
1904
2077
  "commands",
1905
- "chat",
1906
- "chat.js"
2078
+ "compile",
2079
+ "upload.js"
1907
2080
  ]
1908
2081
  },
1909
- "chat:messages": {
2082
+ "config:clear": {
1910
2083
  "aliases": [],
1911
- "args": {
1912
- "face_model": {
1913
- "description": "Face model (e.g. myface, myface@claude-sonnet-4-6, or head:socrates@claude-sonnet-4-6)",
1914
- "name": "face_model",
1915
- "required": true
1916
- }
1917
- },
1918
- "description": "Anthropic Messages API proxy via a face (alias: chat:chat auto-routes Anthropic models here)",
2084
+ "args": {},
2085
+ "description": "Delete all saved credentials and config",
1919
2086
  "flags": {
1920
2087
  "json": {
1921
2088
  "description": "Format output as json.",
@@ -1948,53 +2115,16 @@
1948
2115
  "multiple": false,
1949
2116
  "type": "option"
1950
2117
  },
1951
- "message": {
1952
- "char": "m",
1953
- "description": "User message (repeatable)",
1954
- "name": "message",
1955
- "required": true,
1956
- "hasDynamicHelp": false,
1957
- "multiple": true,
1958
- "type": "option"
1959
- },
1960
- "system": {
1961
- "description": "System prompt",
1962
- "name": "system",
1963
- "hasDynamicHelp": false,
1964
- "multiple": false,
1965
- "type": "option"
1966
- },
1967
- "stream": {
1968
- "description": "Stream the response",
1969
- "name": "stream",
1970
- "allowNo": false,
1971
- "type": "boolean"
1972
- },
1973
- "max-tokens": {
1974
- "description": "Max tokens",
1975
- "name": "max-tokens",
1976
- "default": 1024,
1977
- "hasDynamicHelp": false,
1978
- "multiple": false,
1979
- "type": "option"
1980
- },
1981
- "medium": {
1982
- "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.",
1983
- "name": "medium",
1984
- "hasDynamicHelp": false,
1985
- "multiple": false,
1986
- "type": "option"
1987
- },
1988
- "oauth-only": {
1989
- "description": "Prevent fallback to paid system key (use OAuth only)",
1990
- "name": "oauth-only",
2118
+ "yes": {
2119
+ "description": "Skip confirmation",
2120
+ "name": "yes",
1991
2121
  "allowNo": false,
1992
2122
  "type": "boolean"
1993
2123
  }
1994
2124
  },
1995
2125
  "hasDynamicHelp": false,
1996
2126
  "hiddenAliases": [],
1997
- "id": "chat:messages",
2127
+ "id": "config:clear",
1998
2128
  "pluginAlias": "faces-cli",
1999
2129
  "pluginName": "faces-cli",
2000
2130
  "pluginType": "core",
@@ -2004,20 +2134,25 @@
2004
2134
  "relativePath": [
2005
2135
  "dist",
2006
2136
  "commands",
2007
- "chat",
2008
- "messages.js"
2137
+ "config",
2138
+ "clear.js"
2009
2139
  ]
2010
2140
  },
2011
- "chat:responses": {
2141
+ "config:set": {
2012
2142
  "aliases": [],
2013
2143
  "args": {
2014
- "face_model": {
2015
- "description": "Face model (e.g. myface, myface@gpt-4o, or head:socrates@gpt-5.4)",
2016
- "name": "face_model",
2144
+ "key": {
2145
+ "description": "Config key",
2146
+ "name": "key",
2147
+ "required": true
2148
+ },
2149
+ "value": {
2150
+ "description": "Config value",
2151
+ "name": "value",
2017
2152
  "required": true
2018
2153
  }
2019
2154
  },
2020
- "description": "OpenAI Responses API proxy via a face (alias: chat:chat --responses)",
2155
+ "description": "Set a config value (e.g. base_url, api_key, token)",
2021
2156
  "flags": {
2022
2157
  "json": {
2023
2158
  "description": "Format output as json.",
@@ -2049,46 +2184,64 @@
2049
2184
  "hasDynamicHelp": false,
2050
2185
  "multiple": false,
2051
2186
  "type": "option"
2187
+ }
2188
+ },
2189
+ "hasDynamicHelp": false,
2190
+ "hiddenAliases": [],
2191
+ "id": "config:set",
2192
+ "pluginAlias": "faces-cli",
2193
+ "pluginName": "faces-cli",
2194
+ "pluginType": "core",
2195
+ "strict": true,
2196
+ "enableJsonFlag": true,
2197
+ "isESM": true,
2198
+ "relativePath": [
2199
+ "dist",
2200
+ "commands",
2201
+ "config",
2202
+ "set.js"
2203
+ ]
2204
+ },
2205
+ "config:show": {
2206
+ "aliases": [],
2207
+ "args": {},
2208
+ "description": "Print current config (credentials are masked)",
2209
+ "flags": {
2210
+ "json": {
2211
+ "description": "Format output as json.",
2212
+ "helpGroup": "GLOBAL",
2213
+ "name": "json",
2214
+ "allowNo": false,
2215
+ "type": "boolean"
2052
2216
  },
2053
- "message": {
2054
- "char": "m",
2055
- "description": "User input message",
2056
- "name": "message",
2057
- "required": true,
2217
+ "base-url": {
2218
+ "description": "API base URL",
2219
+ "env": "FACES_BASE_URL",
2220
+ "name": "base-url",
2058
2221
  "hasDynamicHelp": false,
2059
2222
  "multiple": false,
2060
2223
  "type": "option"
2061
2224
  },
2062
- "instructions": {
2063
- "description": "System instructions",
2064
- "name": "instructions",
2225
+ "token": {
2226
+ "description": "JWT bearer token",
2227
+ "env": "FACES_TOKEN",
2228
+ "name": "token",
2065
2229
  "hasDynamicHelp": false,
2066
2230
  "multiple": false,
2067
2231
  "type": "option"
2068
2232
  },
2069
- "stream": {
2070
- "description": "Stream the response",
2071
- "name": "stream",
2072
- "allowNo": false,
2073
- "type": "boolean"
2074
- },
2075
- "medium": {
2076
- "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.",
2077
- "name": "medium",
2233
+ "api-key": {
2234
+ "description": "API key",
2235
+ "env": "FACES_API_KEY",
2236
+ "name": "api-key",
2078
2237
  "hasDynamicHelp": false,
2079
2238
  "multiple": false,
2080
2239
  "type": "option"
2081
- },
2082
- "oauth-only": {
2083
- "description": "Prevent fallback to paid system key (use OAuth only)",
2084
- "name": "oauth-only",
2085
- "allowNo": false,
2086
- "type": "boolean"
2087
2240
  }
2088
2241
  },
2089
2242
  "hasDynamicHelp": false,
2090
2243
  "hiddenAliases": [],
2091
- "id": "chat:responses",
2244
+ "id": "config:show",
2092
2245
  "pluginAlias": "faces-cli",
2093
2246
  "pluginName": "faces-cli",
2094
2247
  "pluginType": "core",
@@ -2098,27 +2251,14 @@
2098
2251
  "relativePath": [
2099
2252
  "dist",
2100
2253
  "commands",
2101
- "chat",
2102
- "responses.js"
2103
- ]
2104
- },
2105
- "chat:thread": {
2106
- "aliases": [],
2107
- "args": {
2108
- "face_username": {
2109
- "description": "Face alias (alias@model, or owner:alias@model for a published face) — required when starting a new thread",
2110
- "name": "face_username",
2111
- "required": false
2112
- }
2113
- },
2114
- "description": "Multi-turn chat thread. Conversation history is stored under ~/.faces/threads/<id>.json — resume any thread later with --id.",
2115
- "examples": [
2116
- "<%= config.bin %> <%= command.id %> socrates -m \"What is justice?\"",
2117
- "<%= config.bin %> <%= command.id %> --id t_abc123 -m \"Say more about that\"",
2118
- "<%= config.bin %> <%= command.id %> --list",
2119
- "<%= config.bin %> <%= command.id %> --id t_abc123 --show",
2120
- "<%= config.bin %> <%= command.id %> --id t_abc123 --delete"
2121
- ],
2254
+ "config",
2255
+ "show.js"
2256
+ ]
2257
+ },
2258
+ "keys:create": {
2259
+ "aliases": [],
2260
+ "args": {},
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.",
2122
2262
  "flags": {
2123
2263
  "json": {
2124
2264
  "description": "Format output as json.",
@@ -2151,97 +2291,52 @@
2151
2291
  "multiple": false,
2152
2292
  "type": "option"
2153
2293
  },
2154
- "id": {
2155
- "description": "Resume an existing thread by id",
2156
- "name": "id",
2157
- "hasDynamicHelp": false,
2158
- "multiple": false,
2159
- "type": "option"
2160
- },
2161
- "message": {
2162
- "char": "m",
2163
- "description": "User message",
2164
- "name": "message",
2165
- "hasDynamicHelp": false,
2166
- "multiple": false,
2167
- "type": "option"
2168
- },
2169
- "file": {
2170
- "description": "Read message from file",
2171
- "name": "file",
2172
- "hasDynamicHelp": false,
2173
- "multiple": false,
2174
- "type": "option"
2175
- },
2176
- "llm": {
2177
- "description": "LLM override (only honored when starting a new thread)",
2178
- "name": "llm",
2294
+ "name": {
2295
+ "description": "Key name/label",
2296
+ "name": "name",
2297
+ "required": true,
2179
2298
  "hasDynamicHelp": false,
2180
2299
  "multiple": false,
2181
2300
  "type": "option"
2182
2301
  },
2183
- "system": {
2184
- "description": "System prompt (only honored when starting a new thread)",
2185
- "name": "system",
2302
+ "expires-days": {
2303
+ "description": "Expiry in days (omit for no expiry)",
2304
+ "name": "expires-days",
2186
2305
  "hasDynamicHelp": false,
2187
2306
  "multiple": false,
2188
2307
  "type": "option"
2189
2308
  },
2190
- "max-tokens": {
2191
- "description": "Max tokens",
2192
- "name": "max-tokens",
2309
+ "budget": {
2310
+ "description": "Spend budget in USD",
2311
+ "name": "budget",
2193
2312
  "hasDynamicHelp": false,
2194
2313
  "multiple": false,
2195
2314
  "type": "option"
2196
2315
  },
2197
- "temperature": {
2198
- "description": "Temperature (0.0-2.0, OpenAI/Chat Completions only)",
2199
- "name": "temperature",
2316
+ "face": {
2317
+ "description": "Allowed face alias (repeatable)",
2318
+ "name": "face",
2200
2319
  "hasDynamicHelp": false,
2201
- "multiple": false,
2320
+ "multiple": true,
2202
2321
  "type": "option"
2203
2322
  },
2204
- "stream": {
2205
- "description": "Stream the response",
2206
- "name": "stream",
2207
- "allowNo": false,
2208
- "type": "boolean"
2209
- },
2210
- "medium": {
2211
- "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.",
2212
- "name": "medium",
2323
+ "model": {
2324
+ "description": "Allowed model name (repeatable)",
2325
+ "name": "model",
2213
2326
  "hasDynamicHelp": false,
2214
- "multiple": false,
2327
+ "multiple": true,
2215
2328
  "type": "option"
2216
2329
  },
2217
- "oauth-only": {
2218
- "description": "Prevent fallback to paid system key",
2219
- "name": "oauth-only",
2220
- "allowNo": false,
2221
- "type": "boolean"
2222
- },
2223
- "list": {
2224
- "description": "List saved threads",
2225
- "name": "list",
2226
- "allowNo": false,
2227
- "type": "boolean"
2228
- },
2229
- "show": {
2230
- "description": "Show the thread transcript (requires --id)",
2231
- "name": "show",
2232
- "allowNo": false,
2233
- "type": "boolean"
2234
- },
2235
- "delete": {
2236
- "description": "Delete the thread (requires --id)",
2237
- "name": "delete",
2238
- "allowNo": false,
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,
2239
2334
  "type": "boolean"
2240
2335
  }
2241
2336
  },
2242
2337
  "hasDynamicHelp": false,
2243
2338
  "hiddenAliases": [],
2244
- "id": "chat:thread",
2339
+ "id": "keys:create",
2245
2340
  "pluginAlias": "faces-cli",
2246
2341
  "pluginName": "faces-cli",
2247
2342
  "pluginType": "core",
@@ -2251,14 +2346,14 @@
2251
2346
  "relativePath": [
2252
2347
  "dist",
2253
2348
  "commands",
2254
- "chat",
2255
- "thread.js"
2349
+ "keys",
2350
+ "create.js"
2256
2351
  ]
2257
2352
  },
2258
- "face:attributes": {
2353
+ "keys:list": {
2259
2354
  "aliases": [],
2260
2355
  "args": {},
2261
- "description": "List all supported attribute keys",
2356
+ "description": "List all API keys (JWT required)",
2262
2357
  "flags": {
2263
2358
  "json": {
2264
2359
  "description": "Format output as json.",
@@ -2294,7 +2389,7 @@
2294
2389
  },
2295
2390
  "hasDynamicHelp": false,
2296
2391
  "hiddenAliases": [],
2297
- "id": "face:attributes",
2392
+ "id": "keys:list",
2298
2393
  "pluginAlias": "faces-cli",
2299
2394
  "pluginName": "faces-cli",
2300
2395
  "pluginType": "core",
@@ -2304,14 +2399,20 @@
2304
2399
  "relativePath": [
2305
2400
  "dist",
2306
2401
  "commands",
2307
- "face",
2308
- "attributes.js"
2402
+ "keys",
2403
+ "list.js"
2309
2404
  ]
2310
2405
  },
2311
- "face:create": {
2406
+ "keys:revoke": {
2312
2407
  "aliases": [],
2313
- "args": {},
2314
- "description": "Create a new face",
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)",
2315
2416
  "flags": {
2316
2417
  "json": {
2317
2418
  "description": "Format output as json.",
@@ -2344,85 +2445,16 @@
2344
2445
  "multiple": false,
2345
2446
  "type": "option"
2346
2447
  },
2347
- "name": {
2348
- "description": "Display name",
2349
- "name": "name",
2350
- "required": true,
2351
- "hasDynamicHelp": false,
2352
- "multiple": false,
2353
- "type": "option"
2354
- },
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",
2380
- "hasDynamicHelp": false,
2381
- "multiple": false,
2382
- "type": "option"
2383
- },
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",
2387
- "hasDynamicHelp": false,
2388
- "multiple": false,
2389
- "type": "option"
2390
- },
2391
- "attr": {
2392
- "description": "Attribute KEY=VALUE (repeatable)",
2393
- "name": "attr",
2394
- "hasDynamicHelp": false,
2395
- "multiple": true,
2396
- "type": "option"
2397
- },
2398
- "tool": {
2399
- "description": "Tool name to enable (repeatable)",
2400
- "name": "tool",
2401
- "hasDynamicHelp": false,
2402
- "multiple": true,
2403
- "type": "option"
2404
- },
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"
2448
+ "yes": {
2449
+ "description": "Skip confirmation",
2450
+ "name": "yes",
2451
+ "allowNo": false,
2452
+ "type": "boolean"
2421
2453
  }
2422
2454
  },
2423
2455
  "hasDynamicHelp": false,
2424
2456
  "hiddenAliases": [],
2425
- "id": "face:create",
2457
+ "id": "keys:revoke",
2426
2458
  "pluginAlias": "faces-cli",
2427
2459
  "pluginName": "faces-cli",
2428
2460
  "pluginType": "core",
@@ -2432,20 +2464,20 @@
2432
2464
  "relativePath": [
2433
2465
  "dist",
2434
2466
  "commands",
2435
- "face",
2436
- "create.js"
2467
+ "keys",
2468
+ "revoke.js"
2437
2469
  ]
2438
2470
  },
2439
- "face:delete": {
2471
+ "keys:update": {
2440
2472
  "aliases": [],
2441
2473
  "args": {
2442
- "face_id": {
2443
- "description": "Face alias",
2444
- "name": "face_id",
2474
+ "key_id": {
2475
+ "description": "Key ID",
2476
+ "name": "key_id",
2445
2477
  "required": true
2446
2478
  }
2447
2479
  },
2448
- "description": "Delete a face permanently",
2480
+ "description": "Update API key metadata (JWT required)",
2449
2481
  "flags": {
2450
2482
  "json": {
2451
2483
  "description": "Format output as json.",
@@ -2478,16 +2510,30 @@
2478
2510
  "multiple": false,
2479
2511
  "type": "option"
2480
2512
  },
2481
- "yes": {
2482
- "description": "Skip confirmation",
2483
- "name": "yes",
2513
+ "name": {
2514
+ "description": "New key name",
2515
+ "name": "name",
2516
+ "hasDynamicHelp": false,
2517
+ "multiple": false,
2518
+ "type": "option"
2519
+ },
2520
+ "budget": {
2521
+ "description": "New spend budget in USD",
2522
+ "name": "budget",
2523
+ "hasDynamicHelp": false,
2524
+ "multiple": false,
2525
+ "type": "option"
2526
+ },
2527
+ "reset-spent": {
2528
+ "description": "Reset spent amount to zero",
2529
+ "name": "reset-spent",
2484
2530
  "allowNo": false,
2485
2531
  "type": "boolean"
2486
2532
  }
2487
2533
  },
2488
2534
  "hasDynamicHelp": false,
2489
2535
  "hiddenAliases": [],
2490
- "id": "face:delete",
2536
+ "id": "keys:update",
2491
2537
  "pluginAlias": "faces-cli",
2492
2538
  "pluginName": "faces-cli",
2493
2539
  "pluginType": "core",
@@ -2497,14 +2543,14 @@
2497
2543
  "relativePath": [
2498
2544
  "dist",
2499
2545
  "commands",
2500
- "face",
2501
- "delete.js"
2546
+ "keys",
2547
+ "update.js"
2502
2548
  ]
2503
2549
  },
2504
- "face:diff": {
2550
+ "face:attributes": {
2505
2551
  "aliases": [],
2506
2552
  "args": {},
2507
- "description": "Compare owned faces pairwise across all centroid components",
2553
+ "description": "List all supported attribute keys",
2508
2554
  "flags": {
2509
2555
  "json": {
2510
2556
  "description": "Format output as json.",
@@ -2536,19 +2582,11 @@
2536
2582
  "hasDynamicHelp": false,
2537
2583
  "multiple": false,
2538
2584
  "type": "option"
2539
- },
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"
2547
2585
  }
2548
2586
  },
2549
2587
  "hasDynamicHelp": false,
2550
2588
  "hiddenAliases": [],
2551
- "id": "face:diff",
2589
+ "id": "face:attributes",
2552
2590
  "pluginAlias": "faces-cli",
2553
2591
  "pluginName": "faces-cli",
2554
2592
  "pluginType": "core",
@@ -2559,19 +2597,13 @@
2559
2597
  "dist",
2560
2598
  "commands",
2561
2599
  "face",
2562
- "diff.js"
2600
+ "attributes.js"
2563
2601
  ]
2564
2602
  },
2565
- "face:edit": {
2603
+ "face:create": {
2566
2604
  "aliases": [],
2567
- "args": {
2568
- "face_id": {
2569
- "description": "Face alias",
2570
- "name": "face_id",
2571
- "required": true
2572
- }
2573
- },
2574
- "description": "Edit a face's metadata",
2605
+ "args": {},
2606
+ "description": "Create a new face",
2575
2607
  "flags": {
2576
2608
  "json": {
2577
2609
  "description": "Format output as json.",
@@ -2605,8 +2637,17 @@
2605
2637
  "type": "option"
2606
2638
  },
2607
2639
  "name": {
2608
- "description": "New display name",
2640
+ "description": "Display name",
2609
2641
  "name": "name",
2642
+ "required": true,
2643
+ "hasDynamicHelp": false,
2644
+ "multiple": false,
2645
+ "type": "option"
2646
+ },
2647
+ "alias": {
2648
+ "description": "Unique alias slug",
2649
+ "name": "alias",
2650
+ "required": true,
2610
2651
  "hasDynamicHelp": false,
2611
2652
  "multiple": false,
2612
2653
  "type": "option"
@@ -2619,7 +2660,7 @@
2619
2660
  "type": "option"
2620
2661
  },
2621
2662
  "tag": {
2622
- "description": "Replace all tags (repeatable, lowercase)",
2663
+ "description": "Tag label (repeatable, lowercase)",
2623
2664
  "name": "tag",
2624
2665
  "hasDynamicHelp": false,
2625
2666
  "multiple": true,
@@ -2633,35 +2674,35 @@
2633
2674
  "type": "option"
2634
2675
  },
2635
2676
  "formula": {
2636
- "description": "New boolean formula (synthetic faces only)",
2677
+ "description": "Boolean formula over owned concrete face aliases (e.g. \"a | b\", \"(a | b) - c\"). Creates a composite face.",
2637
2678
  "name": "formula",
2638
2679
  "hasDynamicHelp": false,
2639
2680
  "multiple": false,
2640
2681
  "type": "option"
2641
2682
  },
2642
2683
  "attr": {
2643
- "description": "Update attribute KEY=VALUE (repeatable)",
2684
+ "description": "Attribute KEY=VALUE (repeatable)",
2644
2685
  "name": "attr",
2645
2686
  "hasDynamicHelp": false,
2646
2687
  "multiple": true,
2647
2688
  "type": "option"
2648
2689
  },
2649
2690
  "tool": {
2650
- "description": "Tool names to set (replaces list, repeatable)",
2691
+ "description": "Tool name to enable (repeatable)",
2651
2692
  "name": "tool",
2652
2693
  "hasDynamicHelp": false,
2653
2694
  "multiple": true,
2654
2695
  "type": "option"
2655
2696
  },
2656
2697
  "profile-addendum": {
2657
- "description": "Replace the per-face system prompt (max 100,000 chars).",
2698
+ "description": "Per-face system prompt, injected after the persona profile and before any per-request system prompt (max 100,000 chars).",
2658
2699
  "name": "profile-addendum",
2659
2700
  "hasDynamicHelp": false,
2660
2701
  "multiple": false,
2661
2702
  "type": "option"
2662
2703
  },
2663
2704
  "profile-addendum-file": {
2664
- "description": "Replace the per-face system prompt from a file.",
2705
+ "description": "Read the per-face system prompt from a file (alternative to --profile-addendum).",
2665
2706
  "exclusive": [
2666
2707
  "profile-addendum"
2667
2708
  ],
@@ -2669,21 +2710,11 @@
2669
2710
  "hasDynamicHelp": false,
2670
2711
  "multiple": false,
2671
2712
  "type": "option"
2672
- },
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",
2680
- "allowNo": false,
2681
- "type": "boolean"
2682
2713
  }
2683
2714
  },
2684
2715
  "hasDynamicHelp": false,
2685
2716
  "hiddenAliases": [],
2686
- "id": "face:edit",
2717
+ "id": "face:create",
2687
2718
  "pluginAlias": "faces-cli",
2688
2719
  "pluginName": "faces-cli",
2689
2720
  "pluginType": "core",
@@ -2694,10 +2725,10 @@
2694
2725
  "dist",
2695
2726
  "commands",
2696
2727
  "face",
2697
- "edit.js"
2728
+ "create.js"
2698
2729
  ]
2699
2730
  },
2700
- "face:get": {
2731
+ "face:delete": {
2701
2732
  "aliases": [],
2702
2733
  "args": {
2703
2734
  "face_id": {
@@ -2706,7 +2737,7 @@
2706
2737
  "required": true
2707
2738
  }
2708
2739
  },
2709
- "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.",
2740
+ "description": "Delete a face permanently",
2710
2741
  "flags": {
2711
2742
  "json": {
2712
2743
  "description": "Format output as json.",
@@ -2739,23 +2770,16 @@
2739
2770
  "multiple": false,
2740
2771
  "type": "option"
2741
2772
  },
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",
2773
+ "yes": {
2774
+ "description": "Skip confirmation",
2775
+ "name": "yes",
2752
2776
  "allowNo": false,
2753
2777
  "type": "boolean"
2754
2778
  }
2755
2779
  },
2756
2780
  "hasDynamicHelp": false,
2757
2781
  "hiddenAliases": [],
2758
- "id": "face:get",
2782
+ "id": "face:delete",
2759
2783
  "pluginAlias": "faces-cli",
2760
2784
  "pluginName": "faces-cli",
2761
2785
  "pluginType": "core",
@@ -2766,13 +2790,13 @@
2766
2790
  "dist",
2767
2791
  "commands",
2768
2792
  "face",
2769
- "get.js"
2793
+ "delete.js"
2770
2794
  ]
2771
2795
  },
2772
- "face:list": {
2796
+ "face:diff": {
2773
2797
  "aliases": [],
2774
2798
  "args": {},
2775
- "description": "List faces. By default lists owned faces; use --public to include published faces from other accounts.",
2799
+ "description": "Compare owned faces pairwise across all centroid components",
2776
2800
  "flags": {
2777
2801
  "json": {
2778
2802
  "description": "Format output as json.",
@@ -2805,55 +2829,10 @@
2805
2829
  "multiple": false,
2806
2830
  "type": "option"
2807
2831
  },
2808
- "tag": {
2809
- "description": "Filter by tag (repeatable, AND logic)",
2810
- "name": "tag",
2811
- "hasDynamicHelp": false,
2812
- "multiple": true,
2813
- "type": "option"
2814
- },
2815
- "team": {
2816
- "description": "Filter by team ID (repeatable, OR logic)",
2817
- "name": "team",
2818
- "hasDynamicHelp": false,
2819
- "multiple": true,
2820
- "type": "option"
2821
- },
2822
- "include": {
2823
- "description": "Include extra fields: tags, teams (comma-separated)",
2824
- "name": "include",
2825
- "hasDynamicHelp": false,
2826
- "multiple": false,
2827
- "type": "option"
2828
- },
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",
2838
- "allowNo": false,
2839
- "type": "boolean"
2840
- },
2841
- "system": {
2842
- "description": "Show only the curated system faces (published faces owned by 'head')",
2843
- "name": "system",
2844
- "allowNo": false,
2845
- "type": "boolean"
2846
- },
2847
- "from-users": {
2848
- "description": "Only published faces from these owners (repeatable/comma-separated)",
2849
- "name": "from-users",
2850
- "hasDynamicHelp": false,
2851
- "multiple": true,
2852
- "type": "option"
2853
- },
2854
- "not-from-users": {
2855
- "description": "Exclude published faces from these owners (repeatable/comma-separated)",
2856
- "name": "not-from-users",
2832
+ "face": {
2833
+ "description": "Face alias to include (repeatable, min 2)",
2834
+ "name": "face",
2835
+ "required": true,
2857
2836
  "hasDynamicHelp": false,
2858
2837
  "multiple": true,
2859
2838
  "type": "option"
@@ -2861,7 +2840,7 @@
2861
2840
  },
2862
2841
  "hasDynamicHelp": false,
2863
2842
  "hiddenAliases": [],
2864
- "id": "face:list",
2843
+ "id": "face:diff",
2865
2844
  "pluginAlias": "faces-cli",
2866
2845
  "pluginName": "faces-cli",
2867
2846
  "pluginType": "core",
@@ -2872,10 +2851,10 @@
2872
2851
  "dist",
2873
2852
  "commands",
2874
2853
  "face",
2875
- "list.js"
2854
+ "diff.js"
2876
2855
  ]
2877
2856
  },
2878
- "face:lock": {
2857
+ "face:edit": {
2879
2858
  "aliases": [],
2880
2859
  "args": {
2881
2860
  "face_id": {
@@ -2884,10 +2863,7 @@
2884
2863
  "required": true
2885
2864
  }
2886
2865
  },
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.",
2888
- "examples": [
2889
- "<%= config.bin %> <%= command.id %> socrates"
2890
- ],
2866
+ "description": "Edit a face's metadata",
2891
2867
  "flags": {
2892
2868
  "json": {
2893
2869
  "description": "Format output as json.",
@@ -2919,98 +2895,87 @@
2919
2895
  "hasDynamicHelp": false,
2920
2896
  "multiple": false,
2921
2897
  "type": "option"
2922
- }
2923
- },
2924
- "hasDynamicHelp": false,
2925
- "hiddenAliases": [],
2926
- "id": "face:lock",
2927
- "pluginAlias": "faces-cli",
2928
- "pluginName": "faces-cli",
2929
- "pluginType": "core",
2930
- "strict": true,
2931
- "enableJsonFlag": true,
2932
- "isESM": true,
2933
- "relativePath": [
2934
- "dist",
2935
- "commands",
2936
- "face",
2937
- "lock.js"
2938
- ]
2939
- },
2940
- "face:neighbors": {
2941
- "aliases": [],
2942
- "args": {
2943
- "face_id": {
2944
- "description": "Face alias",
2945
- "name": "face_id",
2946
- "required": true
2947
- }
2948
- },
2949
- "description": "Find the most similar or dissimilar owned faces to a given face",
2950
- "flags": {
2951
- "json": {
2952
- "description": "Format output as json.",
2953
- "helpGroup": "GLOBAL",
2954
- "name": "json",
2955
- "allowNo": false,
2956
- "type": "boolean"
2957
2898
  },
2958
- "base-url": {
2959
- "description": "API base URL",
2960
- "env": "FACES_BASE_URL",
2961
- "name": "base-url",
2899
+ "name": {
2900
+ "description": "New display name",
2901
+ "name": "name",
2962
2902
  "hasDynamicHelp": false,
2963
2903
  "multiple": false,
2964
2904
  "type": "option"
2965
2905
  },
2966
- "token": {
2967
- "description": "JWT bearer token",
2968
- "env": "FACES_TOKEN",
2969
- "name": "token",
2906
+ "description": {
2907
+ "description": "Plain-text description / bio (max 1500 chars)",
2908
+ "name": "description",
2970
2909
  "hasDynamicHelp": false,
2971
2910
  "multiple": false,
2972
2911
  "type": "option"
2973
2912
  },
2974
- "api-key": {
2975
- "description": "API key",
2976
- "env": "FACES_API_KEY",
2977
- "name": "api-key",
2913
+ "tag": {
2914
+ "description": "Replace all tags (repeatable, lowercase)",
2915
+ "name": "tag",
2978
2916
  "hasDynamicHelp": false,
2979
- "multiple": false,
2917
+ "multiple": true,
2980
2918
  "type": "option"
2981
2919
  },
2982
- "k": {
2983
- "description": "Number of results (1–20)",
2984
- "name": "k",
2985
- "default": 5,
2920
+ "default-model": {
2921
+ "description": "Default LLM for chat (e.g. gpt-4o-mini, claude-sonnet-4-6)",
2922
+ "name": "default-model",
2986
2923
  "hasDynamicHelp": false,
2987
2924
  "multiple": false,
2988
2925
  "type": "option"
2989
2926
  },
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",
2927
+ "formula": {
2928
+ "description": "New boolean formula (synthetic faces only)",
2929
+ "name": "formula",
2994
2930
  "hasDynamicHelp": false,
2995
2931
  "multiple": false,
2996
2932
  "type": "option"
2997
2933
  },
2998
- "direction": {
2999
- "description": "nearest (most similar) or furthest (most dissimilar)",
3000
- "name": "direction",
3001
- "default": "nearest",
2934
+ "attr": {
2935
+ "description": "Update attribute KEY=VALUE (repeatable)",
2936
+ "name": "attr",
2937
+ "hasDynamicHelp": false,
2938
+ "multiple": true,
2939
+ "type": "option"
2940
+ },
2941
+ "tool": {
2942
+ "description": "Tool names to set (replaces list, repeatable)",
2943
+ "name": "tool",
2944
+ "hasDynamicHelp": false,
2945
+ "multiple": true,
2946
+ "type": "option"
2947
+ },
2948
+ "profile-addendum": {
2949
+ "description": "Replace the per-face system prompt (max 100,000 chars).",
2950
+ "name": "profile-addendum",
3002
2951
  "hasDynamicHelp": false,
3003
2952
  "multiple": false,
3004
- "options": [
3005
- "nearest",
3006
- "furthest"
2953
+ "type": "option"
2954
+ },
2955
+ "profile-addendum-file": {
2956
+ "description": "Replace the per-face system prompt from a file.",
2957
+ "exclusive": [
2958
+ "profile-addendum"
3007
2959
  ],
2960
+ "name": "profile-addendum-file",
2961
+ "hasDynamicHelp": false,
2962
+ "multiple": false,
3008
2963
  "type": "option"
2964
+ },
2965
+ "clear-profile-addendum": {
2966
+ "description": "Remove the per-face system prompt.",
2967
+ "exclusive": [
2968
+ "profile-addendum",
2969
+ "profile-addendum-file"
2970
+ ],
2971
+ "name": "clear-profile-addendum",
2972
+ "allowNo": false,
2973
+ "type": "boolean"
3009
2974
  }
3010
2975
  },
3011
2976
  "hasDynamicHelp": false,
3012
2977
  "hiddenAliases": [],
3013
- "id": "face:neighbors",
2978
+ "id": "face:edit",
3014
2979
  "pluginAlias": "faces-cli",
3015
2980
  "pluginName": "faces-cli",
3016
2981
  "pluginType": "core",
@@ -3021,22 +2986,19 @@
3021
2986
  "dist",
3022
2987
  "commands",
3023
2988
  "face",
3024
- "neighbors.js"
2989
+ "edit.js"
3025
2990
  ]
3026
2991
  },
3027
- "face:publish": {
2992
+ "face:get": {
3028
2993
  "aliases": [],
3029
2994
  "args": {
3030
- "alias": {
2995
+ "face_id": {
3031
2996
  "description": "Face alias",
3032
- "name": "alias",
2997
+ "name": "face_id",
3033
2998
  "required": true
3034
2999
  }
3035
3000
  },
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.",
3037
- "examples": [
3038
- "<%= config.bin %> <%= command.id %> alice --yes"
3039
- ],
3001
+ "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.",
3040
3002
  "flags": {
3041
3003
  "json": {
3042
3004
  "description": "Format output as json.",
@@ -3069,16 +3031,23 @@
3069
3031
  "multiple": false,
3070
3032
  "type": "option"
3071
3033
  },
3072
- "yes": {
3073
- "description": "Skip confirmation",
3074
- "name": "yes",
3034
+ "include": {
3035
+ "description": "Include extra fields: tags, teams (comma-separated)",
3036
+ "name": "include",
3037
+ "hasDynamicHelp": false,
3038
+ "multiple": false,
3039
+ "type": "option"
3040
+ },
3041
+ "full": {
3042
+ "description": "Print the full profile_addendum instead of a truncated preview",
3043
+ "name": "full",
3075
3044
  "allowNo": false,
3076
3045
  "type": "boolean"
3077
3046
  }
3078
3047
  },
3079
3048
  "hasDynamicHelp": false,
3080
3049
  "hiddenAliases": [],
3081
- "id": "face:publish",
3050
+ "id": "face:get",
3082
3051
  "pluginAlias": "faces-cli",
3083
3052
  "pluginName": "faces-cli",
3084
3053
  "pluginType": "core",
@@ -3089,25 +3058,13 @@
3089
3058
  "dist",
3090
3059
  "commands",
3091
3060
  "face",
3092
- "publish.js"
3061
+ "get.js"
3093
3062
  ]
3094
3063
  },
3095
- "face:share": {
3064
+ "face:list": {
3096
3065
  "aliases": [],
3097
- "args": {
3098
- "alias": {
3099
- "description": "Face alias",
3100
- "name": "alias",
3101
- "required": true
3102
- }
3103
- },
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.",
3105
- "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"
3110
- ],
3066
+ "args": {},
3067
+ "description": "List faces. By default lists owned faces; use --public to include published faces from other accounts.",
3111
3068
  "flags": {
3112
3069
  "json": {
3113
3070
  "description": "Format output as json.",
@@ -3140,54 +3097,63 @@
3140
3097
  "multiple": false,
3141
3098
  "type": "option"
3142
3099
  },
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",
3100
+ "tag": {
3101
+ "description": "Filter by tag (repeatable, AND logic)",
3102
+ "name": "tag",
3156
3103
  "hasDynamicHelp": false,
3157
3104
  "multiple": true,
3158
3105
  "type": "option"
3159
3106
  },
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",
3107
+ "team": {
3108
+ "description": "Filter by team ID (repeatable, OR logic)",
3109
+ "name": "team",
3167
3110
  "hasDynamicHelp": false,
3168
3111
  "multiple": true,
3169
3112
  "type": "option"
3170
3113
  },
3171
- "none": {
3172
- "description": "Revoke everyone",
3173
- "exclusive": [
3174
- "add",
3175
- "with"
3176
- ],
3177
- "name": "none",
3114
+ "include": {
3115
+ "description": "Include extra fields: tags, teams (comma-separated)",
3116
+ "name": "include",
3117
+ "hasDynamicHelp": false,
3118
+ "multiple": false,
3119
+ "type": "option"
3120
+ },
3121
+ "public": {
3122
+ "description": "Include published faces from other accounts (open to everybody)",
3123
+ "name": "public",
3178
3124
  "allowNo": false,
3179
3125
  "type": "boolean"
3180
3126
  },
3181
- "yes": {
3182
- "description": "Skip the confirmation shown when someone would lose access",
3183
- "name": "yes",
3127
+ "shared": {
3128
+ "description": "Include faces other accounts have shared with YOU in particular",
3129
+ "name": "shared",
3130
+ "allowNo": false,
3131
+ "type": "boolean"
3132
+ },
3133
+ "system": {
3134
+ "description": "Show only the curated system faces (published faces owned by 'head')",
3135
+ "name": "system",
3184
3136
  "allowNo": false,
3185
3137
  "type": "boolean"
3138
+ },
3139
+ "from-users": {
3140
+ "description": "Only published faces from these owners (repeatable/comma-separated)",
3141
+ "name": "from-users",
3142
+ "hasDynamicHelp": false,
3143
+ "multiple": true,
3144
+ "type": "option"
3145
+ },
3146
+ "not-from-users": {
3147
+ "description": "Exclude published faces from these owners (repeatable/comma-separated)",
3148
+ "name": "not-from-users",
3149
+ "hasDynamicHelp": false,
3150
+ "multiple": true,
3151
+ "type": "option"
3186
3152
  }
3187
3153
  },
3188
3154
  "hasDynamicHelp": false,
3189
3155
  "hiddenAliases": [],
3190
- "id": "face:share",
3156
+ "id": "face:list",
3191
3157
  "pluginAlias": "faces-cli",
3192
3158
  "pluginName": "faces-cli",
3193
3159
  "pluginType": "core",
@@ -3198,23 +3164,21 @@
3198
3164
  "dist",
3199
3165
  "commands",
3200
3166
  "face",
3201
- "share.js"
3167
+ "list.js"
3202
3168
  ]
3203
3169
  },
3204
- "face:sources": {
3170
+ "face:lock": {
3205
3171
  "aliases": [],
3206
3172
  "args": {
3207
- "alias": {
3173
+ "face_id": {
3208
3174
  "description": "Face alias",
3209
- "name": "alias",
3175
+ "name": "face_id",
3210
3176
  "required": true
3211
3177
  }
3212
3178
  },
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.",
3179
+ "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.",
3214
3180
  "examples": [
3215
- "<%= config.bin %> <%= command.id %> alice",
3216
- "<%= config.bin %> <%= command.id %> alice --type thread",
3217
- "<%= config.bin %> <%= command.id %> alice --json"
3181
+ "<%= config.bin %> <%= command.id %> socrates"
3218
3182
  ],
3219
3183
  "flags": {
3220
3184
  "json": {
@@ -3247,22 +3211,11 @@
3247
3211
  "hasDynamicHelp": false,
3248
3212
  "multiple": false,
3249
3213
  "type": "option"
3250
- },
3251
- "type": {
3252
- "description": "Show only one kind of source",
3253
- "name": "type",
3254
- "hasDynamicHelp": false,
3255
- "multiple": false,
3256
- "options": [
3257
- "doc",
3258
- "thread"
3259
- ],
3260
- "type": "option"
3261
3214
  }
3262
3215
  },
3263
3216
  "hasDynamicHelp": false,
3264
3217
  "hiddenAliases": [],
3265
- "id": "face:sources",
3218
+ "id": "face:lock",
3266
3219
  "pluginAlias": "faces-cli",
3267
3220
  "pluginName": "faces-cli",
3268
3221
  "pluginType": "core",
@@ -3273,13 +3226,19 @@
3273
3226
  "dist",
3274
3227
  "commands",
3275
3228
  "face",
3276
- "sources.js"
3229
+ "lock.js"
3277
3230
  ]
3278
3231
  },
3279
- "face:stats": {
3232
+ "face:neighbors": {
3280
3233
  "aliases": [],
3281
- "args": {},
3282
- "description": "Compile and chat stats for all owned faces",
3234
+ "args": {
3235
+ "face_id": {
3236
+ "description": "Face alias",
3237
+ "name": "face_id",
3238
+ "required": true
3239
+ }
3240
+ },
3241
+ "description": "Find the most similar or dissimilar owned faces to a given face",
3283
3242
  "flags": {
3284
3243
  "json": {
3285
3244
  "description": "Format output as json.",
@@ -3311,11 +3270,39 @@
3311
3270
  "hasDynamicHelp": false,
3312
3271
  "multiple": false,
3313
3272
  "type": "option"
3273
+ },
3274
+ "k": {
3275
+ "description": "Number of results (1–20)",
3276
+ "name": "k",
3277
+ "default": 5,
3278
+ "hasDynamicHelp": false,
3279
+ "multiple": false,
3280
+ "type": "option"
3281
+ },
3282
+ "component": {
3283
+ "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.",
3284
+ "name": "component",
3285
+ "default": "face",
3286
+ "hasDynamicHelp": false,
3287
+ "multiple": false,
3288
+ "type": "option"
3289
+ },
3290
+ "direction": {
3291
+ "description": "nearest (most similar) or furthest (most dissimilar)",
3292
+ "name": "direction",
3293
+ "default": "nearest",
3294
+ "hasDynamicHelp": false,
3295
+ "multiple": false,
3296
+ "options": [
3297
+ "nearest",
3298
+ "furthest"
3299
+ ],
3300
+ "type": "option"
3314
3301
  }
3315
3302
  },
3316
3303
  "hasDynamicHelp": false,
3317
3304
  "hiddenAliases": [],
3318
- "id": "face:stats",
3305
+ "id": "face:neighbors",
3319
3306
  "pluginAlias": "faces-cli",
3320
3307
  "pluginName": "faces-cli",
3321
3308
  "pluginType": "core",
@@ -3326,10 +3313,10 @@
3326
3313
  "dist",
3327
3314
  "commands",
3328
3315
  "face",
3329
- "stats.js"
3316
+ "neighbors.js"
3330
3317
  ]
3331
3318
  },
3332
- "face:teams": {
3319
+ "face:publish": {
3333
3320
  "aliases": [],
3334
3321
  "args": {
3335
3322
  "alias": {
@@ -3338,7 +3325,10 @@
3338
3325
  "required": true
3339
3326
  }
3340
3327
  },
3341
- "description": "Set a face's team memberships (replaces all)",
3328
+ "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.",
3329
+ "examples": [
3330
+ "<%= config.bin %> <%= command.id %> alice --yes"
3331
+ ],
3342
3332
  "flags": {
3343
3333
  "json": {
3344
3334
  "description": "Format output as json.",
@@ -3371,18 +3361,16 @@
3371
3361
  "multiple": false,
3372
3362
  "type": "option"
3373
3363
  },
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"
3364
+ "yes": {
3365
+ "description": "Skip confirmation",
3366
+ "name": "yes",
3367
+ "allowNo": false,
3368
+ "type": "boolean"
3381
3369
  }
3382
3370
  },
3383
3371
  "hasDynamicHelp": false,
3384
3372
  "hiddenAliases": [],
3385
- "id": "face:teams",
3373
+ "id": "face:publish",
3386
3374
  "pluginAlias": "faces-cli",
3387
3375
  "pluginName": "faces-cli",
3388
3376
  "pluginType": "core",
@@ -3393,21 +3381,24 @@
3393
3381
  "dist",
3394
3382
  "commands",
3395
3383
  "face",
3396
- "teams.js"
3384
+ "publish.js"
3397
3385
  ]
3398
3386
  },
3399
- "face:unlock": {
3387
+ "face:share": {
3400
3388
  "aliases": [],
3401
3389
  "args": {
3402
- "face_id": {
3390
+ "alias": {
3403
3391
  "description": "Face alias",
3404
- "name": "face_id",
3392
+ "name": "alias",
3405
3393
  "required": true
3406
3394
  }
3407
3395
  },
3408
- "description": "Unlock a face (make it writable again). Thaws the face and everything it owns (documents, threads, voiceprint).",
3396
+ "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.",
3409
3397
  "examples": [
3410
- "<%= config.bin %> <%= command.id %> socrates"
3398
+ "<%= config.bin %> <%= command.id %> alice --list",
3399
+ "<%= config.bin %> <%= command.id %> alice --add dana",
3400
+ "<%= config.bin %> <%= command.id %> alice --with dana --with sam@example.com",
3401
+ "<%= config.bin %> <%= command.id %> alice --none --yes"
3411
3402
  ],
3412
3403
  "flags": {
3413
3404
  "json": {
@@ -3430,21 +3421,65 @@
3430
3421
  "env": "FACES_TOKEN",
3431
3422
  "name": "token",
3432
3423
  "hasDynamicHelp": false,
3433
- "multiple": false,
3424
+ "multiple": false,
3425
+ "type": "option"
3426
+ },
3427
+ "api-key": {
3428
+ "description": "API key",
3429
+ "env": "FACES_API_KEY",
3430
+ "name": "api-key",
3431
+ "hasDynamicHelp": false,
3432
+ "multiple": false,
3433
+ "type": "option"
3434
+ },
3435
+ "list": {
3436
+ "description": "Show who the face is shared with, and change nothing",
3437
+ "name": "list",
3438
+ "allowNo": false,
3439
+ "type": "boolean"
3440
+ },
3441
+ "add": {
3442
+ "description": "Add an account, keeping everyone already on the list — username or email (repeatable)",
3443
+ "exclusive": [
3444
+ "with",
3445
+ "none"
3446
+ ],
3447
+ "name": "add",
3448
+ "hasDynamicHelp": false,
3449
+ "multiple": true,
3434
3450
  "type": "option"
3435
3451
  },
3436
- "api-key": {
3437
- "description": "API key",
3438
- "env": "FACES_API_KEY",
3439
- "name": "api-key",
3452
+ "with": {
3453
+ "description": "Set the list to exactly these accounts, dropping anyone else (repeatable)",
3454
+ "exclusive": [
3455
+ "add",
3456
+ "none"
3457
+ ],
3458
+ "name": "with",
3440
3459
  "hasDynamicHelp": false,
3441
- "multiple": false,
3460
+ "multiple": true,
3442
3461
  "type": "option"
3462
+ },
3463
+ "none": {
3464
+ "description": "Revoke everyone",
3465
+ "exclusive": [
3466
+ "add",
3467
+ "with"
3468
+ ],
3469
+ "name": "none",
3470
+ "allowNo": false,
3471
+ "type": "boolean"
3472
+ },
3473
+ "yes": {
3474
+ "description": "Skip the confirmation shown when someone would lose access",
3475
+ "name": "yes",
3476
+ "allowNo": false,
3477
+ "type": "boolean"
3443
3478
  }
3444
3479
  },
3445
3480
  "hasDynamicHelp": false,
3446
3481
  "hiddenAliases": [],
3447
- "id": "face:unlock",
3482
+ "id": "face:share",
3448
3483
  "pluginAlias": "faces-cli",
3449
3484
  "pluginName": "faces-cli",
3450
3485
  "pluginType": "core",
@@ -3455,10 +3490,10 @@
3455
3490
  "dist",
3456
3491
  "commands",
3457
3492
  "face",
3458
- "unlock.js"
3493
+ "share.js"
3459
3494
  ]
3460
3495
  },
3461
- "face:unpublish": {
3496
+ "face:sources": {
3462
3497
  "aliases": [],
3463
3498
  "args": {
3464
3499
  "alias": {
@@ -3467,7 +3502,12 @@
3467
3502
  "required": true
3468
3503
  }
3469
3504
  },
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.",
3505
+ "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.",
3506
+ "examples": [
3507
+ "<%= config.bin %> <%= command.id %> alice",
3508
+ "<%= config.bin %> <%= command.id %> alice --type thread",
3509
+ "<%= config.bin %> <%= command.id %> alice --json"
3510
+ ],
3471
3511
  "flags": {
3472
3512
  "json": {
3473
3513
  "description": "Format output as json.",
@@ -3499,11 +3539,22 @@
3499
3539
  "hasDynamicHelp": false,
3500
3540
  "multiple": false,
3501
3541
  "type": "option"
3542
+ },
3543
+ "type": {
3544
+ "description": "Show only one kind of source",
3545
+ "name": "type",
3546
+ "hasDynamicHelp": false,
3547
+ "multiple": false,
3548
+ "options": [
3549
+ "doc",
3550
+ "thread"
3551
+ ],
3552
+ "type": "option"
3502
3553
  }
3503
3554
  },
3504
3555
  "hasDynamicHelp": false,
3505
3556
  "hiddenAliases": [],
3506
- "id": "face:unpublish",
3557
+ "id": "face:sources",
3507
3558
  "pluginAlias": "faces-cli",
3508
3559
  "pluginName": "faces-cli",
3509
3560
  "pluginType": "core",
@@ -3514,23 +3565,13 @@
3514
3565
  "dist",
3515
3566
  "commands",
3516
3567
  "face",
3517
- "unpublish.js"
3568
+ "sources.js"
3518
3569
  ]
3519
3570
  },
3520
- "face:unshare": {
3571
+ "face:stats": {
3521
3572
  "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
- ],
3573
+ "args": {},
3574
+ "description": "Compile and chat stats for all owned faces",
3534
3575
  "flags": {
3535
3576
  "json": {
3536
3577
  "description": "Format output as json.",
@@ -3562,36 +3603,11 @@
3562
3603
  "hasDynamicHelp": false,
3563
3604
  "multiple": false,
3564
3605
  "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
3606
  }
3591
3607
  },
3592
3608
  "hasDynamicHelp": false,
3593
3609
  "hiddenAliases": [],
3594
- "id": "face:unshare",
3610
+ "id": "face:stats",
3595
3611
  "pluginAlias": "faces-cli",
3596
3612
  "pluginName": "faces-cli",
3597
3613
  "pluginType": "core",
@@ -3602,13 +3618,19 @@
3602
3618
  "dist",
3603
3619
  "commands",
3604
3620
  "face",
3605
- "unshare.js"
3621
+ "stats.js"
3606
3622
  ]
3607
3623
  },
3608
- "keys:create": {
3624
+ "face:teams": {
3609
3625
  "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.",
3626
+ "args": {
3627
+ "alias": {
3628
+ "description": "Face alias",
3629
+ "name": "alias",
3630
+ "required": true
3631
+ }
3632
+ },
3633
+ "description": "Set a face's team memberships (replaces all)",
3612
3634
  "flags": {
3613
3635
  "json": {
3614
3636
  "description": "Format output as json.",
@@ -3641,52 +3663,18 @@
3641
3663
  "multiple": false,
3642
3664
  "type": "option"
3643
3665
  },
3644
- "name": {
3645
- "description": "Key name/label",
3646
- "name": "name",
3666
+ "team": {
3667
+ "description": "Team ID (repeatable, replaces all memberships)",
3668
+ "name": "team",
3647
3669
  "required": true,
3648
3670
  "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
3671
  "multiple": true,
3678
3672
  "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
3673
  }
3686
3674
  },
3687
3675
  "hasDynamicHelp": false,
3688
3676
  "hiddenAliases": [],
3689
- "id": "keys:create",
3677
+ "id": "face:teams",
3690
3678
  "pluginAlias": "faces-cli",
3691
3679
  "pluginName": "faces-cli",
3692
3680
  "pluginType": "core",
@@ -3696,14 +3684,23 @@
3696
3684
  "relativePath": [
3697
3685
  "dist",
3698
3686
  "commands",
3699
- "keys",
3700
- "create.js"
3687
+ "face",
3688
+ "teams.js"
3701
3689
  ]
3702
3690
  },
3703
- "keys:list": {
3691
+ "face:unlock": {
3704
3692
  "aliases": [],
3705
- "args": {},
3706
- "description": "List all API keys (JWT required)",
3693
+ "args": {
3694
+ "face_id": {
3695
+ "description": "Face alias",
3696
+ "name": "face_id",
3697
+ "required": true
3698
+ }
3699
+ },
3700
+ "description": "Unlock a face (make it writable again). Thaws the face and everything it owns (documents, threads, voiceprint).",
3701
+ "examples": [
3702
+ "<%= config.bin %> <%= command.id %> socrates"
3703
+ ],
3707
3704
  "flags": {
3708
3705
  "json": {
3709
3706
  "description": "Format output as json.",
@@ -3739,7 +3736,7 @@
3739
3736
  },
3740
3737
  "hasDynamicHelp": false,
3741
3738
  "hiddenAliases": [],
3742
- "id": "keys:list",
3739
+ "id": "face:unlock",
3743
3740
  "pluginAlias": "faces-cli",
3744
3741
  "pluginName": "faces-cli",
3745
3742
  "pluginType": "core",
@@ -3749,20 +3746,20 @@
3749
3746
  "relativePath": [
3750
3747
  "dist",
3751
3748
  "commands",
3752
- "keys",
3753
- "list.js"
3749
+ "face",
3750
+ "unlock.js"
3754
3751
  ]
3755
3752
  },
3756
- "keys:revoke": {
3753
+ "face:unpublish": {
3757
3754
  "aliases": [],
3758
3755
  "args": {
3759
- "key_id": {
3760
- "description": "Key ID",
3761
- "name": "key_id",
3756
+ "alias": {
3757
+ "description": "Face alias",
3758
+ "name": "alias",
3762
3759
  "required": true
3763
3760
  }
3764
3761
  },
3765
- "description": "Revoke an API key (JWT required)",
3762
+ "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.",
3766
3763
  "flags": {
3767
3764
  "json": {
3768
3765
  "description": "Format output as json.",
@@ -3794,17 +3791,11 @@
3794
3791
  "hasDynamicHelp": false,
3795
3792
  "multiple": false,
3796
3793
  "type": "option"
3797
- },
3798
- "yes": {
3799
- "description": "Skip confirmation",
3800
- "name": "yes",
3801
- "allowNo": false,
3802
- "type": "boolean"
3803
3794
  }
3804
3795
  },
3805
3796
  "hasDynamicHelp": false,
3806
3797
  "hiddenAliases": [],
3807
- "id": "keys:revoke",
3798
+ "id": "face:unpublish",
3808
3799
  "pluginAlias": "faces-cli",
3809
3800
  "pluginName": "faces-cli",
3810
3801
  "pluginType": "core",
@@ -3814,20 +3805,24 @@
3814
3805
  "relativePath": [
3815
3806
  "dist",
3816
3807
  "commands",
3817
- "keys",
3818
- "revoke.js"
3808
+ "face",
3809
+ "unpublish.js"
3819
3810
  ]
3820
3811
  },
3821
- "keys:update": {
3812
+ "face:unshare": {
3822
3813
  "aliases": [],
3823
3814
  "args": {
3824
- "key_id": {
3825
- "description": "Key ID",
3826
- "name": "key_id",
3815
+ "alias": {
3816
+ "description": "Face alias",
3817
+ "name": "alias",
3827
3818
  "required": true
3828
3819
  }
3829
3820
  },
3830
- "description": "Update API key metadata (JWT required)",
3821
+ "description": "Revoke access to a shared face. Takes effect immediately — there is no grace period.",
3822
+ "examples": [
3823
+ "<%= config.bin %> <%= command.id %> alice --from dana --yes",
3824
+ "<%= config.bin %> <%= command.id %> alice --all --yes"
3825
+ ],
3831
3826
  "flags": {
3832
3827
  "json": {
3833
3828
  "description": "Format output as json.",
@@ -3860,30 +3855,35 @@
3860
3855
  "multiple": false,
3861
3856
  "type": "option"
3862
3857
  },
3863
- "name": {
3864
- "description": "New key name",
3865
- "name": "name",
3858
+ "from": {
3859
+ "description": "Account to revoke (repeatable)",
3860
+ "exclusive": [
3861
+ "all"
3862
+ ],
3863
+ "name": "from",
3866
3864
  "hasDynamicHelp": false,
3867
- "multiple": false,
3865
+ "multiple": true,
3868
3866
  "type": "option"
3869
3867
  },
3870
- "budget": {
3871
- "description": "New spend budget in USD",
3872
- "name": "budget",
3873
- "hasDynamicHelp": false,
3874
- "multiple": false,
3875
- "type": "option"
3868
+ "all": {
3869
+ "description": "Revoke everyone",
3870
+ "exclusive": [
3871
+ "from"
3872
+ ],
3873
+ "name": "all",
3874
+ "allowNo": false,
3875
+ "type": "boolean"
3876
3876
  },
3877
- "reset-spent": {
3878
- "description": "Reset spent amount to zero",
3879
- "name": "reset-spent",
3877
+ "yes": {
3878
+ "description": "Skip confirmation",
3879
+ "name": "yes",
3880
3880
  "allowNo": false,
3881
3881
  "type": "boolean"
3882
3882
  }
3883
3883
  },
3884
3884
  "hasDynamicHelp": false,
3885
3885
  "hiddenAliases": [],
3886
- "id": "keys:update",
3886
+ "id": "face:unshare",
3887
3887
  "pluginAlias": "faces-cli",
3888
3888
  "pluginName": "faces-cli",
3889
3889
  "pluginType": "core",
@@ -3893,8 +3893,8 @@
3893
3893
  "relativePath": [
3894
3894
  "dist",
3895
3895
  "commands",
3896
- "keys",
3897
- "update.js"
3896
+ "face",
3897
+ "unshare.js"
3898
3898
  ]
3899
3899
  },
3900
3900
  "style:delete": {
@@ -7127,5 +7127,5 @@
7127
7127
  ]
7128
7128
  }
7129
7129
  },
7130
- "version": "1.8.4"
7130
+ "version": "1.8.5"
7131
7131
  }