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.
@@ -1,9 +1,9 @@
1
1
  {
2
- "$comment": "The Initiative plug-in contract: the vocabulary a plug-in manifest draws on and the shape it takes. Hand-authored HERE, in the initiative-plugin-sdk repository, and nowhere else. Running `npm run generate` in that repository rewrites schemas/plugin-manifest.json and src/contract.ts from this file. Initiative vendors this file to derive its validator's constants and hold its normalizer to the field inventory; the copies under initiative's backend/vendor/plugin-kit and frontend/src/contract are refreshed by backend/scripts/refresh_plugin_kit.py and are not edited there. Edit this; never the generated output. A manifest describes a plug-in's API and nothing about how a consumer PRESENTS it: there is no term here for a control, a picker, a default or a bound, because what a step looks like on somebody's canvas is that consumer's to decide and ours to stay out of.",
2
+ "$comment": "The Initiative plug-in contract: the vocabulary a plug-in manifest draws on and the shape it takes. Hand-authored HERE, in the initiative-plugin-sdk repository, and nowhere else. Running `npm run generate` in that repository rewrites schemas/plugin-manifest.json and src/contract.ts from this file. Initiative vendors this file to derive its validator's constants and hold its normalizer to the field inventory; the copies under initiative's backend/vendor/plugin-kit and frontend/src/contract are refreshed by backend/scripts/refresh_plugin_kit.py and are not edited there. Edit this; never the generated output. A manifest describes a plug-in's API and nothing about how a consumer PRESENTS it: there is no term here for a control, a picker, a default or a bound, because what a step looks like on somebody's canvas is that consumer's to decide and ours to stay out of. Fields, parts and actions are the one exception, and a narrow one: they say how a plug-in's own values are shown in Initiative's own components, and the community's managers decide where.",
3
3
  "schema": {
4
4
  "$id": "https://initiativetasks.com/schemas/plugin-manifest-v1.json",
5
5
  "title": "Initiative plug-in manifest (the 'definition' body)",
6
- "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."
6
+ "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."
7
7
  },
8
8
  "charsets": {
9
9
  "identifier": "-0123456789_abcdefghijklmnopqrstuvwxyz",
@@ -16,13 +16,17 @@
16
16
  "localeTag": "-ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz",
17
17
  "version": "0123456789.-+abcdefghijklmnopqrstuvwxyz",
18
18
  "artwork": "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789/._-",
19
- "queryName": "-.0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ[]_abcdefghijklmnopqrstuvwxyz~"
19
+ "queryName": "-.0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ[]_abcdefghijklmnopqrstuvwxyz~",
20
+ "metadataKey": "._0123456789abcdefghijklmnopqrstuvwxyz"
20
21
  },
21
22
  "enums": {
22
23
  "feature": [
24
+ "actions",
23
25
  "dashboards",
24
26
  "endpoints",
27
+ "fields",
25
28
  "pages",
29
+ "parts",
26
30
  "widgets"
27
31
  ],
28
32
  "protocol": [
@@ -151,6 +155,32 @@
151
155
  "geolocation",
152
156
  "microphone"
153
157
  ],
158
+ "itemKind": [
159
+ "task",
160
+ "calendar_event",
161
+ "queue_item",
162
+ "counter",
163
+ "gallery_image",
164
+ "post"
165
+ ],
166
+ "fieldKind": [
167
+ "text",
168
+ "number",
169
+ "date",
170
+ "datetime",
171
+ "link",
172
+ "badge",
173
+ "progress",
174
+ "checkbox"
175
+ ],
176
+ "tone": [
177
+ "accent",
178
+ "positive",
179
+ "negative",
180
+ "warning",
181
+ "neutral",
182
+ "muted"
183
+ ],
154
184
  "listingKind": [
155
185
  "plugin",
156
186
  "dashboard"
@@ -206,6 +236,19 @@
206
236
  "returnsPerEndpoint": 24,
207
237
  "pages": 12,
208
238
  "pageCapabilities": 8,
239
+ "fields": 32,
240
+ "parts": 16,
241
+ "actions": 16,
242
+ "partNodes": 50,
243
+ "partDepth": 4,
244
+ "metadataKeyLength": 64,
245
+ "metadataValueBytes": 8192,
246
+ "metadataLookupLength": 255,
247
+ "metadataKeysPerObject": 32,
248
+ "metadataBytesPerObject": 65536,
249
+ "installMetadataKeys": 256,
250
+ "installMetadataBytes": 1048576,
251
+ "partsPlacedPerItem": 3,
209
252
  "bundledDashboards": 8,
210
253
  "dashboardWidgets": 50,
211
254
  "dashboardGridColumns": 12,
@@ -1166,6 +1209,375 @@
1166
1209
  }
1167
1210
  }
1168
1211
  },
