@ue-shed/protocol 0.1.0-rc.4 → 0.1.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.
Files changed (83) hide show
  1. package/README.md +1 -1
  2. package/contracts/cameras/provisioning/v1/README.md +12 -0
  3. package/contracts/cameras/provisioning/v1/fixtures/provision-request-valid.json +14 -0
  4. package/contracts/cameras/provisioning/v1/provision-request.schema.json +90 -0
  5. package/contracts/cameras/review/v1/README.md +39 -10
  6. package/contracts/cameras/review/v1/assessment-capabilities.schema.json +86 -0
  7. package/contracts/cameras/review/v1/capture-request.schema.json +173 -19
  8. package/contracts/cameras/review/v1/capture-response.schema.json +576 -1
  9. package/contracts/cameras/review/v1/fixtures/assessment-capabilities.json +36 -0
  10. package/contracts/cameras/review/v1/fixtures/capture-area.json +42 -0
  11. package/contracts/cameras/review/v1/fixtures/capture-assessed-v2.json +56 -0
  12. package/contracts/cameras/review/v1/fixtures/capture-assessed.json +55 -0
  13. package/contracts/cameras/review/v1/fixtures/capture-clear-failed.json +62 -0
  14. package/contracts/cameras/review/v1/fixtures/capture-clear.json +72 -0
  15. package/contracts/cameras/review/v1/fixtures/capture-request-area-valid.json +29 -0
  16. package/contracts/cameras/review/v1/fixtures/capture-request-clear-valid.json +30 -0
  17. package/contracts/cameras/review/v1/fixtures/capture-request-relative-valid.json +29 -0
  18. package/contracts/cameras/review/v1/fixtures/invalid-assessment-capabilities-supported-without-effective-method.json +14 -0
  19. package/contracts/scenarios/live/v1/README.md +9 -0
  20. package/contracts/scenarios/live/v1/fixtures/cancel-accepted.json +8 -0
  21. package/contracts/scenarios/live/v1/fixtures/execution-request.json +44 -0
  22. package/contracts/scenarios/live/v1/fixtures/prepare-prepared.json +9 -0
  23. package/contracts/scenarios/live/v1/fixtures/start-accepted.json +10 -0
  24. package/contracts/scenarios/live/v1/fixtures/status-active.json +11 -0
  25. package/contracts/scenarios/live/v1/fixtures/status-rejected-stale.json +10 -0
  26. package/contracts/scenarios/live/v1/fixtures/status-terminal-cancelled.json +33 -0
  27. package/contracts/scenarios/live/v1/fixtures/status-terminal-missing-divergence.json +54 -0
  28. package/contracts/uasset-io/v1/README.md +34 -0
  29. package/contracts/uasset-io/v1/event.schema.json +6779 -0
  30. package/contracts/uasset-io/v1/fixtures/invalid/event-result-unknown-kind.json +7 -0
  31. package/contracts/uasset-io/v1/fixtures/invalid/event-unknown-kind.json +6 -0
  32. package/contracts/uasset-io/v1/fixtures/invalid/project-index-page-unbounded.json +7196 -0
  33. package/contracts/uasset-io/v1/fixtures/invalid/project-index-query-oversize-limit.json +15 -0
  34. package/contracts/uasset-io/v1/fixtures/invalid/request-wrong-major.json +6 -0
  35. package/contracts/uasset-io/v1/fixtures/valid/accepted-event.json +7 -0
  36. package/contracts/uasset-io/v1/fixtures/valid/authoring-result-event.json +26 -0
  37. package/contracts/uasset-io/v1/fixtures/valid/extract-text-occurrence-result-event.json +26 -0
  38. package/contracts/uasset-io/v1/fixtures/valid/extract-text-result-event.json +23 -0
  39. package/contracts/uasset-io/v1/fixtures/valid/extract-text-summary-result-event.json +23 -0
  40. package/contracts/uasset-io/v1/fixtures/valid/extract-texture-record-result-event.json +29 -0
  41. package/contracts/uasset-io/v1/fixtures/valid/inspect-result-event.json +29 -0
  42. package/contracts/uasset-io/v1/fixtures/valid/partial-completed-event.json +7 -0
  43. package/contracts/uasset-io/v1/fixtures/valid/project-index-accepted-event.json +7 -0
  44. package/contracts/uasset-io/v1/fixtures/valid/project-index-page-result-event.json +28 -0
  45. package/contracts/uasset-io/v1/fixtures/valid/project-index-progress-event.json +9 -0
  46. package/contracts/uasset-io/v1/fixtures/valid/project-index-query-request.json +19 -0
  47. package/contracts/uasset-io/v1/fixtures/valid/project-index-rebuild-request.json +13 -0
  48. package/contracts/uasset-io/v1/fixtures/valid/project-index-refresh-request.json +13 -0
  49. package/contracts/uasset-io/v1/fixtures/valid/project-index-stale-generation-failed-event.json +11 -0
  50. package/contracts/uasset-io/v1/fixtures/valid/project-index-status-request.json +13 -0
  51. package/contracts/uasset-io/v1/fixtures/valid/project-index-status-result-event.json +22 -0
  52. package/contracts/uasset-io/v1/fixtures/valid/project-index-summary-result-event.json +25 -0
  53. package/contracts/uasset-io/v1/fixtures/valid/saved-world-result-event.json +27 -0
  54. package/contracts/uasset-io/v1/fixtures/valid/scan-asset-result-event.json +47 -0
  55. package/contracts/uasset-io/v1/fixtures/valid/scan-inventory-result-event.json +15 -0
  56. package/contracts/uasset-io/v1/fixtures/valid/scan-request.json +17 -0
  57. package/contracts/uasset-io/v1/fixtures/valid/scan-summary-result-event.json +24 -0
  58. package/contracts/uasset-io/v1/request.schema.json +512 -0
  59. package/dist/companion.d.ts +16 -0
  60. package/dist/companion.d.ts.map +1 -1
  61. package/dist/companion.js +8 -0
  62. package/dist/companion.js.map +1 -1
  63. package/dist/editor-asset-navigation.d.ts +63 -0
  64. package/dist/editor-asset-navigation.d.ts.map +1 -0
  65. package/dist/editor-asset-navigation.js +32 -0
  66. package/dist/editor-asset-navigation.js.map +1 -0
  67. package/dist/index.d.ts +4 -0
  68. package/dist/index.d.ts.map +1 -1
  69. package/dist/index.js +4 -0
  70. package/dist/index.js.map +1 -1
  71. package/dist/saved-world.d.ts +223 -0
  72. package/dist/saved-world.d.ts.map +1 -0
  73. package/dist/saved-world.js +82 -0
  74. package/dist/saved-world.js.map +1 -0
  75. package/dist/uasset-inspection.d.ts +1037 -0
  76. package/dist/uasset-inspection.d.ts.map +1 -0
  77. package/dist/uasset-inspection.js +446 -0
  78. package/dist/uasset-inspection.js.map +1 -0
  79. package/dist/uasset-io.d.ts +2602 -0
  80. package/dist/uasset-io.d.ts.map +1 -0
  81. package/dist/uasset-io.js +306 -0
  82. package/dist/uasset-io.js.map +1 -0
  83. package/package.json +3 -2
