@klok-integration/cli 0.7.302 → 0.7.314

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.
@@ -437,6 +437,34 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
437
437
  THE SOFTWARE.
438
438
  ```
439
439
 
440
+ ## cross-spawn@7.0.6
441
+
442
+ Licence: MIT — https://github.com/moxystudio/node-cross-spawn
443
+
444
+ ```
445
+ The MIT License (MIT)
446
+
447
+ Copyright (c) 2018 Made With MOXY Lda <hello@moxy.studio>
448
+
449
+ Permission is hereby granted, free of charge, to any person obtaining a copy
450
+ of this software and associated documentation files (the "Software"), to deal
451
+ in the Software without restriction, including without limitation the rights
452
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
453
+ copies of the Software, and to permit persons to whom the Software is
454
+ furnished to do so, subject to the following conditions:
455
+
456
+ The above copyright notice and this permission notice shall be included in
457
+ all copies or substantial portions of the Software.
458
+
459
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
460
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
461
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
462
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
463
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
464
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
465
+ THE SOFTWARE.
466
+ ```
467
+
440
468
  ## deepmerge@4.3.1
441
469
 
442
470
  Licence: MIT — https://github.com/TehShrike/deepmerge
@@ -557,6 +585,35 @@ The above copyright notice and this permission notice shall be included in all c
557
585
  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
558
586
  ```
559
587
 
588
+ ## eventsource@3.0.7
589
+
590
+ Licence: MIT — https://github.com/EventSource/eventsource#readme
591
+
592
+ ```
593
+ The MIT License
594
+
595
+ Copyright (c) EventSource GitHub organisation
596
+
597
+ Permission is hereby granted, free of charge, to any person obtaining
598
+ a copy of this software and associated documentation files (the
599
+ "Software"), to deal in the Software without restriction, including
600
+ without limitation the rights to use, copy, modify, merge, publish,
601
+ distribute, sublicense, and/or sell copies of the Software, and to
602
+ permit persons to whom the Software is furnished to do so, subject to
603
+ the following conditions:
604
+
605
+ The above copyright notice and this permission notice shall be
606
+ included in all copies or substantial portions of the Software.
607
+
608
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
609
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
610
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
611
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
612
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
613
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
614
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
615
+ ```
616
+
560
617
  ## eventsource-parser@3.1.1
561
618
 
562
619
  Licence: MIT — https://github.com/rexxars/eventsource-parser#readme
@@ -838,6 +895,28 @@ The above copyright notice and this permission notice shall be included in all c
838
895
  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
839
896
  ```
840
897
 
898
+ ## isexe@2.0.0
899
+
900
+ Licence: ISC — https://github.com/isaacs/isexe#readme
901
+
902
+ ```
903
+ The ISC License
904
+
905
+ Copyright (c) Isaac Z. Schlueter and Contributors
906
+
907
+ Permission to use, copy, modify, and/or distribute this software for any
908
+ purpose with or without fee is hereby granted, provided that the above
909
+ copyright notice and this permission notice appear in all copies.
910
+
911
+ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
912
+ WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
913
+ MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
914
+ ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
915
+ WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
916
+ ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
917
+ IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
918
+ ```
919
+
841
920
  ## jose@6.2.12
842
921
 
843
922
  Licence: MIT — https://github.com/panva/jose
@@ -958,6 +1037,50 @@ The above copyright notice and this permission notice shall be included in all c
958
1037
  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
959
1038
  ```
960
1039
 
