initiative-plugin-sdk 5.0.0 → 6.0.0

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.
@@ -2,7 +2,7 @@
2
2
  "$schema": "https://json-schema.org/draft/2020-12/schema",
3
3
  "$id": "https://initiativetasks.com/schemas/plugin-manifest-v1.json",
4
4
  "title": "Initiative plug-in manifest (the 'definition' body)",
5
- "description": "What a plug-in declares it can do. A plug-in is a container, which names its `service` and answers Initiative's calls, or declarative, which names its `hosts` and no service, and whose endpoints, connection checks and webhook events Initiative runs itself from the requests and JSONata expressions written here; one plug-in is never both. This is the 'definition' field of the document served at /.well-known/initiative-plugin.json, NOT that whole document: a registrar also requires protocol_version, public_id and kind alongside it, and refuses a definition served bare. Generated from the platform's own validator vocabulary. A manifest that satisfies this schema is well-formed, not necessarily acceptable. Cross-references (the endpoint a widget binds, a requires term's connection, an endpoint's service prefix), the direction-specific rules on an endpoint, the features/blocks cross-check in both directions, UTF-8 byte-size caps, the rules tying a connection's flow and token to its scope and fields, what a webhooks block names, what a vendor setup writes to, whether every expression parses, what a declarative request and its steps name, and the bounds and unique ids of schedules are enforced by the platform on publish and are not expressible here.",
5
+ "description": "What a plug-in declares it can do. A plug-in is a container, which names its `service` and answers Initiative's calls, or declarative, which names its `hosts` and no service, and whose endpoints, connection checks and webhook events Initiative runs itself from the requests and JSONata expressions written here; one plug-in is never both. This is the 'definition' field of the document served at /.well-known/initiative-plugin.json, NOT that whole document: a registrar also requires protocol_version, public_id and kind alongside it, and refuses a definition served bare. Generated from the platform's own validator vocabulary. A manifest that satisfies this schema is well-formed, not necessarily acceptable. Cross-references (the endpoint a widget binds, a requires term's connection, an endpoint's service prefix), the direction-specific rules on an endpoint, the features/blocks cross-check in both directions, UTF-8 byte-size caps, the rules tying a connection's flow and token to its scope and fields, what a webhooks block names, what a vendor setup writes to, whether every expression parses, what a declarative request and its steps name, the bounds and unique ids of schedules, the unique keys and ids of fields, parts and actions, what a part's nodes and an action name, and a part's size and depth are enforced by the platform on publish and are not expressible here.",
6
6
  "type": "object",
7
7
  "required": [
8
8
  "plugin_kind",
@@ -85,12 +85,15 @@
85
85
  },
86
86
  "features": {
87
87
  "type": "array",
88
- "maxItems": 4,
88
+ "maxItems": 7,
89
89
  "items": {
90
90
  "enum": [
91
+ "actions",
91
92
  "dashboards",
92
93
  "endpoints",
94
+ "fields",
93
95
  "pages",
96
+ "parts",
94
97
  "widgets"
95
98
  ]
96
99
  },
@@ -187,6 +190,30 @@
187
190
  "$ref": "#/$defs/bundledDashboard"
188
191
  },
189
192
  "description": "Ready-made arrangements of this plug-in's own widgets. Publishing the plug-in publishes one ordinary dashboard listing per entry, offered to communities that install the plug-in."
193
+ },
194
+ "fields": {
195
+ "type": "array",
196
+ "maxItems": 32,
197
+ "items": {
198
+ "$ref": "#/$defs/field"
199
+ },
200
+ "description": "How the plug-in's metadata is shown on items. A container plug-in's only: a declarative plug-in holds no installation token, so it keeps no metadata to show."
201
+ },
202
+ "parts": {
203
+ "type": "array",
204
+ "maxItems": 16,
205
+ "items": {
206
+ "$ref": "#/$defs/part"
207
+ },
208
+ "description": "Pieces of items' pages and views, built from Initiative's components and bound to the plug-in's fields and actions. A container plug-in's only, as fields are."
209
+ },
210
+ "actions": {
211
+ "type": "array",
212
+ "maxItems": 16,
213
+ "items": {
214
+ "$ref": "#/$defs/action"
215
+ },
216
+ "description": "What a reader may run on an item, each one of the plug-in's write endpoints. A container plug-in's only: a declarative plug-in has no handler to do an action's work."
190
217
  }
191
218
  },
192
219
  "$defs": {
@@ -1152,6 +1179,412 @@
1152
1179
  }
1153
1180
  }
1154
1181
  },
