@shortlink-org/portolan 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 (188) hide show
  1. package/README.md +151 -6
  2. package/catalog/model.go +147 -0
  3. package/catalog/roundtrip_test.go +7 -0
  4. package/cli/portolan.mjs +6 -1
  5. package/go.mod +7 -0
  6. package/go.sum +20 -6
  7. package/package.json +10 -9
  8. package/plugin/describe.go +38 -0
  9. package/plugins/README.md +296 -5
  10. package/plugins/extract-argocd/options.schema.json +44 -0
  11. package/plugins/extract-celery/main.py +1 -0
  12. package/plugins/extract-csharp-ddd/README.md +213 -0
  13. package/plugins/extract-csharp-ddd/options.schema.json +55 -0
  14. package/plugins/extract-django/README.md +13 -2
  15. package/plugins/extract-django/choices.py +47 -0
  16. package/plugins/extract-django/domain.py +2 -1
  17. package/plugins/extract-django/extract_test.py +13 -0
  18. package/plugins/extract-django/lifecycle.py +2 -28
  19. package/plugins/extract-django/main.py +1 -0
  20. package/plugins/extract-django/rules.py +154 -0
  21. package/plugins/extract-django/rules_test.py +158 -0
  22. package/plugins/extract-go-sqs/options.schema.json +21 -0
  23. package/plugins/extract-http-clients/describe.go +5 -4
  24. package/plugins/extract-java/build/org/portolan/extract/Main.class +0 -0
  25. package/plugins/extract-k8s/options.schema.json +32 -0
  26. package/plugins/extract-laravel/Cargo.lock +962 -0
  27. package/plugins/extract-laravel/Cargo.toml +20 -0
  28. package/plugins/extract-laravel/README.md +200 -0
  29. package/plugins/extract-laravel/options.schema.json +68 -0
  30. package/plugins/extract-laravel/rustfmt.toml +1 -0
  31. package/plugins/extract-php-ddd/Cargo.lock +972 -0
  32. package/plugins/extract-php-ddd/Cargo.toml +22 -0
  33. package/plugins/extract-php-ddd/README.md +141 -0
  34. package/plugins/extract-php-ddd/options.schema.json +50 -0
  35. package/plugins/extract-php-ddd/rustfmt.toml +1 -0
  36. package/plugins/extract-python-kafka/main.py +1 -0
  37. package/plugins/extract-terraform/options.schema.json +26 -0
  38. package/plugins/extract-ts/main.ts +1 -0
  39. package/plugins/phpscan/Cargo.lock +953 -0
  40. package/plugins/phpscan/Cargo.toml +19 -0
  41. package/plugins/phpscan/rustfmt.toml +1 -0
  42. package/plugins/portolan-go.wasm +0 -0
  43. package/plugins/pyplugin/catalog.py +24 -1
  44. package/plugins/verify-otel/options.schema.json +12 -0
  45. package/portolan.json +130 -3
  46. package/rules/builtin.json +218 -0
  47. package/schema/portolan.schema.json +880 -13
  48. package/scripts/README.md +3 -1
  49. package/scripts/delivery-presets.mjs +36 -3
  50. package/scripts/gen-likec4.mjs +149 -16
  51. package/scripts/gen-likec4.test.mjs +96 -0
  52. package/scripts/gen.mjs +30 -3
  53. package/scripts/gitops-example.test.mjs +108 -0
  54. package/scripts/host-plugins/fetch-argocd.mjs +338 -0
  55. package/scripts/host-plugins/fetch-argocd.options.json +49 -0
  56. package/scripts/host-plugins/fetch-argocd.test.mjs +274 -0
  57. package/scripts/host-plugins/fetch-bsr.mjs +1 -0
  58. package/scripts/host-plugins/fetch-csr.mjs +1 -0
  59. package/scripts/host-plugins/fetch-git.mjs +1 -0
  60. package/scripts/host-plugins/fetch-k8s.mjs +263 -0
  61. package/scripts/host-plugins/fetch-k8s.options.json +50 -0
  62. package/scripts/host-plugins/fetch-k8s.test.mjs +259 -0
  63. package/scripts/host-plugins/k8s-topology.mjs +183 -0
  64. package/scripts/json-format.mjs +192 -0
  65. package/scripts/json-format.test.mjs +97 -0
  66. package/scripts/local-api.mjs +216 -8
  67. package/scripts/local-api.test.mjs +88 -2
  68. package/scripts/local-discovery.mjs +12 -0
  69. package/scripts/manifest.mjs +10 -1
  70. package/scripts/plugin-host.mjs +23 -1
  71. package/scripts/plugins-fresh.mjs +97 -0
  72. package/scripts/plugins-fresh.test.mjs +64 -0
  73. package/scripts/run-builtin.mjs +26 -5
  74. package/scripts/schema.mjs +138 -19
  75. package/scripts/trace-trials.mjs +176 -0
  76. package/scripts/trace-trials.test.mjs +142 -0
  77. package/scripts/warning-policy.mjs +12 -6
  78. package/scripts/warning-policy.test.mjs +40 -3
  79. package/src/app/Breadcrumbs.test.ts +3 -0
  80. package/src/app/Breadcrumbs.tsx +3 -0
  81. package/src/app/CatalogApp.tsx +2 -0
  82. package/src/app/SidebarFooter.tsx +20 -4
  83. package/src/catalog-index.ts +25 -0
  84. package/src/catalog-model.ts +246 -1
  85. package/src/catalog-validation.ts +104 -2
  86. package/src/catalog.test.ts +40 -1
  87. package/src/components/ChannelRows.test.tsx +76 -1
  88. package/src/components/ChannelRows.tsx +223 -60
  89. package/src/components/DeploymentRows.tsx +131 -0
  90. package/src/components/DocsLinks.test.tsx +27 -0
  91. package/src/components/DocsLinks.tsx +56 -0
  92. package/src/components/FieldTree.tsx +5 -2
  93. package/src/components/HTTPDestinationEvidence.tsx +1 -1
  94. package/src/components/PluginIcon.tsx +77 -0
  95. package/src/components/ProblemRow.tsx +173 -153
  96. package/src/components/RuleMarks.tsx +22 -0
  97. package/src/components/ShapeRows.tsx +24 -20
  98. package/src/data.ts +21 -0
  99. package/src/enrich.test.ts +127 -3
  100. package/src/enrich.ts +104 -6
  101. package/src/er/ErCanvas.tsx +218 -12
  102. package/src/er/GroupNode.tsx +57 -0
  103. package/src/er/StoreHeader.tsx +1 -0
  104. package/src/er/layout.test.ts +85 -2
  105. package/src/er/layout.ts +140 -5
  106. package/src/er/spec.test.ts +17 -0
  107. package/src/er/spec.ts +23 -10
  108. package/src/flow/Recordings.test.tsx +52 -0
  109. package/src/flow/Recordings.tsx +236 -0
  110. package/src/flow/StepDetail.tsx +53 -0
  111. package/src/flow/TraceTrial.tsx +419 -0
  112. package/src/flow/examples.test.ts +33 -0
  113. package/src/flow/examples.ts +37 -0
  114. package/src/flow/outline.test.ts +28 -0
  115. package/src/flow/outline.ts +7 -2
  116. package/src/flow/trace-trial-resume.test.ts +42 -0
  117. package/src/flow/trace-trial-resume.ts +74 -0
  118. package/src/graph/elk.ts +78 -0
  119. package/src/index.css +24 -0
  120. package/src/landing/LandingPage.tsx +15 -11
  121. package/src/landing/ProductTour.tsx +6 -6
  122. package/src/lib/all-problems.ts +27 -17
  123. package/src/lib/centrality.test.ts +251 -0
  124. package/src/lib/centrality.ts +232 -0
  125. package/src/lib/confluence.test.ts +37 -0
  126. package/src/lib/confluence.ts +41 -0
  127. package/src/lib/context-color.ts +1 -1
  128. package/src/lib/deployment-drift.ts +22 -0
  129. package/src/lib/derive.ts +43 -69
  130. package/src/lib/environments.test.ts +83 -0
  131. package/src/lib/environments.ts +57 -0
  132. package/src/lib/integration-url.test.ts +30 -0
  133. package/src/lib/integration-url.ts +63 -0
  134. package/src/lib/kafka-ui.ts +3 -45
  135. package/src/lib/local-api.ts +96 -2
  136. package/src/lib/notion.ts +13 -0
  137. package/src/lib/plugin-index.json +2765 -0
  138. package/src/lib/plugins.test.ts +68 -0
  139. package/src/lib/plugins.ts +264 -0
  140. package/src/lib/problem-flows.test.ts +61 -0
  141. package/src/lib/problem-flows.ts +78 -0
  142. package/src/lib/problem-rules-cel.d.mts +43 -0
  143. package/src/lib/problem-rules-cel.mjs +407 -0
  144. package/src/lib/problem-rules.test.ts +287 -0
  145. package/src/lib/problem-rules.ts +271 -0
  146. package/src/lib/problem-subjects.ts +737 -0
  147. package/src/lib/rule-entries.ts +39 -0
  148. package/src/lib/{data-problems.test.ts → rules-data.test.ts} +18 -16
  149. package/src/lib/rules-deploy.test.ts +133 -0
  150. package/src/lib/{problems.test.ts → rules-edges.test.ts} +8 -3
  151. package/src/lib/{proto-problems.test.ts → rules-proto.test.ts} +9 -25
  152. package/src/lib/{wire-problems.test.ts → rules-wire.test.ts} +13 -11
  153. package/src/lib/rules.test.ts +51 -0
  154. package/src/lib/rules.ts +86 -0
  155. package/src/lib/shape.test.ts +32 -0
  156. package/src/lib/shape.ts +30 -6
  157. package/src/lib/tech.ts +16 -0
  158. package/src/lib/trace-project.test.ts +34 -0
  159. package/src/lib/trace-project.ts +50 -0
  160. package/src/lib/use-problems.ts +23 -0
  161. package/src/lib/warnings.test.ts +9 -0
  162. package/src/lib/warnings.ts +10 -10
  163. package/src/likec4/ids.test.ts +6 -2
  164. package/src/likec4/ids.ts +43 -0
  165. package/src/main.tsx +23 -0
  166. package/src/merge-deployments.test.ts +127 -0
  167. package/src/merge.test.ts +82 -0
  168. package/src/merge.ts +173 -9
  169. package/src/pages/AggregatePage.tsx +57 -7
  170. package/src/pages/ContextMap.tsx +45 -3
  171. package/src/pages/ContextPage.tsx +2 -0
  172. package/src/pages/EventPage.tsx +15 -5
  173. package/src/pages/FlowDetail.tsx +23 -2
  174. package/src/pages/GraphPage.tsx +40 -3
  175. package/src/pages/Overview.tsx +152 -12
  176. package/src/pages/PluginIndex.tsx +190 -0
  177. package/src/pages/Problems.tsx +396 -128
  178. package/src/pages/ServicePage.tsx +58 -2
  179. package/src/pages/Settings.tsx +28 -2
  180. package/src/pages/settings/AboutSettings.tsx +8 -1
  181. package/src/pages/settings/IntegrationsSettings.tsx +63 -17
  182. package/src/pages/settings/RecordingSettings.tsx +138 -0
  183. package/src/pages/settings/RulesSettings.tsx +825 -0
  184. package/src/routes.test.ts +9 -0
  185. package/src/routes.ts +22 -1
  186. package/src/lib/data-problems.ts +0 -314
  187. package/src/lib/proto-problems.ts +0 -237
  188. package/src/lib/wire-problems.ts +0 -342
