@overcrow/mcp 0.1.0 → 0.1.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.
- package/README.md +1 -1
- package/dist/bootstrap/pin.json +43 -43
- package/dist/content/docs/en/cli.md +446 -31
- package/dist/content/docs/en/creator-space.md +78 -0
- package/dist/content/docs/en/guide.md +3 -4
- package/dist/content/docs/en/manifest.md +13 -6
- package/dist/content/docs/en/mcp.md +1 -1
- package/dist/content/docs/en/publish-a-widget.md +94 -0
- package/dist/content/docs/en/publish-keys.md +95 -0
- package/dist/content/docs/en/publishing.md +5 -0
- package/dist/content/docs/en/testing.md +3 -3
- package/dist/content/docs/en/verified-domain.md +46 -0
- package/dist/content/docs/en/widget-listing.md +65 -0
- package/dist/content/docs/en/widget-review.md +57 -0
- package/dist/content/docs/en/widget-statistics.md +134 -0
- package/dist/content/docs/fr/cli.md +467 -32
- package/dist/content/docs/fr/creator-space.md +83 -0
- package/dist/content/docs/fr/guide.md +3 -4
- package/dist/content/docs/fr/manifest.md +15 -6
- package/dist/content/docs/fr/mcp.md +1 -1
- package/dist/content/docs/fr/publish-a-widget.md +101 -0
- package/dist/content/docs/fr/publish-keys.md +97 -0
- package/dist/content/docs/fr/publishing.md +5 -0
- package/dist/content/docs/fr/testing.md +3 -3
- package/dist/content/docs/fr/verified-domain.md +49 -0
- package/dist/content/docs/fr/widget-listing.md +69 -0
- package/dist/content/docs/fr/widget-review.md +59 -0
- package/dist/content/docs/fr/widget-statistics.md +141 -0
- package/dist/content/examples/countdown/manifest.json +1 -1
- package/dist/content/examples/fps/submission.json +8 -0
- package/dist/content/examples/media/submission.json +12 -0
- package/dist/content/examples/notes/submission.json +12 -0
- package/dist/content/examples/performance/submission.json +12 -0
- package/dist/content/examples/playervox-journal/submission.json +12 -0
- package/dist/content/examples/playervox-rating/submission.json +12 -0
- package/dist/content/examples/playervox-reviews/submission.json +8 -0
- package/dist/content/examples/playervox-score/submission.json +8 -0
- package/dist/content/examples/session/submission.json +8 -0
- package/dist/content/examples/stopwatch/submission.json +12 -0
- package/dist/content/examples/twitch-chat/submission.json +12 -0
- package/dist/content/examples/warframe-market/submission.json +24 -0
- package/dist/content/examples/weather/manifest.json +1 -1
- package/dist/content/examples/weather/submission.json +17 -0
- package/dist/content/index.json +106 -2
- package/dist/content/reference/errors.json +224 -12
- package/dist/content/reference/manifest.md +1 -1
- package/dist/hidden.js +47 -0
- package/dist/texts.js +1 -1
- package/dist/tools/project.js +5 -0
- package/dist/tools/submission.js +1 -1
- package/dist/version.js +1 -1
- package/npm-shrinkwrap.json +2 -2
- package/package.json +1 -1
|
@@ -1130,12 +1130,12 @@
|
|
|
1130
1130
|
},
|
|
1131
1131
|
"listing.json": {
|
|
1132
1132
|
"en": {
|
|
1133
|
-
"meaning": "The marketplace text of a submission; read by `admit`. — no",
|
|
1133
|
+
"meaning": "The marketplace text of a submission; read by `admit`. In the creator space, where the listing is edited, only a proposal to import. — no",
|
|
1134
1134
|
"page": "cli",
|
|
1135
1135
|
"section": "Files of a project"
|
|
1136
1136
|
},
|
|
1137
1137
|
"fr": {
|
|
1138
|
-
"meaning": "Le texte de marketplace d’une soumission ; lu par `admit`. — non",
|
|
1138
|
+
"meaning": "Le texte de marketplace d’une soumission ; lu par `admit`. Dans l’espace créateurs, où la fiche se modifie, une simple proposition d’import. — non",
|
|
1139
1139
|
"page": "cli",
|
|
1140
1140
|
"section": "Fichiers d’un projet"
|
|
1141
1141
|
}
|
|
@@ -1274,60 +1274,84 @@
|
|
|
1274
1274
|
},
|
|
1275
1275
|
"admission.reserved_id": {
|
|
1276
1276
|
"en": {
|
|
1277
|
-
"meaning": "error — A `com.playervox.*` ID, reserved for PlayerVox.",
|
|
1277
|
+
"meaning": "error — A `com.playervox.*` ID, reserved for PlayerVox; without `--publisher`, also an ID under a reserved handle (`playervox.*`, `admin.*`…).",
|
|
1278
1278
|
"page": "cli",
|
|
1279
1279
|
"section": "admit"
|
|
1280
1280
|
},
|
|
1281
1281
|
"fr": {
|
|
1282
|
-
"meaning": "erreur — Un ID `com.playervox.*`, réservé à PlayerVox.",
|
|
1282
|
+
"meaning": "erreur — Un ID `com.playervox.*`, réservé à PlayerVox ; sans `--publisher`, aussi un ID sous un pseudo réservé (`playervox.*`, `admin.*`…).",
|
|
1283
|
+
"page": "cli",
|
|
1284
|
+
"section": "admit"
|
|
1285
|
+
}
|
|
1286
|
+
},
|
|
1287
|
+
"admission.placeholder_id": {
|
|
1288
|
+
"en": {
|
|
1289
|
+
"meaning": "error — An example ID, without `--publisher`.",
|
|
1290
|
+
"page": "cli",
|
|
1291
|
+
"section": "admit"
|
|
1292
|
+
},
|
|
1293
|
+
"fr": {
|
|
1294
|
+
"meaning": "erreur — Un ID d’exemple, sans `--publisher`.",
|
|
1295
|
+
"page": "cli",
|
|
1296
|
+
"section": "admit"
|
|
1297
|
+
}
|
|
1298
|
+
},
|
|
1299
|
+
"admission.id_not_owned": {
|
|
1300
|
+
"en": {
|
|
1301
|
+
"meaning": "error — The ID does not belong to the publisher, or, without `--publisher`, cannot belong to any.",
|
|
1302
|
+
"page": "cli",
|
|
1303
|
+
"section": "admit"
|
|
1304
|
+
},
|
|
1305
|
+
"fr": {
|
|
1306
|
+
"meaning": "erreur — L’ID n’appartient pas à l’éditeur, ou, sans `--publisher`, ne peut appartenir à personne.",
|
|
1283
1307
|
"page": "cli",
|
|
1284
1308
|
"section": "admit"
|
|
1285
1309
|
}
|
|
1286
1310
|
},
|
|
1287
1311
|
"admission.listing_missing": {
|
|
1288
1312
|
"en": {
|
|
1289
|
-
"meaning": "error — No `listing.json`, or one that breaks the listing's rules.",
|
|
1313
|
+
"meaning": "error — No `listing.json`, or one that breaks the listing's rules (a warning with `--listing optional`).",
|
|
1290
1314
|
"page": "cli",
|
|
1291
1315
|
"section": "admit"
|
|
1292
1316
|
},
|
|
1293
1317
|
"fr": {
|
|
1294
|
-
"meaning": "erreur — Pas de `listing.json`, ou un fichier qui enfreint les règles de la fiche.",
|
|
1318
|
+
"meaning": "erreur — Pas de `listing.json`, ou un fichier qui enfreint les règles de la fiche (un avertissement avec `--listing optional`).",
|
|
1295
1319
|
"page": "cli",
|
|
1296
1320
|
"section": "admit"
|
|
1297
1321
|
}
|
|
1298
1322
|
},
|
|
1299
1323
|
"admission.listing": {
|
|
1300
1324
|
"en": {
|
|
1301
|
-
"meaning": "error — No `listing.json`, or one that breaks the listing's rules.",
|
|
1325
|
+
"meaning": "error — No `listing.json`, or one that breaks the listing's rules (a warning with `--listing optional`).",
|
|
1302
1326
|
"page": "cli",
|
|
1303
1327
|
"section": "admit"
|
|
1304
1328
|
},
|
|
1305
1329
|
"fr": {
|
|
1306
|
-
"meaning": "erreur — Pas de `listing.json`, ou un fichier qui enfreint les règles de la fiche.",
|
|
1330
|
+
"meaning": "erreur — Pas de `listing.json`, ou un fichier qui enfreint les règles de la fiche (un avertissement avec `--listing optional`).",
|
|
1307
1331
|
"page": "cli",
|
|
1308
1332
|
"section": "admit"
|
|
1309
1333
|
}
|
|
1310
1334
|
},
|
|
1311
1335
|
"admission.preview": {
|
|
1312
1336
|
"en": {
|
|
1313
|
-
"meaning": "error — `preview` does not name a packaged PNG within bounds.",
|
|
1337
|
+
"meaning": "error — `preview` does not name a packaged PNG within bounds (a warning with `--listing optional`).",
|
|
1314
1338
|
"page": "cli",
|
|
1315
1339
|
"section": "admit"
|
|
1316
1340
|
},
|
|
1317
1341
|
"fr": {
|
|
1318
|
-
"meaning": "erreur — `preview` ne désigne pas un PNG empaqueté dans les limites.",
|
|
1342
|
+
"meaning": "erreur — `preview` ne désigne pas un PNG empaqueté dans les limites (un avertissement avec `--listing optional`).",
|
|
1319
1343
|
"page": "cli",
|
|
1320
1344
|
"section": "admit"
|
|
1321
1345
|
}
|
|
1322
1346
|
},
|
|
1323
1347
|
"admission.license": {
|
|
1324
1348
|
"en": {
|
|
1325
|
-
"meaning": "error — A PlayerVox widget whose license is not MIT.",
|
|
1349
|
+
"meaning": "error — A PlayerVox widget whose license is not MIT (a warning with `--listing optional`).",
|
|
1326
1350
|
"page": "cli",
|
|
1327
1351
|
"section": "admit"
|
|
1328
1352
|
},
|
|
1329
1353
|
"fr": {
|
|
1330
|
-
"meaning": "erreur — Un widget PlayerVox dont la licence n’est pas MIT.",
|
|
1354
|
+
"meaning": "erreur — Un widget PlayerVox dont la licence n’est pas MIT (un avertissement avec `--listing optional`).",
|
|
1331
1355
|
"page": "cli",
|
|
1332
1356
|
"section": "admit"
|
|
1333
1357
|
}
|
|
@@ -1344,6 +1368,42 @@
|
|
|
1344
1368
|
"section": "admit"
|
|
1345
1369
|
}
|
|
1346
1370
|
},
|
|
1371
|
+
"admission.previous": {
|
|
1372
|
+
"en": {
|
|
1373
|
+
"meaning": "error — The previous version cannot be read.",
|
|
1374
|
+
"page": "cli",
|
|
1375
|
+
"section": "admit"
|
|
1376
|
+
},
|
|
1377
|
+
"fr": {
|
|
1378
|
+
"meaning": "erreur — La version précédente ne peut pas être lue.",
|
|
1379
|
+
"page": "cli",
|
|
1380
|
+
"section": "admit"
|
|
1381
|
+
}
|
|
1382
|
+
},
|
|
1383
|
+
"admission.previous_mismatch": {
|
|
1384
|
+
"en": {
|
|
1385
|
+
"meaning": "error — The previous version is another widget.",
|
|
1386
|
+
"page": "cli",
|
|
1387
|
+
"section": "admit"
|
|
1388
|
+
},
|
|
1389
|
+
"fr": {
|
|
1390
|
+
"meaning": "erreur — La version précédente est un autre widget.",
|
|
1391
|
+
"page": "cli",
|
|
1392
|
+
"section": "admit"
|
|
1393
|
+
}
|
|
1394
|
+
},
|
|
1395
|
+
"admission.version_not_newer": {
|
|
1396
|
+
"en": {
|
|
1397
|
+
"meaning": "error — The version is not above the previous one.",
|
|
1398
|
+
"page": "cli",
|
|
1399
|
+
"section": "admit"
|
|
1400
|
+
},
|
|
1401
|
+
"fr": {
|
|
1402
|
+
"meaning": "erreur — La version n’est pas supérieure à la précédente.",
|
|
1403
|
+
"page": "cli",
|
|
1404
|
+
"section": "admit"
|
|
1405
|
+
}
|
|
1406
|
+
},
|
|
1347
1407
|
"admission.package_rebuilt": {
|
|
1348
1408
|
"en": {
|
|
1349
1409
|
"meaning": "warning — The submitted archive differs from the rebuild in other files.",
|
|
@@ -1368,6 +1428,150 @@
|
|
|
1368
1428
|
"section": "admit"
|
|
1369
1429
|
}
|
|
1370
1430
|
},
|
|
1431
|
+
"sources.archive_size": {
|
|
1432
|
+
"en": {
|
|
1433
|
+
"meaning": "More than 32 MiB.",
|
|
1434
|
+
"page": "cli",
|
|
1435
|
+
"section": "Source archives"
|
|
1436
|
+
},
|
|
1437
|
+
"fr": {
|
|
1438
|
+
"meaning": "Plus de 32 Mio.",
|
|
1439
|
+
"page": "cli",
|
|
1440
|
+
"section": "Archives de sources"
|
|
1441
|
+
}
|
|
1442
|
+
},
|
|
1443
|
+
"sources.too_large": {
|
|
1444
|
+
"en": {
|
|
1445
|
+
"meaning": "More than 64 MiB or 2,000 files once uncompressed.",
|
|
1446
|
+
"page": "cli",
|
|
1447
|
+
"section": "Source archives"
|
|
1448
|
+
},
|
|
1449
|
+
"fr": {
|
|
1450
|
+
"meaning": "Plus de 64 Mio ou de 2 000 fichiers une fois décompressée.",
|
|
1451
|
+
"page": "cli",
|
|
1452
|
+
"section": "Archives de sources"
|
|
1453
|
+
}
|
|
1454
|
+
},
|
|
1455
|
+
"sources.too_many_files": {
|
|
1456
|
+
"en": {
|
|
1457
|
+
"meaning": "More than 64 MiB or 2,000 files once uncompressed.",
|
|
1458
|
+
"page": "cli",
|
|
1459
|
+
"section": "Source archives"
|
|
1460
|
+
},
|
|
1461
|
+
"fr": {
|
|
1462
|
+
"meaning": "Plus de 64 Mio ou de 2 000 fichiers une fois décompressée.",
|
|
1463
|
+
"page": "cli",
|
|
1464
|
+
"section": "Archives de sources"
|
|
1465
|
+
}
|
|
1466
|
+
},
|
|
1467
|
+
"sources.unsafe_name": {
|
|
1468
|
+
"en": {
|
|
1469
|
+
"meaning": "A name that could leave the widget folder (`../`, `/` first), or that some system cannot use: a character Windows forbids (`\\`, `:`, `*`, `?`, `\"`, `<`, `>`, \\|), anything but printable ASCII, a final dot or space, `CON`, `NUL`, `COM1`… The message names the character and the file.",
|
|
1470
|
+
"page": "cli",
|
|
1471
|
+
"section": "Source archives"
|
|
1472
|
+
},
|
|
1473
|
+
"fr": {
|
|
1474
|
+
"meaning": "Un nom qui pourrait sortir du dossier du widget (`../`, `/` en tête), ou qu’un système ne peut pas utiliser : un caractère interdit par Windows (`\\`, `:`, `*`, `?`, `\"`, `<`, `>`, \\|), autre chose que de l’ASCII imprimable, un point ou une espace final, `CON`, `NUL`, `COM1`… Le message nomme le caractère et le fichier.",
|
|
1475
|
+
"page": "cli",
|
|
1476
|
+
"section": "Archives de sources"
|
|
1477
|
+
}
|
|
1478
|
+
},
|
|
1479
|
+
"sources.backslash": {
|
|
1480
|
+
"en": {
|
|
1481
|
+
"meaning": "Folders separated by `\\`, as Windows PowerShell 5.1 `Compress-Archive` writes them. Send the widget folder itself in the creator space, or use `submit`, which makes a correct ZIP.",
|
|
1482
|
+
"page": "cli",
|
|
1483
|
+
"section": "Source archives"
|
|
1484
|
+
},
|
|
1485
|
+
"fr": {
|
|
1486
|
+
"meaning": "Des dossiers séparés par `\\`, comme les écrit `Compress-Archive` de Windows PowerShell 5.1. Envoyez le dossier du widget lui-même dans l’espace créateurs, ou utilisez `submit`, qui fait un ZIP correct.",
|
|
1487
|
+
"page": "cli",
|
|
1488
|
+
"section": "Archives de sources"
|
|
1489
|
+
}
|
|
1490
|
+
},
|
|
1491
|
+
"sources.duplicate_name": {
|
|
1492
|
+
"en": {
|
|
1493
|
+
"meaning": "Two names that differ only by case, or a file that is also a folder.",
|
|
1494
|
+
"page": "cli",
|
|
1495
|
+
"section": "Source archives"
|
|
1496
|
+
},
|
|
1497
|
+
"fr": {
|
|
1498
|
+
"meaning": "Deux noms qui ne diffèrent que par la casse, ou un fichier qui est aussi un dossier.",
|
|
1499
|
+
"page": "cli",
|
|
1500
|
+
"section": "Archives de sources"
|
|
1501
|
+
}
|
|
1502
|
+
},
|
|
1503
|
+
"sources.link": {
|
|
1504
|
+
"en": {
|
|
1505
|
+
"meaning": "A link, or a device, a FIFO or a socket.",
|
|
1506
|
+
"page": "cli",
|
|
1507
|
+
"section": "Source archives"
|
|
1508
|
+
},
|
|
1509
|
+
"fr": {
|
|
1510
|
+
"meaning": "Un lien, ou un périphérique, une FIFO ou un socket.",
|
|
1511
|
+
"page": "cli",
|
|
1512
|
+
"section": "Archives de sources"
|
|
1513
|
+
}
|
|
1514
|
+
},
|
|
1515
|
+
"sources.special_file": {
|
|
1516
|
+
"en": {
|
|
1517
|
+
"meaning": "A link, or a device, a FIFO or a socket.",
|
|
1518
|
+
"page": "cli",
|
|
1519
|
+
"section": "Source archives"
|
|
1520
|
+
},
|
|
1521
|
+
"fr": {
|
|
1522
|
+
"meaning": "Un lien, ou un périphérique, une FIFO ou un socket.",
|
|
1523
|
+
"page": "cli",
|
|
1524
|
+
"section": "Archives de sources"
|
|
1525
|
+
}
|
|
1526
|
+
},
|
|
1527
|
+
"sources.bomb": {
|
|
1528
|
+
"en": {
|
|
1529
|
+
"meaning": "An entry that inflates far beyond its compressed size, or beyond its declared size.",
|
|
1530
|
+
"page": "cli",
|
|
1531
|
+
"section": "Source archives"
|
|
1532
|
+
},
|
|
1533
|
+
"fr": {
|
|
1534
|
+
"meaning": "Une entrée qui se décompresse bien au-delà de sa taille compressée, ou de sa taille déclarée.",
|
|
1535
|
+
"page": "cli",
|
|
1536
|
+
"section": "Archives de sources"
|
|
1537
|
+
}
|
|
1538
|
+
},
|
|
1539
|
+
"sources.read": {
|
|
1540
|
+
"en": {
|
|
1541
|
+
"meaning": "The file cannot be read (exit status 2).",
|
|
1542
|
+
"page": "cli",
|
|
1543
|
+
"section": "Source archives"
|
|
1544
|
+
},
|
|
1545
|
+
"fr": {
|
|
1546
|
+
"meaning": "Le fichier ne peut pas être lu (code de sortie 2).",
|
|
1547
|
+
"page": "cli",
|
|
1548
|
+
"section": "Archives de sources"
|
|
1549
|
+
}
|
|
1550
|
+
},
|
|
1551
|
+
"sources.encrypted": {
|
|
1552
|
+
"en": {
|
|
1553
|
+
"meaning": "An encrypted entry.",
|
|
1554
|
+
"page": "cli",
|
|
1555
|
+
"section": "Source archives"
|
|
1556
|
+
},
|
|
1557
|
+
"fr": {
|
|
1558
|
+
"meaning": "Une entrée chiffrée.",
|
|
1559
|
+
"page": "cli",
|
|
1560
|
+
"section": "Archives de sources"
|
|
1561
|
+
}
|
|
1562
|
+
},
|
|
1563
|
+
"sources.archive": {
|
|
1564
|
+
"en": {
|
|
1565
|
+
"meaning": "Anything else a ZIP should not hold: a comment above 1,024 bytes or holding an end record, bytes before, between or after the entries or after an entry's compressed data, another name in an extra field, sizes or checksums that disagree.",
|
|
1566
|
+
"page": "cli",
|
|
1567
|
+
"section": "Source archives"
|
|
1568
|
+
},
|
|
1569
|
+
"fr": {
|
|
1570
|
+
"meaning": "Tout autre élément qu’un ZIP ne doit pas contenir : un commentaire de plus de 1 024 octets ou qui contient un enregistrement de fin, des octets avant, entre ou après les entrées ou après les données compressées d’une entrée, un autre nom dans un champ extra, des tailles ou des sommes de contrôle qui ne concordent pas.",
|
|
1571
|
+
"page": "cli",
|
|
1572
|
+
"section": "Archives de sources"
|
|
1573
|
+
}
|
|
1574
|
+
},
|
|
1371
1575
|
"shortcuts.toggle": {
|
|
1372
1576
|
"en": {
|
|
1373
1577
|
"meaning": "text — Host-formatted key chord.",
|
|
@@ -1696,6 +1900,10 @@
|
|
|
1696
1900
|
"from": "Scenarios",
|
|
1697
1901
|
"codes": "`scenario`, `scenario_name`, `too_many_scenarios`"
|
|
1698
1902
|
},
|
|
1903
|
+
"sources": {
|
|
1904
|
+
"from": "A source archive",
|
|
1905
|
+
"codes": "see source archives"
|
|
1906
|
+
},
|
|
1699
1907
|
"init": {
|
|
1700
1908
|
"from": "Those commands",
|
|
1701
1909
|
"codes": "listed above"
|
|
@@ -1707,6 +1915,10 @@
|
|
|
1707
1915
|
"admission": {
|
|
1708
1916
|
"from": "Those commands",
|
|
1709
1917
|
"codes": "listed above"
|
|
1918
|
+
},
|
|
1919
|
+
"submit": {
|
|
1920
|
+
"from": "What `submit` checks before sending",
|
|
1921
|
+
"codes": "`widget_not_submittable`, `agreement_required`, `limit_reached`, `version_too_low`, `justification_missing`, `archive_too_large`, `archive_mismatch`, `release_notes`, `justification`, `review_message`"
|
|
1710
1922
|
}
|
|
1711
1923
|
}
|
|
1712
1924
|
}
|
|
@@ -8,7 +8,7 @@ Generated from the creator documentation (pages `manifest`, `services`) and the
|
|
|
8
8
|
| --- | --- | --- | --- |
|
|
9
9
|
| `schemaVersion` | integer 1 to 1 | yes | Manifest document version. |
|
|
10
10
|
| `apiVersion` | integer 1 to 1 | yes | Widget API version; selects this schema. |
|
|
11
|
-
| `id` | `widget ID` | yes |
|
|
11
|
+
| `id` | `widget ID` | yes | Widget ID, from 3 bytes to 128 bytes: at least two dot-separated segments of `[a-z0-9-]`, each at most 63 bytes and not starting or ending with `-`; `<handle>.<name>` with the publisher's handle, or a domain the publisher verified, reversed, then a name. `com.playervox` and `com.playervox.*` are reserved for packages signed by PlayerVox. |
|
|
12
12
|
| `version` | `version` | yes | SemVer 2.0.0 `MAJOR.MINOR.PATCH[-PRERELEASE]` in canonical form, at most 64 bytes; build metadata is rejected. |
|
|
13
13
|
| `name` | `WidgetName` | yes | Localized widget name shown by the host. |
|
|
14
14
|
| `sizing` | `Sizing` | yes | Size and fit rules applied by the widget's frame. |
|
package/dist/hidden.js
ADDED
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
// Characters a widget name never holds, as the widget schema refuses them
|
|
2
|
+
// (crates/overcrow-widget-schema/src/text.rs, kept equal by a test):
|
|
3
|
+
// invisible, blank and text-direction characters, so that a name cannot
|
|
4
|
+
// read otherwise than it is written.
|
|
5
|
+
/** Inclusive ranges of code points. */
|
|
6
|
+
export const INVISIBLE_CHARACTERS = [
|
|
7
|
+
[0x00ad, 0x00ad],
|
|
8
|
+
[0x034f, 0x034f],
|
|
9
|
+
[0x061c, 0x061c],
|
|
10
|
+
[0x115f, 0x1160],
|
|
11
|
+
[0x17b4, 0x17b5],
|
|
12
|
+
[0x180b, 0x180f],
|
|
13
|
+
[0x200b, 0x200f],
|
|
14
|
+
[0x2028, 0x202e],
|
|
15
|
+
[0x2060, 0x206f],
|
|
16
|
+
[0x2800, 0x2800],
|
|
17
|
+
[0x3164, 0x3164],
|
|
18
|
+
[0xfeff, 0xfeff],
|
|
19
|
+
[0xffa0, 0xffa0],
|
|
20
|
+
[0xfff9, 0xfffb],
|
|
21
|
+
[0x1bca0, 0x1bca3],
|
|
22
|
+
[0x1d173, 0x1d17a],
|
|
23
|
+
[0xe0000, 0xe0fff],
|
|
24
|
+
];
|
|
25
|
+
const isSelector = (code) => code >= 0xfe00 && code <= 0xfe0f;
|
|
26
|
+
/**
|
|
27
|
+
* The first hidden character of `text`, its position counted in characters
|
|
28
|
+
* from 1: an invisible character, or a variation selector that starts the
|
|
29
|
+
* text or follows another one (an emoji keeps its presentation selector).
|
|
30
|
+
*/
|
|
31
|
+
export function hiddenCharacter(text) {
|
|
32
|
+
let previous;
|
|
33
|
+
let position = 0;
|
|
34
|
+
for (const character of text) {
|
|
35
|
+
position += 1;
|
|
36
|
+
const code = character.codePointAt(0) ?? 0;
|
|
37
|
+
const misplacedSelector = isSelector(code) && (previous === undefined || isSelector(previous));
|
|
38
|
+
if (misplacedSelector ||
|
|
39
|
+
INVISIBLE_CHARACTERS.some(([start, end]) => code >= start && code <= end)) {
|
|
40
|
+
return { position, code };
|
|
41
|
+
}
|
|
42
|
+
previous = code;
|
|
43
|
+
}
|
|
44
|
+
return undefined;
|
|
45
|
+
}
|
|
46
|
+
/** `U+202E`. */
|
|
47
|
+
export const codePoint = (code) => `U+${code.toString(16).toUpperCase().padStart(4, "0")}`;
|
package/dist/texts.js
CHANGED
|
@@ -9,7 +9,7 @@ Work in this order: status, setup (once), create_widget, install_sdk, check, tes
|
|
|
9
9
|
|
|
10
10
|
Widget ID: it is final and can never be reused. Ask the user for it: <handle>.<name>, where <handle> is their publisher handle in the OverCrow creator space (such as nova.lol-timers), or a reverse domain they can verify (such as gg.nova.lol-timers). Never com.playervox.*: it is reserved for PlayerVox.
|
|
11
11
|
|
|
12
|
-
Submission: prepare_submission checks everything the creator space asks for, writes the ZIP of the sources to dist/, and lists the texts to write: why the widget needs each permission, the release notes and the description in English and French. Draft them and show them to the user. The user sends the ZIP and the texts in the OverCrow creator space
|
|
12
|
+
Submission: prepare_submission checks everything the creator space asks for, writes the ZIP of the sources to dist/, and lists the texts to write: why the widget needs each permission, the release notes and the description in English and French. Draft them and show them to the user. The user sends the ZIP and the texts in the OverCrow creator space, at creators.playervox.com.
|
|
13
13
|
|
|
14
14
|
Security: ask for the least. Declare only the permissions the widget uses. Network: exact routes (method and path, parameters constrained), a tight maxResponseBytes, no user data sent without a reason. No secret in a widget: it is public. Clipboard writes only in the handler of a user action. Bounded storage.
|
|
15
15
|
|
package/dist/tools/project.js
CHANGED
|
@@ -5,6 +5,7 @@ import { z } from "zod";
|
|
|
5
5
|
import { Cli } from "../cli.js";
|
|
6
6
|
import { projects } from "../content.js";
|
|
7
7
|
import { installPackages } from "../npm.js";
|
|
8
|
+
import { codePoint, hiddenCharacter } from "../hidden.js";
|
|
8
9
|
import { cleanLine } from "../text.js";
|
|
9
10
|
import { DESCRIPTIONS, TEMPLATE_SUMMARIES } from "../texts.js";
|
|
10
11
|
import { ID_FORMS, idProblem, isPlaceholderId } from "../ids.js";
|
|
@@ -19,6 +20,10 @@ export function nameProblem(name) {
|
|
|
19
20
|
REFUSED_IN_NAME.test(name)) {
|
|
20
21
|
return "The name must be 1 to 48 characters, without spaces at either end, control characters, < or >.";
|
|
21
22
|
}
|
|
23
|
+
const hidden = hiddenCharacter(name);
|
|
24
|
+
if (hidden) {
|
|
25
|
+
return `The name holds a hidden character, ${codePoint(hidden.code)}, at position ${hidden.position}: remove it.`;
|
|
26
|
+
}
|
|
22
27
|
return undefined;
|
|
23
28
|
}
|
|
24
29
|
async function listFiles(directory) {
|
package/dist/tools/submission.js
CHANGED
|
@@ -23,7 +23,7 @@ const DIRECTORY = z
|
|
|
23
23
|
const VERSION = /^\d+\.\d+\.\d+$/;
|
|
24
24
|
const MAX_LISTED_INCLUDED = 200;
|
|
25
25
|
const MAX_LISTED_EXCLUDED = 100;
|
|
26
|
-
export const SEND = "The user sends the ZIP and these texts in the OverCrow creator space
|
|
26
|
+
export const SEND = "The user sends the ZIP and these texts in the OverCrow creator space, at creators.playervox.com.";
|
|
27
27
|
const KIB = 1024;
|
|
28
28
|
const kib = (bytes) => `${Math.max(1, Math.round(bytes / KIB))} KiB`;
|
|
29
29
|
const size = (bytes) => bytes >= KIB * KIB && bytes % (KIB * KIB) === 0
|
package/dist/version.js
CHANGED
package/npm-shrinkwrap.json
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@overcrow/mcp",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.2",
|
|
4
4
|
"lockfileVersion": 3,
|
|
5
5
|
"requires": true,
|
|
6
6
|
"packages": {
|
|
7
7
|
"": {
|
|
8
8
|
"name": "@overcrow/mcp",
|
|
9
|
-
"version": "0.1.
|
|
9
|
+
"version": "0.1.2",
|
|
10
10
|
"license": "MIT",
|
|
11
11
|
"dependencies": {
|
|
12
12
|
"@modelcontextprotocol/server": "2.3.1",
|