@vosjs/cli 0.13.1 → 0.14.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/dist/{chunk-YICRU4ER.js → chunk-MMKDYE57.js} +2645 -294
- package/dist/chunk-MMKDYE57.js.map +1 -0
- package/dist/cli.js +1 -1
- package/dist/index.js +1 -1
- package/dist/{run-PCWIQ4GI.js → run-R5P44XNR.js} +2 -2
- package/package.json +5 -5
- package/schema/actions.schema.json +76 -12
- package/schema/channel-specs.json +135 -22
- package/schema/doc.schema.json +418 -103
- package/dist/chunk-YICRU4ER.js.map +0 -1
- /package/dist/{run-PCWIQ4GI.js.map → run-R5P44XNR.js.map} +0 -0
package/dist/cli.js
CHANGED
|
@@ -495,7 +495,7 @@ async function cmdCheck(argv) {
|
|
|
495
495
|
return result.ok ? EXIT_OK : EXIT_ERROR;
|
|
496
496
|
}
|
|
497
497
|
async function delegate(argv, viaAlias = false) {
|
|
498
|
-
const { run } = await import("./run-
|
|
498
|
+
const { run } = await import("./run-R5P44XNR.js");
|
|
499
499
|
if (viaAlias && argv[0]) {
|
|
500
500
|
process.stderr.write(
|
|
501
501
|
`note: "vos voila ${argv[0]}" is now "vos ${argv[0]}".
|
package/dist/index.js
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@vosjs/cli",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.14.0",
|
|
4
4
|
"description": "The vos CLI: record the real product from a scripted browser flow, auto-zoom from the cursor track, cut as data in doc.json, render deterministic video and stills, deliver a release's media per destination spec, and sync with vos.so. One binary, every verb, MIT.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "MIT",
|
|
@@ -51,11 +51,11 @@
|
|
|
51
51
|
"@vosjs/core": "^0.23.2",
|
|
52
52
|
"@vosjs/editor": "^1.3.1",
|
|
53
53
|
"@vosjs/elements": "^0.8.1",
|
|
54
|
-
"@vosjs/render-core": "^0.2.1",
|
|
55
54
|
"@vosjs/shared": "^0.4.1",
|
|
56
|
-
"@vosjs/
|
|
57
|
-
"@vosjs/
|
|
58
|
-
"@vosjs/tween": "^0.8.2"
|
|
55
|
+
"@vosjs/render-core": "^0.2.1",
|
|
56
|
+
"@vosjs/studio-core": "^0.5.0",
|
|
57
|
+
"@vosjs/tween": "^0.8.2",
|
|
58
|
+
"@vosjs/timeline": "^0.4.1"
|
|
59
59
|
},
|
|
60
60
|
"devDependencies": {
|
|
61
61
|
"@types/node": "^22",
|
|
@@ -2,9 +2,11 @@
|
|
|
2
2
|
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
|
3
3
|
"$id": "https://vos.so/schemas/actions.schema.json",
|
|
4
4
|
"title": "vosso actions script",
|
|
5
|
-
"description": "Declarative browser flow executed by `vos record`
|
|
5
|
+
"description": "Declarative browser flow executed by `vos record` — the recipe an agent writes after exploring a site. The recorder synthesizes the cursor track from these steps.",
|
|
6
6
|
"type": "object",
|
|
7
|
-
"required": [
|
|
7
|
+
"required": [
|
|
8
|
+
"steps"
|
|
9
|
+
],
|
|
8
10
|
"additionalProperties": false,
|
|
9
11
|
"properties": {
|
|
10
12
|
"url": {
|
|
@@ -14,7 +16,10 @@
|
|
|
14
16
|
},
|
|
15
17
|
"viewport": {
|
|
16
18
|
"type": "object",
|
|
17
|
-
"required": [
|
|
19
|
+
"required": [
|
|
20
|
+
"width",
|
|
21
|
+
"height"
|
|
22
|
+
],
|
|
18
23
|
"additionalProperties": false,
|
|
19
24
|
"properties": {
|
|
20
25
|
"width": {
|
|
@@ -36,7 +41,10 @@
|
|
|
36
41
|
"oneOf": [
|
|
37
42
|
{
|
|
38
43
|
"type": "object",
|
|
39
|
-
"required": [
|
|
44
|
+
"required": [
|
|
45
|
+
"do",
|
|
46
|
+
"ms"
|
|
47
|
+
],
|
|
40
48
|
"additionalProperties": false,
|
|
41
49
|
"properties": {
|
|
42
50
|
"do": {
|
|
@@ -50,12 +58,20 @@
|
|
|
50
58
|
"type": "string",
|
|
51
59
|
"minLength": 1,
|
|
52
60
|
"description": "Optional stable identity: doc.json anchors name a step by this id (else by index), so a step survives moving or gaining neighbours across script edits. Unique across steps when present."
|
|
61
|
+
},
|
|
62
|
+
"caption": {
|
|
63
|
+
"type": "string",
|
|
64
|
+
"maxLength": 80,
|
|
65
|
+
"description": "a beat's caption: vos deliver lands it as a lower-third at this step's moment on cuts that take words (feed cuts, the demo), never on loops or stills"
|
|
53
66
|
}
|
|
54
67
|
}
|
|
55
68
|
},
|
|
56
69
|
{
|
|
57
70
|
"type": "object",
|
|
58
|
-
"required": [
|
|
71
|
+
"required": [
|
|
72
|
+
"do",
|
|
73
|
+
"selector"
|
|
74
|
+
],
|
|
59
75
|
"additionalProperties": false,
|
|
60
76
|
"properties": {
|
|
61
77
|
"do": {
|
|
@@ -68,18 +84,26 @@
|
|
|
68
84
|
"type": "number",
|
|
69
85
|
"minimum": 0,
|
|
70
86
|
"default": 700,
|
|
71
|
-
"description": "Dwell
|
|
87
|
+
"description": "Dwell — parked cursor becomes a zoom signal."
|
|
72
88
|
},
|
|
73
89
|
"id": {
|
|
74
90
|
"type": "string",
|
|
75
91
|
"minLength": 1,
|
|
76
92
|
"description": "Optional stable identity: doc.json anchors name a step by this id (else by index), so a step survives moving or gaining neighbours across script edits. Unique across steps when present."
|
|
93
|
+
},
|
|
94
|
+
"caption": {
|
|
95
|
+
"type": "string",
|
|
96
|
+
"maxLength": 80,
|
|
97
|
+
"description": "a beat's caption: vos deliver lands it as a lower-third at this step's moment on cuts that take words (feed cuts, the demo), never on loops or stills"
|
|
77
98
|
}
|
|
78
99
|
}
|
|
79
100
|
},
|
|
80
101
|
{
|
|
81
102
|
"type": "object",
|
|
82
|
-
"required": [
|
|
103
|
+
"required": [
|
|
104
|
+
"do",
|
|
105
|
+
"selector"
|
|
106
|
+
],
|
|
83
107
|
"additionalProperties": false,
|
|
84
108
|
"properties": {
|
|
85
109
|
"do": {
|
|
@@ -92,14 +116,23 @@
|
|
|
92
116
|
"type": "string",
|
|
93
117
|
"minLength": 1,
|
|
94
118
|
"description": "Optional stable identity: doc.json anchors name a step by this id (else by index), so a step survives moving or gaining neighbours across script edits. Unique across steps when present."
|
|
119
|
+
},
|
|
120
|
+
"caption": {
|
|
121
|
+
"type": "string",
|
|
122
|
+
"maxLength": 80,
|
|
123
|
+
"description": "a beat's caption: vos deliver lands it as a lower-third at this step's moment on cuts that take words (feed cuts, the demo), never on loops or stills"
|
|
95
124
|
}
|
|
96
125
|
}
|
|
97
126
|
},
|
|
98
127
|
{
|
|
99
128
|
"type": "object",
|
|
100
|
-
"required": [
|
|
129
|
+
"required": [
|
|
130
|
+
"do",
|
|
131
|
+
"selector",
|
|
132
|
+
"text"
|
|
133
|
+
],
|
|
101
134
|
"additionalProperties": false,
|
|
102
|
-
"description": "Typing is a zoom signal
|
|
135
|
+
"description": "Typing is a zoom signal — a type step earns a held frame on its field (the click into it opens the span, the camera releases after the last character). ~0.6s+ of typing qualifies, so pace delayMs like a person (60-90ms) for a camera moment.",
|
|
103
136
|
"properties": {
|
|
104
137
|
"do": {
|
|
105
138
|
"const": "type"
|
|
@@ -124,12 +157,20 @@
|
|
|
124
157
|
"type": "string",
|
|
125
158
|
"minLength": 1,
|
|
126
159
|
"description": "Optional stable identity: doc.json anchors name a step by this id (else by index), so a step survives moving or gaining neighbours across script edits. Unique across steps when present."
|
|
160
|
+
},
|
|
161
|
+
"caption": {
|
|
162
|
+
"type": "string",
|
|
163
|
+
"maxLength": 80,
|
|
164
|
+
"description": "a beat's caption: vos deliver lands it as a lower-third at this step's moment on cuts that take words (feed cuts, the demo), never on loops or stills"
|
|
127
165
|
}
|
|
128
166
|
}
|
|
129
167
|
},
|
|
130
168
|
{
|
|
131
169
|
"type": "object",
|
|
132
|
-
"required": [
|
|
170
|
+
"required": [
|
|
171
|
+
"do",
|
|
172
|
+
"dy"
|
|
173
|
+
],
|
|
133
174
|
"additionalProperties": false,
|
|
134
175
|
"properties": {
|
|
135
176
|
"do": {
|
|
@@ -142,12 +183,21 @@
|
|
|
142
183
|
"type": "string",
|
|
143
184
|
"minLength": 1,
|
|
144
185
|
"description": "Optional stable identity: doc.json anchors name a step by this id (else by index), so a step survives moving or gaining neighbours across script edits. Unique across steps when present."
|
|
186
|
+
},
|
|
187
|
+
"caption": {
|
|
188
|
+
"type": "string",
|
|
189
|
+
"maxLength": 80,
|
|
190
|
+
"description": "a beat's caption: vos deliver lands it as a lower-third at this step's moment on cuts that take words (feed cuts, the demo), never on loops or stills"
|
|
145
191
|
}
|
|
146
192
|
}
|
|
147
193
|
},
|
|
148
194
|
{
|
|
149
195
|
"type": "object",
|
|
150
|
-
"required": [
|
|
196
|
+
"required": [
|
|
197
|
+
"do",
|
|
198
|
+
"x",
|
|
199
|
+
"y"
|
|
200
|
+
],
|
|
151
201
|
"additionalProperties": false,
|
|
152
202
|
"properties": {
|
|
153
203
|
"do": {
|
|
@@ -165,12 +215,21 @@
|
|
|
165
215
|
"type": "string",
|
|
166
216
|
"minLength": 1,
|
|
167
217
|
"description": "Optional stable identity: doc.json anchors name a step by this id (else by index), so a step survives moving or gaining neighbours across script edits. Unique across steps when present."
|
|
218
|
+
},
|
|
219
|
+
"caption": {
|
|
220
|
+
"type": "string",
|
|
221
|
+
"maxLength": 80,
|
|
222
|
+
"description": "a beat's caption: vos deliver lands it as a lower-third at this step's moment on cuts that take words (feed cuts, the demo), never on loops or stills"
|
|
168
223
|
}
|
|
169
224
|
}
|
|
170
225
|
},
|
|
171
226
|
{
|
|
172
227
|
"type": "object",
|
|
173
|
-
"required": [
|
|
228
|
+
"required": [
|
|
229
|
+
"do",
|
|
230
|
+
"tx",
|
|
231
|
+
"ty"
|
|
232
|
+
],
|
|
174
233
|
"additionalProperties": false,
|
|
175
234
|
"description": "Press-move-release: drag an element, slide a range input, move a clip. Start = selector center when given, else (x, y); end = (tx, ty), eased over ms.",
|
|
176
235
|
"properties": {
|
|
@@ -205,6 +264,11 @@
|
|
|
205
264
|
"type": "string",
|
|
206
265
|
"minLength": 1,
|
|
207
266
|
"description": "Optional stable identity: doc.json anchors name a step by this id (else by index), so a step survives moving or gaining neighbours across script edits. Unique across steps when present."
|
|
267
|
+
},
|
|
268
|
+
"caption": {
|
|
269
|
+
"type": "string",
|
|
270
|
+
"maxLength": 80,
|
|
271
|
+
"description": "a beat's caption: vos deliver lands it as a lower-third at this step's moment on cuts that take words (feed cuts, the demo), never on loops or stills"
|
|
208
272
|
}
|
|
209
273
|
}
|
|
210
274
|
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
{
|
|
2
|
-
"$comment": "Per-channel launch-asset specs
|
|
2
|
+
"$comment": "Per-channel launch-asset specs — the data the launch-kit skill loops over (mirrored as references/channel-specs.md in vosjs/skills; update together). Verified against official platform docs 2026-08-04; platform specs drift, re-verify quarterly. Image specs carry `genre`: 'screenshot' = real UI from the take (store policy demands real UX); 'card' = a composed cover — rendered from the poster program when one is in hand. `text` is the destination's word policy: 'none' (the picture carries it alone: a tile, a store screenshot), 'allowed', 'expected' (a card that should say something). `safe` is the rect, as fractions of the frame, that every text box must sit inside (the platform's own chrome or crop covers the rest); the picture checks read both. `template` names the poster template a card destination renders from by default (the family that ships with the CLI: split-cover carries a headline, card-on-gradient carries none).",
|
|
3
3
|
"version": 1,
|
|
4
4
|
"verified": "2026-08-04",
|
|
5
5
|
"specs": [
|
|
@@ -12,7 +12,14 @@
|
|
|
12
12
|
"minSeconds": 60,
|
|
13
13
|
"maxSeconds": 120,
|
|
14
14
|
"format": "mp4 (H.264+AAC)",
|
|
15
|
-
"notes": "Captions burned in. The same public upload serves the Chrome Web Store promo video and Product Hunt video (both take YouTube URLs only)."
|
|
15
|
+
"notes": "Captions burned in. The same public upload serves the Chrome Web Store promo video and Product Hunt video (both take YouTube URLs only).",
|
|
16
|
+
"text": "allowed",
|
|
17
|
+
"safe": {
|
|
18
|
+
"x": 0.05,
|
|
19
|
+
"y": 0.08,
|
|
20
|
+
"w": 0.9,
|
|
21
|
+
"h": 0.84
|
|
22
|
+
}
|
|
16
23
|
},
|
|
17
24
|
{
|
|
18
25
|
"channel": "x",
|
|
@@ -23,8 +30,15 @@
|
|
|
23
30
|
"minSeconds": 30,
|
|
24
31
|
"maxSeconds": 140,
|
|
25
32
|
"maxBytes": 536870912,
|
|
26
|
-
"format": "mp4 (H.264+AAC ONLY
|
|
27
|
-
"notes": "30
|
|
33
|
+
"format": "mp4 (H.264+AAC ONLY — HEVC/VP9/AV1 rejected)",
|
|
34
|
+
"notes": "30–60s plays best; 140s/512MB is the free-tier ceiling. 1:1 also allowed. Native upload, never a link post.",
|
|
35
|
+
"text": "allowed",
|
|
36
|
+
"safe": {
|
|
37
|
+
"x": 0.05,
|
|
38
|
+
"y": 0.08,
|
|
39
|
+
"w": 0.9,
|
|
40
|
+
"h": 0.84
|
|
41
|
+
}
|
|
28
42
|
},
|
|
29
43
|
{
|
|
30
44
|
"channel": "shorts-linkedin",
|
|
@@ -35,7 +49,14 @@
|
|
|
35
49
|
"minSeconds": 30,
|
|
36
50
|
"maxSeconds": 90,
|
|
37
51
|
"format": "mp4 (H.264+AAC)",
|
|
38
|
-
"notes": "Critical text inside a centered ~900
|
|
52
|
+
"notes": "Critical text inside a centered ~900×1160 safe zone — platform chrome covers the rest. Serves YouTube Shorts and LinkedIn native vertical.",
|
|
53
|
+
"text": "expected",
|
|
54
|
+
"safe": {
|
|
55
|
+
"x": 0.0833,
|
|
56
|
+
"y": 0.1979,
|
|
57
|
+
"w": 0.8333,
|
|
58
|
+
"h": 0.6042
|
|
59
|
+
}
|
|
39
60
|
},
|
|
40
61
|
{
|
|
41
62
|
"channel": "github",
|
|
@@ -47,7 +68,14 @@
|
|
|
47
68
|
"maxSeconds": 20,
|
|
48
69
|
"maxBytes": 10485760,
|
|
49
70
|
"format": "mp4 (H.264)",
|
|
50
|
-
"notes": "
|
|
71
|
+
"notes": "≤10MB is the free-plan attachment ceiling; two-pass target bitrate from duration.",
|
|
72
|
+
"text": "none",
|
|
73
|
+
"safe": {
|
|
74
|
+
"x": 0.05,
|
|
75
|
+
"y": 0.08,
|
|
76
|
+
"w": 0.9,
|
|
77
|
+
"h": 0.84
|
|
78
|
+
}
|
|
51
79
|
},
|
|
52
80
|
{
|
|
53
81
|
"channel": "youtube",
|
|
@@ -58,7 +86,15 @@
|
|
|
58
86
|
"maxBytes": 2097152,
|
|
59
87
|
"format": "png|jpg",
|
|
60
88
|
"notes": "",
|
|
61
|
-
"genre": "card"
|
|
89
|
+
"genre": "card",
|
|
90
|
+
"text": "expected",
|
|
91
|
+
"safe": {
|
|
92
|
+
"x": 0.05,
|
|
93
|
+
"y": 0.08,
|
|
94
|
+
"w": 0.9,
|
|
95
|
+
"h": 0.84
|
|
96
|
+
},
|
|
97
|
+
"template": "split-cover"
|
|
62
98
|
},
|
|
63
99
|
{
|
|
64
100
|
"channel": "cws",
|
|
@@ -68,8 +104,15 @@
|
|
|
68
104
|
"h": 800,
|
|
69
105
|
"count": "1-5",
|
|
70
106
|
"format": "png|jpg",
|
|
71
|
-
"notes": "Real UX only
|
|
72
|
-
"genre": "screenshot"
|
|
107
|
+
"notes": "Real UX only — misleading listing images are a removal-grade violation. Full bleed, square corners.",
|
|
108
|
+
"genre": "screenshot",
|
|
109
|
+
"text": "none",
|
|
110
|
+
"safe": {
|
|
111
|
+
"x": 0,
|
|
112
|
+
"y": 0,
|
|
113
|
+
"w": 1,
|
|
114
|
+
"h": 1
|
|
115
|
+
}
|
|
73
116
|
},
|
|
74
117
|
{
|
|
75
118
|
"channel": "cws",
|
|
@@ -79,7 +122,15 @@
|
|
|
79
122
|
"h": 280,
|
|
80
123
|
"format": "png|jpg",
|
|
81
124
|
"notes": "Listings without one rank lower. No text; fill the region; subject centered.",
|
|
82
|
-
"genre": "card"
|
|
125
|
+
"genre": "card",
|
|
126
|
+
"text": "none",
|
|
127
|
+
"safe": {
|
|
128
|
+
"x": 0,
|
|
129
|
+
"y": 0,
|
|
130
|
+
"w": 1,
|
|
131
|
+
"h": 1
|
|
132
|
+
},
|
|
133
|
+
"template": "card-on-gradient"
|
|
83
134
|
},
|
|
84
135
|
{
|
|
85
136
|
"channel": "cws",
|
|
@@ -89,7 +140,15 @@
|
|
|
89
140
|
"h": 560,
|
|
90
141
|
"format": "png|jpg",
|
|
91
142
|
"notes": "Carousel eligibility.",
|
|
92
|
-
"genre": "card"
|
|
143
|
+
"genre": "card",
|
|
144
|
+
"text": "allowed",
|
|
145
|
+
"safe": {
|
|
146
|
+
"x": 0.05,
|
|
147
|
+
"y": 0.08,
|
|
148
|
+
"w": 0.9,
|
|
149
|
+
"h": 0.84
|
|
150
|
+
},
|
|
151
|
+
"template": "split-cover"
|
|
93
152
|
},
|
|
94
153
|
{
|
|
95
154
|
"channel": "cws",
|
|
@@ -98,7 +157,14 @@
|
|
|
98
157
|
"w": 128,
|
|
99
158
|
"h": 128,
|
|
100
159
|
"format": "png",
|
|
101
|
-
"notes": "96
|
|
160
|
+
"notes": "96×96 art + 16px transparent padding.",
|
|
161
|
+
"text": "none",
|
|
162
|
+
"safe": {
|
|
163
|
+
"x": 0,
|
|
164
|
+
"y": 0,
|
|
165
|
+
"w": 1,
|
|
166
|
+
"h": 1
|
|
167
|
+
}
|
|
102
168
|
},
|
|
103
169
|
{
|
|
104
170
|
"channel": "producthunt",
|
|
@@ -108,8 +174,16 @@
|
|
|
108
174
|
"h": 240,
|
|
109
175
|
"maxBytes": 3145728,
|
|
110
176
|
"format": "gif|png",
|
|
111
|
-
"notes": "GIF animates on hover only
|
|
112
|
-
"genre": "card"
|
|
177
|
+
"notes": "GIF animates on hover only — the first frame must stand alone.",
|
|
178
|
+
"genre": "card",
|
|
179
|
+
"text": "none",
|
|
180
|
+
"safe": {
|
|
181
|
+
"x": 0.06,
|
|
182
|
+
"y": 0.06,
|
|
183
|
+
"w": 0.88,
|
|
184
|
+
"h": 0.88
|
|
185
|
+
},
|
|
186
|
+
"template": "card-on-gradient"
|
|
113
187
|
},
|
|
114
188
|
{
|
|
115
189
|
"channel": "producthunt",
|
|
@@ -120,7 +194,14 @@
|
|
|
120
194
|
"count": "4-8",
|
|
121
195
|
"format": "png|jpg|gif",
|
|
122
196
|
"notes": "First image is the hero.",
|
|
123
|
-
"genre": "screenshot"
|
|
197
|
+
"genre": "screenshot",
|
|
198
|
+
"text": "none",
|
|
199
|
+
"safe": {
|
|
200
|
+
"x": 0,
|
|
201
|
+
"y": 0,
|
|
202
|
+
"w": 1,
|
|
203
|
+
"h": 1
|
|
204
|
+
}
|
|
124
205
|
},
|
|
125
206
|
{
|
|
126
207
|
"channel": "x",
|
|
@@ -130,7 +211,15 @@
|
|
|
130
211
|
"h": 675,
|
|
131
212
|
"format": "png|jpg",
|
|
132
213
|
"notes": "",
|
|
133
|
-
"genre": "card"
|
|
214
|
+
"genre": "card",
|
|
215
|
+
"text": "allowed",
|
|
216
|
+
"safe": {
|
|
217
|
+
"x": 0.05,
|
|
218
|
+
"y": 0.08,
|
|
219
|
+
"w": 0.9,
|
|
220
|
+
"h": 0.84
|
|
221
|
+
},
|
|
222
|
+
"template": "split-cover"
|
|
134
223
|
},
|
|
135
224
|
{
|
|
136
225
|
"channel": "linkedin",
|
|
@@ -139,8 +228,16 @@
|
|
|
139
228
|
"w": 1200,
|
|
140
229
|
"h": 627,
|
|
141
230
|
"format": "png|jpg",
|
|
142
|
-
"notes": "1080
|
|
143
|
-
"genre": "card"
|
|
231
|
+
"notes": "1080×1350 vertical also performs in the mobile feed.",
|
|
232
|
+
"genre": "card",
|
|
233
|
+
"text": "expected",
|
|
234
|
+
"safe": {
|
|
235
|
+
"x": 0.05,
|
|
236
|
+
"y": 0.08,
|
|
237
|
+
"w": 0.9,
|
|
238
|
+
"h": 0.84
|
|
239
|
+
},
|
|
240
|
+
"template": "split-cover"
|
|
144
241
|
},
|
|
145
242
|
{
|
|
146
243
|
"channel": "og",
|
|
@@ -150,8 +247,16 @@
|
|
|
150
247
|
"h": 630,
|
|
151
248
|
"maxBytes": 1048576,
|
|
152
249
|
"format": "png|jpg",
|
|
153
|
-
"notes": "Text in the center ~1080
|
|
154
|
-
"genre": "card"
|
|
250
|
+
"notes": "Text in the center ~1080×600. Set twitter:card=summary_large_image explicitly — og:image alone gets the small card.",
|
|
251
|
+
"genre": "card",
|
|
252
|
+
"text": "expected",
|
|
253
|
+
"safe": {
|
|
254
|
+
"x": 0.05,
|
|
255
|
+
"y": 0.0238,
|
|
256
|
+
"w": 0.9,
|
|
257
|
+
"h": 0.9524
|
|
258
|
+
},
|
|
259
|
+
"template": "split-cover"
|
|
155
260
|
},
|
|
156
261
|
{
|
|
157
262
|
"channel": "github",
|
|
@@ -161,8 +266,16 @@
|
|
|
161
266
|
"h": 640,
|
|
162
267
|
"maxBytes": 1048576,
|
|
163
268
|
"format": "png|jpg",
|
|
164
|
-
"notes": "Key text
|
|
165
|
-
"genre": "card"
|
|
269
|
+
"notes": "Key text ≥50px from every edge.",
|
|
270
|
+
"genre": "card",
|
|
271
|
+
"text": "expected",
|
|
272
|
+
"safe": {
|
|
273
|
+
"x": 0.0391,
|
|
274
|
+
"y": 0.0781,
|
|
275
|
+
"w": 0.9219,
|
|
276
|
+
"h": 0.8438
|
|
277
|
+
},
|
|
278
|
+
"template": "card-on-gradient"
|
|
166
279
|
}
|
|
167
280
|
]
|
|
168
281
|
}
|