@mhome/app-facade-protocol 1.62.0 → 1.64.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.
package/README.md CHANGED
@@ -73,7 +73,10 @@ App UI requests full and unwraps the envelope at its transport boundary. Agent
73
73
  and MCP public results use essential; internal workflow reads use full. The CLI
74
74
  uses `--response-detail full|essential`, and the bundled external Skill requests
75
75
  essential. Dashboard essential projection keeps card identity, title, type,
76
- layouts and view choices, excluding renderer configuration and resource payloads.
76
+ view choices, excluding renderer configuration and resource payloads. Card list
77
+ returns only ID/type/title; card detail essential omits layouts. Canvas layout get
78
+ requires one sm/md/lg size and retains every card ID/title/layout in full and essential;
79
+ uninitialized layouts or coordinates are null.
77
80
  Device brief-list essential retains identity, room, capability IDs, Integration and
78
81
  availability, omitting `connectId`, `manufacturerId` and `manufacturerName`.
79
82
  Selected Device detail, history, recent activity and mutation outcomes keep their
@@ -96,6 +99,10 @@ asset manifests and renderer configuration schemas. Selected release detail keep
96
99
  Revisions, installation IDs, existing override config and supported patterns remain.
97
100
  Empty mutation acknowledgements remain empty; they do not invent a new revision.
98
101
 
102
+ Room uses one `/app/room/list` read. Every Room has `roomId`, `roomName`,
103
+ `index`, `deviceCount`, and `deviceIds`; full and essential keep all five fields.
104
+ Membership IDs include Device groups without expanding their members or state.
105
+
99
106
  Targets without a dedicated projection retain their business fields in YAML;
100
107
  essential does not promise a smaller field set for every domain. Targets own that selection.
101
108
 
@@ -0,0 +1,22 @@
1
+ # Entity UI presentation
2
+
3
+ `/app/entity/presentation/get` is a read-only App Facade for the UI. Its direct
4
+ input is `{entityType, entityId}`; tenant, Space and caller come from authenticated
5
+ context. It requires Space read access. It is not an Agent or MCP catalog entry.
6
+
7
+ The successful data object contains `entityEntry`, nullable `entityCard`, and
8
+ `twinAutomations`. The entry and card reuse the existing UI renderer models;
9
+ the schema owns this boundary without duplicating their nested widget/runtime
10
+ contracts. A missing, deleted or differently typed Twin is not found. Device
11
+ presentation reads reuse the device manager; other Twin entities reuse the general
12
+ manager. Ordinary Entity business detail and Group detail retain their own APIs.
13
+
14
+ Device card assembly is best effort. An absent card is `null`, with an empty
15
+ association list. Association-read failures retain the existing execution policy:
16
+ local Core returns an empty list; cloud propagates the error. No writes or repairs
17
+ are performed. Current Twin states still have their separate read/subscription.
18
+
19
+ UI uses `control: {mode: "direct", responseDetail: "full"}` and receives the shared
20
+ `{status: "success", data: ...}` envelope. The generic essential projection returns
21
+ `{status: "success", text: ...}` with the same business fields rendered as YAML;
22
+ there is no domain field reduction. This is not the compact business detail API.
@@ -13,11 +13,11 @@ bridge. A cloud Space composes it in cloud. LLM placement does not change this
13
13
  owner. Cloud entrypoints forward local-Space business to Core; only an unavailable
14
14
  Hub transport permits the explicit read-only registration fallback below.
15
15
 
16
- The result contains `pods`, `scopeId`, `observedAtMs`, and `sourceErrors`.
16
+ The result contains `pods`, `spaceId`, `observedAtMs`, and `sourceErrors`.
17
17
  Every row contains `registrationId`, `clientMode` (`user` or `space`), `registered`
18
- (true), and `connection` with `scopeId`, `state` (`connected`, `disconnected`, or
18
+ (true), and `connection` with `spaceId`, `state` (`connected`, `disconnected`, or
19
19
  `unknown`), and `source` (`hub`, `cloud`, or `unavailable`). Space rows also contain
20
- `scopeId` and `appClientId`. Personal rows contain the saved `name`, `deviceId`,
20
+ `spaceId` and `appClientId`. Personal rows contain the saved `name`, `deviceId`,
21
21
  `model`, `platform`, `firmwareVersion`, `issuedAt`, and `activatedAt`.
22
22
  No tokens, enrollment grants, credential IDs or private keys are returned.
23
23
 
@@ -9,7 +9,7 @@
9
9
  "placement": "local",
10
10
  "accountId": "bot",
11
11
  "conversationId": "group",
12
- "scopeId": "home",
12
+ "spaceId": "home",
13
13
  "displayName": "Family",
14
14
  "createdAtMs": 1
15
15
  }