1182
+ "metadataKey": {
1183
+ "type": "string",
1184
+ "minLength": 1,
1185
+ "maxLength": 64,
1186
+ "pattern": "^[a-z][.0123456789_abcdefghijklmnopqrstuvwxyz]*$",
1187
+ "description": "A key the plug-in keeps a value under, on an item or on its own install: a lowercase letter, then lowercase letters, digits, '_' and '.'."
1188
+ },
1189
+ "field": {
1190
+ "type": "object",
1191
+ "description": "How one of the plug-in's metadata keys is shown on Initiative's items. The plug-in keeps the value in Initiative, through its installation token; Initiative draws it with its own component for `kind` and computes its plain text itself, so a field filters, sorts and exports with no call to the plug-in. Which views show it is chosen by the community's managers, never by the plug-in. Initiative holds what is kept, and these caps are enforced there rather than here: a value of at most 8192 bytes as JSON, with a string of at most 255 characters to be found by; at most 32 keys and 65536 bytes on one item, and 256 keys and 1048576 bytes on the install.",
1192
+ "required": [
1193
+ "key",
1194
+ "name",
1195
+ "kind",
1196
+ "on"
1197
+ ],
1198
+ "properties": {
1199
+ "key": {
1200
+ "$ref": "#/$defs/metadataKey",
1201
+ "description": "The metadata key whose value this shows. Unique among this manifest's fields."
1202
+ },
1203
+ "name": {
1204
+ "$ref": "#/$defs/localizedText",
1205
+ "description": "The field's label."
1206
+ },
1207
+ "kind": {
1208
+ "enum": [
1209
+ "text",
1210
+ "number",
1211
+ "date",
1212
+ "datetime",
1213
+ "link",
1214
+ "badge",
1215
+ "progress",
1216
+ "checkbox"
1217
+ ],
1218
+ "description": "What the value is, and so how it is drawn: 'text' a string; 'number' a number; 'date' a 'YYYY-MM-DD' string; 'datetime' an ISO 8601 string with its offset; 'link' {url, text?}; 'badge' {text, tone?}; 'progress' {value, max}; 'checkbox' a boolean."
1219
+ },
1220
+ "on": {
1221
+ "type": "array",
1222
+ "minItems": 1,
1223
+ "maxItems": 6,
1224
+ "uniqueItems": true,
1225
+ "items": {
1226
+ "enum": [
1227
+ "task",
1228
+ "calendar_event",
1229
+ "queue_item",
1230
+ "counter",
1231
+ "gallery_image",
1232
+ "post"
1233
+ ]
1234
+ },
1235
+ "description": "The item kinds it is offered on."
1236
+ },
1237
+ "description": {
1238
+ "$ref": "#/$defs/localizedText",
1239
+ "description": "The one line the view editor's Add picker shows beside the name."
1240
+ },
1241
+ "tone": {
1242
+ "enum": [
1243
+ "accent",
1244
+ "positive",
1245
+ "negative",
1246
+ "warning",
1247
+ "neutral",
1248
+ "muted"
1249
+ ],
1250
+ "description": "A badge's tone when its value names none."
1251
+ },
1252
+ "requires": {
1253
+ "$ref": "#/$defs/requires"
1254
+ }
1255
+ }
1256
+ },
1257
+ "partNode": {
1258
+ "description": "One node of a part: one of Initiative's own components, told apart by 'type', with its props and, for a section or a stack, the nodes inside it.",
1259
+ "oneOf": [
1260
+ {
1261
+ "$ref": "#/$defs/sectionNode"
1262
+ },
1263
+ {
1264
+ "$ref": "#/$defs/stackNode"
1265
+ },
1266
+ {
1267
+ "$ref": "#/$defs/fieldNode"
1268
+ },
1269
+ {
1270
+ "$ref": "#/$defs/valueNode"
1271
+ },
1272
+ {
1273
+ "$ref": "#/$defs/textNode"
1274
+ },
1275
+ {
1276
+ "$ref": "#/$defs/buttonNode"
1277
+ }
1278
+ ]
1279
+ },
1280
+ "sectionNode": {
1281
+ "type": "object",
1282
+ "description": "A titled group, which the reader may fold.",
1283
+ "required": [
1284
+ "type"
1285
+ ],
1286
+ "properties": {
1287
+ "type": {
1288
+ "const": "section"
1289
+ },
1290
+ "props": {
1291
+ "type": "object",
1292
+ "properties": {
1293
+ "title": {
1294
+ "$ref": "#/$defs/localizedText"
1295
+ },
1296
+ "collapsed": {
1297
+ "type": "boolean",
1298
+ "default": false,
1299
+ "description": "Drawn folded until the reader opens it."
1300
+ }
1301
+ },
1302
+ "additionalProperties": false
1303
+ },
1304
+ "children": {
1305
+ "type": "array",
1306
+ "maxItems": 50,
1307
+ "items": {
1308
+ "$ref": "#/$defs/partNode"
1309
+ },
1310
+ "description": "Drawn in order, inside this one."
1311
+ }
1312
+ },
1313
+ "additionalProperties": false
1314
+ },
1315
+ "stackNode": {
1316
+ "type": "object",
1317
+ "description": "Nodes side by side or one above another.",
1318
+ "required": [
1319
+ "type"
1320
+ ],
1321
+ "properties": {
1322
+ "type": {
1323
+ "const": "stack"
1324
+ },
1325
+ "props": {
1326
+ "type": "object",
1327
+ "properties": {
1328
+ "direction": {
1329
+ "enum": [
1330
+ "row",
1331
+ "column"
1332
+ ],
1333
+ "default": "column"
1334
+ },
1335
+ "gap": {
1336
+ "enum": [
1337
+ "none",
1338
+ "small",
1339
+ "medium",
1340
+ "large"
1341
+ ],
1342
+ "description": "The space between the nodes. Absent: Initiative's own."
1343
+ },
1344
+ "wrap": {
1345
+ "type": "boolean",
1346
+ "default": false,
1347
+ "description": "A row runs onto a second line rather than past its edge."
1348
+ }
1349
+ },
1350
+ "additionalProperties": false
1351
+ },
1352
+ "children": {
1353
+ "type": "array",
1354
+ "maxItems": 50,
1355
+ "items": {
1356
+ "$ref": "#/$defs/partNode"
1357
+ },
1358
+ "description": "Drawn in order, inside this one."
1359
+ }
1360
+ },
1361
+ "additionalProperties": false
1362
+ },
1363
+ "fieldNode": {
1364
+ "type": "object",
1365
+ "description": "A field's label and its value.",
1366
+ "required": [
1367
+ "type",
1368
+ "props"
1369
+ ],
1370
+ "properties": {
1371
+ "type": {
1372
+ "const": "field"
1373
+ },
1374
+ "props": {
1375
+ "type": "object",
1376
+ "required": [
1377
+ "field"
1378
+ ],
1379
+ "properties": {
1380
+ "field": {
1381
+ "$ref": "#/$defs/metadataKey",
1382
+ "description": "One of this manifest's fields, by its key, offered on every item kind the part is."
1383
+ }
1384
+ },
1385
+ "additionalProperties": false
1386
+ }
1387
+ },
1388
+ "additionalProperties": false
1389
+ },
1390
+ "valueNode": {
1391
+ "type": "object",
1392
+ "description": "A field's value alone.",
1393
+ "required": [
1394
+ "type",
1395
+ "props"
1396
+ ],
1397
+ "properties": {
1398
+ "type": {
1399
+ "const": "value"
1400
+ },
1401
+ "props": {
1402
+ "type": "object",
1403
+ "required": [
1404
+ "field"
1405
+ ],
1406
+ "properties": {
1407
+ "field": {
1408
+ "$ref": "#/$defs/metadataKey",
1409
+ "description": "One of this manifest's fields, by its key, offered on every item kind the part is."
1410
+ }
1411
+ },
1412
+ "additionalProperties": false
1413
+ }
1414
+ },
1415
+ "additionalProperties": false
1416
+ },
1417
+ "textNode": {
1418
+ "type": "object",
1419
+ "description": "Words the plug-in wrote.",
1420
+ "required": [
1421
+ "type",
1422
+ "props"
1423
+ ],
1424
+ "properties": {
1425
+ "type": {
1426
+ "const": "text"
1427
+ },
1428
+ "props": {
1429
+ "type": "object",
1430
+ "required": [
1431
+ "text"
1432
+ ],
1433
+ "properties": {
1434
+ "text": {
1435
+ "$ref": "#/$defs/localizedText"
1436
+ },
1437
+ "tone": {
1438
+ "enum": [
1439
+ "accent",
1440
+ "positive",
1441
+ "negative",
1442
+ "warning",
1443
+ "neutral",
1444
+ "muted"
1445
+ ]
1446
+ }
1447
+ },
1448
+ "additionalProperties": false
1449
+ }
1450
+ },
1451
+ "additionalProperties": false
1452
+ },
1453
+ "buttonNode": {
1454
+ "type": "object",
1455
+ "description": "A button that runs one of this plug-in's actions on the item, labelled with the action's name.",
1456
+ "required": [
1457
+ "type",
1458
+ "props"
1459
+ ],
1460
+ "properties": {
1461
+ "type": {
1462
+ "const": "button"
1463
+ },
1464
+ "props": {
1465
+ "type": "object",
1466
+ "required": [
1467
+ "action"
1468
+ ],
1469
+ "properties": {
1470
+ "action": {
1471
+ "$ref": "#/$defs/identifier",
1472
+ "description": "One of this manifest's actions, by its id, offered on every item kind the part is."
1473
+ },
1474
+ "variant": {
1475
+ "enum": [
1476
+ "primary",
1477
+ "secondary",
1478
+ "ghost"
1479
+ ]
1480
+ }
1481
+ },
1482
+ "additionalProperties": false
1483
+ }
1484
+ },
1485
+ "additionalProperties": false
1486
+ },
1487
+ "part": {
1488
+ "type": "object",
1489
+ "description": "A piece of an item's page or view, built from Initiative's own components and bound to this plug-in's fields and actions. Data only: Initiative draws each node, and no plug-in code runs in the reader's browser. Which views show it is chosen by the community's managers, never by the plug-in, and Initiative places at most 3 of a plug-in's parts on one item.",
1490
+ "required": [
1491
+ "id",
1492
+ "name",
1493
+ "on",
1494
+ "tree"
1495
+ ],
1496
+ "properties": {
1497
+ "id": {
1498
+ "$ref": "#/$defs/identifier",
1499
+ "description": "Unique among this manifest's parts."
1500
+ },
1501
+ "name": {
1502
+ "$ref": "#/$defs/localizedText",
1503
+ "description": "What the view editor calls it."
1504
+ },
1505
+ "on": {
1506
+ "type": "array",
1507
+ "minItems": 1,
1508
+ "maxItems": 6,
1509
+ "uniqueItems": true,
1510
+ "items": {
1511
+ "enum": [
1512
+ "task",
1513
+ "calendar_event",
1514
+ "queue_item",
1515
+ "counter",
1516
+ "gallery_image",
1517
+ "post"
1518
+ ]
1519
+ },
1520
+ "description": "The item kinds it is offered on."
1521
+ },
1522
+ "tree": {
1523
+ "$ref": "#/$defs/partNode",
1524
+ "description": "What is drawn: at most 50 nodes, at most 4 deep."
1525
+ },
1526
+ "description": {
1527
+ "$ref": "#/$defs/localizedText",
1528
+ "description": "The one line the view editor's Add picker shows beside the name."
1529
+ },
1530
+ "requires": {
1531
+ "$ref": "#/$defs/requires"
1532
+ }
1533
+ }
1534
+ },
1535
+ "action": {
1536
+ "type": "object",
1537
+ "description": "Something a reader runs on one item, from a part's button or the item's own menu. Initiative only connects: it calls the write endpoint as the installation, with the reader as 'viewer' and the item as 'subject' in the call's token, and the endpoint does the work, usually writing the plug-in's metadata. Initiative then answers the reader with the item's metadata as it stands.",
1538
+ "required": [
1539
+ "id",
1540
+ "name",
1541
+ "endpoint",
1542
+ "on"
1543
+ ],
1544
+ "properties": {
1545
+ "id": {
1546
+ "$ref": "#/$defs/identifier",
1547
+ "description": "Unique among this manifest's actions."
1548
+ },
1549
+ "name": {
1550
+ "$ref": "#/$defs/localizedText",
1551
+ "description": "The button's or the menu entry's label."
1552
+ },
1553
+ "endpoint": {
1554
+ "$ref": "#/$defs/namespacedId",
1555
+ "description": "A write endpoint this manifest declares."
1556
+ },
1557
+ "on": {
1558
+ "type": "array",
1559
+ "minItems": 1,
1560
+ "maxItems": 6,
1561
+ "uniqueItems": true,
1562
+ "items": {
1563
+ "enum": [
1564
+ "task",
1565
+ "calendar_event",
1566
+ "queue_item",
1567
+ "counter",
1568
+ "gallery_image",
1569
+ "post"
1570
+ ]
1571
+ },
1572
+ "description": "The item kinds it is offered on."
1573
+ },
1574
+ "confirm": {
1575
+ "$ref": "#/$defs/localizedText",
1576
+ "description": "A question Initiative asks before running it. Absent: it runs at once."
1577
+ },
1578
+ "menu": {
1579
+ "type": "boolean",
1580
+ "default": false,
1581
+ "description": "Also offered in the item's own menu."
1582
+ },
1583
+ "requires": {
1584
+ "$ref": "#/$defs/requires"
1585
+ }
1586
+ }
1587
+ },
1155
1588
  "bundledDashboard": {
1156
1589
  "type": "object",
1157
1590
  "required": [