1040
+ ## path-key@3.1.1
1041
+
1042
+ Licence: MIT
1043
+
1044
+ ```
1045
+ MIT License
1046
+
1047
+ Copyright (c) Sindre Sorhus <sindresorhus@gmail.com> (sindresorhus.com)
1048
+
1049
+ Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
1050
+
1051
+ The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
1052
+
1053
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
1054
+ ```
1055
+
1056
+ ## pkce-challenge@5.0.1
1057
+
1058
+ Licence: MIT — https://github.com/crouchcd/pkce-challenge#readme
1059
+
1060
+ ```
1061
+ MIT License
1062
+
1063
+ Copyright (c) 2019
1064
+
1065
+ Permission is hereby granted, free of charge, to any person obtaining a copy
1066
+ of this software and associated documentation files (the "Software"), to deal
1067
+ in the Software without restriction, including without limitation the rights
1068
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
1069
+ copies of the Software, and to permit persons to whom the Software is
1070
+ furnished to do so, subject to the following conditions:
1071
+
1072
+ The above copyright notice and this permission notice shall be included in all
1073
+ copies or substantial portions of the Software.
1074
+
1075
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
1076
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
1077
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
1078
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
1079
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
1080
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
1081
+ SOFTWARE.
1082
+ ```
1083
+
961
1084
  ## react@18.3.1
962
1085
 
963
1086
  Licence: MIT — https://reactjs.org/
@@ -1074,6 +1197,38 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
1074
1197
  SOFTWARE.
1075
1198
  ```
1076
1199
 
1200
+ ## shebang-command@2.0.0
1201
+
1202
+ Licence: MIT
1203
+
1204
+ ```
1205
+ MIT License
1206
+
1207
+ Copyright (c) Kevin Mårtensson <kevinmartensson@gmail.com> (github.com/kevva)
1208
+
1209
+ Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
1210
+
1211
+ The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
1212
+
1213
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
1214
+ ```
1215
+
1216
+ ## shebang-regex@3.0.0
1217
+
1218
+ Licence: MIT
1219
+
1220
+ ```
1221
+ MIT License
1222
+
1223
+ Copyright (c) Sindre Sorhus <sindresorhus@gmail.com> (sindresorhus.com)
1224
+
1225
+ Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
1226
+
1227
+ The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
1228
+
1229
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
1230
+ ```
1231
+
1077
1232
  ## signal-exit@3.0.7
1078
1233
 
1079
1234
  Licence: ISC — https://github.com/tapjs/signal-exit
@@ -1190,6 +1345,28 @@ The above copyright notice and this permission notice shall be included in all c
1190
1345
  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
1191
1346
  ```
1192
1347
 
1348
+ ## which@2.0.2
1349
+
1350
+ Licence: ISC — git://github.com/isaacs/node-which.git
1351
+
1352
+ ```
1353
+ The ISC License
1354
+
1355
+ Copyright (c) Isaac Z. Schlueter and Contributors
1356
+
1357
+ Permission to use, copy, modify, and/or distribute this software for any
1358
+ purpose with or without fee is hereby granted, provided that the above
1359
+ copyright notice and this permission notice appear in all copies.
1360
+
1361
+ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
1362
+ WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
1363
+ MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
1364
+ ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
1365
+ WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
1366
+ ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
1367
+ IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
1368
+ ```
1369
+
1193
1370
  ## widest-line@5.0.0
1194
1371
 
1195
1372
  Licence: MIT
@@ -9,13 +9,18 @@ it as the source does.
9
9
  | Klok | The integration platform the documented project runs on (iPaaS): Camel routes on Quarkus, an Apache Pulsar broker, datamodels, and the portal klok.dev |
10
10
  | ODL | Operative Data Layer: the platform's store for datamodel objects, keyed by the object's datamodel type and an id, per tenant; routes write, read and search it (backed by OpenSearch) |
11
11
  | Claim check | A large payload stored in the platform's object storage; the message carries only a reference to it (a `klokcc://` URI) instead of the bytes |
12
- | Broker, topic | Apache Pulsar. A topic is named `persistent://<tenant>[_<env>]/<domain>/<Model>[_<purpose>]` and carries CloudEvents whose data is a datamodel |
12
+ | Broker | The platform's one central Apache Pulsar service, its storage included: the point every system talks to instead of to each other. Klok has no mesh of brokers or sidecars: say the broker |
13
+ | Topic | A named, persisted, ordered log on the broker, `persistent://<tenant>[_<env>]/<domain>/<Model>[_<purpose>]`, owned by the publisher's tenant; it carries CloudEvents whose data is one datamodel. A topic is never called a queue |
14
+ | Subscription | A reader's named cursor on a topic, named after its route id. Its type decides how the topic is read: `exclusive` or `failover` as a stream (one consumer, strict order), `shared` as a queue (competing consumers, each message goes to one of them and the order is given up), `key_shared` as a stream per key (order within a key, parallel across keys). Several subscriptions on one topic each get every message (publish/subscribe) |
13
15
  | CloudEvent | The standard envelope of every broker message: id, type, source, time, and the datamodel as data |