@@ -0,0 +1,54 @@
1
+ {
2
+ "input": {
3
+ "valid": [
4
+ {
5
+ "entityType": "basic.device.Device",
6
+ "entityId": "device-1"
7
+ }
8
+ ],
9
+ "invalid": [
10
+ {},
11
+ {
12
+ "entityType": " ",
13
+ "entityId": "device-1"
14
+ },
15
+ {
16
+ "entityType": "basic.device.Device",
17
+ "entityId": ""
18
+ },
19
+ {
20
+ "entityType": "basic.device.Device",
21
+ "entityId": "device-1",
22
+ "scopeId": "other"
23
+ }
24
+ ]
25
+ },
26
+ "output": {
27
+ "valid": [
28
+ {
29
+ "entityEntry": {
30
+ "uid": "device-1",
31
+ "type": "basic.device.Device",
32
+ "integration": "example.device",
33
+ "name": "Desk lamp",
34
+ "active": false,
35
+ "data": {},
36
+ "capabilities": [],
37
+ "twinTags": [],
38
+ "cardCount": 0,
39
+ "issue": false
40
+ },
41
+ "entityCard": null,
42
+ "twinAutomations": []
43
+ }
44
+ ],
45
+ "invalid": [
46
+ {},
47
+ {
48
+ "entityEntry": null,
49
+ "entityCard": null,
50
+ "twinAutomations": []
51
+ }
52
+ ]
53
+ }
54
+ }
@@ -1,5 +1,5 @@
1
1
  {
2
- "scopeId": "scope-1",
2
+ "spaceId": "scope-1",
3
3
  "configured": true,
4
4
  "hub": {
5
5
  "id": "hub-1",
@@ -1,5 +1,5 @@
1
1
  {
2
- "scopeId": "scope-1",
2
+ "spaceId": "scope-1",
3
3
  "configured": false,
4
4
  "operation": {
5
5
  "kind": "REMOVE",
@@ -80,24 +80,28 @@
80
80
  }
81
81
  },
82
82
  {
83
- "name": "brief-does-not-invent-view-count",
83
+ "name": "dashboard card list is a compact summary",
84
84
  "target": "/app/dashboard/card/list",
85
85
  "data": {
86
+ "spaceId": "space-1",
87
+ "canvasId": "canvas-1",
86
88
  "cards": [
87
89
  {
88
90
  "cardId": "card-1",
89
- "type": "entity",
90
- "title": "Lamp"
91
+ "type": "WIDGET",
92
+ "title": "Power"
91
93
  }
92
94
  ]
93
95
  },
94
96
  "status": "success",
95
97
  "essential": {
98
+ "spaceId": "space-1",
99
+ "canvasId": "canvas-1",
96
100
  "cards": [
97
101
  {
98
102
  "cardId": "card-1",
99
- "type": "entity",
100
- "title": "Lamp"
103
+ "type": "WIDGET",
104
+ "title": "Power"
101
105
  }
102
106
  ]
103
107
  }
@@ -183,13 +187,13 @@
183
187
  "id": "a1",
184
188
  "name": "Morning",
185
189
  "description": "Turn on light",
186
- "type": "TASK_FLOW",
187
190
  "enabled": true,
188
191
  "singleUse": false,
189
192
  "createdAt": 1,
190
193
  "tags": [
191
194
  "internal"
192
- ]
195
+ ],
196
+ "automationType": "TASK_FLOW"
193
197
  }
194
198
  ]
195
199
  },
@@ -199,9 +203,9 @@
199
203
  "id": "a1",
200
204
  "name": "Morning",
201
205
  "description": "Turn on light",
202
- "type": "TASK_FLOW",
203
206
  "enabled": true,
204
- "singleUse": false
207
+ "singleUse": false,
208
+ "automationType": "TASK_FLOW"
205
209
  }
206
210
  ]
207
211
  }
@@ -216,14 +220,12 @@
216
220
  "id": "a1",
217
221
  "name": "Morning",
218
222
  "description": "Turn on light",
219
- "type": "TASK_FLOW",
220
223
  "enabled": true,
221
224
  "singleUse": false,
222
225
  "hasExpire": false,
223
226
  "usedCapabilities": [
224
227
  "light.command.on"
225
228
  ],
226
- "memberIds": [],
227
229
  "inputVars": [
228
230
  {
229
231
  "name": "$room",
@@ -239,7 +241,8 @@
239
241
  }
240
242
  },
241
243
  "updatedAt": 2,
242
- "descriptionTemplate": "Turn on {! $room !}"
244
+ "descriptionTemplate": "Turn on {! $room !}",
245
+ "automationType": "TASK_FLOW"
243
246
  }
244
247
  ]
245
248
  },
@@ -249,14 +252,12 @@
249
252
  "id": "a1",
250
253
  "name": "Morning",
251
254
  "description": "Turn on light",
252
- "type": "TASK_FLOW",
253
255
  "enabled": true,
254
256
  "singleUse": false,
255
257
  "hasExpire": false,
256
258
  "usedCapabilities": [
257
259
  "light.command.on"
258
260
  ],
259
- "memberIds": [],
260
261
  "inputVars": [
261
262
  {
262
263
  "name": "$room",
@@ -265,7 +266,8 @@
265
266
  }
266
267
  ],
267
268
  "scriptHash": "source-hash",
268
- "descriptionTemplate": "Turn on {! $room !}"
269
+ "descriptionTemplate": "Turn on {! $room !}",
270
+ "automationType": "TASK_FLOW"
269
271
  }
270
272
  ]
271
273
  }
@@ -280,8 +282,8 @@
280
282
  "automationId": "a1",
