@mhome/app-facade-protocol 1.1.1 → 1.3.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
@@ -9,3 +9,29 @@ owns public targets, request/response/event schemas, and stable operation
9
9
  identity. Core-to-Node routes and provider runtime models belong to
10
10
  `mhome-core-api` instead.
11
11
 
12
+ `interaction_flow` exposes only the materialized current-step view and session
13
+ commands. Handler operations, the complete step graph, and Node routing
14
+ identity remain internal to MeowCore.
15
+
16
+ Core owns defaults, resolver results, and read-only values. Clients may write
17
+ only editable inputs. Password plaintext is accepted as input but is never
18
+ projected back; `hasValue` lets a client render back navigation without
19
+ recovering the secret. Each current-step resolver projection reports whether
20
+ its complete referenced value is available and which visible inputs can make
21
+ it stale, so clients can resolve it reactively without learning handlers or
22
+ the hidden graph.
23
+
24
+ ## Routing contract
25
+
26
+ `manifest/routing.v1.json` is the canonical client-side routing policy for the
27
+ new `/app/*` facade. Ordinary operations follow the active Space mode. Only
28
+ exceptional domains declare a fixed Cloud, Hub, or request-placement executor.
29
+ Relay permission is separate from execution authority so a client
30
+ cannot silently turn every Hub request into a cloud-proxied request.
31
+
32
+ The checked-in Rust table is generated from that manifest, and non-Rust clients
33
+ consume the same manifest from the npm protocol package. A native Host may
34
+ supervise Hub and Node processes, but it is not a public App Facade executor;
35
+ Host process management remains an implementation detail behind the selected
36
+ Hub. Lion's legacy controller annotations and non-`/app/*` protocols are
37
+ outside this contract.
@@ -0,0 +1,68 @@
1
+ {
2
+ "startRequest": {
3
+ "source": {
4
+ "kind": "plugin",
5
+ "nodeType": "camera",
6
+ "nodeId": "camera-1",
7
+ "flowId": "provider.connect",
8
+ "subjectId": "onvif"
9
+ }
10
+ },
11
+ "resolveRequest": {
12
+ "sessionId": "session-1",
13
+ "commandId": "command-1",
14
+ "expectedRevision": 1,
15
+ "input": { "$host": "192.0.2.1" },
16
+ "vars": ["$cameras"],
17
+ "force": false
18
+ },
19
+ "transitionRequest": {
20
+ "sessionId": "session-1",
21
+ "commandId": "command-2",
22
+ "expectedRevision": 2,
23
+ "input": { "$camera": "camera-1" }
24
+ },
25
+ "completeRequest": {
26
+ "sessionId": "session-1",
27
+ "commandId": "command-3",
28
+ "expectedRevision": 3
29
+ },
30
+ "cancelRequest": {
31
+ "sessionId": "session-1",
32
+ "commandId": "command-4"
33
+ },
34
+ "view": {
35
+ "sessionId": "session-1",
36
+ "revision": 1,
37
+ "stepId": "credentials",
38
+ "content": {
39
+ "type": "form",
40
+ "presentation": {
41
+ "renderer": "typedForm",
42
+ "title": "Connect camera provider"
43
+ },
44
+ "form": {
45
+ "fields": [
46
+ {
47
+ "var": "$password",
48
+ "valueType": "string",
49
+ "control": "password",
50
+ "required": true,
51
+ "repeat": false,
52
+ "label": "Password",
53
+ "readOnly": false,
54
+ "hasValue": false
55
+ }
56
+ ]
57
+ }
58
+ },
59
+ "values": {},
60
+ "resolutions": [],
61
+ "readyToComplete": false
62
+ },
63
+ "completeResponse": {
64
+ "completed": true,
65
+ "result": { "providerConnectionId": "provider-1" }
66
+ },
67
+ "cancelResponse": { "cancelled": true }
68
+ }
@@ -1,7 +1,9 @@
1
1
  {
2
2
  "manifest": "mhome.app-facade.v1",
3
- "contractVersion": "1.1.1",
3
+ "contractVersion": "1.3.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": {
6
8
  "messaging": {
7
9
  "targets": "manifest/targets.v1.json"
@@ -24,9 +26,22 @@
24
26
  "extensionPriority": "after_exact"
25
27
  },
26
28
  "runtime": {
29
+ "contract": "mhome.runtime.status.v1",
30
+ "resourceTypes": ["nodeInstance", "nodeRuntime"],
27
31
  "requestTargets": ["/app/runtime/status/list"],
28
- "eventTargets": ["/app/runtime/status/changed"],
29
- "authority": "host"
32
+ "eventTargets": ["/app/runtime/status/changed"]
33
+ },
34
+ "interactionFlow": {
35
+ "schema": "schema/interaction-flow-app.v1.schema.json",
36
+ "requestTargets": [
37
+ "/app/interaction-flow/start",
38
+ "/app/interaction-flow/resolve",
39
+ "/app/interaction-flow/next",
40
+ "/app/interaction-flow/back",
41
+ "/app/interaction-flow/complete",
42
+ "/app/interaction-flow/cancel"
43
+ ],
44
+ "sessionPersistence": "memory"
30
45
  }
31
46
  }
32
47
  }