package/README.md CHANGED
@@ -4,7 +4,7 @@ Runtime schemas, branded identifiers, compatibility values, and versioned wire c
4
4
  UE Shed clients and Unreal companion plugins.
5
5
 
6
6
  ```sh
7
- npm install @ue-shed/protocol@0.1.0-rc.4 effect@4.0.0-beta.98
7
+ npm install --save-exact @ue-shed/protocol effect@4.0.0-beta.98
8
8
  ```
9
9
 
10
10
  The package supports Node.js 22.14 or newer and exposes one stable JavaScript entry point:
@@ -0,0 +1,12 @@
1
+ # Provisioned camera contract v1
2
+
3
+ `EnsureProvisionedCameras` accepts this bounded JSON request through Remote Control. A provisioned
4
+ camera is a transient runtime realization, identified by a generated `ProvisionedCameraId`; it is
5
+ never a durable Map Review camera record.
6
+
7
+ Each request carries an explicit correlation to either a framing candidate or a durable Review View.
8
+ The compatibility decoder accepts the former candidate-only request shape for already-installed
9
+ clients, but new clients emit only `schemaVersion: 2` and the `correlation` union.
10
+
11
+ The editor returns the same correlation for every provisioned camera. Array index remains a live
12
+ frame transport position, never durable identity.
@@ -0,0 +1,14 @@
1
+ {
2
+ "schemaVersion": 2,
3
+ "previewFps": 5,
4
+ "cameras": [
5
+ {
6
+ "correlation": { "type": "framing_candidate", "candidateId": "context_three_quarter" },
7
+ "fieldOfViewDegrees": 60,
8
+ "location": { "x": 1200, "y": -1400, "z": 700 },
9
+ "rotation": { "pitch": -12, "yaw": 135, "roll": 0 },
10
+ "width": 320,
11
+ "height": 180
12
+ }
13
+ ]
14
+ }
@@ -0,0 +1,90 @@
1
+ {
2
+ "$schema": "https://json-schema.org/draft/2020-12/schema",
3
+ "$id": "https://ue-shed.dev/contracts/cameras/provisioning/v1/provision-request.schema.json",
4
+ "title": "UE Shed provisioned camera request v1",
5
+ "type": "object",
6
+ "additionalProperties": false,
7
+ "required": ["schemaVersion", "previewFps", "cameras"],
8
+ "properties": {
9
+ "schemaVersion": { "const": 2 },
10
+ "previewFps": { "type": "integer", "minimum": 1, "maximum": 10 },
11
+ "cameras": {
12
+ "type": "array",
13
+ "minItems": 1,
14
+ "maxItems": 32,
15
+ "items": {
16
+ "type": "object",
17
+ "additionalProperties": false,
18
+ "required": [
19
+ "correlation",
20
+ "fieldOfViewDegrees",
21
+ "location",
22
+ "rotation",
23
+ "width",
24
+ "height"
25
+ ],
26
+ "properties": {
27
+ "correlation": {
28
+ "oneOf": [
29
+ {
30
+ "type": "object",
31
+ "additionalProperties": false,
32
+ "required": ["type", "candidateId"],
33
+ "properties": {
34
+ "type": { "const": "framing_candidate" },
35
+ "candidateId": {
36
+ "type": "string",
37
+ "minLength": 1,
38
+ "maxLength": 128,
39
+ "pattern": "^[A-Za-z0-9][A-Za-z0-9._-]{0,127}$"
40
+ }
41
+ }
42
+ },
43
+ {
44
+ "type": "object",
45
+ "additionalProperties": false,
46
+ "required": ["type", "reviewViewId"],
47
+ "properties": {
48
+ "type": { "const": "review_view" },
49
+ "reviewViewId": {
50
+ "type": "string",
51
+ "minLength": 1,
52
+ "maxLength": 128,
53
+ "pattern": "^[A-Za-z0-9][A-Za-z0-9._-]{0,127}$"
54
+ }
55
+ }
56
+ }
57
+ ]
58
+ },
59
+ "fieldOfViewDegrees": { "type": "number", "minimum": 5, "maximum": 170 },
60
+ "location": { "$ref": "#/$defs/vector" },
61
+ "rotation": { "$ref": "#/$defs/rotation" },
62
+ "width": { "type": "integer", "minimum": 64, "maximum": 2560 },
63
+ "height": { "type": "integer", "minimum": 64, "maximum": 1440 }
64
+ }
65
+ }
66
+ }
67
+ },
68
+ "$defs": {
69
+ "vector": {
70
+ "type": "object",
71
+ "additionalProperties": false,
72
+ "required": ["x", "y", "z"],
73
+ "properties": {
74
+ "x": { "type": "number" },
75
+ "y": { "type": "number" },
76
+ "z": { "type": "number" }
77
+ }
78
+ },
79
+ "rotation": {
80
+ "type": "object",
81
+ "additionalProperties": false,
82
+ "required": ["pitch", "yaw", "roll"],
83
+ "properties": {
84
+ "pitch": { "type": "number" },
85
+ "yaw": { "type": "number" },
86
+ "roll": { "type": "number" }
87
+ }
88
+ }
89
+ }
90
+ }
@@ -1,22 +1,51 @@
1
1
  # Map Review capture contract v1