14
- | DLQ | Dead letter queue: `<topic>_DLQ`, where a message goes after its retries are exhausted |
16
+ | DLQ | Dead letter topic `<topic>_DLQ`, where a message goes after its retries are exhausted; it is provisioned with its topic |
15
17
  | Tenant | An organisation on the platform, and its security boundary; every topic, ODL object and GitLab group belongs to one tenant |
16
18
  | Domain | A business area inside a tenant. `common` is shared by the tenant's domains, `public` is open to anyone |
17
19
  | Route, route id | One Camel route per Java class (except a `KlokRestApi`, one per operation, and a `KlokRuntimeInstanceRoute`, one per instance `<RouteId>#<instanceKey>`). Its id is `<TENANTSHORT><NNN><LEG><seq>_<Description>`, for example `KLK007T1_PublishKlokStandard`; the class name is the id |
18
- | Leg | The letter in a route id: I ingress (onramp, brings data in), P processing, E egress (offramp, delivers data out), A API, S sub route, T timer |
20
+ | Leg | The letter in a route id: I ingress, P processing, E egress, A API, S sub route, T timer |
21
+ | Ingress, egress | An ingress is a route that takes a message from outside the platform onto the broker; an egress takes a message off the broker to the outside. An ingress is an onramp or a channel adapter, an egress an offramp or a channel adapter. As a word for a service (`klok-postmark-ingress`) it says what the service is, never a permission |
22
+ | Onramp, offramp | An onramp is an ingress with mapping: the system's own format (class X) becomes a platform model (class A, B or C) before it reaches the broker. An offramp is an egress that maps a platform model to the receiving system's format at the last moment |
23
+ | Channel adapter | An ingress or egress that only converts the protocol (HTTP to the broker, the broker to SFTP); the payload stays as it was received. Good design when it is motivated, for example receiving with minimal handling so that no call is lost while a later leg maps; a system's format put on the broker without such a reason is an anti-pattern |
19
24
  | Tenant short name | `TENANTSHORT`, three upper case letters that start every solution and route id of a tenant: the first three consonants of the tenant's name (`KLK` for klok, `DGR` for degerfors), decided by the platform |
20
25
  | Solution | The business flow a set of routes implements; its id is the route id's prefix, for example `KLK007`. The id is allocated once, by a merge request in the tenant's `integration-solutions` registry, and never reused; a solution is reserved, active or retired |
21
26
  | Solution document | The `README.md` of a solution in the tenant's `integration-solutions` registry: its services, legs and flows, kept true to what is built |
@@ -12,9 +12,20 @@ documentation or the dependency catalog can give you.
12
12
  possible by hand in GitLab.
13
13
  * Systems talk to the broker, never to each other. Point-to-point calls, a shared database or a shared file system
14
14
  between systems are not a Klok design.
15
- * Transform at the edge. When data from one system is to reach other systems or domains, the ingress transforms
16
- it from the system's format to a class C or B model, and the egress transforms it to the receiving system's
15
+ * Ingress and egress are the routes that take messages from outside onto the broker and off the broker to the
16
+ outside. An ingress is an **onramp** (with mapping: system format X to a platform model A, B or C) or a
17
+ **channel adapter** (protocol conversion only, the payload stays as received); an egress is an offramp or a sink
18
+ channel adapter.
19
+ * Transform at the edge. When data from one system is to reach other systems or domains, the onramp transforms
20
+ it from the system's format to a class C or B model, and the offramp transforms it to the receiving system's
17
21
  format at the last moment. Replacing a system then changes only its own ingress and egress.