@@ -52,6 +52,14 @@
52
52
  },
53
53
  "description": "CEL policies for reviewed extraction limitations. Expressions are type-checked when the manifest is read and suppression always requires a reason."
54
54
  },
55
+ "problemRules": {
56
+ "type": "array",
57
+ "maxItems": 200,
58
+ "items": {
59
+ "$ref": "#/$defs/problemRule"
60
+ },
61
+ "description": "The rules the Problems page applies. An entry naming a built-in rule (rules/builtin.json) switches it off or re-grades it, with a reason; any other id is a rule of its own, written in CEL over one subject. Expressions are type-checked when the manifest is read and run in the page over the merged catalog."
62
+ },
55
63
  "plugins": {
56
64
  "type": "array",
57
65
  "items": {
@@ -77,6 +85,9 @@
77
85
  "go-domain",
78
86
  "ts-domain",
79
87
  "rust-domain",
88
+ "laravel-domain",
89
+ "php-ddd",
90
+ "csharp-ddd",
80
91
  "java-domain",
81
92
  "django-domain",
82
93
  "celery",
@@ -88,6 +99,10 @@
88
99
  "river",
89
100
  "watermill",
90
101
  "go-nats",
102
+ "go-sqs",
103
+ "terraform",
104
+ "k8s",
105
+ "argocd-gitops",
91
106
  "asyncapi",
92
107
  "graphql",
93
108
  "sql",
@@ -97,6 +112,8 @@
97
112
  "bsr",
98
113
  "git",
99
114
  "csr",
115
+ "k8s-cluster",
116
+ "argocd",
100
117
  "csr-schemas",
101
118
  "proto"
102
119
  ],
@@ -211,6 +228,63 @@
211
228
  }