2
2
 
3
3
  The checked-in JSON Schemas in this directory are the language-neutral authority for the stable
4
- editor wire surface shared by TypeScript and UEShedCameras: capture request/response and selection /
5
- subject-inspection response. TypeScript Effect codecs in `@ue-shed/cameras` and the Unreal C++
6
- companion must remain conformant with them.
4
+ editor wire surface shared by TypeScript and UEShedCameras: capture request/response, optional
5
+ assessment capabilities, and selection / subject-inspection response. TypeScript Effect codecs in
6
+ `@ue-shed/cameras` and the Unreal C++ companion must remain conformant with them.
7
7
 
8
8
  Portable Review Set / Capture Run documents and Workbench IPC remain TypeScript-owned Effect schemas
9
9
  in `@ue-shed/cameras`. They are deliberately outside this JSON authority while Map Review authoring
10
10
  recovery, live preview, and World Scout streaming plans remain active.
11
11
 
12
- The control-plane request asks a separately enabled editor capability to resolve one actor subject,
13
- realize one approved perspective pose transiently, and write one Pure PNG into the project's bounded
14
- review staging directory. The response reports the staged path, effective dimensions, resolved map
15
- and subject, duration, and map-package dirty state before and after capture.
12
+ Minor versions 0–1 accept the original actor plus approved-world-pose request. Minor version 2 adds
13
+ actor or oriented-bounds subjects, world-fixed or actor-relative viewpoints, and a requested
14
+ visibility-assessment method. Minor version 3 keeps those inputs but makes the editor response a raw
15
+ visibility measurement: the plugin reports what it observed and does not assign a product-facing
16
+ `clear`, `partial`, or `blocked` classification. Version 2 responses remain readable with their
17
+ original engine-produced classification. Minor version 4 adds one optional Clear companion to the
18
+ same capture operation. Its request carries only an effective producer instruction (`isolate_target`
19
+ or bounded `hide_explicit` actor paths); consumer policy, thresholds, and presentation remain
20
+ outside the wire contract.
16
21
 