1212
+ "metadataKey": {
1213
+ "type": "string",
1214
+ "minLength": 1,
1215
+ "maxLength": "metadataKeyLength",
1216
+ "patternFrom": "metadataKey",
1217
+ "patternForm": "letterFirst",
1218
+ "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 '.'."
1219
+ },
1220
+ "field": {
1221
+ "type": "object",
1222
+ "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 {metadataValueBytes} bytes as JSON, with a string of at most {metadataLookupLength} characters to be found by; at most {metadataKeysPerObject} keys and {metadataBytesPerObject} bytes on one item, and {installMetadataKeys} keys and {installMetadataBytes} bytes on the install.",
1223
+ "required": [
1224
+ "key",
1225
+ "name",
1226
+ "kind",
1227
+ "on"
1228
+ ],
1229
+ "properties": {
1230
+ "key": {
1231
+ "ref": "metadataKey",
1232
+ "description": "The metadata key whose value this shows. Unique among this manifest's fields."
1233
+ },
1234
+ "name": {
1235
+ "ref": "localizedText",
1236
+ "description": "The field's label."
1237
+ },
1238
+ "kind": {
1239
+ "enum": "fieldKind",
1240
+ "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."
1241
+ },
1242
+ "on": {
1243
+ "type": "array",
1244
+ "minItems": 1,
1245
+ "maxItems": {
1246
+ "wholeOf": "itemKind"
1247
+ },
1248
+ "uniqueItems": true,
1249
+ "items": {
1250
+ "enum": "itemKind"
1251
+ },
1252
+ "description": "The item kinds it is offered on."
1253
+ },
1254
+ "description": {
1255
+ "ref": "localizedText",
1256
+ "description": "The one line the view editor's Add picker shows beside the name."
1257
+ },
1258
+ "tone": {
1259
+ "enum": "tone",
1260
+ "description": "A badge's tone when its value names none."
1261
+ },
1262
+ "requires": {
1263
+ "ref": "requires"
1264
+ }
1265
+ }
1266
+ },
1267
+ "partNode": {
1268
+ "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.",
1269
+ "oneOf": [
1270
+ {
1271
+ "ref": "sectionNode"
1272
+ },
1273
+ {
1274
+ "ref": "stackNode"
1275
+ },
1276
+ {
1277
+ "ref": "fieldNode"
1278
+ },
1279
+ {
1280
+ "ref": "valueNode"
1281
+ },
1282
+ {
1283
+ "ref": "textNode"
1284
+ },
1285
+ {
1286
+ "ref": "buttonNode"
1287
+ }
1288
+ ]
1289
+ },
1290
+ "sectionNode": {
1291
+ "type": "object",
1292
+ "description": "A titled group, which the reader may fold.",
1293
+ "required": [
1294
+ "type"
1295
+ ],
1296
+ "properties": {
1297
+ "type": {
1298
+ "const": "section"
1299
+ },
1300
+ "props": {
1301
+ "type": "object",
1302
+ "properties": {
1303
+ "title": {
1304
+ "ref": "localizedText"
1305
+ },
1306
+ "collapsed": {
1307
+ "type": "boolean",
1308
+ "default": false,
1309
+ "description": "Drawn folded until the reader opens it."
1310
+ }
1311
+ },
1312
+ "additionalProperties": false
1313
+ },
1314
+ "children": {
1315
+ "type": "array",
1316
+ "maxItems": "partNodes",
1317
+ "items": {
1318
+ "ref": "partNode"
1319
+ },
1320
+ "description": "Drawn in order, inside this one."
1321
+ }
1322
+ },
1323
+ "additionalProperties": false
1324
+ },
1325
+ "stackNode": {
1326
+ "type": "object",
1327
+ "description": "Nodes side by side or one above another.",
1328
+ "required": [
1329
+ "type"
1330
+ ],
1331
+ "properties": {
1332
+ "type": {
1333
+ "const": "stack"
1334
+ },
1335
+ "props": {
1336
+ "type": "object",
1337
+ "properties": {
1338
+ "direction": {
1339
+ "enum": [
1340
+ "row",
1341
+ "column"
1342
+ ],
1343
+ "default": "column"
1344
+ },
1345
+ "gap": {
1346
+ "enum": [
1347
+ "none",
1348
+ "small",
1349
+ "medium",
1350
+ "large"
1351
+ ],
1352
+ "description": "The space between the nodes. Absent: Initiative's own."
1353
+ },
1354
+ "wrap": {
1355
+ "type": "boolean",
1356
+ "default": false,
1357
+ "description": "A row runs onto a second line rather than past its edge."
1358
+ }
1359
+ },
1360
+ "additionalProperties": false
1361
+ },
1362
+ "children": {
1363
+ "type": "array",
1364
+ "maxItems": "partNodes",
1365
+ "items": {
1366
+ "ref": "partNode"
1367
+ },
1368
+ "description": "Drawn in order, inside this one."
1369
+ }
1370
+ },
1371
+ "additionalProperties": false
1372
+ },
1373
+ "fieldNode": {
1374
+ "type": "object",
1375
+ "description": "A field's label and its value.",
1376
+ "required": [
1377
+ "type",
1378
+ "props"
1379
+ ],
1380
+ "properties": {
1381
+ "type": {
1382
+ "const": "field"
1383
+ },
1384
+ "props": {
1385
+ "type": "object",
1386
+ "required": [
1387
+ "field"
1388
+ ],
1389
+ "properties": {
1390
+ "field": {
1391
+ "ref": "metadataKey",
1392
+ "description": "One of this manifest's fields, by its key, offered on every item kind the part is."
1393
+ }
1394
+ },
1395
+ "additionalProperties": false
1396
+ }
1397
+ },
1398
+ "additionalProperties": false
1399
+ },
1400
+ "valueNode": {
1401
+ "type": "object",
1402
+ "description": "A field's value alone.",
1403
+ "required": [
1404
+ "type",
1405
+ "props"
1406
+ ],
1407
+ "properties": {
1408
+ "type": {
1409
+ "const": "value"
1410
+ },
1411
+ "props": {
1412
+ "type": "object",
1413
+ "required": [
1414
+ "field"
1415
+ ],
1416
+ "properties": {
1417
+ "field": {
1418
+ "ref": "metadataKey",
1419
+ "description": "One of this manifest's fields, by its key, offered on every item kind the part is."
1420
+ }
1421
+ },
1422
+ "additionalProperties": false
1423
+ }
1424
+ },
1425
+ "additionalProperties": false
1426
+ },
1427
+ "textNode": {
1428
+ "type": "object",
1429
+ "description": "Words the plug-in wrote.",
1430
+ "required": [
1431
+ "type",
1432
+ "props"
1433
+ ],
1434
+ "properties": {
1435
+ "type": {
1436
+ "const": "text"
1437
+ },
1438
+ "props": {
1439
+ "type": "object",
1440
+ "required": [
1441
+ "text"
1442
+ ],
1443
+ "properties": {
1444
+ "text": {
1445
+ "ref": "localizedText"
1446
+ },
1447
+ "tone": {
1448
+ "enum": "tone"
1449
+ }
1450
+ },
1451
+ "additionalProperties": false
1452
+ }
1453
+ },
1454
+ "additionalProperties": false
1455
+ },
1456
+ "buttonNode": {
1457
+ "type": "object",
1458
+ "description": "A button that runs one of this plug-in's actions on the item, labelled with the action's name.",
1459
+ "required": [
1460
+ "type",
1461
+ "props"
1462
+ ],
1463
+ "properties": {
1464
+ "type": {
1465
+ "const": "button"
1466
+ },
1467
+ "props": {
1468
+ "type": "object",
1469
+ "required": [
1470
+ "action"
1471
+ ],
1472
+ "properties": {
1473
+ "action": {
1474
+ "ref": "identifier",
1475
+ "description": "One of this manifest's actions, by its id, offered on every item kind the part is."
1476
+ },
1477
+ "variant": {
1478
+ "enum": [
1479
+ "primary",
1480
+ "secondary",
1481
+ "ghost"
1482
+ ]
1483
+ }
1484
+ },
1485
+ "additionalProperties": false
1486
+ }
1487
+ },
1488
+ "additionalProperties": false
1489
+ },
1490
+ "part": {
1491
+ "type": "object",
1492
+ "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 {partsPlacedPerItem} of a plug-in's parts on one item.",
1493
+ "required": [
1494
+ "id",
1495
+ "name",
1496
+ "on",
1497
+ "tree"
1498
+ ],
1499
+ "properties": {
1500
+ "id": {
1501
+ "ref": "identifier",
1502
+ "description": "Unique among this manifest's parts."
1503
+ },
1504
+ "name": {
1505
+ "ref": "localizedText",
1506
+ "description": "What the view editor calls it."
1507
+ },
1508
+ "on": {
1509
+ "type": "array",
1510
+ "minItems": 1,
1511
+ "maxItems": {
1512
+ "wholeOf": "itemKind"
1513
+ },
1514
+ "uniqueItems": true,
1515
+ "items": {
1516
+ "enum": "itemKind"
1517
+ },
1518
+ "description": "The item kinds it is offered on."
1519
+ },
1520
+ "tree": {
1521
+ "ref": "partNode",
1522
+ "description": "What is drawn: at most {partNodes} nodes, at most {partDepth} deep."
1523
+ },
1524
+ "description": {
1525
+ "ref": "localizedText",
1526
+ "description": "The one line the view editor's Add picker shows beside the name."
1527
+ },
1528
+ "requires": {
1529
+ "ref": "requires"
1530
+ }
1531
+ }
1532
+ },
1533
+ "action": {
1534
+ "type": "object",
1535
+ "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.",
1536
+ "required": [
1537
+ "id",
1538
+ "name",
1539
+ "endpoint",
1540
+ "on"
1541
+ ],
1542
+ "properties": {
1543
+ "id": {
1544
+ "ref": "identifier",
1545
+ "description": "Unique among this manifest's actions."
1546
+ },
1547
+ "name": {
1548
+ "ref": "localizedText",
1549
+ "description": "The button's or the menu entry's label."
1550
+ },
1551
+ "endpoint": {
1552
+ "ref": "namespacedId",
1553
+ "description": "A write endpoint this manifest declares."
1554
+ },
1555
+ "on": {
1556
+ "type": "array",
1557
+ "minItems": 1,
1558
+ "maxItems": {
1559
+ "wholeOf": "itemKind"
1560
+ },
1561
+ "uniqueItems": true,
1562
+ "items": {
1563
+ "enum": "itemKind"
1564
+ },
1565
+ "description": "The item kinds it is offered on."
1566
+ },
1567
+ "confirm": {
1568
+ "ref": "localizedText",
1569
+ "description": "A question Initiative asks before running it. Absent: it runs at once."
1570
+ },
1571
+ "menu": {
1572
+ "type": "boolean",
1573
+ "default": false,
1574
+ "description": "Also offered in the item's own menu."
1575
+ },
1576
+ "requires": {
1577
+ "ref": "requires"
1578
+ }
1579
+ }
1580
+ },
1169
1581
  "bundledDashboard": {
1170
1582
  "type": "object",
1171
1583
  "required": [
@@ -1908,6 +2320,30 @@
1908
2320
  "ref": "bundledDashboard"
1909
2321
  },
1910
2322
  "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."
2323
+ },
2324
+ "fields": {
2325
+ "type": "array",
2326
+ "maxItems": "fields",
2327
+ "items": {
2328
+ "ref": "field"
2329
+ },
2330
+ "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."
2331
+ },
2332
+ "parts": {
2333
+ "type": "array",
2334
+ "maxItems": "parts",
2335
+ "items": {
2336
+ "ref": "part"
2337
+ },
2338
+ "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."
2339
+ },
2340
+ "actions": {
2341
+ "type": "array",
2342
+ "maxItems": "actions",
2343
+ "items": {
2344
+ "ref": "action"
2345
+ },
2346
+ "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."
1911
2347
  }