22
+ * A channel adapter that puts a system's format on the broker is good design when it is motivated: you receive
23
+ with as little handling as possible so that no call from the system is lost, the message waits safely on the
24
+ topic (it can be processed again, or wait for a receiving system that is down), and a later processing leg or
25
+ egress maps it. The solution document says why, which leg maps, and that no other system or domain reads the X
26
+ topic. Example: Postmark inbound mail in KLK006, received by a channel adapter in `klok-postmark-ingress` so that a support mail never bounces while a product is redeployed. Letting class X onto the broker carelessly and without such a
27
+ reason is an anti-pattern and breaks Klok best practice; ask of every ingress "onramp or channel adapter, and
28
+ why?" (https://docs.klok.dev/klok-integration-strategy-and-tactics/platform-2-0/ingress-and-egress/).
18
29
  * Prefer fact events (the whole object) over notifications (an id only).
19
30
  * Hierarchy: tenant (the security boundary; every topic, ODL object and GitLab group belongs to one), then domain
20
31
  (a business area inside the tenant). Domain `common` is shared by the tenant's domains, `public` is open to
@@ -45,7 +56,8 @@ documentation or the dependency catalog can give you.
45
56
  * out of the platform: `KlokOfframpRoute`, `KlokOfframpRouteSync` (serves requests from the broker),
46
57
  `KlokOfframpRouteWithResult`;
47
58
  * on the broker: `KlokProcessingRoute`, `KlokSchemaUpgradeBridge` / `KlokSchemaDowngradeBridge`;
48
- * protocol only, same payload: `KlokChannelAdapterSourceRoute` / `KlokChannelAdapterSinkRoute`;
59
+ * protocol only, the payload as received (a channel adapter, see the principles): `KlokChannelAdapterSourceRoute`
60
+ / `KlokChannelAdapterSinkRoute`;
49
61
  * APIs: `KlokRestApi` with one `KlokRestApiHandlerRoute` per operation; a SOAP API is a `KlokCustomRoute` with
50
62
  camel-cxf; long-running work is a `KlokAsyncTaskWorkerRoute` behind a 202 with a task reference;
51
63
  * everything else: `KlokCustomRoute`; reusable pieces: `KlokSubRoute`, `KlokEnrichSubRoute`.
@@ -99,6 +111,11 @@ documentation or the dependency catalog can give you.
99
111
  When the content belongs to one reader, the publisher may choose that reader's tenant slug as the purpose
100
112
  (`persistent://konvoj/hr/PersonnelScheduleExportV1_degerfors`); that is the publisher's choice, not a condition
101
113
  for reading across tenants.
114
+ * The topic stores, the subscription decides how it is read. A topic is always a persisted, ordered log; whether its
115
+ reader behaves like a stream or a queue is the subscription type (`<RouteId>.subscription.type`): `exclusive`
116
+ (the default) or `failover` read it as a stream in strict order, `shared` as a queue with competing consumers (the
117
+ order is given up), `key_shared` as a stream per message key. Every subscription on a topic gets every message, and
118
+ the framework dead letters to `<topic>_DLQ` whatever the type.
102
119
  * Request/reply: `ReqRes_<Request>_<Reply>[_<purpose>]_Request` and `_Response`. Dead letters: `<topic>_DLQ`.
103
120
  * One datamodel per topic. A breaking change is a new major version and therefore a new topic.
104
121
  * Topics are provisioned from Git; the broker never creates one by itself. A topic exists when its owning tenant's
@@ -14,6 +14,11 @@
14
14
  (?i)class X on the (mesh|broker) # all four datamodel classes may go on the broker; transform at the edge is about readers
15
15
  (?i)class B \(Global\) # class B is "common", shared across the tenant's domains
16
16
  #