212
229
  }
213
230
  },
231
+ {
232
+ "if": {
233
+ "required": [
234
+ "plugin"
235
+ ],
236
+ "properties": {
237
+ "plugin": {
238
+ "const": "laravel-domain"
239
+ }
240
+ }
241
+ },
242
+ "then": {
243
+ "properties": {
244
+ "options": {
245
+ "$ref": "#/$defs/options.laravel-domain"
246
+ }
247
+ }
248
+ }
249
+ },
250
+ {
251
+ "if": {
252
+ "required": [
253
+ "plugin"
254
+ ],
255
+ "properties": {
256
+ "plugin": {
257
+ "const": "php-ddd"
258
+ }
259
+ }
260
+ },
261
+ "then": {
262
+ "properties": {
263
+ "options": {
264
+ "$ref": "#/$defs/options.php-ddd"
265
+ }
266
+ }
267
+ }
268
+ },
269
+ {
270
+ "if": {
271
+ "required": [
272
+ "plugin"
273
+ ],
274
+ "properties": {
275
+ "plugin": {
276
+ "const": "csharp-ddd"
277
+ }
278
+ }
279
+ },
280
+ "then": {
281
+ "properties": {
282
+ "options": {
283
+ "$ref": "#/$defs/options.csharp-ddd"
284
+ }
285
+ }
286
+ }
287
+ },
214
288
  {
215
289
  "if": {
216
290
  "required": [
@@ -420,6 +494,82 @@
420
494
  }
421
495
  }
422
496
  },
497
+ {
498
+ "if": {
499
+ "required": [
500
+ "plugin"
501
+ ],
502
+ "properties": {
503
+ "plugin": {
504
+ "const": "go-sqs"
505
+ }
506
+ }
507
+ },
508
+ "then": {
509
+ "properties": {
510
+ "options": {
511
+ "$ref": "#/$defs/options.go-sqs"
512
+ }
513
+ }
514
+ }
515
+ },
516
+ {
517
+ "if": {
518
+ "required": [
519
+ "plugin"
520
+ ],
521
+ "properties": {
522
+ "plugin": {
523
+ "const": "terraform"
524
+ }
525
+ }
526
+ },
527
+ "then": {
528
+ "properties": {
529
+ "options": {
530
+ "$ref": "#/$defs/options.terraform"
531
+ }
532
+ }
533
+ }
534
+ },
535
+ {
536
+ "if": {
537
+ "required": [
538
+ "plugin"
539
+ ],
540
+ "properties": {
541
+ "plugin": {
542
+ "const": "k8s"
543
+ }
544
+ }
545
+ },
546
+ "then": {
547
+ "properties": {
548
+ "options": {
549
+ "$ref": "#/$defs/options.k8s"
550
+ }
551
+ }
552
+ }
553
+ },
554
+ {
555
+ "if": {
556
+ "required": [
557
+ "plugin"
558
+ ],
559
+ "properties": {
560
+ "plugin": {
561
+ "const": "argocd-gitops"
562
+ }
563
+ }
564
+ },
565
+ "then": {
566
+ "properties": {
567
+ "options": {
568
+ "$ref": "#/$defs/options.argocd-gitops"
569
+ }
570
+ }
571
+ }
572
+ },
423
573
  {
424
574
  "if": {
425
575
  "required": [
@@ -591,6 +741,44 @@
591
741
  }
592
742
  }
593
743
  },
