@mhome/app-facade-protocol 1.3.0 → 1.5.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
@@ -3,6 +3,13 @@
3
3
  Canonical public protocol shared by MeowLink clients, MeowCore, the CLI,
4
4
  Agents, and cloud adapters.
5
5
 
6
+ The package also carries the explicitly private `/local/*` native-daemon
7
+ extension. `/app/*` is portable and may be routed according to the public
8
+ routing manifest. `/local/*` is an exact allowlist for the current MeowLink
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.
12
+
6
13
  Every `/app/*` request uses the strict `FacadeCall` envelope. Invocation
7
14
  metadata lives in `control`; the domain request lives in `input`. The crate
8
15
  owns public targets, request/response/event schemas, and stable operation
@@ -21,6 +28,12 @@ its complete referenced value is available and which visible inputs can make
21
28
  it stale, so clients can resolve it reactively without learning handlers or
22
29
  the hidden graph.
23
30
 
31
+ `topology` exposes the Hub-owned Space network projection. Stable Host, Hub,
32
+ Node, AppClient, and Cloud identities are separate from current transport
33
+ sessions. Durable relations remain present while disconnected and carry an
34
+ explicit observation state so clients can distinguish expected topology from
35
+ the currently observed path.
36
+
24
37
  ## Routing contract
25
38
 
26
39
  `manifest/routing.v1.json` is the canonical client-side routing policy for the