17
+ # Klok has one central broker, not a mesh (2026-10-22): say the broker, a topic or a subscription.
18
+ (?i)\b(the|an?|klok|event|events|integration|async|asynchronous|event-driven|message-based|service) mesh\b # Klok has one central broker, not a mesh: say the broker, a topic or a subscription
19
+ (?i)\b(mesh(en|ens|et|ets)|meddelandemesh(en)?|klok-mesh(en|ens)?)\b # Klok har en central broker, ingen mesh: skriv brokern, en topic eller en subscription
20
+ (?i)\bmesh[- ](theory|teori)\b # the chapter is event-driven integration; Klok has one central broker, not a mesh
21
+ #
17
22
  # Route ids are <TENANTSHORT><NNN><LEG><seq>_<Description>, legs I P E A S T.
18
23
  \bS<(NNNN|ID|SolutionID|Solution|NNN)> # old S-prefixed integration ids; use <TENANTSHORT><NNN><LEG><seq>_<Description>
19
24
  \bS[0-9]{4}[IEP][0-9] # old S-prefixed route id such as S0001I1; use KLK002I1_... style ids
@@ -86,7 +86,10 @@ Into the platform:
86
86
  * A webhook sender: `KlokWebhookOnrampRoute`.
87
87
  * The caller needs a full business reply now: `KlokOnrampRouteSync`. Call it coupling and debt, with an aggressive
88
88
  timeout.
89
- * Same payload, protocol only: `KlokChannelAdapterSourceRoute`.
89
+ * Same payload, protocol only: `KlokChannelAdapterSourceRoute`. Either the payload already is the model its readers
90
+ need, or receiving with minimal handling is the point (no call may be lost, the message must wait on the topic
91
+ for a receiver that is down) and a later leg maps. Write the reason in the solution document; a system's format
92
+ let onto the broker without one is the anti-pattern.
90
93
 
91
94
  Out of the platform:
92
95
 
@@ -176,6 +179,13 @@ synchronous bridge, a timeout of about ten seconds, `[TACTICAL]` on the solution
176
179
  the target is down. The strategy-aligned alternative: `KlokOnrampRoute` answering 202 with a task reference, and the
177
180
  front end polling or listening on a websocket. If they keep the bridge, write down the debt and the unwind condition.
178
181
 
182
+ **Postmark inbound mail for five products.** A support mail must not bounce because QuickRace is redeployed or
183
+ down for a day of planned upgrade. Ingress: a channel adapter per account in
184
+ `klok-postmark-ingress` (KLK006): receive the webhook, put the payload on a topic unchanged, answer Postmark once
185
+ the broker has it. An egress per product delivers each message to the right inbox and maps there. The solution
186
+ document names the reason and the mapping leg; no other domain reads the Postmark topic. That is a motivated
187
+ channel adapter, not `[TACTICAL]`.
188
+
179
189
  **"The offramp can just read the CRM database for the e-mail field."** Reject: that couples the offramp to CRM's
180
190
  schema. CRM publishes customer facts; if the e-mail is missing, extend the fact event or add an enricher in
181
191
  processing against a master data API on the platform. No SQL credential crosses a domain boundary.
@@ -30,7 +30,9 @@ Walk it from the top; do not pick a base class from habit.
30
30
  (the egress then owns retries, dead letters and alerts);
31
31
  * a webhook: `KlokWebhookOnrampRoute`;
32
32
  * the caller needs a full business reply now: `KlokOnrampRouteSync`, hard coupling, use rarely;
33
- * the payload already is the model the readers need, protocol only: `KlokChannelAdapterSourceRoute`.
33
+ * protocol only, the payload as received: `KlokChannelAdapterSourceRoute`, when the payload already is the
34
+ model the readers need, or when receiving with minimal handling is the motivated design and a later leg
35
+ maps (see *Channel adapters and APIs*).
34
36
  * Out of the platform:
35
37
  * transform into the target's format: `KlokOfframpRoute`;
36
38
  * same format: `KlokChannelAdapterSinkRoute`;
@@ -175,8 +177,12 @@ its own `retry.*`, `dlq.*` or `failure.*` keys; configure its caller.
175
177
 
176
178
  ## Channel adapters and APIs
177
179
 