17
- The staged file is not durable evidence. A trusted host validates that the path is beneath
18
- `Saved/UEShed/ReviewStaging`, hashes and copies the PNG into an immutable Capture Run, then deletes the
19
- staged file. The editor capability never accepts an arbitrary output path.
22
+ The editor resolves an actor-relative pose atomically from the actor's current transform. Its
23
+ response records the resolved target, exact effective world pose, projection, bounded visibility
24
+ measurement, staged Pure image, optional staged Clear companion, duration, and map-package dirty
25
+ state. The companion reports its explicit component-list intervention and restoration outcome; a
26
+ Clear failure retains Pure evidence as a typed partial result. Current Capture Runs preserve that raw
27
+ measurement. `@ue-shed/cameras` provides an optional pure classification helper only when a consumer
28
+ supplies its own thresholds; UE Shed does not prescribe defaults. Capture Run v1.2 classifications
29
+ remain readable after migration as explicitly legacy interpretation rather than current evidence.
30
+
31
+ For version 3 actor requests, `automatic` resolves to a bounded render-truthful depth comparison.
32
+ The editor makes one full-scene depth capture and one subject-only depth capture at no more than
33
+ 320×180, then reports the fraction of subject-depth pixels that remain visible in the full scene.
34
+ The method records its version and limitations; translucent or otherwise non-depth-writing subjects
35
+ fail assessment instead of producing a fabricated percentage. Explicit `ray_samples` remains
36
+ available as a cheaper diagnostic because collision and rendered visibility can disagree.
37
+ Unprojectable or fully offscreen v1.3 requests also return `not_assessed`, with the projection
38
+ diagnosis preserved separately. Oriented-area requests return `not_assessed`; area contents are not
39
+ treated as blockers. The requested subject-mask method remains unsupported.
40
+
41
+ `assessment-capabilities.schema.json` describes an optional producer fact report. It records which
42
+ requested assessment methods are supported by this editor, their effective method/version, and the
43
+ maximum depth-comparison render size. It does not select a method, classify a measurement, or set
44
+ consumer visibility thresholds; callers may ignore it and use capture responses alone.
45
+
46
+ Staged files are not durable evidence. A trusted host validates that every path is beneath
47
+ `Saved/UEShed/ReviewStaging`, hashes and copies each PNG into an immutable Capture Run, then deletes
48
+ the staged files. The editor capability never accepts an arbitrary output path.
20
49
 