281
283
  "automationName": "Morning",
282
284
  "automationType": "TASK_FLOW",
283
- "origin": "RECURRING",
284
- "description": "duplicate"
285
+ "description": "duplicate",
286
+ "singleUse": false
285
287
  }
286
288
  ]
287
289
  },
@@ -291,7 +293,7 @@
291
293
  "automationId": "a1",
292
294
  "automationName": "Morning",
293
295
  "automationType": "TASK_FLOW",
294
- "origin": "RECURRING"
296
+ "singleUse": false
295
297
  }
296
298
  ]
297
299
  }
@@ -309,35 +311,31 @@
309
311
  "automationId": "a1",
310
312
  "automationName": "Morning",
311
313
  "automationType": "TASK_FLOW",
312
- "origin": "RECURRING",
313
314
  "activityType": "RUN_FAILED",
314
315
  "timestamp": 100,
315
316
  "instanceId": "run",
316
317
  "threadId": 0,
317
- "error": true,
318
- "panic": false,
319
318
  "actorUserId": "user",
320
319
  "clientId": "client",
321
- "description": "duplicate"
320
+ "description": "duplicate",
321
+ "singleUse": false
322
322
  }
323
323
  ]
324
324
  },
325
325
  "essential": {
326
326
  "since": "10min",
327
327
  "from": 0,
328
- "until": 100,
328
+ "until": "1970-01-01 00:00:00 +00:00 (UTC)",
329
329
  "activities": [
330
330
  {
331
331
  "automationId": "a1",
332
332
  "automationName": "Morning",
333
333
  "automationType": "TASK_FLOW",
334
- "origin": "RECURRING",
335
334
  "activityType": "RUN_FAILED",
336
- "timestamp": 100,
335
+ "timestamp": "1970-01-01 00:00:00 +00:00 (UTC)",
337
336
  "instanceId": "run",
338
337
  "threadId": 0,
339
- "error": true,
340
- "panic": false
338
+ "singleUse": false
341
339
  }
342
340
  ]
343
341
  }
@@ -377,7 +375,7 @@
377
375
  "name": "Morning",
378
376
  "threadId": 0,
379
377
  "instanceId": "run",
380
- "timestamp": 100,
378
+ "timestamp": "1970-01-01 00:00:00 +00:00 (UTC)",
381
379
  "status": "failed",
382
380
  "reportMode": "STD",
383
381
  "logCount": 2,
@@ -437,7 +435,7 @@
437
435
  "name": "Morning",
438
436
  "threadId": 0,
439
437
  "instanceId": "run",
440
- "timestamp": 100,
438
+ "timestamp": "1970-01-01 00:00:00 +00:00 (UTC)",
441
439
  "status": "failed",
442
440
  "reportMode": "STD",
443
441
  "logCount": 2,
@@ -449,8 +447,8 @@
449
447
  "code": "TIMEOUT"
450
448
  },
451
449
  "revision": 3,
452
- "startedAt": 90,
453
- "finishedAt": 100
450
+ "startedAt": "1970-01-01 00:00:00 +00:00 (UTC)",
451
+ "finishedAt": "1970-01-01 00:00:00 +00:00 (UTC)"
454
452
  },
455
453
  "logs": [
456
454
  {
@@ -478,10 +476,10 @@
478
476
  "snapshotId": "v1",
479
477
  "createdAt": 90,
480
478
  "description": "Prior behavior",
481
- "type": "TASK_FLOW",
482
479
  "script": {
483
480
  "script": "private"
484
- }
481
+ },
482
+ "automationType": "TASK_FLOW"
485
483
  }
486
484
  ]
487
485
  },
