@echelon-foundry/design-system 0.3.0 → 0.4.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.
Files changed (73) hide show
  1. package/README.md +29 -0
  2. package/contracts/diagram-presentation.json +109 -0
  3. package/contracts/workflow-capabilities.json +25 -0
  4. package/dist/all.css +175 -3
  5. package/dist/build-metrics.json +32 -4
  6. package/dist/components.css +173 -3
  7. package/dist/foundations.css +2 -0
  8. package/dist/marketing/forma-all.css +176 -4
  9. package/dist/marketing/forma-echelon-marketing.css +3 -1
  10. package/dist/marketing/forma-marketing-theme-echelon.css +1 -1
  11. package/dist/marketing/forma-marketing.css +3 -1
  12. package/dist/marketing/forma-marketing.manifest.json +9 -9
  13. package/dist/marketing/forma-marketing.sha256 +4 -4
  14. package/dist/patterns/bounded-overflow.html +9 -0
  15. package/dist/patterns/button.html +5 -0
  16. package/dist/patterns/container.html +6 -0
  17. package/dist/patterns/date-time-field.html +5 -0
  18. package/dist/patterns/grid.html +5 -0
  19. package/dist/patterns/image-choice.html +2 -2
  20. package/dist/patterns/key-value-list.html +5 -0
  21. package/dist/patterns/section.html +4 -0
  22. package/dist/patterns/skip-link.html +6 -0
  23. package/dist/patterns/split.html +12 -0
  24. package/dist/patterns/surface.html +4 -0
  25. package/dist/patterns/text-field.html +5 -0
  26. package/dist/patterns/text-roles.html +7 -0
  27. package/dist/patterns/textarea.html +5 -0
  28. package/dist/patterns/visually-hidden.html +4 -0
  29. package/docs/MARKETING-SITES.md +1 -1
  30. package/docs/workflow/EMBEDDING.md +148 -0
  31. package/docs/workflow/EXTERNAL-PRODUCERS.md +34 -0
  32. package/docs/workflow/FORMAT.md +196 -0
  33. package/docs/workflow/RENDERING.md +90 -0
  34. package/docs/workflow/REQUIREMENTS-AUDIT-2026-10-01.md +55 -0
  35. package/docs/workflow/VALIDATION.md +91 -0
  36. package/examples/workflows/fixtures.json +101 -0
  37. package/examples/workflows/forma/workflows/accessible.forma-workflow.json +90 -0
  38. package/examples/workflows/forma/workflows/branching.forma-workflow.json +91 -0
  39. package/examples/workflows/forma/workflows/branded.forma-workflow.json +85 -0
  40. package/examples/workflows/forma/workflows/color-mapping.forma-workflow.json +111 -0
  41. package/examples/workflows/forma/workflows/colored.forma-workflow.json +131 -0
  42. package/examples/workflows/forma/workflows/edge-metadata.forma-workflow.json +66 -0
  43. package/examples/workflows/forma/workflows/embedded-edit.forma-workflow.json +117 -0
  44. package/examples/workflows/forma/workflows/embedded-view.forma-workflow.json +93 -0
  45. package/examples/workflows/forma/workflows/extensions.forma-workflow.json +90 -0
  46. package/examples/workflows/forma/workflows/groups.forma-workflow.json +89 -0
  47. package/examples/workflows/forma/workflows/interactive-export.forma-workflow.json +62 -0
  48. package/examples/workflows/forma/workflows/minimal.forma-workflow.json +17 -0
  49. package/examples/workflows/forma/workflows/mobile.forma-workflow.json +80 -0
  50. package/examples/workflows/forma/workflows/multi-step.forma-workflow.json +82 -0
  51. package/examples/workflows/forma/workflows/no-layout.forma-workflow.json +90 -0
  52. package/examples/workflows/forma/workflows/node-metadata.forma-workflow.json +80 -0
  53. package/examples/workflows/forma/workflows/runtime-ports.forma-workflow.json +118 -0
  54. package/examples/workflows/forma/workflows/static-export.forma-workflow.json +77 -0
  55. package/examples/workflows/forma/workflows/swimlanes.forma-workflow.json +130 -0
  56. package/figma/component-contracts.json +140 -0
  57. package/package.json +28 -9
  58. package/patterns/bounded-overflow.html +9 -0
  59. package/patterns/button.html +5 -0
  60. package/patterns/container.html +6 -0
  61. package/patterns/date-time-field.html +5 -0
  62. package/patterns/grid.html +5 -0
  63. package/patterns/image-choice.html +2 -2
  64. package/patterns/key-value-list.html +5 -0
  65. package/patterns/section.html +4 -0
  66. package/patterns/skip-link.html +6 -0
  67. package/patterns/split.html +12 -0
  68. package/patterns/surface.html +4 -0
  69. package/patterns/text-field.html +5 -0
  70. package/patterns/text-roles.html +7 -0
  71. package/patterns/textarea.html +5 -0
  72. package/patterns/visually-hidden.html +4 -0
  73. package/schemas/workflow/1.0/forma-workflow.schema.json +1045 -0