21
50
  Requests and responses declare `ue-shed-review-capture` contract major version 1. Expected failures
22
51
  are structured, include recovery guidance and retry safety, and never masquerade as captured images.
@@ -0,0 +1,86 @@
1
+ {
2
+ "$schema": "https://json-schema.org/draft/2020-12/schema",
3
+ "$id": "https://ue-shed.dev/contracts/cameras/review/v1/assessment-capabilities.schema.json",
4
+ "title": "UE Shed Map Review assessment capabilities v1",
5
+ "type": "object",
6
+ "additionalProperties": false,
7
+ "required": ["contract", "depthCompareMaximumResolution", "methods"],
8
+ "properties": {
9
+ "contract": {
10
+ "type": "object",
11
+ "additionalProperties": false,
12
+ "required": ["name", "version"],
13
+ "properties": {
14
+ "name": { "const": "ue-shed-review-assessment-capabilities" },
15
+ "version": {
16
+ "type": "object",
17
+ "additionalProperties": false,
18
+ "required": ["major", "minor"],
19
+ "properties": {
20
+ "major": { "const": 1 },
21
+ "minor": { "const": 0 }
22
+ }
23
+ }
24
+ }
25
+ },
26
+ "depthCompareMaximumResolution": {
27
+ "type": "object",
28
+ "additionalProperties": false,
29
+ "required": ["width", "height"],
30
+ "properties": {
31
+ "width": { "type": "integer", "minimum": 1 },
32
+ "height": { "type": "integer", "minimum": 1 }
33
+ }
34
+ },
35
+ "methods": {
36
+ "type": "array",
37
+ "minItems": 1,
38
+ "maxItems": 16,
39
+ "items": { "$ref": "#/$defs/methodCapability" }
40
+ }
41
+ },
42
+ "$defs": {
43
+ "effectiveMethod": {
44
+ "type": "object",
45
+ "additionalProperties": false,
46
+ "required": ["method", "version"],
47
+ "properties": {
48
+ "method": { "enum": ["ray_samples", "subject_mask", "depth_compare"] },
49
+ "version": { "type": "integer", "minimum": 1 }
50
+ }
51
+ },
52
+ "methodCapability": {
53
+ "oneOf": [
54
+ {
55
+ "type": "object",
56
+ "additionalProperties": false,
57
+ "required": ["requestedMethod", "status", "effectiveMethod", "limitations"],
58
+ "properties": {
59
+ "requestedMethod": {
60
+ "enum": ["automatic", "ray_samples", "subject_mask", "depth_compare"]
61
+ },
62
+ "status": { "const": "supported" },
63
+ "effectiveMethod": { "$ref": "#/$defs/effectiveMethod" },
64
+ "limitations": {
65
+ "type": "array",
66
+ "maxItems": 8,
67
+ "items": { "type": "string" }
68
+ }
69
+ }
70
+ },
71
+ {
72
+ "type": "object",
73
+ "additionalProperties": false,
74
+ "required": ["requestedMethod", "status", "reason"],
75
+ "properties": {
76
+ "requestedMethod": {
77
+ "enum": ["automatic", "ray_samples", "subject_mask", "depth_compare"]
78
+ },
79
+ "status": { "const": "unsupported" },
80
+ "reason": { "type": "string", "minLength": 1 }
81
+ }
82
+ }
83
+ ]
84
+ }
85
+ }
86
+ }
@@ -4,15 +4,7 @@
4
4
  "title": "UE Shed Map Review capture request v1",