@@ -490,79 +488,9 @@
490
488
  "snapshots": [
491
489
  {
492
490
  "snapshotId": "v1",
493
- "createdAt": 90,
491
+ "createdAt": "1970-01-01 00:00:00 +00:00 (UTC)",
494
492
  "description": "Prior behavior",
495
- "type": "TASK_FLOW"
496
- }
497
- ]
498
- }
499
- },
500
- {
501
- "name": "dashboard card list retains canvas layout",
502
- "target": "/app/dashboard/card/brief/list",
503
- "status": "success",
504
- "data": {
505
- "canvasId": "canvas",
506
- "cards": [
507
- {
508
- "cardId": "card-1",
509
- "type": "widget",
510
- "title": "Power",
511
- "layouts": {
512
- "sm": {
513
- "x": 0,
514
- "y": 0,
515
- "width": 2,
516
- "height": 2
517
- }
518
- },
519
- "views": [
520
- {
521
- "id": "power",
522
- "name": "Power",
523
- "source": {
524
- "type": "widget",
525
- "baseId": "automation-1",
526
- "widgetId": "widget-1"
527
- },
528
- "pattern": "default"
529
- }
530
- ],
531
- "primaryViewId": "power",
532
- "widgets": [
533
- {
534
- "widgetId": "widget-1",
535
- "name": "Power",
536
- "widgetType": "DATA",
537
- "dataType": "NUMBER"
538
- }
539
- ]
540
- }
541
- ]
542
- },
543
- "essential": {
544
- "canvasId": "canvas",
545
- "cards": [
546
- {
547
- "cardId": "card-1",
548
- "type": "widget",
549
- "title": "Power",
550
- "primaryViewId": "power",
551
- "views": [
552
- {
553
- "id": "power",
554
- "name": "Power"
555
- }
556
- ],
557
- "viewCount": 1,
558
- "layouts": {
559
- "sm": {
560
- "x": 0,
561
- "y": 0,
562
- "width": 2,
563
- "height": 2
564
- }
565
- }
493
+ "automationType": "TASK_FLOW"
566
494
  }
567
495
  ]
568
496
  }
@@ -879,29 +807,29 @@
879
807
  "status": "success",
880
808
  "essential": {
881
809
  "since": "10min",
882
- "from": 1793065800000,
883
- "until": 1793066400000,
810
+ "from": "2026-10-27 01:50:00 +00:00 (UTC)",
811
+ "until": "2026-10-27 02:00:00 +00:00 (UTC)",
884
812
  "truncated": true,
885
813
  "updates": [
886
814
  {
887
815
  "deviceId": "d1",
888
816
  "deviceName": "Lamp",
889
817
  "capabilityId": "state.onOff",
890
- "changedAt": 1793066400000,
818
+ "changedAt": "2026-10-27 02:00:00 +00:00 (UTC)",
891
819
  "state": false
892
820
  },
893
821
  {
894
822
  "deviceId": "d2",
895
823
  "deviceName": "Dimmer",
896
824
  "capabilityId": "state.level",
897
- "changedAt": 1793066399000,
825
+ "changedAt": "2026-10-27 01:59:59 +00:00 (UTC)",
898
826
  "state": 0
899
827
  },
900
828
  {
901
829
  "deviceId": "d3",
902
830
  "deviceName": "Button",
903
831
  "capabilityId": "event.click",
904
- "changedAt": 1793066398000,
832
+ "changedAt": "2026-10-27 01:59:58 +00:00 (UTC)",
905
833
  "event": {
906
834
  "value": null
907
835
  }
@@ -910,7 +838,7 @@
910
838
  "deviceId": "d4",
911
839
  "deviceName": "Lamp",
912
840
  "capabilityId": "command.onOff",
913
- "changedAt": 1793066397000,
841
+ "changedAt": "2026-10-27 01:59:57 +00:00 (UTC)",
914
842
  "log": {
915
843
  "source": "Automation",
916
844
  "data": {
@@ -1278,7 +1206,7 @@
1278
1206
  "name": "hub-unconfigured",
1279
1207
  "target": "/app/hub/get",
1280
1208
  "data": {
1281
- "scopeId": "space-demo",
1209
+ "spaceId": "space-demo",
1282
1210
  "configured": false,
1283
1211
  "hub": null,
1284
1212
  "operation": null,
@@ -1286,7 +1214,7 @@
1286
1214
  },
1287
1215
  "status": "success",
1288
1216
  "essential": {
1289
- "scopeId": "space-demo",
1217
+ "spaceId": "space-demo",
1290
1218
  "configured": false,
1291
1219
  "hub": null,
1292
1220
  "operation": null,
@@ -1312,7 +1240,7 @@
1312
1240
  "name": "pod-directory-unknown",
1313
1241
  "target": "/app/pod/list",
1314
1242
  "data": {
1315
- "scopeId": "space-demo",
1243
+ "spaceId": "space-demo",
1316
1244
  "observedAtMs": 1800000000000,
1317
1245
  "pods": [
1318
1246
  {
@@ -1327,7 +1255,7 @@
1327
1255
  "issuedAt": 1800000000000,
1328
1256
  "activatedAt": 1800000001000,
1329
1257
  "connection": {
1330
- "scopeId": null,
1258
+ "spaceId": null,
1331
1259
  "state": "unknown",
1332
1260
  "source": "unavailable"
1333
1261
  }
@@ -1339,7 +1267,7 @@
1339
1267
  },
1340
1268
  "status": "success",
1341
1269
  "essential": {
1342
- "scopeId": "space-demo",
1270
+ "spaceId": "space-demo",
1343
1271
  "observedAtMs": 1800000000000,
1344
1272
  "pods": [
1345
1273
  {
@@ -1354,7 +1282,7 @@
1354
1282
  "issuedAt": 1800000000000,
1355
1283
  "activatedAt": 1800000001000,
1356
1284
  "connection": {
1357
- "scopeId": null,
1285
+ "spaceId": null,
1358
1286
  "state": "unknown",
1359
1287
  "source": "unavailable"
1360
1288
  }
@@ -3284,5 +3212,129 @@
3284
3212
  "essential": {
3285
3213
  "llmMode": "local"
3286
3214
  }
3215
+ },
3216
+ {
3217
+ "name": "room-list-complete-membership",
3218
+ "target": "/app/room/list",
3219
+ "data": {
3220
+ "rooms": [
3221
+ {
3222
+ "roomId": "r1",
3223
+ "roomName": "Living",
3224
+ "index": 0,
3225
+ "deviceCount": 2,
3226
+ "deviceIds": [
3227
+ "d1",
3228
+ "g:1"
3229
+ ]
3230
+ },
3231
+ {
3232
+ "roomId": "r2",
3233
+ "roomName": "Empty",
3234
+ "index": 1,
3235
+ "deviceCount": 0,
3236
+ "deviceIds": []
3237
+ }
3238
+ ]
3239
+ },
3240
+ "status": "success",
3241
+ "essential": {
3242
+ "rooms": [
3243
+ {
3244
+ "roomId": "r1",
3245
+ "roomName": "Living",
3246
+ "index": 0,
3247
+ "deviceCount": 2,
3248
+ "deviceIds": [
3249
+ "d1",
3250
+ "g:1"
3251
+ ]
3252
+ },
3253
+ {
3254
+ "roomId": "r2",
3255
+ "roomName": "Empty",
3256
+ "index": 1,
3257
+ "deviceCount": 0,
3258
+ "deviceIds": []
3259
+ }
3260
+ ]
3261
+ }
3262
+ },
3263
+ {
3264
+ "name": "room-list-empty",
3265
+ "target": "/app/room/list",
3266
+ "data": {
3267
+ "rooms": []
3268
+ },
3269
+ "status": "success",
3270
+ "essential": {
3271
+ "rooms": []
3272
+ }
3273
+ },
3274
+ {
3275
+ "name": "dashboard layout get stored and missing layouts",
3276
+ "target": "/app/dashboard/canvas/layout/get",
3277
+ "status": "success",
3278
+ "data": {
3279
+ "spaceId": "space-1",
3280
+ "canvasId": "canvas-1",
3281
+ "layoutSize": "md",
3282
+ "cards": [
3283
+ {
3284
+ "cardId": "card-1",
3285
+ "title": "Power",
3286
+ "layout": {
3287
+ "x": 0,
3288
+ "y": 1,
3289
+ "width": 2,
3290
+ "height": 2
3291
+ }
3292
+ },
3293
+ {
3294
+ "cardId": "card-2",
3295
+ "title": "Unpositioned",
3296
+ "layout": null
3297
+ }
3298
+ ]
3299
+ },
3300
+ "essential": {
3301
+ "spaceId": "space-1",
3302
+ "canvasId": "canvas-1",
3303
+ "layoutSize": "md",
3304
+ "cards": [
3305
+ {
3306
+ "cardId": "card-1",
3307
+ "title": "Power",
3308
+ "layout": {
3309
+ "x": 0,
3310
+ "y": 1,
3311
+ "width": 2,
3312
+ "height": 2
3313
+ }
3314
+ },
3315
+ {
3316
+ "cardId": "card-2",
3317
+ "title": "Unpositioned",
3318
+ "layout": null
3319
+ }
3320
+ ]
3321
+ }
3322
+ },
3323
+ {
3324
+ "name": "dashboard layout get empty canvas",
3325
+ "target": "/app/dashboard/canvas/layout/get",
3326
+ "status": "success",
3327
+ "data": {
3328
+ "spaceId": "space-1",
3329
+ "canvasId": "canvas-1",
3330
+ "layoutSize": "md",
3331
+ "cards": []
3332
+ },
3333
+ "essential": {
3334
+ "spaceId": "space-1",
3335
+ "canvasId": "canvas-1",
3336
+ "layoutSize": "md",
3337
+ "cards": []
3338
+ }
3287
3339
  }
3288
3340
  ]
@@ -13,7 +13,7 @@
13
13
  "externalActorId": "user-1",
14
14
  "tenantId": "tenant-1",
15
15
  "userId": "mhome-user-1",
16
- "scopeId": "scope-1",
16
+ "spaceId": "scope-1",
17
17
  "displayName": "Telegram",
18
18
  "projections": {
19
19
  "notification": {
@@ -37,7 +37,7 @@
37
37
  "conversationId": "chat-2",
38
38
  "audience": "shared",
39
39
  "tenantId": "tenant-1",
40
- "scopeId": "scope-2",
40
+ "spaceId": "scope-2",
41
41
  "boundByUserId": "mhome-user-1",
42
42
  "displayName": "Project room",
43
43
  "projections": {
@@ -6,7 +6,7 @@
6
6
  "provider": "telegram",
7
7
  "placement": "cloud",
8
8
  "routeId": "route-1",
9
- "scopeId": "scope-1",
9
+ "spaceId": "scope-1",
10
10
  "projections": {
11
11
  "notification": {
12
12
  "enabled": true,
@@ -12,7 +12,7 @@
12
12
  "externalActorId": "user-1",
13
13
  "tenantId": "tenant-1",
14
14
  "userId": "mhome-user-1",
15
- "scopeId": "scope-1",
15
+ "spaceId": "scope-1",
16
16
  "projections": {
17
17
  "notification": {
18
18
  "enabled": true,
@@ -8,7 +8,7 @@
8
8
  "placement": "local",
9
9
  "accountId": "123456",
10
10
  "tenantId": "tenant-1",
11
- "scopeId": "scope-1",
11
+ "spaceId": "scope-1",
12
12
  "grantedByUserId": "user-1",
13
13
  "createdAtMs": 1787961600000,
14
14
  "updatedAtMs": 1787961600000
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "manifest": "mhome.app-facade.v1",
3
- "contractVersion": "1.62.0",
3
+ "contractVersion": "1.64.0",
4
4
  "callSchema": "schema/facade-call.v1.schema.json",
5
5
  "routing": "manifest/routing.v1.json",
6
6
  "routingSchema": "schema/routing.v1.schema.json",
@@ -230,6 +230,13 @@
230
230
  "/app/card-skins/override/set": "#/definitions/empty",
231
231
  "/app/card-skins/override/reset": "#/definitions/empty"
232
232
  }
233
+ },
234
+ "entityPresentation": {
235
+ "schema": "schema/entity-presentation.v1.schema.json",
236
+ "contract": "contract/entity-presentation-v1.md",
237
+ "requestTargets": [
238
+ "/app/entity/presentation/get"
239
+ ]
233
240
  }
234
241
  },
235
242
  "authorization": "manifest/authorization.v1.json",
@@ -1,5 +1,5 @@
1
1
  {
2
- "contractVersion": "1.62.0",
2
+ "contractVersion": "1.64.0",
3
3
  "operations": {
4
4
  "/app/agent/context/get": "spaceRead",
5
5
  "/app/agent/credit/usage": "spaceRead",
@@ -64,21 +64,21 @@
64
64
  "/app/client/page/list": "spaceRead",
65
65
  "/app/client/page/open": "spaceWrite",
66
66
  "/app/client/page/report": "spaceRead",
67
- "/app/dashboard/canvas/brief/list": "spaceRead",
67
+ "/app/dashboard/canvas/list": "spaceRead",
68
68
  "/app/dashboard/canvas/content/get": "spaceRead",
69
69
  "/app/dashboard/canvas/create": "spaceWrite",
70
70
  "/app/dashboard/canvas/delete": "spaceWrite",
71
+ "/app/dashboard/canvas/layout/get": "spaceRead",
71
72
  "/app/dashboard/canvas/layout/update": "spaceWrite",
72
73
  "/app/dashboard/canvas/rename": "spaceWrite",
73
74
  "/app/dashboard/canvas/reorder": "spaceWrite",
74
75
  "/app/dashboard/card/add": "spaceWrite",
75
- "/app/dashboard/card/brief/list": "spaceRead",
76
+ "/app/dashboard/card/list": "spaceRead",
76
77
  "/app/dashboard/card/copy": "spaceWrite",
77
78
  "/app/dashboard/card/delete": "spaceWrite",
78
79
  "/app/dashboard/card/detail/get": "spaceRead",
79
80
  "/app/dashboard/card/main-view/update": "spaceWrite",
80
81
  "/app/dashboard/card/move": "spaceWrite",
81
- "/app/dashboard/list": "spaceRead",
82
82
  "/app/device/activity/recent/list": "spaceRead",
83
83
  "/app/device/brief/list": "spaceRead",
84
84
  "/app/device/detail/get": "spaceRead",
@@ -94,6 +94,7 @@
94
94
  "/app/entity/detail/get": "spaceRead",
95
95
  "/app/entity/history/list": "spaceRead",
96
96
  "/app/entity/list": "spaceRead",
97
+ "/app/entity/presentation/get": "spaceRead",
97
98
  "/app/group/brief/list": "spaceRead",
98
99
  "/app/group/delete": "spaceWrite",
99
100
  "/app/group/detail/get": "spaceRead",
@@ -212,10 +213,8 @@
212
213
  "/app/pod/space/list": "spaceRead",
213
214
  "/app/quickword/list": "spaceRead",
214
215
  "/app/quickword/run": "spaceWrite",
215
- "/app/room/brief/list": "spaceRead",
216
216
  "/app/room/create": "spaceWrite",
217
217
  "/app/room/delete": "spaceWrite",
218
- "/app/room/detail/get": "spaceRead",
219
218
  "/app/room/devices/move": "spaceWrite",
220
219
  "/app/room/devices/remove": "spaceWrite",
221
220
  "/app/room/list": "spaceRead",
@@ -316,7 +315,6 @@
316
315
  "/integration/composite/refresh": "spaceWrite",
317
316
  "/integration/disconnect": "spaceWrite",
318
317
  "/integration/entity/batchGetName": "spaceRead",
319
- "/integration/entity/get": "spaceRead",
320
318
  "/integration/entity/getHistory": "spaceRead",
321
319
  "/integration/group/get": "spaceRead",
322
320
  "/integration/install": "spaceWrite",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "manifest": "mhome.host-provision.targets.v1",
3
- "contractVersion": "1.62.0",
3
+ "contractVersion": "1.64.0",
4
4
  "contract": "contract/host-provisioning-v1.md",
5
5
  "localTargets": [
6
6
  "/local/host/provision/start",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "manifest": "mhome.hub.targets.v1",
3
- "contractVersion": "1.62.0",
3
+ "contractVersion": "1.64.0",
4
4
  "appTargets": [
5
5
  "/app/hub/get",
6
6
  "/app/hub/remove",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "manifest": "mhome.pod.targets.v1",
3
- "contractVersion": "1.62.0",
3
+ "contractVersion": "1.64.0",
4
4
  "contract": "contract/pod-commissioning-v1.md",
5
5
  "localTargets": [
6
6
  "/local/pod/discovery/start",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "manifest": "mhome.app-facade.routing.v1",
3
- "contractVersion": "1.62.0",
3
+ "contractVersion": "1.64.0",
4
4
  "targetPrefix": "/app/",
5
5
  "default": {
6
6
  "execution": "scopeMode"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "manifest": "mhome.messaging.targets.v1",
3
- "contractVersion": "1.62.0",
3
+ "contractVersion": "1.64.0",
4
4
  "requestTargets": [
5
5
  "/app/messaging/provider/list",
6
6
  "/app/messaging/provider-account/list",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mhome/app-facade-protocol",
3
- "version": "1.62.0",
3
+ "version": "1.64.0",
4
4
  "description": "Build-time protocol artifacts for mhome.app-facade",
5
5
  "license": "MIT",
6
6
  "repository": {
package/protocol.json CHANGED
@@ -1,10 +1,11 @@
1
1
  {
2
2
  "protocol": "mhome.app-facade",
3
- "contractVersion": "1.62.0",
3
+ "contractVersion": "1.64.0",
4
4
  "manifest": "manifest/app-facade.v1.json",
5
5
  "schemas": {
6
6
  "hostAuthorization": "schema/host-authorization.v1.schema.json",
7
7
  "hostAccess": "schema/host-access.v1.schema.json",
8
+ "entityPresentation": "schema/entity-presentation.v1.schema.json",
8
9
  "capabilityDescriptor": "schema/capability-descriptor.v1.schema.json",
9
10
  "cardSkinPackage": "schema/card-skin-package.v1.schema.json",
10
11
  "cardSkins": "schema/card-skins.v1.schema.json",
@@ -26,6 +27,7 @@
26
27
  "person": "schema/person.v1.schema.json"
27
28
  },
28
29
  "fixtures": {
30
+ "entityPresentation": "fixtures/entity-presentation.conformance.json",
29
31
  "valid": "fixtures",
30
32
  "invalid": "fixtures/invalid",
31
33
  "hostAccess": "schema/host-access.v1.schema.json",
@@ -0,0 +1,83 @@
1
+ {
2
+ "$schema": "https://json-schema.org/draft/2020-12/schema",
3
+ "$id": "https://mhome.ai/schema/entity-presentation.v1.schema.json",
4
+ "$defs": {
5
+ "input": {
6
+ "type": "object",
7
+ "additionalProperties": false,
8
+ "required": [
9
+ "entityType",
10
+ "entityId"
11
+ ],
12
+ "properties": {
13
+ "entityType": {
14
+ "type": "string",
15
+ "pattern": "\\S"
16
+ },
17
+ "entityId": {
18
+ "type": "string",
19
+ "pattern": "\\S"
20
+ }
21
+ }
22
+ },
23
+ "output": {
24
+ "type": "object",
25
+ "additionalProperties": false,
26
+ "required": [
27
+ "entityEntry",
28
+ "entityCard",
29
+ "twinAutomations"
30
+ ],
31
+ "properties": {
32
+ "entityEntry": {
33
+ "type": "object",
34
+ "required": [
35
+ "uid",
36
+ "type"
37
+ ],
38
+ "properties": {
39
+ "uid": {
40
+ "type": "string"
41
+ },
42
+ "type": {
43
+ "type": "string"
44
+ },
45
+ "integration": {
46
+ "type": [
47
+ "string",
48
+ "null"
49
+ ]
50
+ }
51
+ },
52
+ "additionalProperties": true
53
+ },
54
+ "entityCard": {
55
+ "type": [
56
+ "object",
57
+ "null"
58
+ ],
59
+ "additionalProperties": true
60
+ },
61
+ "twinAutomations": {
62
+ "type": "array",
63
+ "items": {
64
+ "type": "object",
65
+ "required": [
66
+ "id",
67
+ "name"
68
+ ],
69
+ "properties": {
70
+ "id": {
71
+ "type": "string"
72
+ },
73
+ "name": {
74
+ "type": "string"
75
+ }
76
+ },
77
+ "additionalProperties": false
78
+ }
79
+ }
80
+ }
81
+ }
82
+ }
83
+ }
@@ -4,9 +4,9 @@
4
4
  "title": "Authoritative cloud Hub lifecycle state",
5
5
  "type": "object",
6
6
  "additionalProperties": false,
7
- "required": ["scopeId", "configured"],
7
+ "required": ["spaceId", "configured"],
8
8
  "properties": {
9
- "scopeId": { "type": "string", "minLength": 1 },
9
+ "spaceId": { "type": "string", "minLength": 1 },
10
10
  "configured": { "type": "boolean" },
11
11
  "hub": { "$ref": "#/$defs/hub" },
12
12
  "operation": { "$ref": "#/$defs/operation" },
@@ -380,7 +380,7 @@
380
380
  "placement",
381
381
  "accountId",
382
382
  "tenantId",
383
- "scopeId",
383
+ "spaceId",
384
384
  "grantedByUserId",
385
385
  "createdAtMs",
386
386
  "updatedAtMs"
@@ -398,7 +398,7 @@
398
398
  "tenantId": {
399
399
  "$ref": "#/$defs/id"
400
400
  },
401
- "scopeId": {
401
+ "spaceId": {
402
402
  "$ref": "#/$defs/id"
403
403
  },
404
404
  "grantedByUserId": {
@@ -427,7 +427,7 @@
427
427
  "externalActorId",
428
428
  "tenantId",
429
429
  "userId",
430
- "scopeId",
430
+ "spaceId",
431
431
  "projections",
432
432
  "providerData"
433
433
  ],
@@ -453,7 +453,7 @@
453
453
  "tenantId": {
454
454
  "$ref": "#/$defs/id"
455
455
  },
456
- "scopeId": {
456
+ "spaceId": {
457
457
  "$ref": "#/$defs/id"
458
458
  },
459
459
  "displayName": {
@@ -484,7 +484,7 @@
484
484
  "accountId",
485
485
  "conversationId",
486
486
  "tenantId",
487
- "scopeId",
487
+ "spaceId",
488
488
  "boundByUserId",
489
489
  "projections",
490
490
  "providerData"
@@ -511,7 +511,7 @@
511
511
  "tenantId": {
512
512
  "$ref": "#/$defs/id"
513
513
  },
514
- "scopeId": {
514
+ "spaceId": {
515
515
  "$ref": "#/$defs/id"
516
516
  },
517
517
  "displayName": {
@@ -863,7 +863,7 @@
863
863
  "routeId": {
864
864
  "$ref": "#/$defs/id"
865
865
  },
866
- "scopeId": {
866
+ "spaceId": {
867
867
  "$ref": "#/$defs/id"
868
868
  },
869
869
  "projections": {
@@ -2516,7 +2516,7 @@
2516
2516
  "conversationId": {
2517
2517
  "$ref": "#/$defs/id"
2518
2518
  },
2519
- "scopeId": {
2519
+ "spaceId": {
2520
2520
  "$ref": "#/$defs/id"
2521
2521
  },
2522
2522
  "createdAtMs": {
@@ -2533,7 +2533,7 @@
2533
2533
  "placement",
2534
2534
  "accountId",
2535
2535
  "conversationId",
2536
- "scopeId",
2536
+ "spaceId",
2537
2537
  "createdAtMs"
2538
2538
  ]
2539
2539
  },
@@ -3,7 +3,7 @@
3
3
  "additionalProperties": false,
4
4
  "required": [
5
5
  "contract",
6
- "scopeId",
6
+ "spaceId",
7
7
  "observedAtMs",
8
8
  "sessions"
9
9
  ],
@@ -11,7 +11,7 @@
11
11
  "contract": {
12
12
  "const": "mhome.system.clients.v1"
13
13
  },
14
- "scopeId": {
14
+ "spaceId": {
15
15
  "type": "string"
16
16
  },
17
17
  "observedAtMs": {
@@ -3,7 +3,7 @@
3
3
  "additionalProperties": false,
4
4
  "required": [
5
5
  "contract",
6
- "scopeId",
6
+ "spaceId",
7
7
  "hostId",
8
8
  "result"
9
9
  ],
@@ -11,7 +11,7 @@
11
11
  "contract": {
12
12
  "const": "mhome.system.hosts.runtime.v1"
13
13
  },
14
- "scopeId": {
14
+ "spaceId": {
15
15
  "type": "string"
16
16
  },
17
17
  "hostId": {
@@ -3,7 +3,7 @@
3
3
  "additionalProperties": false,
4
4
  "required": [
5
5
  "contract",
6
- "scopeId",
6
+ "spaceId",
7
7
  "observedAtMs",
8
8
  "hosts"
9
9
  ],
@@ -11,7 +11,7 @@
11
11
  "contract": {
12
12
  "const": "mhome.system.hosts.v1"
13
13
  },
14
- "scopeId": {
14
+ "spaceId": {
15
15
  "type": "string"
16
16
  },
17
17
  "observedAtMs": {
@@ -3,7 +3,7 @@
3
3
  "additionalProperties": false,
4
4
  "required": [
5
5
  "contract",
6
- "scopeId",
6
+ "spaceId",
7
7
  "observedAtMs",
8
8
  "instances"
9
9
  ],
@@ -11,7 +11,7 @@
11
11
  "contract": {
12
12
  "const": "mhome.system.instances.v1"
13
13
  },
14
- "scopeId": {
14
+ "spaceId": {
15
15
  "type": "string"
16
16
  },
17
17
  "observedAtMs": {
@@ -6,7 +6,7 @@
6
6
  "additionalProperties": false,
7
7
  "required": [
8
8
  "contract",
9
- "scopeId",
9
+ "spaceId",
10
10
  "generation",
11
11
  "revision",
12
12
  "observedAtMs",
@@ -15,7 +15,7 @@
15
15
  ],
16
16
  "properties": {
17
17
  "contract": { "const": "mhome.space.topology.v1" },
18
- "scopeId": { "type": "string", "minLength": 1 },
18
+ "spaceId": { "type": "string", "minLength": 1 },
19
19
  "generation": { "type": "string", "minLength": 1 },
20
20
  "revision": { "type": "integer", "minimum": 0 },
21
21
  "observedAtMs": { "type": "integer", "minimum": 0 },