1912
2348
  }
1913
2349
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "initiative-plugin-sdk",
3
- "version": "5.0.0",
3
+ "version": "6.0.0",
4
4
  "description": "Build a plug-in for Initiative: one typed definition of its endpoints, hooks, schedules, widgets and listing, the server Initiative calls, the client it calls Initiative with, the CLI that builds its manifest, and declarative integrations Initiative runs from the manifest alone.",
5
5
  "license": "MIT",
6
6
  "type": "module",
@@ -41,6 +41,18 @@
41
41
  "types": "./dist/widget.d.ts",
42
42
  "default": "./dist/widget.js"
43
43
  },
44
+ "./parts": {
45
+ "types": "./dist/parts.d.ts",
46
+ "default": "./dist/parts.js"
47
+ },
48
+ "./jsx-runtime": {
49
+ "types": "./dist/jsx-runtime.d.ts",
50
+ "default": "./dist/jsx-runtime.js"
51
+ },
52
+ "./jsx-dev-runtime": {
53
+ "types": "./dist/jsx-dev-runtime.d.ts",
54
+ "default": "./dist/jsx-dev-runtime.js"
55
+ },
44
56
  "./testing": {
45
57
  "types": "./dist/testing.d.ts",
46
58
  "default": "./dist/testing.js"
@@ -85,9 +97,9 @@
85
97
  }