5
5
  "type": "object",
6
6
  "additionalProperties": false,
7
- "required": [
8
- "contract",
9
- "operationId",
10
- "viewId",
11
- "expectedMapPath",
12
- "subject",
13
- "approvedPose",
14
- "resolution"
15
- ],
7
+ "required": ["contract", "operationId", "viewId", "expectedMapPath", "subject", "resolution"],
16
8
  "properties": {
17
9
  "contract": {
18
10
  "type": "object",
@@ -26,7 +18,7 @@
26
18
  "required": ["major", "minor"],
27
19
  "properties": {
28
20
  "major": { "const": 1 },
29
- "minor": { "type": "integer", "minimum": 0 }
21
+ "minor": { "type": "integer", "minimum": 0, "maximum": 4 }
30
22
  }
31
23
  }
32
24
  }
@@ -35,14 +27,27 @@
35
27
  "viewId": { "$ref": "#/$defs/safeId" },
36
28
  "expectedMapPath": { "type": "string", "minLength": 1 },
37
29
  "subject": {
38
- "type": "object",
39
- "additionalProperties": false,
40
- "required": ["kind", "actorPath"],
41
- "properties": {
42
- "kind": { "const": "actor_path" },
43
- "actorPath": { "type": "string", "minLength": 1 },
44
- "diagnosticLabel": { "type": "string", "minLength": 1 }
45
- }
30
+ "oneOf": [
31
+ {
32
+ "type": "object",
33
+ "additionalProperties": false,
34
+ "required": ["kind", "actorPath"],
35
+ "properties": {
36
+ "kind": { "const": "actor_path" },
37
+ "actorPath": { "type": "string", "minLength": 1 },
38
+ "diagnosticLabel": { "type": "string", "minLength": 1 }
39
+ }
40
+ },
41
+ {
42
+ "type": "object",
43
+ "additionalProperties": false,
44
+ "required": ["kind", "bounds"],
45
+ "properties": {
46
+ "kind": { "const": "oriented_bounds" },
47
+ "bounds": { "$ref": "#/$defs/bounds" }
48
+ }
49
+ }
50
+ ]
46
51
  },
47
52
  "approvedPose": {
48
53
  "type": "object",
@@ -64,8 +69,39 @@
64
69
  "width": { "type": "integer", "minimum": 160, "maximum": 3840 },
65
70
  "height": { "type": "integer", "minimum": 90, "maximum": 2160 }
66
71
  }
67
- }
72
+ },
73
+ "assessment": { "$ref": "#/$defs/assessment" },
74
+ "clearCompanion": { "$ref": "#/$defs/clearCompanion" },
75
+ "viewpoint": { "$ref": "#/$defs/viewpoint" }
68
76
  },