178
- A channel adapter is a dumb pipe: the same payload over another protocol, only `fromUri()` and `toUri()`. As soon as
179
- a field is mapped it is an onramp or an offramp.
180
+ A channel adapter only converts the protocol: the same payload over another protocol, only `fromUri()` and
181
+ `toUri()`. As soon as a field is mapped it is an onramp or an offramp. Use a source channel adapter for a system's
182
+ own format only for a reason the solution document states: you must accept every call without losing a message, so
183
+ the route does as little as possible, the message waits on the topic, and a processing leg or the egress maps it
184
+ later (Postmark inbound mail in KLK006). A system's format on the broker without that reason, read by other domains,
185
+ is the anti-pattern the refusals below describe.
180
186
 
181
187
  `KlokRestApi` declares its operations in `get()`, `post()`, `put()` and `delete()`, one `KlokRestApiHandlerRoute`
182
188
  per operation; an operation's route id is `<ApiRouteId>.<verb><path>`. Errors are answered as JSON
@@ -35,6 +35,7 @@ Examples:
35
35
  klok agent plan KLK001 --change-request change.md
36
36
  klok agent serve
37
37
  klok bead report fortnox-egress-1 --status done --message "Merged MR !12"
38
+ klok code # the bundled terminal agent: tools in src/klokcode/, MCP from klokcode.jsonc
38
39
  klok agents init # KLOK-AGENTS.md, harness rows, platform and tenant skills, the session hook
39
40
  klok agents update # fetch the platform and tenant catalogs, write what moved, prune by marker
40
41
  klok agents update --check # exit 5 when a catalog is outdated or missing, write nothing
@@ -600,6 +601,100 @@ Examples:
600
601
  klok ci timings --project "klok/integration/*" --no-logs
601
602
  ```
602
603
 
604
+ ## klok code
605
+
606
+ ```
607
+ klok code [options] [command]
608
+ ```
609
+
610
+ A small coding agent in the terminal: reads a task, calls tools, answers
611
+
612
+ | Option | Description |
613
+ |---|---|
614
+ | `-m, --model <model>` | Model name (default: klokcode.jsonc `model`, then klok config klokerModel) |
615
+ | `--base-url <url>` | OpenAI compatible base URL, without /chat/completions (default: Kloker) |
616
+
617
+ ### klok code run
618
+
619
+ ```
620
+ klok code run [options] <message...>
621
+ ```
622
+
623
+ Send one message, print the answer and exit
624
+
625
+ | Argument | Description |
626
+ |---|---|
627
+ | `<message...>` | required |
628
+
629
+ ### klok code mcp
630
+
631
+ ```
632
+ klok code mcp [options] [command]
633
+ ```
634
+
635
+ Manage the MCP servers of ~/.config/klokcode/klokcode.jsonc, or $XDG_CONFIG_HOME/klokcode/klokcode.jsonc when it is set
636
+
637
+ #### klok code mcp add
638
+
639
+ ```
640
+ klok code mcp add [options] [name] [command...]
641
+ ```
642
+
643
+ Add an MCP server: a remote one with --url, or a local one with the command after --, e.g. `klok code mcp add shop --url http://localhost:4141/mcp` or `klok code mcp add files -- npx -y @modelcontextprotocol/server-filesystem .`. Asks for what is left out.
644
+
645
+ | Argument | Description |
646
+ |---|---|
647
+ | `[name]` | optional |
648
+ | `[command...]` | optional |
649
+
650
+ | Option | Description |
651
+ |---|---|
652
+ | `--url <url>` | URL of a remote MCP server |
653
+ | `--header <KEY=VALUE>` | HTTP header for a remote MCP server (repeatable) |
654
+ | `--env <KEY=VALUE>` | Environment variable for a local MCP server (repeatable) |
655
+
656
+ #### klok code mcp list
657
+
658
+ ```
659
+ klok code mcp list [options]
660
+ ```
661
+
662
+ Connect to every MCP server and list its tools
663
+
664
+ #### klok code mcp remove
665
+
666
+ ```
667
+ klok code mcp remove [options] <name>
668
+ ```
669
+
670
+ Remove an MCP server from the global configuration
671
+
672
+ | Argument | Description |
673
+ |---|---|
674
+ | `<name>` | required |
675
+
676
+ ### klok code demo
677
+
678
+ ```
679
+ klok code demo [options] [command]
680
+ ```
681
+
682
+ Demo services for workshops
683
+
684
+ #### klok code demo shop
685
+
686
+ ```
687
+ klok code demo shop [options]
688
+ ```
689
+
690
+ Start the demo shop: an MCP server with orders and e-mail, and a page showing both (Ctrl+C stops)
691
+
692
+ | Option | Description |
693
+ |---|---|
694
+ | `--port <port>` | Port to listen on (default: `4141`) |
695
+ | `--report-to <address>` | Address the orders ask for reports to be sent to (default: `rapport@extern-redovisning.example`) |
696
+ | `--dry-run` | Log the mail instead of handing it to Postmark |
697
+
603
698
  ## klok datamodel