@@ -0,0 +1,46 @@
1
+ {
2
+ "manifest": "mhome.app-facade.routing.v1",
3
+ "contractVersion": "1.3.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/system/feedback/submit",
20
+ "/app/timeline/entity/latest/list"
21
+ ],
22
+ "scopeModeTargets": [
23
+ "/app/scope/context/get"
24
+ ],
25
+ "hubPrefixes": [
26
+ "/app/plugin/",
27
+ "/app/interaction-flow/",
28
+ "/app/object-storage/",
29
+ "/app/runtime/"
30
+ ],
31
+ "requestPlacementPrefixes": [
32
+ "/app/messaging/"
33
+ ],
34
+ "cloudRelayTargets": [
35
+ "/app/plugin/candidate/list",
36
+ "/app/plugin/detail/get",
37
+ "/app/plugin/installed/list",
38
+ "/app/object-storage/overview",
39
+ "/app/object-storage/folders/create",
40
+ "/app/object-storage/folders/get",
41
+ "/app/object-storage/folders/update",
42
+ "/app/object-storage/folders/list",
43
+ "/app/object-storage/settings/update"
44
+ ]
45
+ }
46
+ }
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "manifest": "mhome.messaging.targets.v1",
3
- "contractVersion": "1.1.1",
3
+ "contractVersion": "1.3.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.1.1",
3
+ "version": "1.3.0",
4
4
  "description": "Build-time protocol artifacts for mhome.app-facade",
5
5
  "license": "MIT",