@@ -0,0 +1,17 @@
1
+ {
2
+ "scopeId": "scope-1",
3
+ "configured": true,
4
+ "hub": {
5
+ "id": "hub-1",
6
+ "name": "Home Hub",
7
+ "type": "local",
8
+ "hostId": "host-1",
9
+ "isTest": false,
10
+ "status": "ready",
11
+ "cloud": {
12
+ "connectionStatus": "connected",
13
+ "lastConnectedAt": 1700000000000,
14
+ "firmwareVersion": "1.0.0"
15
+ }
16
+ }
17
+ }
@@ -0,0 +1,15 @@
1
+ {
2
+ "scopeId": "scope-1",
3
+ "configured": false,
4
+ "operation": {
5
+ "kind": "REMOVE",
6
+ "state": "RUNNING",
7
+ "phase": "CLEARING_LOCAL_DATA",
8
+ "startedAt": 1700000000000,
9
+ "hubId": "hub-old"
10
+ },
11
+ "revocation": {
12
+ "hubId": "hub-old",
13
+ "revocationId": "revoke-1"
14
+ }
15
+ }
@@ -0,0 +1,22 @@
1
+ {
2
+ "scopeId": "scope-1",
3
+ "configured": true,
4
+ "hub": {
5
+ "id": "hub-1",
6
+ "name": "Home Hub",
7
+ "type": "local",
8
+ "hostId": "host-1",
9
+ "isTest": false,
10
+ "status": "ready",
11
+ "cloud": {
12
+ "connectionStatus": "connected"
13
+ },
14
+ "local": {
15
+ "discovered": true,
16
+ "connected": true,
17
+ "connectionStatus": "connected",
18
+ "hostName": "Living Room Mac",
19
+ "version": "1.0.0"
20
+ }
21
+ }
22
+ }
@@ -1,10 +1,15 @@
1
1
  {
2
2
  "manifest": "mhome.app-facade.v1",
3
- "contractVersion": "1.3.0",
3
+ "contractVersion": "1.5.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",
7
7
  "domains": {
8
+ "hub": {
9
+ "targets": "manifest/hub-targets.v1.json",
10
+ "cloudStateTarget": "/app/hub/get",
11
+ "nativeCompositeTarget": "/local/hub/get"
12
+ },
8
13
  "messaging": {
9
14
  "targets": "manifest/targets.v1.json"
10
15
  },
@@ -31,6 +36,12 @@
31
36
  "requestTargets": ["/app/runtime/status/list"],
32
37
  "eventTargets": ["/app/runtime/status/changed"]
33
38
  },
39
+ "topology": {
40
+ "contract": "mhome.space.topology.v1",
41
+ "schema": "schema/topology.v1.schema.json",
42
+ "requestTargets": ["/app/topology/get"],
43
+ "eventTargets": ["/app/topology/changed"]
44
+ },
34
45
  "interactionFlow": {
35
46
  "schema": "schema/interaction-flow-app.v1.schema.json",
36
47
  "requestTargets": [
@@ -0,0 +1,20 @@
1
+ {
2
+ "manifest": "mhome.hub.targets.v1",
3
+ "contractVersion": "1.0.0",
4
+ "appTargets": [
5
+ "/app/hub/get",
6
+ "/app/hub/remove",
7
+ "/app/hub/cache/clear"
8
+ ],
9
+ "localTargets": [
10
+ "/local/hub/get",
11
+ "/local/hub/candidates",
12
+ "/local/hub/add/start",
13
+ "/local/hub/add/confirm",
14
+ "/local/hub/add/status",
15
+ "/local/hub/add/cancel"
16
+ ],
17
+ "appInvocationModes": ["direct"],
18
+ "localPayload": "domainInput",
19
+ "localForwardable": false
20
+ }
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "manifest": "mhome.app-facade.routing.v1",
3
- "contractVersion": "1.3.0",
3
+ "contractVersion": "1.5.0",
4
4
  "targetPrefix": "/app/",
5
5
  "default": {
6
6
  "execution": "scopeMode",
@@ -16,6 +16,9 @@
16
16
  "cloudTargets": [
17
17
  "/app/agent/context/get",
18
18
  "/app/credit/record",
19
+ "/app/hub/cache/clear",
20
+ "/app/hub/get",
21
+ "/app/hub/remove",
19
22
  "/app/system/feedback/submit",
20
23
  "/app/timeline/entity/latest/list"
21
24
  ],
@@ -26,7 +29,8 @@
26
29
  "/app/plugin/",
27
30
  "/app/interaction-flow/",
28
31
  "/app/object-storage/",
29
- "/app/runtime/"
32
+ "/app/runtime/",
33
+ "/app/topology/"
30
34
  ],
31
35
  "requestPlacementPrefixes": [
32
36
  "/app/messaging/"
@@ -40,7 +44,8 @@
40
44
  "/app/object-storage/folders/get",
41
45
  "/app/object-storage/folders/update",
42
46
  "/app/object-storage/folders/list",
43
- "/app/object-storage/settings/update"
47
+ "/app/object-storage/settings/update",
48
+ "/app/topology/get"
44
49
  ]
45
50
  }
46
51
  }
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "manifest": "mhome.messaging.targets.v1",
3
- "contractVersion": "1.3.0",
3
+ "contractVersion": "1.5.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.3.0",
3
+ "version": "1.5.0",
4
4
  "description": "Build-time protocol artifacts for mhome.app-facade",
5
5
  "license": "MIT",
6
6
  "repository": {
package/protocol.json CHANGED
@@ -1,12 +1,15 @@
1
1
  {
2
2
  "protocol": "mhome.app-facade",
3
- "contractVersion": "1.3.0",
3
+ "contractVersion": "1.5.0",
4
4
  "manifest": "manifest/app-facade.v1.json",
5
5
  "schemas": {
6
6
  "call": "schema/facade-call.v1.schema.json",
7
7
  "frame": "schema/messaging-frame.v3.schema.json",
8
8
  "interactionFlow": "schema/interaction-flow-app.v1.schema.json",
9
- "routing": "schema/routing.v1.schema.json"
9
+ "routing": "schema/routing.v1.schema.json",
10
+ "hubState": "schema/hub-state.v1.schema.json",
11
+ "localHubState": "schema/local-hub-state.v1.schema.json",
12
+ "topology": "schema/topology.v1.schema.json"
10
13
  },
11
14
  "fixtures": {
12
15
  "valid": "fixtures",
@@ -0,0 +1,89 @@
1
+ {
2
+ "$schema": "https://json-schema.org/draft/2020-12/schema",
3
+ "$id": "https://schemas.mhome.ai/app-facade/hub-state.v1.schema.json",
4
+ "title": "Authoritative cloud Hub lifecycle state",
5
+ "type": "object",
6
+ "additionalProperties": false,
7
+ "required": ["scopeId", "configured"],
8
+ "properties": {
9
+ "scopeId": { "type": "string", "minLength": 1 },
10
+ "configured": { "type": "boolean" },
11
+ "hub": { "$ref": "#/$defs/hub" },
12
+ "operation": { "$ref": "#/$defs/operation" },
13
+ "revocation": { "$ref": "#/$defs/revocation" }
14
+ },
15
+ "allOf": [
16
+ {
17
+ "if": { "properties": { "configured": { "const": true } }, "required": ["configured"] },
18
+ "then": { "required": ["hub"] },
19
+ "else": { "not": { "required": ["hub"] } }
20
+ }
21
+ ],
22
+ "$defs": {
23
+ "hub": {
24
+ "type": "object",
25
+ "additionalProperties": false,
26
+ "required": ["id", "type", "hostId", "isTest", "status", "cloud"],
27
+ "properties": {
28
+ "id": { "type": "string", "minLength": 1 },
29
+ "name": { "type": "string" },
30
+ "type": { "type": "string", "minLength": 1 },
31
+ "hostId": { "type": "string", "minLength": 1 },
32
+ "isTest": { "type": "boolean" },
33
+ "status": { "type": "string", "minLength": 1 },
34
+ "cloud": {
35
+ "type": "object",
36
+ "additionalProperties": false,
37
+ "properties": {
38
+ "connectionStatus": { "type": "string" },
39
+ "lastConnectedAt": { "type": "integer" },
40
+ "firmwareVersion": { "type": "string" }
41
+ }
42
+ }
43
+ }
44
+ },
45
+ "operation": {
46
+ "type": "object",
47
+ "additionalProperties": false,
48
+ "required": ["kind", "state", "phase", "startedAt"],
49
+ "properties": {
50
+ "kind": { "enum": ["SETUP", "REMOVE"] },
51
+ "state": { "enum": ["RUNNING", "FAILED"] },
52
+ "phase": {
53
+ "enum": [
54
+ "WAITING_FOR_HUB",
55
+ "PREPARING_DATA",
56
+ "SYNCING_DATA",
57
+ "BACKING_UP_DATA",
58
+ "FENCING_CLOUD",
59
+ "CLEARING_LOCAL_DATA",
60
+ "FINALIZING",
61
+ "CLEANING_UP"
62
+ ]
63
+ },
64
+ "startedAt": { "type": "integer" },
65
+ "expiresAt": { "type": "integer" },
66
+ "hostId": { "type": "string" },
67
+ "hubId": { "type": "string" },
68
+ "failure": {
69
+ "type": "object",
70
+ "additionalProperties": false,
71
+ "required": ["reason"],
72
+ "properties": {
73
+ "reason": { "type": "string", "minLength": 1 },
74
+ "at": { "type": "integer" }
75
+ }
76
+ }
77
+ }
78
+ },
79
+ "revocation": {
80
+ "type": "object",
81
+ "additionalProperties": false,
82
+ "required": ["hubId", "revocationId"],
83
+ "properties": {
84
+ "hubId": { "type": "string", "minLength": 1 },
85
+ "revocationId": { "type": "string", "minLength": 1 }
86
+ }
87
+ }
88
+ }
89
+ }
@@ -0,0 +1,65 @@
1
+ {
2
+ "$schema": "https://json-schema.org/draft/2020-12/schema",
3
+ "$id": "https://schemas.mhome.ai/app-facade/local-hub-state.v1.schema.json",
4
+ "title": "Native-client composite Hub state",
5
+ "type": "object",
6
+ "additionalProperties": false,
7
+ "required": ["scopeId", "configured"],
8
+ "properties": {
9
+ "scopeId": { "type": "string", "minLength": 1 },
10
+ "configured": { "type": "boolean" },
11
+ "hub": { "$ref": "#/$defs/localHub" },
12
+ "operation": { "$ref": "hub-state.v1.schema.json#/$defs/operation" },
13
+ "revocation": { "$ref": "hub-state.v1.schema.json#/$defs/revocation" },
14
+ "pairing": {
15
+ "type": "object",
16
+ "additionalProperties": false,
17
+ "required": ["sessionId", "state", "phase", "startedAt", "expiresAt"],
18
+ "properties": {
19
+ "sessionId": { "type": "string", "minLength": 1 },
20
+ "state": { "type": "string", "minLength": 1 },
21
+ "phase": { "type": "string", "minLength": 1 },
22
+ "startedAt": { "type": "integer" },
23
+ "expiresAt": { "type": "integer" },
24
+ "hostId": { "type": "string" },
25
+ "hubId": { "type": "string" },
26
+ "failure": { "$ref": "hub-state.v1.schema.json#/$defs/operation/properties/failure" }
27
+ }
28
+ }
29
+ },
30
+ "allOf": [
31
+ {
32
+ "if": { "properties": { "configured": { "const": true } }, "required": ["configured"] },
33
+ "then": { "required": ["hub"] },
34
+ "else": { "not": { "required": ["hub"] } }
35
+ }
36
+ ],
37
+ "$defs": {
38
+ "localHub": {
39
+ "type": "object",
40
+ "additionalProperties": false,
41
+ "required": ["id", "type", "hostId", "isTest", "status", "cloud", "local"],
42
+ "properties": {
43
+ "id": { "type": "string", "minLength": 1 },
44
+ "name": { "type": "string" },
45
+ "type": { "type": "string", "minLength": 1 },
46
+ "hostId": { "type": "string", "minLength": 1 },
47
+ "isTest": { "type": "boolean" },
48
+ "status": { "type": "string", "minLength": 1 },
49
+ "cloud": { "$ref": "hub-state.v1.schema.json#/$defs/hub/properties/cloud" },
50
+ "local": {
51
+ "type": "object",
52
+ "additionalProperties": false,
53
+ "required": ["discovered", "connected"],
54
+ "properties": {
55
+ "discovered": { "type": "boolean" },
56
+ "connected": { "type": "boolean" },
57
+ "connectionStatus": { "type": "string" },
58
+ "hostName": { "type": "string" },
59
+ "version": { "type": "string" }
60
+ }
61
+ }
62
+ }
63
+ }
64
+ }
65
+ }
@@ -0,0 +1,182 @@
1
+ {
2
+ "$schema": "https://json-schema.org/draft/2020-12/schema",
3
+ "$id": "https://mhome.ai/schema/space-topology.v1.schema.json",
4
+ "title": "mHome Space Topology",
5
+ "type": "object",
6
+ "additionalProperties": false,
7
+ "required": [
8
+ "contract",
9
+ "scopeId",
10
+ "generation",
11
+ "revision",
12
+ "observedAtMs",
13
+ "entities",
14
+ "edges"
15
+ ],
16
+ "properties": {
17
+ "contract": { "const": "mhome.space.topology.v1" },
18
+ "scopeId": { "type": "string", "minLength": 1 },
19
+ "generation": { "type": "string", "minLength": 1 },
20
+ "revision": { "type": "integer", "minimum": 0 },
21
+ "observedAtMs": { "type": "integer", "minimum": 0 },
22
+ "entities": {
23
+ "type": "array",
24
+ "items": { "$ref": "#/$defs/entity" }
25
+ },
26
+ "edges": {
27
+ "type": "array",
28
+ "items": { "$ref": "#/$defs/edge" }
29
+ }
30
+ },
31
+ "$defs": {
32
+ "baseEntity": {
33
+ "type": "object",
34
+ "required": ["id", "kind", "displayName"],
35
+ "properties": {
36
+ "id": { "type": "string", "minLength": 1 },
37
+ "kind": { "type": "string" },
38
+ "displayName": { "type": "string", "minLength": 1 }
39
+ }
40
+ },
41
+ "entity": {
42
+ "oneOf": [
43
+ {
44
+ "allOf": [
45
+ { "$ref": "#/$defs/baseEntity" },
46
+ {
47
+ "type": "object",
48
+ "additionalProperties": false,
49
+ "required": ["id", "kind", "hostId", "displayName"],
50
+ "properties": {
51
+ "id": { "type": "string" },
52
+ "kind": { "const": "host" },
53
+ "hostId": { "type": "string", "minLength": 1 },
54
+ "displayName": { "type": "string", "minLength": 1 }
55
+ }
56
+ }
57
+ ]
58
+ },
59
+ {
60
+ "type": "object",
61
+ "additionalProperties": false,
62
+ "required": ["id", "kind", "hubId", "hostId", "displayName"],
63
+ "properties": {
64
+ "id": { "type": "string", "minLength": 1 },
65
+ "kind": { "const": "hub" },
66
+ "hubId": { "type": "string", "minLength": 1 },
67
+ "hostId": { "type": "string", "minLength": 1 },
68
+ "displayName": { "type": "string", "minLength": 1 }
69
+ }
70
+ },
71
+ {
72
+ "type": "object",
73
+ "additionalProperties": false,
74
+ "required": [
75
+ "id",
76
+ "kind",
77
+ "nodeId",
78
+ "nodeType",
79
+ "hostId",
80
+ "displayName",
81
+ "bindingState",
82
+ "runtime"
83
+ ],
84
+ "properties": {
85
+ "id": { "type": "string", "minLength": 1 },
86
+ "kind": { "const": "node" },
87
+ "nodeId": { "type": "string", "minLength": 1 },
88
+ "nodeType": { "type": "string", "minLength": 1 },
89
+ "hostId": { "type": "string", "minLength": 1 },
90
+ "displayName": { "type": "string", "minLength": 1 },
91
+ "bindingState": { "type": "string", "minLength": 1 },
92
+ "runtime": { "$ref": "#/$defs/runtime" }
93
+ }
94
+ },
95
+ {
96
+ "type": "object",
97
+ "additionalProperties": false,
98
+ "required": [
99
+ "id",
100
+ "kind",
101
+ "appClientId",
102
+ "source",
103
+ "deviceType",
104
+ "displayName",
105
+ "isCurrent",
106
+ "hasLocalCredential"
107
+ ],
108
+ "properties": {
109
+ "id": { "type": "string", "minLength": 1 },
110
+ "kind": { "const": "client" },
111
+ "appClientId": { "type": "string", "minLength": 1 },
112
+ "curClientId": { "type": "string", "minLength": 1 },
113
+ "source": { "type": "string" },
114
+ "deviceType": { "type": "string" },
115
+ "displayName": { "type": "string", "minLength": 1 },
116
+ "isCurrent": { "type": "boolean" },
117
+ "routeKind": {
118
+ "enum": ["localDirect", "cloudBridgeShadow"]
119
+ },
120
+ "hasLocalCredential": { "type": "boolean" }
121
+ }
122
+ },
123
+ {
124
+ "type": "object",
125
+ "additionalProperties": false,
126
+ "required": ["id", "kind", "displayName"],
127
+ "properties": {
128
+ "id": { "const": "cloud:primary" },
129
+ "kind": { "const": "cloud" },
130
+ "displayName": { "type": "string", "minLength": 1 }
131
+ }
132
+ }
133
+ ]
134
+ },
135
+ "runtime": {
136
+ "type": "object",
137
+ "additionalProperties": false,
138
+ "required": ["state"],
139
+ "properties": {
140
+ "state": { "enum": ["healthy", "degraded", "offline", "unknown"] },
141
+ "reason": { "type": "string" },
142
+ "updatedAtMs": { "type": "integer", "minimum": 0 }
143
+ }
144
+ },
145
+ "edge": {
146
+ "type": "object",
147
+ "additionalProperties": false,
148
+ "required": [
149
+ "id",
150
+ "source",
151
+ "target",
152
+ "relation",
153
+ "basis",
154
+ "durability",
155
+ "observation"
156
+ ],
157
+ "properties": {
158
+ "id": { "type": "string", "minLength": 1 },
159
+ "source": { "type": "string", "minLength": 1 },
160
+ "target": { "type": "string", "minLength": 1 },
161
+ "relation": {
162
+ "enum": ["hub-cloud", "node-hub", "client-hub", "client-cloud"]
163
+ },
164
+ "basis": {
165
+ "enum": ["hubCommission", "nodeBinding", "localCredential", "liveRoute"]
166
+ },
167
+ "durability": { "enum": ["durable", "ephemeral"] },
168
+ "observation": { "$ref": "#/$defs/observation" }
169
+ }
170
+ },
171
+ "observation": {
172
+ "type": "object",
173
+ "additionalProperties": false,
174
+ "required": ["state", "observedAtMs"],
175
+ "properties": {
176
+ "state": { "enum": ["connected", "disconnected", "unknown"] },
177
+ "observedAtMs": { "type": "integer", "minimum": 0 },
178
+ "reason": { "type": "string" }
179
+ }
180
+ }
181
+ }
182
+ }