@mhome/app-facade-protocol 1.45.0 → 1.46.1

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 (67) hide show
  1. package/README.md +12 -7
  2. package/contract/card-skins-v1.md +138 -0
  3. package/fixtures/actor-link-code-create.request.json +2 -5
  4. package/fixtures/actor-link-code-create.response.json +1 -1
  5. package/fixtures/actor-link-delete.request.json +7 -1
  6. package/fixtures/actor-link-delete.response.json +7 -1
  7. package/fixtures/actor-link-list.request.json +5 -1
  8. package/fixtures/actor-link-list.response.json +18 -1
  9. package/fixtures/authorization/decisions.json +36 -0
  10. package/fixtures/bind-code-create.request.json +5 -0
  11. package/fixtures/{surface-bind-code-create.response.json → bind-code-create.response.json} +1 -1
  12. package/fixtures/binding-list.request.json +5 -0
  13. package/fixtures/binding-list.response.json +18 -0
  14. package/fixtures/card-skins/space.json +79 -0
  15. package/fixtures/identity-code-failed.response.json +1 -2
  16. package/fixtures/identity-code-status.request.json +7 -1
  17. package/fixtures/identity-code-status.response.json +1 -2
  18. package/fixtures/interaction-flow.conformance.json +15 -5
  19. package/fixtures/provider-account-delete.response.json +3 -1
  20. package/fixtures/provider-account-list.request.json +4 -1
  21. package/fixtures/provider-account-status.request.json +4 -1
  22. package/fixtures/provider-account-status.response.json +4 -2
  23. package/fixtures/provider-account-test.request.json +7 -1
  24. package/fixtures/provider-account-test.response.json +5 -1
  25. package/fixtures/provider-account-update.request.json +3 -1
  26. package/fixtures/provider-list.request.json +4 -1
  27. package/fixtures/provider-list.response.json +20 -5
  28. package/fixtures/route-delete.request.json +5 -1
  29. package/fixtures/route-delete.response.json +3 -1
  30. package/fixtures/route-list.request.json +5 -1
  31. package/fixtures/route-list.response.json +4 -3
  32. package/fixtures/route-update.request.json +4 -2
  33. package/fixtures/route-update.response.json +4 -2
  34. package/fixtures/routing/cases.json +450 -0
  35. package/fixtures/setup-options.request.json +4 -1
  36. package/fixtures/setup-options.response.json +5 -1
  37. package/fixtures/setup-start.request.json +3 -1
  38. package/fixtures/setup-start.response.json +3 -1
  39. package/fixtures/setup-status.request.json +5 -1
  40. package/fixtures/shared-account-grant-create.request.json +5 -1
  41. package/fixtures/shared-account-grant-create.response.json +3 -1
  42. package/fixtures/shared-account-grant-delete.request.json +5 -1
  43. package/fixtures/shared-account-grant-delete.response.json +3 -1
  44. package/fixtures/shared-account-grant-list.request.json +5 -1
  45. package/fixtures/shared-account-grant-list.response.json +10 -1
  46. package/fixtures/shared-code-bind-create.request.json +2 -6
  47. package/fixtures/shared-code-link-create.request.json +2 -5
  48. package/fixtures/unbind.request.json +7 -0
  49. package/fixtures/unbind.response.json +7 -0
  50. package/manifest/app-facade.v1.json +52 -2
  51. package/manifest/host-provision-targets.v1.json +1 -1
  52. package/manifest/hub-targets.v1.json +1 -1
  53. package/manifest/pod-targets.v1.json +1 -1
  54. package/manifest/routing.v1.json +19 -37
  55. package/manifest/targets.v1.json +16 -18
  56. package/package.json +1 -1
  57. package/protocol.json +3 -1
  58. package/schema/card-skin-package.v1.schema.json +238 -0
  59. package/schema/card-skins.v1.schema.json +537 -0
  60. package/schema/messaging-frame.v3.schema.json +233 -373
  61. package/schema/routing.v1.schema.json +37 -14
  62. package/fixtures/identity-code-event.response.json +0 -33
  63. package/fixtures/surface-bind-code-create.request.json +0 -9
  64. package/fixtures/surface-dismiss.request.json +0 -1
  65. package/fixtures/surface-dismiss.response.json +0 -1
  66. package/fixtures/surface-list.request.json +0 -1
  67. package/fixtures/surface-list.response.json +0 -1