6
6
  "repository": {
package/protocol.json CHANGED
@@ -1,13 +1,16 @@
1
1
  {
2
2
  "protocol": "mhome.app-facade",
3
- "contractVersion": "1.1.1",
3
+ "contractVersion": "1.3.0",
4
4
  "manifest": "manifest/app-facade.v1.json",
5
5
  "schemas": {
6
6
  "call": "schema/facade-call.v1.schema.json",
7
- "frame": "schema/messaging-frame.v3.schema.json"
7
+ "frame": "schema/messaging-frame.v3.schema.json",
8
+ "interactionFlow": "schema/interaction-flow-app.v1.schema.json",
9
+ "routing": "schema/routing.v1.schema.json"
8
10
  },
9
11
  "fixtures": {
10
12
  "valid": "fixtures",
11
- "invalid": "fixtures/invalid"
13
+ "invalid": "fixtures/invalid",
14
+ "interactionFlow": "fixtures/interaction-flow.conformance.json"
12
15
  }
13
16
  }
@@ -0,0 +1,183 @@
1
+ {
2
+ "$schema": "https://json-schema.org/draft/2020-12/schema",
3
+ "$id": "urn:mhome:app-facade:interaction-flow:v1",
4
+ "title": "MeowLink Interaction Flow App protocol v1",
5
+ "type": "object",
6
+ "additionalProperties": false,
7
+ "required": ["startRequest", "resolveRequest", "transitionRequest", "completeRequest", "cancelRequest", "view", "completeResponse", "cancelResponse"],
8
+ "properties": {
9
+ "startRequest": { "$ref": "#/$defs/startRequest" },
10
+ "resolveRequest": { "$ref": "#/$defs/resolveRequest" },
11
+ "transitionRequest": { "$ref": "#/$defs/transitionRequest" },
12
+ "completeRequest": { "$ref": "#/$defs/completeRequest" },
13
+ "cancelRequest": { "$ref": "#/$defs/cancelRequest" },
14
+ "view": { "$ref": "#/$defs/view" },
15
+ "completeResponse": { "$ref": "#/$defs/completeResponse" },
16
+ "cancelResponse": { "$ref": "#/$defs/cancelResponse" }
17
+ },
18
+ "$defs": {
19
+ "nonEmpty": { "type": "string", "minLength": 1, "maxLength": 256 },
20
+ "source": {
21
+ "type": "object",
22
+ "additionalProperties": false,
23
+ "required": ["kind", "nodeType", "nodeId", "flowId"],
24
+ "properties": {
25
+ "kind": { "const": "plugin" },
26
+ "nodeType": { "$ref": "#/$defs/nonEmpty" },
27
+ "nodeId": { "$ref": "#/$defs/nonEmpty" },
28
+ "flowId": { "$ref": "#/$defs/nonEmpty" },
29
+ "subjectId": { "$ref": "#/$defs/nonEmpty" }
30
+ }
31
+ },
32
+ "startRequest": {
33
+ "type": "object",
34
+ "additionalProperties": false,
35
+ "required": ["source"],
36
+ "properties": { "source": { "$ref": "#/$defs/source" } }
37
+ },
38
+ "resolveRequest": {
39
+ "type": "object",
40
+ "additionalProperties": false,
41
+ "required": ["sessionId", "commandId", "expectedRevision", "vars"],
42
+ "properties": {
43
+ "sessionId": { "$ref": "#/$defs/nonEmpty" },
44
+ "commandId": { "$ref": "#/$defs/nonEmpty" },
45
+ "expectedRevision": { "type": "integer", "minimum": 0 },
46
+ "input": { "type": "object" },
47
+ "vars": { "type": "array", "items": { "$ref": "#/$defs/nonEmpty" }, "maxItems": 128 },
48
+ "force": { "type": "boolean" }
49
+ }
50
+ },
51
+ "transitionRequest": {
52
+ "type": "object",
53
+ "additionalProperties": false,
54
+ "required": ["sessionId", "commandId", "expectedRevision"],
55
+ "properties": {
56
+ "sessionId": { "$ref": "#/$defs/nonEmpty" },
57
+ "commandId": { "$ref": "#/$defs/nonEmpty" },
58
+ "expectedRevision": { "type": "integer", "minimum": 0 },
59
+ "input": { "type": "object" }
60
+ }
61
+ },
62
+ "completeRequest": {
63
+ "type": "object",
64
+ "additionalProperties": false,
65
+ "required": ["sessionId", "commandId", "expectedRevision"],
66
+ "properties": {
67
+ "sessionId": { "$ref": "#/$defs/nonEmpty" },
68
+ "commandId": { "$ref": "#/$defs/nonEmpty" },
69
+ "expectedRevision": { "type": "integer", "minimum": 0 }
70
+ }
71
+ },
72
+ "cancelRequest": {
73
+ "type": "object",
74
+ "additionalProperties": false,
75
+ "required": ["sessionId", "commandId"],
76
+ "properties": {
77
+ "sessionId": { "$ref": "#/$defs/nonEmpty" },
78
+ "commandId": { "$ref": "#/$defs/nonEmpty" }
79
+ }
80
+ },
81
+ "presentation": {
82
+ "type": "object",
83
+ "additionalProperties": false,
84
+ "required": ["renderer"],
85
+ "properties": {
86
+ "renderer": { "const": "typedForm" },
87
+ "title": { "type": "string" },
88
+ "description": { "type": "string" },
89
+ "content": { "type": "string" }
90
+ }
91
+ },
92
+ "field": {
93
+ "type": "object",
94
+ "additionalProperties": false,
95
+ "required": ["var", "valueType", "control", "required", "repeat", "readOnly", "hasValue"],
96
+ "properties": {
97
+ "var": { "$ref": "#/$defs/nonEmpty" },
98
+ "valueType": { "enum": ["string", "boolean"] },
99
+ "control": { "enum": ["text", "password", "longText", "select", "boolean"] },
100
+ "required": { "type": "boolean" },
101
+ "repeat": { "type": "boolean" },
102
+ "label": { "type": "string" },
103
+ "options": { "type": "array" },
104
+ "optionUnavailableText": { "type": "string" },
105
+ "readOnly": { "type": "boolean" },
106
+ "hasValue": { "type": "boolean" },
107
+ "minRows": { "type": "integer", "minimum": 1 }
108
+ }
109
+ },
110
+ "resolution": {
111
+ "type": "object",
112
+ "additionalProperties": false,
113
+ "required": ["var", "available", "dependsOn"],
114
+ "properties": {
115
+ "var": { "$ref": "#/$defs/nonEmpty" },
116
+ "available": { "type": "boolean" },
117
+ "dependsOn": {
118
+ "type": "array",
119
+ "items": { "$ref": "#/$defs/nonEmpty" },
120
+ "uniqueItems": true
121
+ }
122
+ }
123
+ },
124
+ "content": {
125
+ "oneOf": [
126
+ {
127
+ "type": "object",
128
+ "additionalProperties": false,
129
+ "required": ["type", "presentation", "form"],
130
+ "properties": {
131
+ "type": { "const": "form" },
132
+ "presentation": { "$ref": "#/$defs/presentation" },
133
+ "form": {
134
+ "type": "object",
135
+ "additionalProperties": false,
136
+ "required": ["fields"],
137
+ "properties": { "fields": { "type": "array", "items": { "$ref": "#/$defs/field" } } }
138
+ }
139
+ }
140
+ },
141
+ {
142
+ "type": "object",
143
+ "additionalProperties": false,
144
+ "required": ["type", "presentation", "authorizationUrl", "completionMode"],
145
+ "properties": {
146
+ "type": { "const": "externalAuth" },
147
+ "presentation": { "$ref": "#/$defs/presentation" },
148
+ "authorizationUrl": { "type": "string", "format": "uri" },
149
+ "completionMode": { "enum": ["callback", "poll"] },
150
+ "pollAfterMs": { "type": "integer", "minimum": 250, "maximum": 60000 }
151
+ }
152
+ }
153
+ ]
154
+ },
155
+ "view": {
156
+ "type": "object",
157
+ "additionalProperties": false,
158
+ "required": ["sessionId", "revision", "stepId", "content", "resolutions", "readyToComplete"],
159
+ "properties": {
160
+ "sessionId": { "$ref": "#/$defs/nonEmpty" },
161
+ "revision": { "type": "integer", "minimum": 0 },
162
+ "stepId": { "$ref": "#/$defs/nonEmpty" },
163
+ "content": { "$ref": "#/$defs/content" },
164
+ "values": { "type": "object" },
165
+ "resolutions": { "type": "array", "items": { "$ref": "#/$defs/resolution" } },
166
+ "backStepId": { "$ref": "#/$defs/nonEmpty" },
167
+ "readyToComplete": { "type": "boolean" }
168
+ }
169
+ },
170
+ "completeResponse": {
171
+ "type": "object",
172
+ "additionalProperties": false,
173
+ "required": ["completed"],
174
+ "properties": { "completed": { "type": "boolean" }, "result": true }
175
+ },
176
+ "cancelResponse": {
177
+ "type": "object",
178
+ "additionalProperties": false,
179
+ "required": ["cancelled"],
180
+ "properties": { "cancelled": { "type": "boolean" } }
181
+ }
182
+ }
183
+ }
@@ -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
+ }