@mhome/app-facade-protocol 1.1.2 → 1.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +22 -0
- package/fixtures/hub-state.configured.json +17 -0
- package/fixtures/hub-state.revoked.json +15 -0
- package/fixtures/local-hub-state.configured.json +22 -0
- package/manifest/app-facade.v1.json +11 -3
- package/manifest/hub-targets.v1.json +20 -0
- package/manifest/routing.v1.json +49 -0
- package/manifest/targets.v1.json +1 -1
- package/package.json +1 -1
- package/protocol.json +5 -2
- package/schema/hub-state.v1.schema.json +89 -0
- package/schema/local-hub-state.v1.schema.json +65 -0
- package/schema/routing.v1.schema.json +65 -0
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
|
|
@@ -20,3 +27,18 @@ recovering the secret. Each current-step resolver projection reports whether
|
|
|
20
27
|
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.
|
|
30
|
+
|
|
31
|
+
## Routing contract
|
|
32
|
+
|
|
33
|
+
`manifest/routing.v1.json` is the canonical client-side routing policy for the
|
|
34
|
+
new `/app/*` facade. Ordinary operations follow the active Space mode. Only
|
|
35
|
+
exceptional domains declare a fixed Cloud, Hub, or request-placement executor.
|
|
36
|
+
Relay permission is separate from execution authority so a client
|
|
37
|
+
cannot silently turn every Hub request into a cloud-proxied request.
|
|
38
|
+
|
|
39
|
+
The checked-in Rust table is generated from that manifest, and non-Rust clients
|
|
40
|
+
consume the same manifest from the npm protocol package. A native Host may
|
|
41
|
+
supervise Hub and Node processes, but it is not a public App Facade executor;
|
|
42
|
+
Host process management remains an implementation detail behind the selected
|
|
43
|
+
Hub. Lion's legacy controller annotations and non-`/app/*` protocols are
|
|
44
|
+
outside this contract.
|
|
@@ -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,8 +1,15 @@
|
|
|
1
1
|
{
|
|
2
2
|
"manifest": "mhome.app-facade.v1",
|
|
3
|
-
"contractVersion": "1.
|
|
3
|
+
"contractVersion": "1.4.0",
|
|
4
4
|
"callSchema": "schema/facade-call.v1.schema.json",
|
|
5
|
+
"routing": "manifest/routing.v1.json",
|
|
6
|
+
"routingSchema": "schema/routing.v1.schema.json",
|
|
5
7
|
"domains": {
|
|
8
|
+
"hub": {
|
|
9
|
+
"targets": "manifest/hub-targets.v1.json",
|
|
10
|
+
"cloudStateTarget": "/app/hub/get",
|
|
11
|
+
"nativeCompositeTarget": "/local/hub/get"
|
|
12
|
+
},
|
|
6
13
|
"messaging": {
|
|
7
14
|
"targets": "manifest/targets.v1.json"
|
|
8
15
|
},
|
|
@@ -24,9 +31,10 @@
|
|
|
24
31
|
"extensionPriority": "after_exact"
|
|
25
32
|
},
|
|
26
33
|
"runtime": {
|
|
34
|
+
"contract": "mhome.runtime.status.v1",
|
|
35
|
+
"resourceTypes": ["nodeInstance", "nodeRuntime"],
|
|
27
36
|
"requestTargets": ["/app/runtime/status/list"],
|
|
28
|
-
"eventTargets": ["/app/runtime/status/changed"]
|
|
29
|
-
"authority": "host"
|
|
37
|
+
"eventTargets": ["/app/runtime/status/changed"]
|
|
30
38
|
},
|
|
31
39
|
"interactionFlow": {
|
|
32
40
|
"schema": "schema/interaction-flow-app.v1.schema.json",
|
|
@@ -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
|
+
}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
{
|
|
2
|
+
"manifest": "mhome.app-facade.routing.v1",
|
|
3
|
+
"contractVersion": "1.4.0",
|
|
4
|
+
"targetPrefix": "/app/",
|
|
5
|
+
"default": {
|
|
6
|
+
"execution": "scopeMode",
|
|
7
|
+
"relay": "directOnly"
|
|
8
|
+
},
|
|
9
|
+
"matching": "exactBeforePrefix",
|
|
10
|
+
"placementJsonPointer": "/input/placement",
|
|
11
|
+
"rules": {
|
|
12
|
+
"cloudPrefixes": [
|
|
13
|
+
"/app/scope/",
|
|
14
|
+
"/app/inspire/"
|
|
15
|
+
],
|
|
16
|
+
"cloudTargets": [
|
|
17
|
+
"/app/agent/context/get",
|
|
18
|
+
"/app/credit/record",
|
|
19
|
+
"/app/hub/cache/clear",
|
|
20
|
+
"/app/hub/get",
|
|
21
|
+
"/app/hub/remove",
|
|
22
|
+
"/app/system/feedback/submit",
|
|
23
|
+
"/app/timeline/entity/latest/list"
|
|
24
|
+
],
|
|
25
|
+
"scopeModeTargets": [
|
|
26
|
+
"/app/scope/context/get"
|
|
27
|
+
],
|
|
28
|
+
"hubPrefixes": [
|
|
29
|
+
"/app/plugin/",
|
|
30
|
+
"/app/interaction-flow/",
|
|
31
|
+
"/app/object-storage/",
|
|
32
|
+
"/app/runtime/"
|
|
33
|
+
],
|
|
34
|
+
"requestPlacementPrefixes": [
|
|
35
|
+
"/app/messaging/"
|
|
36
|
+
],
|
|
37
|
+
"cloudRelayTargets": [
|
|
38
|
+
"/app/plugin/candidate/list",
|
|
39
|
+
"/app/plugin/detail/get",
|
|
40
|
+
"/app/plugin/installed/list",
|
|
41
|
+
"/app/object-storage/overview",
|
|
42
|
+
"/app/object-storage/folders/create",
|
|
43
|
+
"/app/object-storage/folders/get",
|
|
44
|
+
"/app/object-storage/folders/update",
|
|
45
|
+
"/app/object-storage/folders/list",
|
|
46
|
+
"/app/object-storage/settings/update"
|
|
47
|
+
]
|
|
48
|
+
}
|
|
49
|
+
}
|
package/manifest/targets.v1.json
CHANGED
package/package.json
CHANGED
package/protocol.json
CHANGED
|
@@ -1,11 +1,14 @@
|
|
|
1
1
|
{
|
|
2
2
|
"protocol": "mhome.app-facade",
|
|
3
|
-
"contractVersion": "1.
|
|
3
|
+
"contractVersion": "1.4.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
|
-
"interactionFlow": "schema/interaction-flow-app.v1.schema.json"
|
|
8
|
+
"interactionFlow": "schema/interaction-flow-app.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"
|
|
9
12
|
},
|
|
10
13
|
"fixtures": {
|
|
11
14
|
"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,65 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
|
3
|
+
"$id": "https://mhome.ai/schema/app-facade-routing.v1.schema.json",
|
|
4
|
+
"title": "MeowLink App Facade routing contract",
|
|
5
|
+
"type": "object",
|
|
6
|
+
"additionalProperties": false,
|
|
7
|
+
"required": [
|
|
8
|
+
"manifest",
|
|
9
|
+
"contractVersion",
|
|
10
|
+
"targetPrefix",
|
|
11
|
+
"default",
|
|
12
|
+
"matching",
|
|
13
|
+
"placementJsonPointer",
|
|
14
|
+
"rules"
|
|
15
|
+
],
|
|
16
|
+
"properties": {
|
|
17
|
+
"manifest": { "const": "mhome.app-facade.routing.v1" },
|
|
18
|
+
"contractVersion": {
|
|
19
|
+
"type": "string",
|
|
20
|
+
"pattern": "^[0-9]+\\.[0-9]+\\.[0-9]+$"
|
|
21
|
+
},
|
|
22
|
+
"targetPrefix": { "const": "/app/" },
|
|
23
|
+
"default": {
|
|
24
|
+
"type": "object",
|
|
25
|
+
"additionalProperties": false,
|
|
26
|
+
"required": ["execution", "relay"],
|
|
27
|
+
"properties": {
|
|
28
|
+
"execution": { "const": "scopeMode" },
|
|
29
|
+
"relay": { "const": "directOnly" }
|
|
30
|
+
}
|
|
31
|
+
},
|
|
32
|
+
"matching": { "const": "exactBeforePrefix" },
|
|
33
|
+
"placementJsonPointer": { "const": "/input/placement" },
|
|
34
|
+
"rules": {
|
|
35
|
+
"type": "object",
|
|
36
|
+
"additionalProperties": false,
|
|
37
|
+
"required": [
|
|
38
|
+
"cloudPrefixes",
|
|
39
|
+
"cloudTargets",
|
|
40
|
+
"scopeModeTargets",
|
|
41
|
+
"hubPrefixes",
|
|
42
|
+
"requestPlacementPrefixes",
|
|
43
|
+
"cloudRelayTargets"
|
|
44
|
+
],
|
|
45
|
+
"properties": {
|
|
46
|
+
"cloudPrefixes": { "$ref": "#/$defs/targetList" },
|
|
47
|
+
"cloudTargets": { "$ref": "#/$defs/targetList" },
|
|
48
|
+
"scopeModeTargets": { "$ref": "#/$defs/targetList" },
|
|
49
|
+
"hubPrefixes": { "$ref": "#/$defs/targetList" },
|
|
50
|
+
"requestPlacementPrefixes": { "$ref": "#/$defs/targetList" },
|
|
51
|
+
"cloudRelayTargets": { "$ref": "#/$defs/targetList" }
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
},
|
|
55
|
+
"$defs": {
|
|
56
|
+
"targetList": {
|
|
57
|
+
"type": "array",
|
|
58
|
+
"uniqueItems": true,
|
|
59
|
+
"items": {
|
|
60
|
+
"type": "string",
|
|
61
|
+
"pattern": "^/app/"
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
}
|