package/README.md CHANGED
@@ -7,8 +7,9 @@ The package also carries the explicitly private `/local/*` native-daemon
7
7
  extension. `/app/*` is portable and may be routed according to the public
8
8
  routing manifest. `/local/*` is an exact allowlist for the current MeowLink
9
9
  native client process and must never be forwarded to cloud, Hub, or Host
10
- connections. Hub `/app/*` calls are direct-only `FacadeCall`s; Hub `/local/*`
11
- calls carry the domain input directly and never use the public envelope.
10
+ connections. Hub `/app/*` calls use `FacadeCall`, whether delivered directly
11
+ or forwarded by authenticated Cloud ingress. The separate Hub `/local/*`
12
+ protocol carries domain input and never uses the public envelope.
12
13
 
13
14
  Every `/app/*` request uses the strict `FacadeCall` envelope. Invocation
14
15
  metadata lives in `control`; the domain request lives in `input`. The crate
@@ -57,13 +58,17 @@ claim of that Host requires. See [the contract](contract/host-provisioning-v1.md
57
58
 
58
59
  ## Routing contract
59
60
 
60
- `manifest/routing.v1.json` is the canonical client-side routing policy for the
61
+ `manifest/routing.v1.json` is the shared business execution policy for the
61
62
  new `/app/*` facade. Ordinary operations follow the active Space mode. Only
62
63
  exceptional domains declare a fixed Cloud, Hub, or request-placement executor.
63
- Relay permission is separate from execution authority so a client
64
- cannot silently turn every Hub request into a cloud-proxied request.
65
-
66
- The checked-in Rust table is generated from that manifest, and non-Rust clients
64
+ Cloud-capable User Clients may enter through Cloud for registered public control
65
+ operations. Lion resolves the same execution rules before converting domain input,
66
+ and forwards complete Core-owned calls through the authenticated Bridge. Runtime
67
+ connection state, ingress restrictions, authorization, and surface exposure remain
68
+ separate concerns. A transport change never changes business ownership or replays
69
+ a request whose outcome is unknown.
70
+
71
+ The checked-in Rust table is generated from that manifest, and Lion and non-Rust clients
67
72
  consume the same manifest from the npm protocol package. Local Spaces execute
68
73
  Host inventory and management on the selected Hub through `/app/system/hosts/*`.
69
74
  A native Client remains the path when no local Hub is selected. Lion's legacy
@@ -0,0 +1,138 @@
1
+ # Card skins v1
2
+
3
+ These direct App Facade operations manage MeowLink Dashboard skins. They do not
4
+ change device state or expose the application SDK to a skin. `control` remains
5
+ the standard Facade envelope; `input` must match the named definition in
6
+ `schema/card-skins.v1.schema.json`. Responses are JSON. Tenant, Space and caller
7
+ identity come exclusively from authenticated ingress, never from domain input.
8
+
9
+ ## Catalog and publication
10
+
11
+ `/app/card-skins/catalog/*` always executes in Cloud. Catalog reads require a
12
+ User principal. Package creation reserves `packageId` in that tenant. Only the
13
+ stored author may edit its display metadata or publish versions. Authorship is
14
+ immutable. Package lookup is by known package ID; this is not a public marketplace
15
+ or a searchable cross-tenant catalog.
16
+
17
+ | Target suffix | Input definition | Output |
18
+ | --- | --- | --- |
19
+ | `catalog/package/get` | `packageGet` | `{revision, value: {packageId, authorUserId, name, description, createdAt}}` |
20
+ | `catalog/package/create` | `packageCreate` | `{}` |
21
+ | `catalog/package/update` | `packageUpdate` | `{}` |
22
+ | `catalog/release/get` | `releaseGet` | `{id, baseUrl, manifest}` |
23
+ | `catalog/release/list` | `packageGet` | `{releases: [...]}`; ordering is unspecified |
24
+ | `catalog/publish/prepare` | `publishPrepare` | `{uploadId, expiresAt, files: [{path, url, headers}]}` |
25
+ | `catalog/publish/complete` | `publishComplete` | The immutable release |
26
+
27
+ Times are Unix milliseconds. Prepare validates the complete manifest against
28
+ `schema/card-skin-package.v1.schema.json`, its config schemas, paths, file types,
29
+ unique renderer IDs/patterns and inventory. A package has one nonempty bundled
30
+ `.mjs` entry, at most 128 files and 128 renderers, at most 8 MiB per file and 32 MiB
31
+ in total. Metadata documents are limited to 256 KiB UTF-8 JSON. The manifest lists
32
+ only supported asset extensions with their exact media type, size and SHA-256.
33
+ `manifest.json` is reserved. Config schemas are synchronous, self-contained JSON
34
+ Schema draft-07, with only fragment `$ref`s, no `$async`, and at most 64 levels.
35
+ Each config root must have `type: object`.
36
+
37
+ Each prepared session binds one manifest, author and immutable delivery directory.
38
+ It expires after 15 minutes. Upload each file with HTTP PUT to its returned URL
39
+ and the exact returned headers. Upload grants are bearer secrets; only their
40
+ SHA-256 digests are persisted. The server verifies the actual body before writing
41
+ it to a private bucket. S3 conditional create / OSS forbid-overwrite makes each
42
+ verified object immutable; clients never receive an object-store write URL.
43
+ A repeated identical PUT is safe. Different bytes, sizes or media types fail.
44
+
45
+ Complete checks authorship, session expiry and all server-verified immutable
46
+ object receipts before a create-only release write. Missing files never create a
47
+ release. Two sessions racing for the same version have one winner. Retrying the
48
+ winning completion returns that exact release, including after session expiry;
49
+ a different session cannot replace it. Unknown storage outcomes are errors, not
50
+ automatically replayed business operations. Reload the version to resolve them.
51
+ A newer version requires another prepare/upload/complete cycle.
52
+
53
+ Published `baseUrl` is a stable HTTPS directory. GET of a declared file checks the
54
+ published release and its random delivery-directory ID, verifies content integrity,
55
+ and serves the correct media type with CORS, `nosniff`, and immutable caching.
56
+ There is no expiring signed URL in a release. Unpublished files cannot be fetched
57
+ through delivery. A delivery URL is shareable: knowledge of it permits reading
58
+ that release's executable bytes, without granting catalog or upload permissions.
59
+ Do not put secrets in skins. Config values stay in the Space selection.
60
+
61
+ The publication service validates metadata and bytes, not JavaScript behavior.
62
+ The authoring build verifies the bundled ESM structure; the browser host verifies
63
+ renderer exports against the manifest before using them. Skins run in the host's
64
+ JavaScript realm and are not sandboxed by the UI interface. Publication is not a
65
+ claim of a malicious-code audit or cryptographic browser SRI enforcement.
66
+
67
+ ## Space selection
68
+
69
+ These operations execute on the authoritative owner of the Space: Cloud for
70
+ cloud Spaces, Core for local Spaces. Read requires Space read access; mutations
71
+ require Space write access. Agent/MCP surface exposure is separate and is not
72
+ introduced by this contract.
73
+
74
+ | Target suffix | Input definition | Output |
75
+ | --- | --- | --- |
76
+ | `selection/get` | `empty` | `{revision: string|null, selection: {installations, overrides, releases}}` |
77
+ | `install` | `install` | `{}` |
78
+ | `uninstall` | `uninstall` | `{}` |
79
+ | `upgrade` | `upgrade` | `{}` |
80
+ | `override/set` | `overrideSet` | `{}` |
81
+ | `override/reset` | `overrideReset` | `{}` |
82
+
83
+ Every mutation **requires** `expectedRevision`: null means the document has never
84
+ been created; otherwise it must equal the latest read token. A stale token returns
85
+ `PRECONDITION_FAIL` without retry or overwrite. An empty selection can have a
86
+ non-null revision. Mutation responses acknowledge the write; read the selection
87
+ again for its latest state/revision, which may include another writer's edit.
88
+
89
+ Install takes a known package ID and exact version; the service resolves the
90
+ published release from the tenant catalog. Core uses its authenticated cloud
91
+ bridge for that read. Neither accepts client-provided release IDs, manifests or
92
+ URLs. Installation does not automatically enable pattern overrides. Each package
93
+ has one installation per Space; installing another version uses `upgrade`.
94
+
95
+ Set override selects an installed renderer declaring that pattern and validates
96
+ the supplied config against its schema. Reset removes just that pattern's
97
+ override. Uninstall removes the installation, its pinned descriptor and every
98
+ override referencing it in one commit. Reset/uninstall/config edits use local
99
+ pinned metadata; they do not need a live catalog connection.
100
+
101
+ Upgrade keeps the installation ID and all existing overrides. Every affected
102
+ renderer must still exist, declare exactly the same pattern/contract ID/version,
103
+ and accept the existing config. A different catalog identity is never silently
104
+ substituted after Space transfer. Any incompatibility rejects the entire write;
105
+ there is no partial upgrade or implicit config conversion. The user can explicitly
106
+ reset incompatible overrides before switching versions. Successful upgrades
107
+ atomically replace the pinned release while preserving valid overrides.
108
+
109
+ The cloud/SQLite storage contract and `ui/cardSkins` backup category retain
110
+ complete pinned descriptors. They do not cache executable bytes for offline use.
111
+ An installed host still performs its own current-pattern compatibility check;
112
+ publication does not assume every MeowLink client supports the same contracts.
113
+
114
+ ## Deployment and boundaries
115
+
116
+ The cloud service needs a private `card-skins.storage.bucket` on its configured
117
+ AWS/OSS provider and an HTTPS `card-skins.delivery.base-url` reaching the binary
118
+ controller. Object-store credentials must not grant end users overwrite/delete
119
+ access to skin objects. Existing release directories and URLs must be preserved
120
+ across deployment. A trusted reverse proxy/CDN may cache successful delivery;
121
+ upload and error responses are `no-store`.
122
+
123
+ Unfinished publishing sessions expire but their draft records and unreferenced
124
+ objects are currently retained. This version provides no automatic garbage
125
+ collector, package deletion or release deletion. Cleanup must never remove a
126
+ published directory. The App dashboard and Space management page consume these
127
+ endpoints through the existing SDK transport port. The page supports installation,
128
+ pattern selection, configuration, explicit version changes and uninstall. Visible
129
+ clients refresh selection on reconnect, foregrounding and every 30 seconds;
130
+ realtime notifications remain future work. The standalone versioned Card DevKit
131
+ provides project creation, metadata, typed builds, verification, real App preview
132
+ and publication. The MeowLink CLI and Agent/MCP tools expose catalog queries and
133
+ Space installation/override management; the external coding Agent Skill guides
134
+ authoring with the DevKit. Built-in Agent project editing and compilation require
135
+ a future local execution node. These source capabilities require their matching
136
+ published artifacts and deployed services. See the frontend's
137
+ [card guide](../../../../pallas-cat/docs/cards/README.md) for the authoring tools
138
+ and management flow.
@@ -1,8 +1,5 @@
1
1
  {
2
- "target": "/app/messaging/actor/link-code/create",
2
+ "target": "/app/messaging/link/code/create",
3
3
  "direction": "request",
4
- "body": {
5
- "provider": "telegram",
6
- "placement": "local"
7
- }
4
+ "body": {}
8
5
  }
@@ -1,5 +1,5 @@
1
1
  {
2
- "target": "/app/messaging/actor/link-code/create",
2
+ "target": "/app/messaging/link/code/create",
3
3
  "direction": "response",
4
4
  "body": {
5
5
  "challenge": {
@@ -1 +1,7 @@
1
- {"target":"/app/messaging/actor/link/delete","direction":"request","body":{"provider":"telegram","placement":"local","linkId":"link_a"}}
1
+ {
2
+ "target": "/app/messaging/unlink",
3
+ "direction": "request",
4
+ "body": {
5
+ "linkId": "link_a"
6
+ }
7
+ }
@@ -1 +1,7 @@
1
- {"target":"/app/messaging/actor/link/delete","direction":"response","body":{"success":true}}
1
+ {
2
+ "target": "/app/messaging/unlink",
3
+ "direction": "response",
4
+ "body": {
5
+ "success": true
6
+ }
7
+ }
@@ -1 +1,5 @@
1
- {"target":"/app/messaging/actor/link/list","direction":"request","body":{"provider":"telegram","placement":"local","accountId":"bot_a"}}
1
+ {
2
+ "target": "/app/messaging/link/list",
3
+ "direction": "request",
4
+ "body": {}
5
+ }
@@ -1 +1,18 @@
1
- {"target":"/app/messaging/actor/link/list","direction":"response","body":{"links":[{"linkId":"link_a","provider":"telegram","placement":"local","accountId":"bot_a","externalUserId":"user_42","displayName":"Alice","createdAtMs":1720000000000,"updatedAtMs":1720000000000}]}}
1
+ {
2
+ "target": "/app/messaging/link/list",
3
+ "direction": "response",
4
+ "body": {
5
+ "links": [
6
+ {
7
+ "linkId": "link_a",
8
+ "provider": "telegram",
9
+ "placement": "local",
10
+ "accountId": "bot_a",
11
+ "externalUserId": "user_42",
12
+ "displayName": "Alice",
13
+ "createdAtMs": 1720000000000,
14
+ "updatedAtMs": 1720000000000
15
+ }
16
+ ]
17
+ }
18
+ }
@@ -614,5 +614,41 @@
614
614
  "scopeId": "space",
615
615
  "target": "/app/artifact/internal/read",
616
616
  "allowed": false
617
+ },
618
+ {
619
+ "name": "credit-usage:owner",
620
+ "principal": {
621
+ "kind": "user",
622
+ "userId": "owner"
623
+ },
624
+ "memberRole": "OWNER",
625
+ "tenantId": "tenant",
626
+ "scopeId": "space",
627
+ "target": "/app/agent/credit/usage",
628
+ "allowed": true
629
+ },
630
+ {
631
+ "name": "credit-usage:member",
632
+ "principal": {
633
+ "kind": "user",
634
+ "userId": "member"
635
+ },
636
+ "memberRole": "MEMBER",
637
+ "tenantId": "tenant",
638
+ "scopeId": "space",
639
+ "target": "/app/agent/credit/usage",
640
+ "allowed": true
641
+ },
642
+ {
643
+ "name": "credit-usage:nonmember",
644
+ "principal": {
645
+ "kind": "user",
646
+ "userId": "nonmember"
647
+ },
648
+ "memberRole": null,
649
+ "tenantId": "tenant",
650
+ "scopeId": "space",
651
+ "target": "/app/agent/credit/usage",
652
+ "allowed": false
617
653
  }
618
654
  ]
@@ -0,0 +1,5 @@
1
+ {
2
+ "target": "/app/messaging/bind/code/create",
3
+ "direction": "request",
4
+ "body": {}
5
+ }
@@ -1,5 +1,5 @@
1
1
  {
2
- "target": "/app/messaging/surface/bind-code/create",
2
+ "target": "/app/messaging/bind/code/create",
3
3
  "direction": "response",
4
4
  "body": {
5
5
  "challenge": {
@@ -0,0 +1,5 @@
1
+ {
2
+ "target": "/app/messaging/binding/list",
3
+ "direction": "request",
4
+ "body": {}
5
+ }
@@ -0,0 +1,18 @@
1
+ {
2
+ "target": "/app/messaging/binding/list",
3
+ "direction": "response",
4
+ "body": {
5
+ "bindings": [
6
+ {
7
+ "bindingId": "binding",
8
+ "provider": "telegram",
9
+ "placement": "local",
10
+ "accountId": "bot",
11
+ "conversationId": "group",
12
+ "scopeId": "home",
13
+ "displayName": "Family",
14
+ "createdAtMs": 1
15
+ }
16
+ ]
17
+ }
18
+ }
@@ -0,0 +1,79 @@
1
+ {
2
+ "tenantId": "mlink",
3
+ "scopeId": "space-a",
4
+ "selection": {
5
+ "installations": [
6
+ {
7
+ "id": "evening",
8
+ "spaceId": "space-a",
9
+ "releaseId": "mlink:example.evening@1.0.0"
10
+ }
11
+ ],
12
+ "overrides": [
13
+ {
14
+ "spaceId": "space-a",
15
+ "patternId": "basic.device.onoff_brightness_color",
16
+ "installationId": "evening",
17
+ "rendererId": "evening-light",
18
+ "config": {
19
+ "accent": "#c04040"
20
+ }
21
+ }
22
+ ],
23
+ "releases": [
24
+ {
25
+ "id": "mlink:example.evening@1.0.0",
26
+ "baseUrl": "https://skins.example.test/evening/1.0.0/",
27
+ "manifest": {
28
+ "schemaVersion": 1,
29
+ "packageId": "example.evening",
30
+ "version": "1.0.0",
31
+ "name": "Evening cards",
32
+ "description": "Full-card skins for a color light, a playable speaker and a thermostat.",
33
+ "apiVersion": 1,
34
+ "entry": "skin.test.mjs",
35
+ "renderers": [
36
+ {
37
+ "id": "evening-light",
38
+ "name": "Evening light",
39
+ "description": "Example light renderer.",
40
+ "supportedPatterns": [
41
+ {
42
+ "patternId": "basic.device.onoff_brightness_color",
43
+ "contractId": "light",
44
+ "contractVersion": 1
45
+ },
46
+ {
47
+ "patternId": "basic.device.onoff_brightness_colorrgb",
48
+ "contractId": "light",
49
+ "contractVersion": 1
50
+ }
51
+ ],
52
+ "detail": {
53
+ "mode": "custom"
54
+ },
55
+ "configSchema": {
56
+ "type": "object",
57
+ "properties": {
58
+ "accent": {
59
+ "type": "string",
60
+ "pattern": "^#[0-9a-fA-F]{6}$"
61
+ }
62
+ },
63
+ "additionalProperties": false
64
+ }
65
+ }
66
+ ],
67
+ "files": [
68
+ {
69
+ "path": "skin.test.mjs",
70
+ "mediaType": "text/javascript",
71
+ "sizeBytes": 1,
72
+ "sha256": "0000000000000000000000000000000000000000000000000000000000000000"
73
+ }
74
+ ]
75
+ }
76
+ }
77
+ ]
78
+ }
79
+ }
@@ -1,11 +1,10 @@
1
1
  {
2
- "target": "/app/messaging/identity-code/status",
2
+ "target": "/app/messaging/code/status",
3
3
  "direction": "response",
4
4
  "body": {
5
5
  "status": {
6
6
  "challengeId": "challenge_01",
7
7
  "provider": "telegram",
8
- "placement": "local",
9
8
  "accountId": "bot_a",
10
9
  "expiresAtMs": 1720000300000,
11
10
  "lifecycle": {
@@ -1 +1,7 @@
1
- {"target":"/app/messaging/identity-code/status","direction":"request","body":{"provider":"telegram","placement":"local","challengeId":"challenge_01"}}
1
+ {
2
+ "target": "/app/messaging/code/status",
3
+ "direction": "request",
4
+ "body": {
5
+ "challengeId": "challenge_01"
6
+ }
7
+ }
@@ -1,11 +1,10 @@
1
1
  {
2
- "target": "/app/messaging/identity-code/status",
2
+ "target": "/app/messaging/code/status",
3
3
  "direction": "response",
4
4
  "body": {
5
5
  "status": {
6
6
  "challengeId": "challenge_01",
7
7
  "provider": "telegram",
8
- "placement": "local",
9
8
  "accountId": "bot_a",
10
9
  "expiresAtMs": 1720000300000,
11
10
  "lifecycle": {
@@ -12,15 +12,21 @@
12
12
  "sessionId": "session-1",
13
13
  "commandId": "command-1",
14
14
  "expectedRevision": 1,
15
- "input": { "$host": "192.0.2.1" },
16
- "vars": ["$cameras"],
15
+ "input": {
16
+ "$host": "192.0.2.1"
17
+ },
18
+ "vars": [
19
+ "$cameras"
20
+ ],
17
21
  "force": false
18
22
  },
19
23
  "transitionRequest": {
20
24
  "sessionId": "session-1",
21
25
  "commandId": "command-2",
22
26
  "expectedRevision": 2,
23
- "input": { "$camera": "camera-1" }
27
+ "input": {
28
+ "$camera": "camera-1"
29
+ }
24
30
  },
25
31
  "completeRequest": {
26
32
  "sessionId": "session-1",
@@ -62,7 +68,11 @@
62
68
  },
63
69
  "completeResponse": {
64
70
  "completed": true,
65
- "result": { "providerConnectionId": "provider-1" }
71
+ "result": {
72
+ "providerConnectionId": "provider-1"
73
+ }
66
74
  },
67
- "cancelResponse": { "cancelled": true }
75
+ "cancelResponse": {
76
+ "cancelled": true
77
+ }
68
78
  }
@@ -1,5 +1,7 @@
1
1
  {
2
2
  "target": "/app/messaging/provider-account/delete",
3
3
  "direction": "response",
4
- "body": { "success": true }
4
+ "body": {
5
+ "success": true
6
+ }
5
7
  }
@@ -1,5 +1,8 @@
1
1
  {
2
2
  "target": "/app/messaging/provider-account/list",
3
3
  "direction": "request",
4
- "body": { "provider": "telegram", "placement": "local" }
4
+ "body": {
5
+ "provider": "telegram",
6
+ "placement": "local"
7
+ }
5
8
  }
@@ -1,5 +1,8 @@
1
1
  {
2
2
  "target": "/app/messaging/provider-account/status",
3
3
  "direction": "request",
4
- "body": { "provider": "telegram", "placement": "local" }
4
+ "body": {
5
+ "provider": "telegram",
6
+ "placement": "local"
7
+ }
5
8
  }
@@ -4,9 +4,11 @@
4
4
  "body": {
5
5
  "status": {
6
6
  "provider": "telegram",
7
- "placement": "local",
8
7
  "enabled": true,
9
- "providerData": { "connected": 1 }
8
+ "providerData": {
9
+ "connected": 1
10
+ },
11
+ "placement": "local"
10
12
  }
11
13
  }
12
14
  }
@@ -1,5 +1,11 @@
1
1
  {
2
2
  "target": "/app/messaging/provider-account/test",
3
3
  "direction": "request",
4
- "body": { "provider": "telegram", "placement": "local", "data": { "botToken": "secret" } }
4
+ "body": {
5
+ "provider": "telegram",
6
+ "placement": "local",
7
+ "data": {
8
+ "botToken": "secret"
9
+ }
10
+ }
5
11
  }
@@ -1,5 +1,9 @@
1
1
  {
2
2
  "target": "/app/messaging/provider-account/test",
3
3
  "direction": "response",
4
- "body": { "result": { "reachable": true } }
4
+ "body": {
5
+ "result": {
6
+ "reachable": true
7
+ }
8
+ }
5
9
  }
@@ -5,6 +5,8 @@
5
5
  "provider": "telegram",
6
6
  "placement": "local",
7
7
  "accountId": "123456",
8
- "data": { "enabled": true }
8
+ "data": {
9
+ "enabled": true
10
+ }
9
11
  }
10
12
  }
@@ -7,7 +7,10 @@
7
7
  {
8
8
  "provider": "telegram",
9
9
  "deprecated": false,
10
- "supportedPlacements": ["cloud", "local"]
10
+ "supportedPlacements": [
11
+ "cloud",
12
+ "local"
13
+ ]
11
14
  }
12
15
  ]
13
16
  }
@@ -10,13 +10,28 @@
10
10
  "deprecated": false,
11
11
  "available": true,
12
12
  "setupFlow": "pairing_code",
13
- "audiences": ["personal", "shared"],
14
- "inboundCapabilities": ["text", "audio", "action"],
15
- "outboundCapabilities": ["text", "markdown", "action"],
13
+ "audiences": [
14
+ "personal",
15
+ "shared"
16
+ ],
17
+ "inboundCapabilities": [
18
+ "text",
19
+ "audio",
20
+ "action"
21
+ ],
22
+ "outboundCapabilities": [
23
+ "text",
24
+ "markdown",
25
+ "action"
26
+ ],
16
27
  "deliveryMode": "unrestricted",
17
28
  "projections": {
18
- "notification": { "supported": true },
19
- "dialog": { "supported": true }
29
+ "notification": {
30
+ "supported": true
31
+ },
32
+ "dialog": {
33
+ "supported": true
34
+ }
20
35
  },
21
36
  "managementOperations": [
22
37
  "provider_account.list",
@@ -1,5 +1,9 @@
1
1
  {
2
2
  "target": "/app/messaging/route/delete",
3
3
  "direction": "request",
4
- "body": { "provider": "telegram", "placement": "cloud", "routeId": "route-1" }
4
+ "body": {
5
+ "provider": "telegram",
6
+ "placement": "cloud",
7
+ "routeId": "route-2"
8
+ }
5
9
  }
@@ -1,5 +1,7 @@
1
1
  {
2
2
  "target": "/app/messaging/route/delete",
3
3
  "direction": "response",
4
- "body": { "success": true }
4
+ "body": {
5
+ "success": true
6
+ }
5
7
  }
@@ -1,5 +1,9 @@
1
1
  {
2
2
  "target": "/app/messaging/route/list",
3
3
  "direction": "request",
4
- "body": { "provider": "telegram", "placement": "cloud", "audience": "personal" }
4
+ "body": {
5
+ "provider": "telegram",
6
+ "placement": "cloud",
7
+ "audience": "personal"
8
+ }
5
9
  }