@mhome/artifact-protocol 1.2.0 → 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 CHANGED
@@ -15,3 +15,7 @@ cloud object store or an authenticated local streaming endpoint.
15
15
 
16
16
  TTL, storage placement, filesystem paths, signed URLs, and cloud object keys are
17
17
  runtime concerns and are deliberately not encoded into an artifact reference.
18
+
19
+ Capability media values (`Image`, `Audio`) use `MediaReference`: exactly `{ "uri": "meow-artifact://v1/..." }`. The reference has no URL, inline bytes, MIME or creation timestamp fields. Parse and check kind and tenant/scope at capability boundaries; do not implicitly import media. Upload bytes with `PutArtifactRequest` or explicitly download finite HTTP(S) content with `ImportArtifactRequest` via `/app/artifact/put` and `/app/artifact/import`. Storage metadata and upload transports retain their MIME and byte fields. Resolve to temporary delivery URLs only at consumers. Conversation media sources retain their existing tagged artifact protocol. Video storage remains unsupported by the runtimes.
20
+
21
+ Image put/import/upload preparation accepts optional `transform`: `{ "format": "JPEG", "maxWidth": 2048, "maxHeight": 2048, "quality": 85, "background": "#ffffff" }`. Omit it to preserve source bytes. Conversion applies image orientation, fits within the optional dimensions without upscaling, strips source metadata, and stores only the output. JPEG quality defaults to 85; PNG rejects quality/background. Transparent JPEG input requires an explicit background. Animated input is rejected during conversion; unchanged imports preserve it. Transformed input may be up to 25 MiB, output up to 5 MiB; decoded dimensions remain bounded. The URI digest and metadata describe output bytes.
@@ -1,8 +1,13 @@
1
1
  {
2
2
  "manifest": "mhome.artifact.v1",
3
- "contractVersion": "1.2.0",
3
+ "contractVersion": "1.4.0",
4
4
  "uriPrefix": "meow-artifact://v1/",
5
- "kinds": ["image", "audio", "video", "file"],
5
+ "kinds": [
6
+ "image",
7
+ "audio",
8
+ "video",
9
+ "file"
10
+ ],
6
11
  "resolve": {
7
12
  "target": "/artifact/resolve",
8
13
  "schema": "schema/artifact-resolve.v1.schema.json",
@@ -17,5 +22,13 @@
17
22
  "target": "/artifact/upload/prepare",
18
23
  "schema": "schema/artifact-upload.v1.schema.json",
19
24
  "schemaVersion": 1
25
+ },
26
+ "mediaReference": {
27
+ "schema": "schema/media-reference.v1.schema.json",
28
+ "schemaVersion": 1
29
+ },
30
+ "import": {
31
+ "schema": "schema/artifact-import.v1.schema.json",
32
+ "schemaVersion": 1
20
33
  }
21
34
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mhome/artifact-protocol",
3
- "version": "1.2.0",
3
+ "version": "1.4.0",
4
4
  "description": "Build-time protocol artifacts for mhome.artifact",
5
5
  "license": "MIT",
6
6
  "repository": {
package/protocol.json CHANGED
@@ -1,11 +1,13 @@
1
1
  {
2
2
  "protocol": "mhome.artifact",
3
- "contractVersion": "1.2.0",
3
+ "contractVersion": "1.4.0",
4
4
  "manifest": "manifest/artifact.v1.json",
5
5
  "schemas": {
6
6
  "artifactMetadata": "schema/artifact-metadata.v1.schema.json",
7
7
  "artifactResolve": "schema/artifact-resolve.v1.schema.json",
8
8
  "artifactPut": "schema/artifact-put.v1.schema.json",
9
+ "artifactImport": "schema/artifact-import.v1.schema.json",
10
+ "mediaReference": "schema/media-reference.v1.schema.json",
9
11
  "artifactUpload": "schema/artifact-upload.v1.schema.json"
10
12
  },
11
13
  "fixtures": {
@@ -0,0 +1,107 @@
1
+ {
2
+ "$schema": "https://json-schema.org/draft/2020-12/schema",
3
+ "$id": "https://mhome.ai/schema/artifact-import.v1.schema.json",
4
+ "title": "MeowLink artifact import request",
5
+ "type": "object",
6
+ "additionalProperties": false,
7
+ "required": [
8
+ "kind",
9
+ "sourceUrl"
10
+ ],
11
+ "properties": {
12
+ "kind": {
13
+ "enum": [
14
+ "IMAGE",
15
+ "AUDIO",
16
+ "FILE"
17
+ ]
18
+ },
19
+ "sourceUrl": {
20
+ "type": "string",
21
+ "pattern": "^https?://",
22
+ "minLength": 8
23
+ },
24
+ "mimeType": {
25
+ "type": "string",
26
+ "minLength": 3,
27
+ "maxLength": 255
28
+ },
29
+ "transform": {
30
+ "type": "object",
31
+ "additionalProperties": false,
32
+ "required": [
33
+ "format"
34
+ ],
35
+ "properties": {
36
+ "format": {
37
+ "enum": [
38
+ "JPEG",
39
+ "PNG"
40
+ ]
41
+ },
42
+ "maxWidth": {
43
+ "type": "integer",
44
+ "minimum": 1,
45
+ "maximum": 16384
46
+ },
47
+ "maxHeight": {
48
+ "type": "integer",
49
+ "minimum": 1,
50
+ "maximum": 16384
51
+ },
52
+ "quality": {
53
+ "type": "integer",
54
+ "minimum": 1,
55
+ "maximum": 100
56
+ },
57
+ "background": {
58
+ "type": "string",
59
+ "pattern": "^#[0-9A-Fa-f]{6}$"
60
+ }
61
+ },
62
+ "allOf": [
63
+ {
64
+ "if": {
65
+ "properties": {
66
+ "format": {
67
+ "const": "PNG"
68
+ }
69
+ }
70
+ },
71
+ "then": {
72
+ "not": {
73
+ "anyOf": [
74
+ {
75
+ "required": [
76
+ "quality"
77
+ ]
78
+ },
79
+ {
80
+ "required": [
81
+ "background"
82
+ ]
83
+ }
84
+ ]
85
+ }
86
+ }
87
+ }
88
+ ]
89
+ }
90
+ },
91
+ "allOf": [
92
+ {
93
+ "if": {
94
+ "required": [
95
+ "transform"
96
+ ]
97
+ },
98
+ "then": {
99
+ "properties": {
100
+ "kind": {
101
+ "const": "IMAGE"
102
+ }
103
+ }
104
+ }
105
+ }
106
+ ]
107
+ }
@@ -3,35 +3,178 @@
3
3
  "$id": "https://mhome.ai/schema/artifact-put.v1.schema.json",
4
4
  "title": "mHome Artifact Put v1",
5
5
  "oneOf": [
6
- { "$ref": "#/$defs/request" },
7
- { "$ref": "#/$defs/response" }
6
+ {
7
+ "$ref": "#/$defs/request"
8
+ },
9
+ {
10
+ "$ref": "#/$defs/response"
11
+ }
8
12
  ],
9
13
  "$defs": {
10
14
  "metadata": {
11
15
  "type": "object",
12
16
  "additionalProperties": false,
13
- "required": ["uri", "kind", "mimeType", "sizeBytes"],
17
+ "required": [
18
+ "uri",
19
+ "kind",
20
+ "mimeType",
21
+ "sizeBytes"
22
+ ],
14
23
  "properties": {
15
- "uri": { "type": "string", "pattern": "^meow-artifact://v1/", "maxLength": 2048 },
16
- "kind": { "enum": ["IMAGE", "AUDIO", "VIDEO", "FILE"] },
17
- "mimeType": { "type": "string", "minLength": 3, "maxLength": 255 },
18
- "sizeBytes": { "type": "integer", "minimum": 1, "maximum": 9007199254740991 },
19
- "width": { "type": "integer", "minimum": 1, "maximum": 2147483647 },
20
- "height": { "type": "integer", "minimum": 1, "maximum": 2147483647 },
21
- "durationMillis": { "type": "integer", "minimum": 1, "maximum": 9007199254740991 }
24
+ "uri": {
25
+ "type": "string",
26
+ "pattern": "^meow-artifact://v1/",
27
+ "maxLength": 2048
28
+ },
29
+ "kind": {
30
+ "enum": [
31
+ "IMAGE",
32
+ "AUDIO",
33
+ "VIDEO",
34
+ "FILE"
35
+ ]
36
+ },
37
+ "mimeType": {
38
+ "type": "string",
39
+ "minLength": 3,
40
+ "maxLength": 255
41
+ },
42
+ "sizeBytes": {
43
+ "type": "integer",
44
+ "minimum": 1,
45
+ "maximum": 9007199254740991
46
+ },
47
+ "width": {
48
+ "type": "integer",
49
+ "minimum": 1,
50
+ "maximum": 2147483647
51
+ },
52
+ "height": {
53
+ "type": "integer",
54
+ "minimum": 1,
55
+ "maximum": 2147483647
56
+ },
57
+ "durationMillis": {
58
+ "type": "integer",
59
+ "minimum": 1,
60
+ "maximum": 9007199254740991
61
+ }
22
62
  }
23
63
  },
24
64
  "request": {
25
65
  "type": "object",
26
66
  "additionalProperties": false,
27
- "required": ["kind", "mimeType", "dataBase64"],
67
+ "required": [
68
+ "kind",
69
+ "mimeType",
70
+ "dataBase64"
71
+ ],
28
72
  "properties": {
29
- "kind": { "enum": ["IMAGE", "AUDIO", "VIDEO", "FILE"] },
30
- "mimeType": { "type": "string", "minLength": 3, "maxLength": 255 },
31
- "dataBase64": { "type": "string", "minLength": 4, "maxLength": 70000000, "pattern": "^[A-Za-z0-9+/]+={0,2}$" },
32
- "durationMillis": { "type": "integer", "minimum": 1, "maximum": 9007199254740991 }
33
- }
73
+ "kind": {
74
+ "enum": [
75
+ "IMAGE",
76
+ "AUDIO",
77
+ "VIDEO",
78
+ "FILE"
79
+ ]
80
+ },
81
+ "mimeType": {
82
+ "type": "string",
83
+ "minLength": 3,
84
+ "maxLength": 255
85
+ },
86
+ "dataBase64": {
87
+ "type": "string",
88
+ "minLength": 4,
89
+ "maxLength": 70000000,
90
+ "pattern": "^[A-Za-z0-9+/]+={0,2}$"
91
+ },
92
+ "durationMillis": {
93
+ "type": "integer",
94
+ "minimum": 1,
95
+ "maximum": 9007199254740991
96
+ },
97
+ "transform": {
98
+ "type": "object",
99
+ "additionalProperties": false,
100
+ "required": [
101
+ "format"
102
+ ],
103
+ "properties": {
104
+ "format": {
105
+ "enum": [
106
+ "JPEG",
107
+ "PNG"
108
+ ]
109
+ },
110
+ "maxWidth": {
111
+ "type": "integer",
112
+ "minimum": 1,
113
+ "maximum": 16384
114
+ },
115
+ "maxHeight": {
116
+ "type": "integer",
117
+ "minimum": 1,
118
+ "maximum": 16384
119
+ },
120
+ "quality": {
121
+ "type": "integer",
122
+ "minimum": 1,
123
+ "maximum": 100
124
+ },
125
+ "background": {
126
+ "type": "string",
127
+ "pattern": "^#[0-9A-Fa-f]{6}$"
128
+ }
129
+ },
130
+ "allOf": [
131
+ {
132
+ "if": {
133
+ "properties": {
134
+ "format": {
135
+ "const": "PNG"
136
+ }
137
+ }
138
+ },
139
+ "then": {
140
+ "not": {
141
+ "anyOf": [
142
+ {
143
+ "required": [
144
+ "quality"
145
+ ]
146
+ },
147
+ {
148
+ "required": [
149
+ "background"
150
+ ]
151
+ }
152
+ ]
153
+ }
154
+ }
155
+ }
156
+ ]
157
+ }
158
+ },
159
+ "allOf": [
160
+ {
161
+ "if": {
162
+ "required": [
163
+ "transform"
164
+ ]
165
+ },
166
+ "then": {
167
+ "properties": {
168
+ "kind": {
169
+ "const": "IMAGE"
170
+ }
171
+ }
172
+ }
173
+ }
174
+ ]
34
175
  },
35
- "response": { "$ref": "#/$defs/metadata" }
176
+ "response": {
177
+ "$ref": "#/$defs/metadata"
178
+ }
36
179
  }
37
180
  }
@@ -3,34 +3,159 @@
3
3
  "$id": "https://mhome.ai/schema/artifact-upload.v1.schema.json",
4
4
  "title": "mHome Artifact Upload v1",
5
5
  "oneOf": [
6
- { "$ref": "#/$defs/request" },
7
- { "$ref": "#/$defs/response" }
6
+ {
7
+ "$ref": "#/$defs/request"
8
+ },
9
+ {
10
+ "$ref": "#/$defs/response"
11
+ }
8
12
  ],
9
13
  "$defs": {
10
14
  "request": {
11
15
  "type": "object",
12
16
  "additionalProperties": false,
13
- "required": ["kind", "mimeType", "sizeBytes", "sha256"],
17
+ "required": [
18
+ "kind",
19
+ "mimeType",
20
+ "sizeBytes",
21
+ "sha256"
22
+ ],
14
23
  "properties": {
15
- "kind": { "enum": ["IMAGE", "AUDIO", "VIDEO", "FILE"] },
16
- "mimeType": { "type": "string", "minLength": 3, "maxLength": 255 },
17
- "sizeBytes": { "type": "integer", "minimum": 1, "maximum": 9007199254740991 },
18
- "sha256": { "type": "string", "pattern": "^[0-9a-f]{64}$" },
19
- "durationMillis": { "type": "integer", "minimum": 1, "maximum": 9007199254740991 }
20
- }
24
+ "kind": {
25
+ "enum": [
26
+ "IMAGE",
27
+ "AUDIO",
28
+ "VIDEO",
29
+ "FILE"
30
+ ]
31
+ },
32
+ "mimeType": {
33
+ "type": "string",
34
+ "minLength": 3,
35
+ "maxLength": 255
36
+ },
37
+ "sizeBytes": {
38
+ "type": "integer",
39
+ "minimum": 1,
40
+ "maximum": 9007199254740991
41
+ },
42
+ "sha256": {
43
+ "type": "string",
44
+ "pattern": "^[0-9a-f]{64}$"
45
+ },
46
+ "durationMillis": {
47
+ "type": "integer",
48
+ "minimum": 1,
49
+ "maximum": 9007199254740991
50
+ },
51
+ "transform": {
52
+ "type": "object",
53
+ "additionalProperties": false,
54
+ "required": [
55
+ "format"
56
+ ],
57
+ "properties": {
58
+ "format": {
59
+ "enum": [
60
+ "JPEG",
61
+ "PNG"
62
+ ]
63
+ },
64
+ "maxWidth": {
65
+ "type": "integer",
66
+ "minimum": 1,
67
+ "maximum": 16384
68
+ },
69
+ "maxHeight": {
70
+ "type": "integer",
71
+ "minimum": 1,
72
+ "maximum": 16384
73
+ },
74
+ "quality": {
75
+ "type": "integer",
76
+ "minimum": 1,
77
+ "maximum": 100
78
+ },
79
+ "background": {
80
+ "type": "string",
81
+ "pattern": "^#[0-9A-Fa-f]{6}$"
82
+ }
83
+ },
84
+ "allOf": [
85
+ {
86
+ "if": {
87
+ "properties": {
88
+ "format": {
89
+ "const": "PNG"
90
+ }
91
+ }
92
+ },
93
+ "then": {
94
+ "not": {
95
+ "anyOf": [
96
+ {
97
+ "required": [
98
+ "quality"
99
+ ]
100
+ },
101
+ {
102
+ "required": [
103
+ "background"
104
+ ]
105
+ }
106
+ ]
107
+ }
108
+ }
109
+ }
110
+ ]
111
+ }
112
+ },
113
+ "allOf": [
114
+ {
115
+ "if": {
116
+ "required": [
117
+ "transform"
118
+ ]
119
+ },
120
+ "then": {
121
+ "properties": {
122
+ "kind": {
123
+ "const": "IMAGE"
124
+ }
125
+ }
126
+ }
127
+ }
128
+ ]
21
129
  },
22
130
  "response": {
23
131
  "type": "object",
24
132
  "additionalProperties": false,
25
- "required": ["uploadId", "url", "headers", "expiresAtUnixMs"],
133
+ "required": [
134
+ "uploadId",
135
+ "url",
136
+ "headers",
137
+ "expiresAtUnixMs"
138
+ ],
26
139
  "properties": {
27
- "uploadId": { "type": "string", "minLength": 1 },
28
- "url": { "type": "string", "pattern": "^https?://" },
140
+ "uploadId": {
141
+ "type": "string",
142
+ "minLength": 1
143
+ },
144
+ "url": {
145
+ "type": "string",
146
+ "pattern": "^https?://"
147
+ },
29
148
  "headers": {
30
149
  "type": "object",
31
- "additionalProperties": { "type": "string" }
150
+ "additionalProperties": {
151
+ "type": "string"
152
+ }
32
153
  },
33
- "expiresAtUnixMs": { "type": "integer", "minimum": 1, "maximum": 9007199254740991 }
154
+ "expiresAtUnixMs": {
155
+ "type": "integer",
156
+ "minimum": 1,
157
+ "maximum": 9007199254740991
158
+ }
34
159
  }
35
160
  }
36
161
  }
@@ -0,0 +1,17 @@
1
+ {
2
+ "$schema": "https://json-schema.org/draft/2020-12/schema",
3
+ "$id": "https://mhome.ai/schema/media-reference.v1.schema.json",
4
+ "title": "MeowLink media reference",
5
+ "type": "object",
6
+ "additionalProperties": false,
7
+ "required": [
8
+ "uri"
9
+ ],
10
+ "properties": {
11
+ "uri": {
12
+ "type": "string",
13
+ "pattern": "^meow-artifact://v1/",
14
+ "maxLength": 2048
15
+ }
16
+ }
17
+ }