604
699
 
605
700
  ```
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: klok-route
3
- description: Write or change a Camel route on the Klok Quarkus extension 2.0 (onramp, processing, offramp, REST API handler, async task worker, custom route) with the correct naming, topics and topic purpose, configuration, error handling, tests and klok-docs. Use for any change inside a Klok integration project.
3
+ description: Write or change a Camel route on the Klok Quarkus extension 2.0 (onramp, channel adapter, processing, offramp, REST API handler, async task worker, custom route) with the correct naming, topics and topic purpose, configuration, error handling, tests and klok-docs. Use for any change inside a Klok integration project.
4
4
  ---
5
5
 
6
6
  # Writing a Klok route
@@ -13,8 +13,12 @@ motivates.
13
13
 
14
14
  ## Steps
15
15
 
16
- 1. **Pick the pattern.** Ingress from a system: `KlokOnrampRoute<SYS, DOM>`; transformation between datamodels:
17
- `KlokProcessingRoute<IN, OUT>`; egress to a system: `KlokOfframpRoute<DOM, SYS>`; synchronous request/reply:
16
+ 1. **Pick the pattern.** Ingress from a system: an onramp, `KlokOnrampRoute<SYS, DOM>`, which maps; or a channel
17
+ adapter, `KlokChannelAdapterSourceRoute<MODEL>`, which only converts the protocol, when receiving with minimal
18
+ handling is the motivated design and a later leg maps (the solution document says why; a system's own format
19
+ let onto the broker without a reason is an anti-pattern,
20
+ https://docs.klok.dev/klok-integration-strategy-and-tactics/platform-2-0/ingress-and-egress/); transformation
21
+ between datamodels: `KlokProcessingRoute<IN, OUT>`; egress to a system: `KlokOfframpRoute<DOM, SYS>`; synchronous request/reply:
18
22
  the `Sync` variants; REST: `KlokRestApi` plus one `KlokRestApiHandlerRoute` per operation; long running work:
19
23
  `KlokAsyncTaskWorkerRoute<REQ, RES>`; anything else: `KlokCustomRoute`.
20
24
  2. **Name it.** `<TENANTSHORT><NNN><LEG><seq>_<Description>`, one class per route. `<TENANTSHORT><NNN>` is the id of
@@ -45,7 +45,8 @@ shared platform service) in `klok/integration-solutions`.
45
45
  6. **Classify every service** the solution needs: *new project*, *new routes in an existing project*, *reused,
46
46
  slight change*, *reused as is*, *client change*. Name the repository of each.
47
47
  7. **Map the legs.** For every route: id (`<TENANTSHORT><NNN><LEG><seq>_<Description>`, leg and sequence not used
48
- before — `klok solutions check` reports duplicates), project, pattern base class, topics with their purpose,
48
+ before — `klok solutions check` reports duplicates), project, pattern base class (for an ingress: onramp or
49
+ channel adapter, and why — a channel adapter needs its reason and the leg that maps), topics with their purpose,
49
50
  datamodels and their class, task types, configuration keys, and how the legs interact (diagrams in the flows
50
51
  section). Route configuration and details stay in the project's `klok-docs/`; the solution links there.
51
52
  8. **Choose the technology deliberately.**