@@ -0,0 +1,1045 @@
1
+ {
2
+ "$schema": "https://json-schema.org/draft/2020-12/schema",
3
+ "$id": "https://forma.echelonfoundry.com/schemas/workflow/1.0/forma-workflow.schema.json",
4
+ "title": "Forma portable workflow",
5
+ "description": "Normative structure of a .forma-workflow.json document, format version 1.0. Semantic rules that a schema cannot express (references, ports, membership, compatibility, static accessibility) are defined in docs/workflow/FORMAT.md and enforced by Forma.Workflow validation.",
6
+ "type": "object",
7
+ "required": [
8
+ "format",
9
+ "formatVersion",
10
+ "id",
11
+ "title",
12
+ "forma",
13
+ "nodes"
14
+ ],
15
+ "additionalProperties": false,
16
+ "properties": {
17
+ "$schema": {
18
+ "type": "string",
19
+ "maxLength": 2048
20
+ },
21
+ "format": {
22
+ "const": "forma-workflow"
23
+ },
24
+ "formatVersion": {
25
+ "$ref": "#/$defs/semver"
26
+ },
27
+ "id": {
28
+ "description": "Stable workflow identifier. It is also the file stem: forma/workflows/<id>.forma-workflow.json.",
29
+ "type": "string",
30
+ "pattern": "^[a-z0-9](?:[a-z0-9-]{0,126}[a-z0-9])?$"
31
+ },
32
+ "title": {
33
+ "$ref": "#/$defs/text"
34
+ },
35
+ "description": {
36
+ "$ref": "#/$defs/longText"
37
+ },
38
+ "language": {
39
+ "description": "BCP 47 language tag of the human-readable text.",
40
+ "type": "string",
41
+ "pattern": "^[A-Za-z]{2,8}(?:-[A-Za-z0-9]{1,8})*$"
42
+ },
43
+ "direction": {
44
+ "description": "Base text direction of the human-readable text.",
45
+ "enum": [
46
+ "ltr",
47
+ "rtl",
48
+ "auto"
49
+ ]
50
+ },
51
+ "forma": {
52
+ "$ref": "#/$defs/formaTarget"
53
+ },
54
+ "metadata": {
55
+ "$ref": "#/$defs/metadata"
56
+ },
57
+ "palette": {
58
+ "description": "Named colour slots. Objects refer to them as palette:<slot>. A slot holds a Forma token or a literal colour, so a brand can re-resolve token slots without rewriting objects.",
59
+ "type": "object",
60
+ "maxProperties": 256,
61
+ "propertyNames": {
62
+ "pattern": "^[a-z][a-z0-9-]{0,63}$"
63
+ },
64
+ "additionalProperties": {
65
+ "$ref": "#/$defs/colorSource"
66
+ }
67
+ },
68
+ "nodes": {
69
+ "type": "array",
70
+ "maxItems": 10000,
71
+ "items": {
72
+ "$ref": "#/$defs/node"
73
+ }
74
+ },
75
+ "edges": {
76
+ "type": "array",
77
+ "maxItems": 20000,
78
+ "items": {
79
+ "$ref": "#/$defs/edge"
80
+ }
81
+ },
82
+ "groups": {
83
+ "type": "array",
84
+ "maxItems": 2000,
85
+ "items": {
86
+ "$ref": "#/$defs/group"
87
+ }
88
+ },
89
+ "layout": {
90
+ "$ref": "#/$defs/workflowLayout"
91
+ },
92
+ "presentation": {
93
+ "$ref": "#/$defs/presentation"
94
+ },
95
+ "extensions": {
96
+ "$ref": "#/$defs/extensions"
97
+ },
98
+ "provenance": {
99
+ "$ref": "#/$defs/provenance"
100
+ }
101
+ },
102
+ "$defs": {
103
+ "semver": {
104
+ "type": "string",
105
+ "pattern": "^(0|[1-9][0-9]{0,8})\\.(0|[1-9][0-9]{0,8})\\.(0|[1-9][0-9]{0,8})(?:-[0-9A-Za-z.-]{1,64})?$"
106
+ },
107
+ "id": {
108
+ "description": "Stable object identifier. Unique across nodes, edges and groups of one workflow; never an array position or DOM identity.",
109
+ "type": "string",
110
+ "pattern": "^[A-Za-z0-9][A-Za-z0-9_.:-]{0,127}$"
111
+ },
112
+ "localId": {
113
+ "description": "Identifier unique within its owner (a port within its node, a reference within its object).",
114
+ "type": "string",
115
+ "pattern": "^[A-Za-z0-9][A-Za-z0-9_.:-]{0,127}$"
116
+ },
117
+ "text": {
118
+ "type": "string",
119
+ "minLength": 1,
120
+ "maxLength": 1000
121
+ },
122
+ "longText": {
123
+ "type": "string",
124
+ "maxLength": 20000
125
+ },
126
+ "namespace": {
127
+ "description": "Reverse-DNS style namespace, for example com.example.erp. The forma prefix is reserved for Forma.",
128
+ "type": "string",
129
+ "pattern": "^[a-z][a-z0-9-]*(?:\\.[a-z][a-z0-9-]*)+$",
130
+ "maxLength": 128
131
+ },
132
+ "nodeKind": {
133
+ "description": "Core kind, or a namespaced producer kind <namespace>:<name> (which then needs kindLabel).",
134
+ "type": "string",
135
+ "anyOf": [
136
+ {
137
+ "enum": [
138
+ "start",
139
+ "end",
140
+ "task",
141
+ "decision",
142
+ "merge",
143
+ "event",
144
+ "subprocess",
145
+ "data",
146
+ "note",
147
+ "external"
148
+ ]
149
+ },
150
+ {
151
+ "pattern": "^[a-z][a-z0-9-]*(?:\\.[a-z][a-z0-9-]*)+:[a-z][a-z0-9-]{0,63}$"
152
+ }
153
+ ]
154
+ },
155
+ "edgeKind": {
156
+ "type": "string",
157
+ "anyOf": [
158
+ {
159
+ "enum": [
160
+ "sequence",
161
+ "conditional",
162
+ "default",
163
+ "exception",
164
+ "message",
165
+ "association",
166
+ "data"
167
+ ]
168
+ },
169
+ {
170
+ "pattern": "^[a-z][a-z0-9-]*(?:\\.[a-z][a-z0-9-]*)+:[a-z][a-z0-9-]{0,63}$"
171
+ }
172
+ ]
173
+ },
174
+ "groupKind": {
175
+ "enum": [
176
+ "group",
177
+ "container",
178
+ "swimlane",
179
+ "phase"
180
+ ]
181
+ },
182
+ "state": {
183
+ "type": "string",
184
+ "anyOf": [
185
+ {
186
+ "enum": [
187
+ "none",
188
+ "pending",
189
+ "ready",
190
+ "active",
191
+ "waiting",
192
+ "complete",
193
+ "blocked",
194
+ "failed",
195
+ "skipped",
196
+ "cancelled",
197
+ "unknown"
198
+ ]
199
+ },
200
+ {
201
+ "pattern": "^[a-z][a-z0-9-]*(?:\\.[a-z][a-z0-9-]*)+:[a-z][a-z0-9-]{0,63}$"
202
+ }
203
+ ]
204
+ },
205
+ "status": {
206
+ "description": "Semantic state. The text label is what people read; colour never carries it alone.",
207
+ "type": "object",
208
+ "required": [
209
+ "state"
210
+ ],
211
+ "additionalProperties": false,
212
+ "properties": {
213
+ "state": {
214
+ "$ref": "#/$defs/state"
215
+ },
216
+ "label": {
217
+ "$ref": "#/$defs/text"
218
+ },
219
+ "detail": {
220
+ "$ref": "#/$defs/longText"
221
+ },
222
+ "updatedAt": {
223
+ "type": "string",
224
+ "maxLength": 64
225
+ }
226
+ },
227
+ "allOf": [
228
+ {
229
+ "description": "A namespaced state carries its own human-readable label.",
230
+ "if": {
231
+ "properties": {
232
+ "state": {
233
+ "pattern": ":"
234
+ }
235
+ }
236
+ },
237
+ "then": {
238
+ "required": [
239
+ "label"
240
+ ]
241
+ }
242
+ }
243
+ ]
244
+ },
245
+ "colorSource": {
246
+ "description": "A Forma colour token (token:<name>) or a lowercase six-digit hex literal.",
247
+ "type": "string",
248
+ "anyOf": [
249
+ {
250
+ "pattern": "^#[0-9a-f]{6}$"
251
+ },
252
+ {
253
+ "enum": [
254
+ "token:accent-primary",
255
+ "token:accent-secondary",
256
+ "token:border-functional",
257
+ "token:border-subtle",
258
+ "token:surface-primary",
259
+ "token:surface-secondary",
260
+ "token:surface-inverse",
261
+ "token:text-primary",
262
+ "token:text-secondary"
263
+ ]
264
+ }
265
+ ]
266
+ },
267
+ "colorValue": {
268
+ "type": "string",
269
+ "anyOf": [
270
+ {
271
+ "$ref": "#/$defs/colorSource"
272
+ },
273
+ {
274
+ "pattern": "^palette:[a-z][a-z0-9-]{0,63}$"
275
+ }
276
+ ]
277
+ },
278
+ "objectColor": {
279
+ "description": "Authored appearance. Separate from kind and status (FMD-COLOR-009).",
280
+ "type": "object",
281
+ "additionalProperties": false,
282
+ "properties": {
283
+ "fill": {
284
+ "$ref": "#/$defs/colorValue"
285
+ },
286
+ "stroke": {
287
+ "$ref": "#/$defs/colorValue"
288
+ },
289
+ "accent": {
290
+ "$ref": "#/$defs/colorValue"
291
+ },
292
+ "foreground": {
293
+ "$ref": "#/$defs/colorValue"
294
+ }
295
+ }
296
+ },
297
+ "edgeColor": {
298
+ "type": "object",
299
+ "additionalProperties": false,
300
+ "properties": {
301
+ "stroke": {
302
+ "$ref": "#/$defs/colorValue"
303
+ }
304
+ }
305
+ },
306
+ "metadata": {
307
+ "description": "Arbitrary application metadata. Forma preserves it unchanged and never interprets it.",
308
+ "type": "object",
309
+ "maxProperties": 1000
310
+ },
311
+ "extensions": {
312
+ "description": "Producer-specific data keyed by namespace. Each value is an object. Unknown extensions round-trip unchanged.",
313
+ "type": "object",
314
+ "maxProperties": 64,
315
+ "propertyNames": {
316
+ "$ref": "#/$defs/namespace"
317
+ },
318
+ "additionalProperties": {
319
+ "type": "object"
320
+ }
321
+ },
322
+ "accessibility": {
323
+ "type": "object",
324
+ "additionalProperties": false,
325
+ "properties": {
326
+ "name": {
327
+ "$ref": "#/$defs/text"
328
+ },
329
+ "description": {
330
+ "$ref": "#/$defs/longText"
331
+ }
332
+ }
333
+ },
334
+ "uri": {
335
+ "description": "http, https or mailto URL, or a relative reference. Script and data URLs are rejected by validation.",
336
+ "type": "string",
337
+ "minLength": 1,
338
+ "maxLength": 4096
339
+ },
340
+ "reference": {
341
+ "description": "A typed pointer to a host or domain object. Forma displays it; it never dereferences it.",
342
+ "type": "object",
343
+ "required": [
344
+ "id",
345
+ "system",
346
+ "key"
347
+ ],
348
+ "additionalProperties": false,
349
+ "properties": {
350
+ "id": {
351
+ "$ref": "#/$defs/localId"
352
+ },
353
+ "system": {
354
+ "$ref": "#/$defs/namespace"
355
+ },
356
+ "type": {
357
+ "type": "string",
358
+ "minLength": 1,
359
+ "maxLength": 128
360
+ },
361
+ "key": {
362
+ "type": "string",
363
+ "minLength": 1,
364
+ "maxLength": 1000
365
+ },
366
+ "label": {
367
+ "$ref": "#/$defs/text"
368
+ },
369
+ "href": {
370
+ "$ref": "#/$defs/uri"
371
+ },
372
+ "metadata": {
373
+ "$ref": "#/$defs/metadata"
374
+ }
375
+ }
376
+ },
377
+ "references": {
378
+ "type": "array",
379
+ "maxItems": 256,
380
+ "items": {
381
+ "$ref": "#/$defs/reference"
382
+ }
383
+ },
384
+ "interactionTarget": {
385
+ "description": "Exactly one destination.",
386
+ "type": "object",
387
+ "minProperties": 1,
388
+ "maxProperties": 1,
389
+ "additionalProperties": false,
390
+ "properties": {
391
+ "workflow": {
392
+ "type": "string",
393
+ "pattern": "^[a-z0-9](?:[a-z0-9-]{0,126}[a-z0-9])?$"
394
+ },
395
+ "node": {
396
+ "$ref": "#/$defs/id"
397
+ },
398
+ "edge": {
399
+ "$ref": "#/$defs/id"
400
+ },
401
+ "group": {
402
+ "$ref": "#/$defs/id"
403
+ },
404
+ "reference": {
405
+ "$ref": "#/$defs/localId"
406
+ },
407
+ "url": {
408
+ "$ref": "#/$defs/uri"
409
+ }
410
+ }
411
+ },
412
+ "interaction": {
413
+ "description": "A declarative intent. The host decides what it does; nothing in a workflow executes.",
414
+ "type": "object",
415
+ "required": [
416
+ "action"
417
+ ],
418
+ "additionalProperties": false,
419
+ "properties": {
420
+ "action": {
421
+ "enum": [
422
+ "none",
423
+ "select",
424
+ "inspect",
425
+ "navigate",
426
+ "open",
427
+ "command"
428
+ ]
429
+ },
430
+ "target": {
431
+ "$ref": "#/$defs/interactionTarget"
432
+ },
433
+ "command": {
434
+ "type": "string",
435
+ "pattern": "^[a-z][a-z0-9-]*(?:\\.[a-z][a-z0-9-]*)+:[a-z][a-z0-9-]{0,63}$"
436
+ },
437
+ "label": {
438
+ "$ref": "#/$defs/text"
439
+ },
440
+ "parameters": {
441
+ "type": "object",
442
+ "maxProperties": 64
443
+ }
444
+ },
445
+ "allOf": [
446
+ {
447
+ "description": "navigate and open need a destination.",
448
+ "if": {
449
+ "properties": {
450
+ "action": {
451
+ "enum": [
452
+ "navigate",
453
+ "open"
454
+ ]
455
+ }
456
+ }
457
+ },
458
+ "then": {
459
+ "required": [
460
+ "target"
461
+ ]
462
+ }
463
+ },
464
+ {
465
+ "description": "A command names the host command and the text people see.",
466
+ "if": {
467
+ "properties": {
468
+ "action": {
469
+ "const": "command"
470
+ }
471
+ }
472
+ },
473
+ "then": {
474
+ "required": [
475
+ "command",
476
+ "label"
477
+ ]
478
+ }
479
+ }
480
+ ]
481
+ },
482
+ "port": {
483
+ "type": "object",
484
+ "required": [
485
+ "id"
486
+ ],
487
+ "additionalProperties": false,
488
+ "properties": {
489
+ "id": {
490
+ "$ref": "#/$defs/localId"
491
+ },
492
+ "side": {
493
+ "enum": [
494
+ "top",
495
+ "right",
496
+ "bottom",
497
+ "left"
498
+ ]
499
+ },
500
+ "direction": {
501
+ "enum": [
502
+ "in",
503
+ "out",
504
+ "inout"
505
+ ]
506
+ },
507
+ "label": {
508
+ "$ref": "#/$defs/text"
509
+ },
510
+ "maxConnections": {
511
+ "type": "integer",
512
+ "minimum": 1,
513
+ "maximum": 10000
514
+ },
515
+ "metadata": {
516
+ "$ref": "#/$defs/metadata"
517
+ },
518
+ "extensions": {
519
+ "$ref": "#/$defs/extensions"
520
+ }
521
+ }
522
+ },
523
+ "coordinate": {
524
+ "type": "number",
525
+ "minimum": -1000000,
526
+ "maximum": 1000000
527
+ },
528
+ "extent": {
529
+ "type": "number",
530
+ "exclusiveMinimum": 0,
531
+ "maximum": 1000000
532
+ },
533
+ "point": {
534
+ "type": "object",
535
+ "required": [
536
+ "x",
537
+ "y"
538
+ ],
539
+ "additionalProperties": false,
540
+ "properties": {
541
+ "x": {
542
+ "$ref": "#/$defs/coordinate"
543
+ },
544
+ "y": {
545
+ "$ref": "#/$defs/coordinate"
546
+ }
547
+ }
548
+ },
549
+ "boxLayout": {
550
+ "description": "Optional presentation geometry in logical canvas units, plus layout intent. Removing every layout object never changes meaning.",
551
+ "type": "object",
552
+ "additionalProperties": false,
553
+ "dependentRequired": {
554
+ "x": [
555
+ "y"
556
+ ],
557
+ "y": [
558
+ "x"
559
+ ]
560
+ },
561
+ "properties": {
562
+ "x": {
563
+ "$ref": "#/$defs/coordinate"
564
+ },
565
+ "y": {
566
+ "$ref": "#/$defs/coordinate"
567
+ },
568
+ "width": {
569
+ "$ref": "#/$defs/extent"
570
+ },
571
+ "height": {
572
+ "$ref": "#/$defs/extent"
573
+ },
574
+ "rank": {
575
+ "description": "Requested layer in the default layout.",
576
+ "type": "integer",
577
+ "minimum": 0,
578
+ "maximum": 10000
579
+ },
580
+ "order": {
581
+ "description": "Requested order within a layer or lane.",
582
+ "type": "integer",
583
+ "minimum": 0,
584
+ "maximum": 100000
585
+ },
586
+ "size": {
587
+ "enum": [
588
+ "compact",
589
+ "standard",
590
+ "wide"
591
+ ]
592
+ }
593
+ }
594
+ },
595
+ "edgeLayout": {
596
+ "type": "object",
597
+ "additionalProperties": false,
598
+ "properties": {
599
+ "routing": {
600
+ "enum": [
601
+ "straight",
602
+ "orthogonal"
603
+ ]
604
+ },
605
+ "waypoints": {
606
+ "type": "array",
607
+ "maxItems": 64,
608
+ "items": {
609
+ "$ref": "#/$defs/point"
610
+ }
611
+ },
612
+ "label": {
613
+ "$ref": "#/$defs/point"
614
+ }
615
+ }
616
+ },
617
+ "endpoint": {
618
+ "type": "object",
619
+ "required": [
620
+ "node"
621
+ ],
622
+ "additionalProperties": false,
623
+ "properties": {
624
+ "node": {
625
+ "$ref": "#/$defs/id"
626
+ },
627
+ "port": {
628
+ "$ref": "#/$defs/localId"
629
+ }
630
+ }
631
+ },
632
+ "node": {
633
+ "type": "object",
634
+ "required": [
635
+ "id",
636
+ "kind",
637
+ "label"
638
+ ],
639
+ "additionalProperties": false,
640
+ "properties": {
641
+ "id": {
642
+ "$ref": "#/$defs/id"
643
+ },
644
+ "kind": {
645
+ "$ref": "#/$defs/nodeKind"
646
+ },
647
+ "kindLabel": {
648
+ "$ref": "#/$defs/text"
649
+ },
650
+ "label": {
651
+ "$ref": "#/$defs/text"
652
+ },
653
+ "description": {
654
+ "$ref": "#/$defs/longText"
655
+ },
656
+ "variant": {
657
+ "description": "Forma shape. Presentation only; it never implies kind.",
658
+ "enum": [
659
+ "rectangle",
660
+ "rounded",
661
+ "pill",
662
+ "ellipse",
663
+ "diamond"
664
+ ]
665
+ },
666
+ "color": {
667
+ "$ref": "#/$defs/objectColor"
668
+ },
669
+ "status": {
670
+ "$ref": "#/$defs/status"
671
+ },
672
+ "ports": {
673
+ "type": "array",
674
+ "maxItems": 64,
675
+ "items": {
676
+ "$ref": "#/$defs/port"
677
+ }
678
+ },
679
+ "references": {
680
+ "$ref": "#/$defs/references"
681
+ },
682
+ "metadata": {
683
+ "$ref": "#/$defs/metadata"
684
+ },
685
+ "accessibility": {
686
+ "$ref": "#/$defs/accessibility"
687
+ },
688
+ "interaction": {
689
+ "$ref": "#/$defs/interaction"
690
+ },
691
+ "layout": {
692
+ "$ref": "#/$defs/boxLayout"
693
+ },
694
+ "extensions": {
695
+ "$ref": "#/$defs/extensions"
696
+ }
697
+ },
698
+ "allOf": [
699
+ {
700
+ "description": "A namespaced producer kind carries its own human-readable kindLabel.",
701
+ "if": {
702
+ "required": [
703
+ "kind"
704
+ ],
705
+ "properties": {
706
+ "kind": {
707
+ "pattern": ":"
708
+ }
709
+ }
710
+ },
711
+ "then": {
712
+ "required": [
713
+ "kindLabel"
714
+ ]
715
+ }
716
+ }
717
+ ]
718
+ },
719
+ "edge": {
720
+ "type": "object",
721
+ "required": [
722
+ "id",
723
+ "source",
724
+ "target"
725
+ ],
726
+ "additionalProperties": false,
727
+ "properties": {
728
+ "id": {
729
+ "$ref": "#/$defs/id"
730
+ },
731
+ "source": {
732
+ "$ref": "#/$defs/endpoint"
733
+ },
734
+ "target": {
735
+ "$ref": "#/$defs/endpoint"
736
+ },
737
+ "direction": {
738
+ "description": "forward (default): source to target.",
739
+ "enum": [
740
+ "forward",
741
+ "backward",
742
+ "both",
743
+ "none"
744
+ ]
745
+ },
746
+ "kind": {
747
+ "$ref": "#/$defs/edgeKind"
748
+ },
749
+ "kindLabel": {
750
+ "$ref": "#/$defs/text"
751
+ },
752
+ "label": {
753
+ "$ref": "#/$defs/text"
754
+ },
755
+ "description": {
756
+ "$ref": "#/$defs/longText"
757
+ },
758
+ "line": {
759
+ "enum": [
760
+ "solid",
761
+ "dashed",
762
+ "dotted"
763
+ ]
764
+ },
765
+ "width": {
766
+ "type": "integer",
767
+ "minimum": 1,
768
+ "maximum": 8
769
+ },
770
+ "color": {
771
+ "$ref": "#/$defs/edgeColor"
772
+ },
773
+ "status": {
774
+ "$ref": "#/$defs/status"
775
+ },
776
+ "references": {
777
+ "$ref": "#/$defs/references"
778
+ },
779
+ "metadata": {
780
+ "$ref": "#/$defs/metadata"
781
+ },
782
+ "accessibility": {
783
+ "$ref": "#/$defs/accessibility"
784
+ },
785
+ "interaction": {
786
+ "$ref": "#/$defs/interaction"
787
+ },
788
+ "layout": {
789
+ "$ref": "#/$defs/edgeLayout"
790
+ },
791
+ "extensions": {
792
+ "$ref": "#/$defs/extensions"
793
+ }
794
+ },
795
+ "allOf": [
796
+ {
797
+ "description": "A namespaced producer kind carries its own human-readable kindLabel.",
798
+ "if": {
799
+ "required": [
800
+ "kind"
801
+ ],
802
+ "properties": {
803
+ "kind": {
804
+ "pattern": ":"
805
+ }
806
+ }
807
+ },
808
+ "then": {
809
+ "required": [
810
+ "kindLabel"
811
+ ]
812
+ }
813
+ }
814
+ ]
815
+ },
816
+ "group": {
817
+ "type": "object",
818
+ "required": [
819
+ "id",
820
+ "kind",
821
+ "label"
822
+ ],
823
+ "additionalProperties": false,
824
+ "properties": {
825
+ "id": {
826
+ "$ref": "#/$defs/id"
827
+ },
828
+ "kind": {
829
+ "$ref": "#/$defs/groupKind"
830
+ },
831
+ "label": {
832
+ "$ref": "#/$defs/text"
833
+ },
834
+ "description": {
835
+ "$ref": "#/$defs/longText"
836
+ },
837
+ "members": {
838
+ "description": "Node identifiers. Canvas overlap never implies membership.",
839
+ "type": "array",
840
+ "maxItems": 10000,
841
+ "uniqueItems": true,
842
+ "items": {
843
+ "$ref": "#/$defs/id"
844
+ }
845
+ },
846
+ "parent": {
847
+ "$ref": "#/$defs/id"
848
+ },
849
+ "line": {
850
+ "enum": [
851
+ "solid",
852
+ "dashed",
853
+ "dotted"
854
+ ]
855
+ },
856
+ "color": {
857
+ "$ref": "#/$defs/objectColor"
858
+ },
859
+ "status": {
860
+ "$ref": "#/$defs/status"
861
+ },
862
+ "references": {
863
+ "$ref": "#/$defs/references"
864
+ },
865
+ "metadata": {
866
+ "$ref": "#/$defs/metadata"
867
+ },
868
+ "accessibility": {
869
+ "$ref": "#/$defs/accessibility"
870
+ },
871
+ "interaction": {
872
+ "$ref": "#/$defs/interaction"
873
+ },
874
+ "layout": {
875
+ "$ref": "#/$defs/boxLayout"
876
+ },
877
+ "extensions": {
878
+ "$ref": "#/$defs/extensions"
879
+ }
880
+ }
881
+ },
882
+ "formaTarget": {
883
+ "description": "The Forma release the workflow targets, and optionally the capabilities it requires.",
884
+ "type": "object",
885
+ "required": [
886
+ "version"
887
+ ],
888
+ "additionalProperties": false,
889
+ "properties": {
890
+ "version": {
891
+ "$ref": "#/$defs/semver"
892
+ },
893
+ "requires": {
894
+ "type": "array",
895
+ "maxItems": 128,
896
+ "uniqueItems": true,
897
+ "items": {
898
+ "type": "string",
899
+ "pattern": "^[a-z][a-z0-9-]*(?:\\.[a-z0-9-]+)+$"
900
+ }
901
+ }
902
+ }
903
+ },
904
+ "workflowLayout": {
905
+ "type": "object",
906
+ "additionalProperties": false,
907
+ "properties": {
908
+ "direction": {
909
+ "description": "Flow direction of the default layout.",
910
+ "enum": [
911
+ "right",
912
+ "down"
913
+ ]
914
+ },
915
+ "mode": {
916
+ "description": "authored: coordinates are intentional. auto: a renderer may recompute them.",
917
+ "enum": [
918
+ "authored",
919
+ "auto"
920
+ ]
921
+ },
922
+ "canvas": {
923
+ "type": "object",
924
+ "additionalProperties": false,
925
+ "required": [
926
+ "width",
927
+ "height"
928
+ ],
929
+ "properties": {
930
+ "width": {
931
+ "$ref": "#/$defs/extent"
932
+ },
933
+ "height": {
934
+ "$ref": "#/$defs/extent"
935
+ }
936
+ }
937
+ }
938
+ }
939
+ },
940
+ "legendEntry": {
941
+ "type": "object",
942
+ "required": [
943
+ "id",
944
+ "label"
945
+ ],
946
+ "additionalProperties": false,
947
+ "properties": {
948
+ "id": {
949
+ "$ref": "#/$defs/localId"
950
+ },
951
+ "label": {
952
+ "$ref": "#/$defs/text"
953
+ },
954
+ "description": {
955
+ "$ref": "#/$defs/longText"
956
+ },
957
+ "color": {
958
+ "$ref": "#/$defs/objectColor"
959
+ },
960
+ "line": {
961
+ "enum": [
962
+ "solid",
963
+ "dashed",
964
+ "dotted"
965
+ ]
966
+ }
967
+ }
968
+ },
969
+ "presentation": {
970
+ "type": "object",
971
+ "additionalProperties": false,
972
+ "properties": {
973
+ "density": {
974
+ "enum": [
975
+ "comfortable",
976
+ "compact"
977
+ ]
978
+ },
979
+ "legend": {
980
+ "type": "array",
981
+ "maxItems": 64,
982
+ "items": {
983
+ "$ref": "#/$defs/legendEntry"
984
+ }
985
+ },
986
+ "legendTitle": {
987
+ "$ref": "#/$defs/text"
988
+ }
989
+ }
990
+ },
991
+ "provenance": {
992
+ "type": "object",
993
+ "additionalProperties": false,
994
+ "properties": {
995
+ "producer": {
996
+ "type": "object",
997
+ "required": [
998
+ "name"
999
+ ],
1000
+ "additionalProperties": false,
1001
+ "properties": {
1002
+ "name": {
1003
+ "$ref": "#/$defs/text"
1004
+ },
1005
+ "version": {
1006
+ "type": "string",
1007
+ "maxLength": 64
1008
+ },
1009
+ "uri": {
1010
+ "$ref": "#/$defs/uri"
1011
+ }
1012
+ }
1013
+ },
1014
+ "createdAt": {
1015
+ "type": "string",
1016
+ "maxLength": 64
1017
+ },
1018
+ "modifiedAt": {
1019
+ "type": "string",
1020
+ "maxLength": 64
1021
+ },
1022
+ "source": {
1023
+ "type": "string",
1024
+ "maxLength": 4096
1025
+ },
1026
+ "modifiedBy": {
1027
+ "type": "object",
1028
+ "required": [
1029
+ "name"
1030
+ ],
1031
+ "additionalProperties": false,
1032
+ "properties": {
1033
+ "name": {
1034
+ "$ref": "#/$defs/text"
1035
+ },
1036
+ "version": {
1037
+ "type": "string",
1038
+ "maxLength": 64
1039
+ }
1040
+ }
1041
+ }
1042
+ }
1043
+ }
1044
+ }
1045
+ }