86
98
  },
87
99
  "devDependencies": {
88
- "@types/node": "^26.6.3",
100
+ "@types/node": "^26.6.4",
89
101
  "esbuild": "^0.28.2",
90
102
  "typescript": "^7.0.2",
91
- "vitest": "^5.0.2"
103
+ "vitest": "^5.0.3"
92
104
  }
93
105
  }
@@ -2,10 +2,10 @@
2
2
  "openapi": "3.1.0",
3
3
  "info": {
4
4
  "title": "Initiative plug-in API",
5
- "version": "5.0.0",
5
+ "version": "6.0.0",
6
6
  "x-initiative-source": {
7
- "version": "0.74.0",
8
- "commit": "0492f28bb7e586091a62a58dcc1bc768d0544416"
7
+ "version": "0.75.3",
8
+ "commit": "b7992004243ed01bf3e971481b11561e1fb7ab58"
9
9
  }
10
10
  },
11
11
  "servers": [
@@ -16456,22 +16456,6 @@
16456
16456
  ],
16457
16457
  "title": "Pinned At"
16458
16458
  },
16459
- "default_view_mode": {
16460
- "anyOf": [
16461
- {
16462
- "type": "string",
16463
- "enum": [
16464
- "table",
16465
- "kanban",
16466
- "calendar"
16467
- ]
16468
- },
16469
- {
16470
- "type": "null"
16471
- }
16472
- ],
16473
- "title": "Default View Mode"
16474
- },
16475
16459
  "owner": {
16476
16460
  "anyOf": [
16477
16461
  {
@@ -16552,7 +16536,6 @@
16552
16536
  "owner_id",
16553
16537
  "is_template",
16554
16538
  "pinned_at",
16555
- "default_view_mode",
16556
16539
  "owner",
16557
16540
  "owner_plugin",
16558
16541
  "initiative",
@@ -16643,22 +16626,6 @@
16643
16626
  ],
16644
16627
  "title": "Pinned"
16645
16628
  },
16646
- "default_view_mode": {
16647
- "anyOf": [
16648
- {
16649
- "type": "string",
16650
- "enum": [
16651
- "table",
16652
- "kanban",
16653
- "calendar"
16654
- ]
16655
- },
16656
- {
16657
- "type": "null"
16658
- }
16659
- ],
16660
- "title": "Default View Mode"
16661
- },
16662
16629
  "start_date": {
16663
16630
  "anyOf": [
16664
16631
  {