744
+ {
745
+ "if": {
746
+ "required": [
747
+ "plugin"
748
+ ],
749
+ "properties": {
750
+ "plugin": {
751
+ "const": "k8s-cluster"
752
+ }
753
+ }
754
+ },
755
+ "then": {
756
+ "properties": {
757
+ "options": {
758
+ "$ref": "#/$defs/options.k8s-cluster"
759
+ }
760
+ }
761
+ }
762
+ },
763
+ {
764
+ "if": {
765
+ "required": [
766
+ "plugin"
767
+ ],
768
+ "properties": {
769
+ "plugin": {
770
+ "const": "argocd"
771
+ }
772
+ }
773
+ },
774
+ "then": {
775
+ "properties": {
776
+ "options": {
777
+ "$ref": "#/$defs/options.argocd"
778
+ }
779
+ }
780
+ }
781
+ },
594
782
  {
595
783
  "if": {
596
784
  "required": [
@@ -803,6 +991,170 @@
803
991
  }
804
992
  },
805
993
  "$defs": {
994
+ "problemRule": {
995
+ "type": "object",
996
+ "additionalProperties": false,
997
+ "required": [
998
+ "id"
999
+ ],
1000
+ "properties": {
1001
+ "id": {
1002
+ "type": "string",
1003
+ "pattern": "^[a-z0-9]+(?:[-.][a-z0-9]+)*$",
1004
+ "description": "The rule. One of the built-in ids - rpc, consumer, cross-service-fk, cross-service-lineage, cross-service-view, shared-store, persistence-drift, column-type, outbox-payload, proto-missing, proto-drift, shared-channel, channel-undeclared, channel-unpublished, message-encoding, subscription-unresolved, deployment-unclaimed, deployment-drift - to switch or re-grade that rule; any other id declares a rule of its own."
1005
+ },
1006
+ "enabled": {
1007
+ "type": "boolean",
1008
+ "default": true,
1009
+ "description": "Whether the rule produces rows. A disabled rule needs a reason and stays listed on the Settings page."
1010
+ },
1011
+ "severity": {
1012
+ "enum": [
1013
+ "error",
1014
+ "warning"
1015
+ ],
1016
+ "description": "How wrong a row of this rule is. For a built-in rule this replaces the severity its passport was written with."
1017
+ },
1018
+ "reason": {
1019
+ "type": "string",
1020
+ "minLength": 1,
1021
+ "description": "Why the rule is off or re-graded, or, for a rule of your own, why the estate holds it."
1022
+ },
1023
+ "over": {
1024
+ "enum": [
1025
+ "service",
1026
+ "call",
1027
+ "copy",
1028
+ "event",
1029
+ "consumer",
1030
+ "channel",
1031
+ "subscription",
1032
+ "table",
1033
+ "column",
1034
+ "deployment",
1035
+ "flow",
1036
+ "aggregate"
1037
+ ],
1038
+ "description": "What one row of the rule is about, and what `when` and `message` read."
1039
+ },
1040
+ "when": {
1041
+ "type": "string",
1042
+ "minLength": 1,
1043
+ "maxLength": 2000,
1044
+ "description": "The condition: a row exists for every subject where it holds. CEL returning bool, over the subject named by `over` and `estate` (services, contexts, stores, channels, externals). Fields by subject: service: id, slug, name, context, kind, repo, path, technologies, owners, provides, methods, calls, unresolvedCalls, aggregates, events, stores, channels, hosts, dials; call: id, interface, method, peer, status, resolved, peerKnown, methodDeclared, service, context, source, module, note; copy: id, service, context, provider, methods, differences, source; event: id, slug, name, aggregate, service, context, versions, deprecated, consumers, unresolvedConsumers, wireName, channel, declaredChannels, fields; consumer: event, name, aggregate, owner, context, consumer, status, resolved, note; channel: address, kind, title, service, context, declared, publishes, sends, receives, events, otherPublishers, otherClaims, source; subscription: service, context, channel, kind, name, encoding, published, publishers, mismatched, mismatchedEncodings, source; table: id, name, kind, store, storeKind, owner, context, role, aggregate, aggregateOwner, aggregateFields, mappedColumns, claimedColumns, block, columns, primaryKey, foreignKeys, foreignReads, hasPayload, indexes, reads, writes, deletes; column: id, name, relation, kind, store, owner, context, type, nullable, pk, fk, fkOwner, from, foreignFrom, foreignOwners, maps, fieldType, typeMatches; deployment: id, name, project, environment, cluster, namespace, repo, path, chart, from, targetRevision, revision, tool, service, labelled, claimed, context, runsIn, images, basis, drifted, drift, url; flow: id, slug, name, owner, trigger, triggerConfidence, participants, contexts, crossContext, steps, verifiedSteps, declaredSteps, unresolvedSteps, seenSteps, events, stores, examples, source; aggregate: id, slug, name, root, modelGroup, service, context, entities, valueObjects, enums, commands, queries, exposedOperations, deprecatedOperations, events, states, transitions, tables."
1045
+ },
1046
+ "message": {
1047
+ "type": "string",
1048
+ "minLength": 1,
1049
+ "maxLength": 2000,
1050
+ "description": "The note on the row. CEL returning string, over the subject named by `over` and `estate` (services, contexts, stores, channels, externals). Fields by subject: service: id, slug, name, context, kind, repo, path, technologies, owners, provides, methods, calls, unresolvedCalls, aggregates, events, stores, channels, hosts, dials; call: id, interface, method, peer, status, resolved, peerKnown, methodDeclared, service, context, source, module, note; copy: id, service, context, provider, methods, differences, source; event: id, slug, name, aggregate, service, context, versions, deprecated, consumers, unresolvedConsumers, wireName, channel, declaredChannels, fields; consumer: event, name, aggregate, owner, context, consumer, status, resolved, note; channel: address, kind, title, service, context, declared, publishes, sends, receives, events, otherPublishers, otherClaims, source; subscription: service, context, channel, kind, name, encoding, published, publishers, mismatched, mismatchedEncodings, source; table: id, name, kind, store, storeKind, owner, context, role, aggregate, aggregateOwner, aggregateFields, mappedColumns, claimedColumns, block, columns, primaryKey, foreignKeys, foreignReads, hasPayload, indexes, reads, writes, deletes; column: id, name, relation, kind, store, owner, context, type, nullable, pk, fk, fkOwner, from, foreignFrom, foreignOwners, maps, fieldType, typeMatches; deployment: id, name, project, environment, cluster, namespace, repo, path, chart, from, targetRevision, revision, tool, service, labelled, claimed, context, runsIn, images, basis, drifted, drift, url; flow: id, slug, name, owner, trigger, triggerConfidence, participants, contexts, crossContext, steps, verifiedSteps, declaredSteps, unresolvedSteps, seenSteps, events, stores, examples, source; aggregate: id, slug, name, root, modelGroup, service, context, entities, valueObjects, enums, commands, queries, exposedOperations, deprecatedOperations, events, states, transitions, tables."
1051
+ },
1052
+ "peer": {
1053
+ "type": "string",
1054
+ "minLength": 1,
1055
+ "maxLength": 2000,
1056
+ "description": "The row's far end, when it has one; a service, event or table id links to its page. CEL returning string, over the subject named by `over` and `estate` (services, contexts, stores, channels, externals). Fields by subject: service: id, slug, name, context, kind, repo, path, technologies, owners, provides, methods, calls, unresolvedCalls, aggregates, events, stores, channels, hosts, dials; call: id, interface, method, peer, status, resolved, peerKnown, methodDeclared, service, context, source, module, note; copy: id, service, context, provider, methods, differences, source; event: id, slug, name, aggregate, service, context, versions, deprecated, consumers, unresolvedConsumers, wireName, channel, declaredChannels, fields; consumer: event, name, aggregate, owner, context, consumer, status, resolved, note; channel: address, kind, title, service, context, declared, publishes, sends, receives, events, otherPublishers, otherClaims, source; subscription: service, context, channel, kind, name, encoding, published, publishers, mismatched, mismatchedEncodings, source; table: id, name, kind, store, storeKind, owner, context, role, aggregate, aggregateOwner, aggregateFields, mappedColumns, claimedColumns, block, columns, primaryKey, foreignKeys, foreignReads, hasPayload, indexes, reads, writes, deletes; column: id, name, relation, kind, store, owner, context, type, nullable, pk, fk, fkOwner, from, foreignFrom, foreignOwners, maps, fieldType, typeMatches; deployment: id, name, project, environment, cluster, namespace, repo, path, chart, from, targetRevision, revision, tool, service, labelled, claimed, context, runsIn, images, basis, drifted, drift, url; flow: id, slug, name, owner, trigger, triggerConfidence, participants, contexts, crossContext, steps, verifiedSteps, declaredSteps, unresolvedSteps, seenSteps, events, stores, examples, source; aggregate: id, slug, name, root, modelGroup, service, context, entities, valueObjects, enums, commands, queries, exposedOperations, deprecatedOperations, events, states, transitions, tables."
1057
+ },
1058
+ "title": {
1059
+ "type": "string",
1060
+ "minLength": 1,
1061
+ "description": "The rule's name on the Settings page."
1062
+ },
1063
+ "note": {
1064
+ "type": "string",
1065
+ "minLength": 1,
1066
+ "description": "The short words on every row of the rule; the title when absent."
1067
+ },
1068
+ "description": {
1069
+ "type": "string",
1070
+ "description": "What the rule checks and why it matters."
1071
+ },
1072
+ "action": {
1073
+ "type": "string",
1074
+ "description": "What a reader does about a row."
1075
+ }
1076
+ },
1077
+ "if": {
1078
+ "properties": {
1079
+ "id": {
1080
+ "enum": [
1081
+ "rpc",
1082
+ "consumer",
1083
+ "cross-service-fk",
1084
+ "cross-service-lineage",
1085
+ "cross-service-view",
1086
+ "shared-store",
1087
+ "persistence-drift",
1088
+ "column-type",
1089
+ "outbox-payload",
1090
+ "proto-missing",
1091
+ "proto-drift",
1092
+ "shared-channel",
1093
+ "channel-undeclared",
1094
+ "channel-unpublished",
1095
+ "message-encoding",
1096
+ "subscription-unresolved",
1097
+ "deployment-unclaimed",
1098
+ "deployment-drift"
1099
+ ]
1100
+ }
1101
+ }
1102
+ },
1103
+ "then": {
1104
+ "not": {
1105
+ "anyOf": [
1106
+ {
1107
+ "required": [
1108
+ "over"
1109
+ ]
1110
+ },
1111
+ {
1112
+ "required": [
1113
+ "when"
1114
+ ]
1115
+ },
1116
+ {
1117
+ "required": [
1118
+ "message"
1119
+ ]
1120
+ },
1121
+ {
1122
+ "required": [
1123
+ "peer"
1124
+ ]
1125
+ },
1126
+ {
1127
+ "required": [
1128
+ "title"
1129
+ ]
1130
+ },
1131
+ {
1132
+ "required": [
1133
+ "note"
1134
+ ]
1135
+ },
1136
+ {
1137
+ "required": [
1138
+ "description"
1139
+ ]
1140
+ },
1141
+ {
1142
+ "required": [
1143
+ "action"
1144
+ ]
1145
+ }
1146
+ ]
1147
+ }
1148
+ },
1149
+ "else": {
1150
+ "required": [
1151
+ "over",
1152
+ "when",
1153
+ "message",
1154
+ "title"
1155
+ ]
1156
+ }
1157
+ },
806
1158
  "warningPolicy": {
807
1159
  "type": "object",
808
1160
  "additionalProperties": false,
@@ -995,7 +1347,9 @@
995
1347
  "enum": [
996
1348
  "fetch-git",
997
1349
  "fetch-bsr",
998
- "fetch-csr"
1350
+ "fetch-csr",
1351
+ "fetch-k8s",
1352
+ "fetch-argocd"
999
1353
  ],
1000
1354
  "description": "A plugin the host runs inside its own process, because it needs a socket or a git binary (portolan.0008). Only the ones shipped with Portolan can be named."
1001
1355
  },
@@ -1473,24 +1827,27 @@
1473
1827
  }
1474
1828
  }