77
+ "allOf": [
78
+ {
79
+ "if": {
80
+ "properties": {
81
+ "contract": {
82
+ "properties": {
83
+ "version": { "properties": { "minor": { "enum": [2, 3, 4] } } }
84
+ }
85
+ }
86
+ }
87
+ },
88
+ "then": { "required": ["assessment", "viewpoint"] },
89
+ "else": { "required": ["approvedPose"] }
90
+ },
91
+ {
92
+ "if": {
93
+ "properties": {
94
+ "contract": {
95
+ "properties": {
96
+ "version": { "properties": { "minor": { "const": 4 } } }
97
+ }
98
+ }
99
+ }
100
+ },
101
+ "then": { "required": ["clearCompanion"] },
102
+ "else": { "not": { "required": ["clearCompanion"] } }
103
+ }
104
+ ],
69
105
  "$defs": {
70
106
  "safeId": { "type": "string", "pattern": "^[A-Za-z0-9][A-Za-z0-9._-]{0,127}$" },
71
107
  "vector": {
@@ -87,6 +123,124 @@
87
123
  "yaw": { "type": "number" },
88
124
  "roll": { "type": "number" }
89
125
  }
126
+ },
127
+ "bounds": {
128
+ "type": "object",
129
+ "additionalProperties": false,
130
+ "required": ["center", "extent", "rotation"],
131
+ "properties": {
132
+ "center": { "$ref": "#/$defs/vector" },
133
+ "extent": { "$ref": "#/$defs/vector" },
134
+ "rotation": { "$ref": "#/$defs/rotation" }
135
+ }
136
+ },
137
+ "assessment": {
138
+ "oneOf": [
139
+ {
140
+ "type": "object",
141
+ "additionalProperties": false,
142
+ "required": ["method"],
143
+ "properties": { "method": { "const": "automatic" } }
144
+ },
145
+ {
146
+ "type": "object",
147
+ "additionalProperties": false,
148
+ "required": ["method", "samplePreset"],
149
+ "properties": {
150
+ "method": { "const": "ray_samples" },
151
+ "samplePreset": { "enum": ["sparse", "standard", "dense"] }
152
+ }
153
+ },
154
+ {
155
+ "type": "object",
156
+ "additionalProperties": false,
157
+ "required": ["method"],
158
+ "properties": { "method": { "enum": ["subject_mask", "depth_compare"] } }
159
+ }
160
+ ]
161
+ },
162
+ "clearCompanion": {
163
+ "oneOf": [
164
+ {
165
+ "type": "object",
166
+ "additionalProperties": false,
167
+ "required": ["status"],
168
+ "properties": { "status": { "const": "not_requested" } }
169
+ },
170
+ {
171
+ "type": "object",
172
+ "additionalProperties": false,
173
+ "required": ["status", "strategy"],
174
+ "properties": {
175
+ "status": { "const": "requested" },
176
+ "strategy": { "const": "isolate_target" }
177
+ }
178
+ },
179
+ {
180
+ "type": "object",
181
+ "additionalProperties": false,
182
+ "required": ["actors", "status", "strategy"],
183
+ "properties": {
184
+ "actors": {
185
+ "type": "array",
186
+ "minItems": 1,
187
+ "maxItems": 32,
188
+ "uniqueItems": true,
189
+ "items": {
190
+ "type": "string",
191
+ "minLength": 7,
192
+ "maxLength": 4096,
193
+ "pattern": "^/Game/"
194
+ }
195
+ },
196
+ "status": { "const": "requested" },
197
+ "strategy": { "const": "hide_explicit" }
198
+ }
199
+ }
200
+ ]
201
+ },
202
+ "viewpoint": {
203
+ "oneOf": [
204
+ {
205
+ "type": "object",
206
+ "additionalProperties": false,
207
+ "required": ["kind", "approvedPose"],
208
+ "properties": {
209
+ "kind": { "const": "world_fixed" },
210
+ "approvedPose": { "$ref": "#/$defs/pose" }
211
+ }
212
+ },
213
+ {
214
+ "type": "object",
215
+ "additionalProperties": false,
216
+ "required": ["kind", "relativePose", "targetSnapshot"],
217
+ "properties": {
218
+ "kind": { "const": "target_relative" },
219
+ "relativePose": { "$ref": "#/$defs/pose" },
220
+ "targetSnapshot": {
221
+ "type": "object",
222
+ "additionalProperties": false,
223
+ "required": ["location", "rotation"],
224
+ "properties": {
225
+ "location": { "$ref": "#/$defs/vector" },
226
+ "rotation": { "$ref": "#/$defs/rotation" }
227
+ }
228
+ }
229
+ }
230
+ }
231
+ ]
232
+ },
233
+ "pose": {
234
+ "type": "object",
235
+ "additionalProperties": false,
236
+ "required": ["aspectRatio", "fieldOfViewDegrees", "location", "projection", "rotation"],
237
+ "properties": {
238
+ "aspectRatio": { "const": "16:9" },
239
+ "fieldOfViewDegrees": { "type": "number", "minimum": 5, "maximum": 170 },
240
+ "projection": { "const": "perspective" },
241
+ "location": { "$ref": "#/$defs/vector" },
242
+ "rotation": { "$ref": "#/$defs/rotation" }
243
+ }
90
244
  }
91
245
  }
92
246
  }