1475
1829
  },
1476
- "options.java-domain": {
1830
+ "options.laravel-domain": {
1477
1831
  "type": "object",
1478
1832
  "additionalProperties": false,
1479
1833
  "properties": {
1480
1834
  "context": {
1481
1835
  "type": "string",
1482
- "description": "Slug of the bounded context this service belongs to. Defaults to the name of the input directory.",
1836
+ "description": "Slug of the bounded context this application belongs to. A composer.json knows its name, not which context owns it. Defaults to the name of the input directory.",
1483
1837
  "examples": [
1484
- "payments"
1838
+ "shop"
1485
1839
  ]
1486
1840
  },
1487
1841
  "contextName": {
1488
1842
  "type": "string",
1489
- "description": "What the context is called on the page. Defaults to the slug, titled."
1843
+ "description": "What the context is called on the page. Defaults to the slug, titled.",
1844
+ "examples": [
1845
+ "Shop"
1846
+ ]
1490
1847
  },
1491
1848
  "contextSummary": {
1492
1849
  "type": "string",
1493
- "description": "A sentence or two on what the context is responsible for."
1850
+ "description": "A sentence or two on what the context is responsible for. Read on the context page and nowhere else."
1494
1851
  },
1495
1852
  "classification": {
1496
1853
  "enum": [
@@ -1504,7 +1861,7 @@
1504
1861
  "type": "string",
1505
1862
  "description": "Slug of the service. Defaults to the name of the input directory.",
1506
1863
  "examples": [
1507
- "ledger"
1864
+ "bagisto"
1508
1865
  ]
1509
1866
  },
1510
1867
  "serviceName": {
@@ -1513,19 +1870,234 @@
1513
1870
  },
1514
1871
  "repo": {
1515
1872
  "type": "string",
1516
- "description": "Where the source lives. Defaults to the scm url in pom.xml.",
1873
+ "description": "Where the source lives. Defaults to composer.json's support.source or homepage when either names a repository.",
1517
1874
  "examples": [
1518
- "github.com/shortlink-org/portolan"
1875
+ "github.com/bagisto/bagisto"
1519
1876
  ]
1520
1877
  },
1521
- "store": {
1878
+ "modules": {
1522
1879
  "type": "string",
1523
- "description": "Slug of the database this service keeps its state in, the same one the sql extractor is given. It is here for the flows: a call on a port lands somewhere, and only the manifest knows where.",
1880
+ "description": "Where the application's modules are, as a directory pattern relative to the input root with `*` for one path segment: `packages/*/*/src` for a package-per-module monolith, `app` for a plain Laravel application. Each match is one module, named after the directory the pattern's last literal segment sits in. Defaults to `packages/*/*/src` when that matches anything, and to `app` otherwise.",
1524
1881
  "examples": [
1525
- "pg"
1882
+ "packages/*/*/src",
1883
+ "app",
1884
+ "modules/*"
1526
1885
  ]
1527
1886
  },
1528
- "peers": {
1887
+ "store": {
1888
+ "type": "string",
1889
+ "description": "Slug of the database the migrations describe and the models read and write. The store's id is the service id and this slug.",
1890
+ "default": "db",
1891
+ "examples": [
1892
+ "mysql"
1893
+ ]
1894
+ },
1895
+ "storeKind": {
1896
+ "enum": [
1897
+ "postgres",
1898
+ "mysql",
1899
+ "sqlite",
1900
+ "other"
1901
+ ],
1902
+ "description": "Which database the migrations are the schema of. Read off config/database.php's default connection when left out - `env('DB_CONNECTION', 'mysql')` names it - and mysql when that cannot be read; given here, it wins."
1903
+ },
1904
+ "out": {
1905
+ "type": "string",
1906
+ "description": "Name of the fragment file, inside the step's output directory. One extractor writes one file, so that a fragment carries the provenance of the run that produced it.",
1907
+ "default": "domain.json"
1908
+ },
1909
+ "storesOut": {
1910
+ "type": "string",
1911
+ "description": "Name of the store fragment, inside the step's output directory. Written when the migrations declare tables or the code reaches any.",
1912
+ "default": "stores.json"
1913
+ },
1914
+ "openapiOut": {
1915
+ "type": "string",
1916
+ "description": "Name of the inferred OpenAPI 3.1 document, inside the step's output directory. Written when the route files expose HTTP operations.",
1917
+ "default": "openapi.inferred.yaml"
1918
+ }
1919
+ }
1920
+ },
1921
+ "options.php-ddd": {
1922
+ "type": "object",
1923
+ "additionalProperties": false,
1924
+ "properties": {
1925
+ "source": {
1926
+ "type": "string",
1927
+ "description": "The directory the bounded contexts are in, relative to the input root: one directory per context, one per module under it, `Domain`, `Application` and `Infrastructure` under that. A `Shared` directory at either level is the shared kernel and is not a context or a module.",
1928
+ "default": "src"
1929
+ },
1930
+ "apps": {
1931
+ "type": "string",
1932
+ "description": "The directory the deployable applications are in, relative to the input root: `<apps>/<context>/<app>`, each with `config/routes/*.yaml` and `src/Controller/`. Each application is a service of its context; a context with none gets one service named after itself.",
1933
+ "default": "apps"
1934
+ },
1935
+ "repo": {
1936
+ "type": "string",
1937
+ "description": "Where the source lives. Defaults to composer.json's support.source or homepage when either names a repository.",
1938
+ "examples": [
1939
+ "github.com/CodelyTV/php-ddd-example"
1940
+ ]
1941
+ },
1942
+ "exchange": {
1943
+ "type": "string",
1944
+ "description": "The RabbitMQ exchange domain events are published to. The code reads it from the environment, so the manifest says.",
1945
+ "default": "domain_events"
1946
+ },
1947
+ "storeKind": {
1948
+ "enum": [
1949
+ "postgres",
1950
+ "mysql",
1951
+ "sqlite",
1952
+ "other"
1953
+ ],
1954
+ "description": "What the Doctrine-mapped tables live in.",
1955
+ "default": "mysql"
1956
+ },
1957
+ "classification": {
1958
+ "enum": [
1959
+ "core",
1960
+ "supporting",
1961
+ "generic"
1962
+ ],
1963
+ "description": "Whether the contexts are core to the business, support it, or are generic and could be bought. One value for every context the tree declares."
1964
+ },
1965
+ "out": {
1966
+ "type": "string",
1967
+ "description": "Name of the fragment file, inside the step's output directory.",
1968
+ "default": "domain.json"
1969
+ },
1970
+ "openapiOut": {
1971
+ "type": "string",
1972
+ "description": "Name of the inferred OpenAPI 3.1 document, inside the step's output directory. Written when the route files expose HTTP operations.",
1973
+ "default": "openapi.inferred.yaml"
1974
+ },
1975
+ "storesOut": {
1976
+ "type": "string",
1977
+ "description": "Name of the store fragment, inside the step's output directory. Written when a Doctrine mapping or a repository adapter names a store.",
1978
+ "default": "stores.json"
1979
+ }
1980
+ }
1981
+ },
1982
+ "options.csharp-ddd": {
1983
+ "type": "object",
1984
+ "additionalProperties": false,
1985
+ "properties": {
1986
+ "modules": {
1987
+ "type": "string",
1988
+ "description": "The directory the modules are in, relative to the input root: one directory per module, `Domain`, `Application`, `Infrastructure` and `IntegrationEvents` under it. Each module is a bounded context with one service.",
1989
+ "default": "src/Modules"
1990
+ },
1991
+ "api": {
1992
+ "type": "string",
1993
+ "description": "The directory the HTTP host is in, relative to the input root. Controllers under a `Modules/<Module>` directory beneath it are that module's HTTP edge.",
1994
+ "default": "src/API"
1995
+ },
1996
+ "database": {
1997
+ "type": "string",
1998
+ "description": "The directory the database project is in, relative to the input root: `Structure/<schema>/Tables/*.sql` and `Structure/<schema>/Views/*.sql` beneath it, one schema per module.",
1999
+ "default": "src/Database"
2000
+ },
2001
+ "repo": {
2002
+ "type": "string",
2003
+ "description": "Where the source lives, as `host/owner/name`. Nothing in a .NET tree says, so the manifest does.",
2004
+ "examples": [
2005
+ "github.com/kgrzybek/modular-monolith-with-ddd"
2006
+ ]
2007
+ },
2008
+ "bus": {
2009
+ "type": "string",
2010
+ "description": "The address of the bus integration events cross modules on. The code names the class, `InMemoryEventBus`, and nothing else, so the manifest says.",
2011
+ "default": "integration-events"
2012
+ },
2013
+ "storeKind": {
2014
+ "enum": [
2015
+ "postgres",
2016
+ "mysql",
2017
+ "sqlite",
2018
+ "other"
2019
+ ],
2020
+ "description": "What the schemas live in. SQL Server is `other`.",
2021
+ "default": "other"
2022
+ },
2023
+ "classification": {
2024
+ "enum": [
2025
+ "core",
2026
+ "supporting",
2027
+ "generic"
2028
+ ],
2029
+ "description": "Whether the modules are core to the business, support it, or are generic and could be bought. One value for every module the tree declares."
2030
+ },
2031
+ "out": {
2032
+ "type": "string",
2033
+ "description": "Name of the fragment file, inside the step's output directory.",
2034
+ "default": "domain.json"
2035
+ },
2036
+ "openapiOut": {
2037
+ "type": "string",
2038
+ "description": "Name of the inferred OpenAPI 3.1 document, inside the step's output directory, one per module with controllers; `{service}` is replaced with the module's slug.",
2039
+ "default": "openapi.{service}.yaml"
2040
+ },
2041
+ "storesOut": {
2042
+ "type": "string",
2043
+ "description": "Name of the store fragment, inside the step's output directory. Written when the database project declares a schema a module maps to.",
2044
+ "default": "stores.json"
2045
+ }
2046
+ }
2047
+ },
2048
+ "options.java-domain": {
2049
+ "type": "object",
2050
+ "additionalProperties": false,
2051
+ "properties": {
2052
+ "context": {
2053
+ "type": "string",
2054
+ "description": "Slug of the bounded context this service belongs to. Defaults to the name of the input directory.",
2055
+ "examples": [
2056
+ "payments"
2057
+ ]
2058
+ },
2059
+ "contextName": {
2060
+ "type": "string",
2061
+ "description": "What the context is called on the page. Defaults to the slug, titled."
2062
+ },
2063
+ "contextSummary": {
2064
+ "type": "string",
2065
+ "description": "A sentence or two on what the context is responsible for."
2066
+ },
2067
+ "classification": {
2068
+ "enum": [
2069
+ "core",
2070
+ "supporting",
2071
+ "generic"
2072
+ ],
2073
+ "description": "Whether the context is core to the business, supports it, or is generic and could be bought."
2074
+ },
2075
+ "service": {
2076
+ "type": "string",
2077
+ "description": "Slug of the service. Defaults to the name of the input directory.",
2078
+ "examples": [
2079
+ "ledger"
2080
+ ]
2081
+ },
2082
+ "serviceName": {
2083
+ "type": "string",
2084
+ "description": "What the service is called on the page. Defaults to the title of its README, and failing that to the slug, titled."
2085
+ },
2086
+ "repo": {
2087
+ "type": "string",
2088
+ "description": "Where the source lives. Defaults to the scm url in pom.xml.",
2089
+ "examples": [
2090
+ "github.com/shortlink-org/portolan"
2091
+ ]
2092
+ },
2093
+ "store": {
2094
+ "type": "string",
2095
+ "description": "Slug of the database this service keeps its state in, the same one the sql extractor is given. It is here for the flows: a call on a port lands somewhere, and only the manifest knows where.",
2096
+ "examples": [
2097
+ "pg"
2098
+ ]
2099
+ },
2100
+ "peers": {
1529
2101
  "type": "object",
1530
2102
  "additionalProperties": {
1531
2103
  "type": "string"
@@ -2151,6 +2723,160 @@
2151
2723
  }
2152
2724
  }
2153
2725
  },
2726
+ "options.go-sqs": {
2727
+ "type": "object",
2728
+ "additionalProperties": false,
2729
+ "properties": {
2730
+ "context": {
2731
+ "type": "string",
2732
+ "description": "Slug of the bounded context this service belongs to. Defaults to the name of the input directory.",
2733
+ "examples": [
2734
+ "shop"
2735
+ ]
2736
+ },
2737
+ "service": {
2738
+ "type": "string",
2739
+ "description": "Slug of the service. Defaults to the name of the input directory.",
2740
+ "examples": [
2741
+ "fulfillment"
2742
+ ]
2743
+ },
2744
+ "out": {
2745
+ "type": "string",
2746
+ "description": "Name of the fragment file, inside the step's output directory.",
2747
+ "default": "sqs.json"
2748
+ }
2749
+ }
2750
+ },
2751
+ "options.terraform": {
2752
+ "type": "object",
2753
+ "additionalProperties": false,
2754
+ "properties": {
2755
+ "context": {
2756
+ "type": "string",
2757
+ "description": "Slug of the bounded context the module deploys into. Defaults to the name of the input directory.",
2758
+ "examples": [
2759
+ "shop"
2760
+ ]
2761
+ },
2762
+ "service": {
2763
+ "type": "string",
2764
+ "description": "Slug of the service the module sits beside. Queues, topics and stores nothing in the module claims are listed on it, and it owns every store. A Lambda function whose name slugs to this becomes the service itself; any other becomes a component of kind function in the same context. Defaults to the name of the input directory.",
2765
+ "examples": [
2766
+ "fulfillment"
2767
+ ]
2768
+ },
2769
+ "dir": {
2770
+ "type": "string",
2771
+ "description": "Directory of *.tf files to read, relative to the input root. Left out, the root is read when it holds *.tf files, and otherwise the one directory under it that does - when there are several, the first by name, and the rest are named in a warning. Local modules (source = ./...) are followed from wherever they are called; registry modules are not read.",
2772
+ "examples": [
2773
+ "deploy/terraform"
2774
+ ]
2775
+ },
2776
+ "out": {
2777
+ "type": "string",
2778
+ "description": "Name of the fragment file, inside the step's output directory.",
2779
+ "default": "terraform.json"
2780
+ }
2781
+ }
2782
+ },
2783
+ "options.k8s": {
2784
+ "type": "object",
2785
+ "additionalProperties": false,
2786
+ "properties": {
2787
+ "context": {
2788
+ "type": "string",
2789
+ "description": "Slug of the bounded context this service belongs to. Defaults to the name of the input directory.",
2790
+ "examples": [
2791
+ "shop"
2792
+ ]
2793
+ },
2794
+ "service": {
2795
+ "type": "string",
2796
+ "description": "Slug of the service. Defaults to the name of the input directory. The workload is found by this name: a Deployment, StatefulSet, DaemonSet, Job or CronJob called so, or labelled so with `app` or `app.kubernetes.io/name`; when the tree holds exactly one workload, that one.",
2797
+ "examples": [
2798
+ "pricing"
2799
+ ]
2800
+ },
2801
+ "paths": {
2802
+ "type": "array",
2803
+ "items": {
2804
+ "type": "string"
2805
+ },
2806
+ "description": "Directories under the input root that hold the manifests, so a repository's other YAML - compose files, CI, buf - is not walked. Left out, the whole root is read and anything without `apiVersion` and `kind` is passed over.",
2807
+ "examples": [
2808
+ [
2809
+ "deploy/k8s"
2810
+ ]
2811
+ ]
2812
+ },
2813
+ "namespace": {
2814
+ "type": "string",
2815
+ "description": "Read only the objects in this namespace. An object that names no namespace is read either way. Left out, every namespace.",
2816
+ "examples": [
2817
+ "shop"
2818
+ ]
2819
+ },
2820
+ "out": {
2821
+ "type": "string",
2822
+ "description": "Name of the fragment file, inside the step's output directory.",
2823
+ "default": "k8s.json"
2824
+ }
2825
+ }
2826
+ },
2827
+ "options.argocd-gitops": {
2828
+ "type": "object",
2829
+ "additionalProperties": false,
2830
+ "properties": {
2831
+ "repo": {
2832
+ "type": "string",
2833
+ "description": "The repository this tree is, spelled the way `Service.repo` spells it. A git generator pointing at another repository cannot be walked and is passed over with a warning; left out, every git generator is taken to mean this tree.",
2834
+ "examples": [
2835
+ "github.com/acme/gitops"
2836
+ ]
2837
+ },
2838
+ "paths": {
2839
+ "type": "array",
2840
+ "items": {
2841
+ "type": "string"
2842
+ },
2843
+ "description": "Directories under the input root that hold the Applications and ApplicationSets, so overlays and charts beside them are not read for Argo CD objects. Left out, the whole root is walked.",
2844
+ "examples": [
2845
+ [
2846
+ "bootstrap",
2847
+ "appsets"
2848
+ ]
2849
+ ]
2850
+ },
2851
+ "environmentLabel": {
2852
+ "type": "string",
2853
+ "default": "env",
2854
+ "description": "The Application label that names the environment. An Application without it is placed by the cluster it deploys to."
2855
+ },
2856
+ "labels": {
2857
+ "type": "object",
2858
+ "additionalProperties": false,
2859
+ "description": "Which Application labels name the service it deploys. The defaults are the Kubernetes recommended labels, the same ones fetch-argocd and fetch-k8s read.",
2860
+ "properties": {
2861
+ "context": {
2862
+ "type": "string",
2863
+ "description": "The label whose value is the bounded context's slug.",
2864
+ "default": "app.kubernetes.io/part-of"
2865
+ },
2866
+ "service": {
2867
+ "type": "string",
2868
+ "description": "The label whose value is the service's slug.",
2869
+ "default": "app.kubernetes.io/name"
2870
+ }
2871
+ }
2872
+ },
2873
+ "out": {
2874
+ "type": "string",
2875
+ "description": "Name of the fragment file, inside the step's output directory.",
2876
+ "default": "argocd.json"
2877
+ }
2878
+ }
2879
+ },
2154
2880
  "options.asyncapi": {
2155
2881
  "type": "object",
2156
2882
  "additionalProperties": false,
@@ -2385,6 +3111,14 @@
2385
3111
  }
2386
3112
  ]
2387
3113
  },
3114
+ "examples": {
3115
+ "type": "integer",
3116
+ "minimum": 0,
3117
+ "description": "How many recordings a flow keeps as examples of itself running: the ones that show the most of it, earliest first. Five when unset; zero keeps none.",
3118
+ "examples": [
3119
+ 3
3120
+ ]
3121
+ },
2388
3122
  "out": {
2389
3123
  "type": "string",
2390
3124
  "description": "Name of the fragment file, inside the step's output directory."
@@ -2674,6 +3408,139 @@
2674
3408
  }
2675
3409
  }
2676
3410
  },
3411
+ "options.k8s-cluster": {
3412
+ "type": "object",
3413
+ "additionalProperties": false,
3414
+ "required": [
3415
+ "cache"
3416
+ ],
3417
+ "properties": {
3418
+ "kubeContext": {
3419
+ "type": "string",
3420
+ "description": "The kubeconfig context to read, passed to kubectl as --context. Left out, kubectl's current context.",
3421
+ "examples": [
3422
+ "prod-eu"
3423
+ ]
3424
+ },
3425
+ "namespaces": {
3426
+ "type": "array",
3427
+ "items": {
3428
+ "type": "string"
3429
+ },
3430
+ "description": "The namespaces to read. Left out, every namespace the credential can list.",
3431
+ "examples": [
3432
+ [
3433
+ "shop",
3434
+ "auth",
3435
+ "payments"
3436
+ ]
3437
+ ]
3438
+ },
3439
+ "labels": {
3440
+ "type": "object",
3441
+ "additionalProperties": false,
3442
+ "description": "Which labels place a workload into the catalog. The defaults are the Kubernetes recommended labels; an estate that labels differently names its own keys here.",
3443
+ "properties": {
3444
+ "context": {
3445
+ "type": "string",
3446
+ "description": "The label whose value is the bounded context's slug.",
3447
+ "default": "app.kubernetes.io/part-of"
3448
+ },
3449
+ "service": {
3450
+ "type": "string",
3451
+ "description": "The label whose value is the service's slug. A workload without it is named after itself.",
3452
+ "default": "app.kubernetes.io/name"
3453
+ }
3454
+ }
3455
+ },
3456
+ "namespaceContexts": {
3457
+ "type": "object",
3458
+ "additionalProperties": {
3459
+ "type": "string"
3460
+ },
3461
+ "description": "Namespace to bounded context, for workloads that carry no context label. A workload with the label keeps it; one with neither is counted in a warning and left out.",
3462
+ "examples": [
3463
+ {
3464
+ "shop": "shop",
3465
+ "shop-jobs": "shop"
3466
+ }
3467
+ ]
3468
+ },
3469
+ "cache": {
3470
+ "type": "string",
3471
+ "description": "Where the last run's fragment was written, repo-relative: the same path as the step's out. An offline run, or one that cannot reach the cluster, replays it unchanged."
3472
+ },
3473
+ "out": {
3474
+ "type": "string",
3475
+ "description": "Name of the fragment file, inside the step's output directory.",
3476
+ "default": "k8s-cluster.json"
3477
+ }
3478
+ }
3479
+ },
3480
+ "options.argocd": {
3481
+ "type": "object",
3482
+ "additionalProperties": false,
3483
+ "required": [
3484
+ "server",
3485
+ "cache"
3486
+ ],
3487
+ "properties": {
3488
+ "server": {
3489
+ "type": "string",
3490
+ "description": "The Argo CD API server: a host, or a URL when it is not https. The token comes from ARGOCD_AUTH_TOKEN, never from here.",
3491
+ "examples": [
3492
+ "argocd.example.com"
3493
+ ]
3494
+ },
3495
+ "projects": {
3496
+ "type": "array",
3497
+ "items": {
3498
+ "type": "string",
3499
+ "minLength": 1
3500
+ },
3501
+ "description": "Argo CD projects to read applications from. Left out, every application the token can list.",
3502
+ "examples": [
3503
+ [
3504
+ "shop",
3505
+ "platform"
3506
+ ]
3507
+ ]
3508
+ },
3509
+ "selector": {
3510
+ "type": "string",
3511
+ "description": "A label selector narrowing the applications, as `argocd app list -l` takes one.",
3512
+ "examples": [
3513
+ "team=shop"
3514
+ ]
3515
+ },
3516
+ "environmentLabel": {
3517
+ "type": "string",
3518
+ "default": "env",
3519
+ "description": "The application label that names the environment. An application without it is placed by the cluster it deploys to."
3520
+ },
3521
+ "labels": {
3522
+ "type": "object",
3523
+ "additionalProperties": false,
3524
+ "description": "Which application labels name the service it deploys. The defaults are the Kubernetes recommended labels, the same ones fetch-k8s reads off a workload; an estate that labels differently names its own keys here. An application without them is placed by the repository and directory it deploys from.",
3525
+ "properties": {
3526
+ "context": {
3527
+ "type": "string",
3528
+ "description": "The label whose value is the bounded context's slug.",
3529
+ "default": "app.kubernetes.io/part-of"
3530
+ },
3531
+ "service": {
3532
+ "type": "string",
3533
+ "description": "The label whose value is the service's slug.",
3534
+ "default": "app.kubernetes.io/name"
3535
+ }
3536
+ }
3537
+ },
3538
+ "cache": {
3539
+ "type": "string",
3540
+ "description": "Where the last run's snapshot was written, repo-relative: the same path as the step's out. An offline run replays what is there and checks it against the lock beside it."
3541
+ }
3542
+ }
3543
+ },
2677
3544
  "options.csr-schemas": {
2678
3545
  "type": "object",
2679
3546
  "additionalProperties": false,